^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for the MaxLinear MxL5xx family of tuners/demods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014-2015 Ralph Metzler <rjkm@metzlerbros.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Marcus Metzler <mocm@metzlerbros.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * developed for Digital Devices GmbH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * based on code:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * which was released under GPL V2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * modify it under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * version 2, as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "mxl5xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "mxl5xx_regs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "mxl5xx_defs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define BYTE0(v) ((v >> 0) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define BYTE1(v) ((v >> 8) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define BYTE2(v) ((v >> 16) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define BYTE3(v) ((v >> 24) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static LIST_HEAD(mxllist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct mxl_base {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct list_head mxllist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct list_head mxls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u8 adr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct i2c_adapter *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) u32 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u32 sku_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 chipversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u32 clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u32 fwversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u8 *ts_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u8 can_clkout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u8 chan_bond;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) u8 demod_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u8 tuner_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) unsigned long next_tune;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct mutex i2c_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct mutex status_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct mutex tune_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u8 buf[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u32 cmd_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u8 cmd_data[MAX_CMD_DATA];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct mxl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct list_head mxl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct mxl_base *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct dvb_frontend fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct device *i2cdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u32 demod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) u32 tuner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u32 tuner_in_use;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u8 xbar[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned long tune_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static void convert_endian(u8 flag, u32 size, u8 *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) for (i = 0; i < (size & ~3); i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) d[i + 0] ^= d[i + 3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) d[i + 3] ^= d[i + 0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) d[i + 0] ^= d[i + 3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) d[i + 1] ^= d[i + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) d[i + 2] ^= d[i + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) d[i + 1] ^= d[i + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) switch (size & 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* do nothing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) d[i + 0] ^= d[i + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) d[i + 1] ^= d[i + 0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) d[i + 0] ^= d[i + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) d[i + 0] ^= d[i + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) d[i + 2] ^= d[i + 0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) d[i + 0] ^= d[i + 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int i2c_write(struct i2c_adapter *adap, u8 adr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u8 *data, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct i2c_msg msg = {.addr = adr, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) .buf = data, .len = len};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int i2c_read(struct i2c_adapter *adap, u8 adr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u8 *data, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct i2c_msg msg = {.addr = adr, .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .buf = data, .len = len};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int i2cread(struct mxl *state, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return i2c_read(state->base->i2c, state->base->adr, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static int i2cwrite(struct mxl *state, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return i2c_write(state->base->i2c, state->base->adr, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int read_register_unlocked(struct mxl *state, u32 reg, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u8 data[MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) MXL_HYDRA_PLID_REG_READ, 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) GET_BYTE(reg, 0), GET_BYTE(reg, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) GET_BYTE(reg, 2), GET_BYTE(reg, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) stat = i2cwrite(state, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) dev_err(state->i2cdev, "i2c read error 1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) stat = i2cread(state, (u8 *) val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) MXL_HYDRA_REG_SIZE_IN_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) le32_to_cpus(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) dev_err(state->i2cdev, "i2c read error 2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define DMA_I2C_INTERRUPT_ADDR 0x8000011C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define DMA_INTR_PROT_WR_CMP 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int send_command(struct mxl *state, u32 size, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u32 val, count = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) mutex_lock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (state->base->fwversion > 0x02010109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (DMA_INTR_PROT_WR_CMP & val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dev_info(state->i2cdev, "%s busy\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) while ((DMA_INTR_PROT_WR_CMP & val) && --count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mutex_unlock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) mutex_lock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (!count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) dev_info(state->i2cdev, "%s busy\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) mutex_unlock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) stat = i2cwrite(state, buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) mutex_unlock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int write_register(struct mxl *state, u32 reg, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u8 data[MXL_HYDRA_REG_WRITE_LEN] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) MXL_HYDRA_PLID_REG_WRITE, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) BYTE0(reg), BYTE1(reg), BYTE2(reg), BYTE3(reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) BYTE0(val), BYTE1(val), BYTE2(val), BYTE3(val),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) mutex_lock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) stat = i2cwrite(state, data, sizeof(data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) mutex_unlock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) dev_err(state->i2cdev, "i2c write error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static int write_firmware_block(struct mxl *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u32 reg, u32 size, u8 *reg_data_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) u8 *buf = state->base->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mutex_lock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) buf[0] = MXL_HYDRA_PLID_REG_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) buf[1] = size + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) buf[2] = GET_BYTE(reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) buf[3] = GET_BYTE(reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) buf[4] = GET_BYTE(reg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) buf[5] = GET_BYTE(reg, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) memcpy(&buf[6], reg_data_ptr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) stat = i2cwrite(state, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) MXL_HYDRA_I2C_HDR_SIZE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) MXL_HYDRA_REG_SIZE_IN_BYTES + size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) mutex_unlock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) dev_err(state->i2cdev, "fw block write failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) static int read_register(struct mxl *state, u32 reg, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) u8 data[MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) MXL_HYDRA_PLID_REG_READ, 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) GET_BYTE(reg, 0), GET_BYTE(reg, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) GET_BYTE(reg, 2), GET_BYTE(reg, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) mutex_lock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) stat = i2cwrite(state, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dev_err(state->i2cdev, "i2c read error 1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (!stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) stat = i2cread(state, (u8 *) val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) MXL_HYDRA_REG_SIZE_IN_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) mutex_unlock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) le32_to_cpus(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) dev_err(state->i2cdev, "i2c read error 2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static int read_register_block(struct mxl *state, u32 reg, u32 size, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) u8 *buf = state->base->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) mutex_lock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) buf[0] = MXL_HYDRA_PLID_REG_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) buf[1] = size + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) buf[2] = GET_BYTE(reg, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) buf[3] = GET_BYTE(reg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) buf[4] = GET_BYTE(reg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) buf[5] = GET_BYTE(reg, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) stat = i2cwrite(state, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (!stat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) stat = i2cread(state, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) convert_endian(MXL_ENABLE_BIG_ENDIAN, size, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) mutex_unlock(&state->base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static int read_by_mnemonic(struct mxl *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) u32 reg, u8 lsbloc, u8 numofbits, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u32 data = 0, mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) stat = read_register(state, reg, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) mask = MXL_GET_REG_MASK_32(lsbloc, numofbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) data &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) data >>= lsbloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *val = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static int update_by_mnemonic(struct mxl *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) u32 reg, u8 lsbloc, u8 numofbits, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) u32 data, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) stat = read_register(state, reg, &data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) mask = MXL_GET_REG_MASK_32(lsbloc, numofbits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) data = (data & ~mask) | ((val << lsbloc) & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) stat = write_register(state, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int firmware_is_alive(struct mxl *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) u32 hb0, hb1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (read_register(state, HYDRA_HEAR_BEAT, &hb0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (read_register(state, HYDRA_HEAR_BEAT, &hb1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (hb1 == hb0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static int init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* init fe stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) p->strength.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) p->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) p->pre_bit_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) p->pre_bit_count.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) p->post_bit_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) p->post_bit_count.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static void release(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) list_del(&state->mxl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* Release one frontend, two more shall take its place! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) state->base->count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (state->base->count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) list_del(&state->base->mxllist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) kfree(state->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static enum dvbfe_algo get_algo(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return DVBFE_ALGO_HW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static u32 gold2root(u32 gold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) u32 x, g, tmp = gold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (tmp >= 0x3ffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) for (g = 0, x = 1; g < tmp; g++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static int cfg_scrambler(struct mxl *state, u32 gold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u32 root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) u8 buf[26] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) MXL_HYDRA_PLID_CMD_WRITE, 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 0, MXL_HYDRA_DEMOD_SCRAMBLE_CODE_CMD, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) state->demod, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 0, 0, 0, 0, 1, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) root = gold2root(gold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) buf[25] = (root >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) buf[24] = (root >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) buf[23] = (root >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) buf[22] = root & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) return send_command(state, sizeof(buf), buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static int cfg_demod_abort_tune(struct mxl *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct MXL_HYDRA_DEMOD_ABORT_TUNE_T abort_tune_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) u8 cmd_size = sizeof(abort_tune_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) u8 cmd_buff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) abort_tune_cmd.demod_id = state->demod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) cmd_size, &abort_tune_cmd, cmd_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) &cmd_buff[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int send_master_cmd(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct dvb_diseqc_master_cmd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /*struct mxl *state = fe->demodulator_priv;*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return 0; /*CfgDemodAbortTune(state);*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static int set_parameters(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct MXL_HYDRA_DEMOD_PARAM_T demod_chan_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) u8 cmd_size = sizeof(demod_chan_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) u8 cmd_buff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) u32 srange = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (p->frequency < 950000 || p->frequency > 2150000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (p->symbol_rate < 1000000 || p->symbol_rate > 45000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* CfgDemodAbortTune(state); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) switch (p->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) case SYS_DSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) demod_chan_cfg.standard = MXL_HYDRA_DSS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) srange = p->symbol_rate / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (srange > 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) srange = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) demod_chan_cfg.standard = MXL_HYDRA_DVBS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_0_35;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) demod_chan_cfg.modulation_scheme = MXL_HYDRA_MOD_QPSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) demod_chan_cfg.pilots = MXL_HYDRA_PILOTS_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) demod_chan_cfg.standard = MXL_HYDRA_DVBS2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) demod_chan_cfg.roll_off = MXL_HYDRA_ROLLOFF_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) demod_chan_cfg.modulation_scheme = MXL_HYDRA_MOD_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) demod_chan_cfg.pilots = MXL_HYDRA_PILOTS_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) cfg_scrambler(state, p->scrambling_sequence_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) demod_chan_cfg.tuner_index = state->tuner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) demod_chan_cfg.demod_index = state->demod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) demod_chan_cfg.frequency_in_hz = p->frequency * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) demod_chan_cfg.symbol_rate_in_hz = p->symbol_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) demod_chan_cfg.max_carrier_offset_in_mhz = srange;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) demod_chan_cfg.spectrum_inversion = MXL_HYDRA_SPECTRUM_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) demod_chan_cfg.fec_code_rate = MXL_HYDRA_FEC_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) mutex_lock(&state->base->tune_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (time_after(jiffies + msecs_to_jiffies(200),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) state->base->next_tune))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) while (time_before(jiffies, state->base->next_tune))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) usleep_range(10000, 11000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) state->base->next_tune = jiffies + msecs_to_jiffies(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) state->tuner_in_use = state->tuner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_SET_PARAM_CMD, MXL_CMD_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) cmd_size, &demod_chan_cfg, cmd_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) stat = send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) &cmd_buff[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) mutex_unlock(&state->base->tune_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static int enable_tuner(struct mxl *state, u32 tuner, u32 enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct mxl *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) cfg_demod_abort_tune(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (state->tuner_in_use != 0xffffffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) mutex_lock(&state->base->tune_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) state->tuner_in_use = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) list_for_each_entry(p, &state->base->mxls, mxl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (p->tuner_in_use == state->tuner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (&p->mxl == &state->base->mxls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) enable_tuner(state, state->tuner, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) mutex_unlock(&state->base->tune_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int read_snr(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) u32 reg_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) mutex_lock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) stat = read_register(state, (HYDRA_DMD_SNR_ADDR_OFFSET +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) HYDRA_DMD_STATUS_OFFSET(state->demod)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) mutex_unlock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) p->cnr.stat[0].svalue = (s16)reg_data * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int read_ber(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) u32 reg[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) mutex_lock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) read_register_block(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) (HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) HYDRA_DMD_STATUS_OFFSET(state->demod)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) (4 * sizeof(u32)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) (u8 *) ®[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) switch (p->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) case SYS_DSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) p->pre_bit_error.stat[0].uvalue = reg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) p->pre_bit_count.stat[0].uvalue = reg[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) read_register_block(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) (HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) HYDRA_DMD_STATUS_OFFSET(state->demod)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) (7 * sizeof(u32)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) (u8 *) ®[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) switch (p->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) case SYS_DSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) p->post_bit_error.stat[0].uvalue = reg[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) p->post_bit_count.stat[0].uvalue = reg[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) p->post_bit_error.stat[0].uvalue = reg[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) p->post_bit_count.stat[0].uvalue = reg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) mutex_unlock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static int read_signal_strength(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) u32 reg_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) mutex_lock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) stat = read_register(state, (HYDRA_DMD_STATUS_INPUT_POWER_ADDR +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) HYDRA_DMD_STATUS_OFFSET(state->demod)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) mutex_unlock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) p->strength.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) p->strength.stat[0].svalue = (s16) reg_data * 10; /* fix scale */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int read_status(struct dvb_frontend *fe, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) u32 reg_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) mutex_lock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) read_register(state, (HYDRA_DMD_LOCK_STATUS_ADDR_OFFSET +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) HYDRA_DMD_STATUS_OFFSET(state->demod)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) mutex_unlock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) *status = (reg_data == 1) ? 0x1f : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) /* signal statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* signal strength is always available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) read_signal_strength(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (*status & FE_HAS_CARRIER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) read_snr(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (*status & FE_HAS_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) read_ber(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int tune(struct dvb_frontend *fe, bool re_tune,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) unsigned int mode_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) unsigned int *delay, enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) *delay = HZ / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (re_tune) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) r = set_parameters(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) state->tune_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return read_status(fe, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) static enum fe_code_rate conv_fec(enum MXL_HYDRA_FEC_E fec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) enum fe_code_rate fec2fec[11] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) FEC_NONE, FEC_1_2, FEC_3_5, FEC_2_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) FEC_7_8, FEC_8_9, FEC_9_10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (fec > MXL_HYDRA_FEC_9_10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return FEC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return fec2fec[fec];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static int get_frontend(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct dtv_frontend_properties *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) u32 reg_data[MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) u32 freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) mutex_lock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) read_register_block(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) (HYDRA_DMD_STANDARD_ADDR_OFFSET +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) HYDRA_DMD_STATUS_OFFSET(state->demod)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) (MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE * 4), /* 25 * 4 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) (u8 *) ®_data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* read demod channel parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) read_register_block(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) (HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) HYDRA_DMD_STATUS_OFFSET(state->demod)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) (4), /* 4 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) (u8 *) &freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) mutex_unlock(&state->base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) dev_dbg(state->i2cdev, "freq=%u delsys=%u srate=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) freq * 1000, reg_data[DMD_STANDARD_ADDR],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) reg_data[DMD_SYMBOL_RATE_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) p->symbol_rate = reg_data[DMD_SYMBOL_RATE_ADDR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) p->frequency = freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * p->delivery_system =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * (MXL_HYDRA_BCAST_STD_E) regData[DMD_STANDARD_ADDR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * p->inversion =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * (MXL_HYDRA_SPECTRUM_E) regData[DMD_SPECTRUM_INVERSION_ADDR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * freqSearchRangeKHz =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * (regData[DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) p->fec_inner = conv_fec(reg_data[DMD_FEC_CODE_RATE_ADDR]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) switch (p->delivery_system) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) case SYS_DSS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) case SYS_DVBS2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) switch ((enum MXL_HYDRA_PILOTS_E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) reg_data[DMD_DVBS2_PILOT_ON_OFF_ADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) case MXL_HYDRA_PILOTS_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) p->pilot = PILOT_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) case MXL_HYDRA_PILOTS_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) p->pilot = PILOT_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) case SYS_DVBS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) switch ((enum MXL_HYDRA_MODULATION_E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) reg_data[DMD_MODULATION_SCHEME_ADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) case MXL_HYDRA_MOD_QPSK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) p->modulation = QPSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case MXL_HYDRA_MOD_8PSK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) p->modulation = PSK_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) switch ((enum MXL_HYDRA_ROLLOFF_E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) reg_data[DMD_SPECTRUM_ROLL_OFF_ADDR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) case MXL_HYDRA_ROLLOFF_0_20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) p->rolloff = ROLLOFF_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) case MXL_HYDRA_ROLLOFF_0_35:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) p->rolloff = ROLLOFF_35;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) case MXL_HYDRA_ROLLOFF_0_25:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) p->rolloff = ROLLOFF_25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static int set_input(struct dvb_frontend *fe, int input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) struct mxl *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) state->tuner = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) static const struct dvb_frontend_ops mxl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) .name = "MaxLinear MxL5xx DVB-S/S2 tuner-demodulator",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) .frequency_min_hz = 300 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) .frequency_max_hz = 2350 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) .symbol_rate_min = 1000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) .symbol_rate_max = 45000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) .caps = FE_CAN_INVERSION_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) FE_CAN_QPSK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) FE_CAN_2G_MODULATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) .init = init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) .release = release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) .get_frontend_algo = get_algo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) .tune = tune,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .read_status = read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .sleep = sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) .get_frontend = get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) .diseqc_send_master_cmd = send_master_cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static struct mxl_base *match_base(struct i2c_adapter *i2c, u8 adr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct mxl_base *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) list_for_each_entry(p, &mxllist, mxllist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (p->i2c == i2c && p->adr == adr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static void cfg_dev_xtal(struct mxl *state, u32 freq, u32 cap, u32 enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (state->base->can_clkout || !enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) update_by_mnemonic(state, 0x90200054, 23, 1, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (freq == 24000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) write_register(state, HYDRA_CRYSTAL_SETTING, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) write_register(state, HYDRA_CRYSTAL_SETTING, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) write_register(state, HYDRA_CRYSTAL_CAP, cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) static u32 get_big_endian(u8 num_of_bits, const u8 buf[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) u32 ret_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) switch (num_of_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) case 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) ret_value = (((u32) buf[0]) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) (((u32) buf[1]) << 8) | buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) ret_value = (((u32) buf[0]) << 24) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) (((u32) buf[1]) << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) (((u32) buf[2]) << 8) | buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return ret_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static int write_fw_segment(struct mxl *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) u32 mem_addr, u32 total_size, u8 *data_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) u32 data_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) u32 size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) u32 orig_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) u8 *w_buf_ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) u32 block_size = ((MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) (MXL_HYDRA_I2C_HDR_SIZE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) u8 w_msg_buffer[MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) (MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) size = orig_size = (((u32)(data_count + block_size)) > total_size) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) (total_size - data_count) : block_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (orig_size & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) size = (orig_size + 4) & ~3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) w_buf_ptr = &w_msg_buffer[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) memset((void *) w_buf_ptr, 0, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) memcpy((void *) w_buf_ptr, (void *) data_ptr, orig_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) convert_endian(1, size, w_buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) status = write_firmware_block(state, mem_addr, size, w_buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) data_count += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) mem_addr += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) data_ptr += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) } while (data_count < total_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) static int do_firmware_download(struct mxl *state, u8 *mbin_buffer_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) u32 mbin_buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) u32 index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) u32 seg_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) u32 seg_address = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct MBIN_FILE_T *mbin_ptr = (struct MBIN_FILE_T *)mbin_buffer_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct MBIN_SEGMENT_T *segment_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) enum MXL_BOOL_E xcpu_fw_flag = MXL_FALSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (mbin_ptr->header.id != MBIN_FILE_HEADER_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) dev_err(state->i2cdev, "%s: Invalid file header ID (%c)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) __func__, mbin_ptr->header.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) status = write_register(state, FW_DL_SIGN_ADDR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) segment_ptr = (struct MBIN_SEGMENT_T *) (&mbin_ptr->data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) for (index = 0; index < mbin_ptr->header.num_segments; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (segment_ptr->header.id != MBIN_SEGMENT_HEADER_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) dev_err(state->i2cdev, "%s: Invalid segment header ID (%c)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) __func__, segment_ptr->header.id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) seg_length = get_big_endian(24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) &(segment_ptr->header.len24[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) seg_address = get_big_endian(32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) &(segment_ptr->header.address[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (state->base->type == MXL_HYDRA_DEVICE_568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if ((((seg_address & 0x90760000) == 0x90760000) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) ((seg_address & 0x90740000) == 0x90740000)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) (xcpu_fw_flag == MXL_FALSE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) update_by_mnemonic(state, 0x8003003C, 0, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) write_register(state, 0x90720000, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) usleep_range(10000, 11000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) xcpu_fw_flag = MXL_TRUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) status = write_fw_segment(state, seg_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) seg_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) (u8 *) segment_ptr->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (((seg_address & 0x90760000) != 0x90760000) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ((seg_address & 0x90740000) != 0x90740000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) status = write_fw_segment(state, seg_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) seg_length, (u8 *) segment_ptr->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) segment_ptr = (struct MBIN_SEGMENT_T *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) &(segment_ptr->data[((seg_length + 3) / 4) * 4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static int check_fw(struct mxl *state, u8 *mbin, u32 mbin_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct MBIN_FILE_HEADER_T *fh = (struct MBIN_FILE_HEADER_T *) mbin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) u32 flen = (fh->image_size24[0] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) (fh->image_size24[1] << 8) | fh->image_size24[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) u8 *fw, cs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (fh->id != 'M' || fh->fmt_version != '1' || flen > 0x3FFF0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) dev_info(state->i2cdev, "Invalid FW Header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) fw = mbin + sizeof(struct MBIN_FILE_HEADER_T);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) for (i = 0; i < flen; i += 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) cs += fw[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (cs != fh->image_checksum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dev_info(state->i2cdev, "Invalid FW Checksum\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) u32 reg_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct MXL_HYDRA_SKU_COMMAND_T dev_sku_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) u8 cmd_size = sizeof(struct MXL_HYDRA_SKU_COMMAND_T);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) u8 cmd_buff[sizeof(struct MXL_HYDRA_SKU_COMMAND_T) + 6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (check_fw(state, mbin, mbin_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /* put CPU into reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) status = update_by_mnemonic(state, 0x8003003C, 0, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /* Reset TX FIFO's, BBAND, XBAR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) status = write_register(state, HYDRA_RESET_TRANSPORT_FIFO_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) HYDRA_RESET_TRANSPORT_FIFO_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) status = write_register(state, HYDRA_RESET_BBAND_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) HYDRA_RESET_BBAND_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) status = write_register(state, HYDRA_RESET_XBAR_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) HYDRA_RESET_XBAR_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) /* Disable clock to Baseband, Wideband, SerDes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * Alias ext & Transport modules
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) status = write_register(state, HYDRA_MODULES_CLK_2_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) HYDRA_DISABLE_CLK_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /* Clear Software & Host interrupt status - (Clear on read) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) status = read_register(state, HYDRA_PRCM_ROOT_CLK_REG, ®_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) status = do_firmware_download(state, mbin, mbin_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (state->base->type == MXL_HYDRA_DEVICE_568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) usleep_range(10000, 11000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* bring XCPU out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) status = write_register(state, 0x90720000, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /* Enable XCPU UART message processing in MCPU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) status = write_register(state, 0x9076B510, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) /* Bring CPU out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) status = update_by_mnemonic(state, 0x8003003C, 0, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* Wait until FW boots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) msleep(150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* Initialize XPT XBAR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) status = write_register(state, XPT_DMD0_BASEADDR, 0x76543210);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (!firmware_is_alive(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) dev_info(state->i2cdev, "Hydra FW alive. Hail!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) /* sometimes register values are wrong shortly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * after first heart beats
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) dev_sku_cfg.sku_type = state->base->sku_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) BUILD_HYDRA_CMD(MXL_HYDRA_DEV_CFG_SKU_CMD, MXL_CMD_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) cmd_size, &dev_sku_cfg, cmd_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) status = send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) &cmd_buff[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static int cfg_ts_pad_mux(struct mxl *state, enum MXL_BOOL_E enable_serial_ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) u32 pad_mux_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (enable_serial_ts == MXL_TRUE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) pad_mux_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if ((state->base->type == MXL_HYDRA_DEVICE_541) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) (state->base->type == MXL_HYDRA_DEVICE_541S))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) pad_mux_value = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if ((state->base->type == MXL_HYDRA_DEVICE_581) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) (state->base->type == MXL_HYDRA_DEVICE_581S))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) pad_mux_value = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) pad_mux_value = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) switch (state->base->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) case MXL_HYDRA_DEVICE_561:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) case MXL_HYDRA_DEVICE_581:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) case MXL_HYDRA_DEVICE_541:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) case MXL_HYDRA_DEVICE_541S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) case MXL_HYDRA_DEVICE_561S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) case MXL_HYDRA_DEVICE_581S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) status |= update_by_mnemonic(state, 0x90000170, 24, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) status |= update_by_mnemonic(state, 0x90000170, 28, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) status |= update_by_mnemonic(state, 0x90000174, 0, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) status |= update_by_mnemonic(state, 0x90000174, 4, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) status |= update_by_mnemonic(state, 0x90000174, 8, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) status |= update_by_mnemonic(state, 0x90000174, 12, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) status |= update_by_mnemonic(state, 0x90000174, 16, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) status |= update_by_mnemonic(state, 0x90000174, 20, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) status |= update_by_mnemonic(state, 0x90000174, 24, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) status |= update_by_mnemonic(state, 0x90000174, 28, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) status |= update_by_mnemonic(state, 0x90000178, 0, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) status |= update_by_mnemonic(state, 0x90000178, 4, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) status |= update_by_mnemonic(state, 0x90000178, 8, 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) case MXL_HYDRA_DEVICE_544:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) case MXL_HYDRA_DEVICE_542:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) status |= update_by_mnemonic(state, 0x9000016C, 4, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) status |= update_by_mnemonic(state, 0x9000016C, 8, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) status |= update_by_mnemonic(state, 0x9000016C, 12, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) status |= update_by_mnemonic(state, 0x9000016C, 16, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) status |= update_by_mnemonic(state, 0x90000170, 0, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) status |= update_by_mnemonic(state, 0x90000178, 12, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) status |= update_by_mnemonic(state, 0x90000178, 16, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) status |= update_by_mnemonic(state, 0x90000178, 20, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) status |= update_by_mnemonic(state, 0x90000178, 24, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) status |= update_by_mnemonic(state, 0x9000017C, 0, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) status |= update_by_mnemonic(state, 0x9000017C, 4, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (enable_serial_ts == MXL_ENABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 0x90000170, 4, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 0x90000170, 8, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 0x90000170, 12, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 0x90000170, 16, 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 0x90000170, 20, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 0x90000170, 24, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 0x90000170, 28, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 0x90000174, 0, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 0x90000174, 4, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 0x90000174, 8, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 0x90000174, 12, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 0x90000174, 16, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 0x90000174, 20, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 0x90000174, 24, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 0x90000174, 28, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 0x90000178, 0, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 0x90000178, 4, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 0x90000178, 8, 3, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 0x90000170, 4, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 0x90000170, 8, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 0x90000170, 12, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 0x90000170, 16, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 0x90000170, 20, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 0x90000170, 24, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 0x90000170, 28, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 0x90000174, 0, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 0x90000174, 4, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 0x90000174, 8, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 0x90000174, 12, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 0x90000174, 16, 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 0x90000174, 20, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 0x90000174, 24, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 0x90000174, 28, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 0x90000178, 0, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 0x90000178, 4, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 0x90000178, 8, 3, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) case MXL_HYDRA_DEVICE_568:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (enable_serial_ts == MXL_FALSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 0x9000016C, 8, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 0x9000016C, 12, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 0x9000016C, 16, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 0x9000016C, 20, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 0x9000016C, 24, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 0x9000016C, 28, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 0x90000170, 0, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 0x90000170, 4, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 0x90000170, 8, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 0x90000170, 12, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 0x90000170, 16, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 0x90000170, 20, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 0x90000170, 24, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 0x90000174, 0, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 0x90000174, 4, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 0x90000174, 8, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 0x90000174, 12, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 0x90000174, 16, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 0x90000174, 20, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 0x90000174, 24, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 0x90000174, 28, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 0x90000178, 0, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 0x90000178, 4, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 0x90000178, 8, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 0x90000178, 12, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 0x90000178, 16, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 0x90000178, 20, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 0x90000178, 24, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 0x90000178, 28, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 0x9000017C, 0, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 0x9000017C, 4, 3, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 0x90000170, 4, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 0x90000170, 8, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 0x90000170, 12, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 0x90000170, 16, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 0x90000170, 20, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 0x90000170, 24, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 0x90000170, 28, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 0x90000174, 0, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 0x90000174, 4, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 0x90000174, 8, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 0x90000174, 12, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) case MXL_HYDRA_DEVICE_584:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 0x90000170, 4, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 0x90000170, 8, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 0x90000170, 12, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 0x90000170, 16, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 0x90000170, 20, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 0x90000170, 24, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 0x90000170, 28, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 0x90000174, 0, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 0x90000174, 4, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 0x90000174, 8, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 0x90000174, 12, 3, pad_mux_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static int set_drive_strength(struct mxl *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) enum MXL_HYDRA_TS_DRIVE_STRENGTH_E ts_drive_strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) int stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) read_register(state, 0x90000194, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) dev_info(state->i2cdev, "DIGIO = %08x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) dev_info(state->i2cdev, "set drive_strength = %u\n", ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) stat |= update_by_mnemonic(state, 0x90000194, 0, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) stat |= update_by_mnemonic(state, 0x90000194, 20, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) stat |= update_by_mnemonic(state, 0x90000194, 24, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) stat |= update_by_mnemonic(state, 0x90000198, 12, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) stat |= update_by_mnemonic(state, 0x90000198, 16, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) stat |= update_by_mnemonic(state, 0x90000198, 20, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) stat |= update_by_mnemonic(state, 0x90000198, 24, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) stat |= update_by_mnemonic(state, 0x9000019C, 0, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) stat |= update_by_mnemonic(state, 0x9000019C, 4, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) stat |= update_by_mnemonic(state, 0x9000019C, 8, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) stat |= update_by_mnemonic(state, 0x9000019C, 24, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) stat |= update_by_mnemonic(state, 0x9000019C, 28, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) stat |= update_by_mnemonic(state, 0x900001A0, 0, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) stat |= update_by_mnemonic(state, 0x900001A0, 4, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) stat |= update_by_mnemonic(state, 0x900001A0, 20, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) stat |= update_by_mnemonic(state, 0x900001A0, 24, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) stat |= update_by_mnemonic(state, 0x900001A0, 28, 3, ts_drive_strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) static int enable_tuner(struct mxl *state, u32 tuner, u32 enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) int stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) struct MXL_HYDRA_TUNER_CMD ctrl_tuner_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) u8 cmd_size = sizeof(ctrl_tuner_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) u8 cmd_buff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) u32 val, count = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) ctrl_tuner_cmd.tuner_id = tuner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) ctrl_tuner_cmd.enable = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) BUILD_HYDRA_CMD(MXL_HYDRA_TUNER_ACTIVATE_CMD, MXL_CMD_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) cmd_size, &ctrl_tuner_cmd, cmd_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) stat = send_command(state, cmd_size + MXL_HYDRA_CMD_HEADER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) &cmd_buff[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) while (--count && ((val >> tuner) & 1) != enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) if (!count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) dev_dbg(state->i2cdev, "tuner %u ready = %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) tuner, (val >> tuner) & 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) static int config_ts(struct mxl *state, enum MXL_HYDRA_DEMOD_ID_E demod_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) struct MXL_HYDRA_MPEGOUT_PARAM_T *mpeg_out_param_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) u32 nco_count_min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) u32 clk_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) struct MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {0x90700010, 8, 1}, {0x90700010, 9, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) {0x90700010, 10, 1}, {0x90700010, 11, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) {0x90700010, 12, 1}, {0x90700010, 13, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) {0x90700010, 14, 1}, {0x90700010, 15, 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) struct MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) {0x90700010, 16, 1}, {0x90700010, 17, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {0x90700010, 18, 1}, {0x90700010, 19, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) {0x90700010, 20, 1}, {0x90700010, 21, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) {0x90700010, 22, 1}, {0x90700010, 23, 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) {0x90700014, 0, 1}, {0x90700014, 1, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) {0x90700014, 2, 1}, {0x90700014, 3, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) {0x90700014, 4, 1}, {0x90700014, 5, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) {0x90700014, 6, 1}, {0x90700014, 7, 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) struct MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) {0x90700018, 0, 3}, {0x90700018, 4, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) {0x90700018, 8, 3}, {0x90700018, 12, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) {0x90700018, 16, 3}, {0x90700018, 20, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) {0x90700018, 24, 3}, {0x90700018, 28, 3} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) struct MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) {0x9070000C, 16, 1}, {0x9070000C, 17, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) {0x9070000C, 18, 1}, {0x9070000C, 19, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {0x9070000C, 20, 1}, {0x9070000C, 21, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) {0x9070000C, 22, 1}, {0x9070000C, 23, 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) struct MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {0x90700010, 0, 1}, {0x90700010, 1, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) {0x90700010, 2, 1}, {0x90700010, 3, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) {0x90700010, 4, 1}, {0x90700010, 5, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) {0x90700010, 6, 1}, {0x90700010, 7, 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) struct MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) {0x9070000C, 0, 1}, {0x9070000C, 1, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) {0x9070000C, 2, 1}, {0x9070000C, 3, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) {0x9070000C, 4, 1}, {0x9070000C, 5, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) {0x9070000C, 6, 1}, {0x9070000C, 7, 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) struct MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) {0x9070000C, 24, 1}, {0x9070000C, 25, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) {0x9070000C, 26, 1}, {0x9070000C, 27, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) {0x9070000C, 28, 1}, {0x9070000C, 29, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) {0x9070000C, 30, 1}, {0x9070000C, 31, 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) struct MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) {0x90700014, 8, 1}, {0x90700014, 9, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {0x90700014, 10, 1}, {0x90700014, 11, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) {0x90700014, 12, 1}, {0x90700014, 13, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) {0x90700014, 14, 1}, {0x90700014, 15, 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) struct MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) {0x907001D4, 0, 1}, {0x907001D4, 1, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) {0x907001D4, 2, 1}, {0x907001D4, 3, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) {0x907001D4, 4, 1}, {0x907001D4, 5, 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) {0x907001D4, 6, 1}, {0x907001D4, 7, 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) struct MXL_REG_FIELD_T xpt_nco_clock_rate[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) {0x90700044, 16, 80}, {0x90700044, 16, 81},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) {0x90700044, 16, 82}, {0x90700044, 16, 83},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) {0x90700044, 16, 84}, {0x90700044, 16, 85},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) {0x90700044, 16, 86}, {0x90700044, 16, 87} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) demod_id = state->base->ts_map[demod_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if (mpeg_out_param_ptr->enable == MXL_ENABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (mpeg_out_param_ptr->mpeg_mode ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) MXL_HYDRA_MPEG_MODE_PARALLEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) cfg_ts_pad_mux(state, MXL_TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 0x90700010, 27, 1, MXL_FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) nco_count_min =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) (u32)(MXL_HYDRA_NCO_CLK / mpeg_out_param_ptr->max_mpeg_clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) if (state->base->chipversion >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) xpt_nco_clock_rate[demod_id].reg_addr, /* Reg Addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) xpt_nco_clock_rate[demod_id].lsb_pos, /* LSB pos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) xpt_nco_clock_rate[demod_id].num_of_bits, /* Num of bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) nco_count_min); /* Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) update_by_mnemonic(state, 0x90700044, 16, 8, nco_count_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (mpeg_out_param_ptr->mpeg_clk_type == MXL_HYDRA_MPEG_CLK_CONTINUOUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) clk_type = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (mpeg_out_param_ptr->mpeg_mode < MXL_HYDRA_MPEG_MODE_PARALLEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) xpt_continuous_clock[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) xpt_continuous_clock[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) xpt_continuous_clock[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) clk_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) update_by_mnemonic(state, 0x907001D4, 8, 1, clk_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) xpt_sync_polarity[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) xpt_sync_polarity[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) xpt_sync_polarity[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) mpeg_out_param_ptr->mpeg_sync_pol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) xpt_valid_polarity[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) xpt_valid_polarity[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) xpt_valid_polarity[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) mpeg_out_param_ptr->mpeg_valid_pol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) xpt_clock_polarity[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) xpt_clock_polarity[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) xpt_clock_polarity[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) mpeg_out_param_ptr->mpeg_clk_pol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) xpt_sync_byte[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) xpt_sync_byte[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) xpt_sync_byte[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) mpeg_out_param_ptr->mpeg_sync_pulse_width);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) xpt_ts_clock_phase[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) xpt_ts_clock_phase[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) xpt_ts_clock_phase[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) mpeg_out_param_ptr->mpeg_clk_phase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) xpt_lsb_first[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) xpt_lsb_first[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) xpt_lsb_first[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) mpeg_out_param_ptr->lsb_or_msb_first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) switch (mpeg_out_param_ptr->mpeg_error_indication) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) case MXL_HYDRA_MPEG_ERR_REPLACE_SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) xpt_err_replace_sync[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) xpt_err_replace_sync[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) xpt_err_replace_sync[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) MXL_TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) xpt_err_replace_valid[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) xpt_err_replace_valid[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) xpt_err_replace_valid[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) MXL_FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) case MXL_HYDRA_MPEG_ERR_REPLACE_VALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) xpt_err_replace_sync[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) xpt_err_replace_sync[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) xpt_err_replace_sync[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) MXL_FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) xpt_err_replace_valid[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) xpt_err_replace_valid[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) xpt_err_replace_valid[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) MXL_TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) case MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) xpt_err_replace_sync[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) xpt_err_replace_sync[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) xpt_err_replace_sync[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) MXL_FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) xpt_err_replace_valid[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) xpt_err_replace_valid[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) xpt_err_replace_valid[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) MXL_FALSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) if (mpeg_out_param_ptr->mpeg_mode != MXL_HYDRA_MPEG_MODE_PARALLEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) status |= update_by_mnemonic(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) xpt_enable_output[demod_id].reg_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) xpt_enable_output[demod_id].lsb_pos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) xpt_enable_output[demod_id].num_of_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) mpeg_out_param_ptr->enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) static int config_mux(struct mxl *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) update_by_mnemonic(state, 0x9070000C, 0, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) update_by_mnemonic(state, 0x9070000C, 1, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) update_by_mnemonic(state, 0x9070000C, 2, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) update_by_mnemonic(state, 0x9070000C, 3, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) update_by_mnemonic(state, 0x9070000C, 4, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) update_by_mnemonic(state, 0x9070000C, 5, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) update_by_mnemonic(state, 0x9070000C, 6, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) update_by_mnemonic(state, 0x9070000C, 7, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) update_by_mnemonic(state, 0x90700008, 0, 2, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) update_by_mnemonic(state, 0x90700008, 2, 2, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) int stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) if (cfg->fw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) return firmware_download(state, cfg->fw, cfg->fw_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) if (!cfg->fw_read)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) buf = vmalloc(0x40000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) cfg->fw_read(cfg->fw_priv, buf, 0x40000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) stat = firmware_download(state, buf, 0x40000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) vfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) static int validate_sku(struct mxl *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) u32 pad_mux_bond = 0, prcm_chip_id = 0, prcm_so_cid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) u32 type = state->base->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) status = read_by_mnemonic(state, 0x90000190, 0, 3, &pad_mux_bond);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) status |= read_by_mnemonic(state, 0x80030000, 0, 12, &prcm_chip_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) status |= read_by_mnemonic(state, 0x80030004, 24, 8, &prcm_so_cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) dev_info(state->i2cdev, "padMuxBond=%08x, prcmChipId=%08x, prcmSoCId=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) pad_mux_bond, prcm_chip_id, prcm_so_cid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (prcm_chip_id != 0x560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) switch (pad_mux_bond) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) case MXL_HYDRA_SKU_ID_581:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (type == MXL_HYDRA_DEVICE_581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (type == MXL_HYDRA_DEVICE_581S) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) state->base->type = MXL_HYDRA_DEVICE_581;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) case MXL_HYDRA_SKU_ID_584:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (type == MXL_HYDRA_DEVICE_584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) case MXL_HYDRA_SKU_ID_544:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (type == MXL_HYDRA_DEVICE_544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) if (type == MXL_HYDRA_DEVICE_542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) case MXL_HYDRA_SKU_ID_582:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) if (type == MXL_HYDRA_DEVICE_582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) static int get_fwinfo(struct mxl *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) u32 val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) status = read_by_mnemonic(state, 0x90000190, 0, 3, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) dev_info(state->i2cdev, "chipID=%08x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) status = read_by_mnemonic(state, 0x80030004, 8, 8, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) dev_info(state->i2cdev, "chipVer=%08x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) status = read_register(state, HYDRA_FIRMWARE_VERSION, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) dev_info(state->i2cdev, "FWVer=%08x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) state->base->fwversion = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) static u8 ts_map1_to_1[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) MXL_HYDRA_DEMOD_ID_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) MXL_HYDRA_DEMOD_ID_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) MXL_HYDRA_DEMOD_ID_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) MXL_HYDRA_DEMOD_ID_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) MXL_HYDRA_DEMOD_ID_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) MXL_HYDRA_DEMOD_ID_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) MXL_HYDRA_DEMOD_ID_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) MXL_HYDRA_DEMOD_ID_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) static u8 ts_map54x[MXL_HYDRA_DEMOD_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) MXL_HYDRA_DEMOD_ID_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) MXL_HYDRA_DEMOD_ID_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) MXL_HYDRA_DEMOD_ID_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) MXL_HYDRA_DEMOD_ID_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) MXL_HYDRA_DEMOD_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) MXL_HYDRA_DEMOD_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) MXL_HYDRA_DEMOD_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) MXL_HYDRA_DEMOD_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) static int probe(struct mxl *state, struct mxl5xx_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) u32 chipver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) int fw, status, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) struct MXL_HYDRA_MPEGOUT_PARAM_T mpeg_interface_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) state->base->ts_map = ts_map1_to_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) switch (state->base->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) case MXL_HYDRA_DEVICE_581:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) case MXL_HYDRA_DEVICE_581S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) state->base->can_clkout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) state->base->demod_num = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) state->base->tuner_num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) state->base->sku_type = MXL_HYDRA_SKU_TYPE_581;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) case MXL_HYDRA_DEVICE_582:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) state->base->can_clkout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) state->base->demod_num = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) state->base->tuner_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) state->base->sku_type = MXL_HYDRA_SKU_TYPE_582;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) case MXL_HYDRA_DEVICE_585:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) state->base->can_clkout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) state->base->demod_num = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) state->base->tuner_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) state->base->sku_type = MXL_HYDRA_SKU_TYPE_585;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) case MXL_HYDRA_DEVICE_544:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) state->base->can_clkout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) state->base->demod_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) state->base->tuner_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) state->base->sku_type = MXL_HYDRA_SKU_TYPE_544;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) state->base->ts_map = ts_map54x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) case MXL_HYDRA_DEVICE_541:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) case MXL_HYDRA_DEVICE_541S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) state->base->can_clkout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) state->base->demod_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) state->base->tuner_num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) state->base->sku_type = MXL_HYDRA_SKU_TYPE_541;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) state->base->ts_map = ts_map54x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) case MXL_HYDRA_DEVICE_561:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) case MXL_HYDRA_DEVICE_561S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) state->base->can_clkout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) state->base->demod_num = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) state->base->tuner_num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) state->base->sku_type = MXL_HYDRA_SKU_TYPE_561;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) case MXL_HYDRA_DEVICE_568:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) state->base->can_clkout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) state->base->demod_num = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) state->base->tuner_num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) state->base->chan_bond = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) state->base->sku_type = MXL_HYDRA_SKU_TYPE_568;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) case MXL_HYDRA_DEVICE_542:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) state->base->can_clkout = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) state->base->demod_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) state->base->tuner_num = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) state->base->sku_type = MXL_HYDRA_SKU_TYPE_542;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) state->base->ts_map = ts_map54x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) case MXL_HYDRA_DEVICE_TEST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) case MXL_HYDRA_DEVICE_584:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) state->base->can_clkout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) state->base->demod_num = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) state->base->tuner_num = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) state->base->sku_type = MXL_HYDRA_SKU_TYPE_584;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) status = validate_sku(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) update_by_mnemonic(state, 0x80030014, 9, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) update_by_mnemonic(state, 0x8003003C, 12, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) status = read_by_mnemonic(state, 0x80030000, 12, 4, &chipver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) state->base->chipversion = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) state->base->chipversion = (chipver == 2) ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) dev_info(state->i2cdev, "Hydra chip version %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) state->base->chipversion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) cfg_dev_xtal(state, cfg->clk, cfg->cap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) fw = firmware_is_alive(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) if (!fw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) status = load_fw(state, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) get_fwinfo(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) config_mux(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) mpeg_interface_cfg.enable = MXL_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) mpeg_interface_cfg.lsb_or_msb_first = MXL_HYDRA_MPEG_SERIAL_MSB_1ST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) /* supports only (0-104&139)MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) if (cfg->ts_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) mpeg_interface_cfg.max_mpeg_clk_rate = cfg->ts_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) mpeg_interface_cfg.max_mpeg_clk_rate = 69; /* 139; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) mpeg_interface_cfg.mpeg_clk_phase = MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_0_DEG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) mpeg_interface_cfg.mpeg_clk_pol = MXL_HYDRA_MPEG_CLK_IN_PHASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) /* MXL_HYDRA_MPEG_CLK_GAPPED; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) mpeg_interface_cfg.mpeg_clk_type = MXL_HYDRA_MPEG_CLK_CONTINUOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) mpeg_interface_cfg.mpeg_error_indication =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) mpeg_interface_cfg.mpeg_mode = MXL_HYDRA_MPEG_MODE_SERIAL_3_WIRE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) mpeg_interface_cfg.mpeg_sync_pol = MXL_HYDRA_MPEG_ACTIVE_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) mpeg_interface_cfg.mpeg_sync_pulse_width = MXL_HYDRA_MPEG_SYNC_WIDTH_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) mpeg_interface_cfg.mpeg_valid_pol = MXL_HYDRA_MPEG_ACTIVE_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) for (j = 0; j < state->base->demod_num; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) status = config_ts(state, (enum MXL_HYDRA_DEMOD_ID_E) j,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) &mpeg_interface_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) set_drive_strength(state, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) struct mxl5xx_cfg *cfg, u32 demod, u32 tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) int (**fn_set_input)(struct dvb_frontend *, int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) struct mxl *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) struct mxl_base *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) state = kzalloc(sizeof(struct mxl), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) if (!state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) state->demod = demod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) state->tuner = tuner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) state->tuner_in_use = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) state->i2cdev = &i2c->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) base = match_base(i2c, cfg->adr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) if (base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) base->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (base->count > base->demod_num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) state->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) base = kzalloc(sizeof(struct mxl_base), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (!base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) base->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) base->adr = cfg->adr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) base->type = cfg->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) base->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) mutex_init(&base->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) mutex_init(&base->status_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) mutex_init(&base->tune_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) INIT_LIST_HEAD(&base->mxls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) state->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if (probe(state, cfg) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) kfree(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) list_add(&base->mxllist, &mxllist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) state->fe.ops = mxl_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) state->xbar[0] = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) state->xbar[1] = demod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) state->xbar[2] = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) state->fe.demodulator_priv = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) *fn_set_input = set_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) list_add(&state->mxl, &base->mxls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) return &state->fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) EXPORT_SYMBOL_GPL(mxl5xx_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) MODULE_DESCRIPTION("MaxLinear MxL5xx DVB-S/S2 tuner-demodulator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) MODULE_LICENSE("GPL v2");