From 798568a771c6ad59a3b20ba159d215d4304da1d4 Mon Sep 17 00:00:00 2001 From: Alex Deryskyba Date: Sun, 2 Oct 2016 12:06:03 +0200 Subject: [PATCH] projects/WeTek_Play_2: Update DVB patch - allow switching between DVB-T and DVB-T2 muxes --- .../patches/linux/wetek_dvb.patch | 3533 +++++++++++++---- 1 file changed, 2806 insertions(+), 727 deletions(-) diff --git a/projects/WeTek_Play_2/patches/linux/wetek_dvb.patch b/projects/WeTek_Play_2/patches/linux/wetek_dvb.patch index 84581aa780..d4ff8d5f4c 100644 --- a/projects/WeTek_Play_2/patches/linux/wetek_dvb.patch +++ b/projects/WeTek_Play_2/patches/linux/wetek_dvb.patch @@ -23726,7 +23726,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/amsmc.h b/drivers/amlogic/dvb_tv/amsmc.h -#endif diff -Naur a/drivers/amlogic/dvb_tv/ascot3.c b/drivers/amlogic/dvb_tv/ascot3.c --- a/drivers/amlogic/dvb_tv/ascot3.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/ascot3.c 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/ascot3.c 2016-09-22 00:39:27.000000000 +0200 @@ -0,0 +1,563 @@ +/* + * ascot3.c @@ -23956,7 +23956,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/ascot3.c b/drivers/amlogic/dvb_tv/ascot3.c + return 0; + + /* Loop Through setting And RFIN matching in Power Save */ -+ ascot3_write_reg(priv, 0x67, 0x00); ++ ascot3_write_reg(priv, 0x67, 0x06); + /* Disable IF signal output (IF_OUT_SEL setting) */ + ascot3_set_reg_bits(priv, 0x74, 0x02, 0x03); + /* Power save setting for analog block */ @@ -24293,7 +24293,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/ascot3.c b/drivers/amlogic/dvb_tv/ascot3.c +MODULE_LICENSE("GPL"); diff -Naur a/drivers/amlogic/dvb_tv/ascot3.h b/drivers/amlogic/dvb_tv/ascot3.h --- a/drivers/amlogic/dvb_tv/ascot3.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/ascot3.h 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/ascot3.h 2016-09-19 19:36:24.000000000 +0200 @@ -0,0 +1,46 @@ +/* + * ascot3.h @@ -24343,7 +24343,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/ascot3.h b/drivers/amlogic/dvb_tv/ascot3.h +#endif diff -Naur a/drivers/amlogic/dvb_tv/avl6211.c b/drivers/amlogic/dvb_tv/avl6211.c --- a/drivers/amlogic/dvb_tv/avl6211.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/avl6211.c 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/avl6211.c 2016-09-19 19:36:24.000000000 +0200 @@ -0,0 +1,1979 @@ +/* + * Driver for the Availink AVL6211+AV2011 DVB-S/S2 demod+tuner @@ -26326,7 +26326,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/avl6211.c b/drivers/amlogic/dvb_tv/avl6211.c +MODULE_LICENSE("GPL"); diff -Naur a/drivers/amlogic/dvb_tv/avl6211.h b/drivers/amlogic/dvb_tv/avl6211.h --- a/drivers/amlogic/dvb_tv/avl6211.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/avl6211.h 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/avl6211.h 2016-09-19 19:36:24.000000000 +0200 @@ -0,0 +1,156 @@ +/* + * Driver for the Availink AVL6211+AV2011 DVB-S/S2 demod+tuner @@ -26487,7 +26487,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/avl6211.h b/drivers/amlogic/dvb_tv/avl6211.h \ No newline at end of file diff -Naur a/drivers/amlogic/dvb_tv/avl6211_reg.h b/drivers/amlogic/dvb_tv/avl6211_reg.h --- a/drivers/amlogic/dvb_tv/avl6211_reg.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/avl6211_reg.h 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/avl6211_reg.h 2016-09-19 19:36:24.000000000 +0200 @@ -0,0 +1,101 @@ +/* + * Driver for the Availink AVL6211+AV2011 DVB-S/S2 demod+tuner @@ -36649,18 +36649,16 @@ diff -Naur a/drivers/amlogic/dvb_tv/c_stb_regs_define.h b/drivers/amlogic/dvb_tv -#define SEC_BLKMV_GEN_REG0 0x24 -#define P_SEC_BLKMV_GEN_REG0 SECBUS3_REG_ADDR(SEC_BLKMV_GEN_REG0) -#endif -diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837er.c ---- a/drivers/amlogic/dvb_tv/cxd2837er.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/cxd2837er.c 2016-06-22 17:39:23.000000000 +0200 -@@ -0,0 +1,1777 @@ +diff -Naur a/drivers/amlogic/dvb_tv/cxd2841er.c b/drivers/amlogic/dvb_tv/cxd2841er.c +--- a/drivers/amlogic/dvb_tv/cxd2841er.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/cxd2841er.c 2016-09-22 15:28:54.000000000 +0200 +@@ -0,0 +1,3812 @@ +/* -+ * cxd2837er.c ++ * cxd2841er.c + * -+ * Sony CXD2837ER digital demodulator driver -+ * -+ * Copyright (C) 2015 Sasa Savic -+ * -+ * Based on CXD2841ER driver ++ * 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. @@ -36689,30 +36687,192 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + +#include "dvb_math.h" +#include "dvb_frontend.h" -+#include "cxd2837er.h" ++#include "cxd2841er.h" ++#include "cxd2841er_priv.h" + +#define MAX_WRITE_REGSIZE 16 ++#define LOG2_E_100X 144 + -+enum cxd2837er_state { ++/* 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 cxd2837er_priv { ++struct cxd2841er_priv { + struct dvb_frontend frontend; + struct i2c_adapter *i2c; + u8 i2c_addr_slvx; + u8 i2c_addr_slvt; -+ const struct cxd2837er_config *config; -+ enum cxd2837er_state state; ++ const struct cxd2841er_config *config; ++ enum cxd2841er_state state; + u8 system; ++ enum cxd2841er_xtal xtal; ++ enum fe_caps caps; +}; + ++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 }, ++}; + +#define MAKE_IFFREQ_CONFIG(iffreq) ((u32)(((iffreq)/41.0)*16777216.0 + 0.5)) ++#define MAKE_IFFREQ_CONFIG_XTAL(xtal, iffreq) ((xtal == SONY_XTAL_24000) ? \ ++ (u32)(((iffreq)/48.0)*16777216.0 + 0.5) : \ ++ (u32)(((iffreq)/41.0)*16777216.0 + 0.5)) + -+static int cxd2837er_write_regs(struct cxd2837er_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\n", ++ (write == 0 ? "read" : "write"), addr, reg, len); ++ print_hex_dump_bytes("cxd2841er: I2C data: ", ++ DUMP_PREFIX_OFFSET, data, len); ++} ++ ++static int cxd2841er_write_regs(struct cxd2841er_priv *priv, + u8 addr, u8 reg, const u8 *data, u32 len) +{ + int ret; @@ -36729,12 +36889,12 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + }; + + if (len + 1 >= sizeof(buf)) { -+ dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n", ++ 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); + @@ -36743,20 +36903,20 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + ret = -EIO; + if (ret < 0) { + dev_warn(&priv->i2c->dev, -+ "i2c wr failed=%d addr=%02x reg=%02x len=%d\n", -+ ret, i2c_addr, reg, len); ++ "%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 cxd2837er_write_reg(struct cxd2837er_priv *priv, ++static int cxd2841er_write_reg(struct cxd2841er_priv *priv, + u8 addr, u8 reg, u8 val) +{ -+ return cxd2837er_write_regs(priv, addr, reg, &val, 1); ++ return cxd2841er_write_regs(priv, addr, reg, &val, 1); +} + -+static int cxd2837er_read_regs(struct cxd2837er_priv *priv, ++static int cxd2841er_read_regs(struct cxd2841er_priv *priv, + u8 addr, u8 reg, u8 *val, u32 len) +{ + int ret; @@ -36781,8 +36941,8 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + ret = -EIO; + if (ret < 0) { + dev_warn(&priv->i2c->dev, -+ "i2c rw failed=%d addr=%02x reg=%02x\n", -+ ret, i2c_addr, reg); ++ "%s: i2c rw failed=%d addr=%02x reg=%02x\n", ++ KBUILD_MODNAME, ret, i2c_addr, reg); + return ret; + } + ret = i2c_transfer(priv->i2c, &msg[1], 1); @@ -36790,70 +36950,201 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + ret = -EIO; + if (ret < 0) { + dev_warn(&priv->i2c->dev, -+ "i2c rd failed=%d addr=%02x reg=%02x\n", -+ ret, i2c_addr, reg); ++ "%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 cxd2837er_read_reg(struct cxd2837er_priv *priv, ++static int cxd2841er_read_reg(struct cxd2841er_priv *priv, + u8 addr, u8 reg, u8 *val) +{ -+ return cxd2837er_read_regs(priv, addr, reg, val, 1); ++ return cxd2841er_read_regs(priv, addr, reg, val, 1); +} + -+static int cxd2837er_set_reg_bits(struct cxd2837er_priv *priv, ++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 = cxd2837er_read_reg(priv, addr, reg, &rdata); ++ res = cxd2841er_read_reg(priv, addr, reg, &rdata); + if (res) + return res; + data = ((data & mask) | (rdata & (mask ^ 0xFF))); + } -+ return cxd2837er_write_reg(priv, addr, reg, data); ++ return cxd2841er_write_reg(priv, addr, reg, data); +} + -+static void cxd2837er_set_ts_clock_mode(struct cxd2837er_priv *priv, ++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 cxd2837er_sleep_tc_to_active_t_band(struct cxd2837er_priv *priv, ++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_init_tc(struct dvb_frontend *fe); ++ ++static int cxd2841er_sleep_tc_to_active_t_band(struct cxd2841er_priv *priv, + u32 bandwidth); + -+static int cxd2837er_sleep_tc_to_active_t2_band(struct cxd2837er_priv *priv, ++static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv, + u32 bandwidth); + -+static int cxd2837er_sleep_tc_to_active_c_band(struct cxd2837er_priv *priv, ++static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv, + u32 bandwidth); + -+static int cxd2837er_retune_active(struct cxd2837er_priv *priv, ++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_retune_active(struct cxd2841er_priv *priv, + struct dtv_frontend_properties *p) +{ + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ if (priv->state != STATE_ACTIVE_TC) { ++ 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 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* disable TS output */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); -+ if (priv->state == STATE_ACTIVE_TC) { ++ 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 cxd2837er_sleep_tc_to_active_t_band( ++ return cxd2841er_sleep_tc_to_active_t_band( + priv, p->bandwidth_hz); + case SYS_DVBT2: -+ return cxd2837er_sleep_tc_to_active_t2_band( ++ return cxd2841er_sleep_tc_to_active_t2_band( + priv, p->bandwidth_hz); + case SYS_DVBC_ANNEX_A: -+ return cxd2837er_sleep_tc_to_active_c_band( -+ priv, 8000000); ++ 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", @@ -36861,7 +37152,75 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return -EINVAL; +} + -+static int cxd2837er_sleep_tc_to_shutdown(struct cxd2837er_priv *priv) ++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) { @@ -36870,16 +37229,16 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return -EINVAL; + } + /* Set SLV-X Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); + /* Disable oscillator */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x15, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x15, 0x01); + /* Set demod mode */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x17, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01); + priv->state = STATE_SHUTDOWN; + return 0; +} + -+static int cxd2837er_active_t_to_sleep_tc(struct cxd2837er_priv *priv) ++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) { @@ -36888,34 +37247,34 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return -EINVAL; + } + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* disable TS output */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); + /* enable Hi-Z setting 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); + /* enable Hi-Z setting 2 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x81, 0xff); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff); + /* Set SLV-X Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); + /* disable ADC 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x18, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* Disable ADC 2 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); + /* Disable ADC 3 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); + /* Disable ADC clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x30, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); + /* Disable RF level monitor */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); + /* Disable demod clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); + priv->state = STATE_SLEEP_TC; + return 0; +} + -+static int cxd2837er_active_t2_to_sleep_tc(struct cxd2837er_priv *priv) ++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) { @@ -36924,44 +37283,44 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return -EINVAL; + } + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* disable TS output */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); + /* enable Hi-Z setting 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); + /* enable Hi-Z setting 2 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x81, 0xff); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff); + /* Cancel DVB-T2 setting */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x13); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x83, 0x40); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x86, 0x21); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x9e, 0x09, 0x0f); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x9f, 0xfb); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x2a); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x38, 0x00, 0x0f); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x00, 0x3f); ++ 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 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); + /* disable ADC 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x18, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* Disable ADC 2 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); + /* Disable ADC 3 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); + /* Disable ADC clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x30, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); + /* Disable RF level monitor */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); + /* Disable demod clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); + priv->state = STATE_SLEEP_TC; + return 0; +} + -+static int cxd2837er_active_c_to_sleep_tc(struct cxd2837er_priv *priv) ++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) { @@ -36970,39 +37329,77 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return -EINVAL; + } + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* disable TS output */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); + /* enable Hi-Z setting 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); + /* enable Hi-Z setting 2 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x81, 0xff); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff); + /* Cancel DVB-C setting */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x11); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xa3, 0x00, 0x1f); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa3, 0x00, 0x1f); + /* Set SLV-X Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); + /* disable ADC 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x18, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* Disable ADC 2 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); + /* Disable ADC 3 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); + /* Disable ADC clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x30, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); + /* Disable RF level monitor */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); + /* Disable demod clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); + priv->state = STATE_SLEEP_TC; + return 0; +} + -+static int cxd2837er_shutdown_to_sleep_tc(struct cxd2837er_priv *priv) ++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) +{ -+ u8 data[2] = { 0x00, 0x00 }; + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + if (priv->state != STATE_SHUTDOWN) { + dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n", @@ -37010,53 +37407,132 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return -EINVAL; + } + /* Set SLV-X Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); + /* Clear all demodulator registers */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x02, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x02, 0x00); + usleep_range(3000, 5000); + /* Set SLV-X Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); + /* Set demod SW reset */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x10, 0x01); -+ /* Set X'tal clock to 20.5Mhz */ -+ cxd2837er_write_regs(priv, I2C_SLVX, 0x13, data, 2); ++ 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 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x10, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x00); + usleep_range(1000, 2000); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 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 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); ++ 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 cxd2837er_tune_done(struct cxd2837er_priv *priv) ++static int cxd2841er_tune_done(struct cxd2841er_priv *priv) +{ + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0, 0); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0, 0); + /* SW Reset */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xfe, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xfe, 0x01); + /* Enable TS output */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xc3, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x00); + return 0; +} + +/* Set TS parallel mode */ -+static void cxd2837er_set_ts_clock_mode(struct cxd2837er_priv *priv, ++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 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); -+ cxd2837er_read_reg(priv, I2C_SLVT, 0xc4, &serial_ts); -+ cxd2837er_read_reg(priv, I2C_SLVT, 0xd3, &ts_rate_ctrl_off); -+ cxd2837er_read_reg(priv, I2C_SLVT, 0xde, &ts_in_off); ++ 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); + @@ -37064,47 +37540,81 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + * slave Bank Addr Bit default Name + * 00h D9h [7:0] 8'h08 OTSCKPERIOD + */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xd9, 0x08); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xd9, 0x08); + /* + * Disable TS IF Clock + * slave Bank Addr Bit default Name + * 00h 32h [0] 1'b1 OREG_CK_TSIF_EN + */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x00, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x00, 0x01); + /* + * slave Bank Addr Bit default Name + * 00h 33h [1:0] 2'b01 OREG_CKSEL_TSIF + */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x33, 0x00, 0x03); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33, 0x00, 0x03); + /* + * Enable TS IF Clock + * slave Bank Addr Bit default Name + * 00h 32h [0] 1'b1 OREG_CK_TSIF_EN + */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x01, 0x01); + + if (system == SYS_DVBT) { + /* Enable parity period for DVB-T */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x66, 0x01, 0x01); ++ 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 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x40); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x66, 0x01, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x66, 0x01, 0x01); + } +} + -+static u8 cxd2837er_chip_id(struct cxd2837er_priv *priv) ++static u8 cxd2841er_chip_id(struct cxd2841er_priv *priv) +{ -+ u8 chip_id; ++ u8 chip_id = 0; + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0, 0); -+ cxd2837er_read_reg(priv, I2C_SLVT, 0xfd, &chip_id); ++ 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 cxd2837er_read_status_t_t2(struct cxd2837er_priv *priv, ++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 ++ * 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; @@ -37114,12 +37624,12 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return -EINVAL; + if (priv->system == SYS_DVBT) { + /* Set SLV-T Bank : 0x10 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); + } else { + /* Set SLV-T Bank : 0x20 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x20); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); + } -+ cxd2837er_read_reg(priv, I2C_SLVT, 0x10, &data); ++ cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data); + if ((data & 0x07) == 0x07) { + dev_dbg(&priv->i2c->dev, + "%s(): invalid hardware state detected\n", __func__); @@ -37134,37 +37644,56 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return 0; +} + -+static int cxd2837er_read_status_c(struct cxd2837er_priv *priv, u8 *tslock) ++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; -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x40); -+ cxd2837er_read_reg(priv, I2C_SLVT, 0x88, &data); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); ++ cxd2841er_read_reg(priv, I2C_SLVT, 0x88, &data); + if ((data & 0x01) == 0) { + *tslock = 0; + } else { -+ cxd2837er_read_reg(priv, I2C_SLVT, 0x10, &data); ++ cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data); + *tslock = ((data & 0x20) ? 1 : 0); + } + return 0; +} + -+static int cxd2837er_read_status_tc(struct dvb_frontend *fe, ++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 cxd2837er_priv *priv = fe->demodulator_priv; ++ 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 = cxd2837er_read_status_t_t2( ++ ret = cxd2841er_read_status_t_t2( + priv, &sync, &tslock, &unlock); + if (ret) + goto done; @@ -37177,8 +37706,22 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + 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 = cxd2837er_read_status_c(priv, &tslock); ++ ret = cxd2841er_read_status_c(priv, &tslock); + if (ret) + goto done; + if (tslock) @@ -37194,7 +37737,136 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return ret; +} + -+static int cxd2837er_get_carrier_offset_t2(struct cxd2837er_priv *priv, ++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 ++ * 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 ++ * 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 ++ * A0h 45h [4:0] ICFRL_CTRLVAL[20:16] ++ * A0h 46h [7:0] ICFRL_CTRLVAL[15:8] ++ * 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]; @@ -37210,8 +37882,8 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + __func__, priv->system); + return -EINVAL; + } -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x20); -+ cxd2837er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data)); ++ 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); @@ -37234,7 +37906,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return 0; +} + -+static int cxd2837er_get_carrier_offset_c(struct cxd2837er_priv *priv, ++static int cxd2841er_get_carrier_offset_c(struct cxd2841er_priv *priv, + int *offset) +{ + u8 data[2]; @@ -37250,33 +37922,33 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + __func__, priv->system); + return -EINVAL; + } -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x40); -+ cxd2837er_read_regs(priv, I2C_SLVT, 0x15, data, sizeof(data)); ++ 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 cxd2837er_read_packet_errors_t( -+ struct cxd2837er_priv *priv, u32 *penum) ++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); ++ __func__, priv->state); + return -EINVAL; + } -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); -+ cxd2837er_read_regs(priv, I2C_SLVT, 0xea, data, sizeof(data)); ++ 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 cxd2837er_read_packet_errors_t2( -+ struct cxd2837er_priv *priv, u32 *penum) ++static int cxd2841er_read_packet_errors_t( ++ struct cxd2841er_priv *priv, u32 *penum) +{ + u8 data[3]; + @@ -37286,87 +37958,402 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + __func__, priv->state); + return -EINVAL; + } -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x24); -+ cxd2837er_read_regs(priv, I2C_SLVT, 0xfd, data, sizeof(data)); ++ 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 cxd2837er_read_ber_t2(struct cxd2837er_priv *priv, u32 *ber) ++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_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 ++ * A0h 35h [0] IFVBER_VALID ++ * A0h 36h [5:0] IFVBER_BITERR[21:16] ++ * A0h 37h [7:0] IFVBER_BITERR[15:8] ++ * A0h 38h [7:0] IFVBER_BITERR[7:0] ++ * A0h 3Dh [5:0] IFVBER_BITNUM[21:16] ++ * A0h 3Eh [7:0] IFVBER_BITNUM[15:8] ++ * 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 ++ * B2h 30h [0] IFLBER_VALID ++ * B2h 31h [3:0] IFLBER_BITERR[27:24] ++ * B2h 32h [7:0] IFLBER_BITERR[23:16] ++ * B2h 33h [7:0] IFLBER_BITERR[15:8] ++ * 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 div, q, r; -+ u32 bit_err, period_exp, n_ldpc; ++ u32 period_exp, n_ldpc; + -+ *ber = 0; + if (priv->state != STATE_ACTIVE_TC) { + dev_dbg(&priv->i2c->dev, + "%s(): invalid state %d\n", __func__, priv->state); + return -EINVAL; + } -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x20); -+ cxd2837er_read_regs(priv, I2C_SLVT, 0x39, data, sizeof(data)); ++ 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 0; ++ return -EINVAL; + } -+ bit_err = ((u32)(data[0] & 0x0f) << 24) | -+ ((u32)data[1] << 16) | -+ ((u32)data[2] << 8) | -+ (u32)data[3]; -+ cxd2837er_read_reg(priv, I2C_SLVT, 0x6f, data); ++ *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; -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x22); -+ cxd2837er_read_reg(priv, I2C_SLVT, 0x5e, data); ++ 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_err > ((1U << period_exp) * n_ldpc)) { ++ 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) { -+ div = (1U << (period_exp - 4)) * (n_ldpc / 200); -+ q = div_u64_rem(3125ULL * bit_err, div, &r); ++ *bit_count = (1U << (period_exp - 4)) * (n_ldpc / 200); ++ *bit_error *= 3125ULL; + } else { -+ div = (1U << period_exp) * (n_ldpc / 200); -+ q = div_u64_rem(50000ULL * bit_err, div, &r); ++ *bit_count = (1U << period_exp) * (n_ldpc / 200); ++ *bit_error *= 50000ULL; + } -+ *ber = (r >= div / 2) ? q + 1 : q; + return 0; +} + -+static int cxd2837er_read_ber_t(struct cxd2837er_priv *priv, u32 *ber) ++static int cxd2841er_read_ber_t(struct cxd2841er_priv *priv, ++ u32 *bit_error, u32 *bit_count) +{ + u8 data[2]; -+ u32 div, q, r; -+ u32 bit_err, period; ++ u32 period; + -+ *ber = 0; + if (priv->state != STATE_ACTIVE_TC) { + dev_dbg(&priv->i2c->dev, + "%s(): invalid state %d\n", __func__, priv->state); + return -EINVAL; + } -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); -+ cxd2837er_read_reg(priv, I2C_SLVT, 0x39, data); ++ 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; + } -+ cxd2837er_read_regs(priv, I2C_SLVT, 0x22, data, sizeof(data)); -+ bit_err = ((u32)data[0] << 8) | (u32)data[1]; -+ cxd2837er_read_reg(priv, I2C_SLVT, 0x6f, data); ++ 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)); -+ div = period / 128; -+ q = div_u64_rem(78125ULL * bit_err, div, &r); -+ *ber = (r >= div / 2) ? q + 1 : q; ++ ++ /* ++ * 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 cxd2837er_read_snr_t(struct cxd2837er_priv *priv, u32 *snr) ++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; ++ ++ /* Set SLV-T Bank : 0xA1 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa1); ++ /* ++ * slave Bank Addr Bit Signal name ++ * A1h 10h [0] ICPM_QUICKRDY ++ * A1h 11h [4:0] ICPM_QUICKCNDT[12:8] ++ * A1h 12h [7:0] ICPM_QUICKCNDT[7:0] ++ */ ++ cxd2841er_read_regs(priv, I2C_SLVT, 0x10, data, 3); ++ 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 = sizeof(s_cn_data) / ++ sizeof(s_cn_data[0]) - 1; ++ } else { ++ cn_data = s2_cn_data; ++ max_index = sizeof(s2_cn_data) / ++ sizeof(s2_cn_data[0]) - 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; ++ } ++ ++ /* ++ * Freeze registers: ensure multiple separate register reads ++ * are from the same snapshot ++ */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01); ++ ++ 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); ++ ++ 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]; @@ -37377,8 +38364,8 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + "%s(): invalid state %d\n", __func__, priv->state); + return -EINVAL; + } -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); -+ cxd2837er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); + reg = ((u32)data[0] << 8) | (u32)data[1]; + if (reg == 0) { + dev_dbg(&priv->i2c->dev, @@ -37391,7 +38378,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return 0; +} + -+static int cxd2837er_read_snr_t2(struct cxd2837er_priv *priv, u32 *snr) ++static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr) +{ + u32 reg; + u8 data[2]; @@ -37402,8 +38389,8 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + "%s(): invalid state %d\n", __func__, priv->state); + return -EINVAL; + } -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x20); -+ cxd2837er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); ++ cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); + reg = ((u32)data[0] << 8) | (u32)data[1]; + if (reg == 0) { + dev_dbg(&priv->i2c->dev, @@ -37417,102 +38404,266 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return 0; +} + -+static u16 cxd2837er_read_agc_gain_t_t2(struct cxd2837er_priv *priv, ++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; ++ } ++ ++ /* Freeze all registers */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01); ++ ++ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); ++ cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); ++ 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 * intlog10(reg) - 9031; ++ return 0; ++} ++ ++static u16 cxd2841er_read_agc_gain_c(struct cxd2841er_priv *priv, + u8 delsys) +{ + u8 data[2]; + -+ cxd2837er_write_reg( -+ priv, I2C_SLVT, 0x00, (delsys == SYS_DVBT ? 0x10 : 0x20)); -+ cxd2837er_read_regs(priv, I2C_SLVT, 0x26, 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 int cxd2837er_read_ber(struct dvb_frontend *fe, u32 *ber) ++static u16 cxd2841er_read_agc_gain_t_t2(struct cxd2841er_priv *priv, ++ u8 delsys) +{ -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ struct cxd2837er_priv *priv = fe->demodulator_priv; ++ u8 data[2]; + -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ *ber = 0; -+ switch (p->delivery_system) { -+ case SYS_DVBT: -+ return cxd2837er_read_ber_t(priv, ber); -+ case SYS_DVBT2: -+ return cxd2837er_read_ber_t2(priv, ber); -+ default: -+ *ber = 0; -+ break; -+ } -+ return 0; ++ 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 int cxd2837er_read_signal_strength(struct dvb_frontend *fe, -+ u16 *strength) ++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 ++ * A0h 1Fh [4:0] IRFAGC_GAIN[12:8] ++ * 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 cxd2837er_priv *priv = fe->demodulator_priv; ++ 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_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 = 65535 - cxd2837er_read_agc_gain_t_t2( -+ priv, p->delivery_system); ++ 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: -+ *strength = 0; ++ p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + break; + } -+ return 0; +} + -+static int cxd2837er_read_snr(struct dvb_frontend *fe, u16 *snr) ++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 cxd2837er_priv *priv = fe->demodulator_priv; ++ 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: -+ cxd2837er_read_snr_t(priv, &tmp); ++ ret = cxd2841er_read_snr_t(priv, &tmp); + break; + case SYS_DVBT2: -+ cxd2837er_read_snr_t2(priv, &tmp); ++ 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); -+ break; ++ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ return; ++ } ++ ++ 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; + } -+ *snr = tmp & 0xffff; -+ return 0; +} + -+static int cxd2837er_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) ++static void cxd2841er_read_ucblocks(struct dvb_frontend *fe) +{ + struct dtv_frontend_properties *p = &fe->dtv_property_cache; -+ struct cxd2837er_priv *priv = fe->demodulator_priv; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; ++ u32 ucblocks; + + 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: -+ cxd2837er_read_packet_errors_t(priv, ucblocks); ++ cxd2841er_read_packet_errors_t(priv, &ucblocks); + break; + case SYS_DVBT2: -+ cxd2837er_read_packet_errors_t2(priv, ucblocks); ++ cxd2841er_read_packet_errors_t2(priv, &ucblocks); ++ break; ++ case SYS_ISDBT: ++ cxd2841er_read_packet_errors_i(priv, &ucblocks); + break; + default: -+ *ucblocks = 0; -+ break; ++ p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ return; + } + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ return 0; ++ ++ p->block_error.stat[0].scale = FE_SCALE_COUNTER; ++ p->block_error.stat[0].uvalue = ucblocks; +} + -+static int cxd2837er_dvbt2_set_profile( -+ struct cxd2837er_priv *priv, enum cxd2837er_dvbt2_profile_t profile) ++static int cxd2841er_dvbt2_set_profile( ++ struct cxd2841er_priv *priv, enum cxd2841er_dvbt2_profile_t profile) +{ + u8 tune_mode; + u8 seq_not2d_time; @@ -37521,31 +38672,34 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + switch (profile) { + case DVBT2_PROFILE_BASE: + tune_mode = 0x01; -+ seq_not2d_time = 12; ++ /* Set early unlock time */ ++ seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x0E:0x0C; + break; + case DVBT2_PROFILE_LITE: + tune_mode = 0x05; -+ seq_not2d_time = 40; ++ /* Set early unlock time */ ++ seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28; + break; + case DVBT2_PROFILE_ANY: + tune_mode = 0x00; -+ seq_not2d_time = 40; ++ /* Set early unlock time */ ++ seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28; + break; + default: + return -EINVAL; + } + /* Set SLV-T Bank : 0x2E */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x2e); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2e); + /* Set profile and tune mode */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x10, tune_mode, 0x07); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x10, tune_mode, 0x07); + /* Set SLV-T Bank : 0x2B */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); + /* Set early unlock detection time */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x9d, seq_not2d_time); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x9d, seq_not2d_time); + return 0; +} + -+static int cxd2837er_dvbt2_set_plp_config(struct cxd2837er_priv *priv, ++static int cxd2841er_dvbt2_set_plp_config(struct cxd2841er_priv *priv, + u8 is_auto, u8 plp_id) +{ + if (is_auto) { @@ -37557,272 +38711,635 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + __func__, plp_id); + } + /* Set SLV-T Bank : 0x23 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x23); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x23); + if (!is_auto) { + /* Manual PLP selection mode. Set the data PLP Id. */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xaf, plp_id); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xaf, plp_id); + } + /* Auto PLP select (Scanning mode = 0x00). Data PLP select = 0x01. */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xad, (is_auto ? 0x00 : 0x01)); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xad, (is_auto ? 0x00 : 0x01)); + return 0; +} + -+static int cxd2837er_sleep_tc_to_active_t2_band(struct cxd2837er_priv *priv, ++static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv, + u32 bandwidth) +{ + u32 iffreq; -+ u8 b20_9f[5]; -+ u8 b10_a6[14]; -+ u8 b10_b6[3]; -+ u8 b10_d7; ++ u8 data[MAX_WRITE_REGSIZE]; ++ ++ const uint8_t nominalRate8bw[3][5] = { ++ /* TRCG Nominal Rate [37:0] */ ++ {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ ++ {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ ++ {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */ ++ }; ++ ++ const uint8_t nominalRate7bw[3][5] = { ++ /* TRCG Nominal Rate [37:0] */ ++ {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ ++ {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ ++ {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */ ++ }; ++ ++ const uint8_t nominalRate6bw[3][5] = { ++ /* TRCG Nominal Rate [37:0] */ ++ {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */ ++ {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ ++ {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */ ++ }; ++ ++ const uint8_t nominalRate5bw[3][5] = { ++ /* TRCG Nominal Rate [37:0] */ ++ {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */ ++ {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */ ++ {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */ ++ }; ++ ++ const uint8_t nominalRate17bw[3][5] = { ++ /* TRCG Nominal Rate [37:0] */ ++ {0x58, 0xE2, 0xAF, 0xE0, 0xBC}, /* 20.5MHz XTal */ ++ {0x68, 0x0F, 0xA2, 0x32, 0xD0}, /* 24MHz XTal */ ++ {0x58, 0xE2, 0xAF, 0xE0, 0xBC} /* 41MHz XTal */ ++ }; ++ ++ const uint8_t itbCoef8bw[3][14] = { ++ {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, ++ 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */ ++ {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, ++ 0x29, 0xA5, 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz XTal */ ++ {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, ++ 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */ ++ }; ++ ++ const uint8_t itbCoef7bw[3][14] = { ++ {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, ++ 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */ ++ {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, ++ 0x29, 0xA2, 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz XTal */ ++ {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, ++ 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */ ++ }; ++ ++ const uint8_t itbCoef6bw[3][14] = { ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, ++ 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ ++ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, ++ 0x29, 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */ ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, ++ 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ ++ }; ++ ++ const uint8_t itbCoef5bw[3][14] = { ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, ++ 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ ++ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, ++ 0x29, 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */ ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, ++ 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ ++ }; ++ ++ const uint8_t itbCoef17bw[3][14] = { ++ {0x25, 0xA0, 0x36, 0x8D, 0x2E, 0x94, 0x28, 0x9B, ++ 0x32, 0x90, 0x2C, 0x9D, 0x29, 0x99}, /* 20.5MHz XTal */ ++ {0x33, 0x8E, 0x2B, 0x97, 0x2D, 0x95, 0x37, 0x8B, ++ 0x30, 0x97, 0x2D, 0x9A, 0x21, 0xA4}, /* 24MHz XTal */ ++ {0x25, 0xA0, 0x36, 0x8D, 0x2E, 0x94, 0x28, 0x9B, ++ 0x32, 0x90, 0x2C, 0x9D, 0x29, 0x99} /* 41MHz XTal */ ++ }; ++ ++ /* Set SLV-T Bank : 0x20 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); + -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + switch (bandwidth) { + case 8000000: -+ /* bank 0x20, reg 0x9f */ -+ b20_9f[0] = 0x11; -+ b20_9f[1] = 0xf0; -+ b20_9f[2] = 0x00; -+ b20_9f[3] = 0x00; -+ b20_9f[4] = 0x00; -+ /* bank 0x10, reg 0xa6 */ -+ b10_a6[0] = 0x26; -+ b10_a6[1] = 0xaf; -+ b10_a6[2] = 0x06; -+ b10_a6[3] = 0xcd; -+ b10_a6[4] = 0x13; -+ b10_a6[5] = 0xbb; -+ b10_a6[6] = 0x28; -+ b10_a6[7] = 0xba; -+ b10_a6[8] = 0x23; -+ b10_a6[9] = 0xa9; -+ b10_a6[10] = 0x1f; -+ b10_a6[11] = 0xa8; -+ b10_a6[12] = 0x2c; -+ b10_a6[13] = 0xc8; -+ iffreq = MAKE_IFFREQ_CONFIG(4.80); -+ b10_d7 = 0x00; ++ /* */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate8bw[priv->xtal], 5); ++ ++ /* Set SLV-T Bank : 0x27 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, ++ 0x7a, 0x00, 0x0f); ++ ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ ++ /* Group delay equaliser settings for ++ * ASCOT2D, ASCOT2E and ASCOT3 tuners ++ */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef8bw[priv->xtal], 14); ++ /* */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits( ++ priv, I2C_SLVT, 0xD7, 0x00, 0x07); + break; + case 7000000: -+ /* bank 0x20, reg 0x9f */ -+ b20_9f[0] = 0x14; -+ b20_9f[1] = 0x80; -+ b20_9f[2] = 0x00; -+ b20_9f[3] = 0x00; -+ b20_9f[4] = 0x00; -+ /* bank 0x10, reg 0xa6 */ -+ b10_a6[0] = 0x2C; -+ b10_a6[1] = 0xBD; -+ b10_a6[2] = 0x02; -+ b10_a6[3] = 0xCF; -+ b10_a6[4] = 0x04; -+ b10_a6[5] = 0xF8; -+ b10_a6[6] = 0x23; -+ b10_a6[7] = 0xA6; -+ b10_a6[8] = 0x29; -+ b10_a6[9] = 0xB0; -+ b10_a6[10] = 0x26; -+ b10_a6[11] = 0xA9; -+ b10_a6[12] = 0x21; -+ b10_a6[13] = 0xA5; -+ iffreq = MAKE_IFFREQ_CONFIG(4.2); -+ b10_d7 = 0x02; ++ /* */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate7bw[priv->xtal], 5); ++ ++ /* Set SLV-T Bank : 0x27 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, ++ 0x7a, 0x00, 0x0f); ++ ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ ++ /* Group delay equaliser settings for ++ * ASCOT2D, ASCOT2E and ASCOT3 tuners ++ */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef7bw[priv->xtal], 14); ++ /* */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits( ++ priv, I2C_SLVT, 0xD7, 0x02, 0x07); + break; + case 6000000: -+ /* bank 0x20, reg 0x9f */ -+ b20_9f[0] = 0x17; -+ b20_9f[1] = 0xEA; -+ b20_9f[2] = 0xAA; -+ b20_9f[3] = 0xAA; -+ b20_9f[4] = 0xAA; -+ /* bank 0x10, reg 0xa6 */ -+ b10_a6[0] = 0x27; -+ b10_a6[1] = 0xA7; -+ b10_a6[2] = 0x28; -+ b10_a6[3] = 0xB3; -+ b10_a6[4] = 0x02; -+ b10_a6[5] = 0xF0; -+ b10_a6[6] = 0x01; -+ b10_a6[7] = 0xE8; -+ b10_a6[8] = 0x00; -+ b10_a6[9] = 0xCF; -+ b10_a6[10] = 0x00; -+ b10_a6[11] = 0xE6; -+ b10_a6[12] = 0x23; -+ b10_a6[13] = 0xA4; -+ iffreq = MAKE_IFFREQ_CONFIG(3.6); -+ b10_d7 = 0x04; ++ /* */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate6bw[priv->xtal], 5); ++ ++ /* Set SLV-T Bank : 0x27 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, ++ 0x7a, 0x00, 0x0f); ++ ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ ++ /* Group delay equaliser settings for ++ * ASCOT2D, ASCOT2E and ASCOT3 tuners ++ */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef6bw[priv->xtal], 14); ++ /* */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits( ++ priv, I2C_SLVT, 0xD7, 0x04, 0x07); + break; + case 5000000: -+ /* bank 0x20, reg 0x9f */ -+ b20_9f[0] = 0x1C; -+ b20_9f[1] = 0xB3; -+ b20_9f[2] = 0x33; -+ b20_9f[3] = 0x33; -+ b20_9f[4] = 0x33; -+ /* bank 0x10, reg 0xa6 */ -+ b10_a6[0] = 0x27; -+ b10_a6[1] = 0xA7; -+ b10_a6[2] = 0x28; -+ b10_a6[3] = 0xB3; -+ b10_a6[4] = 0x02; -+ b10_a6[5] = 0xF0; -+ b10_a6[6] = 0x01; -+ b10_a6[7] = 0xE8; -+ b10_a6[8] = 0x00; -+ b10_a6[9] = 0xCF; -+ b10_a6[10] = 0x00; -+ b10_a6[11] = 0xE6; -+ b10_a6[12] = 0x23; -+ b10_a6[13] = 0xA4; -+ iffreq = MAKE_IFFREQ_CONFIG(3.6); -+ b10_d7 = 0x06; ++ /* */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate5bw[priv->xtal], 5); ++ ++ /* Set SLV-T Bank : 0x27 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, ++ 0x7a, 0x00, 0x0f); ++ ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ ++ /* Group delay equaliser settings for ++ * ASCOT2D, ASCOT2E and ASCOT3 tuners ++ */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef5bw[priv->xtal], 14); ++ /* */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits( ++ priv, I2C_SLVT, 0xD7, 0x06, 0x07); + break; + case 1712000: -+ /* bank 0x20, reg 0x9f */ -+ b20_9f[0] = 0x58; -+ b20_9f[1] = 0xE2; -+ b20_9f[2] = 0xAF; -+ b20_9f[3] = 0xE0; -+ b20_9f[4] = 0xBC; -+ /* bank 0x10, reg 0xa6 */ -+ b10_a6[0] = 0x25; -+ b10_a6[1] = 0xA0; -+ b10_a6[2] = 0x36; -+ b10_a6[3] = 0x8D; -+ b10_a6[4] = 0x2E; -+ b10_a6[5] = 0x94; -+ b10_a6[6] = 0x28; -+ b10_a6[7] = 0x9B; -+ b10_a6[8] = 0x32; -+ b10_a6[9] = 0x90; -+ b10_a6[10] = 0x2C; -+ b10_a6[11] = 0x9D; -+ b10_a6[12] = 0x29; -+ b10_a6[13] = 0x99; -+ iffreq = MAKE_IFFREQ_CONFIG(3.5); -+ b10_d7 = 0x03; ++ /* */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate17bw[priv->xtal], 5); ++ ++ /* Set SLV-T Bank : 0x27 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, ++ 0x7a, 0x03, 0x0f); ++ ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ ++ /* Group delay equaliser settings for ++ * ASCOT2D, ASCOT2E and ASCOT3 tuners ++ */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef17bw[priv->xtal], 14); ++ /* */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.50); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits( ++ priv, I2C_SLVT, 0xD7, 0x03, 0x07); + break; + default: + return -EINVAL; + } -+ /* Set SLV-T Bank : 0x20 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x20); -+ cxd2837er_write_regs(priv, I2C_SLVT, 0x9f, b20_9f, sizeof(b20_9f)); -+ /* Set SLV-T Bank : 0x27 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x27); -+ cxd2837er_set_reg_bits( -+ priv, I2C_SLVT, 0x7a, -+ (bandwidth == 1712000 ? 0x03 : 0x00), 0x0f); -+ /* Set SLV-T Bank : 0x10 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); -+ /* Group delay equaliser sett. for ASCOT2E */ -+ cxd2837er_write_regs(priv, I2C_SLVT, 0xa6, b10_a6, sizeof(b10_a6)); -+ /* */ -+ b10_b6[0] = (u8) ((iffreq >> 16) & 0xff); -+ b10_b6[1] = (u8)((iffreq >> 8) & 0xff); -+ b10_b6[2] = (u8)(iffreq & 0xff); -+ cxd2837er_write_regs(priv, I2C_SLVT, 0xb6, b10_b6, sizeof(b10_b6)); -+ /* System bandwidth setting */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xd7, b10_d7, 0x07); + return 0; +} + -+static int cxd2837er_sleep_tc_to_active_t_band( -+ struct cxd2837er_priv *priv, u32 bandwidth) ++static int cxd2841er_sleep_tc_to_active_t_band( ++ struct cxd2841er_priv *priv, u32 bandwidth) +{ -+ u8 b13_9c[2] = { 0x01, 0x14 }; -+ u8 bw8mhz_b10_9f[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; -+ u8 bw8mhz_b10_a6[] = { 0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, -+ 0x28, 0xBA, 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8 }; -+ u8 bw8mhz_b10_d9[] = { 0x01, 0xE0 }; -+ u8 bw8mhz_b17_38[] = { 0x01, 0x02 }; -+ u8 bw7mhz_b10_9f[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; -+ u8 bw7mhz_b10_a6[] = { 0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, -+ 0x23, 0xA6, 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5 }; -+ u8 bw7mhz_b10_d9[] = { 0x12, 0xF8 }; -+ u8 bw7mhz_b17_38[] = { 0x00, 0x03 }; -+ u8 bw6mhz_b10_9f[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; -+ u8 bw6mhz_b10_a6[] = { 0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, -+ 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4 }; -+ u8 bw6mhz_b10_d9[] = { 0x1F, 0xDC }; -+ u8 bw6mhz_b17_38[] = { 0x00, 0x03 }; -+ u8 bw5mhz_b10_9f[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; -+ u8 bw5mhz_b10_a6[] = { 0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, -+ 0x01, 0xE8, 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4 }; -+ u8 bw5mhz_b10_d9[] = { 0x26, 0x3C }; -+ u8 bw5mhz_b17_38[] = { 0x00, 0x03 }; -+ u8 b10_b6[3]; -+ u8 d7val; ++ u8 data[MAX_WRITE_REGSIZE]; + u32 iffreq; -+ u8 *b10_9f; -+ u8 *b10_a6; -+ u8 *b10_d9; -+ u8 *b17_38; ++ u8 nominalRate8bw[3][5] = { ++ /* TRCG Nominal Rate [37:0] */ ++ {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ ++ {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ ++ {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */ ++ }; ++ u8 nominalRate7bw[3][5] = { ++ /* TRCG Nominal Rate [37:0] */ ++ {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ ++ {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ ++ {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */ ++ }; ++ u8 nominalRate6bw[3][5] = { ++ /* TRCG Nominal Rate [37:0] */ ++ {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */ ++ {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ ++ {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */ ++ }; ++ u8 nominalRate5bw[3][5] = { ++ /* TRCG Nominal Rate [37:0] */ ++ {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */ ++ {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */ ++ {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */ ++ }; + -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x13); ++ u8 itbCoef8bw[3][14] = { ++ {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9, ++ 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */ ++ {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29, 0xA5, ++ 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz XTal */ ++ {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9, ++ 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */ ++ }; ++ u8 itbCoef7bw[3][14] = { ++ {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0, ++ 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */ ++ {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29, 0xA2, ++ 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz XTal */ ++ {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0, ++ 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */ ++ }; ++ u8 itbCoef6bw[3][14] = { ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, ++ 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ ++ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4, ++ 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */ ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, ++ 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ ++ }; ++ u8 itbCoef5bw[3][14] = { ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, ++ 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ ++ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4, ++ 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */ ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, ++ 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ ++ }; ++ ++ /* Set SLV-T Bank : 0x13 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13); + /* Echo performance optimization setting */ -+ cxd2837er_write_regs(priv, I2C_SLVT, 0x9c, b13_9c, sizeof(b13_9c)); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ data[0] = 0x01; ++ data[1] = 0x14; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x9C, data, 2); ++ ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); + + switch (bandwidth) { + case 8000000: -+ b10_9f = bw8mhz_b10_9f; -+ b10_a6 = bw8mhz_b10_a6; -+ b10_d9 = bw8mhz_b10_d9; -+ b17_38 = bw8mhz_b17_38; -+ d7val = 0; -+ iffreq = MAKE_IFFREQ_CONFIG(4.80); ++ /* */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate8bw[priv->xtal], 5); ++ /* Group delay equaliser settings for ++ * ASCOT2D, ASCOT2E and ASCOT3 tuners ++ */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef8bw[priv->xtal], 14); ++ /* */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.80); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits( ++ priv, I2C_SLVT, 0xD7, 0x00, 0x07); ++ ++ /* Demod core latency setting */ ++ if (priv->xtal == SONY_XTAL_24000) { ++ data[0] = 0x15; ++ data[1] = 0x28; ++ } else { ++ data[0] = 0x01; ++ data[1] = 0xE0; ++ } ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); ++ ++ /* Notch filter setting */ ++ data[0] = 0x01; ++ data[1] = 0x02; ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2); + break; + case 7000000: -+ b10_9f = bw7mhz_b10_9f; -+ b10_a6 = bw7mhz_b10_a6; -+ b10_d9 = bw7mhz_b10_d9; -+ b17_38 = bw7mhz_b17_38; -+ d7val = 2; -+ iffreq = MAKE_IFFREQ_CONFIG(4.20); ++ /* */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate7bw[priv->xtal], 5); ++ /* Group delay equaliser settings for ++ * ASCOT2D, ASCOT2E and ASCOT3 tuners ++ */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef7bw[priv->xtal], 14); ++ /* */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.20); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits( ++ priv, I2C_SLVT, 0xD7, 0x02, 0x07); ++ ++ /* Demod core latency setting */ ++ if (priv->xtal == SONY_XTAL_24000) { ++ data[0] = 0x1F; ++ data[1] = 0xF8; ++ } else { ++ data[0] = 0x12; ++ data[1] = 0xF8; ++ } ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); ++ ++ /* Notch filter setting */ ++ data[0] = 0x00; ++ data[1] = 0x03; ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2); + break; + case 6000000: -+ b10_9f = bw6mhz_b10_9f; -+ b10_a6 = bw6mhz_b10_a6; -+ b10_d9 = bw6mhz_b10_d9; -+ b17_38 = bw6mhz_b17_38; -+ d7val = 4; -+ iffreq = MAKE_IFFREQ_CONFIG(3.60); ++ /* */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate6bw[priv->xtal], 5); ++ /* Group delay equaliser settings for ++ * ASCOT2D, ASCOT2E and ASCOT3 tuners ++ */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef6bw[priv->xtal], 14); ++ /* */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits( ++ priv, I2C_SLVT, 0xD7, 0x04, 0x07); ++ ++ /* Demod core latency setting */ ++ if (priv->xtal == SONY_XTAL_24000) { ++ data[0] = 0x25; ++ data[1] = 0x4C; ++ } else { ++ data[0] = 0x1F; ++ data[1] = 0xDC; ++ } ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); ++ ++ /* Notch filter setting */ ++ data[0] = 0x00; ++ data[1] = 0x03; ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2); + break; + case 5000000: -+ b10_9f = bw5mhz_b10_9f; -+ b10_a6 = bw5mhz_b10_a6; -+ b10_d9 = bw5mhz_b10_d9; -+ b17_38 = bw5mhz_b17_38; -+ d7val = 6; -+ iffreq = MAKE_IFFREQ_CONFIG(3.60); ++ /* */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate5bw[priv->xtal], 5); ++ /* Group delay equaliser settings for ++ * ASCOT2D, ASCOT2E and ASCOT3 tuners ++ */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef5bw[priv->xtal], 14); ++ /* */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.60); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits( ++ priv, I2C_SLVT, 0xD7, 0x06, 0x07); ++ ++ /* Demod core latency setting */ ++ if (priv->xtal == SONY_XTAL_24000) { ++ data[0] = 0x2C; ++ data[1] = 0xC2; ++ } else { ++ data[0] = 0x26; ++ data[1] = 0x3C; ++ } ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); ++ ++ /* Notch filter setting */ ++ data[0] = 0x00; ++ data[1] = 0x03; ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2); + break; -+ default: -+ dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n", ++ } ++ ++ return 0; ++} ++ ++static int cxd2841er_sleep_tc_to_active_i_band( ++ struct cxd2841er_priv *priv, u32 bandwidth) ++{ ++ u32 iffreq; ++ u8 data[3]; ++ ++ /* TRCG Nominal Rate */ ++ u8 nominalRate8bw[3][5] = { ++ {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ ++ {0x11, 0xB8, 0x00, 0x00, 0x00}, /* 24MHz XTal */ ++ {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */ ++ }; ++ ++ u8 nominalRate7bw[3][5] = { ++ {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ ++ {0x14, 0x40, 0x00, 0x00, 0x00}, /* 24MHz XTal */ ++ {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */ ++ }; ++ ++ u8 nominalRate6bw[3][5] = { ++ {0x14, 0x2E, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ ++ {0x17, 0xA0, 0x00, 0x00, 0x00}, /* 24MHz XTal */ ++ {0x14, 0x2E, 0x00, 0x00, 0x00} /* 41MHz XTal */ ++ }; ++ ++ u8 itbCoef8bw[3][14] = { ++ {0x00}, /* 20.5MHz XTal */ ++ {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29, ++ 0xA5, 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz Xtal */ ++ {0x0}, /* 41MHz XTal */ ++ }; ++ ++ u8 itbCoef7bw[3][14] = { ++ {0x00}, /* 20.5MHz XTal */ ++ {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29, ++ 0xA2, 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz Xtal */ ++ {0x00}, /* 41MHz XTal */ ++ }; ++ ++ u8 itbCoef6bw[3][14] = { ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, ++ 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ ++ {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, ++ 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz Xtal */ ++ {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, ++ 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 41MHz XTal */ ++ }; ++ ++ dev_dbg(&priv->i2c->dev, "%s() bandwidth=%u\n", __func__, bandwidth); ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ ++ /* 20.5/41MHz Xtal support is not available ++ * on ISDB-T 7MHzBW and 8MHzBW ++ */ ++ if (priv->xtal != SONY_XTAL_24000 && bandwidth > 6000000) { ++ dev_err(&priv->i2c->dev, ++ "%s(): bandwidth %d supported only for 24MHz xtal\n", + __func__, bandwidth); + return -EINVAL; + } -+ /* */ -+ b10_b6[0] = (u8) ((iffreq >> 16) & 0xff); -+ b10_b6[1] = (u8)((iffreq >> 8) & 0xff); -+ b10_b6[2] = (u8)(iffreq & 0xff); -+ cxd2837er_write_regs( -+ priv, I2C_SLVT, 0x9f, b10_9f, sizeof(bw8mhz_b10_9f)); -+ cxd2837er_write_regs( -+ priv, I2C_SLVT, 0xa6, b10_a6, sizeof(bw8mhz_b10_a6)); -+ cxd2837er_write_regs(priv, I2C_SLVT, 0xb6, b10_b6, sizeof(b10_b6)); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xd7, d7val, 0x7); -+ cxd2837er_write_regs( -+ priv, I2C_SLVT, 0xd9, b10_d9, sizeof(bw8mhz_b10_d9)); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x17); -+ cxd2837er_write_regs( -+ priv, I2C_SLVT, 0x38, b17_38, sizeof(bw8mhz_b17_38)); ++ ++ switch (bandwidth) { ++ case 8000000: ++ /* TRCG Nominal Rate */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate8bw[priv->xtal], 5); ++ /* Group delay equaliser settings for ASCOT tuners optimized */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef8bw[priv->xtal], 14); ++ ++ /* IF freq setting */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.75); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x0, 0x7); ++ ++ /* Demod core latency setting */ ++ data[0] = 0x13; ++ data[1] = 0xFC; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); ++ ++ /* Acquisition optimization setting */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x03, 0x07); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x03); ++ break; ++ case 7000000: ++ /* TRCG Nominal Rate */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate7bw[priv->xtal], 5); ++ /* Group delay equaliser settings for ASCOT tuners optimized */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef7bw[priv->xtal], 14); ++ ++ /* IF freq setting */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 4.15); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x02, 0x7); ++ ++ /* Demod core latency setting */ ++ data[0] = 0x1A; ++ data[1] = 0xFA; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); ++ ++ /* Acquisition optimization setting */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x03, 0x07); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x02); ++ break; ++ case 6000000: ++ /* TRCG Nominal Rate */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0x9F, nominalRate6bw[priv->xtal], 5); ++ /* Group delay equaliser settings for ASCOT tuners optimized */ ++ cxd2841er_write_regs(priv, I2C_SLVT, ++ 0xA6, itbCoef6bw[priv->xtal], 14); ++ ++ /* IF freq setting */ ++ iffreq = MAKE_IFFREQ_CONFIG_XTAL(priv->xtal, 3.55); ++ data[0] = (u8) ((iffreq >> 16) & 0xff); ++ data[1] = (u8)((iffreq >> 8) & 0xff); ++ data[2] = (u8)(iffreq & 0xff); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); ++ ++ /* System bandwidth setting */ ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x04, 0x7); ++ ++ /* Demod core latency setting */ ++ if (priv->xtal == SONY_XTAL_24000) { ++ data[0] = 0x1F; ++ data[1] = 0x79; ++ } else { ++ data[0] = 0x1A; ++ data[1] = 0xE2; ++ } ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); ++ ++ /* Acquisition optimization setting */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x07, 0x07); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x02); ++ break; ++ default: ++ dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n", ++ __func__, bandwidth); ++ return -EINVAL; ++ } + return 0; +} + -+static int cxd2837er_sleep_tc_to_active_c_band(struct cxd2837er_priv *priv, ++static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv, + u32 bandwidth) +{ + u8 bw7_8mhz_b10_a6[] = { @@ -37834,24 +39351,24 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + u8 b10_b6[3]; + u32 iffreq; + -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ dev_dbg(&priv->i2c->dev, "%s() bw=%d\n", __func__, bandwidth); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); + switch (bandwidth) { + case 8000000: + case 7000000: -+ cxd2837er_write_regs( ++ cxd2841er_write_regs( + priv, I2C_SLVT, 0xa6, + bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6)); + iffreq = MAKE_IFFREQ_CONFIG(4.9); + break; + case 6000000: -+ cxd2837er_write_regs( ++ cxd2841er_write_regs( + priv, I2C_SLVT, 0xa6, + bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6)); + iffreq = MAKE_IFFREQ_CONFIG(3.7); + break; + default: -+ dev_dbg(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n", ++ dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n", + __func__, bandwidth); + return -EINVAL; + } @@ -37859,293 +39376,523 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + b10_b6[0] = (u8) ((iffreq >> 16) & 0xff); + b10_b6[1] = (u8)((iffreq >> 8) & 0xff); + b10_b6[2] = (u8)(iffreq & 0xff); -+ cxd2837er_write_regs(priv, I2C_SLVT, 0xb6, b10_b6, sizeof(b10_b6)); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xb6, b10_b6, sizeof(b10_b6)); + /* Set SLV-T Bank : 0x11 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x11); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); + switch (bandwidth) { + case 8000000: + case 7000000: -+ cxd2837er_set_reg_bits( ++ cxd2841er_set_reg_bits( + priv, I2C_SLVT, 0xa3, 0x00, 0x1f); + break; + case 6000000: -+ cxd2837er_set_reg_bits( ++ cxd2841er_set_reg_bits( + priv, I2C_SLVT, 0xa3, 0x14, 0x1f); + break; + } + /* Set SLV-T Bank : 0x40 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x40); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); + switch (bandwidth) { + case 8000000: -+ cxd2837er_set_reg_bits( ++ cxd2841er_set_reg_bits( + priv, I2C_SLVT, 0x26, 0x0b, 0x0f); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x27, 0x3e); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x27, 0x3e); + break; + case 7000000: -+ cxd2837er_set_reg_bits( ++ cxd2841er_set_reg_bits( + priv, I2C_SLVT, 0x26, 0x09, 0x0f); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x27, 0xd6); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x27, 0xd6); + break; + case 6000000: -+ cxd2837er_set_reg_bits( ++ cxd2841er_set_reg_bits( + priv, I2C_SLVT, 0x26, 0x08, 0x0f); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x27, 0x6e); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x27, 0x6e); + break; + } + return 0; +} + -+static int cxd2837er_sleep_tc_to_active_t(struct cxd2837er_priv *priv, ++static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv, + u32 bandwidth) +{ + u8 data[2] = { 0x09, 0x54 }; ++ u8 data24m[3] = {0xDC, 0x6C, 0x00}; + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ cxd2837er_set_ts_clock_mode(priv, SYS_DVBT); ++ cxd2841er_set_ts_clock_mode(priv, SYS_DVBT); + /* Set SLV-X Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); + /* Set demod mode */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x17, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* Enable demod clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); + /* Disable RF level monitor */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); + /* Enable ADC clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x30, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); + /* Enable ADC 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); -+ /* xtal freq 20.5MHz */ -+ cxd2837er_write_regs(priv, I2C_SLVT, 0x43, data, 2); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); ++ /* Enable ADC 2 & 3 */ ++ if (priv->xtal == SONY_XTAL_41000) { ++ data[0] = 0x0A; ++ data[1] = 0xD4; ++ } ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); + /* Enable ADC 4 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x18, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); + /* Set SLV-T Bank : 0x10 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); + /* IFAGC gain settings */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x0c, 0x1f); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x0c, 0x1f); + /* Set SLV-T Bank : 0x11 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x11); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); + /* BBAGC TARGET level setting */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x6a, 0x50); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50); + /* Set SLV-T Bank : 0x10 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); + /* ASCOT setting ON */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01); + /* Set SLV-T Bank : 0x18 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x18); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18); + /* Pre-RS BER moniter setting */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x36, 0x40, 0x07); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x36, 0x40, 0x07); + /* FEC Auto Recovery setting */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x01, 0x01); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* TSIF setting */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); -+ cxd2837er_sleep_tc_to_active_t_band(priv, bandwidth); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); ++ ++ if (priv->xtal == SONY_XTAL_24000) { ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xBF, 0x60); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x24, data24m, 3); ++ } ++ ++ cxd2841er_sleep_tc_to_active_t_band(priv, bandwidth); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* Disable HiZ Setting 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x80, 0x28); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28); + /* Disable HiZ Setting 2 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x81, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00); + priv->state = STATE_ACTIVE_TC; + return 0; +} + -+static int cxd2837er_sleep_tc_to_active_t2(struct cxd2837er_priv *priv, ++static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv, + u32 bandwidth) +{ -+ u8 data[2] = { 0x09, 0x54 }; ++ u8 data[MAX_WRITE_REGSIZE]; + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ cxd2837er_set_ts_clock_mode(priv, SYS_DVBT2); ++ cxd2841er_set_ts_clock_mode(priv, SYS_DVBT2); + /* Set SLV-X Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); + /* Set demod mode */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x17, 0x02); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x02); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* Enable demod clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); + /* Disable RF level monitor */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); + /* Enable ADC clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x30, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); + /* Enable ADC 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); -+ /* xtal freq 20.5MHz */ -+ cxd2837er_write_regs(priv, I2C_SLVT, 0x43, data, 2); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); ++ ++ if (priv->xtal == SONY_XTAL_41000) { ++ data[0] = 0x0A; ++ data[1] = 0xD4; ++ } else { ++ data[0] = 0x09; ++ data[1] = 0x54; ++ } ++ ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); + /* Enable ADC 4 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x18, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); + /* Set SLV-T Bank : 0x10 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); + /* IFAGC gain settings */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x0c, 0x1f); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x0c, 0x1f); + /* Set SLV-T Bank : 0x11 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x11); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); + /* BBAGC TARGET level setting */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x6a, 0x50); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50); + /* Set SLV-T Bank : 0x10 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); + /* ASCOT setting ON */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01); + /* Set SLV-T Bank : 0x20 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x20); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); + /* Acquisition optimization setting */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x8b, 0x3c); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x8b, 0x3c); + /* Set SLV-T Bank : 0x2b */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x76, 0x20, 0x70); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x76, 0x20, 0x70); ++ /* Set SLV-T Bank : 0x23 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x23); ++ /* L1 Control setting */ ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xE6, 0x00, 0x03); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* TSIF setting */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); + /* DVB-T2 initial setting */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x13); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x83, 0x10); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x86, 0x34); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x9e, 0x09, 0x0f); -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x9f, 0xd8); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x83, 0x10); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x86, 0x34); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9e, 0x09, 0x0f); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x9f, 0xd8); + /* Set SLV-T Bank : 0x2a */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x2a); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x38, 0x04, 0x0f); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2a); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x38, 0x04, 0x0f); + /* Set SLV-T Bank : 0x2b */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x20, 0x3f); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x20, 0x3f); + -+ cxd2837er_sleep_tc_to_active_t2_band(priv, bandwidth); ++ /* 24MHz Xtal setting */ ++ if (priv->xtal == SONY_XTAL_24000) { ++ /* Set SLV-T Bank : 0x11 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); ++ data[0] = 0xEB; ++ data[1] = 0x03; ++ data[2] = 0x3B; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x33, data, 3); ++ ++ /* Set SLV-T Bank : 0x20 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); ++ data[0] = 0x5E; ++ data[1] = 0x5E; ++ data[2] = 0x47; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x95, data, 3); ++ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x99, 0x18); ++ ++ data[0] = 0x3F; ++ data[1] = 0xFF; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); ++ ++ /* Set SLV-T Bank : 0x24 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x24); ++ data[0] = 0x0B; ++ data[1] = 0x72; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x34, data, 2); ++ ++ data[0] = 0x93; ++ data[1] = 0xF3; ++ data[2] = 0x00; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xD2, data, 3); ++ ++ data[0] = 0x05; ++ data[1] = 0xB8; ++ data[2] = 0xD8; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xDD, data, 3); ++ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xE0, 0x00); ++ ++ /* Set SLV-T Bank : 0x25 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x25); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xED, 0x60); ++ ++ /* Set SLV-T Bank : 0x27 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xFA, 0x34); ++ ++ /* Set SLV-T Bank : 0x2B */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2B); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x4B, 0x2F); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x9E, 0x0E); ++ ++ /* Set SLV-T Bank : 0x2D */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2D); ++ data[0] = 0x89; ++ data[1] = 0x89; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x24, data, 2); ++ ++ /* Set SLV-T Bank : 0x5E */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x5E); ++ data[0] = 0x24; ++ data[1] = 0x95; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x8C, data, 2); ++ } ++ ++ cxd2841er_sleep_tc_to_active_t2_band(priv, bandwidth); + + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* Disable HiZ Setting 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x80, 0x28); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28); + /* Disable HiZ Setting 2 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x81, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00); + priv->state = STATE_ACTIVE_TC; + return 0; +} + -+static int cxd2837er_sleep_tc_to_active_c(struct cxd2837er_priv *priv, ++/* ISDB-Tb part */ ++static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv, ++ u32 bandwidth) ++{ ++ u8 data[2] = { 0x09, 0x54 }; ++ u8 data24m[2] = {0x60, 0x00}; ++ u8 data24m2[3] = {0xB7, 0x1B, 0x00}; ++ ++ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); ++ cxd2841er_set_ts_clock_mode(priv, SYS_DVBT); ++ /* Set SLV-X Bank : 0x00 */ ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ /* Set demod mode */ ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x06); ++ /* 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 RF level monitor */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x01); ++ /* Enable ADC clock */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); ++ /* Enable ADC 1 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); ++ /* xtal freq 20.5MHz or 24M */ ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); ++ /* Enable ADC 4 */ ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); ++ /* ASCOT setting ON */ ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01); ++ /* FEC Auto Recovery setting */ ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x00, 0x01); ++ /* ISDB-T initial setting */ ++ /* Set SLV-T Bank : 0x00 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x00, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x00, 0x01); ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x69, 0x04, 0x07); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x6B, 0x03, 0x07); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9D, 0x50, 0xFF); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xD3, 0x06, 0x1F); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xED, 0x00, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xE2, 0xCE, 0x80); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xF2, 0x13, 0x10); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xDE, 0x2E, 0x3F); ++ /* Set SLV-T Bank : 0x15 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xDE, 0x02, 0x03); ++ /* Set SLV-T Bank : 0x1E */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x1E); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x73, 0x68, 0xFF); ++ /* Set SLV-T Bank : 0x63 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x63); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x81, 0x00, 0x01); ++ ++ /* for xtal 24MHz */ ++ /* Set SLV-T Bank : 0x10 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xBF, data24m, 2); ++ /* Set SLV-T Bank : 0x60 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0xA8, data24m2, 3); ++ ++ cxd2841er_sleep_tc_to_active_i_band(priv, bandwidth); ++ /* Set SLV-T Bank : 0x00 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ /* Disable HiZ Setting 1 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28); ++ /* Disable HiZ Setting 2 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00); ++ priv->state = STATE_ACTIVE_TC; ++ return 0; ++} ++ ++static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv, + u32 bandwidth) +{ + u8 data[2] = { 0x09, 0x54 }; + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ cxd2837er_set_ts_clock_mode(priv, SYS_DVBC_ANNEX_A); ++ cxd2841er_set_ts_clock_mode(priv, SYS_DVBC_ANNEX_A); + /* Set SLV-X Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); + /* Set demod mode */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x17, 0x04); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x04); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* Enable demod clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); + /* Disable RF level monitor */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); + /* Enable ADC clock */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x30, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); + /* Enable ADC 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); + /* xtal freq 20.5MHz */ -+ cxd2837er_write_regs(priv, I2C_SLVT, 0x43, data, 2); ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); + /* Enable ADC 4 */ -+ cxd2837er_write_reg(priv, I2C_SLVX, 0x18, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); + /* Set SLV-T Bank : 0x10 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); + /* IFAGC gain settings */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x09, 0x1f); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x09, 0x1f); + /* Set SLV-T Bank : 0x11 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x11); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); + /* BBAGC TARGET level setting */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x6a, 0x48); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x48); + /* Set SLV-T Bank : 0x10 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); + /* ASCOT setting ON */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 0x01, 0x01); + /* Set SLV-T Bank : 0x40 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x40); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); + /* Demod setting */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xc3, 0x00, 0x04); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc3, 0x00, 0x04); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* TSIF setting */ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); + -+ cxd2837er_sleep_tc_to_active_c_band(priv, 8000000); ++ cxd2841er_sleep_tc_to_active_c_band(priv, bandwidth); + /* Set SLV-T Bank : 0x00 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); + /* Disable HiZ Setting 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x80, 0x28); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28); + /* Disable HiZ Setting 2 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x81, 0x00); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00); + priv->state = STATE_ACTIVE_TC; + return 0; +} + -+static int cxd2837er_get_frontend(struct dvb_frontend *fe) ++static int cxd2841er_get_frontend(struct dvb_frontend *fe, ++ struct dtv_frontend_properties *p) +{ + enum fe_status status = 0; -+ u16 strength = 0, snr = 0; -+ u32 errors = 0, ber = 0; -+ struct cxd2837er_priv *priv = fe->demodulator_priv; -+ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ if (priv->state == STATE_ACTIVE_TC) -+ cxd2837er_read_status_tc(fe, &status); ++ if (priv->state == STATE_ACTIVE_S) ++ cxd2841er_read_status_s(fe, &status); ++ else if (priv->state == STATE_ACTIVE_TC) ++ cxd2841er_read_status_tc(fe, &status); ++ ++ cxd2841er_read_signal_strength(fe); + + if (status & FE_HAS_LOCK) { -+ cxd2837er_read_signal_strength(fe, &strength); -+ p->strength.len = 1; -+ p->strength.stat[0].scale = FE_SCALE_RELATIVE; -+ p->strength.stat[0].uvalue = strength; -+ cxd2837er_read_snr(fe, &snr); -+ p->cnr.len = 1; -+ p->cnr.stat[0].scale = FE_SCALE_DECIBEL; -+ p->cnr.stat[0].svalue = snr; -+ cxd2837er_read_ucblocks(fe, &errors); -+ p->block_error.len = 1; -+ p->block_error.stat[0].scale = FE_SCALE_COUNTER; -+ p->block_error.stat[0].uvalue = errors; -+ cxd2837er_read_ber(fe, &ber); -+ p->post_bit_error.len = 1; -+ p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; -+ p->post_bit_error.stat[0].uvalue = ber; ++ cxd2841er_read_snr(fe); ++ cxd2841er_read_ucblocks(fe); ++ ++ cxd2841er_read_ber(fe); + } else { -+ p->strength.len = 1; -+ p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ p->cnr.len = 1; + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ p->block_error.len = 1; + p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; -+ p->post_bit_error.len = 1; + p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + } + return 0; +} + -+static int cxd2837er_set_frontend_tc(struct dvb_frontend *fe) ++static int cxd2841er_set_frontend_s(struct dvb_frontend *fe) ++{ ++ int ret = 0, i, timeout, carr_offset; ++ enum fe_status status; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ u32 symbol_rate = p->symbol_rate/1000; ++ ++ dev_dbg(&priv->i2c->dev, "%s(): %s frequency=%d symbol_rate=%d xtal=%d\n", ++ __func__, ++ (p->delivery_system == SYS_DVBS ? "DVB-S" : "DVB-S2"), ++ p->frequency, symbol_rate, priv->xtal); ++ switch (priv->state) { ++ case STATE_SLEEP_S: ++ ret = cxd2841er_sleep_s_to_active_s( ++ priv, p->delivery_system, symbol_rate); ++ break; ++ case STATE_ACTIVE_S: ++ ret = cxd2841er_retune_active(priv, p); ++ break; ++ default: ++ dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", ++ __func__, priv->state); ++ ret = -EINVAL; ++ goto done; ++ } ++ if (ret) { ++ dev_dbg(&priv->i2c->dev, "%s(): tune failed\n", __func__); ++ goto done; ++ } ++ if (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 (fe->ops.i2c_gate_ctrl) ++ fe->ops.i2c_gate_ctrl(fe, 0); ++ cxd2841er_tune_done(priv); ++ timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150; ++ for (i = 0; i < timeout / CXD2841ER_DVBS_POLLING_INVL; i++) { ++ usleep_range(CXD2841ER_DVBS_POLLING_INVL*1000, ++ (CXD2841ER_DVBS_POLLING_INVL + 2) * 1000); ++ cxd2841er_read_status_s(fe, &status); ++ if (status & FE_HAS_LOCK) ++ break; ++ } ++ if (status & FE_HAS_LOCK) { ++ if (cxd2841er_get_carrier_offset_s_s2( ++ priv, &carr_offset)) { ++ ret = -EINVAL; ++ goto done; ++ } ++ dev_dbg(&priv->i2c->dev, "%s(): carrier_offset=%d\n", ++ __func__, carr_offset); ++ } ++done: ++ /* Reset stats */ ++ p->strength.stat[0].scale = FE_SCALE_RELATIVE; ++ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ ++ return ret; ++} ++ ++static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe) +{ + int ret = 0, timeout; + enum fe_status status; -+ struct cxd2837er_priv *priv = fe->demodulator_priv; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + -+ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); ++ ++ dev_dbg(&priv->i2c->dev, "%s() delivery_system=%d bandwidth_hz=%d\n", ++ __func__, p->delivery_system, p->bandwidth_hz); ++ ++ ++ cxd2841er_active_t_to_sleep_tc(priv); ++ cxd2841er_sleep_tc_to_shutdown(priv); ++ cxd2841er_init_tc(fe); ++ + if (p->delivery_system == SYS_DVBT) { + priv->system = SYS_DVBT; + switch (priv->state) { + case STATE_SLEEP_TC: -+ ret = cxd2837er_sleep_tc_to_active_t( ++ ret = cxd2841er_sleep_tc_to_active_t( + priv, p->bandwidth_hz); + break; + case STATE_ACTIVE_TC: -+ ret = cxd2837er_retune_active(priv, p); ++ ret = cxd2841er_retune_active(priv, p); + break; + default: + dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", @@ -38154,32 +39901,56 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + } + } else if (p->delivery_system == SYS_DVBT2) { + priv->system = SYS_DVBT2; -+ cxd2837er_dvbt2_set_plp_config(priv, ++ cxd2841er_dvbt2_set_plp_config(priv, + (int)(p->stream_id > 255), p->stream_id); -+ cxd2837er_dvbt2_set_profile(priv, DVBT2_PROFILE_BASE); ++ cxd2841er_dvbt2_set_profile(priv, DVBT2_PROFILE_BASE); + switch (priv->state) { + case STATE_SLEEP_TC: -+ ret = cxd2837er_sleep_tc_to_active_t2(priv, ++ ret = cxd2841er_sleep_tc_to_active_t2(priv, + p->bandwidth_hz); + break; + case STATE_ACTIVE_TC: -+ ret = cxd2837er_retune_active(priv, p); ++ ret = cxd2841er_retune_active(priv, p); + break; + default: + dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", + __func__, priv->state); + ret = -EINVAL; + } ++ } else if (p->delivery_system == SYS_ISDBT) { ++ priv->system = SYS_ISDBT; ++ switch (priv->state) { ++ case STATE_SLEEP_TC: ++ ret = cxd2841er_sleep_tc_to_active_i( ++ priv, p->bandwidth_hz); ++ break; ++ case STATE_ACTIVE_TC: ++ ret = cxd2841er_retune_active(priv, p); ++ break; ++ default: ++ dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", ++ __func__, priv->state); ++ ret = -EINVAL; ++ } + } else if (p->delivery_system == SYS_DVBC_ANNEX_A || + p->delivery_system == SYS_DVBC_ANNEX_C) { + priv->system = SYS_DVBC_ANNEX_A; ++ /* correct bandwidth */ ++ if (p->bandwidth_hz != 6000000 && ++ p->bandwidth_hz != 7000000 && ++ p->bandwidth_hz != 8000000) { ++ p->bandwidth_hz = 8000000; ++ dev_dbg(&priv->i2c->dev, "%s(): forcing bandwidth to %d\n", ++ __func__, p->bandwidth_hz); ++ } ++ + switch (priv->state) { + case STATE_SLEEP_TC: -+ ret = cxd2837er_sleep_tc_to_active_c( ++ ret = cxd2841er_sleep_tc_to_active_c( + priv, p->bandwidth_hz); + break; + case STATE_ACTIVE_TC: -+ ret = cxd2837er_retune_active(priv, p); ++ ret = cxd2841er_retune_active(priv, p); + break; + default: + dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", @@ -38200,10 +39971,10 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + fe->ops.tuner_ops.set_params(fe); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); -+ cxd2837er_tune_done(priv); ++ cxd2841er_tune_done(priv); + timeout = 2500; + while (timeout > 0) { -+ ret = cxd2837er_read_status_tc(fe, &status); ++ ret = cxd2841er_read_status_tc(fe, &status); + if (ret) + goto done; + if (status & FE_HAS_LOCK) @@ -38218,33 +39989,81 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + return ret; +} + -+static int cxd2837er_tune_tc(struct dvb_frontend *fe, ++static int cxd2841er_tune_s(struct dvb_frontend *fe, ++ bool re_tune, ++ unsigned int mode_flags, ++ unsigned int *delay, ++ enum fe_status *status) ++{ ++ int ret, carrier_offset; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ ++ dev_dbg(&priv->i2c->dev, "%s() re_tune=%d\n", __func__, re_tune); ++ if (re_tune) { ++ ret = cxd2841er_set_frontend_s(fe); ++ if (ret) ++ return ret; ++ cxd2841er_read_status_s(fe, status); ++ if (*status & FE_HAS_LOCK) { ++ if (cxd2841er_get_carrier_offset_s_s2( ++ priv, &carrier_offset)) ++ return -EINVAL; ++ p->frequency += carrier_offset; ++ ret = cxd2841er_set_frontend_s(fe); ++ if (ret) ++ return ret; ++ } ++ } ++ *delay = HZ / 5; ++ return cxd2841er_read_status_s(fe, status); ++} ++ ++static int cxd2841er_tune_tc(struct dvb_frontend *fe, + bool re_tune, + unsigned int mode_flags, + unsigned int *delay, + enum fe_status *status) +{ + int ret, carrier_offset; -+ struct cxd2837er_priv *priv = fe->demodulator_priv; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; + struct dtv_frontend_properties *p = &fe->dtv_property_cache; + -+ dev_dbg(&priv->i2c->dev, "%s(): re_tune %d\n", __func__, re_tune); ++ dev_dbg(&priv->i2c->dev, "%s(): re_tune %d bandwidth=%d\n", __func__, ++ re_tune, p->bandwidth_hz); + if (re_tune) { -+ ret = cxd2837er_set_frontend_tc(fe); ++ ret = cxd2841er_set_frontend_tc(fe); + if (ret) + return ret; -+ cxd2837er_read_status_tc(fe, status); ++ cxd2841er_read_status_tc(fe, status); + if (*status & FE_HAS_LOCK) { + switch (priv->system) { ++ case SYS_ISDBT: ++ ret = cxd2841er_get_carrier_offset_i( ++ priv, p->bandwidth_hz, ++ &carrier_offset); ++ if (ret) ++ return ret; ++ break; + case SYS_DVBT: -+ case SYS_DVBT2: -+ ret = cxd2837er_get_carrier_offset_t2( ++ ret = cxd2841er_get_carrier_offset_t( + priv, p->bandwidth_hz, + &carrier_offset); ++ if (ret) ++ return ret; ++ break; ++ case SYS_DVBT2: ++ ret = cxd2841er_get_carrier_offset_t2( ++ priv, p->bandwidth_hz, ++ &carrier_offset); ++ if (ret) ++ return ret; + break; + case SYS_DVBC_ANNEX_A: -+ ret = cxd2837er_get_carrier_offset_c( ++ ret = cxd2841er_get_carrier_offset_c( + priv, &carrier_offset); ++ if (ret) ++ return ret; + break; + default: + dev_dbg(&priv->i2c->dev, @@ -38252,35 +40071,46 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + __func__, priv->system); + return -EINVAL; + } -+ if (ret) -+ return ret; + dev_dbg(&priv->i2c->dev, "%s(): carrier offset %d\n", + __func__, carrier_offset); + p->frequency += carrier_offset; -+ ret = cxd2837er_set_frontend_tc(fe); ++ ret = cxd2841er_set_frontend_tc(fe); + if (ret) + return ret; + } + } + *delay = HZ / 5; -+ return cxd2837er_read_status_tc(fe, status); ++ return cxd2841er_read_status_tc(fe, status); +} + -+static int cxd2837er_sleep_tc(struct dvb_frontend *fe) ++static int cxd2841er_sleep_s(struct dvb_frontend *fe) +{ -+ struct cxd2837er_priv *priv = fe->demodulator_priv; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; ++ ++ dev_dbg(&priv->i2c->dev, "%s()\n", __func__); ++ cxd2841er_active_s_to_sleep_s(fe->demodulator_priv); ++ cxd2841er_sleep_s_to_shutdown(fe->demodulator_priv); ++ return 0; ++} ++ ++static int cxd2841er_sleep_tc(struct dvb_frontend *fe) ++{ ++ struct cxd2841er_priv *priv = fe->demodulator_priv; + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + if (priv->state == STATE_ACTIVE_TC) { + switch (priv->system) { + case SYS_DVBT: -+ cxd2837er_active_t_to_sleep_tc(priv); ++ cxd2841er_active_t_to_sleep_tc(priv); + break; + case SYS_DVBT2: -+ cxd2837er_active_t2_to_sleep_tc(priv); ++ cxd2841er_active_t2_to_sleep_tc(priv); ++ break; ++ case SYS_ISDBT: ++ cxd2841er_active_i_to_sleep_tc(priv); + break; + case SYS_DVBC_ANNEX_A: -+ cxd2837er_active_c_to_sleep_tc(priv); ++ cxd2841er_active_c_to_sleep_tc(priv); + break; + default: + dev_warn(&priv->i2c->dev, @@ -38293,106 +40123,313 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + __func__, priv->state); + return -EINVAL; + } -+ cxd2837er_sleep_tc_to_shutdown(priv); ++ cxd2841er_sleep_tc_to_shutdown(priv); + return 0; +} + -+static void cxd2837er_release(struct dvb_frontend *fe) ++static int cxd2841er_send_burst(struct dvb_frontend *fe, ++ enum fe_sec_mini_cmd burst) +{ -+ struct cxd2837er_priv *priv = fe->demodulator_priv; ++ u8 data; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; ++ ++ dev_dbg(&priv->i2c->dev, "%s(): burst mode %s\n", __func__, ++ (burst == SEC_MINI_A ? "A" : "B")); ++ if (priv->state != STATE_SLEEP_S && ++ priv->state != STATE_ACTIVE_S) { ++ dev_err(&priv->i2c->dev, "%s(): invalid demod state %d\n", ++ __func__, priv->state); ++ return -EINVAL; ++ } ++ data = (burst == SEC_MINI_A ? 0 : 1); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xbb); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x34, 0x01); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x35, data); ++ return 0; ++} ++ ++static int cxd2841er_set_tone(struct dvb_frontend *fe, ++ enum fe_sec_tone_mode tone) ++{ ++ u8 data; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; ++ ++ dev_dbg(&priv->i2c->dev, "%s(): tone %s\n", __func__, ++ (tone == SEC_TONE_ON ? "On" : "Off")); ++ if (priv->state != STATE_SLEEP_S && ++ priv->state != STATE_ACTIVE_S) { ++ dev_err(&priv->i2c->dev, "%s(): invalid demod state %d\n", ++ __func__, priv->state); ++ return -EINVAL; ++ } ++ data = (tone == SEC_TONE_ON ? 1 : 0); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xbb); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x36, data); ++ return 0; ++} ++ ++static int cxd2841er_send_diseqc_msg(struct dvb_frontend *fe, ++ struct dvb_diseqc_master_cmd *cmd) ++{ ++ int i; ++ u8 data[12]; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; ++ ++ if (priv->state != STATE_SLEEP_S && ++ priv->state != STATE_ACTIVE_S) { ++ dev_err(&priv->i2c->dev, "%s(): invalid demod state %d\n", ++ __func__, priv->state); ++ return -EINVAL; ++ } ++ dev_dbg(&priv->i2c->dev, ++ "%s(): cmd->len %d\n", __func__, cmd->msg_len); ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xbb); ++ /* DiDEqC enable */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x33, 0x01); ++ /* cmd1 length & data */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x3d, cmd->msg_len); ++ memset(data, 0, sizeof(data)); ++ for (i = 0; i < cmd->msg_len && i < sizeof(data); i++) ++ data[i] = cmd->msg[i]; ++ cxd2841er_write_regs(priv, I2C_SLVT, 0x3e, data, sizeof(data)); ++ /* repeat count for cmd1 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x37, 1); ++ /* repeat count for cmd2: always 0 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x38, 0); ++ /* start transmit */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x32, 0x01); ++ /* wait for 1 sec timeout */ ++ for (i = 0; i < 50; i++) { ++ cxd2841er_read_reg(priv, I2C_SLVT, 0x10, data); ++ if (!data[0]) { ++ dev_dbg(&priv->i2c->dev, ++ "%s(): DiSEqC cmd has been sent\n", __func__); ++ return 0; ++ } ++ msleep(20); ++ } ++ dev_dbg(&priv->i2c->dev, ++ "%s(): DiSEqC cmd transmit timeout\n", __func__); ++ return -ETIMEDOUT; ++} ++ ++static void cxd2841er_release(struct dvb_frontend *fe) ++{ ++ struct cxd2841er_priv *priv = fe->demodulator_priv; + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + kfree(priv); +} + -+static int cxd2837er_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) ++static int cxd2841er_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ -+ struct cxd2837er_priv *priv = fe->demodulator_priv; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; + + dev_dbg(&priv->i2c->dev, "%s(): enable=%d\n", __func__, enable); -+ cxd2837er_set_reg_bits( ++ cxd2841er_set_reg_bits( + priv, I2C_SLVX, 0x8, (enable ? 0x01 : 0x00), 0x01); + return 0; +} + -+static enum dvbfe_algo cxd2837er_get_algo(struct dvb_frontend *fe) ++static enum dvbfe_algo cxd2841er_get_algo(struct dvb_frontend *fe) +{ -+ struct cxd2837er_priv *priv = fe->demodulator_priv; ++ struct cxd2841er_priv *priv = fe->demodulator_priv; + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); + return DVBFE_ALGO_HW; +} + -+static int cxd2837er_init_tc(struct dvb_frontend *fe) ++static void cxd2841er_init_stats(struct dvb_frontend *fe) +{ -+ struct cxd2837er_priv *priv = fe->demodulator_priv; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; ++ ++ p->strength.len = 1; ++ p->strength.stat[0].scale = FE_SCALE_RELATIVE; ++ p->cnr.len = 1; ++ p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ p->block_error.len = 1; ++ p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ p->post_bit_error.len = 1; ++ p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++ p->post_bit_count.len = 1; ++ p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; ++} ++ ++ ++static int cxd2841er_init_s(struct dvb_frontend *fe) ++{ ++ struct cxd2841er_priv *priv = fe->demodulator_priv; ++ ++ /* sanity. force demod to SHUTDOWN state */ ++ if (priv->state == STATE_SLEEP_S) { ++ dev_dbg(&priv->i2c->dev, "%s() forcing sleep->shutdown\n", ++ __func__); ++ cxd2841er_sleep_s_to_shutdown(priv); ++ } else if (priv->state == STATE_ACTIVE_S) { ++ dev_dbg(&priv->i2c->dev, "%s() forcing active->sleep->shutdown\n", ++ __func__); ++ cxd2841er_active_s_to_sleep_s(priv); ++ cxd2841er_sleep_s_to_shutdown(priv); ++ } + + dev_dbg(&priv->i2c->dev, "%s()\n", __func__); -+ cxd2837er_shutdown_to_sleep_tc(priv); -+ /* SONY_DEMOD_CONFIG_IFAGCNEG = 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x10); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xcb, -+ priv->config->if_agc ? 0x40 : 0x00, 0x40); -+ /* SONY_DEMOD_CONFIG_IFAGC_ADC_FS = 0 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0xcd, -+ priv->config->ifagc_adc_range); -+ /* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */ -+ cxd2837er_write_reg(priv, I2C_SLVT, 0x00, 0x00); -+ -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xCB, -+ priv->config->ts_error_polarity ? 0x00 : 0x01, 0x01); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xC5, -+ priv->config->clock_polarity ? 0x01 : 0x00, 0x01); -+ cxd2837er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x80); ++ cxd2841er_shutdown_to_sleep_s(priv); ++ /* SONY_DEMOD_CONFIG_SAT_IFAGCNEG set to 1 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xb9, 0x01, 0x01); ++ ++ cxd2841er_init_stats(fe); ++ + return 0; +} + -+static struct dvb_frontend_ops cxd2837er_ops; ++static int cxd2841er_init_tc(struct dvb_frontend *fe) ++{ ++ struct cxd2841er_priv *priv = fe->demodulator_priv; ++ struct dtv_frontend_properties *p = &fe->dtv_property_cache; + -+struct dvb_frontend *cxd2837er_attach(struct cxd2837er_config *cfg, -+ struct i2c_adapter *i2c) ++ dev_dbg(&priv->i2c->dev, "%s() bandwidth_hz=%d\n", ++ __func__, p->bandwidth_hz); ++ cxd2841er_shutdown_to_sleep_tc(priv); ++ /* SONY_DEMOD_CONFIG_IFAGCNEG = 1 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcb, ++ priv->config->if_agc ? 0x40 : 0x00, 0x40); ++ /* SONY_DEMOD_CONFIG_IFAGC_ADC_FS = 0 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0xcd, ++ priv->config->ifagc_adc_range); ++ /* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */ ++ cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xCB, ++ priv->config->ts_error_polarity ? 0x00 : 0x01, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xC5, ++ priv->config->clock_polarity ? 0x01 : 0x00, 0x01); ++ cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x80); ++ ++ cxd2841er_init_stats(fe); ++ ++ return 0; ++} ++ ++static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops; ++static struct dvb_frontend_ops cxd2841er_t_c_ops; ++ ++static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg, ++ struct i2c_adapter *i2c, ++ u8 system) +{ + u8 chip_id = 0; -+ struct cxd2837er_priv *priv = NULL; ++ const char *type; ++ const char *name; ++ struct cxd2841er_priv *priv = NULL; + + /* allocate memory for the internal state */ -+ priv = kzalloc(sizeof(struct cxd2837er_priv), GFP_KERNEL); ++ priv = kzalloc(sizeof(struct cxd2841er_priv), GFP_KERNEL); + if (!priv) + return NULL; + priv->i2c = i2c; + priv->config = cfg; + priv->i2c_addr_slvx = cfg->i2c_addr + 2; + priv->i2c_addr_slvt = cfg->i2c_addr; -+ -+ memcpy(&priv->frontend.ops, -+ &cxd2837er_ops, -+ sizeof(struct dvb_frontend_ops)); -+ ++ priv->xtal = cfg->xtal; + priv->frontend.demodulator_priv = priv; + dev_info(&priv->i2c->dev, -+ "%s(): attaching CXD2837 frontend\n", -+ __func__); -+ dev_info(&priv->i2c->dev, + "%s(): I2C adapter %p SLVX addr %x SLVT addr %x\n", + __func__, priv->i2c, + priv->i2c_addr_slvx, priv->i2c_addr_slvt); -+ chip_id = cxd2837er_chip_id(priv); -+ if (chip_id != CXD2837ER_CHIP_ID) { ++ chip_id = cxd2841er_chip_id(priv); ++ switch (chip_id) { ++ case CXD2837ER_CHIP_ID: ++ snprintf(cxd2841er_t_c_ops.info.name, 128, ++ "Sony CXD2837ER DVB-T/T2/C demodulator"); ++ name = "CXD2837ER"; ++ break; ++ case CXD2841ER_CHIP_ID: ++ snprintf(cxd2841er_t_c_ops.info.name, 128, ++ "Sony CXD2841ER DVB-T/T2/C demodulator"); ++ name = "CXD2841ER"; ++ break; ++ case CXD2854ER_CHIP_ID: ++ snprintf(cxd2841er_t_c_ops.info.name, 128, ++ "Sony CXD2854ER DVB-T/T2/C and ISDB-T demodulator"); ++ cxd2841er_t_c_ops.delsys[3] = SYS_ISDBT; ++ name = "CXD2854ER"; ++ break; ++ default: + dev_err(&priv->i2c->dev, "%s(): invalid chip ID 0x%02x\n", -+ __func__, chip_id); ++ __func__, chip_id); + priv->frontend.demodulator_priv = NULL; + kfree(priv); + return NULL; + } ++ ++ /* create dvb_frontend */ ++ if (system == SYS_DVBS) { ++ memcpy(&priv->frontend.ops, ++ &cxd2841er_dvbs_s2_ops, ++ sizeof(struct dvb_frontend_ops)); ++ type = "S/S2"; ++ } else { ++ memcpy(&priv->frontend.ops, ++ &cxd2841er_t_c_ops, ++ sizeof(struct dvb_frontend_ops)); ++ type = "T/T2/C/ISDB-T"; ++ } ++ ++ dev_info(&priv->i2c->dev, ++ "%s(): attaching %s DVB-%s frontend\n", ++ __func__, name, type); + dev_info(&priv->i2c->dev, "%s(): chip ID 0x%02x OK.\n", + __func__, chip_id); + return &priv->frontend; +} + -+static struct dvb_frontend_ops cxd2837er_ops = { ++struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg, ++ struct i2c_adapter *i2c) ++{ ++ return cxd2841er_attach(cfg, i2c, SYS_DVBS); ++} ++EXPORT_SYMBOL(cxd2841er_attach_s); ++ ++struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg, ++ struct i2c_adapter *i2c) ++{ ++ return cxd2841er_attach(cfg, i2c, 0); ++} ++EXPORT_SYMBOL(cxd2841er_attach_t_c); ++ ++static struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = { ++ .delsys = { SYS_DVBS, SYS_DVBS2 }, ++ .info = { ++ .name = "Sony CXD2841ER DVB-S/S2 demodulator", ++ .frequency_min = 500000, ++ .frequency_max = 2500000, ++ .frequency_stepsize = 0, ++ .symbol_rate_min = 1000000, ++ .symbol_rate_max = 45000000, ++ .symbol_rate_tolerance = 500, ++ .caps = FE_CAN_INVERSION_AUTO | ++ FE_CAN_FEC_AUTO | ++ FE_CAN_QPSK, ++ }, ++ .init = cxd2841er_init_s, ++ .sleep = cxd2841er_sleep_s, ++ .release = cxd2841er_release, ++ .set_frontend = cxd2841er_set_frontend_s, ++ .get_frontend = cxd2841er_get_frontend, ++ .read_status = cxd2841er_read_status_s, ++ .i2c_gate_ctrl = cxd2841er_i2c_gate_ctrl, ++ .get_frontend_algo = cxd2841er_get_algo, ++ .set_tone = cxd2841er_set_tone, ++ .diseqc_send_burst = cxd2841er_send_burst, ++ .diseqc_send_master_cmd = cxd2841er_send_diseqc_msg, ++ .tune = cxd2841er_tune_s ++}; ++ ++static struct dvb_frontend_ops cxd2841er_t_c_ops = { + .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A }, + .info = { -+ .name = "Sony CXD2837 DVB-T/T2/C demodulator", ++ .name = "", /* will set in attach function */ + .caps = FE_CAN_FEC_1_2 | + FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | @@ -38406,7 +40443,6 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + FE_CAN_QAM_128 | + FE_CAN_QAM_256 | + FE_CAN_QAM_AUTO | -+ FE_CAN_INVERSION_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | @@ -38415,33 +40451,28 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.c b/drivers/amlogic/dvb_tv/cxd2837 + .frequency_min = 42000000, + .frequency_max = 1002000000 + }, -+ .init = cxd2837er_init_tc, -+ .read_ber = cxd2837er_read_ber, -+ .sleep = cxd2837er_sleep_tc, -+ .release = cxd2837er_release, -+ .set_frontend = cxd2837er_set_frontend_tc, -+ .get_frontend = cxd2837er_get_frontend, -+ .read_status = cxd2837er_read_status_tc, -+ .tune = cxd2837er_tune_tc, -+ .i2c_gate_ctrl = cxd2837er_i2c_gate_ctrl, -+ .get_frontend_algo = cxd2837er_get_algo ++ .init = cxd2841er_init_tc, ++ .sleep = cxd2841er_sleep_tc, ++ .release = cxd2841er_release, ++ .set_frontend = cxd2841er_set_frontend_tc, ++ .get_frontend = cxd2841er_get_frontend, ++ .read_status = cxd2841er_read_status_tc, ++ .tune = cxd2841er_tune_tc, ++ .i2c_gate_ctrl = cxd2841er_i2c_gate_ctrl, ++ .get_frontend_algo = cxd2841er_get_algo +}; + -+MODULE_DESCRIPTION("Sony CXD2837ER DVB-C/T/T2/ demodulator driver"); -+MODULE_AUTHOR("sasa.savic.sr@gmail.com"); ++MODULE_DESCRIPTION("Sony CXD2841ER/CXD2854ER DVB-C/C2/T/T2/S/S2 demodulator driver"); ++MODULE_AUTHOR("Sergey Kozlov , Abylay Ospan "); +MODULE_LICENSE("GPL"); -diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.h b/drivers/amlogic/dvb_tv/cxd2837er.h ---- a/drivers/amlogic/dvb_tv/cxd2837er.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/cxd2837er.h 2016-02-10 22:34:51.000000000 +0100 -@@ -0,0 +1,56 @@ +diff -Naur a/drivers/amlogic/dvb_tv/cxd2841er.h b/drivers/amlogic/dvb_tv/cxd2841er.h +--- a/drivers/amlogic/dvb_tv/cxd2841er.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/cxd2841er.h 2016-09-21 18:00:41.000000000 +0200 +@@ -0,0 +1,50 @@ +/* -+ * cxd2837er.h ++ * cxd2841er.h + * -+ * Sony CXD2837ER digital demodulator driver -+ * -+ * Copyright (C) 2015 Sasa Savic -+ * -+ * Based on CXD2841ER driver ++ * Sony CXD2441ER digital demodulator driver public definitions + * + * Copyright 2012 Sony Corporation + * Copyright (C) 2014 NetUP Inc. @@ -38459,36 +40490,83 @@ diff -Naur a/drivers/amlogic/dvb_tv/cxd2837er.h b/drivers/amlogic/dvb_tv/cxd2837 + * GNU General Public License for more details. + */ + -+#ifndef CXD2837ER_H -+#define CXD2837ER_H ++#ifndef CXD2841ER_H ++#define CXD2841ER_H + +#include +#include + -+struct cxd2837er_config { ++enum cxd2841er_xtal { ++ SONY_XTAL_20500, /* 20.5 MHz */ ++ SONY_XTAL_24000, /* 24 MHz */ ++ SONY_XTAL_41000 /* 41 MHz */ ++}; ++ ++struct cxd2841er_config { + u8 i2c_addr; + u8 if_agc; + u8 ifagc_adc_range; + u8 ts_error_polarity; + u8 clock_polarity; -+ u8 mxl603; ++ u8 mxl603; ++ enum cxd2841er_xtal xtal; +}; + ++extern struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg, ++ struct i2c_adapter *i2c); ++ ++extern struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg, ++ struct i2c_adapter *i2c); ++ ++#endif +diff -Naur a/drivers/amlogic/dvb_tv/cxd2841er_priv.h b/drivers/amlogic/dvb_tv/cxd2841er_priv.h +--- a/drivers/amlogic/dvb_tv/cxd2841er_priv.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/cxd2841er_priv.h 2016-09-21 17:56:25.000000000 +0200 +@@ -0,0 +1,45 @@ ++/* ++ * cxd2841er_priv.h ++ * ++ * Sony CXD2441ER digital demodulator driver internal definitions ++ * ++ * Copyright 2012 Sony Corporation ++ * Copyright (C) 2014 NetUP Inc. ++ * Copyright (C) 2014 Sergey Kozlov ++ * Copyright (C) 2014 Abylay Ospan ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef CXD2841ER_PRIV_H ++#define CXD2841ER_PRIV_H ++ +#define I2C_SLVX 0 +#define I2C_SLVT 1 + ++#define CXD2841ER_CHIP_ID 0xa7 ++#define CXD2854ER_CHIP_ID 0xc1 +#define CXD2837ER_CHIP_ID 0xb1 + -+enum cxd2837er_dvbt2_profile_t { ++#define CXD2841ER_DVBS_POLLING_INVL 10 ++ ++struct cxd2841er_cnr_data { ++ u32 value; ++ int cnr_x1000; ++}; ++ ++enum cxd2841er_dvbt2_profile_t { + DVBT2_PROFILE_ANY = 0, + DVBT2_PROFILE_BASE = 1, + DVBT2_PROFILE_LITE = 2 +}; + -+ -+extern struct dvb_frontend *cxd2837er_attach(struct cxd2837er_config *cfg, -+ struct i2c_adapter *i2c); -+ +#endif diff -Naur a/drivers/amlogic/dvb_tv/Kconfig b/drivers/amlogic/dvb_tv/Kconfig --- a/drivers/amlogic/dvb_tv/Kconfig 2016-09-14 16:08:31.000000000 +0200 @@ -38789,7 +40867,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/Kconfig b/drivers/amlogic/dvb_tv/Kconfig diff -Naur a/drivers/amlogic/dvb_tv/Makefile b/drivers/amlogic/dvb_tv/Makefile --- a/drivers/amlogic/dvb_tv/Makefile 2016-09-14 16:08:31.000000000 +0200 -+++ b/drivers/amlogic/dvb_tv/Makefile 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/Makefile 2016-09-21 19:04:21.000000000 +0200 @@ -1,62 +1,10 @@ # -# Makefile for the DVB driver. @@ -38800,7 +40878,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/Makefile b/drivers/amlogic/dvb_tv/Makefile +obj-$(CONFIG_AM_DVB) += wetekplay.o -aml-objs=aml_dvb.o aml_dmx.o -+wetekplay-objs = nimdetect.o mxl603.o avl6211.o mn88436.o cxd2837er.o ascot3.o ++wetekplay-objs = nimdetect.o mxl603.o avl6211.o mn88436.o cxd2841er.o ascot3.o -obj-$(CONFIG_AM_DVB) += aml_fe.o - @@ -38860,7 +40938,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/Makefile b/drivers/amlogic/dvb_tv/Makefile +EXTRA_CFLAGS += -I. diff -Naur a/drivers/amlogic/dvb_tv/mn88436.c b/drivers/amlogic/dvb_tv/mn88436.c --- a/drivers/amlogic/dvb_tv/mn88436.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/mn88436.c 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/mn88436.c 2016-09-19 19:36:24.000000000 +0200 @@ -0,0 +1,379 @@ +/* + * Driver for the Panasonic MN88436 ATSC demodulator @@ -39243,7 +41321,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/mn88436.c b/drivers/amlogic/dvb_tv/mn88436.c +MODULE_LICENSE("GPL"); diff -Naur a/drivers/amlogic/dvb_tv/mn88436.h b/drivers/amlogic/dvb_tv/mn88436.h --- a/drivers/amlogic/dvb_tv/mn88436.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/mn88436.h 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/mn88436.h 2016-09-19 19:36:24.000000000 +0200 @@ -0,0 +1,47 @@ +/* + * Driver for the Panasonic MN88436 ATSC demodulator @@ -39295,7 +41373,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/mn88436.h b/drivers/amlogic/dvb_tv/mn88436.h \ No newline at end of file diff -Naur a/drivers/amlogic/dvb_tv/mxl603.c b/drivers/amlogic/dvb_tv/mxl603.c --- a/drivers/amlogic/dvb_tv/mxl603.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/mxl603.c 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/mxl603.c 2016-09-19 19:36:24.000000000 +0200 @@ -0,0 +1,1096 @@ +/* + * Driver for the MaxLinear MxL603 tuner @@ -40395,7 +42473,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/mxl603.c b/drivers/amlogic/dvb_tv/mxl603.c +MODULE_LICENSE("GPL"); diff -Naur a/drivers/amlogic/dvb_tv/mxl603.h b/drivers/amlogic/dvb_tv/mxl603.h --- a/drivers/amlogic/dvb_tv/mxl603.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/mxl603.h 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/mxl603.h 2016-09-19 19:36:24.000000000 +0200 @@ -0,0 +1,83 @@ +/* + * Driver for the MaxLinear MxL603 tuner @@ -40482,8 +42560,8 @@ diff -Naur a/drivers/amlogic/dvb_tv/mxl603.h b/drivers/amlogic/dvb_tv/mxl603.h +#endif /* __MXL603_H__ */ diff -Naur a/drivers/amlogic/dvb_tv/nimdetect.c b/drivers/amlogic/dvb_tv/nimdetect.c --- a/drivers/amlogic/dvb_tv/nimdetect.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/nimdetect.c 2016-02-10 22:50:46.000000000 +0100 -@@ -0,0 +1,595 @@ ++++ b/drivers/amlogic/dvb_tv/nimdetect.c 2016-09-21 18:40:46.000000000 +0200 +@@ -0,0 +1,596 @@ +/* + * Wetek NIMs/DVB detection + * @@ -40515,7 +42593,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/nimdetect.c b/drivers/amlogic/dvb_tv/nimdete +#include "nimdetect.h" + +#include "ascot3.h" -+#include "cxd2837er.h" ++#include "cxd2841er.h" +#include "mxl603.h" +#include "avl6211.h" +#include "mn88436.h" @@ -40536,13 +42614,14 @@ diff -Naur a/drivers/amlogic/dvb_tv/nimdetect.c b/drivers/amlogic/dvb_tv/nimdete + +static struct wetek_nims weteknims; + -+static struct cxd2837er_config cxd2837cfg = { ++static struct cxd2841er_config cxd2837cfg = { + .i2c_addr = 0x6C, + .if_agc = 0, + .ifagc_adc_range = 0x39, + .ts_error_polarity = 0, + .clock_polarity = 1, + .mxl603 = 0, ++ .xtal = SONY_XTAL_20500, +}; +struct ascot3_config ascot3cfg = { + .i2c_address = 0x60, @@ -40855,7 +42934,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/nimdetect.c b/drivers/amlogic/dvb_tv/nimdete + + dev_info(&pdev->dev, "Checking for Sony CXD2837 DVB-C/T/T2 demod ...\n"); + -+ weteknims.fe[i] = cxd2837er_attach(&cxd2837cfg, weteknims.i2c[i]); ++ weteknims.fe[i] = cxd2841er_attach_t_c(&cxd2837cfg, weteknims.i2c[i]); + + if (weteknims.fe[i] != NULL) { + if (mxl603_attach(weteknims.fe[i], weteknims.i2c[i], 0x60, &mxl603cfg) == NULL) { @@ -41081,7 +43160,7 @@ diff -Naur a/drivers/amlogic/dvb_tv/nimdetect.c b/drivers/amlogic/dvb_tv/nimdete +MODULE_LICENSE("GPL"); diff -Naur a/drivers/amlogic/dvb_tv/nimdetect.h b/drivers/amlogic/dvb_tv/nimdetect.h --- a/drivers/amlogic/dvb_tv/nimdetect.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/drivers/amlogic/dvb_tv/nimdetect.h 2016-02-10 22:34:51.000000000 +0100 ++++ b/drivers/amlogic/dvb_tv/nimdetect.h 2016-09-19 19:36:24.000000000 +0200 @@ -0,0 +1,54 @@ +/* + * Wetek NIM tuner(s) detection