Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/media/dvb-frontends/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 119 kB image not shown  

Quelle  cxd2841er.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * cxd2841er.c
 *
 * Sony digital demodulator driver for
 * CXD2841ER - DVB-S/S2/T/T2/C/C2
 * CXD2854ER - DVB-S/S2/T/T2/C/C2, ISDB-T/S
 *
 * Copyright 2012 Sony Corporation
 * Copyright (C) 2014 NetUP Inc.
 * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
  */


#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/bitops.h>
#include <linux/math64.h>
#include <linux/log2.h>
#include <linux/dynamic_debug.h>
#include <linux/kernel.h>

#include <linux/int_log.h>
#include <media/dvb_frontend.h>
#include "cxd2841er.h"
#include "cxd2841er_priv.h"

#define MAX_WRITE_REGSIZE 16
#define LOG2_E_100X 144

#define INTLOG10X100(x) ((u32) (((u64) intlog10(x) * 100) >> 24))

/* DVB-C constellation */
enum sony_dvbc_constellation_t {
 SONY_DVBC_CONSTELLATION_16QAM,
 SONY_DVBC_CONSTELLATION_32QAM,
 SONY_DVBC_CONSTELLATION_64QAM,
 SONY_DVBC_CONSTELLATION_128QAM,
 SONY_DVBC_CONSTELLATION_256QAM
};

enum cxd2841er_state {
 STATE_SHUTDOWN = 0,
 STATE_SLEEP_S,
 STATE_ACTIVE_S,
 STATE_SLEEP_TC,
 STATE_ACTIVE_TC
};

struct cxd2841er_priv {
 struct dvb_frontend  frontend;
 struct i2c_adapter  *i2c;
 u8    i2c_addr_slvx;
 u8    i2c_addr_slvt;
 const struct cxd2841er_config *config;
 enum cxd2841er_state  state;
 u8    system;
 enum cxd2841er_xtal  xtal;
 enum fe_caps caps;
 u32    flags;
 unsigned long   stats_time;
};

static const struct cxd2841er_cnr_data s_cn_data[] = {
 { 0x033e, 0 }, { 0x0339, 100 }, { 0x0333, 200 },
 { 0x032e, 300 }, { 0x0329, 400 }, { 0x0324, 500 },
 { 0x031e, 600 }, { 0x0319, 700 }, { 0x0314, 800 },
 { 0x030f, 900 }, { 0x030a, 1000 }, { 0x02ff, 1100 },
 { 0x02f4, 1200 }, { 0x02e9, 1300 }, { 0x02de, 1400 },
 { 0x02d4, 1500 }, { 0x02c9, 1600 }, { 0x02bf, 1700 },
 { 0x02b5, 1800 }, { 0x02ab, 1900 }, { 0x02a1, 2000 },
 { 0x029b, 2100 }, { 0x0295, 2200 }, { 0x0290, 2300 },
 { 0x028a, 2400 }, { 0x0284, 2500 }, { 0x027f, 2600 },
 { 0x0279, 2700 }, { 0x0274, 2800 }, { 0x026e, 2900 },
 { 0x0269, 3000 }, { 0x0262, 3100 }, { 0x025c, 3200 },
 { 0x0255, 3300 }, { 0x024f, 3400 }, { 0x0249, 3500 },
 { 0x0242, 3600 }, { 0x023c, 3700 }, { 0x0236, 3800 },
 { 0x0230, 3900 }, { 0x022a, 4000 }, { 0x0223, 4100 },
 { 0x021c, 4200 }, { 0x0215, 4300 }, { 0x020e, 4400 },
 { 0x0207, 4500 }, { 0x0201, 4600 }, { 0x01fa, 4700 },
 { 0x01f4, 4800 }, { 0x01ed, 4900 }, { 0x01e7, 5000 },
 { 0x01e0, 5100 }, { 0x01d9, 5200 }, { 0x01d2, 5300 },
 { 0x01cb, 5400 }, { 0x01c4, 5500 }, { 0x01be, 5600 },
 { 0x01b7, 5700 }, { 0x01b1, 5800 }, { 0x01aa, 5900 },
 { 0x01a4, 6000 }, { 0x019d, 6100 }, { 0x0196, 6200 },
 { 0x018f, 6300 }, { 0x0189, 6400 }, { 0x0182, 6500 },
 { 0x017c, 6600 }, { 0x0175, 6700 }, { 0x016f, 6800 },
 { 0x0169, 6900 }, { 0x0163, 7000 }, { 0x015c, 7100 },
 { 0x0156, 7200 }, { 0x0150, 7300 }, { 0x014a, 7400 },
 { 0x0144, 7500 }, { 0x013e, 7600 }, { 0x0138, 7700 },
 { 0x0132, 7800 }, { 0x012d, 7900 }, { 0x0127, 8000 },
 { 0x0121, 8100 }, { 0x011c, 8200 }, { 0x0116, 8300 },
 { 0x0111, 8400 }, { 0x010b, 8500 }, { 0x0106, 8600 },
 { 0x0101, 8700 }, { 0x00fc, 8800 }, { 0x00f7, 8900 },
 { 0x00f2, 9000 }, { 0x00ee, 9100 }, { 0x00ea, 9200 },
 { 0x00e6, 9300 }, { 0x00e2, 9400 }, { 0x00de, 9500 },
 { 0x00da, 9600 }, { 0x00d7, 9700 }, { 0x00d3, 9800 },
 { 0x00d0, 9900 }, { 0x00cc, 10000 }, { 0x00c7, 10100 },
 { 0x00c3, 10200 }, { 0x00bf, 10300 }, { 0x00ba, 10400 },
 { 0x00b6, 10500 }, { 0x00b2, 10600 }, { 0x00ae, 10700 },
 { 0x00aa, 10800 }, { 0x00a7, 10900 }, { 0x00a3, 11000 },
 { 0x009f, 11100 }, { 0x009c, 11200 }, { 0x0098, 11300 },
 { 0x0094, 11400 }, { 0x0091, 11500 }, { 0x008e, 11600 },
 { 0x008a, 11700 }, { 0x0087, 11800 }, { 0x0084, 11900 },
 { 0x0081, 12000 }, { 0x007e, 12100 }, { 0x007b, 12200 },
 { 0x0079, 12300 }, { 0x0076, 12400 }, { 0x0073, 12500 },
 { 0x0071, 12600 }, { 0x006e, 12700 }, { 0x006c, 12800 },
 { 0x0069, 12900 }, { 0x0067, 13000 }, { 0x0065, 13100 },
 { 0x0062, 13200 }, { 0x0060, 13300 }, { 0x005e, 13400 },
 { 0x005c, 13500 }, { 0x005a, 13600 }, { 0x0058, 13700 },
 { 0x0056, 13800 }, { 0x0054, 13900 }, { 0x0052, 14000 },
 { 0x0050, 14100 }, { 0x004e, 14200 }, { 0x004c, 14300 },
 { 0x004b, 14400 }, { 0x0049, 14500 }, { 0x0047, 14600 },
 { 0x0046, 14700 }, { 0x0044, 14800 }, { 0x0043, 14900 },
 { 0x0041, 15000 }, { 0x003f, 15100 }, { 0x003e, 15200 },
 { 0x003c, 15300 }, { 0x003b, 15400 }, { 0x003a, 15500 },
 { 0x0037, 15700 }, { 0x0036, 15800 }, { 0x0034, 15900 },
 { 0x0033, 16000 }, { 0x0032, 16100 }, { 0x0031, 16200 },
 { 0x0030, 16300 }, { 0x002f, 16400 }, { 0x002e, 16500 },
 { 0x002d, 16600 }, { 0x002c, 16700 }, { 0x002b, 16800 },
 { 0x002a, 16900 }, { 0x0029, 17000 }, { 0x0028, 17100 },
 { 0x0027, 17200 }, { 0x0026, 17300 }, { 0x0025, 17400 },
 { 0x0024, 17500 }, { 0x0023, 17600 }, { 0x0022, 17800 },
 { 0x0021, 17900 }, { 0x0020, 18000 }, { 0x001f, 18200 },
 { 0x001e, 18300 }, { 0x001d, 18500 }, { 0x001c, 18700 },
 { 0x001b, 18900 }, { 0x001a, 19000 }, { 0x0019, 19200 },
 { 0x0018, 19300 }, { 0x0017, 19500 }, { 0x0016, 19700 },
 { 0x0015, 19900 }, { 0x0014, 20000 },
};

static const struct cxd2841er_cnr_data s2_cn_data[] = {
 { 0x05af, 0 }, { 0x0597, 100 }, { 0x057e, 200 },
 { 0x0567, 300 }, { 0x0550, 400 }, { 0x0539, 500 },
 { 0x0522, 600 }, { 0x050c, 700 }, { 0x04f6, 800 },
 { 0x04e1, 900 }, { 0x04cc, 1000 }, { 0x04b6, 1100 },
 { 0x04a1, 1200 }, { 0x048c, 1300 }, { 0x0477, 1400 },
 { 0x0463, 1500 }, { 0x044f, 1600 }, { 0x043c, 1700 },
 { 0x0428, 1800 }, { 0x0416, 1900 }, { 0x0403, 2000 },
 { 0x03ef, 2100 }, { 0x03dc, 2200 }, { 0x03c9, 2300 },
 { 0x03b6, 2400 }, { 0x03a4, 2500 }, { 0x0392, 2600 },
 { 0x0381, 2700 }, { 0x036f, 2800 }, { 0x035f, 2900 },
 { 0x034e, 3000 }, { 0x033d, 3100 }, { 0x032d, 3200 },
 { 0x031d, 3300 }, { 0x030d, 3400 }, { 0x02fd, 3500 },
 { 0x02ee, 3600 }, { 0x02df, 3700 }, { 0x02d0, 3800 },
 { 0x02c2, 3900 }, { 0x02b4, 4000 }, { 0x02a6, 4100 },
 { 0x0299, 4200 }, { 0x028c, 4300 }, { 0x027f, 4400 },
 { 0x0272, 4500 }, { 0x0265, 4600 }, { 0x0259, 4700 },
 { 0x024d, 4800 }, { 0x0241, 4900 }, { 0x0236, 5000 },
 { 0x022b, 5100 }, { 0x0220, 5200 }, { 0x0215, 5300 },
 { 0x020a, 5400 }, { 0x0200, 5500 }, { 0x01f6, 5600 },
 { 0x01ec, 5700 }, { 0x01e2, 5800 }, { 0x01d8, 5900 },
 { 0x01cf, 6000 }, { 0x01c6, 6100 }, { 0x01bc, 6200 },
 { 0x01b3, 6300 }, { 0x01aa, 6400 }, { 0x01a2, 6500 },
 { 0x0199, 6600 }, { 0x0191, 6700 }, { 0x0189, 6800 },
 { 0x0181, 6900 }, { 0x0179, 7000 }, { 0x0171, 7100 },
 { 0x0169, 7200 }, { 0x0161, 7300 }, { 0x015a, 7400 },
 { 0x0153, 7500 }, { 0x014b, 7600 }, { 0x0144, 7700 },
 { 0x013d, 7800 }, { 0x0137, 7900 }, { 0x0130, 8000 },
 { 0x012a, 8100 }, { 0x0124, 8200 }, { 0x011e, 8300 },
 { 0x0118, 8400 }, { 0x0112, 8500 }, { 0x010c, 8600 },
 { 0x0107, 8700 }, { 0x0101, 8800 }, { 0x00fc, 8900 },
 { 0x00f7, 9000 }, { 0x00f2, 9100 }, { 0x00ec, 9200 },
 { 0x00e7, 9300 }, { 0x00e2, 9400 }, { 0x00dd, 9500 },
 { 0x00d8, 9600 }, { 0x00d4, 9700 }, { 0x00cf, 9800 },
 { 0x00ca, 9900 }, { 0x00c6, 10000 }, { 0x00c2, 10100 },
 { 0x00be, 10200 }, { 0x00b9, 10300 }, { 0x00b5, 10400 },
 { 0x00b1, 10500 }, { 0x00ae, 10600 }, { 0x00aa, 10700 },
 { 0x00a6, 10800 }, { 0x00a3, 10900 }, { 0x009f, 11000 },
 { 0x009b, 11100 }, { 0x0098, 11200 }, { 0x0095, 11300 },
 { 0x0091, 11400 }, { 0x008e, 11500 }, { 0x008b, 11600 },
 { 0x0088, 11700 }, { 0x0085, 11800 }, { 0x0082, 11900 },
 { 0x007f, 12000 }, { 0x007c, 12100 }, { 0x007a, 12200 },
 { 0x0077, 12300 }, { 0x0074, 12400 }, { 0x0072, 12500 },
 { 0x006f, 12600 }, { 0x006d, 12700 }, { 0x006b, 12800 },
 { 0x0068, 12900 }, { 0x0066, 13000 }, { 0x0064, 13100 },
 { 0x0061, 13200 }, { 0x005f, 13300 }, { 0x005d, 13400 },
 { 0x005b, 13500 }, { 0x0059, 13600 }, { 0x0057, 13700 },
 { 0x0055, 13800 }, { 0x0053, 13900 }, { 0x0051, 14000 },
 { 0x004f, 14100 }, { 0x004e, 14200 }, { 0x004c, 14300 },
 { 0x004a, 14400 }, { 0x0049, 14500 }, { 0x0047, 14600 },
 { 0x0045, 14700 }, { 0x0044, 14800 }, { 0x0042, 14900 },
 { 0x0041, 15000 }, { 0x003f, 15100 }, { 0x003e, 15200 },
 { 0x003c, 15300 }, { 0x003b, 15400 }, { 0x003a, 15500 },
 { 0x0038, 15600 }, { 0x0037, 15700 }, { 0x0036, 15800 },
 { 0x0034, 15900 }, { 0x0033, 16000 }, { 0x0032, 16100 },
 { 0x0031, 16200 }, { 0x0030, 16300 }, { 0x002f, 16400 },
 { 0x002e, 16500 }, { 0x002d, 16600 }, { 0x002c, 16700 },
 { 0x002b, 16800 }, { 0x002a, 16900 }, { 0x0029, 17000 },
 { 0x0028, 17100 }, { 0x0027, 17200 }, { 0x0026, 17300 },
 { 0x0025, 17400 }, { 0x0024, 17500 }, { 0x0023, 17600 },
 { 0x0022, 17800 }, { 0x0021, 17900 }, { 0x0020, 18000 },
 { 0x001f, 18200 }, { 0x001e, 18300 }, { 0x001d, 18500 },
 { 0x001c, 18700 }, { 0x001b, 18900 }, { 0x001a, 19000 },
 { 0x0019, 19200 }, { 0x0018, 19300 }, { 0x0017, 19500 },
 { 0x0016, 19700 }, { 0x0015, 19900 }, { 0x0014, 20000 },
};

static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv);
static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv);

static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv,
    u8 addr, u8 reg, u8 write,
    const u8 *data, u32 len)
{
 dev_dbg(&priv->i2c->dev,
  "cxd2841er: I2C %s addr %02x reg 0x%02x size %d data %*ph\n",
  (write == 0 ? "read" : "write"), addr, reg, len, len, data);
}

static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
    u8 addr, u8 reg, const u8 *data, u32 len)
{
 int ret;
 u8 buf[MAX_WRITE_REGSIZE + 1];
 u8 i2c_addr = (addr == I2C_SLVX ?
  priv->i2c_addr_slvx : priv->i2c_addr_slvt);
 struct i2c_msg msg[1] = {
  {
   .addr = i2c_addr,
   .flags = 0,
   .len = len + 1,
   .buf = buf,
  }
 };

 if (len + 1 >= sizeof(buf)) {
  dev_warn(&priv->i2c->dev, "wr reg=%04x: len=%d is too big!\n",
    reg, len + 1);
  return -E2BIG;
 }

 cxd2841er_i2c_debug(priv, i2c_addr, reg, 1, data, len);
 buf[0] = reg;
 memcpy(&buf[1], data, len);

 ret = i2c_transfer(priv->i2c, msg, 1);
 if (ret >= 0 && ret != 1)
  ret = -EIO;
 if (ret < 0) {
  dev_warn(&priv->i2c->dev,
   "%s: i2c wr failed=%d addr=%02x reg=%02x len=%d\n",
   KBUILD_MODNAME, ret, i2c_addr, reg, len);
  return ret;
 }
 return 0;
}

static int cxd2841er_write_reg(struct cxd2841er_priv *priv,
          u8 addr, u8 reg, u8 val)
{
 u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */

 return cxd2841er_write_regs(priv, addr, reg, &tmp, 1);
}

static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
          u8 addr, u8 reg, u8 *val, u32 len)
{
 int ret;
 u8 i2c_addr = (addr == I2C_SLVX ?
  priv->i2c_addr_slvx : priv->i2c_addr_slvt);
 struct i2c_msg msg[2] = {
  {
   .addr = i2c_addr,
   .flags = 0,
   .len = 1,
   .buf = ®,
  }, {
   .addr = i2c_addr,
   .flags = I2C_M_RD,
   .len = len,
   .buf = val,
  }
 };

 ret = i2c_transfer(priv->i2c, msg, 2);
 if (ret >= 0 && ret != 2)
  ret = -EIO;
 if (ret < 0) {
  dev_warn(&priv->i2c->dev,
   "%s: i2c rd failed=%d addr=%02x reg=%02x\n",
   KBUILD_MODNAME, ret, i2c_addr, reg);
  return ret;
 }
 cxd2841er_i2c_debug(priv, i2c_addr, reg, 0, val, len);
 return 0;
}

static int cxd2841er_read_reg(struct cxd2841er_priv *priv,
         u8 addr, u8 reg, u8 *val)
{
 return cxd2841er_read_regs(priv, addr, reg, val, 1);
}

static int cxd2841er_set_reg_bits(struct cxd2841er_priv *priv,
      u8 addr, u8 reg, u8 data, u8 mask)
{
 int res;
 u8 rdata;

 if (mask != 0xff) {
  res = cxd2841er_read_reg(priv, addr, reg, &rdata);
  if (res)
   return res;
  data = ((data & mask) | (rdata & (mask ^ 0xFF)));
 }
 return cxd2841er_write_reg(priv, addr, reg, data);
}

static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz)
{
 return div_u64(ifhz * 16777216ull,
         (xtal == SONY_XTAL_24000) ? 48000000 : 41000000);
}

static u32 cxd2841er_calc_iffreq(u32 ifhz)
{
 return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz);
}

static int cxd2841er_get_if_hz(struct cxd2841er_priv *priv, u32 def_hz)
{
 u32 hz;

 if (priv->frontend.ops.tuner_ops.get_if_frequency
   && (priv->flags & CXD2841ER_AUTO_IFHZ))
  priv->frontend.ops.tuner_ops.get_if_frequency(
   &priv->frontend, &hz);
 else
  hz = def_hz;

 return hz;
}

static int cxd2841er_tuner_set(struct dvb_frontend *fe)
{
 struct cxd2841er_priv *priv = fe->demodulator_priv;

 if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
  fe->ops.i2c_gate_ctrl(fe, 1);
 if (fe->ops.tuner_ops.set_params)
  fe->ops.tuner_ops.set_params(fe);
 if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
  fe->ops.i2c_gate_ctrl(fe, 0);

 return 0;
}

static int cxd2841er_dvbs2_set_symbol_rate(struct cxd2841er_priv *priv,
        u32 symbol_rate)
{
 u32 reg_value = 0;
 u8 data[3] = {0, 0, 0};

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 /*
 * regValue = (symbolRateKSps * 2^14 / 1000) + 0.5
 *          = ((symbolRateKSps * 2^14) + 500) / 1000
 *          = ((symbolRateKSps * 16384) + 500) / 1000
 */

 reg_value = DIV_ROUND_CLOSEST(symbol_rate * 16384, 1000);
 if ((reg_value == 0) || (reg_value > 0xFFFFF)) {
  dev_err(&priv->i2c->dev,
   "%s(): reg_value is out of range\n", __func__);
  return -EINVAL;
 }
 data[0] = (u8)((reg_value >> 16) & 0x0F);
 data[1] = (u8)((reg_value >>  8) & 0xFF);
 data[2] = (u8)(reg_value & 0xFF);
 /* Set SLV-T Bank : 0xAE */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xae);
 cxd2841er_write_regs(priv, I2C_SLVT, 0x20, data, 3);
 return 0;
}

static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
     u8 system);

static int cxd2841er_sleep_s_to_active_s(struct cxd2841er_priv *priv,
      u8 system, u32 symbol_rate)
{
 int ret;
 u8 data[4] = { 0, 0, 0, 0 };

 if (priv->state != STATE_SLEEP_S) {
  dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, (int)priv->state);
  return -EINVAL;
 }
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 cxd2841er_set_ts_clock_mode(priv, SYS_DVBS);
 /* Set demod mode */
 if (system == SYS_DVBS) {
  data[0] = 0x0A;
 } else if (system == SYS_DVBS2) {
  data[0] = 0x0B;
 } else {
  dev_err(&priv->i2c->dev, "%s(): invalid delsys %d\n",
   __func__, system);
  return -EINVAL;
 }
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 cxd2841er_write_reg(priv, I2C_SLVX, 0x17, data[0]);
 /* DVB-S/S2 */
 data[0] = 0x00;
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* Enable S/S2 auto detection 1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2d, data[0]);
 /* Set SLV-T Bank : 0xAE */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xae);
 /* Enable S/S2 auto detection 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, data[0]);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* Enable demod clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01);
 /* Enable ADC clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x31, 0x01);
 /* Enable ADC 1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16);
 /* Enable ADC 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x3f);
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* Enable ADC 3 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
 /* Set SLV-T Bank : 0xA3 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa3);
 cxd2841er_write_reg(priv, I2C_SLVT, 0xac, 0x00);
 data[0] = 0x07;
 data[1] = 0x3B;
 data[2] = 0x08;
 data[3] = 0xC5;
 /* Set SLV-T Bank : 0xAB */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xab);
 cxd2841er_write_regs(priv, I2C_SLVT, 0x98, data, 4);
 data[0] = 0x05;
 data[1] = 0x80;
 data[2] = 0x0A;
 data[3] = 0x80;
 cxd2841er_write_regs(priv, I2C_SLVT, 0xa8, data, 4);
 data[0] = 0x0C;
 data[1] = 0xCC;
 cxd2841er_write_regs(priv, I2C_SLVT, 0xc3, data, 2);
 /* Set demod parameter */
 ret = cxd2841er_dvbs2_set_symbol_rate(priv, symbol_rate);
 if (ret != 0)
  return ret;
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* disable Hi-Z setting 1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x10);
 /* disable Hi-Z setting 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00);
 priv->state = STATE_ACTIVE_S;
 return 0;
}

static int cxd2841er_sleep_tc_to_active_t_band(struct cxd2841er_priv *priv,
            u32 bandwidth);

static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
      u32 bandwidth);

static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
            u32 bandwidth);

static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv,
  u32 bandwidth);

static int cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv *priv);

static int cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv *priv);

static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv);

static int cxd2841er_sleep_tc(struct dvb_frontend *fe);

static int cxd2841er_retune_active(struct cxd2841er_priv *priv,
       struct dtv_frontend_properties *p)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_S &&
   priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* disable TS output */
 cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
 if (priv->state == STATE_ACTIVE_S)
  return cxd2841er_dvbs2_set_symbol_rate(
    priv, p->symbol_rate / 1000);
 else if (priv->state == STATE_ACTIVE_TC) {
  switch (priv->system) {
  case SYS_DVBT:
   return cxd2841er_sleep_tc_to_active_t_band(
     priv, p->bandwidth_hz);
  case SYS_DVBT2:
   return cxd2841er_sleep_tc_to_active_t2_band(
     priv, p->bandwidth_hz);
  case SYS_DVBC_ANNEX_A:
   return cxd2841er_sleep_tc_to_active_c_band(
     priv, p->bandwidth_hz);
  case SYS_ISDBT:
   cxd2841er_active_i_to_sleep_tc(priv);
   cxd2841er_sleep_tc_to_shutdown(priv);
   cxd2841er_shutdown_to_sleep_tc(priv);
   return cxd2841er_sleep_tc_to_active_i(
     priv, p->bandwidth_hz);
  }
 }
 dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
  __func__, priv->system);
 return -EINVAL;
}

static int cxd2841er_active_s_to_sleep_s(struct cxd2841er_priv *priv)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_S) {
  dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* disable TS output */
 cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
 /* enable Hi-Z setting 1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x1f);
 /* enable Hi-Z setting 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* disable ADC 1 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* disable ADC clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x31, 0x00);
 /* disable ADC 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16);
 /* disable ADC 3 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x27);
 /* SADC Bias ON */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x69, 0x06);
 /* disable demod clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
 /* Set SLV-T Bank : 0xAE */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xae);
 /* disable S/S2 auto detection1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* disable S/S2 auto detection2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2d, 0x00);
 priv->state = STATE_SLEEP_S;
 return 0;
}

static int cxd2841er_sleep_s_to_shutdown(struct cxd2841er_priv *priv)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_SLEEP_S) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* Disable DSQOUT */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
 /* Disable DSQIN */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x9c, 0x00);
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* Disable oscillator */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x15, 0x01);
 /* Set demod mode */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01);
 priv->state = STATE_SHUTDOWN;
 return 0;
}

static int cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv *priv)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_SLEEP_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* Disable oscillator */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x15, 0x01);
 /* Set demod mode */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01);
 priv->state = STATE_SHUTDOWN;
 return 0;
}

static int cxd2841er_active_t_to_sleep_tc(struct cxd2841er_priv *priv)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* disable TS output */
 cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
 /* enable Hi-Z setting 1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
 /* enable Hi-Z setting 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* disable ADC 1 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* Disable ADC 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
 /* Disable ADC 3 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
 /* Disable ADC clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
 /* Disable RF level monitor */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
 /* Disable demod clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
 priv->state = STATE_SLEEP_TC;
 return 0;
}

static int cxd2841er_active_t2_to_sleep_tc(struct cxd2841er_priv *priv)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* disable TS output */
 cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
 /* enable Hi-Z setting 1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
 /* enable Hi-Z setting 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
 /* Cancel DVB-T2 setting */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x83, 0x40);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x86, 0x21);
 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9e, 0x09, 0x0f);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x9f, 0xfb);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2a);
 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x38, 0x00, 0x0f);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b);
 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x00, 0x3f);
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* disable ADC 1 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* Disable ADC 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
 /* Disable ADC 3 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
 /* Disable ADC clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
 /* Disable RF level monitor */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
 /* Disable demod clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
 priv->state = STATE_SLEEP_TC;
 return 0;
}

static int cxd2841er_active_c_to_sleep_tc(struct cxd2841er_priv *priv)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* disable TS output */
 cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
 /* enable Hi-Z setting 1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
 /* enable Hi-Z setting 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
 /* Cancel DVB-C setting */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11);
 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa3, 0x00, 0x1f);
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* disable ADC 1 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* Disable ADC 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
 /* Disable ADC 3 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
 /* Disable ADC clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
 /* Disable RF level monitor */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
 /* Disable demod clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
 priv->state = STATE_SLEEP_TC;
 return 0;
}

static int cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv *priv)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
    __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* disable TS output */
 cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
 /* enable Hi-Z setting 1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
 /* enable Hi-Z setting 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);

 /* TODO: Cancel demod parameter */

 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* disable ADC 1 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* Disable ADC 2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
 /* Disable ADC 3 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
 /* Disable ADC clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
 /* Disable RF level monitor */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
 /* Disable demod clock */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
 priv->state = STATE_SLEEP_TC;
 return 0;
}

static int cxd2841er_shutdown_to_sleep_s(struct cxd2841er_priv *priv)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_SHUTDOWN) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* Clear all demodulator registers */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x02, 0x00);
 usleep_range(3000, 5000);
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* Set demod SW reset */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01);

 switch (priv->xtal) {
 case SONY_XTAL_20500:
  cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x00);
  break;
 case SONY_XTAL_24000:
  /* Select demod frequency */
  cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00);
  cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x03);
  break;
 case SONY_XTAL_41000:
  cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x01);
  break;
 default:
  dev_dbg(&priv->i2c->dev, "%s(): invalid demod xtal %d\n",
    __func__, priv->xtal);
  return -EINVAL;
 }

 /* Set demod mode */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x0a);
 /* Clear demod SW reset */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x00);
 usleep_range(1000, 2000);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* enable DSQOUT */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x1F);
 /* enable DSQIN */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x9C, 0x40);
 /* TADC Bias On */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
 /* SADC Bias On */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x27);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x69, 0x06);
 priv->state = STATE_SLEEP_S;
 return 0;
}

static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv)
{
 u8 data = 0;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_SHUTDOWN) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* Clear all demodulator registers */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x02, 0x00);
 usleep_range(3000, 5000);
 /* Set SLV-X Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
 /* Set demod SW reset */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01);
  /* Select ADC clock mode */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x13, 0x00);

 switch (priv->xtal) {
 case SONY_XTAL_20500:
  data = 0x0;
  break;
 case SONY_XTAL_24000:
  /* Select demod frequency */
  cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00);
  data = 0x3;
  break;
 case SONY_XTAL_41000:
  cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00);
  data = 0x1;
  break;
 }
 cxd2841er_write_reg(priv, I2C_SLVX, 0x14, data);
 /* Clear demod SW reset */
 cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x00);
 usleep_range(1000, 2000);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 /* TADC Bias On */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
 /* SADC Bias On */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x27);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x69, 0x06);
 priv->state = STATE_SLEEP_TC;
 return 0;
}

static int cxd2841er_tune_done(struct cxd2841er_priv *priv)
{
 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0, 0);
 /* SW Reset */
 cxd2841er_write_reg(priv, I2C_SLVT, 0xfe, 0x01);
 /* Enable TS output */
 cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x00);
 return 0;
}

/* Set TS parallel mode */
static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
     u8 system)
{
 u8 serial_ts, ts_rate_ctrl_off, ts_in_off;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 /* Set SLV-T Bank : 0x00 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
 cxd2841er_read_reg(priv, I2C_SLVT, 0xc4, &serial_ts);
 cxd2841er_read_reg(priv, I2C_SLVT, 0xd3, &ts_rate_ctrl_off);
 cxd2841er_read_reg(priv, I2C_SLVT, 0xde, &ts_in_off);
 dev_dbg(&priv->i2c->dev, "%s(): ser_ts=0x%02x rate_ctrl_off=0x%02x in_off=0x%02x\n",
  __func__, serial_ts, ts_rate_ctrl_off, ts_in_off);

 /*
 * slave    Bank    Addr    Bit    default    Name
 * <SLV-T>  00h     C4h     [1:0]  2'b??      OSERCKMODE
 */

 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
  ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
 /*
 * slave    Bank    Addr    Bit    default    Name
 * <SLV-T>  00h     D1h     [1:0]  2'b??      OSERDUTYMODE
 */

 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd1,
  ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
 /*
 * slave    Bank    Addr    Bit    default    Name
 * <SLV-T>  00h     D9h     [7:0]  8'h08      OTSCKPERIOD
 */

 cxd2841er_write_reg(priv, I2C_SLVT, 0xd9, 0x08);
 /*
 * Disable TS IF Clock
 * slave    Bank    Addr    Bit    default    Name
 * <SLV-T>  00h     32h     [0]    1'b1       OREG_CK_TSIF_EN
 */

 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x00, 0x01);
 /*
 * slave    Bank    Addr    Bit    default    Name
 * <SLV-T>  00h     33h     [1:0]  2'b01      OREG_CKSEL_TSIF
 */

 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33,
  ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
 /*
 * Enable TS IF Clock
 * slave    Bank    Addr    Bit    default    Name
 * <SLV-T>  00h     32h     [0]    1'b1       OREG_CK_TSIF_EN
 */

 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x01, 0x01);

 if (system == SYS_DVBT) {
  /* Enable parity period for DVB-T */
  cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
  cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x66, 0x01, 0x01);
 } else if (system == SYS_DVBC_ANNEX_A) {
  /* Enable parity period for DVB-C */
  cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
  cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x66, 0x01, 0x01);
 }
}

static u8 cxd2841er_chip_id(struct cxd2841er_priv *priv)
{
 u8 chip_id = 0;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (cxd2841er_write_reg(priv, I2C_SLVT, 0, 0) == 0)
  cxd2841er_read_reg(priv, I2C_SLVT, 0xfd, &chip_id);
 else if (cxd2841er_write_reg(priv, I2C_SLVX, 0, 0) == 0)
  cxd2841er_read_reg(priv, I2C_SLVX, 0xfd, &chip_id);

 return chip_id;
}

static int cxd2841er_read_status_s(struct dvb_frontend *fe,
       enum fe_status *status)
{
 u8 reg = 0;
 struct cxd2841er_priv *priv = fe->demodulator_priv;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 *status = 0;
 if (priv->state != STATE_ACTIVE_S) {
  dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /* Set SLV-T Bank : 0xA0 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
 /*
 *  slave     Bank      Addr      Bit      Signal name
 * <SLV-T>    A0h       11h       [2]      ITSLOCK
 */

 cxd2841er_read_reg(priv, I2C_SLVT, 0x11, ®);
 if (reg & 0x04) {
  *status = FE_HAS_SIGNAL
   | FE_HAS_CARRIER
   | FE_HAS_VITERBI
   | FE_HAS_SYNC
   | FE_HAS_LOCK;
 }
 dev_dbg(&priv->i2c->dev, "%s(): result 0x%x\n", __func__, *status);
 return 0;
}

static int cxd2841er_read_status_t_t2(struct cxd2841er_priv *priv,
          u8 *sync, u8 *tslock, u8 *unlock)
{
 u8 data = 0;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC)
  return -EINVAL;
 if (priv->system == SYS_DVBT) {
  /* Set SLV-T Bank : 0x10 */
  cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
 } else {
  /* Set SLV-T Bank : 0x20 */
  cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
 }
 cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data);
 if ((data & 0x07) == 0x07) {
  dev_dbg(&priv->i2c->dev,
   "%s(): invalid hardware state detected\n", __func__);
  *sync = 0;
  *tslock = 0;
  *unlock = 0;
 } else {
  *sync = ((data & 0x07) == 0x6 ? 1 : 0);
  *tslock = ((data & 0x20) ? 1 : 0);
  *unlock = ((data & 0x10) ? 1 : 0);
 }
 return 0;
}

static int cxd2841er_read_status_c(struct cxd2841er_priv *priv, u8 *tslock)
{
 u8 data;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC)
  return -EINVAL;
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
 cxd2841er_read_reg(priv, I2C_SLVT, 0x88, &data);
 if ((data & 0x01) == 0) {
  *tslock = 0;
 } else {
  cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data);
  *tslock = ((data & 0x20) ? 1 : 0);
 }
 return 0;
}

static int cxd2841er_read_status_i(struct cxd2841er_priv *priv,
  u8 *sync, u8 *tslock, u8 *unlock)
{
 u8 data = 0;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC)
  return -EINVAL;
 /* Set SLV-T Bank : 0x60 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
 cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data);
 dev_dbg(&priv->i2c->dev,
   "%s(): lock=0x%x\n", __func__, data);
 *sync = ((data & 0x02) ? 1 : 0);
 *tslock = ((data & 0x01) ? 1 : 0);
 *unlock = ((data & 0x10) ? 1 : 0);
 return 0;
}

static int cxd2841er_read_status_tc(struct dvb_frontend *fe,
        enum fe_status *status)
{
 int ret = 0;
 u8 sync = 0;
 u8 tslock = 0;
 u8 unlock = 0;
 struct cxd2841er_priv *priv = fe->demodulator_priv;

 *status = 0;
 if (priv->state == STATE_ACTIVE_TC) {
  if (priv->system == SYS_DVBT || priv->system == SYS_DVBT2) {
   ret = cxd2841er_read_status_t_t2(
    priv, &sync, &tslock, &unlock);
   if (ret)
    goto done;
   if (unlock)
    goto done;
   if (sync)
    *status = FE_HAS_SIGNAL |
     FE_HAS_CARRIER |
     FE_HAS_VITERBI |
     FE_HAS_SYNC;
   if (tslock)
    *status |= FE_HAS_LOCK;
  } else if (priv->system == SYS_ISDBT) {
   ret = cxd2841er_read_status_i(
     priv, &sync, &tslock, &unlock);
   if (ret)
    goto done;
   if (unlock)
    goto done;
   if (sync)
    *status = FE_HAS_SIGNAL |
     FE_HAS_CARRIER |
     FE_HAS_VITERBI |
     FE_HAS_SYNC;
   if (tslock)
    *status |= FE_HAS_LOCK;
  } else if (priv->system == SYS_DVBC_ANNEX_A) {
   ret = cxd2841er_read_status_c(priv, &tslock);
   if (ret)
    goto done;
   if (tslock)
    *status = FE_HAS_SIGNAL |
     FE_HAS_CARRIER |
     FE_HAS_VITERBI |
     FE_HAS_SYNC |
     FE_HAS_LOCK;
  }
 }
done:
 dev_dbg(&priv->i2c->dev, "%s(): status 0x%x\n", __func__, *status);
 return ret;
}

static int cxd2841er_get_carrier_offset_s_s2(struct cxd2841er_priv *priv,
          int *offset)
{
 u8 data[3];
 u8 is_hs_mode;
 s32 cfrl_ctrlval;
 s32 temp_div, temp_q, temp_r;

 if (priv->state != STATE_ACTIVE_S) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 /*
 * Get High Sampling Rate mode
 *  slave     Bank      Addr      Bit      Signal name
 * <SLV-T>    A0h       10h       [0]      ITRL_LOCK
 */

 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
 cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data[0]);
 if (data[0] & 0x01) {
  /*
 *  slave     Bank      Addr      Bit      Signal name
 * <SLV-T>    A0h       50h       [4]      IHSMODE
 */

  cxd2841er_read_reg(priv, I2C_SLVT, 0x50, &data[0]);
  is_hs_mode = (data[0] & 0x10 ? 1 : 0);
 } else {
  dev_dbg(&priv->i2c->dev,
   "%s(): unable to detect sampling rate mode\n",
   __func__);
  return -EINVAL;
 }
 /*
 *  slave     Bank      Addr      Bit      Signal name
 * <SLV-T>    A0h       45h       [4:0]    ICFRL_CTRLVAL[20:16]
 * <SLV-T>    A0h       46h       [7:0]    ICFRL_CTRLVAL[15:8]
 * <SLV-T>    A0h       47h       [7:0]    ICFRL_CTRLVAL[7:0]
 */

 cxd2841er_read_regs(priv, I2C_SLVT, 0x45, data, 3);
 cfrl_ctrlval = sign_extend32((((u32)data[0] & 0x1F) << 16) |
    (((u32)data[1] & 0xFF) <<  8) |
    ((u32)data[2] & 0xFF), 20);
 temp_div = (is_hs_mode ? 1048576 : 1572864);
 if (cfrl_ctrlval > 0) {
  temp_q = div_s64_rem(97375LL * cfrl_ctrlval,
   temp_div, &temp_r);
 } else {
  temp_q = div_s64_rem(-97375LL * cfrl_ctrlval,
   temp_div, &temp_r);
 }
 if (temp_r >= temp_div / 2)
  temp_q++;
 if (cfrl_ctrlval > 0)
  temp_q *= -1;
 *offset = temp_q;
 return 0;
}

static int cxd2841er_get_carrier_offset_i(struct cxd2841er_priv *priv,
        u32 bandwidth, int *offset)
{
 u8 data[4];

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 if (priv->system != SYS_ISDBT) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
   __func__, priv->system);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data));
 *offset = -1 * sign_extend32(
  ((u32)(data[0] & 0x1F) << 24) | ((u32)data[1] << 16) |
  ((u32)data[2] << 8) | (u32)data[3], 29);

 switch (bandwidth) {
 case 6000000:
  *offset = -1 * ((*offset) * 8/264);
  break;
 case 7000000:
  *offset = -1 * ((*offset) * 8/231);
  break;
 case 8000000:
  *offset = -1 * ((*offset) * 8/198);
  break;
 default:
  dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n",
    __func__, bandwidth);
  return -EINVAL;
 }

 dev_dbg(&priv->i2c->dev, "%s(): bandwidth %d offset %d\n",
   __func__, bandwidth, *offset);

 return 0;
}

static int cxd2841er_get_carrier_offset_t(struct cxd2841er_priv *priv,
        u32 bandwidth, int *offset)
{
 u8 data[4];

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 if (priv->system != SYS_DVBT) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
   __func__, priv->system);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data));
 *offset = -1 * sign_extend32(
  ((u32)(data[0] & 0x1F) << 24) | ((u32)data[1] << 16) |
  ((u32)data[2] << 8) | (u32)data[3], 29);
 *offset *= (bandwidth / 1000000);
 *offset /= 235;
 return 0;
}

static int cxd2841er_get_carrier_offset_t2(struct cxd2841er_priv *priv,
        u32 bandwidth, int *offset)
{
 u8 data[4];

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 if (priv->system != SYS_DVBT2) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
   __func__, priv->system);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data));
 *offset = -1 * sign_extend32(
  ((u32)(data[0] & 0x0F) << 24) | ((u32)data[1] << 16) |
  ((u32)data[2] << 8) | (u32)data[3], 27);
 switch (bandwidth) {
 case 1712000:
  *offset /= 582;
  break;
 case 5000000:
 case 6000000:
 case 7000000:
 case 8000000:
  *offset *= (bandwidth / 1000000);
  *offset /= 940;
  break;
 default:
  dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n",
   __func__, bandwidth);
  return -EINVAL;
 }
 return 0;
}

static int cxd2841er_get_carrier_offset_c(struct cxd2841er_priv *priv,
       int *offset)
{
 u8 data[2];

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 if (priv->system != SYS_DVBC_ANNEX_A) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
   __func__, priv->system);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x15, data, sizeof(data));
 *offset = div_s64(41000LL * sign_extend32((((u32)data[0] & 0x3f) << 8)
      | (u32)data[1], 13), 16384);
 return 0;
}

static int cxd2841er_read_packet_errors_c(
  struct cxd2841er_priv *priv, u32 *penum)
{
 u8 data[3];

 *penum = 0;
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
    __func__, priv->state);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
 cxd2841er_read_regs(priv, I2C_SLVT, 0xea, data, sizeof(data));
 if (data[2] & 0x01)
  *penum = ((u32)data[0] << 8) | (u32)data[1];
 return 0;
}

static int cxd2841er_read_packet_errors_t(
  struct cxd2841er_priv *priv, u32 *penum)
{
 u8 data[3];

 *penum = 0;
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
 cxd2841er_read_regs(priv, I2C_SLVT, 0xea, data, sizeof(data));
 if (data[2] & 0x01)
  *penum = ((u32)data[0] << 8) | (u32)data[1];
 return 0;
}

static int cxd2841er_read_packet_errors_t2(
  struct cxd2841er_priv *priv, u32 *penum)
{
 u8 data[3];

 *penum = 0;
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
   __func__, priv->state);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x24);
 cxd2841er_read_regs(priv, I2C_SLVT, 0xfd, data, sizeof(data));
 if (data[0] & 0x01)
  *penum = ((u32)data[1] << 8) | (u32)data[2];
 return 0;
}

static int cxd2841er_read_packet_errors_i(
  struct cxd2841er_priv *priv, u32 *penum)
{
 u8 data[2];

 *penum = 0;
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
    __func__, priv->state);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
 cxd2841er_read_regs(priv, I2C_SLVT, 0xA1, data, 1);

 if (!(data[0] & 0x01))
  return 0;

 /* Layer A */
 cxd2841er_read_regs(priv, I2C_SLVT, 0xA2, data, sizeof(data));
 *penum = ((u32)data[0] << 8) | (u32)data[1];

 /* Layer B */
 cxd2841er_read_regs(priv, I2C_SLVT, 0xA4, data, sizeof(data));
 *penum += ((u32)data[0] << 8) | (u32)data[1];

 /* Layer C */
 cxd2841er_read_regs(priv, I2C_SLVT, 0xA6, data, sizeof(data));
 *penum += ((u32)data[0] << 8) | (u32)data[1];

 return 0;
}

static int cxd2841er_read_ber_c(struct cxd2841er_priv *priv,
  u32 *bit_error, u32 *bit_count)
{
 u8 data[3];
 u32 bit_err, period_exp;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
    __func__, priv->state);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x62, data, sizeof(data));
 if (!(data[0] & 0x80)) {
  dev_dbg(&priv->i2c->dev,
    "%s(): no valid BER data\n", __func__);
  return -EINVAL;
 }
 bit_err = ((u32)(data[0] & 0x3f) << 16) |
  ((u32)data[1] << 8) |
  (u32)data[2];
 cxd2841er_read_reg(priv, I2C_SLVT, 0x60, data);
 period_exp = data[0] & 0x1f;

 if ((period_exp <= 11) && (bit_err > (1 << period_exp) * 204 * 8)) {
  dev_dbg(&priv->i2c->dev,
    "%s(): period_exp(%u) or bit_err(%u) not in range. no valid BER data\n",
    __func__, period_exp, bit_err);
  return -EINVAL;
 }

 dev_dbg(&priv->i2c->dev,
   "%s(): period_exp(%u) or bit_err(%u) count=%d\n",
   __func__, period_exp, bit_err,
   ((1 << period_exp) * 204 * 8));

 *bit_error = bit_err;
 *bit_count = ((1 << period_exp) * 204 * 8);

 return 0;
}

static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv,
  u32 *bit_error, u32 *bit_count)
{
 u8 data[3];
 u8 pktnum[2];

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
    __func__, priv->state);
  return -EINVAL;
 }

 cxd2841er_freeze_regs(priv);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x5B, pktnum, sizeof(pktnum));
 cxd2841er_read_regs(priv, I2C_SLVT, 0x16, data, sizeof(data));
 cxd2841er_unfreeze_regs(priv);

 if (!pktnum[0] && !pktnum[1]) {
  dev_dbg(&priv->i2c->dev,
    "%s(): no valid BER data\n", __func__);
  return -EINVAL;
 }

 *bit_error = ((u32)(data[0] & 0x7F) << 16) |
  ((u32)data[1] << 8) | data[2];
 *bit_count = ((((u32)pktnum[0] << 8) | pktnum[1]) * 204 * 8);
 dev_dbg(&priv->i2c->dev, "%s(): bit_error=%u bit_count=%u\n",
   __func__, *bit_error, *bit_count);

 return 0;
}

static int cxd2841er_mon_read_ber_s(struct cxd2841er_priv *priv,
        u32 *bit_error, u32 *bit_count)
{
 u8 data[11];

 /* Set SLV-T Bank : 0xA0 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
 /*
 *  slave     Bank      Addr      Bit      Signal name
 * <SLV-T>    A0h       35h       [0]      IFVBER_VALID
 * <SLV-T>    A0h       36h       [5:0]    IFVBER_BITERR[21:16]
 * <SLV-T>    A0h       37h       [7:0]    IFVBER_BITERR[15:8]
 * <SLV-T>    A0h       38h       [7:0]    IFVBER_BITERR[7:0]
 * <SLV-T>    A0h       3Dh       [5:0]    IFVBER_BITNUM[21:16]
 * <SLV-T>    A0h       3Eh       [7:0]    IFVBER_BITNUM[15:8]
 * <SLV-T>    A0h       3Fh       [7:0]    IFVBER_BITNUM[7:0]
 */

 cxd2841er_read_regs(priv, I2C_SLVT, 0x35, data, 11);
 if (data[0] & 0x01) {
  *bit_error = ((u32)(data[1]  & 0x3F) << 16) |
        ((u32)(data[2]  & 0xFF) <<  8) |
        (u32)(data[3]  & 0xFF);
  *bit_count = ((u32)(data[8]  & 0x3F) << 16) |
        ((u32)(data[9]  & 0xFF) <<  8) |
        (u32)(data[10] & 0xFF);
  if ((*bit_count == 0) || (*bit_error > *bit_count)) {
   dev_dbg(&priv->i2c->dev,
    "%s(): invalid bit_error %d, bit_count %d\n",
    __func__, *bit_error, *bit_count);
   return -EINVAL;
  }
  return 0;
 }
 dev_dbg(&priv->i2c->dev, "%s(): no data available\n", __func__);
 return -EINVAL;
}


static int cxd2841er_mon_read_ber_s2(struct cxd2841er_priv *priv,
         u32 *bit_error, u32 *bit_count)
{
 u8 data[5];
 u32 period;

 /* Set SLV-T Bank : 0xB2 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xb2);
 /*
 *  slave     Bank      Addr      Bit      Signal name
 * <SLV-T>    B2h       30h       [0]      IFLBER_VALID
 * <SLV-T>    B2h       31h       [3:0]    IFLBER_BITERR[27:24]
 * <SLV-T>    B2h       32h       [7:0]    IFLBER_BITERR[23:16]
 * <SLV-T>    B2h       33h       [7:0]    IFLBER_BITERR[15:8]
 * <SLV-T>    B2h       34h       [7:0]    IFLBER_BITERR[7:0]
 */

 cxd2841er_read_regs(priv, I2C_SLVT, 0x30, data, 5);
 if (data[0] & 0x01) {
  /* Bit error count */
  *bit_error = ((u32)(data[1] & 0x0F) << 24) |
        ((u32)(data[2] & 0xFF) << 16) |
        ((u32)(data[3] & 0xFF) <<  8) |
        (u32)(data[4] & 0xFF);

  /* Set SLV-T Bank : 0xA0 */
  cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
  cxd2841er_read_reg(priv, I2C_SLVT, 0x7a, data);
  /* Measurement period */
  period = (u32)(1 << (data[0] & 0x0F));
  if (period == 0) {
   dev_dbg(&priv->i2c->dev,
    "%s(): period is 0\n", __func__);
   return -EINVAL;
  }
  if (*bit_error > (period * 64800)) {
   dev_dbg(&priv->i2c->dev,
    "%s(): invalid bit_err 0x%x period 0x%x\n",
    __func__, *bit_error, period);
   return -EINVAL;
  }
  *bit_count = period * 64800;

  return 0;
 } else {
  dev_dbg(&priv->i2c->dev,
   "%s(): no data available\n", __func__);
 }
 return -EINVAL;
}

static int cxd2841er_read_ber_t2(struct cxd2841er_priv *priv,
     u32 *bit_error, u32 *bit_count)
{
 u8 data[4];
 u32 period_exp, n_ldpc;

 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev,
   "%s(): invalid state %d\n", __func__, priv->state);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x39, data, sizeof(data));
 if (!(data[0] & 0x10)) {
  dev_dbg(&priv->i2c->dev,
   "%s(): no valid BER data\n", __func__);
  return -EINVAL;
 }
 *bit_error = ((u32)(data[0] & 0x0f) << 24) |
       ((u32)data[1] << 16) |
       ((u32)data[2] << 8) |
       (u32)data[3];
 cxd2841er_read_reg(priv, I2C_SLVT, 0x6f, data);
 period_exp = data[0] & 0x0f;
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x22);
 cxd2841er_read_reg(priv, I2C_SLVT, 0x5e, data);
 n_ldpc = ((data[0] & 0x03) == 0 ? 16200 : 64800);
 if (*bit_error > ((1U << period_exp) * n_ldpc)) {
  dev_dbg(&priv->i2c->dev,
   "%s(): invalid BER value\n", __func__);
  return -EINVAL;
 }

 /*
 * FIXME: the right thing would be to return bit_error untouched,
 * but, as we don't know the scale returned by the counters, let's
 * at least preserver BER = bit_error/bit_count.
 */

 if (period_exp >= 4) {
  *bit_count = (1U << (period_exp - 4)) * (n_ldpc / 200);
  *bit_error *= 3125ULL;
 } else {
  *bit_count = (1U << period_exp) * (n_ldpc / 200);
  *bit_error *= 50000ULL;
 }
 return 0;
}

static int cxd2841er_read_ber_t(struct cxd2841er_priv *priv,
    u32 *bit_error, u32 *bit_count)
{
 u8 data[2];
 u32 period;

 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev,
   "%s(): invalid state %d\n", __func__, priv->state);
  return -EINVAL;
 }
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
 cxd2841er_read_reg(priv, I2C_SLVT, 0x39, data);
 if (!(data[0] & 0x01)) {
  dev_dbg(&priv->i2c->dev,
   "%s(): no valid BER data\n", __func__);
  return 0;
 }
 cxd2841er_read_regs(priv, I2C_SLVT, 0x22, data, sizeof(data));
 *bit_error = ((u32)data[0] << 8) | (u32)data[1];
 cxd2841er_read_reg(priv, I2C_SLVT, 0x6f, data);
 period = ((data[0] & 0x07) == 0) ? 256 : (4096 << (data[0] & 0x07));

 /*
 * FIXME: the right thing would be to return bit_error untouched,
 * but, as we don't know the scale returned by the counters, let's
 * at least preserver BER = bit_error/bit_count.
 */

 *bit_count = period / 128;
 *bit_error *= 78125ULL;
 return 0;
}

static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv)
{
 /*
 * Freeze registers: ensure multiple separate register reads
 * are from the same snapshot
 */

 cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01);
 return 0;
}

static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv)
{
 /*
 * un-freeze registers
 */

 cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x00);
 return 0;
}

static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
  u8 delsys, u32 *snr)
{
 u8 data[3];
 u32 res = 0, value;
 int min_index, max_index, index;
 static const struct cxd2841er_cnr_data *cn_data;

 cxd2841er_freeze_regs(priv);
 /* Set SLV-T Bank : 0xA1 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa1);
 /*
 *  slave     Bank      Addr      Bit     Signal name
 * <SLV-T>    A1h       10h       [0]     ICPM_QUICKRDY
 * <SLV-T>    A1h       11h       [4:0]   ICPM_QUICKCNDT[12:8]
 * <SLV-T>    A1h       12h       [7:0]   ICPM_QUICKCNDT[7:0]
 */

 cxd2841er_read_regs(priv, I2C_SLVT, 0x10, data, 3);
 cxd2841er_unfreeze_regs(priv);

 if (data[0] & 0x01) {
  value = ((u32)(data[1] & 0x1F) << 8) | (u32)(data[2] & 0xFF);
  min_index = 0;
  if (delsys == SYS_DVBS) {
   cn_data = s_cn_data;
   max_index = ARRAY_SIZE(s_cn_data) - 1;
  } else {
   cn_data = s2_cn_data;
   max_index = ARRAY_SIZE(s2_cn_data) - 1;
  }
  if (value >= cn_data[min_index].value) {
   res = cn_data[min_index].cnr_x1000;
   goto done;
  }
  if (value <= cn_data[max_index].value) {
   res = cn_data[max_index].cnr_x1000;
   goto done;
  }
  while ((max_index - min_index) > 1) {
   index = (max_index + min_index) / 2;
   if (value == cn_data[index].value) {
    res = cn_data[index].cnr_x1000;
    goto done;
   } else if (value > cn_data[index].value)
    max_index = index;
   else
    min_index = index;
   if ((max_index - min_index) <= 1) {
    if (value == cn_data[max_index].value) {
     res = cn_data[max_index].cnr_x1000;
     goto done;
    } else {
     res = cn_data[min_index].cnr_x1000;
     goto done;
    }
   }
  }
 } else {
  dev_dbg(&priv->i2c->dev,
   "%s(): no data available\n", __func__);
  return -EINVAL;
 }
done:
 *snr = res;
 return 0;
}

static uint32_t sony_log(uint32_t x)
{
 return (((10000>>8)*(intlog2(x)>>16) + LOG2_E_100X/2)/LOG2_E_100X);
}

static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
{
 u32 reg;
 u8 data[2];
 enum sony_dvbc_constellation_t qam = SONY_DVBC_CONSTELLATION_16QAM;

 *snr = 0;
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev,
    "%s(): invalid state %d\n",
    __func__, priv->state);
  return -EINVAL;
 }

 cxd2841er_freeze_regs(priv);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1);
 qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x4C, data, 2);
 cxd2841er_unfreeze_regs(priv);

 reg = ((u32)(data[0]&0x1f) << 8) | (u32)data[1];
 if (reg == 0) {
  dev_dbg(&priv->i2c->dev,
    "%s(): reg value out of range\n", __func__);
  return 0;
 }

 switch (qam) {
 case SONY_DVBC_CONSTELLATION_16QAM:
 case SONY_DVBC_CONSTELLATION_64QAM:
 case SONY_DVBC_CONSTELLATION_256QAM:
  /* SNR(dB) = -9.50 * ln(IREG_SNR_ESTIMATE / (24320)) */
  if (reg < 126)
   reg = 126;
  *snr = -95 * (int32_t)sony_log(reg) + 95941;
  break;
 case SONY_DVBC_CONSTELLATION_32QAM:
 case SONY_DVBC_CONSTELLATION_128QAM:
  /* SNR(dB) = -8.75 * ln(IREG_SNR_ESTIMATE / (20800)) */
  if (reg < 69)
   reg = 69;
  *snr = -88 * (int32_t)sony_log(reg) + 86999;
  break;
 default:
  return -EINVAL;
 }

 return 0;
}

static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
{
 u32 reg;
 u8 data[2];

 *snr = 0;
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev,
   "%s(): invalid state %d\n", __func__, priv->state);
  return -EINVAL;
 }

 cxd2841er_freeze_regs(priv);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
 cxd2841er_unfreeze_regs(priv);

 reg = ((u32)data[0] << 8) | (u32)data[1];
 if (reg == 0) {
  dev_dbg(&priv->i2c->dev,
   "%s(): reg value out of range\n", __func__);
  return 0;
 }
 if (reg > 4996)
  reg = 4996;
 *snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(5350 - reg)) + 285);
 return 0;
}

static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr)
{
 u32 reg;
 u8 data[2];

 *snr = 0;
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev,
   "%s(): invalid state %d\n", __func__, priv->state);
  return -EINVAL;
 }

 cxd2841er_freeze_regs(priv);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
 cxd2841er_unfreeze_regs(priv);

 reg = ((u32)data[0] << 8) | (u32)data[1];
 if (reg == 0) {
  dev_dbg(&priv->i2c->dev,
   "%s(): reg value out of range\n", __func__);
  return 0;
 }
 if (reg > 10876)
  reg = 10876;
 *snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(12600 - reg)) + 320);
 return 0;
}

static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr)
{
 u32 reg;
 u8 data[2];

 *snr = 0;
 if (priv->state != STATE_ACTIVE_TC) {
  dev_dbg(&priv->i2c->dev,
    "%s(): invalid state %d\n", __func__,
    priv->state);
  return -EINVAL;
 }

 cxd2841er_freeze_regs(priv);
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
 cxd2841er_unfreeze_regs(priv);

 reg = ((u32)data[0] << 8) | (u32)data[1];
 if (reg == 0) {
  dev_dbg(&priv->i2c->dev,
    "%s(): reg value out of range\n", __func__);
  return 0;
 }
 *snr = 10000 * (intlog10(reg) >> 24) - 9031;
 return 0;
}

static u16 cxd2841er_read_agc_gain_c(struct cxd2841er_priv *priv,
     u8 delsys)
{
 u8 data[2];

 cxd2841er_write_reg(
  priv, I2C_SLVT, 0x00, 0x40);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x49, data, 2);
 dev_dbg(&priv->i2c->dev,
   "%s(): AGC value=%u\n",
   __func__, (((u16)data[0] & 0x0F) << 8) |
   (u16)(data[1] & 0xFF));
 return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4;
}

static u16 cxd2841er_read_agc_gain_t_t2(struct cxd2841er_priv *priv,
     u8 delsys)
{
 u8 data[2];

 cxd2841er_write_reg(
  priv, I2C_SLVT, 0x00, (delsys == SYS_DVBT ? 0x10 : 0x20));
 cxd2841er_read_regs(priv, I2C_SLVT, 0x26, data, 2);
 dev_dbg(&priv->i2c->dev,
   "%s(): AGC value=%u\n",
   __func__, (((u16)data[0] & 0x0F) << 8) |
   (u16)(data[1] & 0xFF));
 return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4;
}

static u16 cxd2841er_read_agc_gain_i(struct cxd2841er_priv *priv,
  u8 delsys)
{
 u8 data[2];

 cxd2841er_write_reg(
   priv, I2C_SLVT, 0x00, 0x60);
 cxd2841er_read_regs(priv, I2C_SLVT, 0x26, data, 2);

 dev_dbg(&priv->i2c->dev,
   "%s(): AGC value=%u\n",
   __func__, (((u16)data[0] & 0x0F) << 8) |
   (u16)(data[1] & 0xFF));
 return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4;
}

static u16 cxd2841er_read_agc_gain_s(struct cxd2841er_priv *priv)
{
 u8 data[2];

 /* Set SLV-T Bank : 0xA0 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
 /*
 *  slave     Bank      Addr      Bit       Signal name
 * <SLV-T>    A0h       1Fh       [4:0]     IRFAGC_GAIN[12:8]
 * <SLV-T>    A0h       20h       [7:0]     IRFAGC_GAIN[7:0]
 */

 cxd2841er_read_regs(priv, I2C_SLVT, 0x1f, data, 2);
 return ((((u16)data[0] & 0x1F) << 8) | (u16)(data[1] & 0xFF)) << 3;
}

static void cxd2841er_read_ber(struct dvb_frontend *fe)
{
 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 struct cxd2841er_priv *priv = fe->demodulator_priv;
 u32 ret, bit_error = 0, bit_count = 0;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 switch (p->delivery_system) {
 case SYS_DVBC_ANNEX_A:
 case SYS_DVBC_ANNEX_B:
 case SYS_DVBC_ANNEX_C:
  ret = cxd2841er_read_ber_c(priv, &bit_error, &bit_count);
  break;
 case SYS_ISDBT:
  ret = cxd2841er_read_ber_i(priv, &bit_error, &bit_count);
  break;
 case SYS_DVBS:
  ret = cxd2841er_mon_read_ber_s(priv, &bit_error, &bit_count);
  break;
 case SYS_DVBS2:
  ret = cxd2841er_mon_read_ber_s2(priv, &bit_error, &bit_count);
  break;
 case SYS_DVBT:
  ret = cxd2841er_read_ber_t(priv, &bit_error, &bit_count);
  break;
 case SYS_DVBT2:
  ret = cxd2841er_read_ber_t2(priv, &bit_error, &bit_count);
  break;
 default:
  p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  return;
 }

 if (!ret) {
  p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
  p->post_bit_error.stat[0].uvalue += bit_error;
  p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
  p->post_bit_count.stat[0].uvalue += bit_count;
 } else {
  p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
 }
}

static void cxd2841er_read_signal_strength(struct dvb_frontend *fe)
{
 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 struct cxd2841er_priv *priv = fe->demodulator_priv;
 s32 strength;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 switch (p->delivery_system) {
 case SYS_DVBT:
 case SYS_DVBT2:
  strength = cxd2841er_read_agc_gain_t_t2(priv,
       p->delivery_system);
  p->strength.stat[0].scale = FE_SCALE_DECIBEL;
  /* Formula was empirically determinated @ 410 MHz */
  p->strength.stat[0].uvalue = strength * 366 / 100 - 89520;
  break/* Code moved out of the function */
 case SYS_DVBC_ANNEX_A:
 case SYS_DVBC_ANNEX_B:
 case SYS_DVBC_ANNEX_C:
  strength = cxd2841er_read_agc_gain_c(priv,
       p->delivery_system);
  p->strength.stat[0].scale = FE_SCALE_DECIBEL;
  /*
 * Formula was empirically determinated via linear regression,
 * using frequencies: 175 MHz, 410 MHz and 800 MHz, and a
 * stream modulated with QAM64
 */

  p->strength.stat[0].uvalue = strength * 4045 / 1000 - 85224;
  break;
 case SYS_ISDBT:
  strength = cxd2841er_read_agc_gain_i(priv, p->delivery_system);
  p->strength.stat[0].scale = FE_SCALE_DECIBEL;
  /*
 * Formula was empirically determinated via linear regression,
 * using frequencies: 175 MHz, 410 MHz and 800 MHz.
 */

  p->strength.stat[0].uvalue = strength * 3775 / 1000 - 90185;
  break;
 case SYS_DVBS:
 case SYS_DVBS2:
  strength = 65535 - cxd2841er_read_agc_gain_s(priv);
  p->strength.stat[0].scale = FE_SCALE_RELATIVE;
  p->strength.stat[0].uvalue = strength;
  break;
 default:
  p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  break;
 }
}

static void cxd2841er_read_snr(struct dvb_frontend *fe)
{
 u32 tmp = 0;
 int ret = 0;
 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 struct cxd2841er_priv *priv = fe->demodulator_priv;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 switch (p->delivery_system) {
 case SYS_DVBC_ANNEX_A:
 case SYS_DVBC_ANNEX_B:
 case SYS_DVBC_ANNEX_C:
  ret = cxd2841er_read_snr_c(priv, &tmp);
  break;
 case SYS_DVBT:
  ret = cxd2841er_read_snr_t(priv, &tmp);
  break;
 case SYS_DVBT2:
  ret = cxd2841er_read_snr_t2(priv, &tmp);
  break;
 case SYS_ISDBT:
  ret = cxd2841er_read_snr_i(priv, &tmp);
  break;
 case SYS_DVBS:
 case SYS_DVBS2:
  ret = cxd2841er_dvbs_read_snr(priv, p->delivery_system, &tmp);
  break;
 default:
  dev_dbg(&priv->i2c->dev, "%s(): unknown delivery system %d\n",
   __func__, p->delivery_system);
  p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  return;
 }

 dev_dbg(&priv->i2c->dev, "%s(): snr=%d\n",
   __func__, (int32_t)tmp);

 if (!ret) {
  p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
  p->cnr.stat[0].svalue = tmp;
 } else {
  p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
 }
}

static void cxd2841er_read_ucblocks(struct dvb_frontend *fe)
{
 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
 struct cxd2841er_priv *priv = fe->demodulator_priv;
 u32 ucblocks = 0;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 switch (p->delivery_system) {
 case SYS_DVBC_ANNEX_A:
 case SYS_DVBC_ANNEX_B:
 case SYS_DVBC_ANNEX_C:
  cxd2841er_read_packet_errors_c(priv, &ucblocks);
  break;
 case SYS_DVBT:
  cxd2841er_read_packet_errors_t(priv, &ucblocks);
  break;
 case SYS_DVBT2:
  cxd2841er_read_packet_errors_t2(priv, &ucblocks);
  break;
 case SYS_ISDBT:
  cxd2841er_read_packet_errors_i(priv, &ucblocks);
  break;
 default:
  p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
  return;
 }
 dev_dbg(&priv->i2c->dev, "%s() ucblocks=%u\n", __func__, ucblocks);

 p->block_error.stat[0].scale = FE_SCALE_COUNTER;
 p->block_error.stat[0].uvalue = ucblocks;
}

static int cxd2841er_dvbt2_set_profile(
 struct cxd2841er_priv *priv, enum cxd2841er_dvbt2_profile_t profile)
{
 u8 tune_mode;
 u8 seq_not2d_time;

 dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
 switch (profile) {
 case DVBT2_PROFILE_BASE:
  tune_mode = 0x01;
  /* Set early unlock time */
  seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x0E:0x0C;
  break;
 case DVBT2_PROFILE_LITE:
  tune_mode = 0x05;
  /* Set early unlock time */
  seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28;
  break;
 case DVBT2_PROFILE_ANY:
  tune_mode = 0x00;
  /* Set early unlock time */
  seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28;
  break;
 default:
  return -EINVAL;
 }
 /* Set SLV-T Bank : 0x2E */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2e);
 /* Set profile and tune mode */
 cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x10, tune_mode, 0x07);
 /* Set SLV-T Bank : 0x2B */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b);
 /* Set early unlock detection time */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x9d, seq_not2d_time);
 return 0;
}

static int cxd2841er_dvbt2_set_plp_config(struct cxd2841er_priv *priv,
       u8 is_auto, u8 plp_id)
{
 if (is_auto) {
  dev_dbg(&priv->i2c->dev,
   "%s() using auto PLP selection\n", __func__);
 } else {
  dev_dbg(&priv->i2c->dev,
   "%s() using manual PLP selection, ID %d\n",
   __func__, plp_id);
 }
 /* Set SLV-T Bank : 0x23 */
 cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x23);
 if (!is_auto) {
  /* Manual PLP selection mode. Set the data PLP Id. */
  cxd2841er_write_reg(priv, I2C_SLVT, 0xaf, plp_id);
 }
 /* Auto PLP select (Scanning mode = 0x00). Data PLP select = 0x01. */
 cxd2841er_write_reg(priv, I2C_SLVT, 0xad, (is_auto ? 0x00 : 0x01));
 return 0;
}

static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
      u32 bandwidth)
{
 u32 iffreq, ifhz;
 u8 data[MAX_WRITE_REGSIZE];

 static const uint8_t nominalRate8bw[3][5] = {
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=92 H=95 G=93

¤ Dauer der Verarbeitung: 0.30 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.