^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) * Support for LGDT3302 and LGDT3303 - VSB/QAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^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) * NOTES ABOUT THIS DRIVER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * This Linux driver supports:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * DViCO FusionHDTV 3 Gold-Q
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * DViCO FusionHDTV 3 Gold-T
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * DViCO FusionHDTV 5 Gold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * DViCO FusionHDTV 5 Lite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * DViCO FusionHDTV 5 USB Gold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * pcHDTV HD5500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <media/dvb_frontend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <media/dvb_math.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "lgdt330x_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "lgdt330x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Use Equalizer Mean Squared Error instead of Phaser Tracker MSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* #define USE_EQMSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) module_param(debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) MODULE_PARM_DESC(debug, "Turn on/off lgdt330x frontend debugging (default:off).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define dprintk(state, fmt, arg...) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (debug) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) dev_printk(KERN_DEBUG, &state->client->dev, fmt, ##arg);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct lgdt330x_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Configuration settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct lgdt330x_config config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct dvb_frontend frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Demodulator private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) enum fe_modulation current_modulation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 snr; /* Result of last SNR calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u16 ucblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned long last_stats_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* Tuner private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) u32 current_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int i2c_write_demod_bytes(struct lgdt330x_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) const u8 *buf, /* data bytes to send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) int len /* number of bytes to send */)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) for (i = 0; i < len - 1; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) err = i2c_master_send(state->client, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (err != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) dev_warn(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) "%s: error (addr %02x <- %02x, err = %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __func__, buf[0], buf[1], err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return -EREMOTEIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) buf += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * This routine writes the register (reg) to the demod bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * then reads the data returned for (len) bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static int i2c_read_demod_bytes(struct lgdt330x_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) enum I2C_REG reg, u8 *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u8 wr[] = { reg };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct i2c_msg msg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) .addr = state->client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) .buf = wr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) .len = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .addr = state->client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) .buf = buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) .len = len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ret = i2c_transfer(state->client->adapter, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (ret != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) dev_warn(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) "%s: addr 0x%02x select 0x%02x error (ret == %i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) __func__, state->client->addr, reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Software reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int lgdt3302_sw_reset(struct lgdt330x_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u8 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u8 reset[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) IRQ_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * bit 6 is active low software reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * bits 5-0 are 1 to mask interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ret = i2c_write_demod_bytes(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) reset, sizeof(reset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* force reset high (inactive) and unmask interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) reset[1] = 0x7f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ret = i2c_write_demod_bytes(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) reset, sizeof(reset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static int lgdt3303_sw_reset(struct lgdt330x_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) u8 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) u8 reset[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 0x00 /* bit 0 is active low software reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) ret = i2c_write_demod_bytes(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) reset, sizeof(reset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /* force reset high (inactive) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) reset[1] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ret = i2c_write_demod_bytes(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) reset, sizeof(reset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int lgdt330x_sw_reset(struct lgdt330x_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) switch (state->config.demod_chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) case LGDT3302:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return lgdt3302_sw_reset(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case LGDT3303:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return lgdt3303_sw_reset(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int lgdt330x_init(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) char *chip_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * Array of byte pairs <address, value>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * to initialize each different chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static const u8 lgdt3302_init_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* Use 50MHz param values from spec sheet since xtal is 50 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Change the value of NCOCTFV[25:0] of carrier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * recovery center frequency register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) VSB_CARRIER_FREQ0, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) VSB_CARRIER_FREQ1, 0x87,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) VSB_CARRIER_FREQ2, 0x8e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) VSB_CARRIER_FREQ3, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * Change the TPCLK pin polarity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * data is valid on falling clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) DEMUX_CONTROL, 0xfb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * Change the value of IFBW[11:0] of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * AGC IF/RF loop filter bandwidth register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) AGC_RF_BANDWIDTH0, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) AGC_RF_BANDWIDTH1, 0x93,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) AGC_RF_BANDWIDTH2, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * Change the value of bit 6, 'nINAGCBY' and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * 'NSSEL[1:0] of ACG function control register 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) AGC_FUNC_CTRL2, 0xc6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * Change the value of bit 6 'RFFIX'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * of AGC function control register 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) AGC_FUNC_CTRL3, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * Set the value of 'INLVTHD' register 0x2a/0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * to 0x7fe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) AGC_DELAY0, 0x07,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) AGC_DELAY2, 0xfe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * Change the value of IAGCBW[15:8]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * of inner AGC loop filter bandwidth
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) AGC_LOOP_BANDWIDTH0, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) AGC_LOOP_BANDWIDTH1, 0x9a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static const u8 lgdt3303_init_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 0x4c, 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static const u8 flip_1_lgdt3303_init_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 0x4c, 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 0x87, 0xf3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static const u8 flip_2_lgdt3303_init_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 0x4c, 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 0x87, 0xda
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * Hardware reset is done using gpio[0] of cx23880x chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * I'd like to do it here, but don't know how to find chip address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * cx88-cards.c arranges for the reset bit to be inactive (high).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * Maybe there needs to be a callable function in cx88-core or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * the caller of this function needs to do it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) switch (state->config.demod_chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) case LGDT3302:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) chip_name = "LGDT3302";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) err = i2c_write_demod_bytes(state, lgdt3302_init_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) sizeof(lgdt3302_init_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case LGDT3303:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) chip_name = "LGDT3303";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) switch (state->config.clock_polarity_flip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) err = i2c_write_demod_bytes(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) flip_2_lgdt3303_init_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) sizeof(flip_2_lgdt3303_init_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) err = i2c_write_demod_bytes(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) flip_1_lgdt3303_init_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) sizeof(flip_1_lgdt3303_init_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) err = i2c_write_demod_bytes(state, lgdt3303_init_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) sizeof(lgdt3303_init_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) chip_name = "undefined";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) dev_warn(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) "Only LGDT3302 and LGDT3303 are supported chips.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) dprintk(state, "Initialized the %s chip\n", chip_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) p->cnr.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) p->block_error.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) p->block_count.len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) state->last_stats_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return lgdt330x_sw_reset(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int lgdt330x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) *ucblocks = state->ucblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return 0;
^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) static int lgdt330x_set_parameters(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * Array of byte pairs <address, value>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * to initialize 8VSB for lgdt3303 chip 50 MHz IF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static const u8 lgdt3303_8vsb_44_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 0x04, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 0x0d, 0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 0x0e, 0x87,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 0x0f, 0x8e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 0x10, 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 0x47, 0x8b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * Array of byte pairs <address, value>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * to initialize QAM for lgdt3303 chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static const u8 lgdt3303_qam_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 0x04, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 0x0d, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 0x0e, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 0x0f, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 0x10, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 0x51, 0x63,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 0x47, 0x66,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 0x48, 0x66,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 0x4d, 0x1a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 0x49, 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 0x4a, 0x9b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* Change only if we are actually changing the modulation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (state->current_modulation != p->modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) switch (p->modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) case VSB_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) dprintk(state, "VSB_8 MODE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* Select VSB mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) top_ctrl_cfg[1] = 0x03;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* Select ANT connector if supported by card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (state->config.pll_rf_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) state->config.pll_rf_set(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) if (state->config.demod_chip == LGDT3303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) err = i2c_write_demod_bytes(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) lgdt3303_8vsb_44_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) sizeof(lgdt3303_8vsb_44_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case QAM_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) dprintk(state, "QAM_64 MODE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /* Select QAM_64 mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) top_ctrl_cfg[1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* Select CABLE connector if supported by card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (state->config.pll_rf_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) state->config.pll_rf_set(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (state->config.demod_chip == LGDT3303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) err = i2c_write_demod_bytes(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) lgdt3303_qam_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) sizeof(lgdt3303_qam_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case QAM_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) dprintk(state, "QAM_256 MODE\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /* Select QAM_256 mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) top_ctrl_cfg[1] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) /* Select CABLE connector if supported by card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (state->config.pll_rf_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) state->config.pll_rf_set(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (state->config.demod_chip == LGDT3303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) err = i2c_write_demod_bytes(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) lgdt3303_qam_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) sizeof(lgdt3303_qam_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) dev_warn(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) "%s: Modulation type(%d) UNSUPPORTED\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) __func__, p->modulation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) dev_warn(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) "%s: error blasting bytes to lgdt3303 for modulation type(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) __func__, p->modulation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * select serial or parallel MPEG hardware interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * Parallel: 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) top_ctrl_cfg[1] |= state->config.serial_mpeg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Select the requested mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) i2c_write_demod_bytes(state, top_ctrl_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) sizeof(top_ctrl_cfg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (state->config.set_ts_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) state->config.set_ts_params(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) state->current_modulation = p->modulation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* Tune to the specified frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (fe->ops.tuner_ops.set_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) fe->ops.tuner_ops.set_params(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) fe->ops.i2c_gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* Keep track of the new frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * FIXME this is the wrong way to do this...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * The tuner is shared with the video4linux analog API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) state->current_frequency = p->frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) lgdt330x_sw_reset(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int lgdt330x_get_frontend(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct dtv_frontend_properties *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) p->frequency = state->current_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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * Calculate SNR estimation (scaled by 2^24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * 8-VSB SNR equations from LGDT3302 and LGDT3303 datasheets, QAM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * equations from LGDT3303 datasheet. VSB is the same between the '02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * and '03, so maybe QAM is too? Perhaps someone with a newer datasheet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * that has QAM information could verify?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) * For 8-VSB: (two ways, take your pick)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * LGDT3302:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) * SNR_EQ = 10 * log10(25 * 24^2 / EQ_MSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) * LGDT3303:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * SNR_EQ = 10 * log10(25 * 32^2 / EQ_MSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * LGDT3302 & LGDT3303:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * SNR_PT = 10 * log10(25 * 32^2 / PT_MSE) (we use this one)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * For 64-QAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * SNR = 10 * log10( 688128 / MSEQAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * For 256-QAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * SNR = 10 * log10( 696320 / MSEQAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * We re-write the snr equation as:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * SNR * 2^24 = 10*(c - intlog10(MSE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * Where for 256-QAM, c = log10(696320) * 2^24, and so on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static u32 calculate_snr(u32 mse, u32 c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (mse == 0) /* No signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) mse = intlog10(mse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (mse > c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * Negative SNR, which is possible, but realisticly the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * demod will lose lock before the signal gets this bad.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * The API only allows for unsigned values, so just return 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return 10 * (c - mse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) static int lgdt3302_read_snr(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) u8 buf[5]; /* read data buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) u32 noise; /* noise value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) u32 c; /* per-modulation SNR calculation constant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) switch (state->current_modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) case VSB_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) #ifdef USE_EQMSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* Use Equalizer Mean-Square Error Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) /* SNR for ranges from -15.61 to +41.58 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) c = 69765745; /* log10(25*24^2)*2^24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) /* Use Phase Tracker Mean-Square Error Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* SNR for ranges from -13.11 to +44.08 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) noise = ((buf[0] & 7 << 3) << 13) | (buf[3] << 8) | buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) c = 73957994; /* log10(25*32^2)*2^24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) case QAM_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) case QAM_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) noise = ((buf[0] & 3) << 8) | buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* log10(688128)*2^24 and log10(696320)*2^24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) dev_err(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) "%s: Modulation set to unsupported value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) state->snr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) state->snr = calculate_snr(noise, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) dprintk(state, "noise = 0x%08x, snr = %d.%02d dB\n", noise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return 0;
^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) static int lgdt3303_read_snr(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) u8 buf[5]; /* read data buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) u32 noise; /* noise value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) u32 c; /* per-modulation SNR calculation constant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) switch (state->current_modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case VSB_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) #ifdef USE_EQMSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Use Equalizer Mean-Square Error Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* SNR for ranges from -16.12 to +44.08 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) | buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) c = 73957994; /* log10(25*32^2)*2^24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* Use Phase Tracker Mean-Square Error Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* SNR for ranges from -13.11 to +44.08 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) c = 73957994; /* log10(25*32^2)*2^24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) case QAM_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) case QAM_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) i2c_read_demod_bytes(state, CARRIER_MSEQAM1, buf, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) noise = (buf[0] << 8) | buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) c = state->current_modulation == QAM_64 ? 97939837 : 98026066;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* log10(688128)*2^24 and log10(696320)*2^24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) dev_err(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) "%s: Modulation set to unsupported value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) state->snr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) state->snr = calculate_snr(noise, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) dprintk(state, "noise = 0x%08x, snr = %d.%02d dB\n", noise,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) static int lgdt330x_read_snr(struct dvb_frontend *fe, u16 *snr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) *snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static int lgdt330x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* Calculate Strength from SNR up to 35dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * Even though the SNR can go higher than 35dB, there is some comfort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * factor in having a range of strong signals that can show at 100%
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) u16 snr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ret = fe->ops.read_snr(fe, &snr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /* scale the range 0 - 35*2^24 into 0 - 65535 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (state->snr >= 8960 * 0x10000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) *strength = 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) *strength = state->snr / 8960;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static int lgdt3302_read_status(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) *status = 0; /* Reset status result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* AGC status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dprintk(state, "AGC_STATUS = 0x%02x\n", buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if ((buf[0] & 0x0c) == 0x8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * Test signal does not exist flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) * as well as the AGC lock flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) *status |= FE_HAS_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * You must set the Mask bits to 1 in the IRQ_MASK in order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * to see that status bit in the IRQ_STATUS register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * This is done in SwReset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) /* signal status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) dprintk(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) "TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) buf[0], buf[1], buf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* sync status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if ((buf[2] & 0x03) == 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) *status |= FE_HAS_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* FEC error status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if ((buf[2] & 0x0c) == 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) *status |= FE_HAS_LOCK | FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /* Carrier Recovery Lock Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) dprintk(state, "CARRIER_LOCK = 0x%02x\n", buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) switch (state->current_modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case QAM_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) case QAM_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* Need to understand why there are 3 lock levels here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if ((buf[0] & 0x07) == 0x07)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) *status |= FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) case VSB_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if ((buf[0] & 0x80) == 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) *status |= FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) dev_warn(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) "%s: Modulation set to unsupported value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) __func__);
^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) if (!(*status & FE_HAS_LOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (state->last_stats_time &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) time_is_after_jiffies(state->last_stats_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) state->last_stats_time = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) err = lgdt3302_read_snr(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) p->cnr.stat[0].svalue = (((u64)state->snr) * 1000) >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) state->ucblocks = (buf[0] << 8) | buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) dprintk(state, "UCB = 0x%02x\n", state->ucblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) p->block_error.stat[0].uvalue += state->ucblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* FIXME: what's the basis for block count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) p->block_count.stat[0].uvalue += 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) p->block_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) p->block_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static int lgdt3303_read_status(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) enum fe_status *status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct dtv_frontend_properties *p = &fe->dtv_property_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) *status = 0; /* Reset status result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /* lgdt3303 AGC status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) err = i2c_read_demod_bytes(state, 0x58, buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) dprintk(state, "AGC_STATUS = 0x%02x\n", buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if ((buf[0] & 0x21) == 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * Test input signal does not exist flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * as well as the AGC lock flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) *status |= FE_HAS_SIGNAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* Carrier Recovery Lock Status Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dprintk(state, "CARRIER_LOCK = 0x%02x\n", buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) switch (state->current_modulation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) case QAM_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) case QAM_64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* Need to understand why there are 3 lock levels here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if ((buf[0] & 0x07) == 0x07)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) *status |= FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) i2c_read_demod_bytes(state, 0x8a, buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) dprintk(state, "QAM LOCK = 0x%02x\n", buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if ((buf[0] & 0x04) == 0x04)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) *status |= FE_HAS_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if ((buf[0] & 0x01) == 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) *status |= FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if ((buf[0] & 0x08) == 0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) *status |= FE_HAS_VITERBI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) case VSB_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if ((buf[0] & 0x80) == 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) *status |= FE_HAS_CARRIER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) i2c_read_demod_bytes(state, 0x38, buf, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) dprintk(state, "8-VSB LOCK = 0x%02x\n", buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if ((buf[0] & 0x02) == 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) *status |= FE_HAS_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if ((buf[0] & 0x01) == 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) *status |= FE_HAS_VITERBI | FE_HAS_LOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) dev_warn(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) "%s: Modulation set to unsupported value\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (!(*status & FE_HAS_LOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return 0;
^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) if (state->last_stats_time &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) time_is_after_jiffies(state->last_stats_time))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) state->last_stats_time = jiffies + msecs_to_jiffies(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) err = lgdt3303_read_snr(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) p->cnr.stat[0].svalue = (((u64)state->snr) * 1000) >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) state->ucblocks = (buf[0] << 8) | buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) dprintk(state, "UCB = 0x%02x\n", state->ucblocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) p->block_error.stat[0].uvalue += state->ucblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) /* FIXME: what's the basis for block count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) p->block_count.stat[0].uvalue += 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) p->block_error.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) p->block_count.stat[0].scale = FE_SCALE_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) lgdt330x_get_tune_settings(struct dvb_frontend *fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct dvb_frontend_tune_settings *fe_tune_settings)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* I have no idea about this - it may not be needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) fe_tune_settings->min_delay_ms = 500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) fe_tune_settings->step_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) fe_tune_settings->max_drift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) static void lgdt330x_release(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) struct lgdt330x_state *state = fe->demodulator_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct i2c_client *client = state->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) i2c_unregister_device(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static struct dvb_frontend *lgdt330x_get_dvb_frontend(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct lgdt330x_state *state = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) return &state->frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static const struct dvb_frontend_ops lgdt3302_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) static const struct dvb_frontend_ops lgdt3303_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) static int lgdt330x_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct lgdt330x_state *state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u8 buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /* Allocate memory for the internal state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) state = kzalloc(sizeof(*state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (!state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /* Setup the state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) memcpy(&state->config, client->dev.platform_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) sizeof(state->config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) i2c_set_clientdata(client, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) state->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* Create dvb_frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) switch (state->config.demod_chip) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) case LGDT3302:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) memcpy(&state->frontend.ops, &lgdt3302_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) case LGDT3303:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) memcpy(&state->frontend.ops, &lgdt3303_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) sizeof(struct dvb_frontend_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) state->frontend.demodulator_priv = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* Setup get frontend callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) state->config.get_dvb_frontend = lgdt330x_get_dvb_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /* Verify communication with demod chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (i2c_read_demod_bytes(state, 2, buf, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) state->current_frequency = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) state->current_modulation = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) dev_info(&state->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) "Demod loaded for LGDT330%s chip\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) state->config.demod_chip == LGDT3302 ? "2" : "3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) if (debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) dev_printk(KERN_DEBUG, &client->dev, "Error loading lgdt330x driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) struct dvb_frontend *lgdt330x_attach(const struct lgdt330x_config *_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) u8 demod_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) struct i2c_board_info board_info = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct lgdt330x_config config = *_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) strscpy(board_info.type, "lgdt330x", sizeof(board_info.type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) board_info.addr = demod_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) board_info.platform_data = &config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) client = i2c_new_client_device(i2c, &board_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (!i2c_client_has_driver(client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return lgdt330x_get_dvb_frontend(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) EXPORT_SYMBOL(lgdt330x_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) static const struct dvb_frontend_ops lgdt3302_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) .name = "LG Electronics LGDT3302 VSB/QAM Frontend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) .frequency_min_hz = 54 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) .frequency_max_hz = 858 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) .frequency_stepsize_hz = 62500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) .symbol_rate_min = 5056941, /* QAM 64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) .symbol_rate_max = 10762000, /* VSB 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) .init = lgdt330x_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) .set_frontend = lgdt330x_set_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) .get_frontend = lgdt330x_get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) .get_tune_settings = lgdt330x_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) .read_status = lgdt3302_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) .read_signal_strength = lgdt330x_read_signal_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .read_snr = lgdt330x_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .read_ucblocks = lgdt330x_read_ucblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) .release = lgdt330x_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static const struct dvb_frontend_ops lgdt3303_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) .info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) .name = "LG Electronics LGDT3303 VSB/QAM Frontend",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .frequency_min_hz = 54 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .frequency_max_hz = 858 * MHz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .frequency_stepsize_hz = 62500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .symbol_rate_min = 5056941, /* QAM 64 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .symbol_rate_max = 10762000, /* VSB 8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .init = lgdt330x_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .set_frontend = lgdt330x_set_parameters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .get_frontend = lgdt330x_get_frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .get_tune_settings = lgdt330x_get_tune_settings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .read_status = lgdt3303_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) .read_signal_strength = lgdt330x_read_signal_strength,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .read_snr = lgdt330x_read_snr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) .read_ucblocks = lgdt330x_read_ucblocks,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) .release = lgdt330x_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) static int lgdt330x_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) struct lgdt330x_state *state = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) dev_dbg(&client->dev, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static const struct i2c_device_id lgdt330x_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {"lgdt330x", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) MODULE_DEVICE_TABLE(i2c, lgdt330x_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static struct i2c_driver lgdt330x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) .name = "lgdt330x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) .suppress_bind_attrs = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) .probe = lgdt330x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) .remove = lgdt330x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) .id_table = lgdt330x_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) module_i2c_driver(lgdt330x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) MODULE_AUTHOR("Wilson Michaels");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) MODULE_LICENSE("GPL");