^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Linux-DVB Driver for DiBcom's DiB7000M and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * first generation DiB7000P-demodulator-family.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "dib7000m.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define dprintk(fmt, arg...) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) if (debug) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) printk(KERN_DEBUG pr_fmt("%s: " fmt), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) __func__, ##arg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct dib7000m_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct dvb_frontend demod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct dib7000m_config cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u8 i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct i2c_adapter *i2c_adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct dibx000_i2c_master i2c_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* offset is 1 in case of the 7000MC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 reg_offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u16 wbd_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u8 current_band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u32 current_bandwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct dibx000_agc_config *current_agc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) u32 timf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u32 timf_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u32 internal_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u8 div_force_off : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u8 div_state : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u16 div_sync_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u16 revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u8 agc_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* for the I2C transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct i2c_msg msg[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u8 i2c_write_buffer[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u8 i2c_read_buffer[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct mutex i2c_buffer_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) enum dib7000m_power_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) DIB7000M_POWER_ALL = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) DIB7000M_POWER_NO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) DIB7000M_POWER_INTERF_ANALOG_AGC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) DIB7000M_POWER_INTERFACE_ONLY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u16 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) dprintk("could not acquire lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) state->i2c_write_buffer[1] = reg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) state->msg[0].addr = state->i2c_addr >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) state->msg[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) state->msg[0].buf = state->i2c_write_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) state->msg[0].len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) state->msg[1].addr = state->i2c_addr >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) state->msg[1].flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) state->msg[1].buf = state->i2c_read_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) state->msg[1].len = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) dprintk("i2c read error on %d\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) mutex_unlock(&state->i2c_buffer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) dprintk("could not acquire lock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) state->i2c_write_buffer[1] = reg & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) state->i2c_write_buffer[2] = (val >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) state->i2c_write_buffer[3] = val & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) memset(&state->msg[0], 0, sizeof(struct i2c_msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) state->msg[0].addr = state->i2c_addr >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) state->msg[0].flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) state->msg[0].buf = state->i2c_write_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) state->msg[0].len = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) -EREMOTEIO : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) mutex_unlock(&state->i2c_buffer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u16 l = 0, r, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) n = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) l = *n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) while (l) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) r = *n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) r++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) dib7000m_write_word(state, r, *n++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) r++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) } while (--l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) l = *n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) u16 outreg, fifo_threshold, smo_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) sram = 0x0005; /* by default SRAM output is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) outreg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) fifo_threshold = 1792;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) dprintk("setting output mode for demod %p to %d\n", &state->demod, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) outreg = (1 << 10); /* 0x0400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) outreg = (1 << 10) | (1 << 6); /* 0x0440 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) case OUTMODE_MPEG2_SERIAL: // STBs with serial input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) case OUTMODE_DIVERSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (state->cfg.hostbus_diversity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) outreg = (1 << 10) | (4 << 6); /* 0x0500 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) sram |= 0x0c00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) smo_mode |= (3 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) fifo_threshold = 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) outreg = (1 << 10) | (5 << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case OUTMODE_HIGH_Z: // disable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) outreg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->demod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (state->cfg.output_mpeg2_in_188_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) smo_mode |= (1 << 5) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) ret |= dib7000m_write_word(state, 294 + state->reg_offs, smo_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) ret |= dib7000m_write_word(state, 295 + state->reg_offs, fifo_threshold); /* synchronous fread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ret |= dib7000m_write_word(state, 1795, outreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ret |= dib7000m_write_word(state, 1805, sram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (state->revision == 0x4003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (mode == OUTMODE_DIVERSITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) clk_cfg1 |= (1 << 1); // P_O_CLK_en
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) dib7000m_write_word(state, 909, clk_cfg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* by default everything is going to be powered off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906 = 0x3fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u8 offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* now, depending on the requested mode, we power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* power up everything in the demod */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case DIB7000M_POWER_ALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case DIB7000M_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) case DIB7000M_POWER_INTERF_ANALOG_AGC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) reg_906 &= ~((1 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case DIB7000M_POWER_NO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* always power down unused parts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!state->cfg.mobile_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* P_sdio_select_clk = 0 on MC and after*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (state->revision != 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) reg_906 <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (state->revision == 0x4003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) offset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) dib7000m_write_word(state, 903 + offset, reg_903);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) dib7000m_write_word(state, 904 + offset, reg_904);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) dib7000m_write_word(state, 905 + offset, reg_905);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dib7000m_write_word(state, 906 + offset, reg_906);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) u16 reg_913 = dib7000m_read_word(state, 913),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) reg_914 = dib7000m_read_word(state, 914);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) switch (no) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case DIBX000_SLOW_ADC_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) reg_914 |= (1 << 1) | (1 << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ret |= dib7000m_write_word(state, 914, reg_914);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) reg_914 &= ~(1 << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) case DIBX000_SLOW_ADC_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) reg_914 |= (1 << 1) | (1 << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case DIBX000_ADC_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (state->revision == 0x4000) { // workaround for PA/MA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) // power-up ADC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) dib7000m_write_word(state, 913, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) dib7000m_write_word(state, 914, reg_914 & 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) // power-down bandgag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) dib7000m_write_word(state, 913, (1 << 15));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) dib7000m_write_word(state, 914, reg_914 & 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) reg_913 &= 0x0fff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) reg_914 &= 0x0003;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) case DIBX000_ADC_OFF: // leave the VBG voltage on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) reg_913 |= (1 << 14) | (1 << 13) | (1 << 12);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) case DIBX000_VBG_ENABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) reg_913 &= ~(1 << 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) case DIBX000_VBG_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) reg_913 |= (1 << 15);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) // dprintk("913: %x, 914: %x\n", reg_913, reg_914);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ret |= dib7000m_write_word(state, 913, reg_913);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ret |= dib7000m_write_word(state, 914, reg_914);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) u32 timf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!bw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) bw = 8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) // store the current bandwidth for later use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) state->current_bandwidth = bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (state->timf == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) dprintk("using default timf\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) timf = state->timf_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dprintk("using updated timf\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) timf = state->timf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) timf = timf * (bw / 50) / 160;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) dib7000m_write_word(state, 24, (u16) ((timf ) & 0xffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return 0;
^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 dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct dib7000m_state *state = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (state->div_force_off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) dprintk("diversity combination deactivated - forced by COFDM parameters\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) onoff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) state->div_state = (u8)onoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (onoff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) dib7000m_write_word(state, 263 + state->reg_offs, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) dib7000m_write_word(state, 264 + state->reg_offs, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) dib7000m_write_word(state, 263 + state->reg_offs, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dib7000m_write_word(state, 264 + state->reg_offs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) dib7000m_write_word(state, 266 + state->reg_offs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int dib7000m_sad_calib(struct dib7000m_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* internal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) // dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writing in set_bandwidth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* do the calibration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) dib7000m_write_word(state, 929, (1 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) dib7000m_write_word(state, 929, (0 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return 0;
^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 void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000) & 0xffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) dib7000m_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) dib7000m_write_word(state, 22, (u16) ( bw->ifreq & 0xffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dib7000m_write_word(state, 928, bw->sad_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static void dib7000m_reset_pll(struct dib7000m_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) const struct dibx000_bandwidth_config *bw = state->cfg.bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u16 reg_907,reg_910;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /* default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) (bw->enable_refdiv << 1) | (0 << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) // for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) // this is only working only for 30 MHz crystals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (!state->cfg.quartz_direct) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) reg_910 |= (1 << 5); // forcing the predivider to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) // if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if(state->cfg.input_clk_is_div_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) reg_907 |= (16 << 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) reg_907 |= (8 << 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) reg_907 |= (bw->pll_ratio & 0x3f) << 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) reg_910 |= (bw->pll_prediv << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) dib7000m_write_word(state, 910, reg_910); // pll cfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) dib7000m_write_word(state, 907, reg_907); // clk cfg0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dib7000m_write_word(state, 908, 0x0006); // clk_cfg1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dib7000m_reset_pll_common(state, bw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static void dib7000mc_reset_pll(struct dib7000m_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) const struct dibx000_bandwidth_config *bw = state->cfg.bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) u16 clk_cfg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) // clk_cfg0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) // clk_cfg1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) dib7000m_write_word(state, 908, clk_cfg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) dib7000m_write_word(state, 908, clk_cfg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) // smpl_cfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dib7000m_reset_pll_common(state, bw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int dib7000m_reset_gpio(struct dib7000m_state *st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* reset the GPIOs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dib7000m_write_word(st, 773, st->cfg.gpio_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dib7000m_write_word(st, 774, st->cfg.gpio_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* TODO 782 is P_gpio_od */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dib7000m_write_word(st, 780, st->cfg.pwm_freq_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static u16 dib7000m_defaults_common[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) // auto search configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 3, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 0x0004,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 0x1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 0x0814,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 12, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 0x001b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 0x7740,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 0x005b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 0x8d80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 0x01c9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 0xc380,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 0x0080,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 0x0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 0x0090,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 0x0001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 0xd4c0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 1, 26,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 0x6680, // P_corm_thres Lock algorithms configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 1, 170,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 8, 173,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 1, 182,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 8192, // P_fft_nb_to_cut
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 2, 195,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 0x0ccd, // P_pha3_thres
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 0, // P_cti_use_cpe, P_cti_use_prog
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 1, 205,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 0x200f, // P_cspu_regul, P_cspu_win_cut
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 5, 214,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 0x023d, // P_adp_regul_cnt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 0x00a4, // P_adp_noise_cnt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 0x00a4, // P_adp_regul_ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 0x7ff0, // P_adp_noise_ext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 0x3ccc, // P_adp_fil
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 1, 226,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 0, // P_2d_byp_ti_num
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 1, 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 0x800, // P_equal_thres_wgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 1, 263,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 0x0001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 1, 281,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 0x0010, // P_fec_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 1, 294,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static u16 dib7000m_defaults[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /* set ADC level to -16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 11, 76,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) (1 << 13) - 825 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) (1 << 13) - 837 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) (1 << 13) - 811 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) (1 << 13) - 766 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) (1 << 13) - 737 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) (1 << 13) - 693 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) (1 << 13) - 648 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) (1 << 13) - 619 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) (1 << 13) - 575 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) (1 << 13) - 531 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) (1 << 13) - 501 - 117,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) // Tuner IO bank: max drive (14mA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 1, 912,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 0x2c8a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 1, 1817,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static int dib7000m_demod_reset(struct dib7000m_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* restart all parts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) dib7000m_write_word(state, 898, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dib7000m_write_word(state, 899, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) dib7000m_write_word(state, 900, 0xff0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dib7000m_write_word(state, 901, 0xfffc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) dib7000m_write_word(state, 898, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) dib7000m_write_word(state, 899, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) dib7000m_write_word(state, 900, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) dib7000m_write_word(state, 901, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (state->revision == 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) dib7000m_reset_pll(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) dib7000mc_reset_pll(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (dib7000m_reset_gpio(state) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) dprintk("GPIO reset was not successful.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) dprintk("OUTPUT_MODE could not be reset.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* unforce divstr regardless whether i2c enumeration was done or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) dib7000m_set_bandwidth(state, 8000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dib7000m_sad_calib(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (state->cfg.dvbt_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (state->cfg.mobile_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) dib7000m_write_word(state, 261 + state->reg_offs, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) dib7000m_write_word(state, 224 + state->reg_offs, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if(state->cfg.tuner_is_baseband)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) dib7000m_write_word(state, 36, 0x0755);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) dib7000m_write_word(state, 36, 0x1f55);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) // P_divclksel=3 P_divbitsel=1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (state->revision == 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) dib7000m_write_word(state, 909, (3 << 4) | 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) dib7000m_write_tab(state, dib7000m_defaults_common);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) dib7000m_write_tab(state, dib7000m_defaults);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) state->internal_clk = state->cfg.bw->internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static void dib7000m_restart_agc(struct dib7000m_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) // P_restart_iqc & P_restart_agc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dib7000m_write_word(state, 898, 0x0c00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) dib7000m_write_word(state, 898, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static int dib7000m_agc_soft_split(struct dib7000m_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) u16 agc,split_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) // n_agc_global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) agc = dib7000m_read_word(state, 390);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (agc > state->current_agc->split.min_thres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) split_offset = state->current_agc->split.min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) else if (agc < state->current_agc->split.max_thres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) split_offset = state->current_agc->split.max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) split_offset = state->current_agc->split.max *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) (agc - state->current_agc->split.min_thres) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) dprintk("AGC split_offset: %d\n", split_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) // P_agc_force_split and P_agc_split_offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int dib7000m_update_lna(struct dib7000m_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) u16 dyn_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (state->cfg.update_lna) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) // read dyn_gain here (because it is demod-dependent and not fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) dyn_gain = dib7000m_read_word(state, 390);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) dib7000m_restart_agc(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct dibx000_agc_config *agc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (state->current_band == band && state->current_agc != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) state->current_band = band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) for (i = 0; i < state->cfg.agc_config_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (state->cfg.agc[i].band_caps & band) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) agc = &state->cfg.agc[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (agc == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) dprintk("no valid AGC configuration found for band 0x%02x\n", band);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) state->current_agc = agc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /* AGC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) dib7000m_write_word(state, 72 , agc->setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) dib7000m_write_word(state, 73 , agc->inv_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) dib7000m_write_word(state, 74 , agc->time_stabiliz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) // Demod AGC loop configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) dib7000m_write_word(state, 99, (agc->beta_mant << 6) | agc->beta_exp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* AGC continued */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (state->wbd_ref != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) dib7000m_write_word(state, 102, state->wbd_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) else // use default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) dib7000m_write_word(state, 102, agc->wbd_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) dib7000m_write_word(state, 104, agc->agc1_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) dib7000m_write_word(state, 105, agc->agc1_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) dib7000m_write_word(state, 106, agc->agc2_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) dib7000m_write_word(state, 107, agc->agc2_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (state->revision > 0x4000) { // settings for the MC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) dib7000m_write_word(state, 71, agc->agc1_pt3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) // dprintk("929: %x %d %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) // (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) // wrong default values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) for (i = 0; i < 9; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) dib7000m_write_word(state, 88 + i, b[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static void dib7000m_update_timf(struct dib7000m_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) state->timf = timf * 160 / (state->current_bandwidth / 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dib7000m_write_word(state, 23, (u16) (timf >> 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) dprintk("updated timf_frequency: %d (default: %d)\n", state->timf, state->timf_default);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int dib7000m_agc_startup(struct dvb_frontend *demod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) struct dib7000m_state *state = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) u16 cfg_72 = dib7000m_read_word(state, 72);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) u8 *agc_state = &state->agc_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) u8 agc_split;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) switch (state->agc_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) // set power-up level: interf+analog+AGC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) dib7000m_set_adc_state(state, DIBX000_ADC_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ret = 7; /* ADC power up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) (*agc_state)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /* AGC initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (state->cfg.agc_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) state->cfg.agc_control(&state->demod, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) dib7000m_write_word(state, 75, 32768);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (!state->current_agc->perform_agc_softsplit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) /* we are using the wbd - so slow AGC startup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) (*agc_state)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) ret = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* default AGC startup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) (*agc_state) = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* wait AGC rough lock time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ret = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) dib7000m_restart_agc(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) case 2: /* fast split search path after 5sec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) dib7000m_write_word(state, 72, cfg_72 | (1 << 4)); /* freeze AGC loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dib7000m_write_word(state, 103, 2 << 9); /* fast split search 0.25kHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) (*agc_state)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ret = 14;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) case 3: /* split search ended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) dib7000m_write_word(state, 72, cfg_72 & ~(1 << 4)); /* std AGC loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) dib7000m_restart_agc(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) dprintk("SPLIT %p: %u\n", demod, agc_split);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) (*agc_state)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) ret = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) case 4: /* LNA startup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /* wait AGC accurate lock time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) ret = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (dib7000m_update_lna(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) // wait only AGC rough lock time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ret = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) (*agc_state)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) dib7000m_agc_soft_split(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (state->cfg.agc_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) state->cfg.agc_control(&state->demod, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) (*agc_state)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static void dib7000m_set_channel(struct dib7000m_state *state, struct dtv_frontend_properties *ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) u8 seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) u16 value, est[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* nfft, guard, qam, alpha */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) switch (ch->transmission_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) switch (ch->guard_interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) switch (ch->modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) case QPSK: value |= (0 << 3); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) case QAM_16: value |= (1 << 3); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) case QAM_64: value |= (2 << 3); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) switch (HIERARCHY_1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) case HIERARCHY_2: value |= 2; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) case HIERARCHY_4: value |= 4; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) case HIERARCHY_1: value |= 1; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) dib7000m_write_word(state, 0, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) dib7000m_write_word(state, 5, (seq << 4));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (1 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) value |= (1 << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (ch->hierarchy == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) value |= (1 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (1 == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) value |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) case FEC_2_3: value |= (2 << 1); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) case FEC_3_4: value |= (3 << 1); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) case FEC_5_6: value |= (5 << 1); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) case FEC_7_8: value |= (7 << 1); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) case FEC_1_2: value |= (1 << 1); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) dib7000m_write_word(state, 267 + state->reg_offs, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /* offset loop parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) /* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=1, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) dib7000m_write_word(state, 32, (0 << 4) | 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) dib7000m_write_word(state, 33, (0 << 4) | 0x5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* P_dvsy_sync_wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) switch (ch->transmission_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case TRANSMISSION_MODE_8K: value = 256; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) case TRANSMISSION_MODE_4K: value = 128; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) case TRANSMISSION_MODE_2K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) default: value = 64; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) switch (ch->guard_interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) case GUARD_INTERVAL_1_16: value *= 2; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) case GUARD_INTERVAL_1_8: value *= 4; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) case GUARD_INTERVAL_1_4: value *= 8; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) case GUARD_INTERVAL_1_32: value *= 1; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) /* deactivate the possibility of diversity reception if extended interleave - not for 7000MC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (1 == 1 || state->revision > 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) state->div_force_off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) state->div_force_off = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) dib7000m_set_diversity_in(&state->demod, state->div_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /* channel estimation fine configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) switch (ch->modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) case QAM_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) case QAM_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) for (value = 0; value < 4; value++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) // set power-up level: autosearch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) static int dib7000m_autosearch_start(struct dvb_frontend *demod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct dib7000m_state *state = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct dtv_frontend_properties schan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) u32 value, factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) schan = *ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) schan.modulation = QAM_64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) schan.guard_interval = GUARD_INTERVAL_1_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) schan.transmission_mode = TRANSMISSION_MODE_8K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) schan.code_rate_HP = FEC_2_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) schan.code_rate_LP = FEC_3_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) schan.hierarchy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) dib7000m_set_channel(state, &schan, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) factor = BANDWIDTH_TO_KHZ(schan.bandwidth_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (factor >= 5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) factor = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) factor = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) value = 30 * state->internal_clk * factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) ret |= dib7000m_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) ret |= dib7000m_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) value = 100 * state->internal_clk * factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) ret |= dib7000m_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) ret |= dib7000m_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) value = 500 * state->internal_clk * factor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) ret |= dib7000m_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) // start search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) value = dib7000m_read_word(state, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /* clear n_irq_pending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (state->revision == 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) dib7000m_write_word(state, 1793, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) dib7000m_read_word(state, 537);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ret |= dib7000m_write_word(state, 0, (u16) value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) u16 irq_pending = dib7000m_read_word(state, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (irq_pending & 0x1) { // failed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) dprintk("autosearch failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (irq_pending & 0x2) { // succeeded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) dprintk("autosearch succeeded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return 0; // still pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) struct dib7000m_state *state = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (state->revision == 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return dib7000m_autosearch_irq(state, 1793);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return dib7000m_autosearch_irq(state, 537);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static int dib7000m_tune(struct dvb_frontend *demod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) struct dib7000m_state *state = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) // we are already tuned - just resuming from suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) dib7000m_set_channel(state, ch, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) // restart demod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) ret |= dib7000m_write_word(state, 898, 0x4000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) ret |= dib7000m_write_word(state, 898, 0x0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) msleep(45);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) // never achieved a lock before - wait for timfreq to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (state->timf == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) msleep(200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) //dump_reg(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) value = (6 << 8) | 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) switch (ch->transmission_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) ret |= dib7000m_write_word(state, 26, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) value = (0 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) switch (ch->transmission_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) case TRANSMISSION_MODE_2K: value |= 0x6; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) case TRANSMISSION_MODE_4K: value |= 0x7; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) case TRANSMISSION_MODE_8K: value |= 0x8; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) ret |= dib7000m_write_word(state, 32, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) value = (0 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) switch (ch->transmission_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) case TRANSMISSION_MODE_2K: value |= 0x6; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) case TRANSMISSION_MODE_4K: value |= 0x7; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) case TRANSMISSION_MODE_8K: value |= 0x8; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) ret |= dib7000m_write_word(state, 33, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) // we achieved a lock - it's time to update the timf freq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if ((dib7000m_read_word(state, 535) >> 6) & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) dib7000m_update_timf(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) static int dib7000m_wakeup(struct dvb_frontend *demod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct dib7000m_state *state = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) dprintk("could not start Slow ADC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) static int dib7000m_sleep(struct dvb_frontend *demod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) struct dib7000m_state *st = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) static int dib7000m_identify(struct dib7000m_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) dprintk("wrong Vendor ID (0x%x)\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) state->revision = dib7000m_read_word(state, 897);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (state->revision != 0x4000 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) state->revision != 0x4001 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) state->revision != 0x4002 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) state->revision != 0x4003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) dprintk("wrong Device ID (0x%x)\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) /* protect this driver to be used with 7000PC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) dprintk("this driver does not work with DiB7000PC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) switch (state->revision) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) case 0x4000: dprintk("found DiB7000MA/PA/MB/PB\n"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) case 0x4001: state->reg_offs = 1; dprintk("found DiB7000HC\n"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) case 0x4002: state->reg_offs = 1; dprintk("found DiB7000MC\n"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) case 0x4003: state->reg_offs = 1; dprintk("found DiB9000\n"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) static int dib7000m_get_frontend(struct dvb_frontend* fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct dtv_frontend_properties *fep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct dib7000m_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) u16 tps = dib7000m_read_word(state,480);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) fep->inversion = INVERSION_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) switch ((tps >> 8) & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) switch (tps & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) switch ((tps >> 14) & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) case 0: fep->modulation = QPSK; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) case 1: fep->modulation = QAM_16; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) default: fep->modulation = QAM_64; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) fep->hierarchy = HIERARCHY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) switch ((tps >> 5) & 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) case 1: fep->code_rate_HP = FEC_1_2; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) case 2: fep->code_rate_HP = FEC_2_3; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) case 3: fep->code_rate_HP = FEC_3_4; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) case 5: fep->code_rate_HP = FEC_5_6; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) default: fep->code_rate_HP = FEC_7_8; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) switch ((tps >> 2) & 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) case 1: fep->code_rate_LP = FEC_1_2; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) case 2: fep->code_rate_LP = FEC_2_3; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) case 3: fep->code_rate_LP = FEC_3_4; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) case 5: fep->code_rate_LP = FEC_5_6; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) default: fep->code_rate_LP = FEC_7_8; break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) /* native interleaver: (dib7000m_read_word(state, 481) >> 5) & 0x1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static int dib7000m_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) struct dib7000m_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) int time, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (fe->ops.tuner_ops.set_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) fe->ops.tuner_ops.set_params(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /* start up the AGC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) state->agc_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) time = dib7000m_agc_startup(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (time != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) msleep(time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) } while (time != -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) fep->guard_interval == GUARD_INTERVAL_AUTO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) fep->modulation == QAM_AUTO ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) fep->code_rate_HP == FEC_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) int i = 800, found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) dib7000m_autosearch_start(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) found = dib7000m_autosearch_is_irq(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) } while (found == 0 && i--);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) dprintk("autosearch returns: %d\n", found);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (found == 0 || found == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return 0; // no channel found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) dib7000m_get_frontend(fe, fep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) ret = dib7000m_tune(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) /* make this a config parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) static int dib7000m_read_status(struct dvb_frontend *fe, enum fe_status *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) struct dib7000m_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) u16 lock = dib7000m_read_word(state, 535);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) *stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (lock & 0x8000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) *stat |= FE_HAS_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (lock & 0x3000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) *stat |= FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (lock & 0x0100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) *stat |= FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (lock & 0x0010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) *stat |= FE_HAS_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (lock & 0x0008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) *stat |= FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct dib7000m_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) struct dib7000m_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) *unc = dib7000m_read_word(state, 534);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) struct dib7000m_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) u16 val = dib7000m_read_word(state, 390);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) *strength = 65535 - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) *snr = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) tune->min_delay_ms = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) static void dib7000m_release(struct dvb_frontend *demod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) struct dib7000m_state *st = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) dibx000_exit_i2c_master(&st->i2c_master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) struct dib7000m_state *st = demod->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) EXPORT_SYMBOL(dib7000m_get_i2c_master);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) struct dib7000m_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) val |= (onoff & 0x1) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) dprintk("PID filter enabled %d\n", onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return dib7000m_write_word(state, 294 + state->reg_offs, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) struct dib7000m_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) dprintk("PID filter: index %x, PID %d, OnOff %d\n", id, pid, onoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) return dib7000m_write_word(state, 300 + state->reg_offs + id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) onoff ? (1 << 13) | pid : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) EXPORT_SYMBOL(dib7000m_pid_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) /* used with some prototype boards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) u8 default_addr, struct dib7000m_config cfg[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) struct dib7000m_state st = { .i2c_adap = i2c };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) int k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) u8 new_addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) for (k = no_of_demods-1; k >= 0; k--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) st.cfg = cfg[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) /* designated i2c address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) new_addr = (0x40 + k) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) st.i2c_addr = new_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (dib7000m_identify(&st) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) st.i2c_addr = default_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) if (dib7000m_identify(&st) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) dprintk("DiB7000M #%d: not identified\n", k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) /* start diversity to pull_down div_str - just for i2c-enumeration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) /* set new i2c address and force divstart */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
^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) for (k = 0; k < no_of_demods; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) st.cfg = cfg[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) st.i2c_addr = (0x40 + k) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) // unforce divstr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) dib7000m_write_word(&st,1794, st.i2c_addr << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) /* deactivate div - it was just for i2c-enumeration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) EXPORT_SYMBOL(dib7000m_i2c_enumeration);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) static const struct dvb_frontend_ops dib7000m_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) struct dvb_frontend *demod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) struct dib7000m_state *st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if (st == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) st->i2c_adap = i2c_adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) st->i2c_addr = i2c_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) demod = &st->demod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) demod->demodulator_priv = st;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) mutex_init(&st->i2c_buffer_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) st->timf_default = cfg->bw->timf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (dib7000m_identify(st) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (st->revision == 0x4000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) dib7000m_demod_reset(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) return demod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) kfree(st);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) EXPORT_SYMBOL(dib7000m_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) static const struct dvb_frontend_ops dib7000m_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) .delsys = { SYS_DVBT },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .name = "DiBcom 7000MA/MB/PA/PB/MC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) .frequency_min_hz = 44250 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) .frequency_max_hz = 867250 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .frequency_stepsize_hz = 62500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .caps = FE_CAN_INVERSION_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) FE_CAN_TRANSMISSION_MODE_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) FE_CAN_GUARD_INTERVAL_AUTO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) FE_CAN_RECOVER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) FE_CAN_HIERARCHY_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) .release = dib7000m_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) .init = dib7000m_wakeup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) .sleep = dib7000m_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) .set_frontend = dib7000m_set_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) .get_tune_settings = dib7000m_fe_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) .get_frontend = dib7000m_get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) .read_status = dib7000m_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) .read_ber = dib7000m_read_ber,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) .read_signal_strength = dib7000m_read_signal_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) .read_snr = dib7000m_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) .read_ucblocks = dib7000m_read_unc_blocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) MODULE_LICENSE("GPL");