^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ascot2e.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Sony Ascot3E DVB-T/T2/C/C2 tuner driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2012 Sony Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2014 NetUP Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/dvb/frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "ascot2e.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define MAX_WRITE_REGSIZE 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) enum ascot2e_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) STATE_UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) STATE_SLEEP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) STATE_ACTIVE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct ascot2e_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u32 frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u8 i2c_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct i2c_adapter *i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) enum ascot2e_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) void *set_tuner_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int (*set_tuner)(void *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) enum ascot2e_tv_system_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) ASCOT2E_DTV_DVBT_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) ASCOT2E_DTV_DVBT_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) ASCOT2E_DTV_DVBT_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) ASCOT2E_DTV_DVBT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ASCOT2E_DTV_DVBT2_1_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) ASCOT2E_DTV_DVBT2_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ASCOT2E_DTV_DVBT2_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) ASCOT2E_DTV_DVBT2_7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) ASCOT2E_DTV_DVBT2_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ASCOT2E_DTV_DVBC_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) ASCOT2E_DTV_DVBC_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ASCOT2E_DTV_DVBC2_6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) ASCOT2E_DTV_DVBC2_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ASCOT2E_DTV_UNKNOWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct ascot2e_band_sett {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u8 if_out_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u8 agc_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u8 mix_oll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u8 rf_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) u8 if_bpf_gc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u8 fif_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u8 bw_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u8 bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u8 rf_oldet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) u8 if_bpf_f0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define ASCOT2E_AUTO 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define ASCOT2E_OFFSET(ofs) ((u8)(ofs) & 0x1F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define ASCOT2E_BW_6 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define ASCOT2E_BW_7 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define ASCOT2E_BW_8 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define ASCOT2E_BW_1_7 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static struct ascot2e_band_sett ascot2e_sett[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_7, 0x0B, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ASCOT2E_OFFSET(-4), ASCOT2E_OFFSET(-2), ASCOT2E_BW_8, 0x0B, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ASCOT2E_OFFSET(-10), ASCOT2E_OFFSET(-16), ASCOT2E_BW_1_7, 0x0B, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ASCOT2E_OFFSET(-8), ASCOT2E_OFFSET(-6), ASCOT2E_BW_6, 0x0B, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_7, 0x0B, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ASCOT2E_OFFSET(-4), ASCOT2E_OFFSET(-2), ASCOT2E_BW_8, 0x0B, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x02, ASCOT2E_AUTO, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-8), ASCOT2E_BW_6, 0x09, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x02, ASCOT2E_AUTO, 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) ASCOT2E_OFFSET(-2), ASCOT2E_OFFSET(-1), ASCOT2E_BW_8, 0x09, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ASCOT2E_OFFSET(-6), ASCOT2E_OFFSET(-4), ASCOT2E_BW_6, 0x09, 0x00 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) { ASCOT2E_AUTO, ASCOT2E_AUTO, 0x03, ASCOT2E_AUTO, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ASCOT2E_OFFSET(-2), ASCOT2E_OFFSET(2), ASCOT2E_BW_8, 0x09, 0x00 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void ascot2e_i2c_debug(struct ascot2e_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u8 reg, u8 write, const u8 *data, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dev_dbg(&priv->i2c->dev, "ascot2e: I2C %s reg 0x%02x size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) (write == 0 ? "read" : "write"), reg, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) print_hex_dump_bytes("ascot2e: I2C data: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) DUMP_PREFIX_OFFSET, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static int ascot2e_write_regs(struct ascot2e_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u8 reg, const u8 *data, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) u8 buf[MAX_WRITE_REGSIZE + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct i2c_msg msg[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .addr = priv->i2c_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) .len = len + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (len + 1 > sizeof(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) reg, len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ascot2e_i2c_debug(priv, reg, 1, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) buf[0] = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) memcpy(&buf[1], data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ret = i2c_transfer(priv->i2c, msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (ret >= 0 && ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dev_warn(&priv->i2c->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) "%s: i2c wr failed=%d reg=%02x len=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) KBUILD_MODNAME, ret, reg, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return ascot2e_write_regs(priv, reg, &tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int ascot2e_read_regs(struct ascot2e_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u8 reg, u8 *val, u32 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct i2c_msg msg[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) .addr = priv->i2c_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .buf = ®,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .addr = priv->i2c_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .len = len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .buf = val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ret = i2c_transfer(priv->i2c, &msg[0], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (ret >= 0 && ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) dev_warn(&priv->i2c->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) "%s: I2C rw failed=%d addr=%02x reg=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) KBUILD_MODNAME, ret, priv->i2c_address, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ret = i2c_transfer(priv->i2c, &msg[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (ret >= 0 && ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ret = -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) dev_warn(&priv->i2c->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) "%s: i2c rd failed=%d addr=%02x reg=%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) KBUILD_MODNAME, ret, priv->i2c_address, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ascot2e_i2c_debug(priv, reg, 0, val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) static int ascot2e_read_reg(struct ascot2e_priv *priv, u8 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ascot2e_read_regs(priv, reg, val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int ascot2e_set_reg_bits(struct ascot2e_priv *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u8 reg, u8 data, u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 rdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (mask != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) res = ascot2e_read_reg(priv, reg, &rdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (res != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) data = ((data & mask) | (rdata & (mask ^ 0xFF)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return ascot2e_write_reg(priv, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static int ascot2e_enter_power_save(struct ascot2e_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) u8 data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (priv->state == STATE_SLEEP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) data[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) data[1] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ascot2e_write_regs(priv, 0x14, data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ascot2e_write_reg(priv, 0x50, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) priv->state = STATE_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int ascot2e_leave_power_save(struct ascot2e_priv *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) u8 data[2] = { 0xFB, 0x0F };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (priv->state == STATE_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ascot2e_write_regs(priv, 0x14, data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ascot2e_write_reg(priv, 0x50, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) priv->state = STATE_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int ascot2e_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct ascot2e_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return ascot2e_leave_power_save(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) static void ascot2e_release(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct ascot2e_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) kfree(fe->tuner_priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) fe->tuner_priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static int ascot2e_sleep(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct ascot2e_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) ascot2e_enter_power_save(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) static enum ascot2e_tv_system_t ascot2e_get_tv_system(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) enum ascot2e_tv_system_t system = ASCOT2E_DTV_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct ascot2e_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (p->delivery_system == SYS_DVBT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (p->bandwidth_hz <= 5000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) system = ASCOT2E_DTV_DVBT_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) else if (p->bandwidth_hz <= 6000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) system = ASCOT2E_DTV_DVBT_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) else if (p->bandwidth_hz <= 7000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) system = ASCOT2E_DTV_DVBT_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) else if (p->bandwidth_hz <= 8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) system = ASCOT2E_DTV_DVBT_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) system = ASCOT2E_DTV_DVBT_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) p->bandwidth_hz = 8000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) } else if (p->delivery_system == SYS_DVBT2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (p->bandwidth_hz <= 5000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) system = ASCOT2E_DTV_DVBT2_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) else if (p->bandwidth_hz <= 6000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) system = ASCOT2E_DTV_DVBT2_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) else if (p->bandwidth_hz <= 7000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) system = ASCOT2E_DTV_DVBT2_7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) else if (p->bandwidth_hz <= 8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) system = ASCOT2E_DTV_DVBT2_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) system = ASCOT2E_DTV_DVBT2_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) p->bandwidth_hz = 8000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) } else if (p->delivery_system == SYS_DVBC_ANNEX_A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (p->bandwidth_hz <= 6000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) system = ASCOT2E_DTV_DVBC_6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) else if (p->bandwidth_hz <= 8000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) system = ASCOT2E_DTV_DVBC_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) dev_dbg(&priv->i2c->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) "%s(): ASCOT2E DTV system %d (delsys %d, bandwidth %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) __func__, (int)system, p->delivery_system, p->bandwidth_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static int ascot2e_set_params(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) u8 data[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) u32 frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) enum ascot2e_tv_system_t tv_system;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct ascot2e_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) __func__, p->frequency / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) tv_system = ascot2e_get_tv_system(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (tv_system == ASCOT2E_DTV_UNKNOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) dev_dbg(&priv->i2c->dev, "%s(): unknown DTV system\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (priv->set_tuner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) priv->set_tuner(priv->set_tuner_data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) frequency = roundup(p->frequency / 1000, 25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (priv->state == STATE_SLEEP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) ascot2e_leave_power_save(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* IF_OUT_SEL / AGC_SEL setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) data[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) if (ascot2e_sett[tv_system].agc_sel != ASCOT2E_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) /* AGC pin setting from parameter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) data[0] |= (u8)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) (ascot2e_sett[tv_system].agc_sel & 0x03) << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (ascot2e_sett[tv_system].if_out_sel != ASCOT2E_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* IFOUT pin setting from parameter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) data[0] |= (u8)(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) (ascot2e_sett[tv_system].if_out_sel & 0x01) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* Set bit[4:2] only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) ascot2e_set_reg_bits(priv, 0x05, data[0], 0x1c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* 0x06 - 0x0F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /* REF_R setting (0x06) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (tv_system == ASCOT2E_DTV_DVBC_6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) tv_system == ASCOT2E_DTV_DVBC_8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* xtal, xtal*2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) data[0] = (frequency > 500000) ? 16 : 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* xtal/8, xtal/4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) data[0] = (frequency > 500000) ? 2 : 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* XOSC_SEL=100uA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) data[1] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) /* KBW setting (0x08), KC0 setting (0x09), KC1 setting (0x0A) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (tv_system == ASCOT2E_DTV_DVBC_6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) tv_system == ASCOT2E_DTV_DVBC_8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) data[2] = 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) data[3] = 120;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) data[4] = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) data[2] = 48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) data[3] = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) data[4] = 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* ORDER/R2_RANGE/R2_BANK/C2_BANK setting (0x0B) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (tv_system == ASCOT2E_DTV_DVBC_6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) tv_system == ASCOT2E_DTV_DVBC_8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) data[5] = (frequency > 500000) ? 0x08 : 0x0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) data[5] = (frequency > 500000) ? 0x30 : 0x38;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* Set MIX_OLL (0x0C) value from parameter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) data[6] = ascot2e_sett[tv_system].mix_oll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* Set RF_GAIN (0x0D) setting from parameter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (ascot2e_sett[tv_system].rf_gain == ASCOT2E_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* RF_GAIN auto control enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ascot2e_write_reg(priv, 0x4E, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* RF_GAIN Default value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) data[7] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* RF_GAIN auto control disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ascot2e_write_reg(priv, 0x4E, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) data[7] = ascot2e_sett[tv_system].rf_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* Set IF_BPF_GC/FIF_OFFSET (0x0E) value from parameter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) data[8] = (u8)((ascot2e_sett[tv_system].fif_offset << 3) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) (ascot2e_sett[tv_system].if_bpf_gc & 0x07));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* Set BW_OFFSET (0x0F) value from parameter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) data[9] = ascot2e_sett[tv_system].bw_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ascot2e_write_regs(priv, 0x06, data, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * 0x45 - 0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * LNA optimization setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * RF_LNA_DIST1-5, RF_LNA_CM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (tv_system == ASCOT2E_DTV_DVBC_6 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) tv_system == ASCOT2E_DTV_DVBC_8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) data[0] = 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) data[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) data[2] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) data[0] = 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) data[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) data[2] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ascot2e_write_regs(priv, 0x45, data, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* 0x49 - 0x4A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) Set RF_OLDET_ENX/RF_OLDET_OLL value from parameter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) data[0] = ascot2e_sett[tv_system].rf_oldet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Set IF_BPF_F0 value from parameter table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) data[1] = ascot2e_sett[tv_system].if_bpf_f0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ascot2e_write_regs(priv, 0x49, data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * Tune now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * RFAGC fast mode / RFAGC auto control enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * (set bit[7], bit[5:4] only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * vco_cal = 1, set MIX_OL_CPU_EN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) ascot2e_set_reg_bits(priv, 0x0c, 0x90, 0xb0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /* Logic wake up, CPU wake up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) data[0] = 0xc4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) data[1] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) ascot2e_write_regs(priv, 0x03, data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* 0x10 - 0x14 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) data[0] = (u8)(frequency & 0xFF); /* 0x10: FRF_L */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) data[1] = (u8)((frequency >> 8) & 0xFF); /* 0x11: FRF_M */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) data[2] = (u8)((frequency >> 16) & 0x0F); /* 0x12: FRF_H (bit[3:0]) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* 0x12: BW (bit[5:4]) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) data[2] |= (u8)(ascot2e_sett[tv_system].bw << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) data[3] = 0xFF; /* 0x13: VCO calibration enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) data[4] = 0xFF; /* 0x14: Analog block enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* Tune (Burst write) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) ascot2e_write_regs(priv, 0x10, data, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /* CPU deep sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ascot2e_write_reg(priv, 0x04, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* Logic sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ascot2e_write_reg(priv, 0x03, 0xC0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /* RFAGC normal mode (set bit[5:4] only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ascot2e_set_reg_bits(priv, 0x0C, 0x00, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) priv->frequency = frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static int ascot2e_get_frequency(struct dvb_frontend *fe, u32 *frequency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct ascot2e_priv *priv = fe->tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) *frequency = priv->frequency * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static const struct dvb_tuner_ops ascot2e_tuner_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .name = "Sony ASCOT2E",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .frequency_min_hz = 1 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .frequency_max_hz = 1200 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .frequency_step_hz = 25 * kHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .init = ascot2e_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .release = ascot2e_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) .sleep = ascot2e_sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .set_params = ascot2e_set_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) .get_frequency = ascot2e_get_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) const struct ascot2e_config *config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) u8 data[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct ascot2e_priv *priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) priv = kzalloc(sizeof(struct ascot2e_priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (priv == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) priv->i2c_address = (config->i2c_address >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) priv->i2c = i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) priv->set_tuner_data = config->set_tuner_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) priv->set_tuner = config->set_tuner_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) fe->ops.i2c_gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* 16 MHz xTal frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) data[0] = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* VCO current setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) data[1] = 0x06;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* Logic wake up, CPU boot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) data[2] = 0xC4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) data[3] = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ascot2e_write_regs(priv, 0x01, data, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* RFVGA optimization setting (RF_DIST0 - RF_DIST2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) data[0] = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) data[1] = 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) data[2] = 0x25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) ascot2e_write_regs(priv, 0x22, data, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* PLL mode setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) ascot2e_write_reg(priv, 0x28, 0x1e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* RSSI setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) ascot2e_write_reg(priv, 0x59, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* TODO check CPU HW error state here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) msleep(80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /* Xtal oscillator current control setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ascot2e_write_reg(priv, 0x4c, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) /* XOSC_SEL=100uA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ascot2e_write_reg(priv, 0x07, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /* CPU deep sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ascot2e_write_reg(priv, 0x04, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* Logic sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ascot2e_write_reg(priv, 0x03, 0xc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /* Power save setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) data[0] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) data[1] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ascot2e_write_regs(priv, 0x14, data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ascot2e_write_reg(priv, 0x50, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) priv->state = STATE_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) fe->ops.i2c_gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) memcpy(&fe->ops.tuner_ops, &ascot2e_tuner_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) sizeof(struct dvb_tuner_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) fe->tuner_priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dev_info(&priv->i2c->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) "Sony ASCOT2E attached on addr=%x at I2C adapter %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) priv->i2c_address, priv->i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) return fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) EXPORT_SYMBOL(ascot2e_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) MODULE_DESCRIPTION("Sony ASCOT2E terr/cab tuner driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) MODULE_AUTHOR("info@netup.ru");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) MODULE_LICENSE("GPL");