^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * ngene-cards.c: nGene PCIe bridge driver - card specific info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005-2007 Micronas
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2008-2009 Ralph Metzler <rjkm@metzlerbros.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Modifications for new nGene firmware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * support for EEPROM-copying,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * support for new dual DVB-S2 card prototype
^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) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pci_ids.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "ngene.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* demods/tuners */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "stv6110x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "stv090x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "lnbh24.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "lgdt330x.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "mt2131.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "tda18271c2dd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "drxk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "drxd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "dvb-pll.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "stv0367.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "stv0367_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "tda18212.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "cxd2841er.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "stv0910.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "stv6111.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "lnbh25.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* I2C transfer functions used for demod/tuner probing***********************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static int i2c_io(struct i2c_adapter *adapter, u8 adr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .buf = wbuf, .len = wlen },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {.addr = adr, .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .buf = rbuf, .len = rlen } };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
^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) static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct i2c_msg msg = {.addr = adr, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .buf = data, .len = len};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static int i2c_write_reg(struct i2c_adapter *adap, u8 adr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u8 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) u8 msg[2] = {reg, val};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return i2c_write(adap, adr, msg, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .buf = val, .len = 1 } };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u16 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u8 msg[2] = {reg >> 8, reg & 0xff};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .buf = msg, .len = 2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {.addr = adr, .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .buf = val, .len = 1} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
^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) static int i2c_read_regs(struct i2c_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u8 adr, u8 reg, u8 *val, u8 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .buf = ®, .len = 1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {.addr = adr, .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .buf = val, .len = len} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return i2c_read_regs(adapter, adr, reg, val, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Demod/tuner attachment ***************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static struct i2c_adapter *i2c_adapter_from_chan(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (chan->number < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return &chan->dev->channel[0].i2c_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return &chan->dev->channel[1].i2c_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int tuner_attach_stv6110(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct i2c_adapter *i2c = i2c_adapter_from_chan(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct stv090x_config *feconf = (struct stv090x_config *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) chan->dev->card_info->fe_config[chan->number];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct stv6110x_config *tunerconf = (struct stv6110x_config *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) chan->dev->card_info->tuner_config[chan->number];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) const struct stv6110x_devctl *ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (ctl == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dev_err(pdev, "No STV6110X found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) feconf->tuner_init = ctl->tuner_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) feconf->tuner_sleep = ctl->tuner_sleep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) feconf->tuner_set_mode = ctl->tuner_set_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) feconf->tuner_set_frequency = ctl->tuner_set_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) feconf->tuner_get_frequency = ctl->tuner_get_frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) feconf->tuner_set_bbgain = ctl->tuner_set_bbgain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) feconf->tuner_get_bbgain = ctl->tuner_get_bbgain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) feconf->tuner_set_refclk = ctl->tuner_set_refclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) feconf->tuner_get_status = ctl->tuner_get_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 0;
^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 tuner_attach_stv6111(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct i2c_adapter *i2c = i2c_adapter_from_chan(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct dvb_frontend *fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u8 adr = 4 + ((chan->number & 1) ? 0x63 : 0x60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) fe = dvb_attach(stv6111_attach, chan->fe, i2c, adr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!fe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) fe = dvb_attach(stv6111_attach, chan->fe, i2c, adr & ~4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (!fe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) dev_err(pdev, "stv6111_attach() failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct ngene_channel *chan = fe->sec_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) down(&chan->dev->pll_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) status = chan->gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) status = chan->gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) up(&chan->dev->pll_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int tuner_attach_tda18271(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct i2c_adapter *i2c = i2c_adapter_from_chan(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct dvb_frontend *fe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (chan->fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) chan->fe->ops.i2c_gate_ctrl(chan->fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) fe = dvb_attach(tda18271c2dd_attach, chan->fe, i2c, 0x60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (chan->fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) chan->fe->ops.i2c_gate_ctrl(chan->fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!fe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dev_err(pdev, "No TDA18271 found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static int tuner_tda18212_ping(struct ngene_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct i2c_adapter *i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned short adr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u8 tda_id[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) u8 subaddr = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) dev_dbg(pdev, "stv0367-tda18212 tuner ping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) if (chan->fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) chan->fe->ops.i2c_gate_ctrl(chan->fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (i2c_read_regs(i2c, adr, subaddr, tda_id, sizeof(tda_id)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) dev_dbg(pdev, "tda18212 ping 1 fail\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (i2c_read_regs(i2c, adr, subaddr, tda_id, sizeof(tda_id)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dev_warn(pdev, "tda18212 ping failed, expect problems\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (chan->fe->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) chan->fe->ops.i2c_gate_ctrl(chan->fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static int tuner_attach_tda18212(struct ngene_channel *chan, u32 dmdtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct i2c_adapter *i2c = i2c_adapter_from_chan(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) struct tda18212_config config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) .fe = chan->fe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) .if_dvbt_6 = 3550,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) .if_dvbt_7 = 3700,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) .if_dvbt_8 = 4150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) .if_dvbt2_6 = 3250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) .if_dvbt2_7 = 4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .if_dvbt2_8 = 4000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .if_dvbc = 5000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) u8 addr = (chan->number & 1) ? 0x63 : 0x60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * due to a hardware quirk with the I2C gate on the stv0367+tda18212
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * combo, the tda18212 must be probed by reading it's id _twice_ when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * cold started, or it very likely will fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (dmdtype == DEMOD_TYPE_STV0367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) tuner_tda18212_ping(chan, i2c, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /* perform tuner probe/init/attach */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) client = dvb_module_probe("tda18212", NULL, i2c, addr, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (!client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) chan->i2c_client[0] = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) chan->i2c_client_fe = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dev_err(pdev, "TDA18212 tuner not found. Device is not fully operational.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) static int tuner_attach_probe(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) switch (chan->demod_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) case DEMOD_TYPE_STV090X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return tuner_attach_stv6110(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case DEMOD_TYPE_DRXK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return tuner_attach_tda18271(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case DEMOD_TYPE_STV0367:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) case DEMOD_TYPE_SONY_CT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) case DEMOD_TYPE_SONY_ISDBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) case DEMOD_TYPE_SONY_C2T2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) case DEMOD_TYPE_SONY_C2T2I:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return tuner_attach_tda18212(chan, chan->demod_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) case DEMOD_TYPE_STV0910:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return tuner_attach_stv6111(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static int demod_attach_stv0900(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct i2c_adapter *i2c = i2c_adapter_from_chan(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct stv090x_config *feconf = (struct stv090x_config *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) chan->dev->card_info->fe_config[chan->number];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) chan->fe = dvb_attach(stv090x_attach, feconf, i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) : STV090x_DEMODULATOR_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (chan->fe == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) dev_err(pdev, "No STV0900 found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) /* store channel info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (feconf->tuner_i2c_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) chan->fe->analog_demod_priv = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 0, chan->dev->card_info->lnb[chan->number])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) dev_err(pdev, "No LNBH24 found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) dvb_frontend_detach(chan->fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) chan->fe = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return -ENODEV;
^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) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static struct stv0910_cfg stv0910_p = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .adr = 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .parallel = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .rptlvl = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) .clk = 30000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .tsspeed = 0x28,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static struct lnbh25_config lnbh25_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .i2c_address = 0x0c << 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .data2_config = LNBH25_TEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static int demod_attach_stv0910(struct ngene_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct stv0910_cfg cfg = stv0910_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct lnbh25_config lnbcfg = lnbh25_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) chan->fe = dvb_attach(stv0910_attach, i2c, &cfg, (chan->number & 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!chan->fe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) cfg.adr = 0x6c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) chan->fe = dvb_attach(stv0910_attach, i2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) &cfg, (chan->number & 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!chan->fe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) dev_err(pdev, "stv0910_attach() failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * attach lnbh25 - leftshift by one as the lnbh25 driver expects 8bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * i2c addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) lnbcfg.i2c_address = (((chan->number & 1) ? 0x0d : 0x0c) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (!dvb_attach(lnbh25_attach, chan->fe, &lnbcfg, i2c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) lnbcfg.i2c_address = (((chan->number & 1) ? 0x09 : 0x08) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (!dvb_attach(lnbh25_attach, chan->fe, &lnbcfg, i2c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) dev_err(pdev, "lnbh25_attach() failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) dvb_frontend_detach(chan->fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) chan->fe = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static struct stv0367_config ddb_stv0367_config[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) .demod_address = 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .xtal = 27000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .if_khz = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .if_iq_mode = FE_TER_NORMAL_IF_TUNER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .demod_address = 0x1e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .xtal = 27000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .if_khz = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .if_iq_mode = FE_TER_NORMAL_IF_TUNER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .ts_mode = STV0367_SERIAL_PUNCT_CLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .clk_pol = STV0367_CLOCKPOLARITY_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static int demod_attach_stv0367(struct ngene_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) chan->fe = dvb_attach(stv0367ddb_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) &ddb_stv0367_config[(chan->number & 1)], i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (!chan->fe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) dev_err(pdev, "stv0367ddb_attach() failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) chan->fe->sec_priv = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int demod_attach_cxd28xx(struct ngene_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct i2c_adapter *i2c, int osc24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct cxd2841er_config cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* the cxd2841er driver expects 8bit/shifted I2C addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) cfg.i2c_addr = ((chan->number & 1) ? 0x6d : 0x6c) << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) cfg.xtal = osc24 ? SONY_XTAL_24000 : SONY_XTAL_20500;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) cfg.flags = CXD2841ER_AUTO_IFHZ | CXD2841ER_EARLY_TUNE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) CXD2841ER_NO_WAIT_LOCK | CXD2841ER_NO_AGCNEG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) CXD2841ER_TSBITS | CXD2841ER_TS_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* attach frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) chan->fe = dvb_attach(cxd2841er_attach_t_c, &cfg, i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (!chan->fe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) dev_err(pdev, "CXD28XX attach failed!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) chan->fe->sec_priv = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct ngene_channel *chan = fe->analog_demod_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) down(&chan->dev->pll_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) up(&chan->dev->pll_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int port_has_stv0900(struct i2c_adapter *i2c, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (i2c_read_reg16(i2c, 0x68+port/2, 0xf100, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) static int port_has_drxk(struct i2c_adapter *i2c, int port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (i2c_read(i2c, 0x29+port, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int port_has_stv0367(struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (i2c_read_reg16(i2c, 0x1e, 0xf000, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (val != 0x60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (i2c_read_reg16(i2c, 0x1f, 0xf000, &val) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (val != 0x60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int ngene_port_has_cxd2099(struct i2c_adapter *i2c, u8 *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) u8 probe[4] = { 0xe0, 0x00, 0x00, 0x00 }, data[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct i2c_msg msgs[2] = {{ .addr = 0x40, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .buf = probe, .len = 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) { .addr = 0x40, .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .buf = data, .len = 4 } };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) val = i2c_transfer(i2c, msgs, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (val != 2)
^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) if (data[0] == 0x02 && data[1] == 0x2b && data[3] == 0x43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) *type = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) *type = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static int demod_attach_drxk(struct ngene_channel *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct drxk_config config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) memset(&config, 0, sizeof(config));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) config.microcode_name = "drxk_a3.mc";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) config.qam_demod_parameter_count = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) config.adr = 0x29 + (chan->number ^ 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) chan->fe = dvb_attach(drxk_attach, &config, i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!chan->fe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) dev_err(pdev, "No DRXK found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) chan->fe->sec_priv = chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /* XO2 related lists and functions ******************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static char *xo2names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) "DUAL DVB-S2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) "DUAL DVB-C/T/T2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) "DUAL DVB-ISDBT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) "DUAL DVB-C/C2/T/T2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) "DUAL ATSC",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) "DUAL DVB-C/C2/T/T2/I",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static int init_xo2(struct ngene_channel *chan, struct i2c_adapter *i2c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) u8 addr = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) u8 val, data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) int res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) res = i2c_read_regs(i2c, addr, 0x04, data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (res < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (data[0] != 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) dev_info(pdev, "Invalid XO2 on channel %d\n", chan->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) i2c_read_reg(i2c, addr, 0x08, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (val != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) i2c_write_reg(i2c, addr, 0x08, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* Enable tuner power, disable pll, reset demods */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) i2c_write_reg(i2c, addr, 0x08, 0x04);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) usleep_range(2000, 3000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) /* Release demod resets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) i2c_write_reg(i2c, addr, 0x08, 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * speed: 0=55,1=75,2=90,3=104 MBit/s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * Note: The ngene hardware must be run at 75 MBit/s compared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * to more modern ddbridge hardware which runs at 90 MBit/s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * else there will be issues with the data transport and non-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * working secondary/slave demods/tuners.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) i2c_write_reg(i2c, addr, 0x09, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) i2c_write_reg(i2c, addr, 0x0a, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) i2c_write_reg(i2c, addr, 0x0b, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) usleep_range(2000, 3000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) /* Start XO2 PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) i2c_write_reg(i2c, addr, 0x08, 0x87);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static int port_has_xo2(struct i2c_adapter *i2c, u8 *type, u8 *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) u8 probe[1] = { 0x00 }, data[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) u8 addr = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) *type = NGENE_XO2_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (i2c_io(i2c, addr, probe, 1, data, 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (data[0] == 'D' && data[1] == 'F') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) *id = data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) *type = NGENE_XO2_TYPE_DUOFLEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) if (data[0] == 'C' && data[1] == 'I') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) *id = data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) *type = NGENE_XO2_TYPE_CI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /* Probing and port/channel handling ****************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static int cineS2_probe(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct i2c_adapter *i2c = i2c_adapter_from_chan(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct stv090x_config *fe_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) u8 xo2_type, xo2_id, xo2_demodtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) u8 sony_osc24 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct i2c_msg i2c_msg = { .flags = 0, .buf = buf };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (port_has_xo2(i2c, &xo2_type, &xo2_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) xo2_id >>= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) dev_dbg(pdev, "XO2 on channel %d (type %d, id %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) chan->number, xo2_type, xo2_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) switch (xo2_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) case NGENE_XO2_TYPE_DUOFLEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (chan->number & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) dev_dbg(pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) "skipping XO2 init on odd channel %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) chan->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) init_xo2(chan, i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) xo2_demodtype = DEMOD_TYPE_XO2 + xo2_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) switch (xo2_demodtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) case DEMOD_TYPE_SONY_CT2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) case DEMOD_TYPE_SONY_ISDBT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) case DEMOD_TYPE_SONY_C2T2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case DEMOD_TYPE_SONY_C2T2I:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) dev_info(pdev, "%s (XO2) on channel %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) xo2names[xo2_id], chan->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) chan->demod_type = xo2_demodtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if (xo2_demodtype == DEMOD_TYPE_SONY_C2T2I)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) sony_osc24 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) demod_attach_cxd28xx(chan, i2c, sony_osc24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) case DEMOD_TYPE_STV0910:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) dev_info(pdev, "%s (XO2) on channel %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) xo2names[xo2_id], chan->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) chan->demod_type = xo2_demodtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) demod_attach_stv0910(chan, i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) dev_warn(pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) "Unsupported XO2 module on channel %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) chan->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) case NGENE_XO2_TYPE_CI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) dev_info(pdev, "DuoFlex CI modules not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) dev_info(pdev, "Unsupported XO2 module type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) } else if (port_has_stv0900(i2c, chan->number)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) chan->demod_type = DEMOD_TYPE_STV090X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) fe_conf = chan->dev->card_info->fe_config[chan->number];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* demod found, attach it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) rc = demod_attach_stv0900(chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (rc < 0 || chan->number < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /* demod #2: reprogram outputs DPN1 & DPN2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) i2c_msg.addr = fe_conf->address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) i2c_msg.len = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) buf[0] = 0xf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) switch (chan->number) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) buf[1] = 0x5c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) buf[2] = 0xc2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) buf[1] = 0x61;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) buf[2] = 0xcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) rc = i2c_transfer(i2c, &i2c_msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) if (rc != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dev_err(pdev, "Could not setup DPNx\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) } else if (port_has_drxk(i2c, chan->number^2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) chan->demod_type = DEMOD_TYPE_DRXK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) demod_attach_drxk(chan, i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) } else if (port_has_stv0367(i2c)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) chan->demod_type = DEMOD_TYPE_STV0367;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) dev_info(pdev, "STV0367 on channel %d\n", chan->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) demod_attach_stv0367(chan, i2c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) dev_info(pdev, "No demod found on chan %d\n", chan->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static struct lgdt330x_config aver_m780 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) .demod_chip = LGDT3303,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) .serial_mpeg = 0x00, /* PARALLEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) .clock_polarity_flip = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) static struct mt2131_config m780_tunerconfig = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 0xc0 >> 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /* A single func to attach the demo and tuner, rather than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * use two sep funcs like the current design mandates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) static int demod_attach_lg330x(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) chan->fe = dvb_attach(lgdt330x_attach, &aver_m780,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 0xb2 >> 1, &chan->i2c_adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (chan->fe == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev_err(pdev, "No LGDT330x found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) dvb_attach(mt2131_attach, chan->fe, &chan->i2c_adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) &m780_tunerconfig, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return (chan->fe) ? 0 : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static int demod_attach_drxd(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct drxd_config *feconf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) feconf = chan->dev->card_info->fe_config[chan->number];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) chan->fe = dvb_attach(drxd_attach, feconf, chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) &chan->i2c_adapter, &chan->dev->pci_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (!chan->fe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) dev_err(pdev, "No DRXD found!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static int tuner_attach_dtt7520x(struct ngene_channel *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct drxd_config *feconf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) feconf = chan->dev->card_info->fe_config[chan->number];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (!dvb_attach(dvb_pll_attach, chan->fe, feconf->pll_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) &chan->i2c_adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) feconf->pll_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) dev_err(pdev, "No pll(%d) found!\n", feconf->pll_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /* EEPROM TAGS **************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) #define MICNG_EE_START 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) #define MICNG_EE_END 0x0FF0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) #define MICNG_EETAG_END0 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) #define MICNG_EETAG_END1 0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /* 0x0001 - 0x000F reserved for housekeeping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* 0xFFFF - 0xFFFE reserved for housekeeping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /* Micronas assigned tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) EEProm tags for hardware support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) #define MICNG_EETAG_DRXD1_OSCDEVIATION 0x1000 /* 2 Bytes data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) #define MICNG_EETAG_DRXD2_OSCDEVIATION 0x1001 /* 2 Bytes data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) #define MICNG_EETAG_MT2060_1_1STIF 0x1100 /* 2 Bytes data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) #define MICNG_EETAG_MT2060_2_1STIF 0x1101 /* 2 Bytes data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) /* Tag range for OEMs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) #define MICNG_EETAG_OEM_FIRST 0xC000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) #define MICNG_EETAG_OEM_LAST 0xFFEF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) static int i2c_write_eeprom(struct i2c_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) u8 adr, u16 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) struct device *pdev = adapter->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) u8 m[3] = {(reg >> 8), (reg & 0xff), data};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) .len = sizeof(m)};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (i2c_transfer(adapter, &msg, 1) != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) dev_err(pdev, "Error writing EEPROM!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static int i2c_read_eeprom(struct i2c_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) u8 adr, u16 reg, u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct device *pdev = adapter->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) u8 msg[2] = {(reg >> 8), (reg & 0xff)};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) .buf = msg, .len = 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {.addr = adr, .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) .buf = data, .len = len} };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (i2c_transfer(adapter, msgs, 2) != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) dev_err(pdev, "Error reading EEPROM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) static int ReadEEProm(struct i2c_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) u16 Tag, u32 MaxLen, u8 *data, u32 *pLength)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct device *pdev = adapter->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) u16 Addr = MICNG_EE_START, Length, tag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) u8 EETag[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) tag = (EETag[0] << 8) | EETag[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (tag == Tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) Addr += sizeof(u16) + 1 + EETag[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) dev_err(pdev, "Reached EOEE @ Tag = %04x Length = %3d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) tag, EETag[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) Length = EETag[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (Length > MaxLen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) Length = (u16) MaxLen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (Length > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) Addr += sizeof(u16) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) status = i2c_read_eeprom(adapter, 0x50, Addr, data, Length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) *pLength = EETag[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (Length < EETag[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) status = STATUS_BUFFER_OVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static int WriteEEProm(struct i2c_adapter *adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) u16 Tag, u32 Length, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct device *pdev = adapter->dev.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) u16 Addr = MICNG_EE_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) u8 EETag[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) u16 tag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) int retry, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) while (Addr + sizeof(u16) + 1 < MICNG_EE_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (i2c_read_eeprom(adapter, 0x50, Addr, EETag, sizeof(EETag)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) tag = (EETag[0] << 8) | EETag[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (tag == MICNG_EETAG_END0 || tag == MICNG_EETAG_END1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (tag == Tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) Addr += sizeof(u16) + 1 + EETag[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (Addr + sizeof(u16) + 1 + EETag[2] > MICNG_EE_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev_err(pdev, "Reached EOEE @ Tag = %04x Length = %3d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) tag, EETag[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (Length > EETag[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* Note: We write the data one byte at a time to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) issues with page sizes. (which are different for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) each manufacture and eeprom size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) Addr += sizeof(u16) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) for (i = 0; i < Length; i++, Addr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) status = i2c_write_eeprom(adapter, 0x50, Addr, data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /* Poll for finishing write cycle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) retry = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) while (retry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) u8 Tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) status = i2c_read_eeprom(adapter, 0x50, Addr, &Tmp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (Tmp != data[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) dev_err(pdev, "eeprom write error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) retry -= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) dev_err(pdev, "Timeout polling eeprom\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static int eeprom_read_ushort(struct i2c_adapter *adapter, u16 tag, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) u32 len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) stat = ReadEEProm(adapter, tag, 2, buf, &len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (len != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) *data = (buf[0] << 8) | buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) static int eeprom_write_ushort(struct i2c_adapter *adapter, u16 tag, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) int stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) buf[0] = data >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) buf[1] = data & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) stat = WriteEEProm(adapter, tag, 2, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) static s16 osc_deviation(void *priv, s16 deviation, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) struct ngene_channel *chan = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) struct device *pdev = &chan->dev->pci_dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct i2c_adapter *adap = &chan->i2c_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) u16 data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) data = (u16) deviation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) dev_info(pdev, "write deviation %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) deviation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) eeprom_write_ushort(adap, 0x1000 + chan->number, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (eeprom_read_ushort(adap, 0x1000 + chan->number, &data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) dev_info(pdev, "read deviation %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) (s16)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return (s16) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* Switch control (I2C gates, etc.) *****************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) static struct stv090x_config fe_cineS2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) .device = STV0900,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) .demod_mode = STV090x_DUAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) .clk_mode = STV090x_CLK_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) .xtal = 27000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .address = 0x68,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) .repeater_level = STV090x_RPTLEVEL_16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) .adc1_range = STV090x_ADC_1Vpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) .adc2_range = STV090x_ADC_1Vpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) .diseqc_envelope_mode = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) .tuner_i2c_lock = cineS2_tuner_i2c_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) static struct stv090x_config fe_cineS2_2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) .device = STV0900,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) .demod_mode = STV090x_DUAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) .clk_mode = STV090x_CLK_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) .xtal = 27000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) .address = 0x69,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .repeater_level = STV090x_RPTLEVEL_16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .adc1_range = STV090x_ADC_1Vpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .adc2_range = STV090x_ADC_1Vpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) .diseqc_envelope_mode = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) .tuner_i2c_lock = cineS2_tuner_i2c_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static struct stv6110x_config tuner_cineS2_0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) .addr = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .refclk = 27000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .clk_div = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static struct stv6110x_config tuner_cineS2_1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) .addr = 0x63,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) .refclk = 27000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .clk_div = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static const struct ngene_info ngene_info_cineS2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .type = NGENE_SIDEWINDER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .name = "Linux4Media cineS2 DVB-S2 Twin Tuner",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .fe_config = {&fe_cineS2, &fe_cineS2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) .lnb = {0x0b, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) .tsf = {3, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) .fw_version = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) .msi_supported = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) static const struct ngene_info ngene_info_satixS2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) .type = NGENE_SIDEWINDER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) .name = "Mystique SaTiX-S2 Dual",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) .demod_attach = {demod_attach_stv0900, demod_attach_stv0900},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) .fe_config = {&fe_cineS2, &fe_cineS2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .lnb = {0x0b, 0x08},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .tsf = {3, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .fw_version = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .msi_supported = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) static const struct ngene_info ngene_info_satixS2v2 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .type = NGENE_SIDEWINDER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .name = "Mystique SaTiX-S2 Dual (v2)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) NGENE_IO_TSOUT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) .lnb = {0x0a, 0x08, 0x0b, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .tsf = {3, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .fw_version = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) .msi_supported = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static const struct ngene_info ngene_info_cineS2v5 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) .type = NGENE_SIDEWINDER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) NGENE_IO_TSOUT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) .lnb = {0x0a, 0x08, 0x0b, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) .tsf = {3, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .fw_version = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .msi_supported = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static const struct ngene_info ngene_info_duoFlex = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) .type = NGENE_SIDEWINDER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .name = "Digital Devices DuoFlex PCIe or miniPCIe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) NGENE_IO_TSOUT},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) .demod_attach = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) .tuner_attach = {tuner_attach_probe, tuner_attach_probe, tuner_attach_probe, tuner_attach_probe},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .lnb = {0x0a, 0x08, 0x0b, 0x09},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .tsf = {3, 3},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) .fw_version = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) .msi_supported = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static const struct ngene_info ngene_info_m780 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) .type = NGENE_APP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) .name = "Aver M780 ATSC/QAM-B",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) /* Channel 0 is analog, which is currently unsupported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) .io_type = { NGENE_IO_NONE, NGENE_IO_TSIN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) .demod_attach = { NULL, demod_attach_lg330x },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) /* Ensure these are NULL else the frame will call them (as funcs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .tuner_attach = { NULL, NULL, NULL, NULL },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .fe_config = { NULL, &aver_m780 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) .avf = { 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /* A custom electrical interface config for the demod to bridge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .tsf = { 4, 4 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) .fw_version = 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) static struct drxd_config fe_terratec_dvbt_0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) .index = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) .demod_address = 0x70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) .demod_revision = 0xa2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) .demoda_address = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) .pll_address = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) .pll_type = DVB_PLL_THOMSON_DTT7520X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) .clock = 20000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) .osc_deviation = osc_deviation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) static struct drxd_config fe_terratec_dvbt_1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) .index = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) .demod_address = 0x71,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) .demod_revision = 0xa2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) .demoda_address = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) .pll_address = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) .pll_type = DVB_PLL_THOMSON_DTT7520X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) .clock = 20000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) .osc_deviation = osc_deviation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) static const struct ngene_info ngene_info_terratec = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) .type = NGENE_TERRATEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) .name = "Terratec Integra/Cinergy2400i Dual DVB-T",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) .demod_attach = {demod_attach_drxd, demod_attach_drxd},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) .tuner_attach = {tuner_attach_dtt7520x, tuner_attach_dtt7520x},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) .fe_config = {&fe_terratec_dvbt_0, &fe_terratec_dvbt_1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) .i2c_access = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) /* PCI Subsystem ID *********************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) #define NGENE_ID(_subvend, _subdev, _driverdata) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) .vendor = NGENE_VID, .device = NGENE_PID, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) .subvendor = _subvend, .subdevice = _subdev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) .driver_data = (unsigned long) &_driverdata }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) static const struct pci_device_id ngene_id_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) NGENE_ID(0x18c3, 0xab04, ngene_info_cineS2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) NGENE_ID(0x18c3, 0xab05, ngene_info_cineS2v5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) NGENE_ID(0x18c3, 0xabc3, ngene_info_cineS2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) NGENE_ID(0x18c3, 0xabc4, ngene_info_cineS2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) NGENE_ID(0x1461, 0x062e, ngene_info_m780),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) NGENE_ID(0x153b, 0x1167, ngene_info_terratec),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) MODULE_DEVICE_TABLE(pci, ngene_id_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* Init/Exit ****************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static pci_ers_result_t ngene_error_detected(struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) pci_channel_state_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) dev_err(&dev->dev, "PCI error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (state == pci_channel_io_perm_failure)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return PCI_ERS_RESULT_DISCONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (state == pci_channel_io_frozen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) return PCI_ERS_RESULT_NEED_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return PCI_ERS_RESULT_CAN_RECOVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static pci_ers_result_t ngene_slot_reset(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) dev_info(&dev->dev, "slot reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) static void ngene_resume(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) dev_info(&dev->dev, "resume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) static const struct pci_error_handlers ngene_errors = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) .error_detected = ngene_error_detected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) .slot_reset = ngene_slot_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) .resume = ngene_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static struct pci_driver ngene_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .name = "ngene",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) .id_table = ngene_id_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .probe = ngene_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .remove = ngene_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .err_handler = &ngene_errors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) .shutdown = ngene_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) static __init int module_init_ngene(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) /* pr_*() since we don't have a device to use with dev_*() yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) pr_info("nGene PCIE bridge driver, Copyright (C) 2005-2007 Micronas\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return pci_register_driver(&ngene_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) static __exit void module_exit_ngene(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) pci_unregister_driver(&ngene_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) module_init(module_init_ngene);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) module_exit(module_exit_ngene);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) MODULE_DESCRIPTION("nGene");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) MODULE_AUTHOR("Micronas, Ralph Metzler, Manfred Voelkel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) MODULE_LICENSE("GPL");