24 #include <linux/kernel.h>
25 #include <linux/module.h>
30 #include <linux/i2c.h>
31 #include <asm/div64.h>
37 #define DRX_FW_FILENAME_A2 "drxd-a2-1.1.fw"
38 #define DRX_FW_FILENAME_B1 "drxd-b1-1.1.fw"
42 #define DRX_I2C_RMW 0x10
43 #define DRX_I2C_BROADCAST 0x20
44 #define DRX_I2C_CLEARCRC 0x80
45 #define DRX_I2C_SINGLE_MASTER 0xC0
46 #define DRX_I2C_MODEFLAGS 0xC0
47 #define DRX_I2C_FLAGS 0xF0
50 #define SIZEOF_ARRAY(array) (sizeof((array))/sizeof((array)[0]))
53 #define DEFAULT_LOCK_TIMEOUT 1100
55 #define DRX_CHANNEL_AUTO 0
56 #define DRX_CHANNEL_HIGH 1
57 #define DRX_CHANNEL_LOW 2
59 #define DRX_LOCK_MPEG 1
60 #define DRX_LOCK_FEC 2
61 #define DRX_LOCK_DEMOD 4
211 struct i2c_msg msg = {.
addr = adr, .flags = 0, .buf =
data, .len = len };
219 u8 adr,
u8 *msg,
int len,
u8 *answ,
int alen)
223 .
addr = adr, .flags = 0,
224 .buf =
msg, .len = len
227 .buf = answ, .len = alen
247 u8 adr = state->
config.demod_address;
248 u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
249 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
255 *data = mm2[0] | (mm2[1] << 8);
256 return mm2[0] | (mm2[1] << 8);
261 u8 adr = state->
config.demod_address;
262 u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
263 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
271 mm2[0] | (mm2[1] << 8) | (mm2[2] << 16) | (mm2[3] << 24);
277 u8 adr = state->
config.demod_address;
278 u8 mm[6] = { reg & 0xff, (reg >> 16) & 0xff,
279 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
280 data & 0xff, (data >> 8) & 0xff
290 u8 adr = state->
config.demod_address;
291 u8 mm[8] = { reg & 0xff, (reg >> 16) & 0xff,
292 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
293 data & 0xff, (data >> 8) & 0xff,
294 (data >> 16) & 0xff, (data >> 24) & 0xff
302 static int write_chunk(
struct drxd_state *state,
305 u8 adr = state->
config.demod_address;
306 u8 mm[
CHUNK_SIZE + 4] = { reg & 0xff, (reg >> 16) & 0xff,
307 flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
311 for (i = 0; i <
len; i++)
323 while (BlockSize > 0) {
326 if (write_chunk(state, Address, pBlock, Chunk, Flags) < 0)
329 Address += (Chunk >> 1);
335 static int WriteTable(
struct drxd_state *state,
u8 * pTable)
344 u32 Address = pTable[0] | (pTable[1] << 8) |
345 (pTable[2] << 16) | (pTable[3] << 24);
347 if (Address == 0xFFFFFFFF)
349 pTable +=
sizeof(
u32);
351 Length = pTable[0] | (pTable[1] << 8);
352 pTable +=
sizeof(
u16);
355 status =
WriteBlock(state, Address, Length * 2, pTable, 0);
356 pTable += (Length * 2);
365 static int ResetCEFR(
struct drxd_state *state)
372 return WriteTable(state, state->
m_InitCP);
381 status = WriteTable(state, state->
m_InitCE);
515 return WriteTable(state, state->
m_InitEQ);
520 return WriteTable(state, state->
m_InitEC);
525 return WriteTable(state, state->
m_InitSC);
528 static int InitAtomicRead(
struct drxd_state *state)
533 static int CorrectSysClockDeviation(
struct drxd_state *state);
535 static int DRX_GetLockStatus(
struct drxd_state *state,
u32 * pLockStatus)
551 printk(
KERN_ERR "Can't read SC_RA_RAM_LOCK__A status = %08x\n", status);
558 if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask) {
560 CorrectSysClockDeviation(state);
563 if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
566 if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
582 u16 FeAgRegPm1AgcWri;
583 u16 FeAgRegAgModeLop;
608 u16 FeAgRegAgModeLop;
609 u16 FeAgRegEgcSetLvl;
648 const u16 maxRur = 8;
649 const u16 slowIncrDecLUT[] = { 3, 4, 4, 5, 6 };
650 const u16 fastIncrDecLUT[] = { 14, 15, 15, 16,
666 if (invRurCount > maxRur) {
668 fineSpeed += fineSteps;
670 rurCount = maxRur - invRurCount;
682 fastIncrDecLUT[fineSpeed /
686 slowIncrDecLUT[fineSpeed /
758 u16 FeAgRegAgAgcSio = 0;
810 u16 FeAgRegAgAgcSio = 0;
851 u16 FeAgRegAgAgcSio = 0;
892 u32 Vmax, Rpar, Vmin, Vout;
894 if (R2 == 0 && (R1 == 0 || R3 == 0))
897 Vmax = (3300 *
R2) / (R1 + R2);
898 Rpar = (R2 *
R3) / (R3 + R2);
899 Vmin = (3300 * Rpar) / (R1 + Rpar);
900 Vout = Vmin + ((Vmax - Vmin) * Value) / 1024;
929 static int DownloadMicrocode(
struct drxd_state *state,
930 const u8 *pMCImage,
u32 Length)
939 pSrc = (
u8 *) pMCImage;
943 offset +=
sizeof(
u16);
944 nBlocks = (pSrc[0] << 8) | pSrc[1];
946 offset +=
sizeof(
u16);
948 for (i = 0; i < nBlocks; i++) {
949 Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
950 (pSrc[2] << 8) | pSrc[3];
952 offset +=
sizeof(
u32);
954 BlockSize = ((pSrc[0] << 8) | pSrc[1]) *
sizeof(
u16);
956 offset +=
sizeof(
u16);
961 offset +=
sizeof(
u16);
966 offset +=
sizeof(
u16);
968 status =
WriteBlock(state, Address, BlockSize,
996 }
while (waitCmd != 0);
1003 static int HI_CfgCommand(
struct drxd_state *state)
1031 return HI_CfgCommand(state);
1034 static int HI_ResetCommand(
struct drxd_state *state)
1048 static int DRX_ConfigureI2CBridge(
struct drxd_state *state,
int bEnableBridge)
1056 return HI_CfgCommand(state);
1059 #define HI_TR_WRITE 0x9
1060 #define HI_TR_READ 0xA
1061 #define HI_TR_READ_WRITE 0xB
1062 #define HI_TR_BROADCAST 0x4
1065 static int AtomicReadBlock(
struct drxd_state *state,
1072 if ((!pData) || ((DataSize & 1) != 0))
1103 for (i = 0; i < (DataSize / 2); i += 1) {
1110 pData[2 *
i] = (
u8) (word & 0xFF);
1111 pData[(2 *
i) + 1] = (
u8) (word >> 8);
1118 static int AtomicReadReg32(
struct drxd_state *state,
1126 status = AtomicReadBlock(state, Addr,
sizeof(
u32),
buf, Flags);
1127 *pData = (((
u32)
buf[0]) << 0) +
1134 static int StopAllProcessors(
struct drxd_state *state)
1140 static int EnableAndResetMB(
struct drxd_state *state)
1172 static int ResetECOD(
struct drxd_state *state)
1190 static int SetCfgPga(
struct drxd_state *state,
int pgaSwitch)
1261 status = WriteTable(state, state->
m_InitFE_1);
1271 status = SetCfgPga(state, 0);
1288 status = WriteTable(state, state->
m_InitFE_2);
1306 static int SC_WaitForReady(
struct drxd_state *state)
1313 if (status == 0 || curCmd == 0)
1319 static int SC_SendCommand(
struct drxd_state *state,
u16 cmd)
1325 SC_WaitForReady(state);
1329 if (errCode == 0xFFFF) {
1337 static int SC_ProcStartCommand(
struct drxd_state *state,
1350 SC_WaitForReady(state);
1361 static int SC_SetPrefParamCommand(
struct drxd_state *state,
1368 status = SC_WaitForReady(state);
1396 status = SC_WaitForReady(state);
1411 static int ConfigureMPEGOutput(
struct drxd_state *state,
int bEnableOutput)
1416 u16 EcOcRegIprInvMpg = 0;
1417 u16 EcOcRegOcModeLop = 0;
1418 u16 EcOcRegOcModeHip = 0;
1419 u16 EcOcRegOcMpgSio = 0;
1424 if (bEnableOutput) {
1466 EcOcRegIprInvMpg &= (~(0x00FF));
1470 EcOcRegIprInvMpg &= (~(0x0100));
1474 EcOcRegIprInvMpg &= (~(0x0200));
1478 EcOcRegIprInvMpg &= (~(0x0400));
1482 EcOcRegIprInvMpg &= (~(0x0800));
1501 static int SetDeviceTypeId(
struct drxd_state *state)
1519 if (deviceId == 0) {
1593 static int CorrectSysClockDeviation(
struct drxd_state *state)
1599 u32 sysClockInHz = 0;
1600 u32 sysClockFreq = 0;
1601 s16 oscClockDeviation;
1617 if ((nomincr - incr < -500) || (nomincr - incr > 500))
1620 if ((nomincr - incr < -2000) || (nomincr - incr > 2000))
1624 switch (state->
props.bandwidth_hz) {
1642 sysClockInHz = MulDiv32(incr, bandwidth, 1 << 21);
1643 sysClockFreq = (
u32) (sysClockInHz / 1000);
1645 if ((sysClockInHz % 1000) > 500)
1649 oscClockDeviation = (
u16) ((((
s32) (sysClockFreq) -
1658 if (Diff >= -200 && Diff <= 200) {
1661 if (state->
config.osc_deviation) {
1685 static int DRX_Stop(
struct drxd_state *state)
1695 status = DRX_GetLockStatus(state, &lock);
1700 status = StopOC(state);
1706 status = ConfigureMPEGOutput(state, 0);
1792 static int StartDiversity(
struct drxd_state *state)
1806 if (state->
props.bandwidth_hz == 8000000) {
1833 static int SetFrequencyShift(
struct drxd_state *state,
1834 u32 offsetFreq,
int channelMirrored)
1836 int negativeShift = (state->
tuner_mirrors == channelMirrored);
1871 static int SetCfgNoiseCalibration(
struct drxd_state *state,
1881 if (noiseCal->
cpOpt) {
1911 u16 transmissionParams = 0;
1912 u16 operationMode = 0;
1913 u16 qpskTdTpsPwr = 0;
1914 u16 qam16TdTpsPwr = 0;
1915 u16 qam64TdTpsPwr = 0;
1918 int mirrorFreqSpect;
1920 u16 qpskSnCeGain = 0;
1921 u16 qam16SnCeGain = 0;
1922 u16 qam64SnCeGain = 0;
1923 u16 qpskIsGainMan = 0;
1924 u16 qam16IsGainMan = 0;
1925 u16 qam64IsGainMan = 0;
1926 u16 qpskIsGainExp = 0;
1927 u16 qam16IsGainExp = 0;
1928 u16 qam64IsGainExp = 0;
1929 u16 bandwidthParam = 0;
1932 off = (off - 500) / 1000;
1934 off = (off + 500) / 1000;
1939 status = ResetECOD(state);
1943 status = InitSC(state);
1947 status = InitFT(state);
1950 status = InitCP(state);
1953 status = InitCE(state);
1956 status = InitEQ(state);
1959 status = InitSC(state);
1966 status = SetCfgIfAgc(state, &state->
if_agc_cfg);
1969 status = SetCfgRfAgc(state, &state->
rf_agc_cfg);
2342 status = Write16(state,
2348 bandwidthParam = 0x4807;
2349 status = Write16(state,
2355 bandwidthParam = 0x0F07;
2356 status = Write16(state,
2390 status = SetCfgNoiseCalibration(state, &state->
noise_cal);
2407 (1ULL << 21), bandwidth) - (1 << 23);
2417 SetFrequencyShift(state, off, mirrorFreqSpect);
2437 status = SC_SetPrefParamCommand(state, 0x0000, transmissionParams, operationMode);
2446 status = StartOC(state);
2451 status = StartDiversity(state);
2462 static int CDRXD(
struct drxd_state *state,
u32 IntermediateFrequency)
2464 u32 ulRfAgcOutputLevel = 0xffffffff;
2465 u32 ulRfAgcSettleLevel = 528;
2466 u32 ulRfAgcMinLevel = 0;
2468 u32 ulRfAgcSpeed = 0;
2469 u32 ulRfAgcMode = 0;
2470 u32 ulRfAgcR1 = 820;
2471 u32 ulRfAgcR2 = 2200;
2472 u32 ulRfAgcR3 = 150;
2473 u32 ulIfAgcMode = 0;
2474 u32 ulIfAgcOutputLevel = 0xffffffff;
2475 u32 ulIfAgcSettleLevel = 0xffffffff;
2476 u32 ulIfAgcMinLevel = 0xffffffff;
2477 u32 ulIfAgcMaxLevel = 0xffffffff;
2478 u32 ulIfAgcSpeed = 0xffffffff;
2479 u32 ulIfAgcR1 = 820;
2480 u32 ulIfAgcR2 = 2200;
2481 u32 ulIfAgcR3 = 150;
2483 u32 ulSerialMode = 0;
2484 u32 ulEcOcRegOcModeLop = 4;
2487 u32 ulHiI2cPatch = 0;
2504 if (ulIfAgcMode == 0 &&
2531 if (ulRfAgcMode == 0 &&
2543 if (ulRfAgcMode == 2)
2546 if (ulEnvironment <= 2)
2549 if (ulEnvironmentDiversity <= 2)
2551 (ulEnvironmentDiversity);
2569 switch (ulHiI2cPatch) {
2603 ulHiI2cDelay) / 1000;
2607 ulHiI2cBridgeDelay) / 1000;
2623 CDRXD(state, state->
config.IF ? state->
config.IF : 36000000);
2628 status = SetDeviceTypeId(state);
2641 status = Write16(state, 0x43012D, 0x047f, 0);
2646 status = HI_ResetCommand(state);
2650 status = StopAllProcessors(state);
2653 status = InitCC(state);
2659 if (state->
config.osc_deviation)
2661 state->
config.osc_deviation(state->
priv, 0, 0);
2668 s32 deviation = (devA / (1000000
L));
2674 if ((devB * (devA % 1000000
L) > 1000000L)) {
2676 deviation += (devB / 2);
2683 status = InitHI(state);
2686 status = InitAtomicRead(state);
2690 status = EnableAndResetMB(state);
2694 status = ResetCEFR(state);
2699 status = DownloadMicrocode(state, fw, fw_size);
2710 SetCfgPga(state, 0);
2717 status = InitFE(state);
2720 status = InitFT(state);
2723 status = InitCP(state);
2726 status = InitCE(state);
2729 status = InitEQ(state);
2732 status = InitEC(state);
2735 status = InitSC(state);
2739 status = SetCfgIfAgc(state, &state->
if_agc_cfg);
2742 status = SetCfgRfAgc(state, &state->
rf_agc_cfg);
2766 status = StopOC(state);
2779 DRX_GetLockStatus(state, pLockStatus);
2783 ConfigureMPEGOutput(state, 1);
2795 static int drxd_read_signal_strength(
struct dvb_frontend *fe,
u16 * strength)
2801 res = ReadIFAgc(state, &value);
2805 *strength = 0xffff - (value << 4);
2824 if (lock & DRX_LOCK_FEC)
2849 if (state->
config.disable_i2c_gate_ctrl == 1)
2852 return DRX_ConfigureI2CBridge(state, onoff);
2856 static int drxd_get_tune_settings(
struct dvb_frontend *fe,
2877 static int drxd_read_ucblocks(
struct dvb_frontend *fe,
u32 * ucblocks)
2887 ConfigureMPEGOutput(state, 0);
2905 if (fe->
ops.tuner_ops.set_params) {
2906 fe->
ops.tuner_ops.set_params(fe);
2907 if (fe->
ops.i2c_gate_ctrl)
2908 fe->
ops.i2c_gate_ctrl(fe, 0);
2913 return DRX_Start(state, off);
2926 .name =
"Micronas DRXD DVB-T",
2927 .frequency_min = 47125000,
2928 .frequency_max = 855250000,
2929 .frequency_stepsize = 166667,
2930 .frequency_tolerance = 0,
2940 .release = drxd_release,
2942 .sleep = drxd_sleep,
2943 .i2c_gate_ctrl = drxd_i2c_gate_ctrl,
2945 .set_frontend = drxd_set_frontend,
2946 .get_tune_settings = drxd_get_tune_settings,
2948 .read_status = drxd_read_status,
2949 .read_ber = drxd_read_ber,
2950 .read_signal_strength = drxd_read_signal_strength,
2951 .read_snr = drxd_read_snr,
2952 .read_ucblocks = drxd_read_ucblocks,
2964 memset(state, 0,
sizeof(*state));
2974 if (Read16(state, 0, 0, 0) < 0)
2980 ConfigureMPEGOutput(state, 0);