Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003     Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner driver
0004 
0005     Copyright (C) 2008 Patrick Boettcher <pb@linuxtv.org>
0006     Copyright (C) 2009 Sergey Tyurin <forum.free-x.de>
0007     Updated 2012 by Jannis Achstetter <jannis_achstetter@web.de>
0008     Copyright (C) 2015 Jemma Denson <jdenson@gmail.com>
0009     April 2015
0010         Refactored & simplified driver
0011         Updated to work with delivery system supplied by DVBv5
0012         Add frequency, fec & pilot to get_frontend
0013 
0014     Cards supported: Technisat Skystar S2
0015 
0016 */
0017 
0018 #include <linux/slab.h>
0019 #include <linux/kernel.h>
0020 #include <linux/module.h>
0021 #include <linux/moduleparam.h>
0022 #include <linux/init.h>
0023 #include <linux/firmware.h>
0024 #include <media/dvb_frontend.h>
0025 #include "cx24120.h"
0026 
0027 #define CX24120_SEARCH_RANGE_KHZ 5000
0028 #define CX24120_FIRMWARE "dvb-fe-cx24120-1.20.58.2.fw"
0029 
0030 /* cx24120 i2c registers  */
0031 #define CX24120_REG_CMD_START   0x00        /* write cmd_id */
0032 #define CX24120_REG_CMD_ARGS    0x01        /* write command arguments */
0033 #define CX24120_REG_CMD_END 0x1f        /* write 0x01 for end */
0034 
0035 #define CX24120_REG_MAILBOX 0x33
0036 #define CX24120_REG_FREQ3   0x34        /* frequency */
0037 #define CX24120_REG_FREQ2   0x35
0038 #define CX24120_REG_FREQ1   0x36
0039 
0040 #define CX24120_REG_FECMODE 0x39        /* FEC status */
0041 #define CX24120_REG_STATUS  0x3a        /* Tuner status */
0042 #define CX24120_REG_SIGSTR_H    0x3a        /* Signal strength high */
0043 #define CX24120_REG_SIGSTR_L    0x3b        /* Signal strength low byte */
0044 #define CX24120_REG_QUALITY_H   0x40        /* SNR high byte */
0045 #define CX24120_REG_QUALITY_L   0x41        /* SNR low byte */
0046 
0047 #define CX24120_REG_BER_HH  0x47        /* BER high byte of high word */
0048 #define CX24120_REG_BER_HL  0x48        /* BER low byte of high word */
0049 #define CX24120_REG_BER_LH  0x49        /* BER high byte of low word */
0050 #define CX24120_REG_BER_LL  0x4a        /* BER low byte of low word */
0051 
0052 #define CX24120_REG_UCB_H   0x50        /* UCB high byte */
0053 #define CX24120_REG_UCB_L   0x51        /* UCB low byte  */
0054 
0055 #define CX24120_REG_CLKDIV  0xe6
0056 #define CX24120_REG_RATEDIV 0xf0
0057 
0058 #define CX24120_REG_REVISION    0xff        /* Chip revision (ro) */
0059 
0060 /* Command messages */
0061 enum command_message_id {
0062     CMD_VCO_SET     = 0x10,     /* cmd.len = 12; */
0063     CMD_TUNEREQUEST     = 0x11,     /* cmd.len = 15; */
0064 
0065     CMD_MPEG_ONOFF      = 0x13,     /* cmd.len = 4; */
0066     CMD_MPEG_INIT       = 0x14,     /* cmd.len = 7; */
0067     CMD_BANDWIDTH       = 0x15,     /* cmd.len = 12; */
0068     CMD_CLOCK_READ      = 0x16,     /* read clock */
0069     CMD_CLOCK_SET       = 0x17,     /* cmd.len = 10; */
0070 
0071     CMD_DISEQC_MSG1     = 0x20,     /* cmd.len = 11; */
0072     CMD_DISEQC_MSG2     = 0x21,     /* cmd.len = d->msg_len + 6; */
0073     CMD_SETVOLTAGE      = 0x22,     /* cmd.len = 2; */
0074     CMD_SETTONE     = 0x23,     /* cmd.len = 4; */
0075     CMD_DISEQC_BURST    = 0x24,     /* cmd.len not used !!! */
0076 
0077     CMD_READ_SNR        = 0x1a,     /* Read signal strength */
0078     CMD_START_TUNER     = 0x1b,     /* ??? */
0079 
0080     CMD_FWVERSION       = 0x35,
0081 
0082     CMD_BER_CTRL        = 0x3c,     /* cmd.len = 0x03; */
0083 };
0084 
0085 #define CX24120_MAX_CMD_LEN 30
0086 
0087 /* pilot mask */
0088 #define CX24120_PILOT_OFF   0x00
0089 #define CX24120_PILOT_ON    0x40
0090 #define CX24120_PILOT_AUTO  0x80
0091 
0092 /* signal status */
0093 #define CX24120_HAS_SIGNAL  0x01
0094 #define CX24120_HAS_CARRIER 0x02
0095 #define CX24120_HAS_VITERBI 0x04
0096 #define CX24120_HAS_LOCK    0x08
0097 #define CX24120_HAS_UNK1    0x10
0098 #define CX24120_HAS_UNK2    0x20
0099 #define CX24120_STATUS_MASK 0x0f
0100 #define CX24120_SIGNAL_MASK 0xc0
0101 
0102 /* ber window */
0103 #define CX24120_BER_WINDOW  16
0104 #define CX24120_BER_WSIZE   ((1 << CX24120_BER_WINDOW) * 208 * 8)
0105 
0106 #define info(args...) pr_info("cx24120: " args)
0107 #define err(args...)  pr_err("cx24120: ### ERROR: " args)
0108 
0109 /* The Demod/Tuner can't easily provide these, we cache them */
0110 struct cx24120_tuning {
0111     u32 frequency;
0112     u32 symbol_rate;
0113     enum fe_spectral_inversion inversion;
0114     enum fe_code_rate fec;
0115 
0116     enum fe_delivery_system delsys;
0117     enum fe_modulation modulation;
0118     enum fe_pilot pilot;
0119 
0120     /* Demod values */
0121     u8 fec_val;
0122     u8 fec_mask;
0123     u8 clkdiv;
0124     u8 ratediv;
0125     u8 inversion_val;
0126     u8 pilot_val;
0127 };
0128 
0129 /* Private state */
0130 struct cx24120_state {
0131     struct i2c_adapter *i2c;
0132     const struct cx24120_config *config;
0133     struct dvb_frontend frontend;
0134 
0135     u8 cold_init;
0136     u8 mpeg_enabled;
0137     u8 need_clock_set;
0138 
0139     /* current and next tuning parameters */
0140     struct cx24120_tuning dcur;
0141     struct cx24120_tuning dnxt;
0142 
0143     enum fe_status fe_status;
0144 
0145     /* dvbv5 stats calculations */
0146     u32 bitrate;
0147     u32 berw_usecs;
0148     u32 ber_prev;
0149     u32 ucb_offset;
0150     unsigned long ber_jiffies_stats;
0151     unsigned long per_jiffies_stats;
0152 };
0153 
0154 /* Command message to firmware */
0155 struct cx24120_cmd {
0156     u8 id;
0157     u8 len;
0158     u8 arg[CX24120_MAX_CMD_LEN];
0159 };
0160 
0161 /* Read single register */
0162 static int cx24120_readreg(struct cx24120_state *state, u8 reg)
0163 {
0164     int ret;
0165     u8 buf = 0;
0166     struct i2c_msg msg[] = {
0167         {
0168             .addr = state->config->i2c_addr,
0169             .flags = 0,
0170             .len = 1,
0171             .buf = &reg
0172         }, {
0173             .addr = state->config->i2c_addr,
0174             .flags = I2C_M_RD,
0175             .len = 1,
0176             .buf = &buf
0177         }
0178     };
0179 
0180     ret = i2c_transfer(state->i2c, msg, 2);
0181     if (ret != 2) {
0182         err("Read error: reg=0x%02x, ret=%i)\n", reg, ret);
0183         return ret;
0184     }
0185 
0186     dev_dbg(&state->i2c->dev, "reg=0x%02x; data=0x%02x\n", reg, buf);
0187 
0188     return buf;
0189 }
0190 
0191 /* Write single register */
0192 static int cx24120_writereg(struct cx24120_state *state, u8 reg, u8 data)
0193 {
0194     u8 buf[] = { reg, data };
0195     struct i2c_msg msg = {
0196         .addr = state->config->i2c_addr,
0197         .flags = 0,
0198         .buf = buf,
0199         .len = 2
0200     };
0201     int ret;
0202 
0203     ret = i2c_transfer(state->i2c, &msg, 1);
0204     if (ret != 1) {
0205         err("Write error: i2c_write error(err == %i, 0x%02x: 0x%02x)\n",
0206             ret, reg, data);
0207         return ret;
0208     }
0209 
0210     dev_dbg(&state->i2c->dev, "reg=0x%02x; data=0x%02x\n", reg, data);
0211 
0212     return 0;
0213 }
0214 
0215 /* Write multiple registers in chunks of i2c_wr_max-sized buffers */
0216 static int cx24120_writeregs(struct cx24120_state *state,
0217                  u8 reg, const u8 *values, u16 len, u8 incr)
0218 {
0219     int ret;
0220     u16 max = state->config->i2c_wr_max > 0 ?
0221                 state->config->i2c_wr_max :
0222                 len;
0223 
0224     struct i2c_msg msg = {
0225         .addr = state->config->i2c_addr,
0226         .flags = 0,
0227     };
0228 
0229     msg.buf = kmalloc(max + 1, GFP_KERNEL);
0230     if (!msg.buf)
0231         return -ENOMEM;
0232 
0233     while (len) {
0234         msg.buf[0] = reg;
0235         msg.len = len > max ? max : len;
0236         memcpy(&msg.buf[1], values, msg.len);
0237 
0238         len    -= msg.len;      /* data length revers counter */
0239         values += msg.len;      /* incr data pointer */
0240 
0241         if (incr)
0242             reg += msg.len;
0243         msg.len++;              /* don't forget the addr byte */
0244 
0245         ret = i2c_transfer(state->i2c, &msg, 1);
0246         if (ret != 1) {
0247             err("i2c_write error(err == %i, 0x%02x)\n", ret, reg);
0248             goto out;
0249         }
0250 
0251         dev_dbg(&state->i2c->dev, "reg=0x%02x; data=%*ph\n",
0252             reg, msg.len - 1, msg.buf + 1);
0253     }
0254 
0255     ret = 0;
0256 
0257 out:
0258     kfree(msg.buf);
0259     return ret;
0260 }
0261 
0262 static const struct dvb_frontend_ops cx24120_ops;
0263 
0264 struct dvb_frontend *cx24120_attach(const struct cx24120_config *config,
0265                     struct i2c_adapter *i2c)
0266 {
0267     struct cx24120_state *state;
0268     int demod_rev;
0269 
0270     info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner\n");
0271     state = kzalloc(sizeof(*state), GFP_KERNEL);
0272     if (!state) {
0273         err("Unable to allocate memory for cx24120_state\n");
0274         goto error;
0275     }
0276 
0277     /* setup the state */
0278     state->config = config;
0279     state->i2c = i2c;
0280 
0281     /* check if the demod is present and has proper type */
0282     demod_rev = cx24120_readreg(state, CX24120_REG_REVISION);
0283     switch (demod_rev) {
0284     case 0x07:
0285         info("Demod cx24120 rev. 0x07 detected.\n");
0286         break;
0287     case 0x05:
0288         info("Demod cx24120 rev. 0x05 detected.\n");
0289         break;
0290     default:
0291         err("Unsupported demod revision: 0x%x detected.\n", demod_rev);
0292         goto error;
0293     }
0294 
0295     /* create dvb_frontend */
0296     state->cold_init = 0;
0297     memcpy(&state->frontend.ops, &cx24120_ops,
0298            sizeof(struct dvb_frontend_ops));
0299     state->frontend.demodulator_priv = state;
0300 
0301     info("Conexant cx24120/cx24118 attached.\n");
0302     return &state->frontend;
0303 
0304 error:
0305     kfree(state);
0306     return NULL;
0307 }
0308 EXPORT_SYMBOL(cx24120_attach);
0309 
0310 static int cx24120_test_rom(struct cx24120_state *state)
0311 {
0312     int err, ret;
0313 
0314     err = cx24120_readreg(state, 0xfd);
0315     if (err & 4) {
0316         ret = cx24120_readreg(state, 0xdf) & 0xfe;
0317         err = cx24120_writereg(state, 0xdf, ret);
0318     }
0319     return err;
0320 }
0321 
0322 static int cx24120_read_snr(struct dvb_frontend *fe, u16 *snr)
0323 {
0324     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0325 
0326     if (c->cnr.stat[0].scale != FE_SCALE_DECIBEL)
0327         *snr = 0;
0328     else
0329         *snr = div_s64(c->cnr.stat[0].svalue, 100);
0330 
0331     return 0;
0332 }
0333 
0334 static int cx24120_read_ber(struct dvb_frontend *fe, u32 *ber)
0335 {
0336     struct cx24120_state *state = fe->demodulator_priv;
0337     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0338 
0339     if (c->post_bit_error.stat[0].scale != FE_SCALE_COUNTER) {
0340         *ber = 0;
0341         return 0;
0342     }
0343 
0344     *ber = c->post_bit_error.stat[0].uvalue - state->ber_prev;
0345     state->ber_prev = c->post_bit_error.stat[0].uvalue;
0346 
0347     return 0;
0348 }
0349 
0350 static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state,
0351                          u8 flag);
0352 
0353 /* Check if we're running a command that needs to disable mpeg out */
0354 static void cx24120_check_cmd(struct cx24120_state *state, u8 id)
0355 {
0356     switch (id) {
0357     case CMD_TUNEREQUEST:
0358     case CMD_CLOCK_READ:
0359     case CMD_DISEQC_MSG1:
0360     case CMD_DISEQC_MSG2:
0361     case CMD_SETVOLTAGE:
0362     case CMD_SETTONE:
0363     case CMD_DISEQC_BURST:
0364         cx24120_msg_mpeg_output_global_config(state, 0);
0365         /* Old driver would do a msleep(100) here */
0366         return;
0367     default:
0368         return;
0369     }
0370 }
0371 
0372 /* Send a message to the firmware */
0373 static int cx24120_message_send(struct cx24120_state *state,
0374                 struct cx24120_cmd *cmd)
0375 {
0376     int ficus;
0377 
0378     if (state->mpeg_enabled) {
0379         /* Disable mpeg out on certain commands */
0380         cx24120_check_cmd(state, cmd->id);
0381     }
0382 
0383     cx24120_writereg(state, CX24120_REG_CMD_START, cmd->id);
0384     cx24120_writeregs(state, CX24120_REG_CMD_ARGS, &cmd->arg[0],
0385               cmd->len, 1);
0386     cx24120_writereg(state, CX24120_REG_CMD_END, 0x01);
0387 
0388     ficus = 1000;
0389     while (cx24120_readreg(state, CX24120_REG_CMD_END)) {
0390         msleep(20);
0391         ficus -= 20;
0392         if (ficus == 0) {
0393             err("Error sending message to firmware\n");
0394             return -EREMOTEIO;
0395         }
0396     }
0397     dev_dbg(&state->i2c->dev, "sent message 0x%02x\n", cmd->id);
0398 
0399     return 0;
0400 }
0401 
0402 /* Send a message and fill arg[] with the results */
0403 static int cx24120_message_sendrcv(struct cx24120_state *state,
0404                    struct cx24120_cmd *cmd, u8 numreg)
0405 {
0406     int ret, i;
0407 
0408     if (numreg > CX24120_MAX_CMD_LEN) {
0409         err("Too many registers to read. cmd->reg = %d", numreg);
0410         return -EREMOTEIO;
0411     }
0412 
0413     ret = cx24120_message_send(state, cmd);
0414     if (ret != 0)
0415         return ret;
0416 
0417     if (!numreg)
0418         return 0;
0419 
0420     /* Read numreg registers starting from register cmd->len */
0421     for (i = 0; i < numreg; i++)
0422         cmd->arg[i] = cx24120_readreg(state, (cmd->len + i + 1));
0423 
0424     return 0;
0425 }
0426 
0427 static int cx24120_read_signal_strength(struct dvb_frontend *fe,
0428                     u16 *signal_strength)
0429 {
0430     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0431 
0432     if (c->strength.stat[0].scale != FE_SCALE_RELATIVE)
0433         *signal_strength = 0;
0434     else
0435         *signal_strength = c->strength.stat[0].uvalue;
0436 
0437     return 0;
0438 }
0439 
0440 static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state,
0441                          u8 enable)
0442 {
0443     struct cx24120_cmd cmd;
0444     int ret;
0445 
0446     cmd.id = CMD_MPEG_ONOFF;
0447     cmd.len = 4;
0448     cmd.arg[0] = 0x01;
0449     cmd.arg[1] = 0x00;
0450     cmd.arg[2] = enable ? 0 : (u8)(-1);
0451     cmd.arg[3] = 0x01;
0452 
0453     ret = cx24120_message_send(state, &cmd);
0454     if (ret != 0) {
0455         dev_dbg(&state->i2c->dev, "failed to %s MPEG output\n",
0456             enable ? "enable" : "disable");
0457         return ret;
0458     }
0459 
0460     state->mpeg_enabled = enable;
0461     dev_dbg(&state->i2c->dev, "MPEG output %s\n",
0462         enable ? "enabled" : "disabled");
0463 
0464     return 0;
0465 }
0466 
0467 static int cx24120_msg_mpeg_output_config(struct cx24120_state *state, u8 seq)
0468 {
0469     struct cx24120_cmd cmd;
0470     struct cx24120_initial_mpeg_config i =
0471             state->config->initial_mpeg_config;
0472 
0473     cmd.id = CMD_MPEG_INIT;
0474     cmd.len = 7;
0475     cmd.arg[0] = seq; /* sequental number - can be 0,1,2 */
0476     cmd.arg[1] = ((i.x1 & 0x01) << 1) | ((i.x1 >> 1) & 0x01);
0477     cmd.arg[2] = 0x05;
0478     cmd.arg[3] = 0x02;
0479     cmd.arg[4] = ((i.x2 >> 1) & 0x01);
0480     cmd.arg[5] = (i.x2 & 0xf0) | (i.x3 & 0x0f);
0481     cmd.arg[6] = 0x10;
0482 
0483     return cx24120_message_send(state, &cmd);
0484 }
0485 
0486 static int cx24120_diseqc_send_burst(struct dvb_frontend *fe,
0487                      enum fe_sec_mini_cmd burst)
0488 {
0489     struct cx24120_state *state = fe->demodulator_priv;
0490     struct cx24120_cmd cmd;
0491 
0492     dev_dbg(&state->i2c->dev, "\n");
0493 
0494     /*
0495      * Yes, cmd.len is set to zero. The old driver
0496      * didn't specify any len, but also had a
0497      * memset 0 before every use of the cmd struct
0498      * which would have set it to zero.
0499      * This quite probably needs looking into.
0500      */
0501     cmd.id = CMD_DISEQC_BURST;
0502     cmd.len = 0;
0503     cmd.arg[0] = 0x00;
0504     cmd.arg[1] = (burst == SEC_MINI_B) ? 0x01 : 0x00;
0505 
0506     return cx24120_message_send(state, &cmd);
0507 }
0508 
0509 static int cx24120_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
0510 {
0511     struct cx24120_state *state = fe->demodulator_priv;
0512     struct cx24120_cmd cmd;
0513 
0514     dev_dbg(&state->i2c->dev, "(%d)\n", tone);
0515 
0516     if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
0517         err("Invalid tone=%d\n", tone);
0518         return -EINVAL;
0519     }
0520 
0521     cmd.id = CMD_SETTONE;
0522     cmd.len = 4;
0523     cmd.arg[0] = 0x00;
0524     cmd.arg[1] = 0x00;
0525     cmd.arg[2] = 0x00;
0526     cmd.arg[3] = (tone == SEC_TONE_ON) ? 0x01 : 0x00;
0527 
0528     return cx24120_message_send(state, &cmd);
0529 }
0530 
0531 static int cx24120_set_voltage(struct dvb_frontend *fe,
0532                    enum fe_sec_voltage voltage)
0533 {
0534     struct cx24120_state *state = fe->demodulator_priv;
0535     struct cx24120_cmd cmd;
0536 
0537     dev_dbg(&state->i2c->dev, "(%d)\n", voltage);
0538 
0539     cmd.id = CMD_SETVOLTAGE;
0540     cmd.len = 2;
0541     cmd.arg[0] = 0x00;
0542     cmd.arg[1] = (voltage == SEC_VOLTAGE_18) ? 0x01 : 0x00;
0543 
0544     return cx24120_message_send(state, &cmd);
0545 }
0546 
0547 static int cx24120_send_diseqc_msg(struct dvb_frontend *fe,
0548                    struct dvb_diseqc_master_cmd *d)
0549 {
0550     struct cx24120_state *state = fe->demodulator_priv;
0551     struct cx24120_cmd cmd;
0552     int back_count;
0553 
0554     dev_dbg(&state->i2c->dev, "\n");
0555 
0556     cmd.id = CMD_DISEQC_MSG1;
0557     cmd.len = 11;
0558     cmd.arg[0] = 0x00;
0559     cmd.arg[1] = 0x00;
0560     cmd.arg[2] = 0x03;
0561     cmd.arg[3] = 0x16;
0562     cmd.arg[4] = 0x28;
0563     cmd.arg[5] = 0x01;
0564     cmd.arg[6] = 0x01;
0565     cmd.arg[7] = 0x14;
0566     cmd.arg[8] = 0x19;
0567     cmd.arg[9] = 0x14;
0568     cmd.arg[10] = 0x1e;
0569 
0570     if (cx24120_message_send(state, &cmd)) {
0571         err("send 1st message(0x%x) failed\n", cmd.id);
0572         return -EREMOTEIO;
0573     }
0574 
0575     cmd.id = CMD_DISEQC_MSG2;
0576     cmd.len = d->msg_len + 6;
0577     cmd.arg[0] = 0x00;
0578     cmd.arg[1] = 0x01;
0579     cmd.arg[2] = 0x02;
0580     cmd.arg[3] = 0x00;
0581     cmd.arg[4] = 0x00;
0582     cmd.arg[5] = d->msg_len;
0583 
0584     memcpy(&cmd.arg[6], &d->msg, d->msg_len);
0585 
0586     if (cx24120_message_send(state, &cmd)) {
0587         err("send 2nd message(0x%x) failed\n", cmd.id);
0588         return -EREMOTEIO;
0589     }
0590 
0591     back_count = 500;
0592     do {
0593         if (!(cx24120_readreg(state, 0x93) & 0x01)) {
0594             dev_dbg(&state->i2c->dev, "diseqc sequence sent\n");
0595             return 0;
0596         }
0597         msleep(20);
0598         back_count -= 20;
0599     } while (back_count);
0600 
0601     err("Too long waiting for diseqc.\n");
0602     return -ETIMEDOUT;
0603 }
0604 
0605 static void cx24120_get_stats(struct cx24120_state *state)
0606 {
0607     struct dvb_frontend *fe = &state->frontend;
0608     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0609     struct cx24120_cmd cmd;
0610     int ret, cnr, msecs;
0611     u16 sig, ucb;
0612     u32 ber;
0613 
0614     dev_dbg(&state->i2c->dev, "\n");
0615 
0616     /* signal strength */
0617     if (state->fe_status & FE_HAS_SIGNAL) {
0618         cmd.id = CMD_READ_SNR;
0619         cmd.len = 1;
0620         cmd.arg[0] = 0x00;
0621 
0622         ret = cx24120_message_send(state, &cmd);
0623         if (ret != 0) {
0624             err("error reading signal strength\n");
0625             return;
0626         }
0627 
0628         /* raw */
0629         sig = cx24120_readreg(state, CX24120_REG_SIGSTR_H) >> 6;
0630         sig = sig << 8;
0631         sig |= cx24120_readreg(state, CX24120_REG_SIGSTR_L);
0632         dev_dbg(&state->i2c->dev,
0633             "signal strength from firmware = 0x%x\n", sig);
0634 
0635         /* cooked */
0636         sig = -100 * sig + 94324;
0637 
0638         c->strength.stat[0].scale = FE_SCALE_RELATIVE;
0639         c->strength.stat[0].uvalue = sig;
0640     } else {
0641         c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0642     }
0643 
0644     /* CNR */
0645     if (state->fe_status & FE_HAS_VITERBI) {
0646         cnr = cx24120_readreg(state, CX24120_REG_QUALITY_H) << 8;
0647         cnr |= cx24120_readreg(state, CX24120_REG_QUALITY_L);
0648         dev_dbg(&state->i2c->dev, "read SNR index = %d\n", cnr);
0649 
0650         /* guessed - seems about right */
0651         cnr = cnr * 100;
0652 
0653         c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
0654         c->cnr.stat[0].svalue = cnr;
0655     } else {
0656         c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0657     }
0658 
0659     /* BER & UCB require lock */
0660     if (!(state->fe_status & FE_HAS_LOCK)) {
0661         c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0662         c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0663         c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0664         c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0665         return;
0666     }
0667 
0668     /* BER */
0669     if (time_after(jiffies, state->ber_jiffies_stats)) {
0670         msecs = (state->berw_usecs + 500) / 1000;
0671         state->ber_jiffies_stats = jiffies + msecs_to_jiffies(msecs);
0672 
0673         ber = cx24120_readreg(state, CX24120_REG_BER_HH) << 24;
0674         ber |= cx24120_readreg(state, CX24120_REG_BER_HL) << 16;
0675         ber |= cx24120_readreg(state, CX24120_REG_BER_LH) << 8;
0676         ber |= cx24120_readreg(state, CX24120_REG_BER_LL);
0677         dev_dbg(&state->i2c->dev, "read BER index = %d\n", ber);
0678 
0679         c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
0680         c->post_bit_error.stat[0].uvalue += ber;
0681 
0682         c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
0683         c->post_bit_count.stat[0].uvalue += CX24120_BER_WSIZE;
0684     }
0685 
0686     /* UCB */
0687     if (time_after(jiffies, state->per_jiffies_stats)) {
0688         state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
0689 
0690         ucb = cx24120_readreg(state, CX24120_REG_UCB_H) << 8;
0691         ucb |= cx24120_readreg(state, CX24120_REG_UCB_L);
0692         dev_dbg(&state->i2c->dev, "ucblocks = %d\n", ucb);
0693 
0694         /* handle reset */
0695         if (ucb < state->ucb_offset)
0696             state->ucb_offset = c->block_error.stat[0].uvalue;
0697 
0698         c->block_error.stat[0].scale = FE_SCALE_COUNTER;
0699         c->block_error.stat[0].uvalue = ucb + state->ucb_offset;
0700 
0701         c->block_count.stat[0].scale = FE_SCALE_COUNTER;
0702         c->block_count.stat[0].uvalue += state->bitrate / 8 / 208;
0703     }
0704 }
0705 
0706 static void cx24120_set_clock_ratios(struct dvb_frontend *fe);
0707 
0708 /* Read current tuning status */
0709 static int cx24120_read_status(struct dvb_frontend *fe, enum fe_status *status)
0710 {
0711     struct cx24120_state *state = fe->demodulator_priv;
0712     int lock;
0713 
0714     lock = cx24120_readreg(state, CX24120_REG_STATUS);
0715 
0716     dev_dbg(&state->i2c->dev, "status = 0x%02x\n", lock);
0717 
0718     *status = 0;
0719 
0720     if (lock & CX24120_HAS_SIGNAL)
0721         *status = FE_HAS_SIGNAL;
0722     if (lock & CX24120_HAS_CARRIER)
0723         *status |= FE_HAS_CARRIER;
0724     if (lock & CX24120_HAS_VITERBI)
0725         *status |= FE_HAS_VITERBI | FE_HAS_SYNC;
0726     if (lock & CX24120_HAS_LOCK)
0727         *status |= FE_HAS_LOCK;
0728 
0729     /*
0730      * TODO: is FE_HAS_SYNC in the right place?
0731      * Other cx241xx drivers have this slightly
0732      * different
0733      */
0734 
0735     state->fe_status = *status;
0736     cx24120_get_stats(state);
0737 
0738     /* Set the clock once tuned in */
0739     if (state->need_clock_set && *status & FE_HAS_LOCK) {
0740         /* Set clock ratios */
0741         cx24120_set_clock_ratios(fe);
0742 
0743         /* Old driver would do a msleep(200) here */
0744 
0745         /* Renable mpeg output */
0746         if (!state->mpeg_enabled)
0747             cx24120_msg_mpeg_output_global_config(state, 1);
0748 
0749         state->need_clock_set = 0;
0750     }
0751 
0752     return 0;
0753 }
0754 
0755 /*
0756  * FEC & modulation lookup table
0757  * Used for decoding the REG_FECMODE register
0758  * once tuned in.
0759  */
0760 struct cx24120_modfec {
0761     enum fe_delivery_system delsys;
0762     enum fe_modulation mod;
0763     enum fe_code_rate fec;
0764     u8 val;
0765 };
0766 
0767 static const struct cx24120_modfec modfec_lookup_table[] = {
0768     /*delsys     mod    fec       val */
0769     { SYS_DVBS,  QPSK,  FEC_1_2,  0x01 },
0770     { SYS_DVBS,  QPSK,  FEC_2_3,  0x02 },
0771     { SYS_DVBS,  QPSK,  FEC_3_4,  0x03 },
0772     { SYS_DVBS,  QPSK,  FEC_4_5,  0x04 },
0773     { SYS_DVBS,  QPSK,  FEC_5_6,  0x05 },
0774     { SYS_DVBS,  QPSK,  FEC_6_7,  0x06 },
0775     { SYS_DVBS,  QPSK,  FEC_7_8,  0x07 },
0776 
0777     { SYS_DVBS2, QPSK,  FEC_1_2,  0x04 },
0778     { SYS_DVBS2, QPSK,  FEC_3_5,  0x05 },
0779     { SYS_DVBS2, QPSK,  FEC_2_3,  0x06 },
0780     { SYS_DVBS2, QPSK,  FEC_3_4,  0x07 },
0781     { SYS_DVBS2, QPSK,  FEC_4_5,  0x08 },
0782     { SYS_DVBS2, QPSK,  FEC_5_6,  0x09 },
0783     { SYS_DVBS2, QPSK,  FEC_8_9,  0x0a },
0784     { SYS_DVBS2, QPSK,  FEC_9_10, 0x0b },
0785 
0786     { SYS_DVBS2, PSK_8, FEC_3_5,  0x0c },
0787     { SYS_DVBS2, PSK_8, FEC_2_3,  0x0d },
0788     { SYS_DVBS2, PSK_8, FEC_3_4,  0x0e },
0789     { SYS_DVBS2, PSK_8, FEC_5_6,  0x0f },
0790     { SYS_DVBS2, PSK_8, FEC_8_9,  0x10 },
0791     { SYS_DVBS2, PSK_8, FEC_9_10, 0x11 },
0792 };
0793 
0794 /* Retrieve current fec, modulation & pilot values */
0795 static int cx24120_get_fec(struct dvb_frontend *fe)
0796 {
0797     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0798     struct cx24120_state *state = fe->demodulator_priv;
0799     int idx;
0800     int ret;
0801     int fec;
0802 
0803     ret = cx24120_readreg(state, CX24120_REG_FECMODE);
0804     fec = ret & 0x3f; /* Lower 6 bits */
0805 
0806     dev_dbg(&state->i2c->dev, "raw fec = %d\n", fec);
0807 
0808     for (idx = 0; idx < ARRAY_SIZE(modfec_lookup_table); idx++) {
0809         if (modfec_lookup_table[idx].delsys != state->dcur.delsys)
0810             continue;
0811         if (modfec_lookup_table[idx].val != fec)
0812             continue;
0813 
0814         break; /* found */
0815     }
0816 
0817     if (idx >= ARRAY_SIZE(modfec_lookup_table)) {
0818         dev_dbg(&state->i2c->dev, "couldn't find fec!\n");
0819         return -EINVAL;
0820     }
0821 
0822     /* save values back to cache */
0823     c->modulation = modfec_lookup_table[idx].mod;
0824     c->fec_inner = modfec_lookup_table[idx].fec;
0825     c->pilot = (ret & 0x80) ? PILOT_ON : PILOT_OFF;
0826 
0827     dev_dbg(&state->i2c->dev, "mod(%d), fec(%d), pilot(%d)\n",
0828         c->modulation, c->fec_inner, c->pilot);
0829 
0830     return 0;
0831 }
0832 
0833 /* Calculate ber window time */
0834 static void cx24120_calculate_ber_window(struct cx24120_state *state, u32 rate)
0835 {
0836     struct dvb_frontend *fe = &state->frontend;
0837     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0838     u64 tmp;
0839 
0840     /*
0841      * Calculate bitrate from rate in the clock ratios table.
0842      * This isn't *exactly* right but close enough.
0843      */
0844     tmp = (u64)c->symbol_rate * rate;
0845     do_div(tmp, 256);
0846     state->bitrate = tmp;
0847 
0848     /* usecs per ber window */
0849     tmp = 1000000ULL * CX24120_BER_WSIZE;
0850     do_div(tmp, state->bitrate);
0851     state->berw_usecs = tmp;
0852 
0853     dev_dbg(&state->i2c->dev, "bitrate: %u, berw_usecs: %u\n",
0854         state->bitrate, state->berw_usecs);
0855 }
0856 
0857 /*
0858  * Clock ratios lookup table
0859  *
0860  * Values obtained from much larger table in old driver
0861  * which had numerous entries which would never match.
0862  *
0863  * There's probably some way of calculating these but I
0864  * can't determine the pattern
0865  */
0866 struct cx24120_clock_ratios_table {
0867     enum fe_delivery_system delsys;
0868     enum fe_pilot pilot;
0869     enum fe_modulation mod;
0870     enum fe_code_rate fec;
0871     u32 m_rat;
0872     u32 n_rat;
0873     u32 rate;
0874 };
0875 
0876 static const struct cx24120_clock_ratios_table clock_ratios_table[] = {
0877     /*delsys     pilot      mod    fec       m_rat    n_rat   rate */
0878     { SYS_DVBS2, PILOT_OFF, QPSK,  FEC_1_2,  273088,  254505, 274 },
0879     { SYS_DVBS2, PILOT_OFF, QPSK,  FEC_3_5,  17272,   13395,  330 },
0880     { SYS_DVBS2, PILOT_OFF, QPSK,  FEC_2_3,  24344,   16967,  367 },
0881     { SYS_DVBS2, PILOT_OFF, QPSK,  FEC_3_4,  410788,  254505, 413 },
0882     { SYS_DVBS2, PILOT_OFF, QPSK,  FEC_4_5,  438328,  254505, 440 },
0883     { SYS_DVBS2, PILOT_OFF, QPSK,  FEC_5_6,  30464,   16967,  459 },
0884     { SYS_DVBS2, PILOT_OFF, QPSK,  FEC_8_9,  487832,  254505, 490 },
0885     { SYS_DVBS2, PILOT_OFF, QPSK,  FEC_9_10, 493952,  254505, 496 },
0886     { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_5,  328168,  169905, 494 },
0887     { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_2_3,  24344,   11327,  550 },
0888     { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_3_4,  410788,  169905, 618 },
0889     { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_5_6,  30464,   11327,  688 },
0890     { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_8_9,  487832,  169905, 735 },
0891     { SYS_DVBS2, PILOT_OFF, PSK_8, FEC_9_10, 493952,  169905, 744 },
0892     { SYS_DVBS2, PILOT_ON,  QPSK,  FEC_1_2,  273088,  260709, 268 },
0893     { SYS_DVBS2, PILOT_ON,  QPSK,  FEC_3_5,  328168,  260709, 322 },
0894     { SYS_DVBS2, PILOT_ON,  QPSK,  FEC_2_3,  121720,  86903,  358 },
0895     { SYS_DVBS2, PILOT_ON,  QPSK,  FEC_3_4,  410788,  260709, 403 },
0896     { SYS_DVBS2, PILOT_ON,  QPSK,  FEC_4_5,  438328,  260709, 430 },
0897     { SYS_DVBS2, PILOT_ON,  QPSK,  FEC_5_6,  152320,  86903,  448 },
0898     { SYS_DVBS2, PILOT_ON,  QPSK,  FEC_8_9,  487832,  260709, 479 },
0899     { SYS_DVBS2, PILOT_ON,  QPSK,  FEC_9_10, 493952,  260709, 485 },
0900     { SYS_DVBS2, PILOT_ON,  PSK_8, FEC_3_5,  328168,  173853, 483 },
0901     { SYS_DVBS2, PILOT_ON,  PSK_8, FEC_2_3,  121720,  57951,  537 },
0902     { SYS_DVBS2, PILOT_ON,  PSK_8, FEC_3_4,  410788,  173853, 604 },
0903     { SYS_DVBS2, PILOT_ON,  PSK_8, FEC_5_6,  152320,  57951,  672 },
0904     { SYS_DVBS2, PILOT_ON,  PSK_8, FEC_8_9,  487832,  173853, 718 },
0905     { SYS_DVBS2, PILOT_ON,  PSK_8, FEC_9_10, 493952,  173853, 727 },
0906     { SYS_DVBS,  PILOT_OFF, QPSK,  FEC_1_2,  152592,  152592, 256 },
0907     { SYS_DVBS,  PILOT_OFF, QPSK,  FEC_2_3,  305184,  228888, 341 },
0908     { SYS_DVBS,  PILOT_OFF, QPSK,  FEC_3_4,  457776,  305184, 384 },
0909     { SYS_DVBS,  PILOT_OFF, QPSK,  FEC_5_6,  762960,  457776, 427 },
0910     { SYS_DVBS,  PILOT_OFF, QPSK,  FEC_7_8,  1068144, 610368, 448 },
0911 };
0912 
0913 /* Set clock ratio from lookup table */
0914 static void cx24120_set_clock_ratios(struct dvb_frontend *fe)
0915 {
0916     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0917     struct cx24120_state *state = fe->demodulator_priv;
0918     struct cx24120_cmd cmd;
0919     int ret, idx;
0920 
0921     /* Find fec, modulation, pilot */
0922     ret = cx24120_get_fec(fe);
0923     if (ret != 0)
0924         return;
0925 
0926     /* Find the clock ratios in the lookup table */
0927     for (idx = 0; idx < ARRAY_SIZE(clock_ratios_table); idx++) {
0928         if (clock_ratios_table[idx].delsys != state->dcur.delsys)
0929             continue;
0930         if (clock_ratios_table[idx].mod != c->modulation)
0931             continue;
0932         if (clock_ratios_table[idx].fec != c->fec_inner)
0933             continue;
0934         if (clock_ratios_table[idx].pilot != c->pilot)
0935             continue;
0936 
0937         break;      /* found */
0938     }
0939 
0940     if (idx >= ARRAY_SIZE(clock_ratios_table)) {
0941         info("Clock ratio not found - data reception in danger\n");
0942         return;
0943     }
0944 
0945     /* Read current values? */
0946     cmd.id = CMD_CLOCK_READ;
0947     cmd.len = 1;
0948     cmd.arg[0] = 0x00;
0949     ret = cx24120_message_sendrcv(state, &cmd, 6);
0950     if (ret != 0)
0951         return;
0952     /* in cmd[0]-[5] - result */
0953 
0954     dev_dbg(&state->i2c->dev, "m=%d, n=%d; idx: %d m=%d, n=%d, rate=%d\n",
0955         cmd.arg[2] | (cmd.arg[1] << 8) | (cmd.arg[0] << 16),
0956         cmd.arg[5] | (cmd.arg[4] << 8) | (cmd.arg[3] << 16),
0957         idx,
0958         clock_ratios_table[idx].m_rat,
0959         clock_ratios_table[idx].n_rat,
0960         clock_ratios_table[idx].rate);
0961 
0962     /* Set the clock */
0963     cmd.id = CMD_CLOCK_SET;
0964     cmd.len = 10;
0965     cmd.arg[0] = 0;
0966     cmd.arg[1] = 0x10;
0967     cmd.arg[2] = (clock_ratios_table[idx].m_rat >> 16) & 0xff;
0968     cmd.arg[3] = (clock_ratios_table[idx].m_rat >>  8) & 0xff;
0969     cmd.arg[4] = (clock_ratios_table[idx].m_rat >>  0) & 0xff;
0970     cmd.arg[5] = (clock_ratios_table[idx].n_rat >> 16) & 0xff;
0971     cmd.arg[6] = (clock_ratios_table[idx].n_rat >>  8) & 0xff;
0972     cmd.arg[7] = (clock_ratios_table[idx].n_rat >>  0) & 0xff;
0973     cmd.arg[8] = (clock_ratios_table[idx].rate >> 8) & 0xff;
0974     cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff;
0975 
0976     cx24120_message_send(state, &cmd);
0977 
0978     /* Calculate ber window rates for stat work */
0979     cx24120_calculate_ber_window(state, clock_ratios_table[idx].rate);
0980 }
0981 
0982 /* Set inversion value */
0983 static int cx24120_set_inversion(struct cx24120_state *state,
0984                  enum fe_spectral_inversion inversion)
0985 {
0986     dev_dbg(&state->i2c->dev, "(%d)\n", inversion);
0987 
0988     switch (inversion) {
0989     case INVERSION_OFF:
0990         state->dnxt.inversion_val = 0x00;
0991         break;
0992     case INVERSION_ON:
0993         state->dnxt.inversion_val = 0x04;
0994         break;
0995     case INVERSION_AUTO:
0996         state->dnxt.inversion_val = 0x0c;
0997         break;
0998     default:
0999         return -EINVAL;
1000     }
1001 
1002     state->dnxt.inversion = inversion;
1003 
1004     return 0;
1005 }
1006 
1007 /* FEC lookup table for tuning */
1008 struct cx24120_modfec_table {
1009     enum fe_delivery_system delsys;
1010     enum fe_modulation mod;
1011     enum fe_code_rate fec;
1012     u8 val;
1013 };
1014 
1015 static const struct cx24120_modfec_table modfec_table[] = {
1016     /*delsys     mod    fec       val */
1017     { SYS_DVBS,  QPSK,  FEC_1_2,  0x2e },
1018     { SYS_DVBS,  QPSK,  FEC_2_3,  0x2f },
1019     { SYS_DVBS,  QPSK,  FEC_3_4,  0x30 },
1020     { SYS_DVBS,  QPSK,  FEC_5_6,  0x31 },
1021     { SYS_DVBS,  QPSK,  FEC_6_7,  0x32 },
1022     { SYS_DVBS,  QPSK,  FEC_7_8,  0x33 },
1023 
1024     { SYS_DVBS2, QPSK,  FEC_1_2,  0x04 },
1025     { SYS_DVBS2, QPSK,  FEC_3_5,  0x05 },
1026     { SYS_DVBS2, QPSK,  FEC_2_3,  0x06 },
1027     { SYS_DVBS2, QPSK,  FEC_3_4,  0x07 },
1028     { SYS_DVBS2, QPSK,  FEC_4_5,  0x08 },
1029     { SYS_DVBS2, QPSK,  FEC_5_6,  0x09 },
1030     { SYS_DVBS2, QPSK,  FEC_8_9,  0x0a },
1031     { SYS_DVBS2, QPSK,  FEC_9_10, 0x0b },
1032 
1033     { SYS_DVBS2, PSK_8, FEC_3_5,  0x0c },
1034     { SYS_DVBS2, PSK_8, FEC_2_3,  0x0d },
1035     { SYS_DVBS2, PSK_8, FEC_3_4,  0x0e },
1036     { SYS_DVBS2, PSK_8, FEC_5_6,  0x0f },
1037     { SYS_DVBS2, PSK_8, FEC_8_9,  0x10 },
1038     { SYS_DVBS2, PSK_8, FEC_9_10, 0x11 },
1039 };
1040 
1041 /* Set fec_val & fec_mask values from delsys, modulation & fec */
1042 static int cx24120_set_fec(struct cx24120_state *state, enum fe_modulation mod,
1043                enum fe_code_rate fec)
1044 {
1045     int idx;
1046 
1047     dev_dbg(&state->i2c->dev, "(0x%02x,0x%02x)\n", mod, fec);
1048 
1049     state->dnxt.fec = fec;
1050 
1051     /* Lookup fec_val from modfec table */
1052     for (idx = 0; idx < ARRAY_SIZE(modfec_table); idx++) {
1053         if (modfec_table[idx].delsys != state->dnxt.delsys)
1054             continue;
1055         if (modfec_table[idx].mod != mod)
1056             continue;
1057         if (modfec_table[idx].fec != fec)
1058             continue;
1059 
1060         /* found */
1061         state->dnxt.fec_mask = 0x00;
1062         state->dnxt.fec_val = modfec_table[idx].val;
1063         return 0;
1064     }
1065 
1066     if (state->dnxt.delsys == SYS_DVBS2) {
1067         /* DVBS2 auto is 0x00/0x00 */
1068         state->dnxt.fec_mask = 0x00;
1069         state->dnxt.fec_val  = 0x00;
1070     } else {
1071         /* Set DVB-S to auto */
1072         state->dnxt.fec_val  = 0x2e;
1073         state->dnxt.fec_mask = 0xac;
1074     }
1075 
1076     return 0;
1077 }
1078 
1079 /* Set pilot */
1080 static int cx24120_set_pilot(struct cx24120_state *state, enum fe_pilot pilot)
1081 {
1082     dev_dbg(&state->i2c->dev, "(%d)\n", pilot);
1083 
1084     /* Pilot only valid in DVBS2 */
1085     if (state->dnxt.delsys != SYS_DVBS2) {
1086         state->dnxt.pilot_val = CX24120_PILOT_OFF;
1087         return 0;
1088     }
1089 
1090     switch (pilot) {
1091     case PILOT_OFF:
1092         state->dnxt.pilot_val = CX24120_PILOT_OFF;
1093         break;
1094     case PILOT_ON:
1095         state->dnxt.pilot_val = CX24120_PILOT_ON;
1096         break;
1097     case PILOT_AUTO:
1098     default:
1099         state->dnxt.pilot_val = CX24120_PILOT_AUTO;
1100     }
1101 
1102     return 0;
1103 }
1104 
1105 /* Set symbol rate */
1106 static int cx24120_set_symbolrate(struct cx24120_state *state, u32 rate)
1107 {
1108     dev_dbg(&state->i2c->dev, "(%d)\n", rate);
1109 
1110     state->dnxt.symbol_rate = rate;
1111 
1112     /* Check symbol rate */
1113     if (rate  > 31000000) {
1114         state->dnxt.clkdiv  = (-(rate < 31000001) & 3) + 2;
1115         state->dnxt.ratediv = (-(rate < 31000001) & 6) + 4;
1116     } else {
1117         state->dnxt.clkdiv  = 3;
1118         state->dnxt.ratediv = 6;
1119     }
1120 
1121     return 0;
1122 }
1123 
1124 /* Overwrite the current tuning params, we are about to tune */
1125 static void cx24120_clone_params(struct dvb_frontend *fe)
1126 {
1127     struct cx24120_state *state = fe->demodulator_priv;
1128 
1129     state->dcur = state->dnxt;
1130 }
1131 
1132 static int cx24120_set_frontend(struct dvb_frontend *fe)
1133 {
1134     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1135     struct cx24120_state *state = fe->demodulator_priv;
1136     struct cx24120_cmd cmd;
1137     int ret;
1138 
1139     switch (c->delivery_system) {
1140     case SYS_DVBS2:
1141         dev_dbg(&state->i2c->dev, "DVB-S2\n");
1142         break;
1143     case SYS_DVBS:
1144         dev_dbg(&state->i2c->dev, "DVB-S\n");
1145         break;
1146     default:
1147         dev_dbg(&state->i2c->dev,
1148             "delivery system(%d) not supported\n",
1149             c->delivery_system);
1150         return -EINVAL;
1151     }
1152 
1153     state->dnxt.delsys = c->delivery_system;
1154     state->dnxt.modulation = c->modulation;
1155     state->dnxt.frequency = c->frequency;
1156     state->dnxt.pilot = c->pilot;
1157 
1158     ret = cx24120_set_inversion(state, c->inversion);
1159     if (ret !=  0)
1160         return ret;
1161 
1162     ret = cx24120_set_fec(state, c->modulation, c->fec_inner);
1163     if (ret !=  0)
1164         return ret;
1165 
1166     ret = cx24120_set_pilot(state, c->pilot);
1167     if (ret != 0)
1168         return ret;
1169 
1170     ret = cx24120_set_symbolrate(state, c->symbol_rate);
1171     if (ret !=  0)
1172         return ret;
1173 
1174     /* discard the 'current' tuning parameters and prepare to tune */
1175     cx24120_clone_params(fe);
1176 
1177     dev_dbg(&state->i2c->dev,
1178         "delsys      = %d\n", state->dcur.delsys);
1179     dev_dbg(&state->i2c->dev,
1180         "modulation  = %d\n", state->dcur.modulation);
1181     dev_dbg(&state->i2c->dev,
1182         "frequency   = %d\n", state->dcur.frequency);
1183     dev_dbg(&state->i2c->dev,
1184         "pilot       = %d (val = 0x%02x)\n",
1185         state->dcur.pilot, state->dcur.pilot_val);
1186     dev_dbg(&state->i2c->dev,
1187         "symbol_rate = %d (clkdiv/ratediv = 0x%02x/0x%02x)\n",
1188          state->dcur.symbol_rate,
1189          state->dcur.clkdiv, state->dcur.ratediv);
1190     dev_dbg(&state->i2c->dev,
1191         "FEC         = %d (mask/val = 0x%02x/0x%02x)\n",
1192         state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
1193     dev_dbg(&state->i2c->dev,
1194         "Inversion   = %d (val = 0x%02x)\n",
1195         state->dcur.inversion, state->dcur.inversion_val);
1196 
1197     /* Flag that clock needs to be set after tune */
1198     state->need_clock_set = 1;
1199 
1200     /* Tune in */
1201     cmd.id = CMD_TUNEREQUEST;
1202     cmd.len = 15;
1203     cmd.arg[0] = 0;
1204     cmd.arg[1]  = (state->dcur.frequency & 0xff0000) >> 16;
1205     cmd.arg[2]  = (state->dcur.frequency & 0x00ff00) >> 8;
1206     cmd.arg[3]  = (state->dcur.frequency & 0x0000ff);
1207     cmd.arg[4]  = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
1208     cmd.arg[5]  = ((state->dcur.symbol_rate / 1000) & 0x00ff);
1209     cmd.arg[6]  = state->dcur.inversion;
1210     cmd.arg[7]  = state->dcur.fec_val | state->dcur.pilot_val;
1211     cmd.arg[8]  = CX24120_SEARCH_RANGE_KHZ >> 8;
1212     cmd.arg[9]  = CX24120_SEARCH_RANGE_KHZ & 0xff;
1213     cmd.arg[10] = 0;        /* maybe rolloff? */
1214     cmd.arg[11] = state->dcur.fec_mask;
1215     cmd.arg[12] = state->dcur.ratediv;
1216     cmd.arg[13] = state->dcur.clkdiv;
1217     cmd.arg[14] = 0;
1218 
1219     /* Send tune command */
1220     ret = cx24120_message_send(state, &cmd);
1221     if (ret != 0)
1222         return ret;
1223 
1224     /* Write symbol rate values */
1225     ret = cx24120_writereg(state, CX24120_REG_CLKDIV, state->dcur.clkdiv);
1226     ret = cx24120_readreg(state, CX24120_REG_RATEDIV);
1227     ret &= 0xfffffff0;
1228     ret |= state->dcur.ratediv;
1229     ret = cx24120_writereg(state, CX24120_REG_RATEDIV, ret);
1230 
1231     return 0;
1232 }
1233 
1234 /* Set vco from config */
1235 static int cx24120_set_vco(struct cx24120_state *state)
1236 {
1237     struct cx24120_cmd cmd;
1238     u32 nxtal_khz, vco;
1239     u64 inv_vco;
1240     u32 xtal_khz = state->config->xtal_khz;
1241 
1242     nxtal_khz = xtal_khz * 4;
1243     vco = nxtal_khz * 10;
1244     inv_vco = DIV_ROUND_CLOSEST_ULL(0x400000000ULL, vco);
1245 
1246     dev_dbg(&state->i2c->dev, "xtal=%d, vco=%d, inv_vco=%lld\n",
1247         xtal_khz, vco, inv_vco);
1248 
1249     cmd.id = CMD_VCO_SET;
1250     cmd.len = 12;
1251     cmd.arg[0] = (vco >> 16) & 0xff;
1252     cmd.arg[1] = (vco >> 8) & 0xff;
1253     cmd.arg[2] = vco & 0xff;
1254     cmd.arg[3] = (inv_vco >> 8) & 0xff;
1255     cmd.arg[4] = (inv_vco) & 0xff;
1256     cmd.arg[5] = 0x03;
1257     cmd.arg[6] = (nxtal_khz >> 8) & 0xff;
1258     cmd.arg[7] = nxtal_khz & 0xff;
1259     cmd.arg[8] = 0x06;
1260     cmd.arg[9] = 0x03;
1261     cmd.arg[10] = (xtal_khz >> 16) & 0xff;
1262     cmd.arg[11] = xtal_khz & 0xff;
1263 
1264     return cx24120_message_send(state, &cmd);
1265 }
1266 
1267 static int cx24120_init(struct dvb_frontend *fe)
1268 {
1269     const struct firmware *fw;
1270     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1271     struct cx24120_state *state = fe->demodulator_priv;
1272     struct cx24120_cmd cmd;
1273     u8 reg;
1274     int ret, i;
1275     unsigned char vers[4];
1276 
1277     if (state->cold_init)
1278         return 0;
1279 
1280     /* ???? */
1281     cx24120_writereg(state, 0xea, 0x00);
1282     cx24120_test_rom(state);
1283     reg = cx24120_readreg(state, 0xfb) & 0xfe;
1284     cx24120_writereg(state, 0xfb, reg);
1285     reg = cx24120_readreg(state, 0xfc) & 0xfe;
1286     cx24120_writereg(state, 0xfc, reg);
1287     cx24120_writereg(state, 0xc3, 0x04);
1288     cx24120_writereg(state, 0xc4, 0x04);
1289     cx24120_writereg(state, 0xce, 0x00);
1290     cx24120_writereg(state, 0xcf, 0x00);
1291     reg = cx24120_readreg(state, 0xea) & 0xfe;
1292     cx24120_writereg(state, 0xea, reg);
1293     cx24120_writereg(state, 0xeb, 0x0c);
1294     cx24120_writereg(state, 0xec, 0x06);
1295     cx24120_writereg(state, 0xed, 0x05);
1296     cx24120_writereg(state, 0xee, 0x03);
1297     cx24120_writereg(state, 0xef, 0x05);
1298     cx24120_writereg(state, 0xf3, 0x03);
1299     cx24120_writereg(state, 0xf4, 0x44);
1300 
1301     for (i = 0; i < 3; i++) {
1302         cx24120_writereg(state, 0xf0 + i, 0x04);
1303         cx24120_writereg(state, 0xe6 + i, 0x02);
1304     }
1305 
1306     cx24120_writereg(state, 0xea, (reg | 0x01));
1307     for (i = 0; i < 6; i += 2) {
1308         cx24120_writereg(state, 0xc5 + i, 0x00);
1309         cx24120_writereg(state, 0xc6 + i, 0x00);
1310     }
1311 
1312     cx24120_writereg(state, 0xe4, 0x03);
1313     cx24120_writereg(state, 0xeb, 0x0a);
1314 
1315     dev_dbg(&state->i2c->dev, "requesting firmware (%s) to download...\n",
1316         CX24120_FIRMWARE);
1317 
1318     ret = state->config->request_firmware(fe, &fw, CX24120_FIRMWARE);
1319     if (ret) {
1320         err("Could not load firmware (%s): %d\n", CX24120_FIRMWARE,
1321             ret);
1322         return ret;
1323     }
1324 
1325     dev_dbg(&state->i2c->dev,
1326         "Firmware found, size %d bytes (%02x %02x .. %02x %02x)\n",
1327         (int)fw->size,          /* firmware_size in bytes */
1328         fw->data[0],            /* fw 1st byte */
1329         fw->data[1],            /* fw 2d byte */
1330         fw->data[fw->size - 2],     /* fw before last byte */
1331         fw->data[fw->size - 1]);    /* fw last byte */
1332 
1333     cx24120_test_rom(state);
1334     reg = cx24120_readreg(state, 0xfb) & 0xfe;
1335     cx24120_writereg(state, 0xfb, reg);
1336     cx24120_writereg(state, 0xe0, 0x76);
1337     cx24120_writereg(state, 0xf7, 0x81);
1338     cx24120_writereg(state, 0xf8, 0x00);
1339     cx24120_writereg(state, 0xf9, 0x00);
1340     cx24120_writeregs(state, 0xfa, fw->data, (fw->size - 1), 0x00);
1341     cx24120_writereg(state, 0xf7, 0xc0);
1342     cx24120_writereg(state, 0xe0, 0x00);
1343     reg = (fw->size - 2) & 0x00ff;
1344     cx24120_writereg(state, 0xf8, reg);
1345     reg = ((fw->size - 2) >> 8) & 0x00ff;
1346     cx24120_writereg(state, 0xf9, reg);
1347     cx24120_writereg(state, 0xf7, 0x00);
1348     cx24120_writereg(state, 0xdc, 0x00);
1349     cx24120_writereg(state, 0xdc, 0x07);
1350     msleep(500);
1351 
1352     /* Check final byte matches final byte of firmware */
1353     reg = cx24120_readreg(state, 0xe1);
1354     if (reg == fw->data[fw->size - 1]) {
1355         dev_dbg(&state->i2c->dev, "Firmware uploaded successfully\n");
1356         ret = 0;
1357     } else {
1358         err("Firmware upload failed. Last byte returned=0x%x\n", ret);
1359         ret = -EREMOTEIO;
1360     }
1361     cx24120_writereg(state, 0xdc, 0x00);
1362     release_firmware(fw);
1363     if (ret != 0)
1364         return ret;
1365 
1366     /* Start tuner */
1367     cmd.id = CMD_START_TUNER;
1368     cmd.len = 3;
1369     cmd.arg[0] = 0x00;
1370     cmd.arg[1] = 0x00;
1371     cmd.arg[2] = 0x00;
1372 
1373     if (cx24120_message_send(state, &cmd) != 0) {
1374         err("Error tuner start! :(\n");
1375         return -EREMOTEIO;
1376     }
1377 
1378     /* Set VCO */
1379     ret = cx24120_set_vco(state);
1380     if (ret != 0) {
1381         err("Error set VCO! :(\n");
1382         return ret;
1383     }
1384 
1385     /* set bandwidth */
1386     cmd.id = CMD_BANDWIDTH;
1387     cmd.len = 12;
1388     cmd.arg[0] = 0x00;
1389     cmd.arg[1] = 0x00;
1390     cmd.arg[2] = 0x00;
1391     cmd.arg[3] = 0x00;
1392     cmd.arg[4] = 0x05;
1393     cmd.arg[5] = 0x02;
1394     cmd.arg[6] = 0x02;
1395     cmd.arg[7] = 0x00;
1396     cmd.arg[8] = 0x05;
1397     cmd.arg[9] = 0x02;
1398     cmd.arg[10] = 0x02;
1399     cmd.arg[11] = 0x00;
1400 
1401     if (cx24120_message_send(state, &cmd)) {
1402         err("Error set bandwidth!\n");
1403         return -EREMOTEIO;
1404     }
1405 
1406     reg = cx24120_readreg(state, 0xba);
1407     if (reg > 3) {
1408         dev_dbg(&state->i2c->dev, "Reset-readreg 0xba: %x\n", ret);
1409         err("Error initialising tuner!\n");
1410         return -EREMOTEIO;
1411     }
1412 
1413     dev_dbg(&state->i2c->dev, "Tuner initialised correctly.\n");
1414 
1415     /* Initialise mpeg outputs */
1416     cx24120_writereg(state, 0xeb, 0x0a);
1417     if (cx24120_msg_mpeg_output_global_config(state, 0) ||
1418         cx24120_msg_mpeg_output_config(state, 0) ||
1419         cx24120_msg_mpeg_output_config(state, 1) ||
1420         cx24120_msg_mpeg_output_config(state, 2)) {
1421         err("Error initialising mpeg output. :(\n");
1422         return -EREMOTEIO;
1423     }
1424 
1425     /* Set size of BER window */
1426     cmd.id = CMD_BER_CTRL;
1427     cmd.len = 3;
1428     cmd.arg[0] = 0x00;
1429     cmd.arg[1] = CX24120_BER_WINDOW;
1430     cmd.arg[2] = CX24120_BER_WINDOW;
1431     if (cx24120_message_send(state, &cmd)) {
1432         err("Error setting ber window\n");
1433         return -EREMOTEIO;
1434     }
1435 
1436     /* Firmware CMD 35: Get firmware version */
1437     cmd.id = CMD_FWVERSION;
1438     cmd.len = 1;
1439     for (i = 0; i < 4; i++) {
1440         cmd.arg[0] = i;
1441         ret = cx24120_message_send(state, &cmd);
1442         if (ret != 0)
1443             return ret;
1444         vers[i] = cx24120_readreg(state, CX24120_REG_MAILBOX);
1445     }
1446     info("FW version %i.%i.%i.%i\n", vers[0], vers[1], vers[2], vers[3]);
1447 
1448     /* init stats here in order signal app which stats are supported */
1449     c->strength.len = 1;
1450     c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1451     c->cnr.len = 1;
1452     c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1453     c->post_bit_error.len = 1;
1454     c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1455     c->post_bit_count.len = 1;
1456     c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1457     c->block_error.len = 1;
1458     c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1459     c->block_count.len = 1;
1460     c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1461 
1462     state->cold_init = 1;
1463 
1464     return 0;
1465 }
1466 
1467 static int cx24120_tune(struct dvb_frontend *fe, bool re_tune,
1468             unsigned int mode_flags, unsigned int *delay,
1469             enum fe_status *status)
1470 {
1471     struct cx24120_state *state = fe->demodulator_priv;
1472     int ret;
1473 
1474     dev_dbg(&state->i2c->dev, "(%d)\n", re_tune);
1475 
1476     /* TODO: Do we need to set delay? */
1477 
1478     if (re_tune) {
1479         ret = cx24120_set_frontend(fe);
1480         if (ret)
1481             return ret;
1482     }
1483 
1484     return cx24120_read_status(fe, status);
1485 }
1486 
1487 static enum dvbfe_algo cx24120_get_algo(struct dvb_frontend *fe)
1488 {
1489     return DVBFE_ALGO_HW;
1490 }
1491 
1492 static int cx24120_sleep(struct dvb_frontend *fe)
1493 {
1494     return 0;
1495 }
1496 
1497 static int cx24120_get_frontend(struct dvb_frontend *fe,
1498                 struct dtv_frontend_properties *c)
1499 {
1500     struct cx24120_state *state = fe->demodulator_priv;
1501     u8 freq1, freq2, freq3;
1502     int status;
1503 
1504     dev_dbg(&state->i2c->dev, "\n");
1505 
1506     /* don't return empty data if we're not tuned in */
1507     status = cx24120_readreg(state, CX24120_REG_STATUS);
1508     if (!(status & CX24120_HAS_LOCK))
1509         return 0;
1510 
1511     /* Get frequency */
1512     freq1 = cx24120_readreg(state, CX24120_REG_FREQ1);
1513     freq2 = cx24120_readreg(state, CX24120_REG_FREQ2);
1514     freq3 = cx24120_readreg(state, CX24120_REG_FREQ3);
1515     c->frequency = (freq3 << 16) | (freq2 << 8) | freq1;
1516     dev_dbg(&state->i2c->dev, "frequency = %d\n", c->frequency);
1517 
1518     /* Get modulation, fec, pilot */
1519     cx24120_get_fec(fe);
1520 
1521     return 0;
1522 }
1523 
1524 static void cx24120_release(struct dvb_frontend *fe)
1525 {
1526     struct cx24120_state *state = fe->demodulator_priv;
1527 
1528     dev_dbg(&state->i2c->dev, "Clear state structure\n");
1529     kfree(state);
1530 }
1531 
1532 static int cx24120_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1533 {
1534     struct cx24120_state *state = fe->demodulator_priv;
1535     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1536 
1537     if (c->block_error.stat[0].scale != FE_SCALE_COUNTER) {
1538         *ucblocks = 0;
1539         return 0;
1540     }
1541 
1542     *ucblocks = c->block_error.stat[0].uvalue - state->ucb_offset;
1543 
1544     return 0;
1545 }
1546 
1547 static const struct dvb_frontend_ops cx24120_ops = {
1548     .delsys = { SYS_DVBS, SYS_DVBS2 },
1549     .info = {
1550         .name = "Conexant CX24120/CX24118",
1551         .frequency_min_hz =  950 * MHz,
1552         .frequency_max_hz = 2150 * MHz,
1553         .frequency_stepsize_hz = 1011 * kHz,
1554         .frequency_tolerance_hz = 5 * MHz,
1555         .symbol_rate_min = 1000000,
1556         .symbol_rate_max = 45000000,
1557         .caps = FE_CAN_INVERSION_AUTO |
1558             FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1559             FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1560             FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1561             FE_CAN_2G_MODULATION |
1562             FE_CAN_QPSK | FE_CAN_RECOVER
1563     },
1564     .release =          cx24120_release,
1565 
1566     .init =             cx24120_init,
1567     .sleep =            cx24120_sleep,
1568 
1569     .tune =             cx24120_tune,
1570     .get_frontend_algo =        cx24120_get_algo,
1571     .set_frontend =         cx24120_set_frontend,
1572 
1573     .get_frontend =         cx24120_get_frontend,
1574     .read_status =          cx24120_read_status,
1575     .read_ber =         cx24120_read_ber,
1576     .read_signal_strength =     cx24120_read_signal_strength,
1577     .read_snr =         cx24120_read_snr,
1578     .read_ucblocks =        cx24120_read_ucblocks,
1579 
1580     .diseqc_send_master_cmd =   cx24120_send_diseqc_msg,
1581 
1582     .diseqc_send_burst =        cx24120_diseqc_send_burst,
1583     .set_tone =         cx24120_set_tone,
1584     .set_voltage =          cx24120_set_voltage,
1585 };
1586 
1587 MODULE_DESCRIPTION("DVB Frontend module for Conexant CX24120/CX24118 hardware");
1588 MODULE_AUTHOR("Jemma Denson");
1589 MODULE_LICENSE("GPL");