Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: dvb-frontends: MaxLinear MxL5xx DVB-S/S2 tuner-demodulator driver

This adds the frontend driver for the MaxLinear MxL5xx family of tuner-
demodulators, as used on Digital Devices MaxS4/8 four/eight-tuner cards.

The driver was picked from the dddvb vendor driver package and - judging
solely from the diff - has undergone a 100% rework:

- Silly #define's used to pass multiple values to functions were
expanded. This resulted in macro/register names not being usable
anymore for such occurences, but makes the code WAY more read-,
understand- and maintainable.
- CamelCase was changed to kernel_case
- All typedef were removed
- Overall code style was fixed, besides >80char lines in _defs.h and
_regs.h, checkpatch is happy.
- Also, signal stat acquisition was made to comply with the DVB API
ways to do these things.

Permission to reuse and mainline the driver code was formally granted by
Ralph Metzler <rjkm@metzlerbros.de>.

Signed-off-by: Daniel Scheller <d.scheller@gmx.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

authored by

Daniel Scheller and committed by
Mauro Carvalho Chehab
3c4e0415 20e671df

+3022
+9
drivers/media/dvb-frontends/Kconfig
··· 53 53 54 54 Say Y when you want to support these frontends. 55 55 56 + config DVB_MXL5XX 57 + tristate "MaxLinear MxL5xx based tuner-demodulators" 58 + depends on DVB_CORE && I2C 59 + default m if !MEDIA_SUBDRV_AUTOSELECT 60 + help 61 + MaxLinear MxL5xx family of DVB-S/S2 tuners/demodulators. 62 + 63 + Say Y when you want to support these frontends. 64 + 56 65 config DVB_M88DS3103 57 66 tristate "Montage Technology M88DS3103" 58 67 depends on DVB_CORE && I2C && I2C_MUX
+1
drivers/media/dvb-frontends/Makefile
··· 112 112 obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o 113 113 obj-$(CONFIG_DVB_STV0910) += stv0910.o 114 114 obj-$(CONFIG_DVB_STV6111) += stv6111.o 115 + obj-$(CONFIG_DVB_MXL5XX) += mxl5xx.o 115 116 obj-$(CONFIG_DVB_SI2165) += si2165.o 116 117 obj-$(CONFIG_DVB_A8293) += a8293.o 117 118 obj-$(CONFIG_DVB_SP2) += sp2.o
+1873
drivers/media/dvb-frontends/mxl5xx.c
··· 1 + /* 2 + * Driver for the MaxLinear MxL5xx family of tuners/demods 3 + * 4 + * Copyright (C) 2014-2015 Ralph Metzler <rjkm@metzlerbros.de> 5 + * Marcus Metzler <mocm@metzlerbros.de> 6 + * developed for Digital Devices GmbH 7 + * 8 + * based on code: 9 + * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved 10 + * which was released under GPL V2 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License 14 + * version 2, as published by the Free Software Foundation. 15 + * 16 + * This program is distributed in the hope that it will be useful, 17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 + * GNU General Public License for more details. 20 + * 21 + */ 22 + 23 + #include <linux/kernel.h> 24 + #include <linux/module.h> 25 + #include <linux/moduleparam.h> 26 + #include <linux/init.h> 27 + #include <linux/delay.h> 28 + #include <linux/firmware.h> 29 + #include <linux/i2c.h> 30 + #include <linux/version.h> 31 + #include <linux/mutex.h> 32 + #include <linux/vmalloc.h> 33 + #include <asm/div64.h> 34 + #include <asm/unaligned.h> 35 + 36 + #include "dvb_frontend.h" 37 + #include "mxl5xx.h" 38 + #include "mxl5xx_regs.h" 39 + #include "mxl5xx_defs.h" 40 + 41 + #define BYTE0(v) ((v >> 0) & 0xff) 42 + #define BYTE1(v) ((v >> 8) & 0xff) 43 + #define BYTE2(v) ((v >> 16) & 0xff) 44 + #define BYTE3(v) ((v >> 24) & 0xff) 45 + 46 + LIST_HEAD(mxllist); 47 + 48 + struct mxl_base { 49 + struct list_head mxllist; 50 + struct list_head mxls; 51 + 52 + u8 adr; 53 + struct i2c_adapter *i2c; 54 + 55 + u32 count; 56 + u32 type; 57 + u32 sku_type; 58 + u32 chipversion; 59 + u32 clock; 60 + u32 fwversion; 61 + 62 + u8 *ts_map; 63 + u8 can_clkout; 64 + u8 chan_bond; 65 + u8 demod_num; 66 + u8 tuner_num; 67 + 68 + unsigned long next_tune; 69 + 70 + struct mutex i2c_lock; 71 + struct mutex status_lock; 72 + struct mutex tune_lock; 73 + 74 + u8 buf[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; 75 + 76 + u32 cmd_size; 77 + u8 cmd_data[MAX_CMD_DATA]; 78 + }; 79 + 80 + struct mxl { 81 + struct list_head mxl; 82 + 83 + struct mxl_base *base; 84 + struct dvb_frontend fe; 85 + struct device *i2cdev; 86 + u32 demod; 87 + u32 tuner; 88 + u32 tuner_in_use; 89 + u8 xbar[3]; 90 + 91 + unsigned long tune_time; 92 + }; 93 + 94 + static void convert_endian(u8 flag, u32 size, u8 *d) 95 + { 96 + u32 i; 97 + 98 + if (!flag) 99 + return; 100 + for (i = 0; i < (size & ~3); i += 4) { 101 + d[i + 0] ^= d[i + 3]; 102 + d[i + 3] ^= d[i + 0]; 103 + d[i + 0] ^= d[i + 3]; 104 + 105 + d[i + 1] ^= d[i + 2]; 106 + d[i + 2] ^= d[i + 1]; 107 + d[i + 1] ^= d[i + 2]; 108 + } 109 + 110 + switch (size & 3) { 111 + case 0: 112 + case 1: 113 + /* do nothing */ 114 + break; 115 + case 2: 116 + d[i + 0] ^= d[i + 1]; 117 + d[i + 1] ^= d[i + 0]; 118 + d[i + 0] ^= d[i + 1]; 119 + break; 120 + 121 + case 3: 122 + d[i + 0] ^= d[i + 2]; 123 + d[i + 2] ^= d[i + 0]; 124 + d[i + 0] ^= d[i + 2]; 125 + break; 126 + } 127 + 128 + } 129 + 130 + static int i2c_write(struct i2c_adapter *adap, u8 adr, 131 + u8 *data, u32 len) 132 + { 133 + struct i2c_msg msg = {.addr = adr, .flags = 0, 134 + .buf = data, .len = len}; 135 + 136 + return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; 137 + } 138 + 139 + static int i2c_read(struct i2c_adapter *adap, u8 adr, 140 + u8 *data, u32 len) 141 + { 142 + struct i2c_msg msg = {.addr = adr, .flags = I2C_M_RD, 143 + .buf = data, .len = len}; 144 + 145 + return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; 146 + } 147 + 148 + static int i2cread(struct mxl *state, u8 *data, int len) 149 + { 150 + return i2c_read(state->base->i2c, state->base->adr, data, len); 151 + } 152 + 153 + static int i2cwrite(struct mxl *state, u8 *data, int len) 154 + { 155 + return i2c_write(state->base->i2c, state->base->adr, data, len); 156 + } 157 + 158 + static int read_register_unlocked(struct mxl *state, u32 reg, u32 *val) 159 + { 160 + int stat; 161 + u8 data[MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE] = { 162 + MXL_HYDRA_PLID_REG_READ, 0x04, 163 + GET_BYTE(reg, 0), GET_BYTE(reg, 1), 164 + GET_BYTE(reg, 2), GET_BYTE(reg, 3), 165 + }; 166 + 167 + stat = i2cwrite(state, data, 168 + MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE); 169 + if (stat) 170 + dev_err(state->i2cdev, "i2c read error 1\n"); 171 + if (!stat) 172 + stat = i2cread(state, (u8 *) val, 173 + MXL_HYDRA_REG_SIZE_IN_BYTES); 174 + le32_to_cpus(val); 175 + if (stat) 176 + dev_err(state->i2cdev, "i2c read error 2\n"); 177 + return stat; 178 + } 179 + 180 + #define DMA_I2C_INTERRUPT_ADDR 0x8000011C 181 + #define DMA_INTR_PROT_WR_CMP 0x08 182 + 183 + static int send_command(struct mxl *state, u32 size, u8 *buf) 184 + { 185 + int stat; 186 + u32 val, count = 10; 187 + 188 + mutex_lock(&state->base->i2c_lock); 189 + if (state->base->fwversion > 0x02010109) { 190 + read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR, &val); 191 + if (DMA_INTR_PROT_WR_CMP & val) 192 + dev_info(state->i2cdev, "%s busy\n", __func__); 193 + while ((DMA_INTR_PROT_WR_CMP & val) && --count) { 194 + mutex_unlock(&state->base->i2c_lock); 195 + usleep_range(1000, 2000); 196 + mutex_lock(&state->base->i2c_lock); 197 + read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR, 198 + &val); 199 + } 200 + if (!count) { 201 + dev_info(state->i2cdev, "%s busy\n", __func__); 202 + mutex_unlock(&state->base->i2c_lock); 203 + return -EBUSY; 204 + } 205 + } 206 + stat = i2cwrite(state, buf, size); 207 + mutex_unlock(&state->base->i2c_lock); 208 + return stat; 209 + } 210 + 211 + static int write_register(struct mxl *state, u32 reg, u32 val) 212 + { 213 + int stat; 214 + u8 data[MXL_HYDRA_REG_WRITE_LEN] = { 215 + MXL_HYDRA_PLID_REG_WRITE, 0x08, 216 + BYTE0(reg), BYTE1(reg), BYTE2(reg), BYTE3(reg), 217 + BYTE0(val), BYTE1(val), BYTE2(val), BYTE3(val), 218 + }; 219 + mutex_lock(&state->base->i2c_lock); 220 + stat = i2cwrite(state, data, sizeof(data)); 221 + mutex_unlock(&state->base->i2c_lock); 222 + if (stat) 223 + dev_err(state->i2cdev, "i2c write error\n"); 224 + return stat; 225 + } 226 + 227 + static int write_firmware_block(struct mxl *state, 228 + u32 reg, u32 size, u8 *reg_data_ptr) 229 + { 230 + int stat; 231 + u8 *buf = state->base->buf; 232 + 233 + mutex_lock(&state->base->i2c_lock); 234 + buf[0] = MXL_HYDRA_PLID_REG_WRITE; 235 + buf[1] = size + 4; 236 + buf[2] = GET_BYTE(reg, 0); 237 + buf[3] = GET_BYTE(reg, 1); 238 + buf[4] = GET_BYTE(reg, 2); 239 + buf[5] = GET_BYTE(reg, 3); 240 + memcpy(&buf[6], reg_data_ptr, size); 241 + stat = i2cwrite(state, buf, 242 + MXL_HYDRA_I2C_HDR_SIZE + 243 + MXL_HYDRA_REG_SIZE_IN_BYTES + size); 244 + mutex_unlock(&state->base->i2c_lock); 245 + if (stat) 246 + dev_err(state->i2cdev, "fw block write failed\n"); 247 + return stat; 248 + } 249 + 250 + static int read_register(struct mxl *state, u32 reg, u32 *val) 251 + { 252 + int stat; 253 + u8 data[MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE] = { 254 + MXL_HYDRA_PLID_REG_READ, 0x04, 255 + GET_BYTE(reg, 0), GET_BYTE(reg, 1), 256 + GET_BYTE(reg, 2), GET_BYTE(reg, 3), 257 + }; 258 + 259 + mutex_lock(&state->base->i2c_lock); 260 + stat = i2cwrite(state, data, 261 + MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE); 262 + if (stat) 263 + dev_err(state->i2cdev, "i2c read error 1\n"); 264 + if (!stat) 265 + stat = i2cread(state, (u8 *) val, 266 + MXL_HYDRA_REG_SIZE_IN_BYTES); 267 + mutex_unlock(&state->base->i2c_lock); 268 + le32_to_cpus(val); 269 + if (stat) 270 + dev_err(state->i2cdev, "i2c read error 2\n"); 271 + return stat; 272 + } 273 + 274 + static int read_register_block(struct mxl *state, u32 reg, u32 size, u8 *data) 275 + { 276 + int stat; 277 + u8 *buf = state->base->buf; 278 + 279 + mutex_lock(&state->base->i2c_lock); 280 + 281 + buf[0] = MXL_HYDRA_PLID_REG_READ; 282 + buf[1] = size + 4; 283 + buf[2] = GET_BYTE(reg, 0); 284 + buf[3] = GET_BYTE(reg, 1); 285 + buf[4] = GET_BYTE(reg, 2); 286 + buf[5] = GET_BYTE(reg, 3); 287 + stat = i2cwrite(state, buf, 288 + MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES); 289 + if (!stat) { 290 + stat = i2cread(state, data, size); 291 + convert_endian(MXL_ENABLE_BIG_ENDIAN, size, data); 292 + } 293 + mutex_unlock(&state->base->i2c_lock); 294 + return stat; 295 + } 296 + 297 + static int read_by_mnemonic(struct mxl *state, 298 + u32 reg, u8 lsbloc, u8 numofbits, u32 *val) 299 + { 300 + u32 data = 0, mask = 0; 301 + int stat; 302 + 303 + stat = read_register(state, reg, &data); 304 + if (stat) 305 + return stat; 306 + mask = MXL_GET_REG_MASK_32(lsbloc, numofbits); 307 + data &= mask; 308 + data >>= lsbloc; 309 + *val = data; 310 + return 0; 311 + } 312 + 313 + 314 + static int update_by_mnemonic(struct mxl *state, 315 + u32 reg, u8 lsbloc, u8 numofbits, u32 val) 316 + { 317 + u32 data, mask; 318 + int stat; 319 + 320 + stat = read_register(state, reg, &data); 321 + if (stat) 322 + return stat; 323 + mask = MXL_GET_REG_MASK_32(lsbloc, numofbits); 324 + data = (data & ~mask) | ((val << lsbloc) & mask); 325 + stat = write_register(state, reg, data); 326 + return stat; 327 + } 328 + 329 + static int firmware_is_alive(struct mxl *state) 330 + { 331 + u32 hb0, hb1; 332 + 333 + if (read_register(state, HYDRA_HEAR_BEAT, &hb0)) 334 + return 0; 335 + msleep(20); 336 + if (read_register(state, HYDRA_HEAR_BEAT, &hb1)) 337 + return 0; 338 + if (hb1 == hb0) 339 + return 0; 340 + return 1; 341 + } 342 + 343 + static int init(struct dvb_frontend *fe) 344 + { 345 + struct dtv_frontend_properties *p = &fe->dtv_property_cache; 346 + 347 + /* init fe stats */ 348 + p->strength.len = 1; 349 + p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 350 + p->cnr.len = 1; 351 + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 352 + p->pre_bit_error.len = 1; 353 + p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 354 + p->pre_bit_count.len = 1; 355 + p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 356 + p->post_bit_error.len = 1; 357 + p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 358 + p->post_bit_count.len = 1; 359 + p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 360 + 361 + return 0; 362 + } 363 + 364 + static void release(struct dvb_frontend *fe) 365 + { 366 + struct mxl *state = fe->demodulator_priv; 367 + 368 + list_del(&state->mxl); 369 + /* Release one frontend, two more shall take its place! */ 370 + state->base->count--; 371 + if (state->base->count == 0) { 372 + list_del(&state->base->mxllist); 373 + kfree(state->base); 374 + } 375 + kfree(state); 376 + } 377 + 378 + static int get_algo(struct dvb_frontend *fe) 379 + { 380 + return DVBFE_ALGO_HW; 381 + } 382 + 383 + static int cfg_demod_abort_tune(struct mxl *state) 384 + { 385 + struct MXL_HYDRA_DEMOD_ABORT_TUNE_T abort_tune_cmd; 386 + u8 cmd_size = sizeof(abort_tune_cmd); 387 + u8 cmd_buff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; 388 + 389 + abort_tune_cmd.demod_id = state->demod; 390 + BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE, 391 + cmd_size, &abort_tune_cmd, cmd_buff); 392 + return send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE, 393 + &cmd_buff[0]); 394 + } 395 + 396 + static int send_master_cmd(struct dvb_frontend *fe, 397 + struct dvb_diseqc_master_cmd *cmd) 398 + { 399 + /*struct mxl *state = fe->demodulator_priv;*/ 400 + 401 + return 0; /*CfgDemodAbortTune(state);*/ 402 + } 403 + 404 + static int set_parameters(struct dvb_frontend *fe) 405 + { 406 + struct mxl *state = fe->demodulator_priv; 407 + struct dtv_frontend_properties *p = &fe->dtv_property_cache; 408 + struct MXL_HYDRA_DEMOD_PARAM_T demod_chan_cfg; 409 + u8 cmd_size = sizeof(demod_chan_cfg); 410 + u8 cmd_buff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; 411 + u32 srange = 10; 412 + int stat; 413 + 414 + if (p->frequency < 950000 || p->frequency > 2150000) 415 + return -EINVAL; 416 + if (p->symbol_rate < 1000000 || p->symbol_rate > 45000000) 417 + return -EINVAL; 418 + 419 + /* CfgDemodAbortTune(state); */ 420 + 421 + switch (p->delivery_system) { 422 + case SYS_DSS: 423 + demod_chan_cfg.standard = MXL_HYDRA_DSS; 424 + demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_AUTO; 425 + break; 426 + case SYS_DVBS: 427 + srange = p->symbol_rate / 1000000; 428 + if (srange > 10) 429 + srange = 10; 430 + demod_chan_cfg.standard = MXL_HYDRA_DVBS; 431 + demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_0_35; 432 + demod_chan_cfg.modulation_scheme = MXL_HYDRA_MOD_QPSK; 433 + demod_chan_cfg.pilots = MXL_HYDRA_PILOTS_OFF; 434 + break; 435 + case SYS_DVBS2: 436 + demod_chan_cfg.standard = MXL_HYDRA_DVBS2; 437 + demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_AUTO; 438 + demod_chan_cfg.modulation_scheme = MXL_HYDRA_MOD_AUTO; 439 + demod_chan_cfg.pilots = MXL_HYDRA_PILOTS_AUTO; 440 + /* cfg_scrambler(state); */ 441 + break; 442 + default: 443 + return -EINVAL; 444 + } 445 + demod_chan_cfg.tuner_index = state->tuner; 446 + demod_chan_cfg.demod_index = state->demod; 447 + demod_chan_cfg.frequency_in_hz = p->frequency * 1000; 448 + demod_chan_cfg.symbol_rate_in_hz = p->symbol_rate; 449 + demod_chan_cfg.max_carrier_offset_in_mhz = srange; 450 + demod_chan_cfg.spectrum_inversion = MXL_HYDRA_SPECTRUM_AUTO; 451 + demod_chan_cfg.fec_code_rate = MXL_HYDRA_FEC_AUTO; 452 + 453 + mutex_lock(&state->base->tune_lock); 454 + if (time_after(jiffies + msecs_to_jiffies(200), 455 + state->base->next_tune)) 456 + while (time_before(jiffies, state->base->next_tune)) 457 + usleep_range(10000, 11000); 458 + state->base->next_tune = jiffies + msecs_to_jiffies(100); 459 + state->tuner_in_use = state->tuner; 460 + BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_SET_PARAM_CMD, MXL_CMD_WRITE, 461 + cmd_size, &demod_chan_cfg, cmd_buff); 462 + stat = send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE, 463 + &cmd_buff[0]); 464 + mutex_unlock(&state->base->tune_lock); 465 + return stat; 466 + } 467 + 468 + static int enable_tuner(struct mxl *state, u32 tuner, u32 enable); 469 + 470 + static int sleep(struct dvb_frontend *fe) 471 + { 472 + struct mxl *state = fe->demodulator_priv; 473 + struct mxl *p; 474 + 475 + cfg_demod_abort_tune(state); 476 + if (state->tuner_in_use != 0xffffffff) { 477 + mutex_lock(&state->base->tune_lock); 478 + state->tuner_in_use = 0xffffffff; 479 + list_for_each_entry(p, &state->base->mxls, mxl) { 480 + if (p->tuner_in_use == state->tuner) 481 + break; 482 + } 483 + if (&p->mxl == &state->base->mxls) 484 + enable_tuner(state, state->tuner, 0); 485 + mutex_unlock(&state->base->tune_lock); 486 + } 487 + return 0; 488 + } 489 + 490 + static int read_snr(struct dvb_frontend *fe) 491 + { 492 + struct mxl *state = fe->demodulator_priv; 493 + int stat; 494 + u32 reg_data = 0; 495 + struct dtv_frontend_properties *p = &fe->dtv_property_cache; 496 + 497 + mutex_lock(&state->base->status_lock); 498 + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); 499 + stat = read_register(state, (HYDRA_DMD_SNR_ADDR_OFFSET + 500 + HYDRA_DMD_STATUS_OFFSET(state->demod)), 501 + &reg_data); 502 + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); 503 + mutex_unlock(&state->base->status_lock); 504 + 505 + p->cnr.stat[0].scale = FE_SCALE_DECIBEL; 506 + p->cnr.stat[0].svalue = (s16)reg_data * 10; 507 + 508 + return stat; 509 + } 510 + 511 + static int read_ber(struct dvb_frontend *fe) 512 + { 513 + struct mxl *state = fe->demodulator_priv; 514 + struct dtv_frontend_properties *p = &fe->dtv_property_cache; 515 + u32 reg[8]; 516 + 517 + mutex_lock(&state->base->status_lock); 518 + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); 519 + read_register_block(state, 520 + (HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET + 521 + HYDRA_DMD_STATUS_OFFSET(state->demod)), 522 + (4 * sizeof(u32)), 523 + (u8 *) &reg[0]); 524 + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); 525 + 526 + switch (p->delivery_system) { 527 + case SYS_DSS: 528 + case SYS_DVBS: 529 + p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; 530 + p->pre_bit_error.stat[0].uvalue = reg[2]; 531 + p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; 532 + p->pre_bit_count.stat[0].uvalue = reg[3]; 533 + break; 534 + default: 535 + break; 536 + } 537 + 538 + read_register_block(state, 539 + (HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET + 540 + HYDRA_DMD_STATUS_OFFSET(state->demod)), 541 + (7 * sizeof(u32)), 542 + (u8 *) &reg[0]); 543 + 544 + switch (p->delivery_system) { 545 + case SYS_DSS: 546 + case SYS_DVBS: 547 + p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 548 + p->post_bit_error.stat[0].uvalue = reg[5]; 549 + p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 550 + p->post_bit_count.stat[0].uvalue = reg[6]; 551 + break; 552 + case SYS_DVBS2: 553 + p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 554 + p->post_bit_error.stat[0].uvalue = reg[1]; 555 + p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 556 + p->post_bit_count.stat[0].uvalue = reg[2]; 557 + break; 558 + default: 559 + break; 560 + } 561 + 562 + mutex_unlock(&state->base->status_lock); 563 + 564 + return 0; 565 + } 566 + 567 + static int read_signal_strength(struct dvb_frontend *fe) 568 + { 569 + struct mxl *state = fe->demodulator_priv; 570 + struct dtv_frontend_properties *p = &fe->dtv_property_cache; 571 + int stat; 572 + u32 reg_data = 0; 573 + 574 + mutex_lock(&state->base->status_lock); 575 + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); 576 + stat = read_register(state, (HYDRA_DMD_STATUS_INPUT_POWER_ADDR + 577 + HYDRA_DMD_STATUS_OFFSET(state->demod)), 578 + &reg_data); 579 + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); 580 + mutex_unlock(&state->base->status_lock); 581 + 582 + p->strength.stat[0].scale = FE_SCALE_DECIBEL; 583 + p->strength.stat[0].svalue = (s16) reg_data * 10; /* fix scale */ 584 + 585 + return stat; 586 + } 587 + 588 + static int read_status(struct dvb_frontend *fe, enum fe_status *status) 589 + { 590 + struct mxl *state = fe->demodulator_priv; 591 + struct dtv_frontend_properties *p = &fe->dtv_property_cache; 592 + u32 reg_data = 0; 593 + 594 + mutex_lock(&state->base->status_lock); 595 + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); 596 + read_register(state, (HYDRA_DMD_LOCK_STATUS_ADDR_OFFSET + 597 + HYDRA_DMD_STATUS_OFFSET(state->demod)), 598 + &reg_data); 599 + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); 600 + mutex_unlock(&state->base->status_lock); 601 + 602 + *status = (reg_data == 1) ? 0x1f : 0; 603 + 604 + /* signal statistics */ 605 + 606 + /* signal strength is always available */ 607 + read_signal_strength(fe); 608 + 609 + if (*status & FE_HAS_CARRIER) 610 + read_snr(fe); 611 + else 612 + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 613 + 614 + if (*status & FE_HAS_SYNC) 615 + read_ber(fe); 616 + else { 617 + p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 618 + p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 619 + p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 620 + p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 621 + } 622 + 623 + return 0; 624 + } 625 + 626 + static int tune(struct dvb_frontend *fe, bool re_tune, 627 + unsigned int mode_flags, 628 + unsigned int *delay, enum fe_status *status) 629 + { 630 + struct mxl *state = fe->demodulator_priv; 631 + int r = 0; 632 + 633 + *delay = HZ / 2; 634 + if (re_tune) { 635 + r = set_parameters(fe); 636 + if (r) 637 + return r; 638 + state->tune_time = jiffies; 639 + return 0; 640 + } 641 + if (*status & FE_HAS_LOCK) 642 + return 0; 643 + 644 + r = read_status(fe, status); 645 + if (r) 646 + return r; 647 + 648 + return 0; 649 + } 650 + 651 + static enum fe_code_rate conv_fec(enum MXL_HYDRA_FEC_E fec) 652 + { 653 + enum fe_code_rate fec2fec[11] = { 654 + FEC_NONE, FEC_1_2, FEC_3_5, FEC_2_3, 655 + FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7, 656 + FEC_7_8, FEC_8_9, FEC_9_10 657 + }; 658 + 659 + if (fec > MXL_HYDRA_FEC_9_10) 660 + return FEC_NONE; 661 + return fec2fec[fec]; 662 + } 663 + 664 + static int get_frontend(struct dvb_frontend *fe, 665 + struct dtv_frontend_properties *p) 666 + { 667 + struct mxl *state = fe->demodulator_priv; 668 + u32 reg_data[MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE]; 669 + u32 freq; 670 + 671 + mutex_lock(&state->base->status_lock); 672 + HYDRA_DEMOD_STATUS_LOCK(state, state->demod); 673 + read_register_block(state, 674 + (HYDRA_DMD_STANDARD_ADDR_OFFSET + 675 + HYDRA_DMD_STATUS_OFFSET(state->demod)), 676 + (MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE * 4), /* 25 * 4 bytes */ 677 + (u8 *) &reg_data[0]); 678 + /* read demod channel parameters */ 679 + read_register_block(state, 680 + (HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR + 681 + HYDRA_DMD_STATUS_OFFSET(state->demod)), 682 + (4), /* 4 bytes */ 683 + (u8 *) &freq); 684 + HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); 685 + mutex_unlock(&state->base->status_lock); 686 + 687 + dev_dbg(state->i2cdev, "freq=%u delsys=%u srate=%u\n", 688 + freq * 1000, reg_data[DMD_STANDARD_ADDR], 689 + reg_data[DMD_SYMBOL_RATE_ADDR]); 690 + p->symbol_rate = reg_data[DMD_SYMBOL_RATE_ADDR]; 691 + p->frequency = freq; 692 + /* 693 + * p->delivery_system = 694 + * (MXL_HYDRA_BCAST_STD_E) regData[DMD_STANDARD_ADDR]; 695 + * p->inversion = 696 + * (MXL_HYDRA_SPECTRUM_E) regData[DMD_SPECTRUM_INVERSION_ADDR]; 697 + * freqSearchRangeKHz = 698 + * (regData[DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR]); 699 + */ 700 + 701 + p->fec_inner = conv_fec(reg_data[DMD_FEC_CODE_RATE_ADDR]); 702 + switch (p->delivery_system) { 703 + case SYS_DSS: 704 + break; 705 + case SYS_DVBS2: 706 + switch ((enum MXL_HYDRA_PILOTS_E) 707 + reg_data[DMD_DVBS2_PILOT_ON_OFF_ADDR]) { 708 + case MXL_HYDRA_PILOTS_OFF: 709 + p->pilot = PILOT_OFF; 710 + break; 711 + case MXL_HYDRA_PILOTS_ON: 712 + p->pilot = PILOT_ON; 713 + break; 714 + default: 715 + break; 716 + } 717 + case SYS_DVBS: 718 + switch ((enum MXL_HYDRA_MODULATION_E) 719 + reg_data[DMD_MODULATION_SCHEME_ADDR]) { 720 + case MXL_HYDRA_MOD_QPSK: 721 + p->modulation = QPSK; 722 + break; 723 + case MXL_HYDRA_MOD_8PSK: 724 + p->modulation = PSK_8; 725 + break; 726 + default: 727 + break; 728 + } 729 + switch ((enum MXL_HYDRA_ROLLOFF_E) 730 + reg_data[DMD_SPECTRUM_ROLL_OFF_ADDR]) { 731 + case MXL_HYDRA_ROLLOFF_0_20: 732 + p->rolloff = ROLLOFF_20; 733 + break; 734 + case MXL_HYDRA_ROLLOFF_0_35: 735 + p->rolloff = ROLLOFF_35; 736 + break; 737 + case MXL_HYDRA_ROLLOFF_0_25: 738 + p->rolloff = ROLLOFF_25; 739 + break; 740 + default: 741 + break; 742 + } 743 + break; 744 + default: 745 + return -EINVAL; 746 + } 747 + return 0; 748 + } 749 + 750 + static int set_input(struct dvb_frontend *fe, int input) 751 + { 752 + struct mxl *state = fe->demodulator_priv; 753 + 754 + state->tuner = input; 755 + return 0; 756 + } 757 + 758 + static struct dvb_frontend_ops mxl_ops = { 759 + .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, 760 + .info = { 761 + .name = "MaxLinear MxL5xx DVB-S/S2 tuner-demodulator", 762 + .frequency_min = 300000, 763 + .frequency_max = 2350000, 764 + .frequency_stepsize = 0, 765 + .frequency_tolerance = 0, 766 + .symbol_rate_min = 1000000, 767 + .symbol_rate_max = 45000000, 768 + .caps = FE_CAN_INVERSION_AUTO | 769 + FE_CAN_FEC_AUTO | 770 + FE_CAN_QPSK | 771 + FE_CAN_2G_MODULATION 772 + }, 773 + .init = init, 774 + .release = release, 775 + .get_frontend_algo = get_algo, 776 + .tune = tune, 777 + .read_status = read_status, 778 + .sleep = sleep, 779 + .get_frontend = get_frontend, 780 + .diseqc_send_master_cmd = send_master_cmd, 781 + }; 782 + 783 + static struct mxl_base *match_base(struct i2c_adapter *i2c, u8 adr) 784 + { 785 + struct mxl_base *p; 786 + 787 + list_for_each_entry(p, &mxllist, mxllist) 788 + if (p->i2c == i2c && p->adr == adr) 789 + return p; 790 + return NULL; 791 + } 792 + 793 + static void cfg_dev_xtal(struct mxl *state, u32 freq, u32 cap, u32 enable) 794 + { 795 + if (state->base->can_clkout || !enable) 796 + update_by_mnemonic(state, 0x90200054, 23, 1, enable); 797 + 798 + if (freq == 24000000) 799 + write_register(state, HYDRA_CRYSTAL_SETTING, 0); 800 + else 801 + write_register(state, HYDRA_CRYSTAL_SETTING, 1); 802 + 803 + write_register(state, HYDRA_CRYSTAL_CAP, cap); 804 + } 805 + 806 + static u32 get_big_endian(u8 num_of_bits, const u8 buf[]) 807 + { 808 + u32 ret_value = 0; 809 + 810 + switch (num_of_bits) { 811 + case 24: 812 + ret_value = (((u32) buf[0]) << 16) | 813 + (((u32) buf[1]) << 8) | buf[2]; 814 + break; 815 + case 32: 816 + ret_value = (((u32) buf[0]) << 24) | 817 + (((u32) buf[1]) << 16) | 818 + (((u32) buf[2]) << 8) | buf[3]; 819 + break; 820 + default: 821 + break; 822 + } 823 + 824 + return ret_value; 825 + } 826 + 827 + static int write_fw_segment(struct mxl *state, 828 + u32 mem_addr, u32 total_size, u8 *data_ptr) 829 + { 830 + int status; 831 + u32 data_count = 0; 832 + u32 size = 0; 833 + u32 orig_size = 0; 834 + u8 *w_buf_ptr = NULL; 835 + u32 block_size = ((MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH - 836 + (MXL_HYDRA_I2C_HDR_SIZE + 837 + MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4; 838 + u8 w_msg_buffer[MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH - 839 + (MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)]; 840 + 841 + do { 842 + size = orig_size = (((u32)(data_count + block_size)) > total_size) ? 843 + (total_size - data_count) : block_size; 844 + 845 + if (orig_size & 3) 846 + size = (orig_size + 4) & ~3; 847 + w_buf_ptr = &w_msg_buffer[0]; 848 + memset((void *) w_buf_ptr, 0, size); 849 + memcpy((void *) w_buf_ptr, (void *) data_ptr, orig_size); 850 + convert_endian(1, size, w_buf_ptr); 851 + status = write_firmware_block(state, mem_addr, size, w_buf_ptr); 852 + if (status) 853 + return status; 854 + data_count += size; 855 + mem_addr += size; 856 + data_ptr += size; 857 + } while (data_count < total_size); 858 + 859 + return status; 860 + } 861 + 862 + static int do_firmware_download(struct mxl *state, u8 *mbin_buffer_ptr, 863 + u32 mbin_buffer_size) 864 + 865 + { 866 + int status; 867 + u32 index = 0; 868 + u32 seg_length = 0; 869 + u32 seg_address = 0; 870 + struct MBIN_FILE_T *mbin_ptr = (struct MBIN_FILE_T *)mbin_buffer_ptr; 871 + struct MBIN_SEGMENT_T *segment_ptr; 872 + enum MXL_BOOL_E xcpu_fw_flag = MXL_FALSE; 873 + 874 + if (mbin_ptr->header.id != MBIN_FILE_HEADER_ID) { 875 + dev_err(state->i2cdev, "%s: Invalid file header ID (%c)\n", 876 + __func__, mbin_ptr->header.id); 877 + return -EINVAL; 878 + } 879 + status = write_register(state, FW_DL_SIGN_ADDR, 0); 880 + if (status) 881 + return status; 882 + segment_ptr = (struct MBIN_SEGMENT_T *) (&mbin_ptr->data[0]); 883 + for (index = 0; index < mbin_ptr->header.num_segments; index++) { 884 + if (segment_ptr->header.id != MBIN_SEGMENT_HEADER_ID) { 885 + dev_err(state->i2cdev, "%s: Invalid segment header ID (%c)\n", 886 + __func__, segment_ptr->header.id); 887 + return -EINVAL; 888 + } 889 + seg_length = get_big_endian(24, 890 + &(segment_ptr->header.len24[0])); 891 + seg_address = get_big_endian(32, 892 + &(segment_ptr->header.address[0])); 893 + 894 + if (state->base->type == MXL_HYDRA_DEVICE_568) { 895 + if ((((seg_address & 0x90760000) == 0x90760000) || 896 + ((seg_address & 0x90740000) == 0x90740000)) && 897 + (xcpu_fw_flag == MXL_FALSE)) { 898 + update_by_mnemonic(state, 0x8003003C, 0, 1, 1); 899 + msleep(200); 900 + write_register(state, 0x90720000, 0); 901 + usleep_range(10000, 11000); 902 + xcpu_fw_flag = MXL_TRUE; 903 + } 904 + status = write_fw_segment(state, seg_address, 905 + seg_length, 906 + (u8 *) segment_ptr->data); 907 + } else { 908 + if (((seg_address & 0x90760000) != 0x90760000) && 909 + ((seg_address & 0x90740000) != 0x90740000)) 910 + status = write_fw_segment(state, seg_address, 911 + seg_length, (u8 *) segment_ptr->data); 912 + } 913 + if (status) 914 + return status; 915 + segment_ptr = (struct MBIN_SEGMENT_T *) 916 + &(segment_ptr->data[((seg_length + 3) / 4) * 4]); 917 + } 918 + return status; 919 + } 920 + 921 + static int check_fw(struct mxl *state, u8 *mbin, u32 mbin_len) 922 + { 923 + struct MBIN_FILE_HEADER_T *fh = (struct MBIN_FILE_HEADER_T *) mbin; 924 + u32 flen = (fh->image_size24[0] << 16) | 925 + (fh->image_size24[1] << 8) | fh->image_size24[2]; 926 + u8 *fw, cs = 0; 927 + u32 i; 928 + 929 + if (fh->id != 'M' || fh->fmt_version != '1' || flen > 0x3FFF0) { 930 + dev_info(state->i2cdev, "Invalid FW Header\n"); 931 + return -1; 932 + } 933 + fw = mbin + sizeof(struct MBIN_FILE_HEADER_T); 934 + for (i = 0; i < flen; i += 1) 935 + cs += fw[i]; 936 + if (cs != fh->image_checksum) { 937 + dev_info(state->i2cdev, "Invalid FW Checksum\n"); 938 + return -1; 939 + } 940 + return 0; 941 + } 942 + 943 + static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len) 944 + { 945 + int status; 946 + u32 reg_data = 0; 947 + struct MXL_HYDRA_SKU_COMMAND_T dev_sku_cfg; 948 + u8 cmd_size = sizeof(struct MXL_HYDRA_SKU_COMMAND_T); 949 + u8 cmd_buff[sizeof(struct MXL_HYDRA_SKU_COMMAND_T) + 6]; 950 + 951 + if (check_fw(state, mbin, mbin_len)) 952 + return -1; 953 + 954 + /* put CPU into reset */ 955 + status = update_by_mnemonic(state, 0x8003003C, 0, 1, 0); 956 + if (status) 957 + return status; 958 + usleep_range(1000, 2000); 959 + 960 + /* Reset TX FIFO's, BBAND, XBAR */ 961 + status = write_register(state, HYDRA_RESET_TRANSPORT_FIFO_REG, 962 + HYDRA_RESET_TRANSPORT_FIFO_DATA); 963 + if (status) 964 + return status; 965 + status = write_register(state, HYDRA_RESET_BBAND_REG, 966 + HYDRA_RESET_BBAND_DATA); 967 + if (status) 968 + return status; 969 + status = write_register(state, HYDRA_RESET_XBAR_REG, 970 + HYDRA_RESET_XBAR_DATA); 971 + if (status) 972 + return status; 973 + 974 + /* Disable clock to Baseband, Wideband, SerDes, 975 + * Alias ext & Transport modules 976 + */ 977 + status = write_register(state, HYDRA_MODULES_CLK_2_REG, 978 + HYDRA_DISABLE_CLK_2); 979 + if (status) 980 + return status; 981 + /* Clear Software & Host interrupt status - (Clear on read) */ 982 + status = read_register(state, HYDRA_PRCM_ROOT_CLK_REG, &reg_data); 983 + if (status) 984 + return status; 985 + status = do_firmware_download(state, mbin, mbin_len); 986 + if (status) 987 + return status; 988 + 989 + if (state->base->type == MXL_HYDRA_DEVICE_568) { 990 + usleep_range(10000, 11000); 991 + 992 + /* bring XCPU out of reset */ 993 + status = write_register(state, 0x90720000, 1); 994 + if (status) 995 + return status; 996 + msleep(500); 997 + 998 + /* Enable XCPU UART message processing in MCPU */ 999 + status = write_register(state, 0x9076B510, 1); 1000 + if (status) 1001 + return status; 1002 + } else { 1003 + /* Bring CPU out of reset */ 1004 + status = update_by_mnemonic(state, 0x8003003C, 0, 1, 1); 1005 + if (status) 1006 + return status; 1007 + /* Wait until FW boots */ 1008 + msleep(150); 1009 + } 1010 + 1011 + /* Initialize XPT XBAR */ 1012 + status = write_register(state, XPT_DMD0_BASEADDR, 0x76543210); 1013 + if (status) 1014 + return status; 1015 + 1016 + if (!firmware_is_alive(state)) 1017 + return -1; 1018 + 1019 + dev_info(state->i2cdev, "Hydra FW alive. Hail!\n"); 1020 + 1021 + /* sometimes register values are wrong shortly 1022 + * after first heart beats 1023 + */ 1024 + msleep(50); 1025 + 1026 + dev_sku_cfg.sku_type = state->base->sku_type; 1027 + BUILD_HYDRA_CMD(MXL_HYDRA_DEV_CFG_SKU_CMD, MXL_CMD_WRITE, 1028 + cmd_size, &dev_sku_cfg, cmd_buff); 1029 + status = send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE, 1030 + &cmd_buff[0]); 1031 + 1032 + return status; 1033 + } 1034 + 1035 + static int cfg_ts_pad_mux(struct mxl *state, enum MXL_BOOL_E enable_serial_ts) 1036 + { 1037 + int status = 0; 1038 + u32 pad_mux_value = 0; 1039 + 1040 + if (enable_serial_ts == MXL_TRUE) { 1041 + pad_mux_value = 0; 1042 + if ((state->base->type == MXL_HYDRA_DEVICE_541) || 1043 + (state->base->type == MXL_HYDRA_DEVICE_541S)) 1044 + pad_mux_value = 2; 1045 + } else { 1046 + if ((state->base->type == MXL_HYDRA_DEVICE_581) || 1047 + (state->base->type == MXL_HYDRA_DEVICE_581S)) 1048 + pad_mux_value = 2; 1049 + else 1050 + pad_mux_value = 3; 1051 + } 1052 + 1053 + switch (state->base->type) { 1054 + case MXL_HYDRA_DEVICE_561: 1055 + case MXL_HYDRA_DEVICE_581: 1056 + case MXL_HYDRA_DEVICE_541: 1057 + case MXL_HYDRA_DEVICE_541S: 1058 + case MXL_HYDRA_DEVICE_561S: 1059 + case MXL_HYDRA_DEVICE_581S: 1060 + status |= update_by_mnemonic(state, 0x90000170, 24, 3, 1061 + pad_mux_value); 1062 + status |= update_by_mnemonic(state, 0x90000170, 28, 3, 1063 + pad_mux_value); 1064 + status |= update_by_mnemonic(state, 0x90000174, 0, 3, 1065 + pad_mux_value); 1066 + status |= update_by_mnemonic(state, 0x90000174, 4, 3, 1067 + pad_mux_value); 1068 + status |= update_by_mnemonic(state, 0x90000174, 8, 3, 1069 + pad_mux_value); 1070 + status |= update_by_mnemonic(state, 0x90000174, 12, 3, 1071 + pad_mux_value); 1072 + status |= update_by_mnemonic(state, 0x90000174, 16, 3, 1073 + pad_mux_value); 1074 + status |= update_by_mnemonic(state, 0x90000174, 20, 3, 1075 + pad_mux_value); 1076 + status |= update_by_mnemonic(state, 0x90000174, 24, 3, 1077 + pad_mux_value); 1078 + status |= update_by_mnemonic(state, 0x90000174, 28, 3, 1079 + pad_mux_value); 1080 + status |= update_by_mnemonic(state, 0x90000178, 0, 3, 1081 + pad_mux_value); 1082 + status |= update_by_mnemonic(state, 0x90000178, 4, 3, 1083 + pad_mux_value); 1084 + status |= update_by_mnemonic(state, 0x90000178, 8, 3, 1085 + pad_mux_value); 1086 + break; 1087 + 1088 + case MXL_HYDRA_DEVICE_544: 1089 + case MXL_HYDRA_DEVICE_542: 1090 + status |= update_by_mnemonic(state, 0x9000016C, 4, 3, 1); 1091 + status |= update_by_mnemonic(state, 0x9000016C, 8, 3, 0); 1092 + status |= update_by_mnemonic(state, 0x9000016C, 12, 3, 0); 1093 + status |= update_by_mnemonic(state, 0x9000016C, 16, 3, 0); 1094 + status |= update_by_mnemonic(state, 0x90000170, 0, 3, 0); 1095 + status |= update_by_mnemonic(state, 0x90000178, 12, 3, 1); 1096 + status |= update_by_mnemonic(state, 0x90000178, 16, 3, 1); 1097 + status |= update_by_mnemonic(state, 0x90000178, 20, 3, 1); 1098 + status |= update_by_mnemonic(state, 0x90000178, 24, 3, 1); 1099 + status |= update_by_mnemonic(state, 0x9000017C, 0, 3, 1); 1100 + status |= update_by_mnemonic(state, 0x9000017C, 4, 3, 1); 1101 + if (enable_serial_ts == MXL_ENABLE) { 1102 + status |= update_by_mnemonic(state, 1103 + 0x90000170, 4, 3, 0); 1104 + status |= update_by_mnemonic(state, 1105 + 0x90000170, 8, 3, 0); 1106 + status |= update_by_mnemonic(state, 1107 + 0x90000170, 12, 3, 0); 1108 + status |= update_by_mnemonic(state, 1109 + 0x90000170, 16, 3, 0); 1110 + status |= update_by_mnemonic(state, 1111 + 0x90000170, 20, 3, 1); 1112 + status |= update_by_mnemonic(state, 1113 + 0x90000170, 24, 3, 1); 1114 + status |= update_by_mnemonic(state, 1115 + 0x90000170, 28, 3, 2); 1116 + status |= update_by_mnemonic(state, 1117 + 0x90000174, 0, 3, 2); 1118 + status |= update_by_mnemonic(state, 1119 + 0x90000174, 4, 3, 2); 1120 + status |= update_by_mnemonic(state, 1121 + 0x90000174, 8, 3, 2); 1122 + status |= update_by_mnemonic(state, 1123 + 0x90000174, 12, 3, 2); 1124 + status |= update_by_mnemonic(state, 1125 + 0x90000174, 16, 3, 2); 1126 + status |= update_by_mnemonic(state, 1127 + 0x90000174, 20, 3, 2); 1128 + status |= update_by_mnemonic(state, 1129 + 0x90000174, 24, 3, 2); 1130 + status |= update_by_mnemonic(state, 1131 + 0x90000174, 28, 3, 2); 1132 + status |= update_by_mnemonic(state, 1133 + 0x90000178, 0, 3, 2); 1134 + status |= update_by_mnemonic(state, 1135 + 0x90000178, 4, 3, 2); 1136 + status |= update_by_mnemonic(state, 1137 + 0x90000178, 8, 3, 2); 1138 + } else { 1139 + status |= update_by_mnemonic(state, 1140 + 0x90000170, 4, 3, 3); 1141 + status |= update_by_mnemonic(state, 1142 + 0x90000170, 8, 3, 3); 1143 + status |= update_by_mnemonic(state, 1144 + 0x90000170, 12, 3, 3); 1145 + status |= update_by_mnemonic(state, 1146 + 0x90000170, 16, 3, 3); 1147 + status |= update_by_mnemonic(state, 1148 + 0x90000170, 20, 3, 3); 1149 + status |= update_by_mnemonic(state, 1150 + 0x90000170, 24, 3, 3); 1151 + status |= update_by_mnemonic(state, 1152 + 0x90000170, 28, 3, 3); 1153 + status |= update_by_mnemonic(state, 1154 + 0x90000174, 0, 3, 3); 1155 + status |= update_by_mnemonic(state, 1156 + 0x90000174, 4, 3, 3); 1157 + status |= update_by_mnemonic(state, 1158 + 0x90000174, 8, 3, 3); 1159 + status |= update_by_mnemonic(state, 1160 + 0x90000174, 12, 3, 3); 1161 + status |= update_by_mnemonic(state, 1162 + 0x90000174, 16, 3, 3); 1163 + status |= update_by_mnemonic(state, 1164 + 0x90000174, 20, 3, 1); 1165 + status |= update_by_mnemonic(state, 1166 + 0x90000174, 24, 3, 1); 1167 + status |= update_by_mnemonic(state, 1168 + 0x90000174, 28, 3, 1); 1169 + status |= update_by_mnemonic(state, 1170 + 0x90000178, 0, 3, 1); 1171 + status |= update_by_mnemonic(state, 1172 + 0x90000178, 4, 3, 1); 1173 + status |= update_by_mnemonic(state, 1174 + 0x90000178, 8, 3, 1); 1175 + } 1176 + break; 1177 + 1178 + case MXL_HYDRA_DEVICE_568: 1179 + if (enable_serial_ts == MXL_FALSE) { 1180 + status |= update_by_mnemonic(state, 1181 + 0x9000016C, 8, 3, 5); 1182 + status |= update_by_mnemonic(state, 1183 + 0x9000016C, 12, 3, 5); 1184 + status |= update_by_mnemonic(state, 1185 + 0x9000016C, 16, 3, 5); 1186 + status |= update_by_mnemonic(state, 1187 + 0x9000016C, 20, 3, 5); 1188 + status |= update_by_mnemonic(state, 1189 + 0x9000016C, 24, 3, 5); 1190 + status |= update_by_mnemonic(state, 1191 + 0x9000016C, 28, 3, 5); 1192 + status |= update_by_mnemonic(state, 1193 + 0x90000170, 0, 3, 5); 1194 + status |= update_by_mnemonic(state, 1195 + 0x90000170, 4, 3, 5); 1196 + status |= update_by_mnemonic(state, 1197 + 0x90000170, 8, 3, 5); 1198 + status |= update_by_mnemonic(state, 1199 + 0x90000170, 12, 3, 5); 1200 + status |= update_by_mnemonic(state, 1201 + 0x90000170, 16, 3, 5); 1202 + status |= update_by_mnemonic(state, 1203 + 0x90000170, 20, 3, 5); 1204 + 1205 + status |= update_by_mnemonic(state, 1206 + 0x90000170, 24, 3, pad_mux_value); 1207 + status |= update_by_mnemonic(state, 1208 + 0x90000174, 0, 3, pad_mux_value); 1209 + status |= update_by_mnemonic(state, 1210 + 0x90000174, 4, 3, pad_mux_value); 1211 + status |= update_by_mnemonic(state, 1212 + 0x90000174, 8, 3, pad_mux_value); 1213 + status |= update_by_mnemonic(state, 1214 + 0x90000174, 12, 3, pad_mux_value); 1215 + status |= update_by_mnemonic(state, 1216 + 0x90000174, 16, 3, pad_mux_value); 1217 + status |= update_by_mnemonic(state, 1218 + 0x90000174, 20, 3, pad_mux_value); 1219 + status |= update_by_mnemonic(state, 1220 + 0x90000174, 24, 3, pad_mux_value); 1221 + status |= update_by_mnemonic(state, 1222 + 0x90000174, 28, 3, pad_mux_value); 1223 + status |= update_by_mnemonic(state, 1224 + 0x90000178, 0, 3, pad_mux_value); 1225 + status |= update_by_mnemonic(state, 1226 + 0x90000178, 4, 3, pad_mux_value); 1227 + 1228 + status |= update_by_mnemonic(state, 1229 + 0x90000178, 8, 3, 5); 1230 + status |= update_by_mnemonic(state, 1231 + 0x90000178, 12, 3, 5); 1232 + status |= update_by_mnemonic(state, 1233 + 0x90000178, 16, 3, 5); 1234 + status |= update_by_mnemonic(state, 1235 + 0x90000178, 20, 3, 5); 1236 + status |= update_by_mnemonic(state, 1237 + 0x90000178, 24, 3, 5); 1238 + status |= update_by_mnemonic(state, 1239 + 0x90000178, 28, 3, 5); 1240 + status |= update_by_mnemonic(state, 1241 + 0x9000017C, 0, 3, 5); 1242 + status |= update_by_mnemonic(state, 1243 + 0x9000017C, 4, 3, 5); 1244 + } else { 1245 + status |= update_by_mnemonic(state, 1246 + 0x90000170, 4, 3, pad_mux_value); 1247 + status |= update_by_mnemonic(state, 1248 + 0x90000170, 8, 3, pad_mux_value); 1249 + status |= update_by_mnemonic(state, 1250 + 0x90000170, 12, 3, pad_mux_value); 1251 + status |= update_by_mnemonic(state, 1252 + 0x90000170, 16, 3, pad_mux_value); 1253 + status |= update_by_mnemonic(state, 1254 + 0x90000170, 20, 3, pad_mux_value); 1255 + status |= update_by_mnemonic(state, 1256 + 0x90000170, 24, 3, pad_mux_value); 1257 + status |= update_by_mnemonic(state, 1258 + 0x90000170, 28, 3, pad_mux_value); 1259 + status |= update_by_mnemonic(state, 1260 + 0x90000174, 0, 3, pad_mux_value); 1261 + status |= update_by_mnemonic(state, 1262 + 0x90000174, 4, 3, pad_mux_value); 1263 + status |= update_by_mnemonic(state, 1264 + 0x90000174, 8, 3, pad_mux_value); 1265 + status |= update_by_mnemonic(state, 1266 + 0x90000174, 12, 3, pad_mux_value); 1267 + } 1268 + break; 1269 + 1270 + 1271 + case MXL_HYDRA_DEVICE_584: 1272 + default: 1273 + status |= update_by_mnemonic(state, 1274 + 0x90000170, 4, 3, pad_mux_value); 1275 + status |= update_by_mnemonic(state, 1276 + 0x90000170, 8, 3, pad_mux_value); 1277 + status |= update_by_mnemonic(state, 1278 + 0x90000170, 12, 3, pad_mux_value); 1279 + status |= update_by_mnemonic(state, 1280 + 0x90000170, 16, 3, pad_mux_value); 1281 + status |= update_by_mnemonic(state, 1282 + 0x90000170, 20, 3, pad_mux_value); 1283 + status |= update_by_mnemonic(state, 1284 + 0x90000170, 24, 3, pad_mux_value); 1285 + status |= update_by_mnemonic(state, 1286 + 0x90000170, 28, 3, pad_mux_value); 1287 + status |= update_by_mnemonic(state, 1288 + 0x90000174, 0, 3, pad_mux_value); 1289 + status |= update_by_mnemonic(state, 1290 + 0x90000174, 4, 3, pad_mux_value); 1291 + status |= update_by_mnemonic(state, 1292 + 0x90000174, 8, 3, pad_mux_value); 1293 + status |= update_by_mnemonic(state, 1294 + 0x90000174, 12, 3, pad_mux_value); 1295 + break; 1296 + } 1297 + return status; 1298 + } 1299 + 1300 + static int set_drive_strength(struct mxl *state, 1301 + enum MXL_HYDRA_TS_DRIVE_STRENGTH_E ts_drive_strength) 1302 + { 1303 + int stat = 0; 1304 + u32 val; 1305 + 1306 + read_register(state, 0x90000194, &val); 1307 + dev_info(state->i2cdev, "DIGIO = %08x\n", val); 1308 + dev_info(state->i2cdev, "set drive_strength = %u\n", ts_drive_strength); 1309 + 1310 + 1311 + stat |= update_by_mnemonic(state, 0x90000194, 0, 3, ts_drive_strength); 1312 + stat |= update_by_mnemonic(state, 0x90000194, 20, 3, ts_drive_strength); 1313 + stat |= update_by_mnemonic(state, 0x90000194, 24, 3, ts_drive_strength); 1314 + stat |= update_by_mnemonic(state, 0x90000198, 12, 3, ts_drive_strength); 1315 + stat |= update_by_mnemonic(state, 0x90000198, 16, 3, ts_drive_strength); 1316 + stat |= update_by_mnemonic(state, 0x90000198, 20, 3, ts_drive_strength); 1317 + stat |= update_by_mnemonic(state, 0x90000198, 24, 3, ts_drive_strength); 1318 + stat |= update_by_mnemonic(state, 0x9000019C, 0, 3, ts_drive_strength); 1319 + stat |= update_by_mnemonic(state, 0x9000019C, 4, 3, ts_drive_strength); 1320 + stat |= update_by_mnemonic(state, 0x9000019C, 8, 3, ts_drive_strength); 1321 + stat |= update_by_mnemonic(state, 0x9000019C, 24, 3, ts_drive_strength); 1322 + stat |= update_by_mnemonic(state, 0x9000019C, 28, 3, ts_drive_strength); 1323 + stat |= update_by_mnemonic(state, 0x900001A0, 0, 3, ts_drive_strength); 1324 + stat |= update_by_mnemonic(state, 0x900001A0, 4, 3, ts_drive_strength); 1325 + stat |= update_by_mnemonic(state, 0x900001A0, 20, 3, ts_drive_strength); 1326 + stat |= update_by_mnemonic(state, 0x900001A0, 24, 3, ts_drive_strength); 1327 + stat |= update_by_mnemonic(state, 0x900001A0, 28, 3, ts_drive_strength); 1328 + 1329 + return stat; 1330 + } 1331 + 1332 + static int enable_tuner(struct mxl *state, u32 tuner, u32 enable) 1333 + { 1334 + int stat = 0; 1335 + struct MXL_HYDRA_TUNER_CMD ctrl_tuner_cmd; 1336 + u8 cmd_size = sizeof(ctrl_tuner_cmd); 1337 + u8 cmd_buff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; 1338 + u32 val, count = 10; 1339 + 1340 + ctrl_tuner_cmd.tuner_id = tuner; 1341 + ctrl_tuner_cmd.enable = enable; 1342 + BUILD_HYDRA_CMD(MXL_HYDRA_TUNER_ACTIVATE_CMD, MXL_CMD_WRITE, 1343 + cmd_size, &ctrl_tuner_cmd, cmd_buff); 1344 + stat = send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE, 1345 + &cmd_buff[0]); 1346 + if (stat) 1347 + return stat; 1348 + read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val); 1349 + while (--count && ((val >> tuner) & 1) != enable) { 1350 + msleep(20); 1351 + read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val); 1352 + } 1353 + if (!count) 1354 + return -1; 1355 + read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val); 1356 + dev_dbg(state->i2cdev, "tuner %u ready = %u\n", 1357 + tuner, (val >> tuner) & 1); 1358 + 1359 + return 0; 1360 + } 1361 + 1362 + 1363 + static int config_ts(struct mxl *state, enum MXL_HYDRA_DEMOD_ID_E demod_id, 1364 + struct MXL_HYDRA_MPEGOUT_PARAM_T *mpeg_out_param_ptr) 1365 + { 1366 + int status = 0; 1367 + u32 nco_count_min = 0; 1368 + u32 clk_type = 0; 1369 + 1370 + struct MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = { 1371 + {0x90700010, 8, 1}, {0x90700010, 9, 1}, 1372 + {0x90700010, 10, 1}, {0x90700010, 11, 1}, 1373 + {0x90700010, 12, 1}, {0x90700010, 13, 1}, 1374 + {0x90700010, 14, 1}, {0x90700010, 15, 1} }; 1375 + struct MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = { 1376 + {0x90700010, 16, 1}, {0x90700010, 17, 1}, 1377 + {0x90700010, 18, 1}, {0x90700010, 19, 1}, 1378 + {0x90700010, 20, 1}, {0x90700010, 21, 1}, 1379 + {0x90700010, 22, 1}, {0x90700010, 23, 1} }; 1380 + struct MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = { 1381 + {0x90700014, 0, 1}, {0x90700014, 1, 1}, 1382 + {0x90700014, 2, 1}, {0x90700014, 3, 1}, 1383 + {0x90700014, 4, 1}, {0x90700014, 5, 1}, 1384 + {0x90700014, 6, 1}, {0x90700014, 7, 1} }; 1385 + struct MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = { 1386 + {0x90700018, 0, 3}, {0x90700018, 4, 3}, 1387 + {0x90700018, 8, 3}, {0x90700018, 12, 3}, 1388 + {0x90700018, 16, 3}, {0x90700018, 20, 3}, 1389 + {0x90700018, 24, 3}, {0x90700018, 28, 3} }; 1390 + struct MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = { 1391 + {0x9070000C, 16, 1}, {0x9070000C, 17, 1}, 1392 + {0x9070000C, 18, 1}, {0x9070000C, 19, 1}, 1393 + {0x9070000C, 20, 1}, {0x9070000C, 21, 1}, 1394 + {0x9070000C, 22, 1}, {0x9070000C, 23, 1} }; 1395 + struct MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = { 1396 + {0x90700010, 0, 1}, {0x90700010, 1, 1}, 1397 + {0x90700010, 2, 1}, {0x90700010, 3, 1}, 1398 + {0x90700010, 4, 1}, {0x90700010, 5, 1}, 1399 + {0x90700010, 6, 1}, {0x90700010, 7, 1} }; 1400 + struct MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = { 1401 + {0x9070000C, 0, 1}, {0x9070000C, 1, 1}, 1402 + {0x9070000C, 2, 1}, {0x9070000C, 3, 1}, 1403 + {0x9070000C, 4, 1}, {0x9070000C, 5, 1}, 1404 + {0x9070000C, 6, 1}, {0x9070000C, 7, 1} }; 1405 + struct MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = { 1406 + {0x9070000C, 24, 1}, {0x9070000C, 25, 1}, 1407 + {0x9070000C, 26, 1}, {0x9070000C, 27, 1}, 1408 + {0x9070000C, 28, 1}, {0x9070000C, 29, 1}, 1409 + {0x9070000C, 30, 1}, {0x9070000C, 31, 1} }; 1410 + struct MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = { 1411 + {0x90700014, 8, 1}, {0x90700014, 9, 1}, 1412 + {0x90700014, 10, 1}, {0x90700014, 11, 1}, 1413 + {0x90700014, 12, 1}, {0x90700014, 13, 1}, 1414 + {0x90700014, 14, 1}, {0x90700014, 15, 1} }; 1415 + struct MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = { 1416 + {0x907001D4, 0, 1}, {0x907001D4, 1, 1}, 1417 + {0x907001D4, 2, 1}, {0x907001D4, 3, 1}, 1418 + {0x907001D4, 4, 1}, {0x907001D4, 5, 1}, 1419 + {0x907001D4, 6, 1}, {0x907001D4, 7, 1} }; 1420 + struct MXL_REG_FIELD_T xpt_nco_clock_rate[MXL_HYDRA_DEMOD_MAX] = { 1421 + {0x90700044, 16, 80}, {0x90700044, 16, 81}, 1422 + {0x90700044, 16, 82}, {0x90700044, 16, 83}, 1423 + {0x90700044, 16, 84}, {0x90700044, 16, 85}, 1424 + {0x90700044, 16, 86}, {0x90700044, 16, 87} }; 1425 + 1426 + demod_id = state->base->ts_map[demod_id]; 1427 + 1428 + if (mpeg_out_param_ptr->enable == MXL_ENABLE) { 1429 + if (mpeg_out_param_ptr->mpeg_mode == 1430 + MXL_HYDRA_MPEG_MODE_PARALLEL) { 1431 + } else { 1432 + cfg_ts_pad_mux(state, MXL_TRUE); 1433 + update_by_mnemonic(state, 1434 + 0x90700010, 27, 1, MXL_FALSE); 1435 + } 1436 + } 1437 + 1438 + nco_count_min = 1439 + (u32)(MXL_HYDRA_NCO_CLK / mpeg_out_param_ptr->max_mpeg_clk_rate); 1440 + 1441 + if (state->base->chipversion >= 2) { 1442 + status |= update_by_mnemonic(state, 1443 + xpt_nco_clock_rate[demod_id].reg_addr, /* Reg Addr */ 1444 + xpt_nco_clock_rate[demod_id].lsb_pos, /* LSB pos */ 1445 + xpt_nco_clock_rate[demod_id].num_of_bits, /* Num of bits */ 1446 + nco_count_min); /* Data */ 1447 + } else 1448 + update_by_mnemonic(state, 0x90700044, 16, 8, nco_count_min); 1449 + 1450 + if (mpeg_out_param_ptr->mpeg_clk_type == MXL_HYDRA_MPEG_CLK_CONTINUOUS) 1451 + clk_type = 1; 1452 + 1453 + if (mpeg_out_param_ptr->mpeg_mode < MXL_HYDRA_MPEG_MODE_PARALLEL) { 1454 + status |= update_by_mnemonic(state, 1455 + xpt_continuous_clock[demod_id].reg_addr, 1456 + xpt_continuous_clock[demod_id].lsb_pos, 1457 + xpt_continuous_clock[demod_id].num_of_bits, 1458 + clk_type); 1459 + } else 1460 + update_by_mnemonic(state, 0x907001D4, 8, 1, clk_type); 1461 + 1462 + status |= update_by_mnemonic(state, 1463 + xpt_sync_polarity[demod_id].reg_addr, 1464 + xpt_sync_polarity[demod_id].lsb_pos, 1465 + xpt_sync_polarity[demod_id].num_of_bits, 1466 + mpeg_out_param_ptr->mpeg_sync_pol); 1467 + 1468 + status |= update_by_mnemonic(state, 1469 + xpt_valid_polarity[demod_id].reg_addr, 1470 + xpt_valid_polarity[demod_id].lsb_pos, 1471 + xpt_valid_polarity[demod_id].num_of_bits, 1472 + mpeg_out_param_ptr->mpeg_valid_pol); 1473 + 1474 + status |= update_by_mnemonic(state, 1475 + xpt_clock_polarity[demod_id].reg_addr, 1476 + xpt_clock_polarity[demod_id].lsb_pos, 1477 + xpt_clock_polarity[demod_id].num_of_bits, 1478 + mpeg_out_param_ptr->mpeg_clk_pol); 1479 + 1480 + status |= update_by_mnemonic(state, 1481 + xpt_sync_byte[demod_id].reg_addr, 1482 + xpt_sync_byte[demod_id].lsb_pos, 1483 + xpt_sync_byte[demod_id].num_of_bits, 1484 + mpeg_out_param_ptr->mpeg_sync_pulse_width); 1485 + 1486 + status |= update_by_mnemonic(state, 1487 + xpt_ts_clock_phase[demod_id].reg_addr, 1488 + xpt_ts_clock_phase[demod_id].lsb_pos, 1489 + xpt_ts_clock_phase[demod_id].num_of_bits, 1490 + mpeg_out_param_ptr->mpeg_clk_phase); 1491 + 1492 + status |= update_by_mnemonic(state, 1493 + xpt_lsb_first[demod_id].reg_addr, 1494 + xpt_lsb_first[demod_id].lsb_pos, 1495 + xpt_lsb_first[demod_id].num_of_bits, 1496 + mpeg_out_param_ptr->lsb_or_msb_first); 1497 + 1498 + switch (mpeg_out_param_ptr->mpeg_error_indication) { 1499 + case MXL_HYDRA_MPEG_ERR_REPLACE_SYNC: 1500 + status |= update_by_mnemonic(state, 1501 + xpt_err_replace_sync[demod_id].reg_addr, 1502 + xpt_err_replace_sync[demod_id].lsb_pos, 1503 + xpt_err_replace_sync[demod_id].num_of_bits, 1504 + MXL_TRUE); 1505 + status |= update_by_mnemonic(state, 1506 + xpt_err_replace_valid[demod_id].reg_addr, 1507 + xpt_err_replace_valid[demod_id].lsb_pos, 1508 + xpt_err_replace_valid[demod_id].num_of_bits, 1509 + MXL_FALSE); 1510 + break; 1511 + 1512 + case MXL_HYDRA_MPEG_ERR_REPLACE_VALID: 1513 + status |= update_by_mnemonic(state, 1514 + xpt_err_replace_sync[demod_id].reg_addr, 1515 + xpt_err_replace_sync[demod_id].lsb_pos, 1516 + xpt_err_replace_sync[demod_id].num_of_bits, 1517 + MXL_FALSE); 1518 + 1519 + status |= update_by_mnemonic(state, 1520 + xpt_err_replace_valid[demod_id].reg_addr, 1521 + xpt_err_replace_valid[demod_id].lsb_pos, 1522 + xpt_err_replace_valid[demod_id].num_of_bits, 1523 + MXL_TRUE); 1524 + break; 1525 + 1526 + case MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED: 1527 + default: 1528 + status |= update_by_mnemonic(state, 1529 + xpt_err_replace_sync[demod_id].reg_addr, 1530 + xpt_err_replace_sync[demod_id].lsb_pos, 1531 + xpt_err_replace_sync[demod_id].num_of_bits, 1532 + MXL_FALSE); 1533 + 1534 + status |= update_by_mnemonic(state, 1535 + xpt_err_replace_valid[demod_id].reg_addr, 1536 + xpt_err_replace_valid[demod_id].lsb_pos, 1537 + xpt_err_replace_valid[demod_id].num_of_bits, 1538 + MXL_FALSE); 1539 + 1540 + break; 1541 + 1542 + } 1543 + 1544 + if (mpeg_out_param_ptr->mpeg_mode != MXL_HYDRA_MPEG_MODE_PARALLEL) { 1545 + status |= update_by_mnemonic(state, 1546 + xpt_enable_output[demod_id].reg_addr, 1547 + xpt_enable_output[demod_id].lsb_pos, 1548 + xpt_enable_output[demod_id].num_of_bits, 1549 + mpeg_out_param_ptr->enable); 1550 + } 1551 + return status; 1552 + } 1553 + 1554 + static int config_mux(struct mxl *state) 1555 + { 1556 + update_by_mnemonic(state, 0x9070000C, 0, 1, 0); 1557 + update_by_mnemonic(state, 0x9070000C, 1, 1, 0); 1558 + update_by_mnemonic(state, 0x9070000C, 2, 1, 0); 1559 + update_by_mnemonic(state, 0x9070000C, 3, 1, 0); 1560 + update_by_mnemonic(state, 0x9070000C, 4, 1, 0); 1561 + update_by_mnemonic(state, 0x9070000C, 5, 1, 0); 1562 + update_by_mnemonic(state, 0x9070000C, 6, 1, 0); 1563 + update_by_mnemonic(state, 0x9070000C, 7, 1, 0); 1564 + update_by_mnemonic(state, 0x90700008, 0, 2, 1); 1565 + update_by_mnemonic(state, 0x90700008, 2, 2, 1); 1566 + return 0; 1567 + } 1568 + 1569 + static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg) 1570 + { 1571 + int stat = 0; 1572 + u8 *buf; 1573 + 1574 + if (cfg->fw) 1575 + return firmware_download(state, cfg->fw, cfg->fw_len); 1576 + 1577 + if (!cfg->fw_read) 1578 + return -1; 1579 + 1580 + buf = vmalloc(0x40000); 1581 + if (!buf) 1582 + return -ENOMEM; 1583 + 1584 + cfg->fw_read(cfg->fw_priv, buf, 0x40000); 1585 + stat = firmware_download(state, buf, 0x40000); 1586 + vfree(buf); 1587 + 1588 + return stat; 1589 + } 1590 + 1591 + static int validate_sku(struct mxl *state) 1592 + { 1593 + u32 pad_mux_bond = 0, prcm_chip_id = 0, prcm_so_cid = 0; 1594 + int status; 1595 + u32 type = state->base->type; 1596 + 1597 + status = read_by_mnemonic(state, 0x90000190, 0, 3, &pad_mux_bond); 1598 + status |= read_by_mnemonic(state, 0x80030000, 0, 12, &prcm_chip_id); 1599 + status |= read_by_mnemonic(state, 0x80030004, 24, 8, &prcm_so_cid); 1600 + if (status) 1601 + return -1; 1602 + 1603 + dev_info(state->i2cdev, "padMuxBond=%08x, prcmChipId=%08x, prcmSoCId=%08x\n", 1604 + pad_mux_bond, prcm_chip_id, prcm_so_cid); 1605 + 1606 + if (prcm_chip_id != 0x560) { 1607 + switch (pad_mux_bond) { 1608 + case MXL_HYDRA_SKU_ID_581: 1609 + if (type == MXL_HYDRA_DEVICE_581) 1610 + return 0; 1611 + if (type == MXL_HYDRA_DEVICE_581S) { 1612 + state->base->type = MXL_HYDRA_DEVICE_581; 1613 + return 0; 1614 + } 1615 + break; 1616 + case MXL_HYDRA_SKU_ID_584: 1617 + if (type == MXL_HYDRA_DEVICE_584) 1618 + return 0; 1619 + break; 1620 + case MXL_HYDRA_SKU_ID_544: 1621 + if (type == MXL_HYDRA_DEVICE_544) 1622 + return 0; 1623 + if (type == MXL_HYDRA_DEVICE_542) 1624 + return 0; 1625 + break; 1626 + case MXL_HYDRA_SKU_ID_582: 1627 + if (type == MXL_HYDRA_DEVICE_582) 1628 + return 0; 1629 + break; 1630 + default: 1631 + return -1; 1632 + } 1633 + } else { 1634 + 1635 + } 1636 + return -1; 1637 + } 1638 + 1639 + static int get_fwinfo(struct mxl *state) 1640 + { 1641 + int status; 1642 + u32 val = 0; 1643 + 1644 + status = read_by_mnemonic(state, 0x90000190, 0, 3, &val); 1645 + if (status) 1646 + return status; 1647 + dev_info(state->i2cdev, "chipID=%08x\n", val); 1648 + 1649 + status = read_by_mnemonic(state, 0x80030004, 8, 8, &val); 1650 + if (status) 1651 + return status; 1652 + dev_info(state->i2cdev, "chipVer=%08x\n", val); 1653 + 1654 + status = read_register(state, HYDRA_FIRMWARE_VERSION, &val); 1655 + if (status) 1656 + return status; 1657 + dev_info(state->i2cdev, "FWVer=%08x\n", val); 1658 + 1659 + state->base->fwversion = val; 1660 + return status; 1661 + } 1662 + 1663 + 1664 + static u8 ts_map1_to_1[MXL_HYDRA_DEMOD_MAX] = { 1665 + MXL_HYDRA_DEMOD_ID_0, 1666 + MXL_HYDRA_DEMOD_ID_1, 1667 + MXL_HYDRA_DEMOD_ID_2, 1668 + MXL_HYDRA_DEMOD_ID_3, 1669 + MXL_HYDRA_DEMOD_ID_4, 1670 + MXL_HYDRA_DEMOD_ID_5, 1671 + MXL_HYDRA_DEMOD_ID_6, 1672 + MXL_HYDRA_DEMOD_ID_7, 1673 + }; 1674 + 1675 + static u8 ts_map54x[MXL_HYDRA_DEMOD_MAX] = { 1676 + MXL_HYDRA_DEMOD_ID_2, 1677 + MXL_HYDRA_DEMOD_ID_3, 1678 + MXL_HYDRA_DEMOD_ID_4, 1679 + MXL_HYDRA_DEMOD_ID_5, 1680 + MXL_HYDRA_DEMOD_MAX, 1681 + MXL_HYDRA_DEMOD_MAX, 1682 + MXL_HYDRA_DEMOD_MAX, 1683 + MXL_HYDRA_DEMOD_MAX, 1684 + }; 1685 + 1686 + static int probe(struct mxl *state, struct mxl5xx_cfg *cfg) 1687 + { 1688 + u32 chipver; 1689 + int fw, status, j; 1690 + struct MXL_HYDRA_MPEGOUT_PARAM_T mpeg_interface_cfg; 1691 + 1692 + state->base->ts_map = ts_map1_to_1; 1693 + 1694 + switch (state->base->type) { 1695 + case MXL_HYDRA_DEVICE_581: 1696 + case MXL_HYDRA_DEVICE_581S: 1697 + state->base->can_clkout = 1; 1698 + state->base->demod_num = 8; 1699 + state->base->tuner_num = 1; 1700 + state->base->sku_type = MXL_HYDRA_SKU_TYPE_581; 1701 + break; 1702 + case MXL_HYDRA_DEVICE_582: 1703 + state->base->can_clkout = 1; 1704 + state->base->demod_num = 8; 1705 + state->base->tuner_num = 3; 1706 + state->base->sku_type = MXL_HYDRA_SKU_TYPE_582; 1707 + break; 1708 + case MXL_HYDRA_DEVICE_585: 1709 + state->base->can_clkout = 0; 1710 + state->base->demod_num = 8; 1711 + state->base->tuner_num = 4; 1712 + state->base->sku_type = MXL_HYDRA_SKU_TYPE_585; 1713 + break; 1714 + case MXL_HYDRA_DEVICE_544: 1715 + state->base->can_clkout = 0; 1716 + state->base->demod_num = 4; 1717 + state->base->tuner_num = 4; 1718 + state->base->sku_type = MXL_HYDRA_SKU_TYPE_544; 1719 + state->base->ts_map = ts_map54x; 1720 + break; 1721 + case MXL_HYDRA_DEVICE_541: 1722 + case MXL_HYDRA_DEVICE_541S: 1723 + state->base->can_clkout = 0; 1724 + state->base->demod_num = 4; 1725 + state->base->tuner_num = 1; 1726 + state->base->sku_type = MXL_HYDRA_SKU_TYPE_541; 1727 + state->base->ts_map = ts_map54x; 1728 + break; 1729 + case MXL_HYDRA_DEVICE_561: 1730 + case MXL_HYDRA_DEVICE_561S: 1731 + state->base->can_clkout = 0; 1732 + state->base->demod_num = 6; 1733 + state->base->tuner_num = 1; 1734 + state->base->sku_type = MXL_HYDRA_SKU_TYPE_561; 1735 + break; 1736 + case MXL_HYDRA_DEVICE_568: 1737 + state->base->can_clkout = 0; 1738 + state->base->demod_num = 8; 1739 + state->base->tuner_num = 1; 1740 + state->base->chan_bond = 1; 1741 + state->base->sku_type = MXL_HYDRA_SKU_TYPE_568; 1742 + break; 1743 + case MXL_HYDRA_DEVICE_542: 1744 + state->base->can_clkout = 1; 1745 + state->base->demod_num = 4; 1746 + state->base->tuner_num = 3; 1747 + state->base->sku_type = MXL_HYDRA_SKU_TYPE_542; 1748 + state->base->ts_map = ts_map54x; 1749 + break; 1750 + case MXL_HYDRA_DEVICE_TEST: 1751 + case MXL_HYDRA_DEVICE_584: 1752 + default: 1753 + state->base->can_clkout = 0; 1754 + state->base->demod_num = 8; 1755 + state->base->tuner_num = 4; 1756 + state->base->sku_type = MXL_HYDRA_SKU_TYPE_584; 1757 + break; 1758 + } 1759 + 1760 + status = validate_sku(state); 1761 + if (status) 1762 + return status; 1763 + 1764 + update_by_mnemonic(state, 0x80030014, 9, 1, 1); 1765 + update_by_mnemonic(state, 0x8003003C, 12, 1, 1); 1766 + status = read_by_mnemonic(state, 0x80030000, 12, 4, &chipver); 1767 + if (status) 1768 + state->base->chipversion = 0; 1769 + else 1770 + state->base->chipversion = (chipver == 2) ? 2 : 1; 1771 + dev_info(state->i2cdev, "Hydra chip version %u\n", 1772 + state->base->chipversion); 1773 + 1774 + cfg_dev_xtal(state, cfg->clk, cfg->cap, 0); 1775 + 1776 + fw = firmware_is_alive(state); 1777 + if (!fw) { 1778 + status = load_fw(state, cfg); 1779 + if (status) 1780 + return status; 1781 + } 1782 + get_fwinfo(state); 1783 + 1784 + config_mux(state); 1785 + mpeg_interface_cfg.enable = MXL_ENABLE; 1786 + mpeg_interface_cfg.lsb_or_msb_first = MXL_HYDRA_MPEG_SERIAL_MSB_1ST; 1787 + /* supports only (0-104&139)MHz */ 1788 + if (cfg->ts_clk) 1789 + mpeg_interface_cfg.max_mpeg_clk_rate = cfg->ts_clk; 1790 + else 1791 + mpeg_interface_cfg.max_mpeg_clk_rate = 69; /* 139; */ 1792 + mpeg_interface_cfg.mpeg_clk_phase = MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_0_DEG; 1793 + mpeg_interface_cfg.mpeg_clk_pol = MXL_HYDRA_MPEG_CLK_IN_PHASE; 1794 + /* MXL_HYDRA_MPEG_CLK_GAPPED; */ 1795 + mpeg_interface_cfg.mpeg_clk_type = MXL_HYDRA_MPEG_CLK_CONTINUOUS; 1796 + mpeg_interface_cfg.mpeg_error_indication = 1797 + MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED; 1798 + mpeg_interface_cfg.mpeg_mode = MXL_HYDRA_MPEG_MODE_SERIAL_3_WIRE; 1799 + mpeg_interface_cfg.mpeg_sync_pol = MXL_HYDRA_MPEG_ACTIVE_HIGH; 1800 + mpeg_interface_cfg.mpeg_sync_pulse_width = MXL_HYDRA_MPEG_SYNC_WIDTH_BIT; 1801 + mpeg_interface_cfg.mpeg_valid_pol = MXL_HYDRA_MPEG_ACTIVE_HIGH; 1802 + 1803 + for (j = 0; j < state->base->demod_num; j++) { 1804 + status = config_ts(state, (enum MXL_HYDRA_DEMOD_ID_E) j, 1805 + &mpeg_interface_cfg); 1806 + if (status) 1807 + return status; 1808 + } 1809 + set_drive_strength(state, 1); 1810 + return 0; 1811 + } 1812 + 1813 + struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, 1814 + struct mxl5xx_cfg *cfg, u32 demod, u32 tuner, 1815 + int (**fn_set_input)(struct dvb_frontend *, int)) 1816 + { 1817 + struct mxl *state; 1818 + struct mxl_base *base; 1819 + 1820 + state = kzalloc(sizeof(struct mxl), GFP_KERNEL); 1821 + if (!state) 1822 + return NULL; 1823 + 1824 + state->demod = demod; 1825 + state->tuner = tuner; 1826 + state->tuner_in_use = 0xffffffff; 1827 + state->i2cdev = &i2c->dev; 1828 + 1829 + base = match_base(i2c, cfg->adr); 1830 + if (base) { 1831 + base->count++; 1832 + if (base->count > base->demod_num) 1833 + goto fail; 1834 + state->base = base; 1835 + } else { 1836 + base = kzalloc(sizeof(struct mxl_base), GFP_KERNEL); 1837 + if (!base) 1838 + goto fail; 1839 + base->i2c = i2c; 1840 + base->adr = cfg->adr; 1841 + base->type = cfg->type; 1842 + base->count = 1; 1843 + mutex_init(&base->i2c_lock); 1844 + mutex_init(&base->status_lock); 1845 + mutex_init(&base->tune_lock); 1846 + INIT_LIST_HEAD(&base->mxls); 1847 + 1848 + state->base = base; 1849 + if (probe(state, cfg) < 0) { 1850 + kfree(base); 1851 + goto fail; 1852 + } 1853 + list_add(&base->mxllist, &mxllist); 1854 + } 1855 + state->fe.ops = mxl_ops; 1856 + state->xbar[0] = 4; 1857 + state->xbar[1] = demod; 1858 + state->xbar[2] = 8; 1859 + state->fe.demodulator_priv = state; 1860 + *fn_set_input = set_input; 1861 + 1862 + list_add(&state->mxl, &base->mxls); 1863 + return &state->fe; 1864 + 1865 + fail: 1866 + kfree(state); 1867 + return NULL; 1868 + } 1869 + EXPORT_SYMBOL_GPL(mxl5xx_attach); 1870 + 1871 + MODULE_DESCRIPTION("MaxLinear MxL5xx DVB-S/S2 tuner-demodulator driver"); 1872 + MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR"); 1873 + MODULE_LICENSE("GPL");
+41
drivers/media/dvb-frontends/mxl5xx.h
··· 1 + #ifndef _MXL5XX_H_ 2 + #define _MXL5XX_H_ 3 + 4 + #include <linux/types.h> 5 + #include <linux/i2c.h> 6 + 7 + #include "dvb_frontend.h" 8 + 9 + struct mxl5xx_cfg { 10 + u8 adr; 11 + u8 type; 12 + u32 cap; 13 + u32 clk; 14 + u32 ts_clk; 15 + 16 + u8 *fw; 17 + u32 fw_len; 18 + 19 + int (*fw_read)(void *priv, u8 *buf, u32 len); 20 + void *fw_priv; 21 + }; 22 + 23 + #if IS_REACHABLE(CONFIG_DVB_MXL5XX) 24 + 25 + extern struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, 26 + struct mxl5xx_cfg *cfg, u32 demod, u32 tuner, 27 + int (**fn_set_input)(struct dvb_frontend *, int)); 28 + 29 + #else 30 + 31 + static inline struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, 32 + struct mxl5xx_cfg *cfg, u32 demod, u32 tuner, 33 + int (**fn_set_input)(struct dvb_frontend *, int)) 34 + { 35 + pr_warn("%s: driver disabled by Kconfig\n", __func__); 36 + return NULL; 37 + } 38 + 39 + #endif /* CONFIG_DVB_MXL5XX */ 40 + 41 + #endif /* _MXL5XX_H_ */
+731
drivers/media/dvb-frontends/mxl5xx_defs.h
··· 1 + /* 2 + * Defines for the Maxlinear MX58x family of tuners/demods 3 + * 4 + * Copyright (C) 2014 Digital Devices GmbH 5 + * 6 + * based on code: 7 + * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved 8 + * which was released under GPL V2 9 + * 10 + * This program is free software; you can redistribute it and/or 11 + * modify it under the terms of the GNU General Public License 12 + * version 2, as published by the Free Software Foundation. 13 + */ 14 + 15 + enum MXL_BOOL_E { 16 + MXL_DISABLE = 0, 17 + MXL_ENABLE = 1, 18 + 19 + MXL_FALSE = 0, 20 + MXL_TRUE = 1, 21 + 22 + MXL_INVALID = 0, 23 + MXL_VALID = 1, 24 + 25 + MXL_NO = 0, 26 + MXL_YES = 1, 27 + 28 + MXL_OFF = 0, 29 + MXL_ON = 1 30 + }; 31 + 32 + /* Firmware-Host Command IDs */ 33 + enum MXL_HYDRA_HOST_CMD_ID_E { 34 + /* --Device command IDs-- */ 35 + MXL_HYDRA_DEV_NO_OP_CMD = 0, /* No OP */ 36 + 37 + MXL_HYDRA_DEV_SET_POWER_MODE_CMD = 1, 38 + MXL_HYDRA_DEV_SET_OVERWRITE_DEF_CMD = 2, 39 + 40 + /* Host-used CMD, not used by firmware */ 41 + MXL_HYDRA_DEV_FIRMWARE_DOWNLOAD_CMD = 3, 42 + 43 + /* Additional CONTROL types from DTV */ 44 + MXL_HYDRA_DEV_SET_BROADCAST_PID_STB_ID_CMD = 4, 45 + MXL_HYDRA_DEV_GET_PMM_SLEEP_CMD = 5, 46 + 47 + /* --Tuner command IDs-- */ 48 + MXL_HYDRA_TUNER_TUNE_CMD = 6, 49 + MXL_HYDRA_TUNER_GET_STATUS_CMD = 7, 50 + 51 + /* --Demod command IDs-- */ 52 + MXL_HYDRA_DEMOD_SET_PARAM_CMD = 8, 53 + MXL_HYDRA_DEMOD_GET_STATUS_CMD = 9, 54 + 55 + MXL_HYDRA_DEMOD_RESET_FEC_COUNTER_CMD = 10, 56 + 57 + MXL_HYDRA_DEMOD_SET_PKT_NUM_CMD = 11, 58 + 59 + MXL_HYDRA_DEMOD_SET_IQ_SOURCE_CMD = 12, 60 + MXL_HYDRA_DEMOD_GET_IQ_DATA_CMD = 13, 61 + 62 + MXL_HYDRA_DEMOD_GET_M68HC05_VER_CMD = 14, 63 + 64 + MXL_HYDRA_DEMOD_SET_ERROR_COUNTER_MODE_CMD = 15, 65 + 66 + /* --- ABORT channel tune */ 67 + MXL_HYDRA_ABORT_TUNE_CMD = 16, /* Abort current tune command. */ 68 + 69 + /* --SWM/FSK command IDs-- */ 70 + MXL_HYDRA_FSK_RESET_CMD = 17, 71 + MXL_HYDRA_FSK_MSG_CMD = 18, 72 + MXL_HYDRA_FSK_SET_OP_MODE_CMD = 19, 73 + 74 + /* --DiSeqC command IDs-- */ 75 + MXL_HYDRA_DISEQC_MSG_CMD = 20, 76 + MXL_HYDRA_DISEQC_COPY_MSG_TO_MAILBOX = 21, 77 + MXL_HYDRA_DISEQC_CFG_MSG_CMD = 22, 78 + 79 + /* --- FFT Debug Command IDs-- */ 80 + MXL_HYDRA_REQ_FFT_SPECTRUM_CMD = 23, 81 + 82 + /* -- Demod scramblle code */ 83 + MXL_HYDRA_DEMOD_SCRAMBLE_CODE_CMD = 24, 84 + 85 + /* ---For host to know how many commands in total */ 86 + MXL_HYDRA_LAST_HOST_CMD = 25, 87 + 88 + MXL_HYDRA_DEMOD_INTR_TYPE_CMD = 47, 89 + MXL_HYDRA_DEV_INTR_CLEAR_CMD = 48, 90 + MXL_HYDRA_TUNER_SPECTRUM_REQ_CMD = 53, 91 + MXL_HYDRA_TUNER_ACTIVATE_CMD = 55, 92 + MXL_HYDRA_DEV_CFG_POWER_MODE_CMD = 56, 93 + MXL_HYDRA_DEV_XTAL_CAP_CMD = 57, 94 + MXL_HYDRA_DEV_CFG_SKU_CMD = 58, 95 + MXL_HYDRA_TUNER_SPECTRUM_MIN_GAIN_CMD = 59, 96 + MXL_HYDRA_DISEQC_CONT_TONE_CFG = 60, 97 + MXL_HYDRA_DEV_RF_WAKE_UP_CMD = 61, 98 + MXL_HYDRA_DEMOD_CFG_EQ_CTRL_PARAM_CMD = 62, 99 + MXL_HYDRA_DEMOD_FREQ_OFFSET_SEARCH_RANGE_CMD = 63, 100 + MXL_HYDRA_DEV_REQ_PWR_FROM_ADCRSSI_CMD = 64, 101 + 102 + MXL_XCPU_PID_FLT_CFG_CMD = 65, 103 + MXL_XCPU_SHMEM_TEST_CMD = 66, 104 + MXL_XCPU_ABORT_TUNE_CMD = 67, 105 + MXL_XCPU_CHAN_TUNE_CMD = 68, 106 + MXL_XCPU_FLT_BOND_HDRS_CMD = 69, 107 + 108 + MXL_HYDRA_DEV_BROADCAST_WAKE_UP_CMD = 70, 109 + MXL_HYDRA_FSK_CFG_FSK_FREQ_CMD = 71, 110 + MXL_HYDRA_FSK_POWER_DOWN_CMD = 72, 111 + MXL_XCPU_CLEAR_CB_STATS_CMD = 73, 112 + MXL_XCPU_CHAN_BOND_RESTART_CMD = 74 113 + }; 114 + 115 + #define MXL_ENABLE_BIG_ENDIAN (0) 116 + 117 + #define MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH 248 118 + 119 + #define MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN (248) 120 + 121 + #define MXL_HYDRA_CAP_MIN 10 122 + #define MXL_HYDRA_CAP_MAX 33 123 + 124 + #define MXL_HYDRA_PLID_REG_READ 0xFB /* Read register PLID */ 125 + #define MXL_HYDRA_PLID_REG_WRITE 0xFC /* Write register PLID */ 126 + 127 + #define MXL_HYDRA_PLID_CMD_READ 0xFD /* Command Read PLID */ 128 + #define MXL_HYDRA_PLID_CMD_WRITE 0xFE /* Command Write PLID */ 129 + 130 + #define MXL_HYDRA_REG_SIZE_IN_BYTES 4 /* Hydra register size in bytes */ 131 + #define MXL_HYDRA_I2C_HDR_SIZE (2 * sizeof(u8)) /* PLID + LEN(0xFF) */ 132 + #define MXL_HYDRA_CMD_HEADER_SIZE (MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE) 133 + 134 + #define MXL_HYDRA_SKU_ID_581 0 135 + #define MXL_HYDRA_SKU_ID_584 1 136 + #define MXL_HYDRA_SKU_ID_585 2 137 + #define MXL_HYDRA_SKU_ID_544 3 138 + #define MXL_HYDRA_SKU_ID_561 4 139 + #define MXL_HYDRA_SKU_ID_582 5 140 + #define MXL_HYDRA_SKU_ID_568 6 141 + 142 + /* macro for register write data buffer size 143 + * (PLID + LEN (0xFF) + RegAddr + RegData) 144 + */ 145 + #define MXL_HYDRA_REG_WRITE_LEN (MXL_HYDRA_I2C_HDR_SIZE + (2 * MXL_HYDRA_REG_SIZE_IN_BYTES)) 146 + 147 + /* macro to extract a single byte from 4-byte(32-bit) data */ 148 + #define GET_BYTE(x, n) (((x) >> (8*(n))) & 0xFF) 149 + 150 + #define MAX_CMD_DATA 512 151 + 152 + #define MXL_GET_REG_MASK_32(lsb_loc, num_of_bits) ((0xFFFFFFFF >> (32 - (num_of_bits))) << (lsb_loc)) 153 + 154 + #define FW_DL_SIGN (0xDEADBEEF) 155 + 156 + #define MBIN_FORMAT_VERSION '1' 157 + #define MBIN_FILE_HEADER_ID 'M' 158 + #define MBIN_SEGMENT_HEADER_ID 'S' 159 + #define MBIN_MAX_FILE_LENGTH (1<<23) 160 + 161 + struct MBIN_FILE_HEADER_T { 162 + u8 id; 163 + u8 fmt_version; 164 + u8 header_len; 165 + u8 num_segments; 166 + u8 entry_address[4]; 167 + u8 image_size24[3]; 168 + u8 image_checksum; 169 + u8 reserved[4]; 170 + }; 171 + 172 + struct MBIN_FILE_T { 173 + struct MBIN_FILE_HEADER_T header; 174 + u8 data[1]; 175 + }; 176 + 177 + struct MBIN_SEGMENT_HEADER_T { 178 + u8 id; 179 + u8 len24[3]; 180 + u8 address[4]; 181 + }; 182 + 183 + struct MBIN_SEGMENT_T { 184 + struct MBIN_SEGMENT_HEADER_T header; 185 + u8 data[1]; 186 + }; 187 + 188 + enum MXL_CMD_TYPE_E { MXL_CMD_WRITE = 0, MXL_CMD_READ }; 189 + 190 + #define BUILD_HYDRA_CMD(cmd_id, req_type, size, data_ptr, cmd_buff) \ 191 + do { \ 192 + cmd_buff[0] = ((req_type == MXL_CMD_WRITE) ? MXL_HYDRA_PLID_CMD_WRITE : MXL_HYDRA_PLID_CMD_READ); \ 193 + cmd_buff[1] = (size > 251) ? 0xff : (u8) (size + 4); \ 194 + cmd_buff[2] = size; \ 195 + cmd_buff[3] = cmd_id; \ 196 + cmd_buff[4] = 0x00; \ 197 + cmd_buff[5] = 0x00; \ 198 + convert_endian(MXL_ENABLE_BIG_ENDIAN, size, (u8 *)data_ptr); \ 199 + memcpy((void *)&cmd_buff[6], data_ptr, size); \ 200 + } while (0) 201 + 202 + struct MXL_REG_FIELD_T { 203 + u32 reg_addr; 204 + u8 lsb_pos; 205 + u8 num_of_bits; 206 + }; 207 + 208 + struct MXL_DEV_CMD_DATA_T { 209 + u32 data_size; 210 + u8 data[MAX_CMD_DATA]; 211 + }; 212 + 213 + enum MXL_HYDRA_SKU_TYPE_E { 214 + MXL_HYDRA_SKU_TYPE_MIN = 0x00, 215 + MXL_HYDRA_SKU_TYPE_581 = 0x00, 216 + MXL_HYDRA_SKU_TYPE_584 = 0x01, 217 + MXL_HYDRA_SKU_TYPE_585 = 0x02, 218 + MXL_HYDRA_SKU_TYPE_544 = 0x03, 219 + MXL_HYDRA_SKU_TYPE_561 = 0x04, 220 + MXL_HYDRA_SKU_TYPE_5XX = 0x05, 221 + MXL_HYDRA_SKU_TYPE_5YY = 0x06, 222 + MXL_HYDRA_SKU_TYPE_511 = 0x07, 223 + MXL_HYDRA_SKU_TYPE_561_DE = 0x08, 224 + MXL_HYDRA_SKU_TYPE_582 = 0x09, 225 + MXL_HYDRA_SKU_TYPE_541 = 0x0A, 226 + MXL_HYDRA_SKU_TYPE_568 = 0x0B, 227 + MXL_HYDRA_SKU_TYPE_542 = 0x0C, 228 + MXL_HYDRA_SKU_TYPE_MAX = 0x0D, 229 + }; 230 + 231 + struct MXL_HYDRA_SKU_COMMAND_T { 232 + enum MXL_HYDRA_SKU_TYPE_E sku_type; 233 + }; 234 + 235 + enum MXL_HYDRA_DEMOD_ID_E { 236 + MXL_HYDRA_DEMOD_ID_0 = 0, 237 + MXL_HYDRA_DEMOD_ID_1, 238 + MXL_HYDRA_DEMOD_ID_2, 239 + MXL_HYDRA_DEMOD_ID_3, 240 + MXL_HYDRA_DEMOD_ID_4, 241 + MXL_HYDRA_DEMOD_ID_5, 242 + MXL_HYDRA_DEMOD_ID_6, 243 + MXL_HYDRA_DEMOD_ID_7, 244 + MXL_HYDRA_DEMOD_MAX 245 + }; 246 + 247 + #define MXL_DEMOD_SCRAMBLE_SEQ_LEN 12 248 + 249 + #define MAX_STEP_SIZE_24_XTAL_102_05_KHZ 195 250 + #define MAX_STEP_SIZE_24_XTAL_204_10_KHZ 215 251 + #define MAX_STEP_SIZE_24_XTAL_306_15_KHZ 203 252 + #define MAX_STEP_SIZE_24_XTAL_408_20_KHZ 177 253 + 254 + #define MAX_STEP_SIZE_27_XTAL_102_05_KHZ 195 255 + #define MAX_STEP_SIZE_27_XTAL_204_10_KHZ 215 256 + #define MAX_STEP_SIZE_27_XTAL_306_15_KHZ 203 257 + #define MAX_STEP_SIZE_27_XTAL_408_20_KHZ 177 258 + 259 + #define MXL_HYDRA_SPECTRUM_MIN_FREQ_KHZ 300000 260 + #define MXL_HYDRA_SPECTRUM_MAX_FREQ_KHZ 2350000 261 + 262 + enum MXL_DEMOD_CHAN_PARAMS_OFFSET_E { 263 + DMD_STANDARD_ADDR = 0, 264 + DMD_SPECTRUM_INVERSION_ADDR, 265 + DMD_SPECTRUM_ROLL_OFF_ADDR, 266 + DMD_SYMBOL_RATE_ADDR, 267 + DMD_MODULATION_SCHEME_ADDR, 268 + DMD_FEC_CODE_RATE_ADDR, 269 + DMD_SNR_ADDR, 270 + DMD_FREQ_OFFSET_ADDR, 271 + DMD_CTL_FREQ_OFFSET_ADDR, 272 + DMD_STR_FREQ_OFFSET_ADDR, 273 + DMD_FTL_FREQ_OFFSET_ADDR, 274 + DMD_STR_NBC_SYNC_LOCK_ADDR, 275 + DMD_CYCLE_SLIP_COUNT_ADDR, 276 + DMD_DISPLAY_IQ_ADDR, 277 + DMD_DVBS2_CRC_ERRORS_ADDR, 278 + DMD_DVBS2_PER_COUNT_ADDR, 279 + DMD_DVBS2_PER_WINDOW_ADDR, 280 + DMD_DVBS_CORR_RS_ERRORS_ADDR, 281 + DMD_DVBS_UNCORR_RS_ERRORS_ADDR, 282 + DMD_DVBS_BER_COUNT_ADDR, 283 + DMD_DVBS_BER_WINDOW_ADDR, 284 + DMD_TUNER_ID_ADDR, 285 + DMD_DVBS2_PILOT_ON_OFF_ADDR, 286 + DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR, 287 + 288 + MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE, 289 + }; 290 + 291 + enum MXL_HYDRA_TUNER_ID_E { 292 + MXL_HYDRA_TUNER_ID_0 = 0, 293 + MXL_HYDRA_TUNER_ID_1, 294 + MXL_HYDRA_TUNER_ID_2, 295 + MXL_HYDRA_TUNER_ID_3, 296 + MXL_HYDRA_TUNER_MAX 297 + }; 298 + 299 + enum MXL_HYDRA_BCAST_STD_E { 300 + MXL_HYDRA_DSS = 0, 301 + MXL_HYDRA_DVBS, 302 + MXL_HYDRA_DVBS2, 303 + }; 304 + 305 + enum MXL_HYDRA_FEC_E { 306 + MXL_HYDRA_FEC_AUTO = 0, 307 + MXL_HYDRA_FEC_1_2, 308 + MXL_HYDRA_FEC_3_5, 309 + MXL_HYDRA_FEC_2_3, 310 + MXL_HYDRA_FEC_3_4, 311 + MXL_HYDRA_FEC_4_5, 312 + MXL_HYDRA_FEC_5_6, 313 + MXL_HYDRA_FEC_6_7, 314 + MXL_HYDRA_FEC_7_8, 315 + MXL_HYDRA_FEC_8_9, 316 + MXL_HYDRA_FEC_9_10, 317 + }; 318 + 319 + enum MXL_HYDRA_MODULATION_E { 320 + MXL_HYDRA_MOD_AUTO = 0, 321 + MXL_HYDRA_MOD_QPSK, 322 + MXL_HYDRA_MOD_8PSK 323 + }; 324 + 325 + enum MXL_HYDRA_SPECTRUM_E { 326 + MXL_HYDRA_SPECTRUM_AUTO = 0, 327 + MXL_HYDRA_SPECTRUM_INVERTED, 328 + MXL_HYDRA_SPECTRUM_NON_INVERTED, 329 + }; 330 + 331 + enum MXL_HYDRA_ROLLOFF_E { 332 + MXL_HYDRA_ROLLOFF_AUTO = 0, 333 + MXL_HYDRA_ROLLOFF_0_20, 334 + MXL_HYDRA_ROLLOFF_0_25, 335 + MXL_HYDRA_ROLLOFF_0_35 336 + }; 337 + 338 + enum MXL_HYDRA_PILOTS_E { 339 + MXL_HYDRA_PILOTS_OFF = 0, 340 + MXL_HYDRA_PILOTS_ON, 341 + MXL_HYDRA_PILOTS_AUTO 342 + }; 343 + 344 + enum MXL_HYDRA_CONSTELLATION_SRC_E { 345 + MXL_HYDRA_FORMATTER = 0, 346 + MXL_HYDRA_LEGACY_FEC, 347 + MXL_HYDRA_FREQ_RECOVERY, 348 + MXL_HYDRA_NBC, 349 + MXL_HYDRA_CTL, 350 + MXL_HYDRA_EQ, 351 + }; 352 + 353 + struct MXL_HYDRA_DEMOD_LOCK_T { 354 + int agc_lock; /* AGC lock info */ 355 + int fec_lock; /* Demod FEC block lock info */ 356 + }; 357 + 358 + struct MXL_HYDRA_DEMOD_STATUS_DVBS_T { 359 + u32 rs_errors; /* RS decoder err counter */ 360 + u32 ber_window; /* Ber Windows */ 361 + u32 ber_count; /* BER count */ 362 + u32 ber_window_iter1; /* Ber Windows - post viterbi */ 363 + u32 ber_count_iter1; /* BER count - post viterbi */ 364 + }; 365 + 366 + struct MXL_HYDRA_DEMOD_STATUS_DSS_T { 367 + u32 rs_errors; /* RS decoder err counter */ 368 + u32 ber_window; /* Ber Windows */ 369 + u32 ber_count; /* BER count */ 370 + }; 371 + 372 + struct MXL_HYDRA_DEMOD_STATUS_DVBS2_T { 373 + u32 crc_errors; /* CRC error counter */ 374 + u32 packet_error_count; /* Number of packet errors */ 375 + u32 total_packets; /* Total packets */ 376 + }; 377 + 378 + struct MXL_HYDRA_DEMOD_STATUS_T { 379 + enum MXL_HYDRA_BCAST_STD_E standard_mask; /* Standard DVB-S, DVB-S2 or DSS */ 380 + 381 + union { 382 + struct MXL_HYDRA_DEMOD_STATUS_DVBS_T demod_status_dvbs; /* DVB-S demod status */ 383 + struct MXL_HYDRA_DEMOD_STATUS_DVBS2_T demod_status_dvbs2; /* DVB-S2 demod status */ 384 + struct MXL_HYDRA_DEMOD_STATUS_DSS_T demod_status_dss; /* DSS demod status */ 385 + } u; 386 + }; 387 + 388 + struct MXL_HYDRA_DEMOD_SIG_OFFSET_INFO_T { 389 + s32 carrier_offset_in_hz; /* CRL offset info */ 390 + s32 symbol_offset_in_symbol; /* SRL offset info */ 391 + }; 392 + 393 + struct MXL_HYDRA_DEMOD_SCRAMBLE_INFO_T { 394 + u8 scramble_sequence[MXL_DEMOD_SCRAMBLE_SEQ_LEN]; /* scramble sequence */ 395 + u32 scramble_code; /* scramble gold code */ 396 + }; 397 + 398 + enum MXL_HYDRA_SPECTRUM_STEP_SIZE_E { 399 + MXL_HYDRA_STEP_SIZE_24_XTAL_102_05KHZ, /* 102.05 KHz for 24 MHz XTAL */ 400 + MXL_HYDRA_STEP_SIZE_24_XTAL_204_10KHZ, /* 204.10 KHz for 24 MHz XTAL */ 401 + MXL_HYDRA_STEP_SIZE_24_XTAL_306_15KHZ, /* 306.15 KHz for 24 MHz XTAL */ 402 + MXL_HYDRA_STEP_SIZE_24_XTAL_408_20KHZ, /* 408.20 KHz for 24 MHz XTAL */ 403 + 404 + MXL_HYDRA_STEP_SIZE_27_XTAL_102_05KHZ, /* 102.05 KHz for 27 MHz XTAL */ 405 + MXL_HYDRA_STEP_SIZE_27_XTAL_204_35KHZ, /* 204.35 KHz for 27 MHz XTAL */ 406 + MXL_HYDRA_STEP_SIZE_27_XTAL_306_52KHZ, /* 306.52 KHz for 27 MHz XTAL */ 407 + MXL_HYDRA_STEP_SIZE_27_XTAL_408_69KHZ, /* 408.69 KHz for 27 MHz XTAL */ 408 + }; 409 + 410 + enum MXL_HYDRA_SPECTRUM_RESOLUTION_E { 411 + MXL_HYDRA_SPECTRUM_RESOLUTION_00_1_DB, /* 0.1 dB */ 412 + MXL_HYDRA_SPECTRUM_RESOLUTION_01_0_DB, /* 1.0 dB */ 413 + MXL_HYDRA_SPECTRUM_RESOLUTION_05_0_DB, /* 5.0 dB */ 414 + MXL_HYDRA_SPECTRUM_RESOLUTION_10_0_DB, /* 10 dB */ 415 + }; 416 + 417 + enum MXL_HYDRA_SPECTRUM_ERROR_CODE_E { 418 + MXL_SPECTRUM_NO_ERROR, 419 + MXL_SPECTRUM_INVALID_PARAMETER, 420 + MXL_SPECTRUM_INVALID_STEP_SIZE, 421 + MXL_SPECTRUM_BW_CANNOT_BE_COVERED, 422 + MXL_SPECTRUM_DEMOD_BUSY, 423 + MXL_SPECTRUM_TUNER_NOT_ENABLED, 424 + }; 425 + 426 + struct MXL_HYDRA_SPECTRUM_REQ_T { 427 + u32 tuner_index; /* TUNER Ctrl: one of MXL58x_TUNER_ID_E */ 428 + u32 demod_index; /* DEMOD Ctrl: one of MXL58x_DEMOD_ID_E */ 429 + enum MXL_HYDRA_SPECTRUM_STEP_SIZE_E step_size_in_khz; 430 + u32 starting_freq_ink_hz; 431 + u32 total_steps; 432 + enum MXL_HYDRA_SPECTRUM_RESOLUTION_E spectrum_division; 433 + }; 434 + 435 + enum MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E { 436 + MXL_HYDRA_SEARCH_MAX_OFFSET = 0, /* DMD searches for max freq offset (i.e. 5MHz) */ 437 + MXL_HYDRA_SEARCH_BW_PLUS_ROLLOFF, /* DMD searches for BW + ROLLOFF/2 */ 438 + }; 439 + 440 + struct MXL58X_CFG_FREQ_OFF_SEARCH_RANGE_T { 441 + u32 demod_index; 442 + enum MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E search_type; 443 + }; 444 + 445 + /* there are two slices 446 + * slice0 - TS0, TS1, TS2 & TS3 447 + * slice1 - TS4, TS5, TS6 & TS7 448 + */ 449 + #define MXL_HYDRA_TS_SLICE_MAX 2 450 + 451 + #define MAX_FIXED_PID_NUM 32 452 + 453 + #define MXL_HYDRA_NCO_CLK 418 /* 418 MHz */ 454 + 455 + #define MXL_HYDRA_MAX_TS_CLOCK 139 /* 139 MHz */ 456 + 457 + #define MXL_HYDRA_TS_FIXED_PID_FILT_SIZE 32 458 + 459 + #define MXL_HYDRA_SHARED_PID_FILT_SIZE_DEFAULT 33 /* Shared PID filter size in 1-1 mux mode */ 460 + #define MXL_HYDRA_SHARED_PID_FILT_SIZE_2_TO_1 66 /* Shared PID filter size in 2-1 mux mode */ 461 + #define MXL_HYDRA_SHARED_PID_FILT_SIZE_4_TO_1 132 /* Shared PID filter size in 4-1 mux mode */ 462 + 463 + enum MXL_HYDRA_PID_BANK_TYPE_E { 464 + MXL_HYDRA_SOFTWARE_PID_BANK = 0, 465 + MXL_HYDRA_HARDWARE_PID_BANK, 466 + }; 467 + 468 + enum MXL_HYDRA_TS_MUX_MODE_E { 469 + MXL_HYDRA_TS_MUX_PID_REMAP = 0, 470 + MXL_HYDRA_TS_MUX_PREFIX_EXTRA_HEADER = 1, 471 + }; 472 + 473 + enum MXL_HYDRA_TS_MUX_TYPE_E { 474 + MXL_HYDRA_TS_MUX_DISABLE = 0, /* No Mux ( 1 TSIF to 1 TSIF) */ 475 + MXL_HYDRA_TS_MUX_2_TO_1, /* Mux 2 TSIF to 1 TSIF */ 476 + MXL_HYDRA_TS_MUX_4_TO_1, /* Mux 4 TSIF to 1 TSIF */ 477 + }; 478 + 479 + enum MXL_HYDRA_TS_GROUP_E { 480 + MXL_HYDRA_TS_GROUP_0_3 = 0, /* TS group 0 to 3 (TS0, TS1, TS2 & TS3) */ 481 + MXL_HYDRA_TS_GROUP_4_7, /* TS group 0 to 3 (TS4, TS5, TS6 & TS7) */ 482 + }; 483 + 484 + enum MXL_HYDRA_TS_PID_FLT_CTRL_E { 485 + MXL_HYDRA_TS_PIDS_ALLOW_ALL = 0, /* Allow all pids */ 486 + MXL_HYDRA_TS_PIDS_DROP_ALL, /* Drop all pids */ 487 + MXL_HYDRA_TS_INVALIDATE_PID_FILTER, /* Delete current PD filter in the device */ 488 + }; 489 + 490 + enum MXL_HYDRA_TS_PID_TYPE_E { 491 + MXL_HYDRA_TS_PID_FIXED = 0, 492 + MXL_HYDRA_TS_PID_REGULAR, 493 + }; 494 + 495 + struct MXL_HYDRA_TS_PID_T { 496 + u16 original_pid; /* pid from TS */ 497 + u16 remapped_pid; /* remapped pid */ 498 + enum MXL_BOOL_E enable; /* enable or disable pid */ 499 + enum MXL_BOOL_E allow_or_drop; /* allow or drop pid */ 500 + enum MXL_BOOL_E enable_pid_remap; /* enable or disable pid remap */ 501 + u8 bond_id; /* Bond ID in A0 always 0 - Only for 568 Sku */ 502 + u8 dest_id; /* Output port ID for the PID - Only for 568 Sku */ 503 + }; 504 + 505 + struct MXL_HYDRA_TS_MUX_PREFIX_HEADER_T { 506 + enum MXL_BOOL_E enable; 507 + u8 num_byte; 508 + u8 header[12]; 509 + }; 510 + 511 + enum MXL_HYDRA_PID_FILTER_BANK_E { 512 + MXL_HYDRA_PID_BANK_A = 0, 513 + MXL_HYDRA_PID_BANK_B, 514 + }; 515 + 516 + enum MXL_HYDRA_MPEG_DATA_FMT_E { 517 + MXL_HYDRA_MPEG_SERIAL_MSB_1ST = 0, 518 + MXL_HYDRA_MPEG_SERIAL_LSB_1ST, 519 + 520 + MXL_HYDRA_MPEG_SYNC_WIDTH_BIT = 0, 521 + MXL_HYDRA_MPEG_SYNC_WIDTH_BYTE 522 + }; 523 + 524 + enum MXL_HYDRA_MPEG_MODE_E { 525 + MXL_HYDRA_MPEG_MODE_SERIAL_4_WIRE = 0, /* MPEG 4 Wire serial mode */ 526 + MXL_HYDRA_MPEG_MODE_SERIAL_3_WIRE, /* MPEG 3 Wire serial mode */ 527 + MXL_HYDRA_MPEG_MODE_SERIAL_2_WIRE, /* MPEG 2 Wire serial mode */ 528 + MXL_HYDRA_MPEG_MODE_PARALLEL /* MPEG parallel mode - valid only for MxL581 */ 529 + }; 530 + 531 + enum MXL_HYDRA_MPEG_CLK_TYPE_E { 532 + MXL_HYDRA_MPEG_CLK_CONTINUOUS = 0, /* Continuous MPEG clock */ 533 + MXL_HYDRA_MPEG_CLK_GAPPED, /* Gapped (gated) MPEG clock */ 534 + }; 535 + 536 + enum MXL_HYDRA_MPEG_CLK_FMT_E { 537 + MXL_HYDRA_MPEG_ACTIVE_LOW = 0, 538 + MXL_HYDRA_MPEG_ACTIVE_HIGH, 539 + 540 + MXL_HYDRA_MPEG_CLK_NEGATIVE = 0, 541 + MXL_HYDRA_MPEG_CLK_POSITIVE, 542 + 543 + MXL_HYDRA_MPEG_CLK_IN_PHASE = 0, 544 + MXL_HYDRA_MPEG_CLK_INVERTED, 545 + }; 546 + 547 + enum MXL_HYDRA_MPEG_CLK_PHASE_E { 548 + MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_0_DEG = 0, 549 + MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_90_DEG, 550 + MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_180_DEG, 551 + MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_270_DEG 552 + }; 553 + 554 + enum MXL_HYDRA_MPEG_ERR_INDICATION_E { 555 + MXL_HYDRA_MPEG_ERR_REPLACE_SYNC = 0, 556 + MXL_HYDRA_MPEG_ERR_REPLACE_VALID, 557 + MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED 558 + }; 559 + 560 + struct MXL_HYDRA_MPEGOUT_PARAM_T { 561 + int enable; /* Enable or Disable MPEG OUT */ 562 + enum MXL_HYDRA_MPEG_CLK_TYPE_E mpeg_clk_type; /* Continuous or gapped */ 563 + enum MXL_HYDRA_MPEG_CLK_FMT_E mpeg_clk_pol; /* MPEG Clk polarity */ 564 + u8 max_mpeg_clk_rate; /* Max MPEG Clk rate (0 - 104 MHz, 139 MHz) */ 565 + enum MXL_HYDRA_MPEG_CLK_PHASE_E mpeg_clk_phase; /* MPEG Clk phase */ 566 + enum MXL_HYDRA_MPEG_DATA_FMT_E lsb_or_msb_first; /* LSB first or MSB first in TS transmission */ 567 + enum MXL_HYDRA_MPEG_DATA_FMT_E mpeg_sync_pulse_width; /* MPEG SYNC pulse width (1-bit or 1-byte) */ 568 + enum MXL_HYDRA_MPEG_CLK_FMT_E mpeg_valid_pol; /* MPEG VALID polarity */ 569 + enum MXL_HYDRA_MPEG_CLK_FMT_E mpeg_sync_pol; /* MPEG SYNC polarity */ 570 + enum MXL_HYDRA_MPEG_MODE_E mpeg_mode; /* config 4/3/2-wire serial or parallel TS out */ 571 + enum MXL_HYDRA_MPEG_ERR_INDICATION_E mpeg_error_indication; /* Enable or Disable MPEG error indication */ 572 + }; 573 + 574 + enum MXL_HYDRA_EXT_TS_IN_ID_E { 575 + MXL_HYDRA_EXT_TS_IN_0 = 0, 576 + MXL_HYDRA_EXT_TS_IN_1, 577 + MXL_HYDRA_EXT_TS_IN_2, 578 + MXL_HYDRA_EXT_TS_IN_3, 579 + MXL_HYDRA_EXT_TS_IN_MAX 580 + }; 581 + 582 + enum MXL_HYDRA_TS_OUT_ID_E { 583 + MXL_HYDRA_TS_OUT_0 = 0, 584 + MXL_HYDRA_TS_OUT_1, 585 + MXL_HYDRA_TS_OUT_2, 586 + MXL_HYDRA_TS_OUT_3, 587 + MXL_HYDRA_TS_OUT_4, 588 + MXL_HYDRA_TS_OUT_5, 589 + MXL_HYDRA_TS_OUT_6, 590 + MXL_HYDRA_TS_OUT_7, 591 + MXL_HYDRA_TS_OUT_MAX 592 + }; 593 + 594 + enum MXL_HYDRA_TS_DRIVE_STRENGTH_E { 595 + MXL_HYDRA_TS_DRIVE_STRENGTH_1X = 0, 596 + MXL_HYDRA_TS_DRIVE_STRENGTH_2X, 597 + MXL_HYDRA_TS_DRIVE_STRENGTH_3X, 598 + MXL_HYDRA_TS_DRIVE_STRENGTH_4X, 599 + MXL_HYDRA_TS_DRIVE_STRENGTH_5X, 600 + MXL_HYDRA_TS_DRIVE_STRENGTH_6X, 601 + MXL_HYDRA_TS_DRIVE_STRENGTH_7X, 602 + MXL_HYDRA_TS_DRIVE_STRENGTH_8X 603 + }; 604 + 605 + enum MXL_HYDRA_DEVICE_E { 606 + MXL_HYDRA_DEVICE_581 = 0, 607 + MXL_HYDRA_DEVICE_584, 608 + MXL_HYDRA_DEVICE_585, 609 + MXL_HYDRA_DEVICE_544, 610 + MXL_HYDRA_DEVICE_561, 611 + MXL_HYDRA_DEVICE_TEST, 612 + MXL_HYDRA_DEVICE_582, 613 + MXL_HYDRA_DEVICE_541, 614 + MXL_HYDRA_DEVICE_568, 615 + MXL_HYDRA_DEVICE_542, 616 + MXL_HYDRA_DEVICE_541S, 617 + MXL_HYDRA_DEVICE_561S, 618 + MXL_HYDRA_DEVICE_581S, 619 + MXL_HYDRA_DEVICE_MAX 620 + }; 621 + 622 + /* Demod IQ data */ 623 + struct MXL_HYDRA_DEMOD_IQ_SRC_T { 624 + u32 demod_id; 625 + u32 source_of_iq; /* == 0, it means I/Q comes from Formatter 626 + * == 1, Legacy FEC 627 + * == 2, Frequency Recovery 628 + * == 3, NBC 629 + * == 4, CTL 630 + * == 5, EQ 631 + * == 6, FPGA 632 + */ 633 + }; 634 + 635 + struct MXL_HYDRA_DEMOD_ABORT_TUNE_T { 636 + u32 demod_id; 637 + }; 638 + 639 + struct MXL_HYDRA_TUNER_CMD { 640 + u8 tuner_id; 641 + u8 enable; 642 + }; 643 + 644 + /* Demod Para for Channel Tune */ 645 + struct MXL_HYDRA_DEMOD_PARAM_T { 646 + u32 tuner_index; 647 + u32 demod_index; 648 + u32 frequency_in_hz; /* Frequency */ 649 + u32 standard; /* one of MXL_HYDRA_BCAST_STD_E */ 650 + u32 spectrum_inversion; /* Input : Spectrum inversion. */ 651 + u32 roll_off; /* rollOff (alpha) factor */ 652 + u32 symbol_rate_in_hz; /* Symbol rate */ 653 + u32 pilots; /* TRUE = pilots enabled */ 654 + u32 modulation_scheme; /* Input : Modulation Scheme is one of MXL_HYDRA_MODULATION_E */ 655 + u32 fec_code_rate; /* Input : Forward error correction rate. Is one of MXL_HYDRA_FEC_E */ 656 + u32 max_carrier_offset_in_mhz; /* Maximum carrier freq offset in MHz. Same as freqSearchRangeKHz, but in unit of MHz. */ 657 + }; 658 + 659 + struct MXL_HYDRA_DEMOD_SCRAMBLE_CODE_T { 660 + u32 demod_index; 661 + u8 scramble_sequence[12]; /* scramble sequence */ 662 + u32 scramble_code; /* scramble gold code */ 663 + }; 664 + 665 + struct MXL_INTR_CFG_T { 666 + u32 intr_type; 667 + u32 intr_duration_in_nano_secs; 668 + u32 intr_mask; 669 + }; 670 + 671 + struct MXL_HYDRA_POWER_MODE_CMD { 672 + u8 power_mode; /* enumeration values are defined in MXL_HYDRA_PWR_MODE_E (device API.h) */ 673 + }; 674 + 675 + struct MXL_HYDRA_RF_WAKEUP_PARAM_T { 676 + u32 time_interval_in_seconds; /* in seconds */ 677 + u32 tuner_index; 678 + s32 rssi_threshold; 679 + }; 680 + 681 + struct MXL_HYDRA_RF_WAKEUP_CFG_T { 682 + u32 tuner_count; 683 + struct MXL_HYDRA_RF_WAKEUP_PARAM_T params; 684 + }; 685 + 686 + enum MXL_HYDRA_AUX_CTRL_MODE_E { 687 + MXL_HYDRA_AUX_CTRL_MODE_FSK = 0, /* Select FSK controller */ 688 + MXL_HYDRA_AUX_CTRL_MODE_DISEQC, /* Select DiSEqC controller */ 689 + }; 690 + 691 + enum MXL_HYDRA_DISEQC_OPMODE_E { 692 + MXL_HYDRA_DISEQC_ENVELOPE_MODE = 0, 693 + MXL_HYDRA_DISEQC_TONE_MODE, 694 + }; 695 + 696 + enum MXL_HYDRA_DISEQC_VER_E { 697 + MXL_HYDRA_DISEQC_1_X = 0, /* Config DiSEqC 1.x mode */ 698 + MXL_HYDRA_DISEQC_2_X, /* Config DiSEqC 2.x mode */ 699 + MXL_HYDRA_DISEQC_DISABLE /* Disable DiSEqC */ 700 + }; 701 + 702 + enum MXL_HYDRA_DISEQC_CARRIER_FREQ_E { 703 + MXL_HYDRA_DISEQC_CARRIER_FREQ_22KHZ = 0, /* DiSEqC signal frequency of 22 KHz */ 704 + MXL_HYDRA_DISEQC_CARRIER_FREQ_33KHZ, /* DiSEqC signal frequency of 33 KHz */ 705 + MXL_HYDRA_DISEQC_CARRIER_FREQ_44KHZ /* DiSEqC signal frequency of 44 KHz */ 706 + }; 707 + 708 + enum MXL_HYDRA_DISEQC_ID_E { 709 + MXL_HYDRA_DISEQC_ID_0 = 0, 710 + MXL_HYDRA_DISEQC_ID_1, 711 + MXL_HYDRA_DISEQC_ID_2, 712 + MXL_HYDRA_DISEQC_ID_3 713 + }; 714 + 715 + enum MXL_HYDRA_FSK_OP_MODE_E { 716 + MXL_HYDRA_FSK_CFG_TYPE_39KPBS = 0, /* 39.0kbps */ 717 + MXL_HYDRA_FSK_CFG_TYPE_39_017KPBS, /* 39.017kbps */ 718 + MXL_HYDRA_FSK_CFG_TYPE_115_2KPBS /* 115.2kbps */ 719 + }; 720 + 721 + struct MXL58X_DSQ_OP_MODE_T { 722 + u32 diseqc_id; /* DSQ 0, 1, 2 or 3 */ 723 + u32 op_mode; /* Envelope mode (0) or internal tone mode (1) */ 724 + u32 version; /* 0: 1.0, 1: 1.1, 2: Disable */ 725 + u32 center_freq; /* 0: 22KHz, 1: 33KHz and 2: 44 KHz */ 726 + }; 727 + 728 + struct MXL_HYDRA_DISEQC_CFG_CONT_TONE_T { 729 + u32 diseqc_id; 730 + u32 cont_tone_flag; /* 1: Enable , 0: Disable */ 731 + };
+367
drivers/media/dvb-frontends/mxl5xx_regs.h
··· 1 + /* 2 + * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved 3 + * 4 + * License type: GPLv2 5 + * 6 + * This program is free software; you can redistribute it and/or modify it under 7 + * the terms of the GNU General Public License as published by the Free Software 8 + * Foundation. 9 + * 10 + * This program is distributed in the hope that it will be useful, but WITHOUT 11 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 13 + * 14 + * This program may alternatively be licensed under a proprietary license from 15 + * MaxLinear, Inc. 16 + * 17 + */ 18 + 19 + #ifndef __MXL58X_REGISTERS_H__ 20 + #define __MXL58X_REGISTERS_H__ 21 + 22 + #define HYDRA_INTR_STATUS_REG 0x80030008 23 + #define HYDRA_INTR_MASK_REG 0x8003000C 24 + 25 + #define HYDRA_CRYSTAL_SETTING 0x3FFFC5F0 /* 0 - 24 MHz & 1 - 27 MHz */ 26 + #define HYDRA_CRYSTAL_CAP 0x3FFFEDA4 /* 0 - 24 MHz & 1 - 27 MHz */ 27 + 28 + #define HYDRA_CPU_RESET_REG 0x8003003C 29 + #define HYDRA_CPU_RESET_DATA 0x00000400 30 + 31 + #define HYDRA_RESET_TRANSPORT_FIFO_REG 0x80030028 32 + #define HYDRA_RESET_TRANSPORT_FIFO_DATA 0x00000000 33 + 34 + #define HYDRA_RESET_BBAND_REG 0x80030024 35 + #define HYDRA_RESET_BBAND_DATA 0x00000000 36 + 37 + #define HYDRA_RESET_XBAR_REG 0x80030020 38 + #define HYDRA_RESET_XBAR_DATA 0x00000000 39 + 40 + #define HYDRA_MODULES_CLK_1_REG 0x80030014 41 + #define HYDRA_DISABLE_CLK_1 0x00000000 42 + 43 + #define HYDRA_MODULES_CLK_2_REG 0x8003001C 44 + #define HYDRA_DISABLE_CLK_2 0x0000000B 45 + 46 + #define HYDRA_PRCM_ROOT_CLK_REG 0x80030018 47 + #define HYDRA_PRCM_ROOT_CLK_DISABLE 0x00000000 48 + 49 + #define HYDRA_CPU_RESET_CHECK_REG 0x80030008 50 + #define HYDRA_CPU_RESET_CHECK_OFFSET 0x40000000 /* <bit 30> */ 51 + 52 + #define HYDRA_SKU_ID_REG 0x90000190 53 + 54 + #define FW_DL_SIGN_ADDR 0x3FFFEAE0 55 + 56 + /* Register to check if FW is running or not */ 57 + #define HYDRA_HEAR_BEAT 0x3FFFEDDC 58 + 59 + /* Firmware version */ 60 + #define HYDRA_FIRMWARE_VERSION 0x3FFFEDB8 61 + #define HYDRA_FW_RC_VERSION 0x3FFFCFAC 62 + 63 + /* Firmware patch version */ 64 + #define HYDRA_FIRMWARE_PATCH_VERSION 0x3FFFEDC2 65 + 66 + /* SOC operating temperature in C */ 67 + #define HYDRA_TEMPARATURE 0x3FFFEDB4 68 + 69 + /* Demod & Tuner status registers */ 70 + /* Demod 0 status base address */ 71 + #define HYDRA_DEMOD_0_BASE_ADDR 0x3FFFC64C 72 + 73 + /* Tuner 0 status base address */ 74 + #define HYDRA_TUNER_0_BASE_ADDR 0x3FFFCE4C 75 + 76 + #define POWER_FROM_ADCRSSI_READBACK 0x3FFFEB6C 77 + 78 + /* Macros to determine base address of respective demod or tuner */ 79 + #define HYDRA_DMD_STATUS_OFFSET(demodID) ((demodID) * 0x100) 80 + #define HYDRA_TUNER_STATUS_OFFSET(tunerID) ((tunerID) * 0x40) 81 + 82 + /* Demod status address offset from respective demod's base address */ 83 + #define HYDRA_DMD_AGC_DIG_LEVEL_ADDR_OFFSET 0x3FFFC64C 84 + #define HYDRA_DMD_LOCK_STATUS_ADDR_OFFSET 0x3FFFC650 85 + #define HYDRA_DMD_ACQ_STATUS_ADDR_OFFSET 0x3FFFC654 86 + 87 + #define HYDRA_DMD_STANDARD_ADDR_OFFSET 0x3FFFC658 88 + #define HYDRA_DMD_SPECTRUM_INVERSION_ADDR_OFFSET 0x3FFFC65C 89 + #define HYDRA_DMD_SPECTRUM_ROLL_OFF_ADDR_OFFSET 0x3FFFC660 90 + #define HYDRA_DMD_SYMBOL_RATE_ADDR_OFFSET 0x3FFFC664 91 + #define HYDRA_DMD_MODULATION_SCHEME_ADDR_OFFSET 0x3FFFC668 92 + #define HYDRA_DMD_FEC_CODE_RATE_ADDR_OFFSET 0x3FFFC66C 93 + 94 + #define HYDRA_DMD_SNR_ADDR_OFFSET 0x3FFFC670 95 + #define HYDRA_DMD_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC674 96 + #define HYDRA_DMD_CTL_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC678 97 + #define HYDRA_DMD_STR_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC67C 98 + #define HYDRA_DMD_FTL_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC680 99 + #define HYDRA_DMD_STR_NBC_SYNC_LOCK_ADDR_OFFSET 0x3FFFC684 100 + #define HYDRA_DMD_CYCLE_SLIP_COUNT_ADDR_OFFSET 0x3FFFC688 101 + 102 + #define HYDRA_DMD_DISPLAY_I_ADDR_OFFSET 0x3FFFC68C 103 + #define HYDRA_DMD_DISPLAY_Q_ADDR_OFFSET 0x3FFFC68E 104 + 105 + #define HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET 0x3FFFC690 106 + #define HYDRA_DMD_DVBS2_PER_COUNT_ADDR_OFFSET 0x3FFFC694 107 + #define HYDRA_DMD_DVBS2_PER_WINDOW_ADDR_OFFSET 0x3FFFC698 108 + 109 + #define HYDRA_DMD_DVBS_CORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC69C 110 + #define HYDRA_DMD_DVBS_UNCORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6A0 111 + #define HYDRA_DMD_DVBS_BER_COUNT_ADDR_OFFSET 0x3FFFC6A4 112 + #define HYDRA_DMD_DVBS_BER_WINDOW_ADDR_OFFSET 0x3FFFC6A8 113 + 114 + /* Debug-purpose DVB-S DMD 0 */ 115 + #define HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6C8 /* corrected RS Errors: 1st iteration */ 116 + #define HYDRA_DMD_DVBS_1ST_UNCORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6CC /* uncorrected RS Errors: 1st iteration */ 117 + #define HYDRA_DMD_DVBS_BER_COUNT_1ST_ADDR_OFFSET 0x3FFFC6D0 118 + #define HYDRA_DMD_DVBS_BER_WINDOW_1ST_ADDR_OFFSET 0x3FFFC6D4 119 + 120 + #define HYDRA_DMD_TUNER_ID_ADDR_OFFSET 0x3FFFC6AC 121 + #define HYDRA_DMD_DVBS2_PILOT_ON_OFF_ADDR_OFFSET 0x3FFFC6B0 122 + #define HYDRA_DMD_FREQ_SEARCH_RANGE_KHZ_ADDR_OFFSET 0x3FFFC6B4 123 + #define HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET 0x3FFFC6B8 124 + #define HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR 0x3FFFC704 125 + #define HYDRA_DMD_STATUS_INPUT_POWER_ADDR 0x3FFFC708 126 + 127 + /* DVB-S new scaled_BER_count for a new BER API, see HYDRA-1343 "DVB-S post viterbi information" */ 128 + #define DMD0_STATUS_DVBS_1ST_SCALED_BER_COUNT_ADDR 0x3FFFC710 /* DMD 0: 1st iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR */ 129 + #define DMD0_STATUS_DVBS_SCALED_BER_COUNT_ADDR 0x3FFFC714 /* DMD 0: 2nd iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR */ 130 + 131 + #define DMD0_SPECTRUM_MIN_GAIN_STATUS 0x3FFFC73C 132 + #define DMD0_SPECTRUM_MIN_GAIN_WB_SAGC_VALUE 0x3FFFC740 133 + #define DMD0_SPECTRUM_MIN_GAIN_NB_SAGC_VALUE 0x3FFFC744 134 + 135 + #define HYDRA_DMD_STATUS_END_ADDR_OFFSET 0x3FFFC748 136 + 137 + /* Tuner status address offset from respective tuners's base address */ 138 + #define HYDRA_TUNER_DEMOD_ID_ADDR_OFFSET 0x3FFFCE4C 139 + #define HYDRA_TUNER_AGC_LOCK_OFFSET 0x3FFFCE50 140 + #define HYDRA_TUNER_SPECTRUM_STATUS_OFFSET 0x3FFFCE54 141 + #define HYDRA_TUNER_SPECTRUM_BIN_SIZE_OFFSET 0x3FFFCE58 142 + #define HYDRA_TUNER_SPECTRUM_ADDRESS_OFFSET 0x3FFFCE5C 143 + #define HYDRA_TUNER_ENABLE_COMPLETE 0x3FFFEB78 144 + 145 + #define HYDRA_DEMOD_STATUS_LOCK(devId, demodId) write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_YES) 146 + #define HYDRA_DEMOD_STATUS_UNLOCK(devId, demodId) write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_NO) 147 + 148 + #define HYDRA_VERSION 0x3FFFEDB8 149 + #define HYDRA_DEMOD0_VERSION 0x3FFFEDBC 150 + #define HYDRA_DEMOD1_VERSION 0x3FFFEDC0 151 + #define HYDRA_DEMOD2_VERSION 0x3FFFEDC4 152 + #define HYDRA_DEMOD3_VERSION 0x3FFFEDC8 153 + #define HYDRA_DEMOD4_VERSION 0x3FFFEDCC 154 + #define HYDRA_DEMOD5_VERSION 0x3FFFEDD0 155 + #define HYDRA_DEMOD6_VERSION 0x3FFFEDD4 156 + #define HYDRA_DEMOD7_VERSION 0x3FFFEDD8 157 + #define HYDRA_HEAR_BEAT 0x3FFFEDDC 158 + #define HYDRA_SKU_MGMT 0x3FFFEBC0 159 + 160 + #define MXL_HYDRA_FPGA_A_ADDRESS 0x91C00000 161 + #define MXL_HYDRA_FPGA_B_ADDRESS 0x91D00000 162 + 163 + /* TS control base address */ 164 + #define HYDRA_TS_CTRL_BASE_ADDR 0x90700000 165 + 166 + #define MPEG_MUX_MODE_SLICE0_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x08) 167 + 168 + #define MPEG_MUX_MODE_SLICE1_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x08) 169 + 170 + #define PID_BANK_SEL_SLICE0_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x190) 171 + #define PID_BANK_SEL_SLICE1_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x1B0) 172 + 173 + #define MPEG_CLK_GATED_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x20) 174 + 175 + #define MPEG_CLK_ALWAYS_ON_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x1D4) 176 + 177 + #define HYDRA_REGULAR_PID_BANK_A_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x190) 178 + 179 + #define HYDRA_FIXED_PID_BANK_A_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x190) 180 + 181 + #define HYDRA_REGULAR_PID_BANK_B_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x1B0) 182 + 183 + #define HYDRA_FIXED_PID_BANK_B_REG (HYDRA_TS_CTRL_BASE_ADDR + 0x1B0) 184 + 185 + #define FIXED_PID_TBL_REG_ADDRESS_0 (HYDRA_TS_CTRL_BASE_ADDR + 0x9000) 186 + #define FIXED_PID_TBL_REG_ADDRESS_1 (HYDRA_TS_CTRL_BASE_ADDR + 0x9100) 187 + #define FIXED_PID_TBL_REG_ADDRESS_2 (HYDRA_TS_CTRL_BASE_ADDR + 0x9200) 188 + #define FIXED_PID_TBL_REG_ADDRESS_3 (HYDRA_TS_CTRL_BASE_ADDR + 0x9300) 189 + 190 + #define FIXED_PID_TBL_REG_ADDRESS_4 (HYDRA_TS_CTRL_BASE_ADDR + 0xB000) 191 + #define FIXED_PID_TBL_REG_ADDRESS_5 (HYDRA_TS_CTRL_BASE_ADDR + 0xB100) 192 + #define FIXED_PID_TBL_REG_ADDRESS_6 (HYDRA_TS_CTRL_BASE_ADDR + 0xB200) 193 + #define FIXED_PID_TBL_REG_ADDRESS_7 (HYDRA_TS_CTRL_BASE_ADDR + 0xB300) 194 + 195 + #define REGULAR_PID_TBL_REG_ADDRESS_0 (HYDRA_TS_CTRL_BASE_ADDR + 0x8000) 196 + #define REGULAR_PID_TBL_REG_ADDRESS_1 (HYDRA_TS_CTRL_BASE_ADDR + 0x8200) 197 + #define REGULAR_PID_TBL_REG_ADDRESS_2 (HYDRA_TS_CTRL_BASE_ADDR + 0x8400) 198 + #define REGULAR_PID_TBL_REG_ADDRESS_3 (HYDRA_TS_CTRL_BASE_ADDR + 0x8600) 199 + 200 + #define REGULAR_PID_TBL_REG_ADDRESS_4 (HYDRA_TS_CTRL_BASE_ADDR + 0xA000) 201 + #define REGULAR_PID_TBL_REG_ADDRESS_5 (HYDRA_TS_CTRL_BASE_ADDR + 0xA200) 202 + #define REGULAR_PID_TBL_REG_ADDRESS_6 (HYDRA_TS_CTRL_BASE_ADDR + 0xA400) 203 + #define REGULAR_PID_TBL_REG_ADDRESS_7 (HYDRA_TS_CTRL_BASE_ADDR + 0xA600) 204 + 205 + /***************************************************************************/ 206 + 207 + #define PAD_MUX_GPIO_00_SYNC_BASEADDR 0x90000188 208 + 209 + 210 + #define PAD_MUX_UART_RX_C_PINMUX_BASEADDR 0x9000001C 211 + 212 + #define XPT_PACKET_GAP_MIN_BASEADDR 0x90700044 213 + #define XPT_NCO_COUNT_BASEADDR 0x90700238 214 + 215 + #define XPT_NCO_COUNT_BASEADDR1 0x9070023C 216 + 217 + /* V2 DigRF status register */ 218 + 219 + #define XPT_PID_BASEADDR 0x90708000 220 + 221 + #define XPT_PID_REMAP_BASEADDR 0x90708004 222 + 223 + #define XPT_KNOWN_PID_BASEADDR 0x90709000 224 + 225 + #define XPT_PID_BASEADDR1 0x9070A000 226 + 227 + #define XPT_PID_REMAP_BASEADDR1 0x9070A004 228 + 229 + #define XPT_KNOWN_PID_BASEADDR1 0x9070B000 230 + 231 + #define XPT_BERT_LOCK_BASEADDR 0x907000B8 232 + 233 + #define XPT_BERT_BASEADDR 0x907000BC 234 + 235 + #define XPT_BERT_INVERT_BASEADDR 0x907000C0 236 + 237 + #define XPT_BERT_HEADER_BASEADDR 0x907000C4 238 + 239 + #define XPT_BERT_BASEADDR1 0x907000C8 240 + 241 + #define XPT_BERT_BIT_COUNT0_BASEADDR 0x907000CC 242 + 243 + #define XPT_BERT_BIT_COUNT0_BASEADDR1 0x907000D0 244 + 245 + #define XPT_BERT_BIT_COUNT1_BASEADDR 0x907000D4 246 + 247 + #define XPT_BERT_BIT_COUNT1_BASEADDR1 0x907000D8 248 + 249 + #define XPT_BERT_BIT_COUNT2_BASEADDR 0x907000DC 250 + 251 + #define XPT_BERT_BIT_COUNT2_BASEADDR1 0x907000E0 252 + 253 + #define XPT_BERT_BIT_COUNT3_BASEADDR 0x907000E4 254 + 255 + #define XPT_BERT_BIT_COUNT3_BASEADDR1 0x907000E8 256 + 257 + #define XPT_BERT_BIT_COUNT4_BASEADDR 0x907000EC 258 + 259 + #define XPT_BERT_BIT_COUNT4_BASEADDR1 0x907000F0 260 + 261 + #define XPT_BERT_BIT_COUNT5_BASEADDR 0x907000F4 262 + 263 + #define XPT_BERT_BIT_COUNT5_BASEADDR1 0x907000F8 264 + 265 + #define XPT_BERT_BIT_COUNT6_BASEADDR 0x907000FC 266 + 267 + #define XPT_BERT_BIT_COUNT6_BASEADDR1 0x90700100 268 + 269 + #define XPT_BERT_BIT_COUNT7_BASEADDR 0x90700104 270 + 271 + #define XPT_BERT_BIT_COUNT7_BASEADDR1 0x90700108 272 + 273 + #define XPT_BERT_ERR_COUNT0_BASEADDR 0x9070010C 274 + 275 + #define XPT_BERT_ERR_COUNT0_BASEADDR1 0x90700110 276 + 277 + #define XPT_BERT_ERR_COUNT1_BASEADDR 0x90700114 278 + 279 + #define XPT_BERT_ERR_COUNT1_BASEADDR1 0x90700118 280 + 281 + #define XPT_BERT_ERR_COUNT2_BASEADDR 0x9070011C 282 + 283 + #define XPT_BERT_ERR_COUNT2_BASEADDR1 0x90700120 284 + 285 + #define XPT_BERT_ERR_COUNT3_BASEADDR 0x90700124 286 + 287 + #define XPT_BERT_ERR_COUNT3_BASEADDR1 0x90700128 288 + 289 + #define XPT_BERT_ERR_COUNT4_BASEADDR 0x9070012C 290 + 291 + #define XPT_BERT_ERR_COUNT4_BASEADDR1 0x90700130 292 + 293 + #define XPT_BERT_ERR_COUNT5_BASEADDR 0x90700134 294 + 295 + #define XPT_BERT_ERR_COUNT5_BASEADDR1 0x90700138 296 + 297 + #define XPT_BERT_ERR_COUNT6_BASEADDR 0x9070013C 298 + 299 + #define XPT_BERT_ERR_COUNT6_BASEADDR1 0x90700140 300 + 301 + #define XPT_BERT_ERR_COUNT7_BASEADDR 0x90700144 302 + 303 + #define XPT_BERT_ERR_COUNT7_BASEADDR1 0x90700148 304 + 305 + #define XPT_BERT_ERROR_BASEADDR 0x9070014C 306 + 307 + #define XPT_BERT_ANALYZER_BASEADDR 0x90700150 308 + 309 + #define XPT_BERT_ANALYZER_BASEADDR1 0x90700154 310 + 311 + #define XPT_BERT_ANALYZER_BASEADDR2 0x90700158 312 + 313 + #define XPT_BERT_ANALYZER_BASEADDR3 0x9070015C 314 + 315 + #define XPT_BERT_ANALYZER_BASEADDR4 0x90700160 316 + 317 + #define XPT_BERT_ANALYZER_BASEADDR5 0x90700164 318 + 319 + #define XPT_BERT_ANALYZER_BASEADDR6 0x90700168 320 + 321 + #define XPT_BERT_ANALYZER_BASEADDR7 0x9070016C 322 + 323 + #define XPT_BERT_ANALYZER_BASEADDR8 0x90700170 324 + 325 + #define XPT_BERT_ANALYZER_BASEADDR9 0x90700174 326 + 327 + #define XPT_DMD0_BASEADDR 0x9070024C 328 + 329 + /* V2 AGC Gain Freeze & step */ 330 + #define DBG_ENABLE_DISABLE_AGC (0x3FFFCF60) /* 1: DISABLE, 0:ENABLE */ 331 + #define WB_DFE0_DFE_FB_RF1_BASEADDR 0x903004A4 332 + 333 + #define WB_DFE1_DFE_FB_RF1_BASEADDR 0x904004A4 334 + 335 + #define WB_DFE2_DFE_FB_RF1_BASEADDR 0x905004A4 336 + 337 + #define WB_DFE3_DFE_FB_RF1_BASEADDR 0x906004A4 338 + 339 + #define AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR 0x90200104 340 + 341 + #define AFE_REG_AFE_REG_SPARE_BASEADDR 0x902000A0 342 + 343 + #define AFE_REG_AFE_REG_SPARE_BASEADDR1 0x902000B4 344 + 345 + #define AFE_REG_AFE_REG_SPARE_BASEADDR2 0x902000C4 346 + 347 + #define AFE_REG_AFE_REG_SPARE_BASEADDR3 0x902000D4 348 + 349 + #define WB_DFE0_DFE_FB_AGC_BASEADDR 0x90300498 350 + 351 + #define WB_DFE1_DFE_FB_AGC_BASEADDR 0x90400498 352 + 353 + #define WB_DFE2_DFE_FB_AGC_BASEADDR 0x90500498 354 + 355 + #define WB_DFE3_DFE_FB_AGC_BASEADDR 0x90600498 356 + 357 + #define WDT_WD_INT_BASEADDR 0x8002000C 358 + 359 + #define FSK_TX_FTM_BASEADDR 0x80090000 360 + 361 + #define FSK_TX_FTM_TX_CNT_BASEADDR 0x80090018 362 + 363 + #define AFE_REG_D2A_FSK_BIAS_BASEADDR 0x90200040 364 + 365 + #define DMD_TEI_BASEADDR 0x3FFFEBE0 366 + 367 + #endif /* __MXL58X_REGISTERS_H__ */