Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
0004 
0005     Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
0006     Copyright (C) 2006-2007 Georg Acher
0007     Copyright (C) 2007-2008 Darron Broad
0008     March 2007
0009         Fixed some bugs.
0010         Added diseqc support.
0011         Added corrected signal strength support.
0012     August 2007
0013         Sync with legacy version.
0014         Some clean ups.
0015     Copyright (C) 2008 Igor Liplianin
0016     September, 9th 2008
0017         Fixed locking on high symbol rates (>30000).
0018         Implement MPEG initialization parameter.
0019     January, 17th 2009
0020         Fill set_voltage with actually control voltage code.
0021         Correct set tone to not affect voltage.
0022 
0023 */
0024 
0025 #include <linux/slab.h>
0026 #include <linux/kernel.h>
0027 #include <linux/module.h>
0028 #include <linux/moduleparam.h>
0029 #include <linux/init.h>
0030 #include <linux/firmware.h>
0031 
0032 #include <media/dvb_frontend.h>
0033 #include "cx24116.h"
0034 
0035 static int debug;
0036 module_param(debug, int, 0644);
0037 MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
0038 
0039 #define dprintk(args...) \
0040     do { \
0041         if (debug) \
0042             printk(KERN_INFO "cx24116: " args); \
0043     } while (0)
0044 
0045 #define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
0046 #define CX24116_SEARCH_RANGE_KHZ 5000
0047 
0048 /* known registers */
0049 #define CX24116_REG_COMMAND (0x00)      /* command args 0x00..0x1e */
0050 #define CX24116_REG_EXECUTE (0x1f)      /* execute command */
0051 #define CX24116_REG_MAILBOX (0x96)      /* FW or multipurpose mailbox? */
0052 #define CX24116_REG_RESET   (0x20)      /* reset status > 0     */
0053 #define CX24116_REG_SIGNAL  (0x9e)      /* signal low           */
0054 #define CX24116_REG_SSTATUS (0x9d)      /* signal high / status */
0055 #define CX24116_REG_QUALITY8 (0xa3)
0056 #define CX24116_REG_QSTATUS (0xbc)
0057 #define CX24116_REG_QUALITY0 (0xd5)
0058 #define CX24116_REG_BER0    (0xc9)
0059 #define CX24116_REG_BER8    (0xc8)
0060 #define CX24116_REG_BER16   (0xc7)
0061 #define CX24116_REG_BER24   (0xc6)
0062 #define CX24116_REG_UCB0    (0xcb)
0063 #define CX24116_REG_UCB8    (0xca)
0064 #define CX24116_REG_CLKDIV  (0xf3)
0065 #define CX24116_REG_RATEDIV (0xf9)
0066 
0067 /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
0068 #define CX24116_REG_FECSTATUS (0x9c)
0069 
0070 /* FECSTATUS bits */
0071 /* mask to determine configured fec (not tuned) or actual fec (tuned) */
0072 #define CX24116_FEC_FECMASK   (0x1f)
0073 
0074 /* Select DVB-S demodulator, else DVB-S2 */
0075 #define CX24116_FEC_DVBS      (0x20)
0076 #define CX24116_FEC_UNKNOWN   (0x40)    /* Unknown/unused */
0077 
0078 /* Pilot mode requested when tuning else always reset when tuned */
0079 #define CX24116_FEC_PILOT     (0x80)
0080 
0081 /* arg buffer size */
0082 #define CX24116_ARGLEN (0x1e)
0083 
0084 /* rolloff */
0085 #define CX24116_ROLLOFF_020 (0x00)
0086 #define CX24116_ROLLOFF_025 (0x01)
0087 #define CX24116_ROLLOFF_035 (0x02)
0088 
0089 /* pilot bit */
0090 #define CX24116_PILOT_OFF (0x00)
0091 #define CX24116_PILOT_ON (0x40)
0092 
0093 /* signal status */
0094 #define CX24116_HAS_SIGNAL   (0x01)
0095 #define CX24116_HAS_CARRIER  (0x02)
0096 #define CX24116_HAS_VITERBI  (0x04)
0097 #define CX24116_HAS_SYNCLOCK (0x08)
0098 #define CX24116_HAS_UNKNOWN1 (0x10)
0099 #define CX24116_HAS_UNKNOWN2 (0x20)
0100 #define CX24116_STATUS_MASK  (0x0f)
0101 #define CX24116_SIGNAL_MASK  (0xc0)
0102 
0103 #define CX24116_DISEQC_TONEOFF   (0)    /* toneburst never sent */
0104 #define CX24116_DISEQC_TONECACHE (1)    /* toneburst cached     */
0105 #define CX24116_DISEQC_MESGCACHE (2)    /* message cached       */
0106 
0107 /* arg offset for DiSEqC */
0108 #define CX24116_DISEQC_BURST  (1)
0109 #define CX24116_DISEQC_ARG2_2 (2)   /* unknown value=2 */
0110 #define CX24116_DISEQC_ARG3_0 (3)   /* unknown value=0 */
0111 #define CX24116_DISEQC_ARG4_0 (4)   /* unknown value=0 */
0112 #define CX24116_DISEQC_MSGLEN (5)
0113 #define CX24116_DISEQC_MSGOFS (6)
0114 
0115 /* DiSEqC burst */
0116 #define CX24116_DISEQC_MINI_A (0)
0117 #define CX24116_DISEQC_MINI_B (1)
0118 
0119 /* DiSEqC tone burst */
0120 static int toneburst = 1;
0121 module_param(toneburst, int, 0644);
0122 MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
0123     "2=MESSAGE CACHE (default:1)");
0124 
0125 /* SNR measurements */
0126 static int esno_snr;
0127 module_param(esno_snr, int, 0644);
0128 MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
0129     "1=ESNO(db * 10) (default:0)");
0130 
0131 enum cmds {
0132     CMD_SET_VCO     = 0x10,
0133     CMD_TUNEREQUEST = 0x11,
0134     CMD_MPEGCONFIG  = 0x13,
0135     CMD_TUNERINIT   = 0x14,
0136     CMD_BANDWIDTH   = 0x15,
0137     CMD_GETAGC      = 0x19,
0138     CMD_LNBCONFIG   = 0x20,
0139     CMD_LNBSEND     = 0x21, /* Formerly CMD_SEND_DISEQC */
0140     CMD_LNBDCLEVEL  = 0x22,
0141     CMD_SET_TONE    = 0x23,
0142     CMD_UPDFWVERS   = 0x35,
0143     CMD_TUNERSLEEP  = 0x36,
0144     CMD_AGCCONTROL  = 0x3b, /* Unknown */
0145 };
0146 
0147 /* The Demod/Tuner can't easily provide these, we cache them */
0148 struct cx24116_tuning {
0149     u32 frequency;
0150     u32 symbol_rate;
0151     enum fe_spectral_inversion inversion;
0152     enum fe_code_rate fec;
0153 
0154     enum fe_delivery_system delsys;
0155     enum fe_modulation modulation;
0156     enum fe_pilot pilot;
0157     enum fe_rolloff rolloff;
0158 
0159     /* Demod values */
0160     u8 fec_val;
0161     u8 fec_mask;
0162     u8 inversion_val;
0163     u8 pilot_val;
0164     u8 rolloff_val;
0165 };
0166 
0167 /* Basic commands that are sent to the firmware */
0168 struct cx24116_cmd {
0169     u8 len;
0170     u8 args[CX24116_ARGLEN];
0171 };
0172 
0173 struct cx24116_state {
0174     struct i2c_adapter *i2c;
0175     const struct cx24116_config *config;
0176 
0177     struct dvb_frontend frontend;
0178 
0179     struct cx24116_tuning dcur;
0180     struct cx24116_tuning dnxt;
0181 
0182     u8 skip_fw_load;
0183     u8 burst;
0184     struct cx24116_cmd dsec_cmd;
0185 };
0186 
0187 static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
0188 {
0189     u8 buf[] = { reg, data };
0190     struct i2c_msg msg = { .addr = state->config->demod_address,
0191         .flags = 0, .buf = buf, .len = 2 };
0192     int err;
0193 
0194     if (debug > 1)
0195         printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
0196             __func__, reg, data);
0197 
0198     err = i2c_transfer(state->i2c, &msg, 1);
0199     if (err != 1) {
0200         printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x, value == 0x%02x)\n",
0201                __func__, err, reg, data);
0202         return -EREMOTEIO;
0203     }
0204 
0205     return 0;
0206 }
0207 
0208 /* Bulk byte writes to a single I2C address, for 32k firmware load */
0209 static int cx24116_writeregN(struct cx24116_state *state, int reg,
0210                  const u8 *data, u16 len)
0211 {
0212     int ret;
0213     struct i2c_msg msg;
0214     u8 *buf;
0215 
0216     buf = kmalloc(len + 1, GFP_KERNEL);
0217     if (!buf)
0218         return -ENOMEM;
0219 
0220     *(buf) = reg;
0221     memcpy(buf + 1, data, len);
0222 
0223     msg.addr = state->config->demod_address;
0224     msg.flags = 0;
0225     msg.buf = buf;
0226     msg.len = len + 1;
0227 
0228     if (debug > 1)
0229         printk(KERN_INFO "cx24116: %s:  write regN 0x%02x, len = %d\n",
0230             __func__, reg, len);
0231 
0232     ret = i2c_transfer(state->i2c, &msg, 1);
0233     if (ret != 1) {
0234         printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
0235              __func__, ret, reg);
0236         ret = -EREMOTEIO;
0237     }
0238 
0239     kfree(buf);
0240 
0241     return ret;
0242 }
0243 
0244 static int cx24116_readreg(struct cx24116_state *state, u8 reg)
0245 {
0246     int ret;
0247     u8 b0[] = { reg };
0248     u8 b1[] = { 0 };
0249     struct i2c_msg msg[] = {
0250         { .addr = state->config->demod_address, .flags = 0,
0251             .buf = b0, .len = 1 },
0252         { .addr = state->config->demod_address, .flags = I2C_M_RD,
0253             .buf = b1, .len = 1 }
0254     };
0255 
0256     ret = i2c_transfer(state->i2c, msg, 2);
0257 
0258     if (ret != 2) {
0259         printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
0260             __func__, reg, ret);
0261         return ret;
0262     }
0263 
0264     if (debug > 1)
0265         printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
0266             reg, b1[0]);
0267 
0268     return b1[0];
0269 }
0270 
0271 static int cx24116_set_inversion(struct cx24116_state *state,
0272     enum fe_spectral_inversion inversion)
0273 {
0274     dprintk("%s(%d)\n", __func__, inversion);
0275 
0276     switch (inversion) {
0277     case INVERSION_OFF:
0278         state->dnxt.inversion_val = 0x00;
0279         break;
0280     case INVERSION_ON:
0281         state->dnxt.inversion_val = 0x04;
0282         break;
0283     case INVERSION_AUTO:
0284         state->dnxt.inversion_val = 0x0C;
0285         break;
0286     default:
0287         return -EINVAL;
0288     }
0289 
0290     state->dnxt.inversion = inversion;
0291 
0292     return 0;
0293 }
0294 
0295 /*
0296  * modfec (modulation and FEC)
0297  * ===========================
0298  *
0299  * MOD          FEC             mask/val    standard
0300  * ----         --------        ----------- --------
0301  * QPSK         FEC_1_2         0x02 0x02+X DVB-S
0302  * QPSK         FEC_2_3         0x04 0x02+X DVB-S
0303  * QPSK         FEC_3_4         0x08 0x02+X DVB-S
0304  * QPSK         FEC_4_5         0x10 0x02+X DVB-S (?)
0305  * QPSK         FEC_5_6         0x20 0x02+X DVB-S
0306  * QPSK         FEC_6_7         0x40 0x02+X DVB-S
0307  * QPSK         FEC_7_8         0x80 0x02+X DVB-S
0308  * QPSK         FEC_8_9         0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
0309  * QPSK         AUTO            0xff 0x02+X DVB-S
0310  *
0311  * For DVB-S high byte probably represents FEC
0312  * and low byte selects the modulator. The high
0313  * byte is search range mask. Bit 5 may turn
0314  * on DVB-S and remaining bits represent some
0315  * kind of calibration (how/what i do not know).
0316  *
0317  * Eg.(2/3) szap "Zone Horror"
0318  *
0319  * mask/val = 0x04, 0x20
0320  * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
0321  *
0322  * mask/val = 0x04, 0x30
0323  * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
0324  *
0325  * After tuning FECSTATUS contains actual FEC
0326  * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
0327  *
0328  * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
0329  *
0330  * NBC-QPSK     FEC_1_2         0x00, 0x04      DVB-S2
0331  * NBC-QPSK     FEC_3_5         0x00, 0x05      DVB-S2
0332  * NBC-QPSK     FEC_2_3         0x00, 0x06      DVB-S2
0333  * NBC-QPSK     FEC_3_4         0x00, 0x07      DVB-S2
0334  * NBC-QPSK     FEC_4_5         0x00, 0x08      DVB-S2
0335  * NBC-QPSK     FEC_5_6         0x00, 0x09      DVB-S2
0336  * NBC-QPSK     FEC_8_9         0x00, 0x0a      DVB-S2
0337  * NBC-QPSK     FEC_9_10        0x00, 0x0b      DVB-S2
0338  *
0339  * NBC-8PSK     FEC_3_5         0x00, 0x0c      DVB-S2
0340  * NBC-8PSK     FEC_2_3         0x00, 0x0d      DVB-S2
0341  * NBC-8PSK     FEC_3_4         0x00, 0x0e      DVB-S2
0342  * NBC-8PSK     FEC_5_6         0x00, 0x0f      DVB-S2
0343  * NBC-8PSK     FEC_8_9         0x00, 0x10      DVB-S2
0344  * NBC-8PSK     FEC_9_10        0x00, 0x11      DVB-S2
0345  *
0346  * For DVB-S2 low bytes selects both modulator
0347  * and FEC. High byte is meaningless here. To
0348  * set pilot, bit 6 (0x40) is set. When inspecting
0349  * FECSTATUS bit 7 (0x80) represents the pilot
0350  * selection whilst not tuned. When tuned, actual FEC
0351  * in use is found in FECSTATUS as per above. Pilot
0352  * value is reset.
0353  */
0354 
0355 /* A table of modulation, fec and configuration bytes for the demod.
0356  * Not all S2 mmodulation schemes are support and not all rates with
0357  * a scheme are support. Especially, no auto detect when in S2 mode.
0358  */
0359 static struct cx24116_modfec {
0360     enum fe_delivery_system delivery_system;
0361     enum fe_modulation modulation;
0362     enum fe_code_rate fec;
0363     u8 mask;    /* In DVBS mode this is used to autodetect */
0364     u8 val;     /* Passed to the firmware to indicate mode selection */
0365 } CX24116_MODFEC_MODES[] = {
0366  /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
0367 
0368  /*mod   fec       mask  val */
0369  { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
0370  { SYS_DVBS, QPSK, FEC_1_2,  0x02, 0x2e }, /* 00000010 00101110 */
0371  { SYS_DVBS, QPSK, FEC_2_3,  0x04, 0x2f }, /* 00000100 00101111 */
0372  { SYS_DVBS, QPSK, FEC_3_4,  0x08, 0x30 }, /* 00001000 00110000 */
0373  { SYS_DVBS, QPSK, FEC_4_5,  0xfe, 0x30 }, /* 000?0000 ?        */
0374  { SYS_DVBS, QPSK, FEC_5_6,  0x20, 0x31 }, /* 00100000 00110001 */
0375  { SYS_DVBS, QPSK, FEC_6_7,  0xfe, 0x30 }, /* 0?000000 ?        */
0376  { SYS_DVBS, QPSK, FEC_7_8,  0x80, 0x32 }, /* 10000000 00110010 */
0377  { SYS_DVBS, QPSK, FEC_8_9,  0xfe, 0x30 }, /* 0000000? ?        */
0378  { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
0379  /* NBC-QPSK */
0380  { SYS_DVBS2, QPSK, FEC_1_2,  0x00, 0x04 },
0381  { SYS_DVBS2, QPSK, FEC_3_5,  0x00, 0x05 },
0382  { SYS_DVBS2, QPSK, FEC_2_3,  0x00, 0x06 },
0383  { SYS_DVBS2, QPSK, FEC_3_4,  0x00, 0x07 },
0384  { SYS_DVBS2, QPSK, FEC_4_5,  0x00, 0x08 },
0385  { SYS_DVBS2, QPSK, FEC_5_6,  0x00, 0x09 },
0386  { SYS_DVBS2, QPSK, FEC_8_9,  0x00, 0x0a },
0387  { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
0388  /* 8PSK */
0389  { SYS_DVBS2, PSK_8, FEC_3_5,  0x00, 0x0c },
0390  { SYS_DVBS2, PSK_8, FEC_2_3,  0x00, 0x0d },
0391  { SYS_DVBS2, PSK_8, FEC_3_4,  0x00, 0x0e },
0392  { SYS_DVBS2, PSK_8, FEC_5_6,  0x00, 0x0f },
0393  { SYS_DVBS2, PSK_8, FEC_8_9,  0x00, 0x10 },
0394  { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
0395  /*
0396   * `val' can be found in the FECSTATUS register when tuning.
0397   * FECSTATUS will give the actual FEC in use if tuning was successful.
0398   */
0399 };
0400 
0401 static int cx24116_lookup_fecmod(struct cx24116_state *state,
0402     enum fe_delivery_system d, enum fe_modulation m, enum fe_code_rate f)
0403 {
0404     int i, ret = -EOPNOTSUPP;
0405 
0406     dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
0407 
0408     for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
0409         if ((d == CX24116_MODFEC_MODES[i].delivery_system) &&
0410             (m == CX24116_MODFEC_MODES[i].modulation) &&
0411             (f == CX24116_MODFEC_MODES[i].fec)) {
0412                 ret = i;
0413                 break;
0414             }
0415     }
0416 
0417     return ret;
0418 }
0419 
0420 static int cx24116_set_fec(struct cx24116_state *state,
0421                enum fe_delivery_system delsys,
0422                enum fe_modulation mod,
0423                enum fe_code_rate fec)
0424 {
0425     int ret = 0;
0426 
0427     dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
0428 
0429     ret = cx24116_lookup_fecmod(state, delsys, mod, fec);
0430 
0431     if (ret < 0)
0432         return ret;
0433 
0434     state->dnxt.fec = fec;
0435     state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
0436     state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
0437     dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
0438         state->dnxt.fec_mask, state->dnxt.fec_val);
0439 
0440     return 0;
0441 }
0442 
0443 static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
0444 {
0445     dprintk("%s(%d)\n", __func__, rate);
0446 
0447     /*  check if symbol rate is within limits */
0448     if ((rate > state->frontend.ops.info.symbol_rate_max) ||
0449         (rate < state->frontend.ops.info.symbol_rate_min)) {
0450         dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate);
0451         return -EOPNOTSUPP;
0452     }
0453 
0454     state->dnxt.symbol_rate = rate;
0455     dprintk("%s() symbol_rate = %d\n", __func__, rate);
0456 
0457     return 0;
0458 }
0459 
0460 static int cx24116_load_firmware(struct dvb_frontend *fe,
0461     const struct firmware *fw);
0462 
0463 static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
0464 {
0465     struct cx24116_state *state = fe->demodulator_priv;
0466     const struct firmware *fw;
0467     int ret = 0;
0468 
0469     dprintk("%s()\n", __func__);
0470 
0471     if (cx24116_readreg(state, 0x20) > 0) {
0472 
0473         if (state->skip_fw_load)
0474             return 0;
0475 
0476         /* Load firmware */
0477         /* request the firmware, this will block until loaded */
0478         printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
0479             __func__, CX24116_DEFAULT_FIRMWARE);
0480         ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
0481             state->i2c->dev.parent);
0482         printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
0483             __func__);
0484         if (ret) {
0485             printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n",
0486                    __func__);
0487             return ret;
0488         }
0489 
0490         /* Make sure we don't recurse back through here
0491          * during loading */
0492         state->skip_fw_load = 1;
0493 
0494         ret = cx24116_load_firmware(fe, fw);
0495         if (ret)
0496             printk(KERN_ERR "%s: Writing firmware to device failed\n",
0497                 __func__);
0498 
0499         release_firmware(fw);
0500 
0501         printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
0502             ret == 0 ? "complete" : "failed");
0503 
0504         /* Ensure firmware is always loaded if required */
0505         state->skip_fw_load = 0;
0506     }
0507 
0508     return ret;
0509 }
0510 
0511 /* Take a basic firmware command structure, format it
0512  * and forward it for processing
0513  */
0514 static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
0515 {
0516     struct cx24116_state *state = fe->demodulator_priv;
0517     int i, ret;
0518 
0519     dprintk("%s()\n", __func__);
0520 
0521     /* Load the firmware if required */
0522     ret = cx24116_firmware_ondemand(fe);
0523     if (ret != 0) {
0524         printk(KERN_ERR "%s(): Unable initialise the firmware\n",
0525             __func__);
0526         return ret;
0527     }
0528 
0529     /* Write the command */
0530     for (i = 0; i < cmd->len ; i++) {
0531         dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
0532         cx24116_writereg(state, i, cmd->args[i]);
0533     }
0534 
0535     /* Start execution and wait for cmd to terminate */
0536     cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
0537     while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
0538         msleep(10);
0539         if (i++ > 64) {
0540             /* Avoid looping forever if the firmware does
0541                 not respond */
0542             printk(KERN_WARNING "%s() Firmware not responding\n",
0543                 __func__);
0544             return -EREMOTEIO;
0545         }
0546     }
0547     return 0;
0548 }
0549 
0550 static int cx24116_load_firmware(struct dvb_frontend *fe,
0551     const struct firmware *fw)
0552 {
0553     struct cx24116_state *state = fe->demodulator_priv;
0554     struct cx24116_cmd cmd;
0555     int i, ret, len, max, remaining;
0556     unsigned char vers[4];
0557 
0558     dprintk("%s\n", __func__);
0559     dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
0560             fw->size,
0561             fw->data[0],
0562             fw->data[1],
0563             fw->data[fw->size-2],
0564             fw->data[fw->size-1]);
0565 
0566     /* Toggle 88x SRST pin to reset demod */
0567     if (state->config->reset_device)
0568         state->config->reset_device(fe);
0569 
0570     /* Begin the firmware load process */
0571     /* Prepare the demod, load the firmware, cleanup after load */
0572 
0573     /* Init PLL */
0574     cx24116_writereg(state, 0xE5, 0x00);
0575     cx24116_writereg(state, 0xF1, 0x08);
0576     cx24116_writereg(state, 0xF2, 0x13);
0577 
0578     /* Start PLL */
0579     cx24116_writereg(state, 0xe0, 0x03);
0580     cx24116_writereg(state, 0xe0, 0x00);
0581 
0582     /* Unknown */
0583     cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
0584     cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
0585 
0586     /* Unknown */
0587     cx24116_writereg(state, 0xF0, 0x03);
0588     cx24116_writereg(state, 0xF4, 0x81);
0589     cx24116_writereg(state, 0xF5, 0x00);
0590     cx24116_writereg(state, 0xF6, 0x00);
0591 
0592     /* Split firmware to the max I2C write len and write.
0593      * Writes whole firmware as one write when i2c_wr_max is set to 0. */
0594     if (state->config->i2c_wr_max)
0595         max = state->config->i2c_wr_max;
0596     else
0597         max = INT_MAX; /* enough for 32k firmware */
0598 
0599     for (remaining = fw->size; remaining > 0; remaining -= max - 1) {
0600         len = remaining;
0601         if (len > max - 1)
0602             len = max - 1;
0603 
0604         cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining],
0605             len);
0606     }
0607 
0608     cx24116_writereg(state, 0xF4, 0x10);
0609     cx24116_writereg(state, 0xF0, 0x00);
0610     cx24116_writereg(state, 0xF8, 0x06);
0611 
0612     /* Firmware CMD 10: VCO config */
0613     cmd.args[0x00] = CMD_SET_VCO;
0614     cmd.args[0x01] = 0x05;
0615     cmd.args[0x02] = 0xdc;
0616     cmd.args[0x03] = 0xda;
0617     cmd.args[0x04] = 0xae;
0618     cmd.args[0x05] = 0xaa;
0619     cmd.args[0x06] = 0x04;
0620     cmd.args[0x07] = 0x9d;
0621     cmd.args[0x08] = 0xfc;
0622     cmd.args[0x09] = 0x06;
0623     cmd.len = 0x0a;
0624     ret = cx24116_cmd_execute(fe, &cmd);
0625     if (ret != 0)
0626         return ret;
0627 
0628     cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
0629 
0630     /* Firmware CMD 14: Tuner config */
0631     cmd.args[0x00] = CMD_TUNERINIT;
0632     cmd.args[0x01] = 0x00;
0633     cmd.args[0x02] = 0x00;
0634     cmd.len = 0x03;
0635     ret = cx24116_cmd_execute(fe, &cmd);
0636     if (ret != 0)
0637         return ret;
0638 
0639     cx24116_writereg(state, 0xe5, 0x00);
0640 
0641     /* Firmware CMD 13: MPEG config */
0642     cmd.args[0x00] = CMD_MPEGCONFIG;
0643     cmd.args[0x01] = 0x01;
0644     cmd.args[0x02] = 0x75;
0645     cmd.args[0x03] = 0x00;
0646     if (state->config->mpg_clk_pos_pol)
0647         cmd.args[0x04] = state->config->mpg_clk_pos_pol;
0648     else
0649         cmd.args[0x04] = 0x02;
0650     cmd.args[0x05] = 0x00;
0651     cmd.len = 0x06;
0652     ret = cx24116_cmd_execute(fe, &cmd);
0653     if (ret != 0)
0654         return ret;
0655 
0656     /* Firmware CMD 35: Get firmware version */
0657     cmd.args[0x00] = CMD_UPDFWVERS;
0658     cmd.len = 0x02;
0659     for (i = 0; i < 4; i++) {
0660         cmd.args[0x01] = i;
0661         ret = cx24116_cmd_execute(fe, &cmd);
0662         if (ret != 0)
0663             return ret;
0664         vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
0665     }
0666     printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
0667         vers[0], vers[1], vers[2], vers[3]);
0668 
0669     return 0;
0670 }
0671 
0672 static int cx24116_read_status(struct dvb_frontend *fe, enum fe_status *status)
0673 {
0674     struct cx24116_state *state = fe->demodulator_priv;
0675 
0676     int lock = cx24116_readreg(state, CX24116_REG_SSTATUS) &
0677         CX24116_STATUS_MASK;
0678 
0679     dprintk("%s: status = 0x%02x\n", __func__, lock);
0680 
0681     *status = 0;
0682 
0683     if (lock & CX24116_HAS_SIGNAL)
0684         *status |= FE_HAS_SIGNAL;
0685     if (lock & CX24116_HAS_CARRIER)
0686         *status |= FE_HAS_CARRIER;
0687     if (lock & CX24116_HAS_VITERBI)
0688         *status |= FE_HAS_VITERBI;
0689     if (lock & CX24116_HAS_SYNCLOCK)
0690         *status |= FE_HAS_SYNC | FE_HAS_LOCK;
0691 
0692     return 0;
0693 }
0694 
0695 static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
0696 {
0697     struct cx24116_state *state = fe->demodulator_priv;
0698 
0699     dprintk("%s()\n", __func__);
0700 
0701     *ber =  (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
0702         (cx24116_readreg(state, CX24116_REG_BER16) << 16) |
0703         (cx24116_readreg(state, CX24116_REG_BER8)  << 8)  |
0704          cx24116_readreg(state, CX24116_REG_BER0);
0705 
0706     return 0;
0707 }
0708 
0709 /* TODO Determine function and scale appropriately */
0710 static int cx24116_read_signal_strength(struct dvb_frontend *fe,
0711     u16 *signal_strength)
0712 {
0713     struct cx24116_state *state = fe->demodulator_priv;
0714     struct cx24116_cmd cmd;
0715     int ret;
0716     u16 sig_reading;
0717 
0718     dprintk("%s()\n", __func__);
0719 
0720     /* Firmware CMD 19: Get AGC */
0721     cmd.args[0x00] = CMD_GETAGC;
0722     cmd.len = 0x01;
0723     ret = cx24116_cmd_execute(fe, &cmd);
0724     if (ret != 0)
0725         return ret;
0726 
0727     sig_reading =
0728         (cx24116_readreg(state,
0729             CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
0730         (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
0731     *signal_strength = 0 - sig_reading;
0732 
0733     dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
0734         __func__, sig_reading, *signal_strength);
0735 
0736     return 0;
0737 }
0738 
0739 /* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
0740 static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
0741 {
0742     struct cx24116_state *state = fe->demodulator_priv;
0743     u8 snr_reading;
0744     static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
0745         0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
0746         0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
0747         0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
0748         0x18000 };
0749 
0750     dprintk("%s()\n", __func__);
0751 
0752     snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
0753 
0754     if (snr_reading >= 0xa0 /* 100% */)
0755         *snr = 0xffff;
0756     else
0757         *snr = snr_tab[(snr_reading & 0xf0) >> 4] +
0758             (snr_tab[(snr_reading & 0x0f)] >> 4);
0759 
0760     dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
0761         snr_reading, *snr);
0762 
0763     return 0;
0764 }
0765 
0766 /* The reelbox patches show the value in the registers represents
0767  * ESNO, from 0->30db (values 0->300). We provide this value by
0768  * default.
0769  */
0770 static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
0771 {
0772     struct cx24116_state *state = fe->demodulator_priv;
0773 
0774     dprintk("%s()\n", __func__);
0775 
0776     *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
0777         cx24116_readreg(state, CX24116_REG_QUALITY0);
0778 
0779     dprintk("%s: raw 0x%04x\n", __func__, *snr);
0780 
0781     return 0;
0782 }
0783 
0784 static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
0785 {
0786     if (esno_snr == 1)
0787         return cx24116_read_snr_esno(fe, snr);
0788     else
0789         return cx24116_read_snr_pct(fe, snr);
0790 }
0791 
0792 static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
0793 {
0794     struct cx24116_state *state = fe->demodulator_priv;
0795 
0796     dprintk("%s()\n", __func__);
0797 
0798     *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
0799         cx24116_readreg(state, CX24116_REG_UCB0);
0800 
0801     return 0;
0802 }
0803 
0804 /* Overwrite the current tuning params, we are about to tune */
0805 static void cx24116_clone_params(struct dvb_frontend *fe)
0806 {
0807     struct cx24116_state *state = fe->demodulator_priv;
0808     state->dcur = state->dnxt;
0809 }
0810 
0811 /* Wait for LNB */
0812 static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
0813 {
0814     struct cx24116_state *state = fe->demodulator_priv;
0815     int i;
0816 
0817     dprintk("%s() qstatus = 0x%02x\n", __func__,
0818         cx24116_readreg(state, CX24116_REG_QSTATUS));
0819 
0820     /* Wait for up to 300 ms */
0821     for (i = 0; i < 30 ; i++) {
0822         if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
0823             return 0;
0824         msleep(10);
0825     }
0826 
0827     dprintk("%s(): LNB not ready\n", __func__);
0828 
0829     return -ETIMEDOUT; /* -EBUSY ? */
0830 }
0831 
0832 static int cx24116_set_voltage(struct dvb_frontend *fe,
0833     enum fe_sec_voltage voltage)
0834 {
0835     struct cx24116_cmd cmd;
0836     int ret;
0837 
0838     dprintk("%s: %s\n", __func__,
0839         voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
0840         voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
0841 
0842     /* Wait for LNB ready */
0843     ret = cx24116_wait_for_lnb(fe);
0844     if (ret != 0)
0845         return ret;
0846 
0847     /* Wait for voltage/min repeat delay */
0848     msleep(100);
0849 
0850     cmd.args[0x00] = CMD_LNBDCLEVEL;
0851     cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
0852     cmd.len = 0x02;
0853 
0854     /* Min delay time before DiSEqC send */
0855     msleep(15);
0856 
0857     return cx24116_cmd_execute(fe, &cmd);
0858 }
0859 
0860 static int cx24116_set_tone(struct dvb_frontend *fe,
0861     enum fe_sec_tone_mode tone)
0862 {
0863     struct cx24116_cmd cmd;
0864     int ret;
0865 
0866     dprintk("%s(%d)\n", __func__, tone);
0867     if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
0868         printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
0869         return -EINVAL;
0870     }
0871 
0872     /* Wait for LNB ready */
0873     ret = cx24116_wait_for_lnb(fe);
0874     if (ret != 0)
0875         return ret;
0876 
0877     /* Min delay time after DiSEqC send */
0878     msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
0879 
0880     /* Now we set the tone */
0881     cmd.args[0x00] = CMD_SET_TONE;
0882     cmd.args[0x01] = 0x00;
0883     cmd.args[0x02] = 0x00;
0884 
0885     switch (tone) {
0886     case SEC_TONE_ON:
0887         dprintk("%s: setting tone on\n", __func__);
0888         cmd.args[0x03] = 0x01;
0889         break;
0890     case SEC_TONE_OFF:
0891         dprintk("%s: setting tone off\n", __func__);
0892         cmd.args[0x03] = 0x00;
0893         break;
0894     }
0895     cmd.len = 0x04;
0896 
0897     /* Min delay time before DiSEqC send */
0898     msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
0899 
0900     return cx24116_cmd_execute(fe, &cmd);
0901 }
0902 
0903 /* Initialise DiSEqC */
0904 static int cx24116_diseqc_init(struct dvb_frontend *fe)
0905 {
0906     struct cx24116_state *state = fe->demodulator_priv;
0907     struct cx24116_cmd cmd;
0908     int ret;
0909 
0910     /* Firmware CMD 20: LNB/DiSEqC config */
0911     cmd.args[0x00] = CMD_LNBCONFIG;
0912     cmd.args[0x01] = 0x00;
0913     cmd.args[0x02] = 0x10;
0914     cmd.args[0x03] = 0x00;
0915     cmd.args[0x04] = 0x8f;
0916     cmd.args[0x05] = 0x28;
0917     cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
0918     cmd.args[0x07] = 0x01;
0919     cmd.len = 0x08;
0920     ret = cx24116_cmd_execute(fe, &cmd);
0921     if (ret != 0)
0922         return ret;
0923 
0924     /* Prepare a DiSEqC command */
0925     state->dsec_cmd.args[0x00] = CMD_LNBSEND;
0926 
0927     /* DiSEqC burst */
0928     state->dsec_cmd.args[CX24116_DISEQC_BURST]  = CX24116_DISEQC_MINI_A;
0929 
0930     /* Unknown */
0931     state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
0932     state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
0933     /* Continuation flag? */
0934     state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
0935 
0936     /* DiSEqC message length */
0937     state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
0938 
0939     /* Command length */
0940     state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
0941 
0942     return 0;
0943 }
0944 
0945 /* Send DiSEqC message with derived burst (hack) || previous burst */
0946 static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
0947     struct dvb_diseqc_master_cmd *d)
0948 {
0949     struct cx24116_state *state = fe->demodulator_priv;
0950     int i, ret;
0951 
0952     /* Validate length */
0953     if (d->msg_len > sizeof(d->msg))
0954         return -EINVAL;
0955 
0956     /* Dump DiSEqC message */
0957     if (debug) {
0958         printk(KERN_INFO "cx24116: %s(", __func__);
0959         for (i = 0 ; i < d->msg_len ;) {
0960             printk(KERN_INFO "0x%02x", d->msg[i]);
0961             if (++i < d->msg_len)
0962                 printk(KERN_INFO ", ");
0963         }
0964         printk(") toneburst=%d\n", toneburst);
0965     }
0966 
0967     /* DiSEqC message */
0968     for (i = 0; i < d->msg_len; i++)
0969         state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
0970 
0971     /* DiSEqC message length */
0972     state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
0973 
0974     /* Command length */
0975     state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
0976         state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
0977 
0978     /* DiSEqC toneburst */
0979     if (toneburst == CX24116_DISEQC_MESGCACHE)
0980         /* Message is cached */
0981         return 0;
0982 
0983     else if (toneburst == CX24116_DISEQC_TONEOFF)
0984         /* Message is sent without burst */
0985         state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
0986 
0987     else if (toneburst == CX24116_DISEQC_TONECACHE) {
0988         /*
0989          * Message is sent with derived else cached burst
0990          *
0991          * WRITE PORT GROUP COMMAND 38
0992          *
0993          * 0/A/A: E0 10 38 F0..F3
0994          * 1/B/B: E0 10 38 F4..F7
0995          * 2/C/A: E0 10 38 F8..FB
0996          * 3/D/B: E0 10 38 FC..FF
0997          *
0998          * databyte[3]= 8421:8421
0999          *              ABCD:WXYZ
1000          *              CLR :SET
1001          *
1002          *              WX= PORT SELECT 0..3    (X=TONEBURST)
1003          *              Y = VOLTAGE             (0=13V, 1=18V)
1004          *              Z = BAND                (0=LOW, 1=HIGH(22K))
1005          */
1006         if (d->msg_len >= 4 && d->msg[2] == 0x38)
1007             state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1008                 ((d->msg[3] & 4) >> 2);
1009         if (debug)
1010             dprintk("%s burst=%d\n", __func__,
1011                 state->dsec_cmd.args[CX24116_DISEQC_BURST]);
1012     }
1013 
1014     /* Wait for LNB ready */
1015     ret = cx24116_wait_for_lnb(fe);
1016     if (ret != 0)
1017         return ret;
1018 
1019     /* Wait for voltage/min repeat delay */
1020     msleep(100);
1021 
1022     /* Command */
1023     ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1024     if (ret != 0)
1025         return ret;
1026     /*
1027      * Wait for send
1028      *
1029      * Eutelsat spec:
1030      * >15ms delay          + (XXX determine if FW does this, see set_tone)
1031      *  13.5ms per byte     +
1032      * >15ms delay          +
1033      *  12.5ms burst        +
1034      * >15ms delay            (XXX determine if FW does this, see set_tone)
1035      */
1036     msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
1037         ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
1038 
1039     return 0;
1040 }
1041 
1042 /* Send DiSEqC burst */
1043 static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
1044     enum fe_sec_mini_cmd burst)
1045 {
1046     struct cx24116_state *state = fe->demodulator_priv;
1047     int ret;
1048 
1049     dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
1050 
1051     /* DiSEqC burst */
1052     if (burst == SEC_MINI_A)
1053         state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1054             CX24116_DISEQC_MINI_A;
1055     else if (burst == SEC_MINI_B)
1056         state->dsec_cmd.args[CX24116_DISEQC_BURST] =
1057             CX24116_DISEQC_MINI_B;
1058     else
1059         return -EINVAL;
1060 
1061     /* DiSEqC toneburst */
1062     if (toneburst != CX24116_DISEQC_MESGCACHE)
1063         /* Burst is cached */
1064         return 0;
1065 
1066     /* Burst is to be sent with cached message */
1067 
1068     /* Wait for LNB ready */
1069     ret = cx24116_wait_for_lnb(fe);
1070     if (ret != 0)
1071         return ret;
1072 
1073     /* Wait for voltage/min repeat delay */
1074     msleep(100);
1075 
1076     /* Command */
1077     ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1078     if (ret != 0)
1079         return ret;
1080 
1081     /*
1082      * Wait for send
1083      *
1084      * Eutelsat spec:
1085      * >15ms delay          + (XXX determine if FW does this, see set_tone)
1086      *  13.5ms per byte     +
1087      * >15ms delay          +
1088      *  12.5ms burst        +
1089      * >15ms delay            (XXX determine if FW does this, see set_tone)
1090      */
1091     msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
1092 
1093     return 0;
1094 }
1095 
1096 static void cx24116_release(struct dvb_frontend *fe)
1097 {
1098     struct cx24116_state *state = fe->demodulator_priv;
1099     dprintk("%s\n", __func__);
1100     kfree(state);
1101 }
1102 
1103 static const struct dvb_frontend_ops cx24116_ops;
1104 
1105 struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
1106     struct i2c_adapter *i2c)
1107 {
1108     struct cx24116_state *state;
1109     int ret;
1110 
1111     dprintk("%s\n", __func__);
1112 
1113     /* allocate memory for the internal state */
1114     state = kzalloc(sizeof(*state), GFP_KERNEL);
1115     if (state == NULL)
1116         return NULL;
1117 
1118     state->config = config;
1119     state->i2c = i2c;
1120 
1121     /* check if the demod is present */
1122     ret = (cx24116_readreg(state, 0xFF) << 8) |
1123         cx24116_readreg(state, 0xFE);
1124     if (ret != 0x0501) {
1125         kfree(state);
1126         printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
1127         return NULL;
1128     }
1129 
1130     /* create dvb_frontend */
1131     memcpy(&state->frontend.ops, &cx24116_ops,
1132         sizeof(struct dvb_frontend_ops));
1133     state->frontend.demodulator_priv = state;
1134     return &state->frontend;
1135 }
1136 EXPORT_SYMBOL(cx24116_attach);
1137 
1138 /*
1139  * Initialise or wake up device
1140  *
1141  * Power config will reset and load initial firmware if required
1142  */
1143 static int cx24116_initfe(struct dvb_frontend *fe)
1144 {
1145     struct cx24116_state *state = fe->demodulator_priv;
1146     struct cx24116_cmd cmd;
1147     int ret;
1148 
1149     dprintk("%s()\n", __func__);
1150 
1151     /* Power on */
1152     cx24116_writereg(state, 0xe0, 0);
1153     cx24116_writereg(state, 0xe1, 0);
1154     cx24116_writereg(state, 0xea, 0);
1155 
1156     /* Firmware CMD 36: Power config */
1157     cmd.args[0x00] = CMD_TUNERSLEEP;
1158     cmd.args[0x01] = 0;
1159     cmd.len = 0x02;
1160     ret = cx24116_cmd_execute(fe, &cmd);
1161     if (ret != 0)
1162         return ret;
1163 
1164     ret = cx24116_diseqc_init(fe);
1165     if (ret != 0)
1166         return ret;
1167 
1168     /* HVR-4000 needs this */
1169     return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
1170 }
1171 
1172 /*
1173  * Put device to sleep
1174  */
1175 static int cx24116_sleep(struct dvb_frontend *fe)
1176 {
1177     struct cx24116_state *state = fe->demodulator_priv;
1178     struct cx24116_cmd cmd;
1179     int ret;
1180 
1181     dprintk("%s()\n", __func__);
1182 
1183     /* Firmware CMD 36: Power config */
1184     cmd.args[0x00] = CMD_TUNERSLEEP;
1185     cmd.args[0x01] = 1;
1186     cmd.len = 0x02;
1187     ret = cx24116_cmd_execute(fe, &cmd);
1188     if (ret != 0)
1189         return ret;
1190 
1191     /* Power off (Shutdown clocks) */
1192     cx24116_writereg(state, 0xea, 0xff);
1193     cx24116_writereg(state, 0xe1, 1);
1194     cx24116_writereg(state, 0xe0, 1);
1195 
1196     return 0;
1197 }
1198 
1199 /* dvb-core told us to tune, the tv property cache will be complete,
1200  * it's safe for is to pull values and use them for tuning purposes.
1201  */
1202 static int cx24116_set_frontend(struct dvb_frontend *fe)
1203 {
1204     struct cx24116_state *state = fe->demodulator_priv;
1205     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1206     struct cx24116_cmd cmd;
1207     enum fe_status tunerstat;
1208     int i, status, ret, retune = 1;
1209 
1210     dprintk("%s()\n", __func__);
1211 
1212     switch (c->delivery_system) {
1213     case SYS_DVBS:
1214         dprintk("%s: DVB-S delivery system selected\n", __func__);
1215 
1216         /* Only QPSK is supported for DVB-S */
1217         if (c->modulation != QPSK) {
1218             dprintk("%s: unsupported modulation selected (%d)\n",
1219                 __func__, c->modulation);
1220             return -EOPNOTSUPP;
1221         }
1222 
1223         /* Pilot doesn't exist in DVB-S, turn bit off */
1224         state->dnxt.pilot_val = CX24116_PILOT_OFF;
1225 
1226         /* DVB-S only supports 0.35 */
1227         if (c->rolloff != ROLLOFF_35) {
1228             dprintk("%s: unsupported rolloff selected (%d)\n",
1229                 __func__, c->rolloff);
1230             return -EOPNOTSUPP;
1231         }
1232         state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1233         break;
1234 
1235     case SYS_DVBS2:
1236         dprintk("%s: DVB-S2 delivery system selected\n", __func__);
1237 
1238         /*
1239          * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
1240          * but not hardware auto detection
1241          */
1242         if (c->modulation != PSK_8 && c->modulation != QPSK) {
1243             dprintk("%s: unsupported modulation selected (%d)\n",
1244                 __func__, c->modulation);
1245             return -EOPNOTSUPP;
1246         }
1247 
1248         switch (c->pilot) {
1249         case PILOT_AUTO:    /* Not supported but emulated */
1250             state->dnxt.pilot_val = (c->modulation == QPSK)
1251                 ? CX24116_PILOT_OFF : CX24116_PILOT_ON;
1252             retune++;
1253             break;
1254         case PILOT_OFF:
1255             state->dnxt.pilot_val = CX24116_PILOT_OFF;
1256             break;
1257         case PILOT_ON:
1258             state->dnxt.pilot_val = CX24116_PILOT_ON;
1259             break;
1260         default:
1261             dprintk("%s: unsupported pilot mode selected (%d)\n",
1262                 __func__, c->pilot);
1263             return -EOPNOTSUPP;
1264         }
1265 
1266         switch (c->rolloff) {
1267         case ROLLOFF_20:
1268             state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
1269             break;
1270         case ROLLOFF_25:
1271             state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
1272             break;
1273         case ROLLOFF_35:
1274             state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1275             break;
1276         case ROLLOFF_AUTO:  /* Rolloff must be explicit */
1277         default:
1278             dprintk("%s: unsupported rolloff selected (%d)\n",
1279                 __func__, c->rolloff);
1280             return -EOPNOTSUPP;
1281         }
1282         break;
1283 
1284     default:
1285         dprintk("%s: unsupported delivery system selected (%d)\n",
1286             __func__, c->delivery_system);
1287         return -EOPNOTSUPP;
1288     }
1289     state->dnxt.delsys = c->delivery_system;
1290     state->dnxt.modulation = c->modulation;
1291     state->dnxt.frequency = c->frequency;
1292     state->dnxt.pilot = c->pilot;
1293     state->dnxt.rolloff = c->rolloff;
1294 
1295     ret = cx24116_set_inversion(state, c->inversion);
1296     if (ret !=  0)
1297         return ret;
1298 
1299     /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1300     ret = cx24116_set_fec(state, c->delivery_system, c->modulation, c->fec_inner);
1301     if (ret !=  0)
1302         return ret;
1303 
1304     ret = cx24116_set_symbolrate(state, c->symbol_rate);
1305     if (ret !=  0)
1306         return ret;
1307 
1308     /* discard the 'current' tuning parameters and prepare to tune */
1309     cx24116_clone_params(fe);
1310 
1311     dprintk("%s:   delsys      = %d\n", __func__, state->dcur.delsys);
1312     dprintk("%s:   modulation  = %d\n", __func__, state->dcur.modulation);
1313     dprintk("%s:   frequency   = %d\n", __func__, state->dcur.frequency);
1314     dprintk("%s:   pilot       = %d (val = 0x%02x)\n", __func__,
1315         state->dcur.pilot, state->dcur.pilot_val);
1316     dprintk("%s:   retune      = %d\n", __func__, retune);
1317     dprintk("%s:   rolloff     = %d (val = 0x%02x)\n", __func__,
1318         state->dcur.rolloff, state->dcur.rolloff_val);
1319     dprintk("%s:   symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1320     dprintk("%s:   FEC         = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1321         state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
1322     dprintk("%s:   Inversion   = %d (val = 0x%02x)\n", __func__,
1323         state->dcur.inversion, state->dcur.inversion_val);
1324 
1325     /* This is also done in advise/acquire on HVR4000 but not on LITE */
1326     if (state->config->set_ts_params)
1327         state->config->set_ts_params(fe, 0);
1328 
1329     /* Set/Reset B/W */
1330     cmd.args[0x00] = CMD_BANDWIDTH;
1331     cmd.args[0x01] = 0x01;
1332     cmd.len = 0x02;
1333     ret = cx24116_cmd_execute(fe, &cmd);
1334     if (ret != 0)
1335         return ret;
1336 
1337     /* Prepare a tune request */
1338     cmd.args[0x00] = CMD_TUNEREQUEST;
1339 
1340     /* Frequency */
1341     cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
1342     cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
1343     cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
1344 
1345     /* Symbol Rate */
1346     cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
1347     cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
1348 
1349     /* Automatic Inversion */
1350     cmd.args[0x06] = state->dcur.inversion_val;
1351 
1352     /* Modulation / FEC / Pilot */
1353     cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1354 
1355     cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
1356     cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
1357     cmd.args[0x0a] = 0x00;
1358     cmd.args[0x0b] = 0x00;
1359     cmd.args[0x0c] = state->dcur.rolloff_val;
1360     cmd.args[0x0d] = state->dcur.fec_mask;
1361 
1362     if (state->dcur.symbol_rate > 30000000) {
1363         cmd.args[0x0e] = 0x04;
1364         cmd.args[0x0f] = 0x00;
1365         cmd.args[0x10] = 0x01;
1366         cmd.args[0x11] = 0x77;
1367         cmd.args[0x12] = 0x36;
1368         cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
1369         cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
1370     } else {
1371         cmd.args[0x0e] = 0x06;
1372         cmd.args[0x0f] = 0x00;
1373         cmd.args[0x10] = 0x00;
1374         cmd.args[0x11] = 0xFA;
1375         cmd.args[0x12] = 0x24;
1376         cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
1377         cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
1378     }
1379 
1380     cmd.len = 0x13;
1381 
1382     /* We need to support pilot and non-pilot tuning in the
1383      * driver automatically. This is a workaround for because
1384      * the demod does not support autodetect.
1385      */
1386     do {
1387         /* Reset status register */
1388         status = cx24116_readreg(state, CX24116_REG_SSTATUS)
1389             & CX24116_SIGNAL_MASK;
1390         cx24116_writereg(state, CX24116_REG_SSTATUS, status);
1391 
1392         /* Tune */
1393         ret = cx24116_cmd_execute(fe, &cmd);
1394         if (ret != 0)
1395             break;
1396 
1397         /*
1398          * Wait for up to 500 ms before retrying
1399          *
1400          * If we are able to tune then generally it occurs within 100ms.
1401          * If it takes longer, try a different toneburst setting.
1402          */
1403         for (i = 0; i < 50 ; i++) {
1404             cx24116_read_status(fe, &tunerstat);
1405             status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
1406             if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
1407                 dprintk("%s: Tuned\n", __func__);
1408                 goto tuned;
1409             }
1410             msleep(10);
1411         }
1412 
1413         dprintk("%s: Not tuned\n", __func__);
1414 
1415         /* Toggle pilot bit when in auto-pilot */
1416         if (state->dcur.pilot == PILOT_AUTO)
1417             cmd.args[0x07] ^= CX24116_PILOT_ON;
1418     } while (--retune);
1419 
1420 tuned:  /* Set/Reset B/W */
1421     cmd.args[0x00] = CMD_BANDWIDTH;
1422     cmd.args[0x01] = 0x00;
1423     cmd.len = 0x02;
1424     return cx24116_cmd_execute(fe, &cmd);
1425 }
1426 
1427 static int cx24116_tune(struct dvb_frontend *fe, bool re_tune,
1428     unsigned int mode_flags, unsigned int *delay, enum fe_status *status)
1429 {
1430     /*
1431      * It is safe to discard "params" here, as the DVB core will sync
1432      * fe->dtv_property_cache with fepriv->parameters_in, where the
1433      * DVBv3 params are stored. The only practical usage for it indicate
1434      * that re-tuning is needed, e. g. (fepriv->state & FESTATE_RETUNE) is
1435      * true.
1436      */
1437 
1438     *delay = HZ / 5;
1439     if (re_tune) {
1440         int ret = cx24116_set_frontend(fe);
1441         if (ret)
1442             return ret;
1443     }
1444     return cx24116_read_status(fe, status);
1445 }
1446 
1447 static enum dvbfe_algo cx24116_get_algo(struct dvb_frontend *fe)
1448 {
1449     return DVBFE_ALGO_HW;
1450 }
1451 
1452 static const struct dvb_frontend_ops cx24116_ops = {
1453     .delsys = { SYS_DVBS, SYS_DVBS2 },
1454     .info = {
1455         .name = "Conexant CX24116/CX24118",
1456         .frequency_min_hz = 950 * MHz,
1457         .frequency_max_hz = 2150 * MHz,
1458         .frequency_stepsize_hz = 1011 * kHz,
1459         .frequency_tolerance_hz = 5 * MHz,
1460         .symbol_rate_min = 1000000,
1461         .symbol_rate_max = 45000000,
1462         .caps = FE_CAN_INVERSION_AUTO |
1463             FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1464             FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1465             FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1466             FE_CAN_2G_MODULATION |
1467             FE_CAN_QPSK | FE_CAN_RECOVER
1468     },
1469 
1470     .release = cx24116_release,
1471 
1472     .init = cx24116_initfe,
1473     .sleep = cx24116_sleep,
1474     .read_status = cx24116_read_status,
1475     .read_ber = cx24116_read_ber,
1476     .read_signal_strength = cx24116_read_signal_strength,
1477     .read_snr = cx24116_read_snr,
1478     .read_ucblocks = cx24116_read_ucblocks,
1479     .set_tone = cx24116_set_tone,
1480     .set_voltage = cx24116_set_voltage,
1481     .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
1482     .diseqc_send_burst = cx24116_diseqc_send_burst,
1483     .get_frontend_algo = cx24116_get_algo,
1484     .tune = cx24116_tune,
1485 
1486     .set_frontend = cx24116_set_frontend,
1487 };
1488 
1489 MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
1490 MODULE_AUTHOR("Steven Toth");
1491 MODULE_LICENSE("GPL");
1492