1a6dc60ffSKozlov Sergey /* 2a6dc60ffSKozlov Sergey * cxd2841er.c 3a6dc60ffSKozlov Sergey * 483808c23SAbylay Ospan * Sony digital demodulator driver for 59ca1736fSAbylay Ospan * CXD2841ER - DVB-S/S2/T/T2/C/C2 69ca1736fSAbylay Ospan * CXD2854ER - DVB-S/S2/T/T2/C/C2, ISDB-T/S 7a6dc60ffSKozlov Sergey * 8a6dc60ffSKozlov Sergey * Copyright 2012 Sony Corporation 9a6dc60ffSKozlov Sergey * Copyright (C) 2014 NetUP Inc. 10a6dc60ffSKozlov Sergey * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru> 11a6dc60ffSKozlov Sergey * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru> 12a6dc60ffSKozlov Sergey * 13a6dc60ffSKozlov Sergey * This program is free software; you can redistribute it and/or modify 14a6dc60ffSKozlov Sergey * it under the terms of the GNU General Public License as published by 15a6dc60ffSKozlov Sergey * the Free Software Foundation; either version 2 of the License, or 16a6dc60ffSKozlov Sergey * (at your option) any later version. 17a6dc60ffSKozlov Sergey * 18a6dc60ffSKozlov Sergey * This program is distributed in the hope that it will be useful, 19a6dc60ffSKozlov Sergey * but WITHOUT ANY WARRANTY; without even the implied warranty of 20a6dc60ffSKozlov Sergey * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21a6dc60ffSKozlov Sergey * GNU General Public License for more details. 22a6dc60ffSKozlov Sergey */ 23a6dc60ffSKozlov Sergey 24a6dc60ffSKozlov Sergey #include <linux/module.h> 25a6dc60ffSKozlov Sergey #include <linux/init.h> 26a6dc60ffSKozlov Sergey #include <linux/string.h> 27a6dc60ffSKozlov Sergey #include <linux/slab.h> 28a6dc60ffSKozlov Sergey #include <linux/bitops.h> 29a6dc60ffSKozlov Sergey #include <linux/math64.h> 30a6dc60ffSKozlov Sergey #include <linux/log2.h> 31a6dc60ffSKozlov Sergey #include <linux/dynamic_debug.h> 32a6dc60ffSKozlov Sergey 33a6dc60ffSKozlov Sergey #include "dvb_math.h" 34a6dc60ffSKozlov Sergey #include "dvb_frontend.h" 35a6dc60ffSKozlov Sergey #include "cxd2841er.h" 36a6dc60ffSKozlov Sergey #include "cxd2841er_priv.h" 37a6dc60ffSKozlov Sergey 38d13a7b67SMauro Carvalho Chehab #define MAX_WRITE_REGSIZE 16 39a6f330cbSAbylay Ospan #define LOG2_E_100X 144 40a6f330cbSAbylay Ospan 41a6f330cbSAbylay Ospan /* DVB-C constellation */ 42a6f330cbSAbylay Ospan enum sony_dvbc_constellation_t { 43a6f330cbSAbylay Ospan SONY_DVBC_CONSTELLATION_16QAM, 44a6f330cbSAbylay Ospan SONY_DVBC_CONSTELLATION_32QAM, 45a6f330cbSAbylay Ospan SONY_DVBC_CONSTELLATION_64QAM, 46a6f330cbSAbylay Ospan SONY_DVBC_CONSTELLATION_128QAM, 47a6f330cbSAbylay Ospan SONY_DVBC_CONSTELLATION_256QAM 48a6f330cbSAbylay Ospan }; 49d13a7b67SMauro Carvalho Chehab 50a6dc60ffSKozlov Sergey enum cxd2841er_state { 51a6dc60ffSKozlov Sergey STATE_SHUTDOWN = 0, 52a6dc60ffSKozlov Sergey STATE_SLEEP_S, 53a6dc60ffSKozlov Sergey STATE_ACTIVE_S, 54a6dc60ffSKozlov Sergey STATE_SLEEP_TC, 55a6dc60ffSKozlov Sergey STATE_ACTIVE_TC 56a6dc60ffSKozlov Sergey }; 57a6dc60ffSKozlov Sergey 58a6dc60ffSKozlov Sergey struct cxd2841er_priv { 59a6dc60ffSKozlov Sergey struct dvb_frontend frontend; 60a6dc60ffSKozlov Sergey struct i2c_adapter *i2c; 61a6dc60ffSKozlov Sergey u8 i2c_addr_slvx; 62a6dc60ffSKozlov Sergey u8 i2c_addr_slvt; 63a6dc60ffSKozlov Sergey const struct cxd2841er_config *config; 64a6dc60ffSKozlov Sergey enum cxd2841er_state state; 65a6dc60ffSKozlov Sergey u8 system; 6683808c23SAbylay Ospan enum cxd2841er_xtal xtal; 673f3b48a0SAbylay Ospan enum fe_caps caps; 68050863aaSDaniel Scheller u32 flags; 69a6dc60ffSKozlov Sergey }; 70a6dc60ffSKozlov Sergey 71a6dc60ffSKozlov Sergey static const struct cxd2841er_cnr_data s_cn_data[] = { 72a6dc60ffSKozlov Sergey { 0x033e, 0 }, { 0x0339, 100 }, { 0x0333, 200 }, 73a6dc60ffSKozlov Sergey { 0x032e, 300 }, { 0x0329, 400 }, { 0x0324, 500 }, 74a6dc60ffSKozlov Sergey { 0x031e, 600 }, { 0x0319, 700 }, { 0x0314, 800 }, 75a6dc60ffSKozlov Sergey { 0x030f, 900 }, { 0x030a, 1000 }, { 0x02ff, 1100 }, 76a6dc60ffSKozlov Sergey { 0x02f4, 1200 }, { 0x02e9, 1300 }, { 0x02de, 1400 }, 77a6dc60ffSKozlov Sergey { 0x02d4, 1500 }, { 0x02c9, 1600 }, { 0x02bf, 1700 }, 78a6dc60ffSKozlov Sergey { 0x02b5, 1800 }, { 0x02ab, 1900 }, { 0x02a1, 2000 }, 79a6dc60ffSKozlov Sergey { 0x029b, 2100 }, { 0x0295, 2200 }, { 0x0290, 2300 }, 80a6dc60ffSKozlov Sergey { 0x028a, 2400 }, { 0x0284, 2500 }, { 0x027f, 2600 }, 81a6dc60ffSKozlov Sergey { 0x0279, 2700 }, { 0x0274, 2800 }, { 0x026e, 2900 }, 82a6dc60ffSKozlov Sergey { 0x0269, 3000 }, { 0x0262, 3100 }, { 0x025c, 3200 }, 83a6dc60ffSKozlov Sergey { 0x0255, 3300 }, { 0x024f, 3400 }, { 0x0249, 3500 }, 84a6dc60ffSKozlov Sergey { 0x0242, 3600 }, { 0x023c, 3700 }, { 0x0236, 3800 }, 85a6dc60ffSKozlov Sergey { 0x0230, 3900 }, { 0x022a, 4000 }, { 0x0223, 4100 }, 86a6dc60ffSKozlov Sergey { 0x021c, 4200 }, { 0x0215, 4300 }, { 0x020e, 4400 }, 87a6dc60ffSKozlov Sergey { 0x0207, 4500 }, { 0x0201, 4600 }, { 0x01fa, 4700 }, 88a6dc60ffSKozlov Sergey { 0x01f4, 4800 }, { 0x01ed, 4900 }, { 0x01e7, 5000 }, 89a6dc60ffSKozlov Sergey { 0x01e0, 5100 }, { 0x01d9, 5200 }, { 0x01d2, 5300 }, 90a6dc60ffSKozlov Sergey { 0x01cb, 5400 }, { 0x01c4, 5500 }, { 0x01be, 5600 }, 91a6dc60ffSKozlov Sergey { 0x01b7, 5700 }, { 0x01b1, 5800 }, { 0x01aa, 5900 }, 92a6dc60ffSKozlov Sergey { 0x01a4, 6000 }, { 0x019d, 6100 }, { 0x0196, 6200 }, 93a6dc60ffSKozlov Sergey { 0x018f, 6300 }, { 0x0189, 6400 }, { 0x0182, 6500 }, 94a6dc60ffSKozlov Sergey { 0x017c, 6600 }, { 0x0175, 6700 }, { 0x016f, 6800 }, 95a6dc60ffSKozlov Sergey { 0x0169, 6900 }, { 0x0163, 7000 }, { 0x015c, 7100 }, 96a6dc60ffSKozlov Sergey { 0x0156, 7200 }, { 0x0150, 7300 }, { 0x014a, 7400 }, 97a6dc60ffSKozlov Sergey { 0x0144, 7500 }, { 0x013e, 7600 }, { 0x0138, 7700 }, 98a6dc60ffSKozlov Sergey { 0x0132, 7800 }, { 0x012d, 7900 }, { 0x0127, 8000 }, 99a6dc60ffSKozlov Sergey { 0x0121, 8100 }, { 0x011c, 8200 }, { 0x0116, 8300 }, 100a6dc60ffSKozlov Sergey { 0x0111, 8400 }, { 0x010b, 8500 }, { 0x0106, 8600 }, 101a6dc60ffSKozlov Sergey { 0x0101, 8700 }, { 0x00fc, 8800 }, { 0x00f7, 8900 }, 102a6dc60ffSKozlov Sergey { 0x00f2, 9000 }, { 0x00ee, 9100 }, { 0x00ea, 9200 }, 103a6dc60ffSKozlov Sergey { 0x00e6, 9300 }, { 0x00e2, 9400 }, { 0x00de, 9500 }, 104a6dc60ffSKozlov Sergey { 0x00da, 9600 }, { 0x00d7, 9700 }, { 0x00d3, 9800 }, 105a6dc60ffSKozlov Sergey { 0x00d0, 9900 }, { 0x00cc, 10000 }, { 0x00c7, 10100 }, 106a6dc60ffSKozlov Sergey { 0x00c3, 10200 }, { 0x00bf, 10300 }, { 0x00ba, 10400 }, 107a6dc60ffSKozlov Sergey { 0x00b6, 10500 }, { 0x00b2, 10600 }, { 0x00ae, 10700 }, 108a6dc60ffSKozlov Sergey { 0x00aa, 10800 }, { 0x00a7, 10900 }, { 0x00a3, 11000 }, 109a6dc60ffSKozlov Sergey { 0x009f, 11100 }, { 0x009c, 11200 }, { 0x0098, 11300 }, 110a6dc60ffSKozlov Sergey { 0x0094, 11400 }, { 0x0091, 11500 }, { 0x008e, 11600 }, 111a6dc60ffSKozlov Sergey { 0x008a, 11700 }, { 0x0087, 11800 }, { 0x0084, 11900 }, 112a6dc60ffSKozlov Sergey { 0x0081, 12000 }, { 0x007e, 12100 }, { 0x007b, 12200 }, 113a6dc60ffSKozlov Sergey { 0x0079, 12300 }, { 0x0076, 12400 }, { 0x0073, 12500 }, 114a6dc60ffSKozlov Sergey { 0x0071, 12600 }, { 0x006e, 12700 }, { 0x006c, 12800 }, 115a6dc60ffSKozlov Sergey { 0x0069, 12900 }, { 0x0067, 13000 }, { 0x0065, 13100 }, 116a6dc60ffSKozlov Sergey { 0x0062, 13200 }, { 0x0060, 13300 }, { 0x005e, 13400 }, 117a6dc60ffSKozlov Sergey { 0x005c, 13500 }, { 0x005a, 13600 }, { 0x0058, 13700 }, 118a6dc60ffSKozlov Sergey { 0x0056, 13800 }, { 0x0054, 13900 }, { 0x0052, 14000 }, 119a6dc60ffSKozlov Sergey { 0x0050, 14100 }, { 0x004e, 14200 }, { 0x004c, 14300 }, 120a6dc60ffSKozlov Sergey { 0x004b, 14400 }, { 0x0049, 14500 }, { 0x0047, 14600 }, 121a6dc60ffSKozlov Sergey { 0x0046, 14700 }, { 0x0044, 14800 }, { 0x0043, 14900 }, 122a6dc60ffSKozlov Sergey { 0x0041, 15000 }, { 0x003f, 15100 }, { 0x003e, 15200 }, 123a6dc60ffSKozlov Sergey { 0x003c, 15300 }, { 0x003b, 15400 }, { 0x003a, 15500 }, 124a6dc60ffSKozlov Sergey { 0x0037, 15700 }, { 0x0036, 15800 }, { 0x0034, 15900 }, 125a6dc60ffSKozlov Sergey { 0x0033, 16000 }, { 0x0032, 16100 }, { 0x0031, 16200 }, 126a6dc60ffSKozlov Sergey { 0x0030, 16300 }, { 0x002f, 16400 }, { 0x002e, 16500 }, 127a6dc60ffSKozlov Sergey { 0x002d, 16600 }, { 0x002c, 16700 }, { 0x002b, 16800 }, 128a6dc60ffSKozlov Sergey { 0x002a, 16900 }, { 0x0029, 17000 }, { 0x0028, 17100 }, 129a6dc60ffSKozlov Sergey { 0x0027, 17200 }, { 0x0026, 17300 }, { 0x0025, 17400 }, 130a6dc60ffSKozlov Sergey { 0x0024, 17500 }, { 0x0023, 17600 }, { 0x0022, 17800 }, 131a6dc60ffSKozlov Sergey { 0x0021, 17900 }, { 0x0020, 18000 }, { 0x001f, 18200 }, 132a6dc60ffSKozlov Sergey { 0x001e, 18300 }, { 0x001d, 18500 }, { 0x001c, 18700 }, 133a6dc60ffSKozlov Sergey { 0x001b, 18900 }, { 0x001a, 19000 }, { 0x0019, 19200 }, 134a6dc60ffSKozlov Sergey { 0x0018, 19300 }, { 0x0017, 19500 }, { 0x0016, 19700 }, 135a6dc60ffSKozlov Sergey { 0x0015, 19900 }, { 0x0014, 20000 }, 136a6dc60ffSKozlov Sergey }; 137a6dc60ffSKozlov Sergey 138a6dc60ffSKozlov Sergey static const struct cxd2841er_cnr_data s2_cn_data[] = { 139a6dc60ffSKozlov Sergey { 0x05af, 0 }, { 0x0597, 100 }, { 0x057e, 200 }, 140a6dc60ffSKozlov Sergey { 0x0567, 300 }, { 0x0550, 400 }, { 0x0539, 500 }, 141a6dc60ffSKozlov Sergey { 0x0522, 600 }, { 0x050c, 700 }, { 0x04f6, 800 }, 142a6dc60ffSKozlov Sergey { 0x04e1, 900 }, { 0x04cc, 1000 }, { 0x04b6, 1100 }, 143a6dc60ffSKozlov Sergey { 0x04a1, 1200 }, { 0x048c, 1300 }, { 0x0477, 1400 }, 144a6dc60ffSKozlov Sergey { 0x0463, 1500 }, { 0x044f, 1600 }, { 0x043c, 1700 }, 145a6dc60ffSKozlov Sergey { 0x0428, 1800 }, { 0x0416, 1900 }, { 0x0403, 2000 }, 146a6dc60ffSKozlov Sergey { 0x03ef, 2100 }, { 0x03dc, 2200 }, { 0x03c9, 2300 }, 147a6dc60ffSKozlov Sergey { 0x03b6, 2400 }, { 0x03a4, 2500 }, { 0x0392, 2600 }, 148a6dc60ffSKozlov Sergey { 0x0381, 2700 }, { 0x036f, 2800 }, { 0x035f, 2900 }, 149a6dc60ffSKozlov Sergey { 0x034e, 3000 }, { 0x033d, 3100 }, { 0x032d, 3200 }, 150a6dc60ffSKozlov Sergey { 0x031d, 3300 }, { 0x030d, 3400 }, { 0x02fd, 3500 }, 151a6dc60ffSKozlov Sergey { 0x02ee, 3600 }, { 0x02df, 3700 }, { 0x02d0, 3800 }, 152a6dc60ffSKozlov Sergey { 0x02c2, 3900 }, { 0x02b4, 4000 }, { 0x02a6, 4100 }, 153a6dc60ffSKozlov Sergey { 0x0299, 4200 }, { 0x028c, 4300 }, { 0x027f, 4400 }, 154a6dc60ffSKozlov Sergey { 0x0272, 4500 }, { 0x0265, 4600 }, { 0x0259, 4700 }, 155a6dc60ffSKozlov Sergey { 0x024d, 4800 }, { 0x0241, 4900 }, { 0x0236, 5000 }, 156a6dc60ffSKozlov Sergey { 0x022b, 5100 }, { 0x0220, 5200 }, { 0x0215, 5300 }, 157a6dc60ffSKozlov Sergey { 0x020a, 5400 }, { 0x0200, 5500 }, { 0x01f6, 5600 }, 158a6dc60ffSKozlov Sergey { 0x01ec, 5700 }, { 0x01e2, 5800 }, { 0x01d8, 5900 }, 159a6dc60ffSKozlov Sergey { 0x01cf, 6000 }, { 0x01c6, 6100 }, { 0x01bc, 6200 }, 160a6dc60ffSKozlov Sergey { 0x01b3, 6300 }, { 0x01aa, 6400 }, { 0x01a2, 6500 }, 161a6dc60ffSKozlov Sergey { 0x0199, 6600 }, { 0x0191, 6700 }, { 0x0189, 6800 }, 162a6dc60ffSKozlov Sergey { 0x0181, 6900 }, { 0x0179, 7000 }, { 0x0171, 7100 }, 163a6dc60ffSKozlov Sergey { 0x0169, 7200 }, { 0x0161, 7300 }, { 0x015a, 7400 }, 164a6dc60ffSKozlov Sergey { 0x0153, 7500 }, { 0x014b, 7600 }, { 0x0144, 7700 }, 165a6dc60ffSKozlov Sergey { 0x013d, 7800 }, { 0x0137, 7900 }, { 0x0130, 8000 }, 166a6dc60ffSKozlov Sergey { 0x012a, 8100 }, { 0x0124, 8200 }, { 0x011e, 8300 }, 167a6dc60ffSKozlov Sergey { 0x0118, 8400 }, { 0x0112, 8500 }, { 0x010c, 8600 }, 168a6dc60ffSKozlov Sergey { 0x0107, 8700 }, { 0x0101, 8800 }, { 0x00fc, 8900 }, 169a6dc60ffSKozlov Sergey { 0x00f7, 9000 }, { 0x00f2, 9100 }, { 0x00ec, 9200 }, 170a6dc60ffSKozlov Sergey { 0x00e7, 9300 }, { 0x00e2, 9400 }, { 0x00dd, 9500 }, 171a6dc60ffSKozlov Sergey { 0x00d8, 9600 }, { 0x00d4, 9700 }, { 0x00cf, 9800 }, 172a6dc60ffSKozlov Sergey { 0x00ca, 9900 }, { 0x00c6, 10000 }, { 0x00c2, 10100 }, 173a6dc60ffSKozlov Sergey { 0x00be, 10200 }, { 0x00b9, 10300 }, { 0x00b5, 10400 }, 174a6dc60ffSKozlov Sergey { 0x00b1, 10500 }, { 0x00ae, 10600 }, { 0x00aa, 10700 }, 175a6dc60ffSKozlov Sergey { 0x00a6, 10800 }, { 0x00a3, 10900 }, { 0x009f, 11000 }, 176a6dc60ffSKozlov Sergey { 0x009b, 11100 }, { 0x0098, 11200 }, { 0x0095, 11300 }, 177a6dc60ffSKozlov Sergey { 0x0091, 11400 }, { 0x008e, 11500 }, { 0x008b, 11600 }, 178a6dc60ffSKozlov Sergey { 0x0088, 11700 }, { 0x0085, 11800 }, { 0x0082, 11900 }, 179a6dc60ffSKozlov Sergey { 0x007f, 12000 }, { 0x007c, 12100 }, { 0x007a, 12200 }, 180a6dc60ffSKozlov Sergey { 0x0077, 12300 }, { 0x0074, 12400 }, { 0x0072, 12500 }, 181a6dc60ffSKozlov Sergey { 0x006f, 12600 }, { 0x006d, 12700 }, { 0x006b, 12800 }, 182a6dc60ffSKozlov Sergey { 0x0068, 12900 }, { 0x0066, 13000 }, { 0x0064, 13100 }, 183a6dc60ffSKozlov Sergey { 0x0061, 13200 }, { 0x005f, 13300 }, { 0x005d, 13400 }, 184a6dc60ffSKozlov Sergey { 0x005b, 13500 }, { 0x0059, 13600 }, { 0x0057, 13700 }, 185a6dc60ffSKozlov Sergey { 0x0055, 13800 }, { 0x0053, 13900 }, { 0x0051, 14000 }, 186a6dc60ffSKozlov Sergey { 0x004f, 14100 }, { 0x004e, 14200 }, { 0x004c, 14300 }, 187a6dc60ffSKozlov Sergey { 0x004a, 14400 }, { 0x0049, 14500 }, { 0x0047, 14600 }, 188a6dc60ffSKozlov Sergey { 0x0045, 14700 }, { 0x0044, 14800 }, { 0x0042, 14900 }, 189a6dc60ffSKozlov Sergey { 0x0041, 15000 }, { 0x003f, 15100 }, { 0x003e, 15200 }, 190a6dc60ffSKozlov Sergey { 0x003c, 15300 }, { 0x003b, 15400 }, { 0x003a, 15500 }, 191a6dc60ffSKozlov Sergey { 0x0038, 15600 }, { 0x0037, 15700 }, { 0x0036, 15800 }, 192a6dc60ffSKozlov Sergey { 0x0034, 15900 }, { 0x0033, 16000 }, { 0x0032, 16100 }, 193a6dc60ffSKozlov Sergey { 0x0031, 16200 }, { 0x0030, 16300 }, { 0x002f, 16400 }, 194a6dc60ffSKozlov Sergey { 0x002e, 16500 }, { 0x002d, 16600 }, { 0x002c, 16700 }, 195a6dc60ffSKozlov Sergey { 0x002b, 16800 }, { 0x002a, 16900 }, { 0x0029, 17000 }, 196a6dc60ffSKozlov Sergey { 0x0028, 17100 }, { 0x0027, 17200 }, { 0x0026, 17300 }, 197a6dc60ffSKozlov Sergey { 0x0025, 17400 }, { 0x0024, 17500 }, { 0x0023, 17600 }, 198a6dc60ffSKozlov Sergey { 0x0022, 17800 }, { 0x0021, 17900 }, { 0x0020, 18000 }, 199a6dc60ffSKozlov Sergey { 0x001f, 18200 }, { 0x001e, 18300 }, { 0x001d, 18500 }, 200a6dc60ffSKozlov Sergey { 0x001c, 18700 }, { 0x001b, 18900 }, { 0x001a, 19000 }, 201a6dc60ffSKozlov Sergey { 0x0019, 19200 }, { 0x0018, 19300 }, { 0x0017, 19500 }, 202a6dc60ffSKozlov Sergey { 0x0016, 19700 }, { 0x0015, 19900 }, { 0x0014, 20000 }, 203a6dc60ffSKozlov Sergey }; 204a6dc60ffSKozlov Sergey 2050854df79SAbylay Ospan static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv); 2060854df79SAbylay Ospan static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv); 2070854df79SAbylay Ospan 208a6dc60ffSKozlov Sergey static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv, 209a6dc60ffSKozlov Sergey u8 addr, u8 reg, u8 write, 210a6dc60ffSKozlov Sergey const u8 *data, u32 len) 211a6dc60ffSKozlov Sergey { 212a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 2135d6d93a1SDaniel Scheller "cxd2841er: I2C %s addr %02x reg 0x%02x size %d data %*ph\n", 2145d6d93a1SDaniel Scheller (write == 0 ? "read" : "write"), addr, reg, len, len, data); 215a6dc60ffSKozlov Sergey } 216a6dc60ffSKozlov Sergey 217a6dc60ffSKozlov Sergey static int cxd2841er_write_regs(struct cxd2841er_priv *priv, 218a6dc60ffSKozlov Sergey u8 addr, u8 reg, const u8 *data, u32 len) 219a6dc60ffSKozlov Sergey { 220a6dc60ffSKozlov Sergey int ret; 221d13a7b67SMauro Carvalho Chehab u8 buf[MAX_WRITE_REGSIZE + 1]; 222a6dc60ffSKozlov Sergey u8 i2c_addr = (addr == I2C_SLVX ? 223a6dc60ffSKozlov Sergey priv->i2c_addr_slvx : priv->i2c_addr_slvt); 224a6dc60ffSKozlov Sergey struct i2c_msg msg[1] = { 225a6dc60ffSKozlov Sergey { 226a6dc60ffSKozlov Sergey .addr = i2c_addr, 227a6dc60ffSKozlov Sergey .flags = 0, 228d13a7b67SMauro Carvalho Chehab .len = len + 1, 229a6dc60ffSKozlov Sergey .buf = buf, 230a6dc60ffSKozlov Sergey } 231a6dc60ffSKozlov Sergey }; 232a6dc60ffSKozlov Sergey 233d13a7b67SMauro Carvalho Chehab if (len + 1 >= sizeof(buf)) { 234d13a7b67SMauro Carvalho Chehab dev_warn(&priv->i2c->dev, "wr reg=%04x: len=%d is too big!\n", 235d13a7b67SMauro Carvalho Chehab reg, len + 1); 236d13a7b67SMauro Carvalho Chehab return -E2BIG; 237d13a7b67SMauro Carvalho Chehab } 238d13a7b67SMauro Carvalho Chehab 239a6dc60ffSKozlov Sergey cxd2841er_i2c_debug(priv, i2c_addr, reg, 1, data, len); 240a6dc60ffSKozlov Sergey buf[0] = reg; 241a6dc60ffSKozlov Sergey memcpy(&buf[1], data, len); 242a6dc60ffSKozlov Sergey 243a6dc60ffSKozlov Sergey ret = i2c_transfer(priv->i2c, msg, 1); 244a6dc60ffSKozlov Sergey if (ret >= 0 && ret != 1) 245a6dc60ffSKozlov Sergey ret = -EIO; 246a6dc60ffSKozlov Sergey if (ret < 0) { 247a6dc60ffSKozlov Sergey dev_warn(&priv->i2c->dev, 248a6dc60ffSKozlov Sergey "%s: i2c wr failed=%d addr=%02x reg=%02x len=%d\n", 249a6dc60ffSKozlov Sergey KBUILD_MODNAME, ret, i2c_addr, reg, len); 250a6dc60ffSKozlov Sergey return ret; 251a6dc60ffSKozlov Sergey } 252a6dc60ffSKozlov Sergey return 0; 253a6dc60ffSKozlov Sergey } 254a6dc60ffSKozlov Sergey 255a6dc60ffSKozlov Sergey static int cxd2841er_write_reg(struct cxd2841er_priv *priv, 256a6dc60ffSKozlov Sergey u8 addr, u8 reg, u8 val) 257a6dc60ffSKozlov Sergey { 258a6dc60ffSKozlov Sergey return cxd2841er_write_regs(priv, addr, reg, &val, 1); 259a6dc60ffSKozlov Sergey } 260a6dc60ffSKozlov Sergey 261a6dc60ffSKozlov Sergey static int cxd2841er_read_regs(struct cxd2841er_priv *priv, 262a6dc60ffSKozlov Sergey u8 addr, u8 reg, u8 *val, u32 len) 263a6dc60ffSKozlov Sergey { 264a6dc60ffSKozlov Sergey int ret; 265a6dc60ffSKozlov Sergey u8 i2c_addr = (addr == I2C_SLVX ? 266a6dc60ffSKozlov Sergey priv->i2c_addr_slvx : priv->i2c_addr_slvt); 267a6dc60ffSKozlov Sergey struct i2c_msg msg[2] = { 268a6dc60ffSKozlov Sergey { 269a6dc60ffSKozlov Sergey .addr = i2c_addr, 270a6dc60ffSKozlov Sergey .flags = 0, 271a6dc60ffSKozlov Sergey .len = 1, 272a6dc60ffSKozlov Sergey .buf = ®, 273a6dc60ffSKozlov Sergey }, { 274a6dc60ffSKozlov Sergey .addr = i2c_addr, 275a6dc60ffSKozlov Sergey .flags = I2C_M_RD, 276a6dc60ffSKozlov Sergey .len = len, 277a6dc60ffSKozlov Sergey .buf = val, 278a6dc60ffSKozlov Sergey } 279a6dc60ffSKozlov Sergey }; 280a6dc60ffSKozlov Sergey 281725e93ebSDaniel Scheller ret = i2c_transfer(priv->i2c, msg, 2); 282725e93ebSDaniel Scheller if (ret >= 0 && ret != 2) 283a6dc60ffSKozlov Sergey ret = -EIO; 284a6dc60ffSKozlov Sergey if (ret < 0) { 285a6dc60ffSKozlov Sergey dev_warn(&priv->i2c->dev, 286a6dc60ffSKozlov Sergey "%s: i2c rd failed=%d addr=%02x reg=%02x\n", 287a6dc60ffSKozlov Sergey KBUILD_MODNAME, ret, i2c_addr, reg); 288a6dc60ffSKozlov Sergey return ret; 289a6dc60ffSKozlov Sergey } 2906c77161aSAbylay Ospan cxd2841er_i2c_debug(priv, i2c_addr, reg, 0, val, len); 291a6dc60ffSKozlov Sergey return 0; 292a6dc60ffSKozlov Sergey } 293a6dc60ffSKozlov Sergey 294a6dc60ffSKozlov Sergey static int cxd2841er_read_reg(struct cxd2841er_priv *priv, 295a6dc60ffSKozlov Sergey u8 addr, u8 reg, u8 *val) 296a6dc60ffSKozlov Sergey { 297a6dc60ffSKozlov Sergey return cxd2841er_read_regs(priv, addr, reg, val, 1); 298a6dc60ffSKozlov Sergey } 299a6dc60ffSKozlov Sergey 300a6dc60ffSKozlov Sergey static int cxd2841er_set_reg_bits(struct cxd2841er_priv *priv, 301a6dc60ffSKozlov Sergey u8 addr, u8 reg, u8 data, u8 mask) 302a6dc60ffSKozlov Sergey { 303a6dc60ffSKozlov Sergey int res; 304a6dc60ffSKozlov Sergey u8 rdata; 305a6dc60ffSKozlov Sergey 306a6dc60ffSKozlov Sergey if (mask != 0xff) { 307a6dc60ffSKozlov Sergey res = cxd2841er_read_reg(priv, addr, reg, &rdata); 308a6dc60ffSKozlov Sergey if (res) 309a6dc60ffSKozlov Sergey return res; 310a6dc60ffSKozlov Sergey data = ((data & mask) | (rdata & (mask ^ 0xFF))); 311a6dc60ffSKozlov Sergey } 312a6dc60ffSKozlov Sergey return cxd2841er_write_reg(priv, addr, reg, data); 313a6dc60ffSKozlov Sergey } 314a6dc60ffSKozlov Sergey 315cbc85a47SDaniel Scheller static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz) 316cbc85a47SDaniel Scheller { 317cbc85a47SDaniel Scheller u64 tmp; 318cbc85a47SDaniel Scheller 319cbc85a47SDaniel Scheller tmp = (u64) ifhz * 16777216; 320cbc85a47SDaniel Scheller do_div(tmp, ((xtal == SONY_XTAL_24000) ? 48000000 : 41000000)); 321cbc85a47SDaniel Scheller 322cbc85a47SDaniel Scheller return (u32) tmp; 323cbc85a47SDaniel Scheller } 324cbc85a47SDaniel Scheller 325cbc85a47SDaniel Scheller static u32 cxd2841er_calc_iffreq(u32 ifhz) 326cbc85a47SDaniel Scheller { 327cbc85a47SDaniel Scheller return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz); 328cbc85a47SDaniel Scheller } 329cbc85a47SDaniel Scheller 3304b866c4eSDaniel Scheller static int cxd2841er_get_if_hz(struct cxd2841er_priv *priv, u32 def_hz) 3314b866c4eSDaniel Scheller { 3324b866c4eSDaniel Scheller u32 hz; 3334b866c4eSDaniel Scheller 3344b866c4eSDaniel Scheller if (priv->frontend.ops.tuner_ops.get_if_frequency 3354b866c4eSDaniel Scheller && (priv->flags & CXD2841ER_AUTO_IFHZ)) 3364b866c4eSDaniel Scheller priv->frontend.ops.tuner_ops.get_if_frequency( 3374b866c4eSDaniel Scheller &priv->frontend, &hz); 3384b866c4eSDaniel Scheller else 3394b866c4eSDaniel Scheller hz = def_hz; 3404b866c4eSDaniel Scheller 3414b866c4eSDaniel Scheller return hz; 3424b866c4eSDaniel Scheller } 3434b866c4eSDaniel Scheller 344c7518d13SDaniel Scheller static int cxd2841er_tuner_set(struct dvb_frontend *fe) 345c7518d13SDaniel Scheller { 346c7518d13SDaniel Scheller struct cxd2841er_priv *priv = fe->demodulator_priv; 347c7518d13SDaniel Scheller 348c7518d13SDaniel Scheller if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl) 349c7518d13SDaniel Scheller fe->ops.i2c_gate_ctrl(fe, 1); 350c7518d13SDaniel Scheller if (fe->ops.tuner_ops.set_params) 351c7518d13SDaniel Scheller fe->ops.tuner_ops.set_params(fe); 352c7518d13SDaniel Scheller if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl) 353c7518d13SDaniel Scheller fe->ops.i2c_gate_ctrl(fe, 0); 354c7518d13SDaniel Scheller 355c7518d13SDaniel Scheller return 0; 356c7518d13SDaniel Scheller } 357c7518d13SDaniel Scheller 358a6dc60ffSKozlov Sergey static int cxd2841er_dvbs2_set_symbol_rate(struct cxd2841er_priv *priv, 359a6dc60ffSKozlov Sergey u32 symbol_rate) 360a6dc60ffSKozlov Sergey { 361a6dc60ffSKozlov Sergey u32 reg_value = 0; 362a6dc60ffSKozlov Sergey u8 data[3] = {0, 0, 0}; 363a6dc60ffSKozlov Sergey 364a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 365a6dc60ffSKozlov Sergey /* 366a6dc60ffSKozlov Sergey * regValue = (symbolRateKSps * 2^14 / 1000) + 0.5 367a6dc60ffSKozlov Sergey * = ((symbolRateKSps * 2^14) + 500) / 1000 368a6dc60ffSKozlov Sergey * = ((symbolRateKSps * 16384) + 500) / 1000 369a6dc60ffSKozlov Sergey */ 370a6dc60ffSKozlov Sergey reg_value = DIV_ROUND_CLOSEST(symbol_rate * 16384, 1000); 371a6dc60ffSKozlov Sergey if ((reg_value == 0) || (reg_value > 0xFFFFF)) { 372a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, 373a6dc60ffSKozlov Sergey "%s(): reg_value is out of range\n", __func__); 374a6dc60ffSKozlov Sergey return -EINVAL; 375a6dc60ffSKozlov Sergey } 376a6dc60ffSKozlov Sergey data[0] = (u8)((reg_value >> 16) & 0x0F); 377a6dc60ffSKozlov Sergey data[1] = (u8)((reg_value >> 8) & 0xFF); 378a6dc60ffSKozlov Sergey data[2] = (u8)(reg_value & 0xFF); 379a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xAE */ 380a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xae); 381a6dc60ffSKozlov Sergey cxd2841er_write_regs(priv, I2C_SLVT, 0x20, data, 3); 382a6dc60ffSKozlov Sergey return 0; 383a6dc60ffSKozlov Sergey } 384a6dc60ffSKozlov Sergey 385a6dc60ffSKozlov Sergey static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv, 386a6dc60ffSKozlov Sergey u8 system); 387a6dc60ffSKozlov Sergey 388a6dc60ffSKozlov Sergey static int cxd2841er_sleep_s_to_active_s(struct cxd2841er_priv *priv, 389a6dc60ffSKozlov Sergey u8 system, u32 symbol_rate) 390a6dc60ffSKozlov Sergey { 391a6dc60ffSKozlov Sergey int ret; 392a6dc60ffSKozlov Sergey u8 data[4] = { 0, 0, 0, 0 }; 393a6dc60ffSKozlov Sergey 394a6dc60ffSKozlov Sergey if (priv->state != STATE_SLEEP_S) { 395a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid state %d\n", 396a6dc60ffSKozlov Sergey __func__, (int)priv->state); 397a6dc60ffSKozlov Sergey return -EINVAL; 398a6dc60ffSKozlov Sergey } 399a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 400a6dc60ffSKozlov Sergey cxd2841er_set_ts_clock_mode(priv, SYS_DVBS); 401a6dc60ffSKozlov Sergey /* Set demod mode */ 402a6dc60ffSKozlov Sergey if (system == SYS_DVBS) { 403a6dc60ffSKozlov Sergey data[0] = 0x0A; 404a6dc60ffSKozlov Sergey } else if (system == SYS_DVBS2) { 405a6dc60ffSKozlov Sergey data[0] = 0x0B; 406a6dc60ffSKozlov Sergey } else { 407a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid delsys %d\n", 408a6dc60ffSKozlov Sergey __func__, system); 409a6dc60ffSKozlov Sergey return -EINVAL; 410a6dc60ffSKozlov Sergey } 411a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 412a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 413a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x17, data[0]); 414a6dc60ffSKozlov Sergey /* DVB-S/S2 */ 415a6dc60ffSKozlov Sergey data[0] = 0x00; 416a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 417a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 418a6dc60ffSKozlov Sergey /* Enable S/S2 auto detection 1 */ 419a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2d, data[0]); 420a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xAE */ 421a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xae); 422a6dc60ffSKozlov Sergey /* Enable S/S2 auto detection 2 */ 423a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x30, data[0]); 424a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 425a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 426a6dc60ffSKozlov Sergey /* Enable demod clock */ 427a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); 428a6dc60ffSKozlov Sergey /* Enable ADC clock */ 429a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x31, 0x01); 430a6dc60ffSKozlov Sergey /* Enable ADC 1 */ 431a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16); 432a6dc60ffSKozlov Sergey /* Enable ADC 2 */ 433a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x3f); 434a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 435a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 436a6dc60ffSKozlov Sergey /* Enable ADC 3 */ 437a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); 438a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xA3 */ 439a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa3); 440a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xac, 0x00); 441a6dc60ffSKozlov Sergey data[0] = 0x07; 442a6dc60ffSKozlov Sergey data[1] = 0x3B; 443a6dc60ffSKozlov Sergey data[2] = 0x08; 444a6dc60ffSKozlov Sergey data[3] = 0xC5; 445a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xAB */ 446a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xab); 447a6dc60ffSKozlov Sergey cxd2841er_write_regs(priv, I2C_SLVT, 0x98, data, 4); 448a6dc60ffSKozlov Sergey data[0] = 0x05; 449a6dc60ffSKozlov Sergey data[1] = 0x80; 450a6dc60ffSKozlov Sergey data[2] = 0x0A; 451a6dc60ffSKozlov Sergey data[3] = 0x80; 452a6dc60ffSKozlov Sergey cxd2841er_write_regs(priv, I2C_SLVT, 0xa8, data, 4); 453a6dc60ffSKozlov Sergey data[0] = 0x0C; 454a6dc60ffSKozlov Sergey data[1] = 0xCC; 455a6dc60ffSKozlov Sergey cxd2841er_write_regs(priv, I2C_SLVT, 0xc3, data, 2); 456a6dc60ffSKozlov Sergey /* Set demod parameter */ 457a6dc60ffSKozlov Sergey ret = cxd2841er_dvbs2_set_symbol_rate(priv, symbol_rate); 458a6dc60ffSKozlov Sergey if (ret != 0) 459a6dc60ffSKozlov Sergey return ret; 460a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 461a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 462a6dc60ffSKozlov Sergey /* disable Hi-Z setting 1 */ 463a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x10); 464a6dc60ffSKozlov Sergey /* disable Hi-Z setting 2 */ 465a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00); 466a6dc60ffSKozlov Sergey priv->state = STATE_ACTIVE_S; 467a6dc60ffSKozlov Sergey return 0; 468a6dc60ffSKozlov Sergey } 469a6dc60ffSKozlov Sergey 470a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_active_t_band(struct cxd2841er_priv *priv, 471a6dc60ffSKozlov Sergey u32 bandwidth); 472a6dc60ffSKozlov Sergey 473a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv, 474a6dc60ffSKozlov Sergey u32 bandwidth); 475a6dc60ffSKozlov Sergey 476a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv, 477a6dc60ffSKozlov Sergey u32 bandwidth); 478a6dc60ffSKozlov Sergey 47976344a3fSMauro Carvalho Chehab static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv, 48076344a3fSMauro Carvalho Chehab u32 bandwidth); 48176344a3fSMauro Carvalho Chehab 48276344a3fSMauro Carvalho Chehab static int cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv *priv); 48376344a3fSMauro Carvalho Chehab 48476344a3fSMauro Carvalho Chehab static int cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv *priv); 48576344a3fSMauro Carvalho Chehab 48676344a3fSMauro Carvalho Chehab static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv); 48776344a3fSMauro Carvalho Chehab 488a6dc60ffSKozlov Sergey static int cxd2841er_retune_active(struct cxd2841er_priv *priv, 489a6dc60ffSKozlov Sergey struct dtv_frontend_properties *p) 490a6dc60ffSKozlov Sergey { 491a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 492a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_S && 493a6dc60ffSKozlov Sergey priv->state != STATE_ACTIVE_TC) { 494a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 495a6dc60ffSKozlov Sergey __func__, priv->state); 496a6dc60ffSKozlov Sergey return -EINVAL; 497a6dc60ffSKozlov Sergey } 498a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 499a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 500a6dc60ffSKozlov Sergey /* disable TS output */ 501a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); 502a6dc60ffSKozlov Sergey if (priv->state == STATE_ACTIVE_S) 503a6dc60ffSKozlov Sergey return cxd2841er_dvbs2_set_symbol_rate( 504a6dc60ffSKozlov Sergey priv, p->symbol_rate / 1000); 505a6dc60ffSKozlov Sergey else if (priv->state == STATE_ACTIVE_TC) { 506a6dc60ffSKozlov Sergey switch (priv->system) { 507a6dc60ffSKozlov Sergey case SYS_DVBT: 508a6dc60ffSKozlov Sergey return cxd2841er_sleep_tc_to_active_t_band( 509a6dc60ffSKozlov Sergey priv, p->bandwidth_hz); 510a6dc60ffSKozlov Sergey case SYS_DVBT2: 511a6dc60ffSKozlov Sergey return cxd2841er_sleep_tc_to_active_t2_band( 512a6dc60ffSKozlov Sergey priv, p->bandwidth_hz); 513a6dc60ffSKozlov Sergey case SYS_DVBC_ANNEX_A: 514a6dc60ffSKozlov Sergey return cxd2841er_sleep_tc_to_active_c_band( 51576344a3fSMauro Carvalho Chehab priv, p->bandwidth_hz); 51676344a3fSMauro Carvalho Chehab case SYS_ISDBT: 51776344a3fSMauro Carvalho Chehab cxd2841er_active_i_to_sleep_tc(priv); 51876344a3fSMauro Carvalho Chehab cxd2841er_sleep_tc_to_shutdown(priv); 51976344a3fSMauro Carvalho Chehab cxd2841er_shutdown_to_sleep_tc(priv); 52076344a3fSMauro Carvalho Chehab return cxd2841er_sleep_tc_to_active_i( 52176344a3fSMauro Carvalho Chehab priv, p->bandwidth_hz); 522a6dc60ffSKozlov Sergey } 523a6dc60ffSKozlov Sergey } 524a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n", 525a6dc60ffSKozlov Sergey __func__, priv->system); 526a6dc60ffSKozlov Sergey return -EINVAL; 527a6dc60ffSKozlov Sergey } 528a6dc60ffSKozlov Sergey 529a6dc60ffSKozlov Sergey static int cxd2841er_active_s_to_sleep_s(struct cxd2841er_priv *priv) 530a6dc60ffSKozlov Sergey { 531a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 532a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_S) { 533a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid state %d\n", 534a6dc60ffSKozlov Sergey __func__, priv->state); 535a6dc60ffSKozlov Sergey return -EINVAL; 536a6dc60ffSKozlov Sergey } 537a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 538a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 539a6dc60ffSKozlov Sergey /* disable TS output */ 540a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); 541a6dc60ffSKozlov Sergey /* enable Hi-Z setting 1 */ 542a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x1f); 543a6dc60ffSKozlov Sergey /* enable Hi-Z setting 2 */ 544a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff); 545a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 546a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 547a6dc60ffSKozlov Sergey /* disable ADC 1 */ 548a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01); 549a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 550a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 551a6dc60ffSKozlov Sergey /* disable ADC clock */ 552a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x31, 0x00); 553a6dc60ffSKozlov Sergey /* disable ADC 2 */ 554a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16); 555a6dc60ffSKozlov Sergey /* disable ADC 3 */ 556a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x27); 557a6dc60ffSKozlov Sergey /* SADC Bias ON */ 558a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x69, 0x06); 559a6dc60ffSKozlov Sergey /* disable demod clock */ 560a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); 561a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xAE */ 562a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xae); 563a6dc60ffSKozlov Sergey /* disable S/S2 auto detection1 */ 564a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 565a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 566a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 567a6dc60ffSKozlov Sergey /* disable S/S2 auto detection2 */ 568a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2d, 0x00); 569a6dc60ffSKozlov Sergey priv->state = STATE_SLEEP_S; 570a6dc60ffSKozlov Sergey return 0; 571a6dc60ffSKozlov Sergey } 572a6dc60ffSKozlov Sergey 573a6dc60ffSKozlov Sergey static int cxd2841er_sleep_s_to_shutdown(struct cxd2841er_priv *priv) 574a6dc60ffSKozlov Sergey { 575a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 576a6dc60ffSKozlov Sergey if (priv->state != STATE_SLEEP_S) { 577a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n", 578a6dc60ffSKozlov Sergey __func__, priv->state); 579a6dc60ffSKozlov Sergey return -EINVAL; 580a6dc60ffSKozlov Sergey } 581a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 582a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 583a6dc60ffSKozlov Sergey /* Disable DSQOUT */ 584a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); 585a6dc60ffSKozlov Sergey /* Disable DSQIN */ 586a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x9c, 0x00); 587a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 588a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 589a6dc60ffSKozlov Sergey /* Disable oscillator */ 590a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x15, 0x01); 591a6dc60ffSKozlov Sergey /* Set demod mode */ 592a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01); 593a6dc60ffSKozlov Sergey priv->state = STATE_SHUTDOWN; 594a6dc60ffSKozlov Sergey return 0; 595a6dc60ffSKozlov Sergey } 596a6dc60ffSKozlov Sergey 597a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv *priv) 598a6dc60ffSKozlov Sergey { 599a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 600a6dc60ffSKozlov Sergey if (priv->state != STATE_SLEEP_TC) { 601a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n", 602a6dc60ffSKozlov Sergey __func__, priv->state); 603a6dc60ffSKozlov Sergey return -EINVAL; 604a6dc60ffSKozlov Sergey } 605a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 606a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 607a6dc60ffSKozlov Sergey /* Disable oscillator */ 608a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x15, 0x01); 609a6dc60ffSKozlov Sergey /* Set demod mode */ 610a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01); 611a6dc60ffSKozlov Sergey priv->state = STATE_SHUTDOWN; 612a6dc60ffSKozlov Sergey return 0; 613a6dc60ffSKozlov Sergey } 614a6dc60ffSKozlov Sergey 615a6dc60ffSKozlov Sergey static int cxd2841er_active_t_to_sleep_tc(struct cxd2841er_priv *priv) 616a6dc60ffSKozlov Sergey { 617a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 618a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 619a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid state %d\n", 620a6dc60ffSKozlov Sergey __func__, priv->state); 621a6dc60ffSKozlov Sergey return -EINVAL; 622a6dc60ffSKozlov Sergey } 623a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 624a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 625a6dc60ffSKozlov Sergey /* disable TS output */ 626a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); 627a6dc60ffSKozlov Sergey /* enable Hi-Z setting 1 */ 628a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); 629a6dc60ffSKozlov Sergey /* enable Hi-Z setting 2 */ 630a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff); 631a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 632a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 633a6dc60ffSKozlov Sergey /* disable ADC 1 */ 634a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01); 635a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 636a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 637a6dc60ffSKozlov Sergey /* Disable ADC 2 */ 638a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); 639a6dc60ffSKozlov Sergey /* Disable ADC 3 */ 640a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); 641a6dc60ffSKozlov Sergey /* Disable ADC clock */ 642a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 643a6dc60ffSKozlov Sergey /* Disable RF level monitor */ 644a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); 645a6dc60ffSKozlov Sergey /* Disable demod clock */ 646a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); 647a6dc60ffSKozlov Sergey priv->state = STATE_SLEEP_TC; 648a6dc60ffSKozlov Sergey return 0; 649a6dc60ffSKozlov Sergey } 650a6dc60ffSKozlov Sergey 651a6dc60ffSKozlov Sergey static int cxd2841er_active_t2_to_sleep_tc(struct cxd2841er_priv *priv) 652a6dc60ffSKozlov Sergey { 653a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 654a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 655a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid state %d\n", 656a6dc60ffSKozlov Sergey __func__, priv->state); 657a6dc60ffSKozlov Sergey return -EINVAL; 658a6dc60ffSKozlov Sergey } 659a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 660a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 661a6dc60ffSKozlov Sergey /* disable TS output */ 662a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); 663a6dc60ffSKozlov Sergey /* enable Hi-Z setting 1 */ 664a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); 665a6dc60ffSKozlov Sergey /* enable Hi-Z setting 2 */ 666a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff); 667a6dc60ffSKozlov Sergey /* Cancel DVB-T2 setting */ 668a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13); 669a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x83, 0x40); 670a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x86, 0x21); 671a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9e, 0x09, 0x0f); 672a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x9f, 0xfb); 673a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2a); 674a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x38, 0x00, 0x0f); 675a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); 676a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x00, 0x3f); 677a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 678a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 679a6dc60ffSKozlov Sergey /* disable ADC 1 */ 680a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01); 681a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 682a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 683a6dc60ffSKozlov Sergey /* Disable ADC 2 */ 684a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); 685a6dc60ffSKozlov Sergey /* Disable ADC 3 */ 686a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); 687a6dc60ffSKozlov Sergey /* Disable ADC clock */ 688a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 689a6dc60ffSKozlov Sergey /* Disable RF level monitor */ 690a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); 691a6dc60ffSKozlov Sergey /* Disable demod clock */ 692a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); 693a6dc60ffSKozlov Sergey priv->state = STATE_SLEEP_TC; 694a6dc60ffSKozlov Sergey return 0; 695a6dc60ffSKozlov Sergey } 696a6dc60ffSKozlov Sergey 697a6dc60ffSKozlov Sergey static int cxd2841er_active_c_to_sleep_tc(struct cxd2841er_priv *priv) 698a6dc60ffSKozlov Sergey { 699a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 700a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 701a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid state %d\n", 702a6dc60ffSKozlov Sergey __func__, priv->state); 703a6dc60ffSKozlov Sergey return -EINVAL; 704a6dc60ffSKozlov Sergey } 705a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 706a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 707a6dc60ffSKozlov Sergey /* disable TS output */ 708a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); 709a6dc60ffSKozlov Sergey /* enable Hi-Z setting 1 */ 710a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); 711a6dc60ffSKozlov Sergey /* enable Hi-Z setting 2 */ 712a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff); 713a6dc60ffSKozlov Sergey /* Cancel DVB-C setting */ 714a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); 715a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa3, 0x00, 0x1f); 716a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 717a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 718a6dc60ffSKozlov Sergey /* disable ADC 1 */ 719a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01); 720a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 721a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 722a6dc60ffSKozlov Sergey /* Disable ADC 2 */ 723a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); 724a6dc60ffSKozlov Sergey /* Disable ADC 3 */ 725a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); 726a6dc60ffSKozlov Sergey /* Disable ADC clock */ 727a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 728a6dc60ffSKozlov Sergey /* Disable RF level monitor */ 729a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); 730a6dc60ffSKozlov Sergey /* Disable demod clock */ 731a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); 732a6dc60ffSKozlov Sergey priv->state = STATE_SLEEP_TC; 733a6dc60ffSKozlov Sergey return 0; 734a6dc60ffSKozlov Sergey } 735a6dc60ffSKozlov Sergey 73683808c23SAbylay Ospan static int cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv *priv) 73783808c23SAbylay Ospan { 73883808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 73983808c23SAbylay Ospan if (priv->state != STATE_ACTIVE_TC) { 74083808c23SAbylay Ospan dev_err(&priv->i2c->dev, "%s(): invalid state %d\n", 74183808c23SAbylay Ospan __func__, priv->state); 74283808c23SAbylay Ospan return -EINVAL; 74383808c23SAbylay Ospan } 74483808c23SAbylay Ospan /* Set SLV-T Bank : 0x00 */ 74583808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 74683808c23SAbylay Ospan /* disable TS output */ 74783808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01); 74883808c23SAbylay Ospan /* enable Hi-Z setting 1 */ 74983808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f); 75083808c23SAbylay Ospan /* enable Hi-Z setting 2 */ 75183808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff); 75283808c23SAbylay Ospan 75383808c23SAbylay Ospan /* TODO: Cancel demod parameter */ 75483808c23SAbylay Ospan 75583808c23SAbylay Ospan /* Set SLV-X Bank : 0x00 */ 75683808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 75783808c23SAbylay Ospan /* disable ADC 1 */ 75883808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01); 75983808c23SAbylay Ospan /* Set SLV-T Bank : 0x00 */ 76083808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 76183808c23SAbylay Ospan /* Disable ADC 2 */ 76283808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); 76383808c23SAbylay Ospan /* Disable ADC 3 */ 76483808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); 76583808c23SAbylay Ospan /* Disable ADC clock */ 76683808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 76783808c23SAbylay Ospan /* Disable RF level monitor */ 76883808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); 76983808c23SAbylay Ospan /* Disable demod clock */ 77083808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00); 77183808c23SAbylay Ospan priv->state = STATE_SLEEP_TC; 77283808c23SAbylay Ospan return 0; 77383808c23SAbylay Ospan } 77483808c23SAbylay Ospan 775a6dc60ffSKozlov Sergey static int cxd2841er_shutdown_to_sleep_s(struct cxd2841er_priv *priv) 776a6dc60ffSKozlov Sergey { 777a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 778a6dc60ffSKozlov Sergey if (priv->state != STATE_SHUTDOWN) { 779a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n", 780a6dc60ffSKozlov Sergey __func__, priv->state); 781a6dc60ffSKozlov Sergey return -EINVAL; 782a6dc60ffSKozlov Sergey } 783a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 784a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 785a6dc60ffSKozlov Sergey /* Clear all demodulator registers */ 786a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x02, 0x00); 787a6dc60ffSKozlov Sergey usleep_range(3000, 5000); 788a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 789a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 790a6dc60ffSKozlov Sergey /* Set demod SW reset */ 791a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01); 79283808c23SAbylay Ospan 79383808c23SAbylay Ospan switch (priv->xtal) { 79483808c23SAbylay Ospan case SONY_XTAL_20500: 795a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x00); 79683808c23SAbylay Ospan break; 79783808c23SAbylay Ospan case SONY_XTAL_24000: 79883808c23SAbylay Ospan /* Select demod frequency */ 79983808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00); 80083808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x03); 80183808c23SAbylay Ospan break; 80283808c23SAbylay Ospan case SONY_XTAL_41000: 80383808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x01); 80483808c23SAbylay Ospan break; 80583808c23SAbylay Ospan default: 80683808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): invalid demod xtal %d\n", 80783808c23SAbylay Ospan __func__, priv->xtal); 80883808c23SAbylay Ospan return -EINVAL; 80983808c23SAbylay Ospan } 81083808c23SAbylay Ospan 811a6dc60ffSKozlov Sergey /* Set demod mode */ 812a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x0a); 813a6dc60ffSKozlov Sergey /* Clear demod SW reset */ 814a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x00); 815a6dc60ffSKozlov Sergey usleep_range(1000, 2000); 816a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 817a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 818a6dc60ffSKozlov Sergey /* enable DSQOUT */ 819a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x1F); 820a6dc60ffSKozlov Sergey /* enable DSQIN */ 821a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x9C, 0x40); 822a6dc60ffSKozlov Sergey /* TADC Bias On */ 823a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); 824a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); 825a6dc60ffSKozlov Sergey /* SADC Bias On */ 826a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16); 827a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x27); 828a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x69, 0x06); 829a6dc60ffSKozlov Sergey priv->state = STATE_SLEEP_S; 830a6dc60ffSKozlov Sergey return 0; 831a6dc60ffSKozlov Sergey } 832a6dc60ffSKozlov Sergey 833a6dc60ffSKozlov Sergey static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv) 834a6dc60ffSKozlov Sergey { 8356c77161aSAbylay Ospan u8 data = 0; 8363f3b48a0SAbylay Ospan 837a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 838a6dc60ffSKozlov Sergey if (priv->state != STATE_SHUTDOWN) { 839a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n", 840a6dc60ffSKozlov Sergey __func__, priv->state); 841a6dc60ffSKozlov Sergey return -EINVAL; 842a6dc60ffSKozlov Sergey } 843a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 844a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 845a6dc60ffSKozlov Sergey /* Clear all demodulator registers */ 846a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x02, 0x00); 847a6dc60ffSKozlov Sergey usleep_range(3000, 5000); 848a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 849a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 850a6dc60ffSKozlov Sergey /* Set demod SW reset */ 851a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01); 8526c77161aSAbylay Ospan /* Select ADC clock mode */ 853a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x13, 0x00); 8546c77161aSAbylay Ospan 8556c77161aSAbylay Ospan switch (priv->xtal) { 8566c77161aSAbylay Ospan case SONY_XTAL_20500: 8576c77161aSAbylay Ospan data = 0x0; 8586c77161aSAbylay Ospan break; 8596c77161aSAbylay Ospan case SONY_XTAL_24000: 8606c77161aSAbylay Ospan /* Select demod frequency */ 8616c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00); 8626c77161aSAbylay Ospan data = 0x3; 8636c77161aSAbylay Ospan break; 8646c77161aSAbylay Ospan case SONY_XTAL_41000: 8656c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00); 8666c77161aSAbylay Ospan data = 0x1; 8676c77161aSAbylay Ospan break; 8686c77161aSAbylay Ospan } 8696c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x14, data); 870a6dc60ffSKozlov Sergey /* Clear demod SW reset */ 871a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x00); 872a6dc60ffSKozlov Sergey usleep_range(1000, 2000); 873a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 874a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 875a6dc60ffSKozlov Sergey /* TADC Bias On */ 876a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a); 877a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a); 878a6dc60ffSKozlov Sergey /* SADC Bias On */ 879a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16); 880a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x27); 881a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x69, 0x06); 882a6dc60ffSKozlov Sergey priv->state = STATE_SLEEP_TC; 883a6dc60ffSKozlov Sergey return 0; 884a6dc60ffSKozlov Sergey } 885a6dc60ffSKozlov Sergey 886a6dc60ffSKozlov Sergey static int cxd2841er_tune_done(struct cxd2841er_priv *priv) 887a6dc60ffSKozlov Sergey { 888a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 889a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 890a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0, 0); 891a6dc60ffSKozlov Sergey /* SW Reset */ 892a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xfe, 0x01); 893a6dc60ffSKozlov Sergey /* Enable TS output */ 894a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x00); 895a6dc60ffSKozlov Sergey return 0; 896a6dc60ffSKozlov Sergey } 897a6dc60ffSKozlov Sergey 898a6dc60ffSKozlov Sergey /* Set TS parallel mode */ 899a6dc60ffSKozlov Sergey static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv, 900a6dc60ffSKozlov Sergey u8 system) 901a6dc60ffSKozlov Sergey { 902a6dc60ffSKozlov Sergey u8 serial_ts, ts_rate_ctrl_off, ts_in_off; 903a6dc60ffSKozlov Sergey 904a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 905a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 906a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 907a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0xc4, &serial_ts); 908a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0xd3, &ts_rate_ctrl_off); 909a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0xde, &ts_in_off); 910a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): ser_ts=0x%02x rate_ctrl_off=0x%02x in_off=0x%02x\n", 911a6dc60ffSKozlov Sergey __func__, serial_ts, ts_rate_ctrl_off, ts_in_off); 912a6dc60ffSKozlov Sergey 913a6dc60ffSKozlov Sergey /* 914a6dc60ffSKozlov Sergey * slave Bank Addr Bit default Name 91503ab1bd5SDaniel Scheller * <SLV-T> 00h C4h [1:0] 2'b?? OSERCKMODE 91603ab1bd5SDaniel Scheller */ 91703ab1bd5SDaniel Scheller cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 91803ab1bd5SDaniel Scheller ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03); 91903ab1bd5SDaniel Scheller /* 92003ab1bd5SDaniel Scheller * slave Bank Addr Bit default Name 92103ab1bd5SDaniel Scheller * <SLV-T> 00h D1h [1:0] 2'b?? OSERDUTYMODE 92203ab1bd5SDaniel Scheller */ 92303ab1bd5SDaniel Scheller cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd1, 92403ab1bd5SDaniel Scheller ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03); 92503ab1bd5SDaniel Scheller /* 92603ab1bd5SDaniel Scheller * slave Bank Addr Bit default Name 927a6dc60ffSKozlov Sergey * <SLV-T> 00h D9h [7:0] 8'h08 OTSCKPERIOD 928a6dc60ffSKozlov Sergey */ 929a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xd9, 0x08); 930a6dc60ffSKozlov Sergey /* 931a6dc60ffSKozlov Sergey * Disable TS IF Clock 932a6dc60ffSKozlov Sergey * slave Bank Addr Bit default Name 933a6dc60ffSKozlov Sergey * <SLV-T> 00h 32h [0] 1'b1 OREG_CK_TSIF_EN 934a6dc60ffSKozlov Sergey */ 935a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x00, 0x01); 936a6dc60ffSKozlov Sergey /* 937a6dc60ffSKozlov Sergey * slave Bank Addr Bit default Name 938a6dc60ffSKozlov Sergey * <SLV-T> 00h 33h [1:0] 2'b01 OREG_CKSEL_TSIF 939a6dc60ffSKozlov Sergey */ 94003ab1bd5SDaniel Scheller cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33, 94103ab1bd5SDaniel Scheller ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03); 942a6dc60ffSKozlov Sergey /* 943a6dc60ffSKozlov Sergey * Enable TS IF Clock 944a6dc60ffSKozlov Sergey * slave Bank Addr Bit default Name 945a6dc60ffSKozlov Sergey * <SLV-T> 00h 32h [0] 1'b1 OREG_CK_TSIF_EN 946a6dc60ffSKozlov Sergey */ 947a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x01, 0x01); 948a6dc60ffSKozlov Sergey 949a6dc60ffSKozlov Sergey if (system == SYS_DVBT) { 950a6dc60ffSKozlov Sergey /* Enable parity period for DVB-T */ 951a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 952a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x66, 0x01, 0x01); 953a6dc60ffSKozlov Sergey } else if (system == SYS_DVBC_ANNEX_A) { 954a6dc60ffSKozlov Sergey /* Enable parity period for DVB-C */ 955a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); 956a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x66, 0x01, 0x01); 957a6dc60ffSKozlov Sergey } 958a6dc60ffSKozlov Sergey } 959a6dc60ffSKozlov Sergey 960a6dc60ffSKozlov Sergey static u8 cxd2841er_chip_id(struct cxd2841er_priv *priv) 961a6dc60ffSKozlov Sergey { 96283808c23SAbylay Ospan u8 chip_id = 0; 963a6dc60ffSKozlov Sergey 964a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 96583808c23SAbylay Ospan if (cxd2841er_write_reg(priv, I2C_SLVT, 0, 0) == 0) 966a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0xfd, &chip_id); 96783808c23SAbylay Ospan else if (cxd2841er_write_reg(priv, I2C_SLVX, 0, 0) == 0) 96883808c23SAbylay Ospan cxd2841er_read_reg(priv, I2C_SLVX, 0xfd, &chip_id); 96983808c23SAbylay Ospan 970a6dc60ffSKozlov Sergey return chip_id; 971a6dc60ffSKozlov Sergey } 972a6dc60ffSKozlov Sergey 973a6dc60ffSKozlov Sergey static int cxd2841er_read_status_s(struct dvb_frontend *fe, 974a6dc60ffSKozlov Sergey enum fe_status *status) 975a6dc60ffSKozlov Sergey { 976a6dc60ffSKozlov Sergey u8 reg = 0; 977a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 978a6dc60ffSKozlov Sergey 979a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 980a6dc60ffSKozlov Sergey *status = 0; 981a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_S) { 982a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid state %d\n", 983a6dc60ffSKozlov Sergey __func__, priv->state); 984a6dc60ffSKozlov Sergey return -EINVAL; 985a6dc60ffSKozlov Sergey } 986a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xA0 */ 987a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0); 988a6dc60ffSKozlov Sergey /* 989a6dc60ffSKozlov Sergey * slave Bank Addr Bit Signal name 990a6dc60ffSKozlov Sergey * <SLV-T> A0h 11h [2] ITSLOCK 991a6dc60ffSKozlov Sergey */ 992a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x11, ®); 993a6dc60ffSKozlov Sergey if (reg & 0x04) { 994a6dc60ffSKozlov Sergey *status = FE_HAS_SIGNAL 995a6dc60ffSKozlov Sergey | FE_HAS_CARRIER 996a6dc60ffSKozlov Sergey | FE_HAS_VITERBI 997a6dc60ffSKozlov Sergey | FE_HAS_SYNC 998a6dc60ffSKozlov Sergey | FE_HAS_LOCK; 999a6dc60ffSKozlov Sergey } 1000a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): result 0x%x\n", __func__, *status); 1001a6dc60ffSKozlov Sergey return 0; 1002a6dc60ffSKozlov Sergey } 1003a6dc60ffSKozlov Sergey 1004a6dc60ffSKozlov Sergey static int cxd2841er_read_status_t_t2(struct cxd2841er_priv *priv, 1005a6dc60ffSKozlov Sergey u8 *sync, u8 *tslock, u8 *unlock) 1006a6dc60ffSKozlov Sergey { 1007a6dc60ffSKozlov Sergey u8 data = 0; 1008a6dc60ffSKozlov Sergey 1009a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 1010a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) 1011a6dc60ffSKozlov Sergey return -EINVAL; 1012a6dc60ffSKozlov Sergey if (priv->system == SYS_DVBT) { 1013a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x10 */ 1014a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 1015a6dc60ffSKozlov Sergey } else { 1016a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x20 */ 1017a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); 1018a6dc60ffSKozlov Sergey } 1019a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data); 1020a6dc60ffSKozlov Sergey if ((data & 0x07) == 0x07) { 1021a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1022a6dc60ffSKozlov Sergey "%s(): invalid hardware state detected\n", __func__); 1023a6dc60ffSKozlov Sergey *sync = 0; 1024a6dc60ffSKozlov Sergey *tslock = 0; 1025a6dc60ffSKozlov Sergey *unlock = 0; 1026a6dc60ffSKozlov Sergey } else { 1027a6dc60ffSKozlov Sergey *sync = ((data & 0x07) == 0x6 ? 1 : 0); 1028a6dc60ffSKozlov Sergey *tslock = ((data & 0x20) ? 1 : 0); 1029a6dc60ffSKozlov Sergey *unlock = ((data & 0x10) ? 1 : 0); 1030a6dc60ffSKozlov Sergey } 1031a6dc60ffSKozlov Sergey return 0; 1032a6dc60ffSKozlov Sergey } 1033a6dc60ffSKozlov Sergey 1034a6dc60ffSKozlov Sergey static int cxd2841er_read_status_c(struct cxd2841er_priv *priv, u8 *tslock) 1035a6dc60ffSKozlov Sergey { 1036a6dc60ffSKozlov Sergey u8 data; 1037a6dc60ffSKozlov Sergey 1038a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 1039a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) 1040a6dc60ffSKozlov Sergey return -EINVAL; 1041a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); 1042a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x88, &data); 1043a6dc60ffSKozlov Sergey if ((data & 0x01) == 0) { 1044a6dc60ffSKozlov Sergey *tslock = 0; 1045a6dc60ffSKozlov Sergey } else { 1046a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data); 1047a6dc60ffSKozlov Sergey *tslock = ((data & 0x20) ? 1 : 0); 1048a6dc60ffSKozlov Sergey } 1049a6dc60ffSKozlov Sergey return 0; 1050a6dc60ffSKozlov Sergey } 1051a6dc60ffSKozlov Sergey 105283808c23SAbylay Ospan static int cxd2841er_read_status_i(struct cxd2841er_priv *priv, 105383808c23SAbylay Ospan u8 *sync, u8 *tslock, u8 *unlock) 105483808c23SAbylay Ospan { 105583808c23SAbylay Ospan u8 data = 0; 105683808c23SAbylay Ospan 105783808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 105883808c23SAbylay Ospan if (priv->state != STATE_ACTIVE_TC) 105983808c23SAbylay Ospan return -EINVAL; 106083808c23SAbylay Ospan /* Set SLV-T Bank : 0x60 */ 106183808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); 106283808c23SAbylay Ospan cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data); 106383808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, 106483808c23SAbylay Ospan "%s(): lock=0x%x\n", __func__, data); 106583808c23SAbylay Ospan *sync = ((data & 0x02) ? 1 : 0); 106683808c23SAbylay Ospan *tslock = ((data & 0x01) ? 1 : 0); 106783808c23SAbylay Ospan *unlock = ((data & 0x10) ? 1 : 0); 106883808c23SAbylay Ospan return 0; 106983808c23SAbylay Ospan } 107083808c23SAbylay Ospan 1071a6dc60ffSKozlov Sergey static int cxd2841er_read_status_tc(struct dvb_frontend *fe, 1072a6dc60ffSKozlov Sergey enum fe_status *status) 1073a6dc60ffSKozlov Sergey { 1074a6dc60ffSKozlov Sergey int ret = 0; 1075a6dc60ffSKozlov Sergey u8 sync = 0; 1076a6dc60ffSKozlov Sergey u8 tslock = 0; 1077a6dc60ffSKozlov Sergey u8 unlock = 0; 1078a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 1079a6dc60ffSKozlov Sergey 1080a6dc60ffSKozlov Sergey *status = 0; 1081a6dc60ffSKozlov Sergey if (priv->state == STATE_ACTIVE_TC) { 1082a6dc60ffSKozlov Sergey if (priv->system == SYS_DVBT || priv->system == SYS_DVBT2) { 1083a6dc60ffSKozlov Sergey ret = cxd2841er_read_status_t_t2( 1084a6dc60ffSKozlov Sergey priv, &sync, &tslock, &unlock); 1085a6dc60ffSKozlov Sergey if (ret) 1086a6dc60ffSKozlov Sergey goto done; 1087a6dc60ffSKozlov Sergey if (unlock) 1088a6dc60ffSKozlov Sergey goto done; 1089a6dc60ffSKozlov Sergey if (sync) 1090a6dc60ffSKozlov Sergey *status = FE_HAS_SIGNAL | 1091a6dc60ffSKozlov Sergey FE_HAS_CARRIER | 1092a6dc60ffSKozlov Sergey FE_HAS_VITERBI | 1093a6dc60ffSKozlov Sergey FE_HAS_SYNC; 1094a6dc60ffSKozlov Sergey if (tslock) 1095a6dc60ffSKozlov Sergey *status |= FE_HAS_LOCK; 109683808c23SAbylay Ospan } else if (priv->system == SYS_ISDBT) { 109783808c23SAbylay Ospan ret = cxd2841er_read_status_i( 109883808c23SAbylay Ospan priv, &sync, &tslock, &unlock); 109983808c23SAbylay Ospan if (ret) 110083808c23SAbylay Ospan goto done; 110183808c23SAbylay Ospan if (unlock) 110283808c23SAbylay Ospan goto done; 110383808c23SAbylay Ospan if (sync) 110483808c23SAbylay Ospan *status = FE_HAS_SIGNAL | 110583808c23SAbylay Ospan FE_HAS_CARRIER | 110683808c23SAbylay Ospan FE_HAS_VITERBI | 110783808c23SAbylay Ospan FE_HAS_SYNC; 110883808c23SAbylay Ospan if (tslock) 110983808c23SAbylay Ospan *status |= FE_HAS_LOCK; 1110a6dc60ffSKozlov Sergey } else if (priv->system == SYS_DVBC_ANNEX_A) { 1111a6dc60ffSKozlov Sergey ret = cxd2841er_read_status_c(priv, &tslock); 1112a6dc60ffSKozlov Sergey if (ret) 1113a6dc60ffSKozlov Sergey goto done; 1114a6dc60ffSKozlov Sergey if (tslock) 1115a6dc60ffSKozlov Sergey *status = FE_HAS_SIGNAL | 1116a6dc60ffSKozlov Sergey FE_HAS_CARRIER | 1117a6dc60ffSKozlov Sergey FE_HAS_VITERBI | 1118a6dc60ffSKozlov Sergey FE_HAS_SYNC | 1119a6dc60ffSKozlov Sergey FE_HAS_LOCK; 1120a6dc60ffSKozlov Sergey } 1121a6dc60ffSKozlov Sergey } 1122a6dc60ffSKozlov Sergey done: 1123a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): status 0x%x\n", __func__, *status); 1124a6dc60ffSKozlov Sergey return ret; 1125a6dc60ffSKozlov Sergey } 1126a6dc60ffSKozlov Sergey 1127a6dc60ffSKozlov Sergey static int cxd2841er_get_carrier_offset_s_s2(struct cxd2841er_priv *priv, 1128a6dc60ffSKozlov Sergey int *offset) 1129a6dc60ffSKozlov Sergey { 1130a6dc60ffSKozlov Sergey u8 data[3]; 1131a6dc60ffSKozlov Sergey u8 is_hs_mode; 1132a6dc60ffSKozlov Sergey s32 cfrl_ctrlval; 1133a6dc60ffSKozlov Sergey s32 temp_div, temp_q, temp_r; 1134a6dc60ffSKozlov Sergey 1135a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_S) { 1136a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 1137a6dc60ffSKozlov Sergey __func__, priv->state); 1138a6dc60ffSKozlov Sergey return -EINVAL; 1139a6dc60ffSKozlov Sergey } 1140a6dc60ffSKozlov Sergey /* 1141a6dc60ffSKozlov Sergey * Get High Sampling Rate mode 1142a6dc60ffSKozlov Sergey * slave Bank Addr Bit Signal name 1143a6dc60ffSKozlov Sergey * <SLV-T> A0h 10h [0] ITRL_LOCK 1144a6dc60ffSKozlov Sergey */ 1145a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0); 1146a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data[0]); 1147a6dc60ffSKozlov Sergey if (data[0] & 0x01) { 1148a6dc60ffSKozlov Sergey /* 1149a6dc60ffSKozlov Sergey * slave Bank Addr Bit Signal name 1150a6dc60ffSKozlov Sergey * <SLV-T> A0h 50h [4] IHSMODE 1151a6dc60ffSKozlov Sergey */ 1152a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x50, &data[0]); 1153a6dc60ffSKozlov Sergey is_hs_mode = (data[0] & 0x10 ? 1 : 0); 1154a6dc60ffSKozlov Sergey } else { 1155a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1156a6dc60ffSKozlov Sergey "%s(): unable to detect sampling rate mode\n", 1157a6dc60ffSKozlov Sergey __func__); 1158a6dc60ffSKozlov Sergey return -EINVAL; 1159a6dc60ffSKozlov Sergey } 1160a6dc60ffSKozlov Sergey /* 1161a6dc60ffSKozlov Sergey * slave Bank Addr Bit Signal name 1162a6dc60ffSKozlov Sergey * <SLV-T> A0h 45h [4:0] ICFRL_CTRLVAL[20:16] 1163a6dc60ffSKozlov Sergey * <SLV-T> A0h 46h [7:0] ICFRL_CTRLVAL[15:8] 1164a6dc60ffSKozlov Sergey * <SLV-T> A0h 47h [7:0] ICFRL_CTRLVAL[7:0] 1165a6dc60ffSKozlov Sergey */ 1166a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x45, data, 3); 1167a6dc60ffSKozlov Sergey cfrl_ctrlval = sign_extend32((((u32)data[0] & 0x1F) << 16) | 1168a6dc60ffSKozlov Sergey (((u32)data[1] & 0xFF) << 8) | 1169a6dc60ffSKozlov Sergey ((u32)data[2] & 0xFF), 20); 1170a6dc60ffSKozlov Sergey temp_div = (is_hs_mode ? 1048576 : 1572864); 1171a6dc60ffSKozlov Sergey if (cfrl_ctrlval > 0) { 1172a6dc60ffSKozlov Sergey temp_q = div_s64_rem(97375LL * cfrl_ctrlval, 1173a6dc60ffSKozlov Sergey temp_div, &temp_r); 1174a6dc60ffSKozlov Sergey } else { 1175a6dc60ffSKozlov Sergey temp_q = div_s64_rem(-97375LL * cfrl_ctrlval, 1176a6dc60ffSKozlov Sergey temp_div, &temp_r); 1177a6dc60ffSKozlov Sergey } 1178a6dc60ffSKozlov Sergey if (temp_r >= temp_div / 2) 1179a6dc60ffSKozlov Sergey temp_q++; 1180a6dc60ffSKozlov Sergey if (cfrl_ctrlval > 0) 1181a6dc60ffSKozlov Sergey temp_q *= -1; 1182a6dc60ffSKozlov Sergey *offset = temp_q; 1183a6dc60ffSKozlov Sergey return 0; 1184a6dc60ffSKozlov Sergey } 1185a6dc60ffSKozlov Sergey 118676344a3fSMauro Carvalho Chehab static int cxd2841er_get_carrier_offset_i(struct cxd2841er_priv *priv, 118776344a3fSMauro Carvalho Chehab u32 bandwidth, int *offset) 118876344a3fSMauro Carvalho Chehab { 118976344a3fSMauro Carvalho Chehab u8 data[4]; 119076344a3fSMauro Carvalho Chehab 119176344a3fSMauro Carvalho Chehab dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 119276344a3fSMauro Carvalho Chehab if (priv->state != STATE_ACTIVE_TC) { 119376344a3fSMauro Carvalho Chehab dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 119476344a3fSMauro Carvalho Chehab __func__, priv->state); 119576344a3fSMauro Carvalho Chehab return -EINVAL; 119676344a3fSMauro Carvalho Chehab } 119776344a3fSMauro Carvalho Chehab if (priv->system != SYS_ISDBT) { 119876344a3fSMauro Carvalho Chehab dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n", 119976344a3fSMauro Carvalho Chehab __func__, priv->system); 120076344a3fSMauro Carvalho Chehab return -EINVAL; 120176344a3fSMauro Carvalho Chehab } 120276344a3fSMauro Carvalho Chehab cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); 120376344a3fSMauro Carvalho Chehab cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data)); 120476344a3fSMauro Carvalho Chehab *offset = -1 * sign_extend32( 120576344a3fSMauro Carvalho Chehab ((u32)(data[0] & 0x1F) << 24) | ((u32)data[1] << 16) | 120676344a3fSMauro Carvalho Chehab ((u32)data[2] << 8) | (u32)data[3], 29); 120776344a3fSMauro Carvalho Chehab 120876344a3fSMauro Carvalho Chehab switch (bandwidth) { 120976344a3fSMauro Carvalho Chehab case 6000000: 121076344a3fSMauro Carvalho Chehab *offset = -1 * ((*offset) * 8/264); 121176344a3fSMauro Carvalho Chehab break; 121276344a3fSMauro Carvalho Chehab case 7000000: 121376344a3fSMauro Carvalho Chehab *offset = -1 * ((*offset) * 8/231); 121476344a3fSMauro Carvalho Chehab break; 121576344a3fSMauro Carvalho Chehab case 8000000: 121676344a3fSMauro Carvalho Chehab *offset = -1 * ((*offset) * 8/198); 121776344a3fSMauro Carvalho Chehab break; 121876344a3fSMauro Carvalho Chehab default: 121976344a3fSMauro Carvalho Chehab dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n", 122076344a3fSMauro Carvalho Chehab __func__, bandwidth); 122176344a3fSMauro Carvalho Chehab return -EINVAL; 122276344a3fSMauro Carvalho Chehab } 122376344a3fSMauro Carvalho Chehab 122476344a3fSMauro Carvalho Chehab dev_dbg(&priv->i2c->dev, "%s(): bandwidth %d offset %d\n", 122576344a3fSMauro Carvalho Chehab __func__, bandwidth, *offset); 122676344a3fSMauro Carvalho Chehab 122776344a3fSMauro Carvalho Chehab return 0; 122876344a3fSMauro Carvalho Chehab } 122976344a3fSMauro Carvalho Chehab 1230c5ea46daSAbylay Ospan static int cxd2841er_get_carrier_offset_t(struct cxd2841er_priv *priv, 1231c5ea46daSAbylay Ospan u32 bandwidth, int *offset) 1232c5ea46daSAbylay Ospan { 1233c5ea46daSAbylay Ospan u8 data[4]; 1234c5ea46daSAbylay Ospan 1235c5ea46daSAbylay Ospan dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 1236c5ea46daSAbylay Ospan if (priv->state != STATE_ACTIVE_TC) { 1237c5ea46daSAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 1238c5ea46daSAbylay Ospan __func__, priv->state); 1239c5ea46daSAbylay Ospan return -EINVAL; 1240c5ea46daSAbylay Ospan } 1241c5ea46daSAbylay Ospan if (priv->system != SYS_DVBT) { 1242c5ea46daSAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n", 1243c5ea46daSAbylay Ospan __func__, priv->system); 1244c5ea46daSAbylay Ospan return -EINVAL; 1245c5ea46daSAbylay Ospan } 1246c5ea46daSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 1247c5ea46daSAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data)); 1248c5ea46daSAbylay Ospan *offset = -1 * sign_extend32( 1249c5ea46daSAbylay Ospan ((u32)(data[0] & 0x1F) << 24) | ((u32)data[1] << 16) | 1250c5ea46daSAbylay Ospan ((u32)data[2] << 8) | (u32)data[3], 29); 12514da093ceSAbylay Ospan *offset *= (bandwidth / 1000000); 12524da093ceSAbylay Ospan *offset /= 235; 1253c5ea46daSAbylay Ospan return 0; 1254c5ea46daSAbylay Ospan } 1255c5ea46daSAbylay Ospan 1256c8946c8dSMauro Carvalho Chehab static int cxd2841er_get_carrier_offset_t2(struct cxd2841er_priv *priv, 1257c8946c8dSMauro Carvalho Chehab u32 bandwidth, int *offset) 1258a6dc60ffSKozlov Sergey { 1259a6dc60ffSKozlov Sergey u8 data[4]; 1260a6dc60ffSKozlov Sergey 1261a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 1262a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 1263a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 1264a6dc60ffSKozlov Sergey __func__, priv->state); 1265a6dc60ffSKozlov Sergey return -EINVAL; 1266a6dc60ffSKozlov Sergey } 1267a6dc60ffSKozlov Sergey if (priv->system != SYS_DVBT2) { 1268a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n", 1269a6dc60ffSKozlov Sergey __func__, priv->system); 1270a6dc60ffSKozlov Sergey return -EINVAL; 1271a6dc60ffSKozlov Sergey } 1272a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); 1273a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data)); 1274a6dc60ffSKozlov Sergey *offset = -1 * sign_extend32( 1275a6dc60ffSKozlov Sergey ((u32)(data[0] & 0x0F) << 24) | ((u32)data[1] << 16) | 1276a6dc60ffSKozlov Sergey ((u32)data[2] << 8) | (u32)data[3], 27); 1277a6dc60ffSKozlov Sergey switch (bandwidth) { 1278a6dc60ffSKozlov Sergey case 1712000: 1279a6dc60ffSKozlov Sergey *offset /= 582; 1280a6dc60ffSKozlov Sergey break; 1281a6dc60ffSKozlov Sergey case 5000000: 1282a6dc60ffSKozlov Sergey case 6000000: 1283a6dc60ffSKozlov Sergey case 7000000: 1284a6dc60ffSKozlov Sergey case 8000000: 1285a6dc60ffSKozlov Sergey *offset *= (bandwidth / 1000000); 1286a6dc60ffSKozlov Sergey *offset /= 940; 1287a6dc60ffSKozlov Sergey break; 1288a6dc60ffSKozlov Sergey default: 1289a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n", 1290a6dc60ffSKozlov Sergey __func__, bandwidth); 1291a6dc60ffSKozlov Sergey return -EINVAL; 1292a6dc60ffSKozlov Sergey } 1293a6dc60ffSKozlov Sergey return 0; 1294a6dc60ffSKozlov Sergey } 1295a6dc60ffSKozlov Sergey 1296c8946c8dSMauro Carvalho Chehab static int cxd2841er_get_carrier_offset_c(struct cxd2841er_priv *priv, 1297c8946c8dSMauro Carvalho Chehab int *offset) 1298a6dc60ffSKozlov Sergey { 1299a6dc60ffSKozlov Sergey u8 data[2]; 1300a6dc60ffSKozlov Sergey 1301a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 1302a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 1303a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 1304a6dc60ffSKozlov Sergey __func__, priv->state); 1305a6dc60ffSKozlov Sergey return -EINVAL; 1306a6dc60ffSKozlov Sergey } 1307a6dc60ffSKozlov Sergey if (priv->system != SYS_DVBC_ANNEX_A) { 1308a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n", 1309a6dc60ffSKozlov Sergey __func__, priv->system); 1310a6dc60ffSKozlov Sergey return -EINVAL; 1311a6dc60ffSKozlov Sergey } 1312a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); 1313a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x15, data, sizeof(data)); 1314a6dc60ffSKozlov Sergey *offset = div_s64(41000LL * sign_extend32((((u32)data[0] & 0x3f) << 8) 1315a6dc60ffSKozlov Sergey | (u32)data[1], 13), 16384); 1316a6dc60ffSKozlov Sergey return 0; 1317a6dc60ffSKozlov Sergey } 1318a6dc60ffSKozlov Sergey 1319a6f330cbSAbylay Ospan static int cxd2841er_read_packet_errors_c( 1320a6f330cbSAbylay Ospan struct cxd2841er_priv *priv, u32 *penum) 1321a6f330cbSAbylay Ospan { 1322a6f330cbSAbylay Ospan u8 data[3]; 1323a6f330cbSAbylay Ospan 1324a6f330cbSAbylay Ospan *penum = 0; 1325a6f330cbSAbylay Ospan if (priv->state != STATE_ACTIVE_TC) { 1326a6f330cbSAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 1327a6f330cbSAbylay Ospan __func__, priv->state); 1328a6f330cbSAbylay Ospan return -EINVAL; 1329a6f330cbSAbylay Ospan } 1330a6f330cbSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); 1331a6f330cbSAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0xea, data, sizeof(data)); 1332a6f330cbSAbylay Ospan if (data[2] & 0x01) 1333a6f330cbSAbylay Ospan *penum = ((u32)data[0] << 8) | (u32)data[1]; 1334a6f330cbSAbylay Ospan return 0; 1335a6f330cbSAbylay Ospan } 1336a6f330cbSAbylay Ospan 1337a6dc60ffSKozlov Sergey static int cxd2841er_read_packet_errors_t( 1338a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv, u32 *penum) 1339a6dc60ffSKozlov Sergey { 1340a6dc60ffSKozlov Sergey u8 data[3]; 1341a6dc60ffSKozlov Sergey 1342a6dc60ffSKozlov Sergey *penum = 0; 1343a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 1344a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 1345a6dc60ffSKozlov Sergey __func__, priv->state); 1346a6dc60ffSKozlov Sergey return -EINVAL; 1347a6dc60ffSKozlov Sergey } 1348a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 1349a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0xea, data, sizeof(data)); 1350a6dc60ffSKozlov Sergey if (data[2] & 0x01) 1351a6dc60ffSKozlov Sergey *penum = ((u32)data[0] << 8) | (u32)data[1]; 1352a6dc60ffSKozlov Sergey return 0; 1353a6dc60ffSKozlov Sergey } 1354a6dc60ffSKozlov Sergey 1355a6dc60ffSKozlov Sergey static int cxd2841er_read_packet_errors_t2( 1356a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv, u32 *penum) 1357a6dc60ffSKozlov Sergey { 1358a6dc60ffSKozlov Sergey u8 data[3]; 1359a6dc60ffSKozlov Sergey 1360a6dc60ffSKozlov Sergey *penum = 0; 1361a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 1362a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 1363a6dc60ffSKozlov Sergey __func__, priv->state); 1364a6dc60ffSKozlov Sergey return -EINVAL; 1365a6dc60ffSKozlov Sergey } 1366a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x24); 1367a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0xfd, data, sizeof(data)); 1368a6dc60ffSKozlov Sergey if (data[0] & 0x01) 1369a6dc60ffSKozlov Sergey *penum = ((u32)data[1] << 8) | (u32)data[2]; 1370a6dc60ffSKozlov Sergey return 0; 1371a6dc60ffSKozlov Sergey } 1372a6dc60ffSKozlov Sergey 137383808c23SAbylay Ospan static int cxd2841er_read_packet_errors_i( 137483808c23SAbylay Ospan struct cxd2841er_priv *priv, u32 *penum) 137583808c23SAbylay Ospan { 137683808c23SAbylay Ospan u8 data[2]; 137783808c23SAbylay Ospan 137883808c23SAbylay Ospan *penum = 0; 137983808c23SAbylay Ospan if (priv->state != STATE_ACTIVE_TC) { 138083808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 138183808c23SAbylay Ospan __func__, priv->state); 138283808c23SAbylay Ospan return -EINVAL; 138383808c23SAbylay Ospan } 138483808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); 138583808c23SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0xA1, data, 1); 138683808c23SAbylay Ospan 138783808c23SAbylay Ospan if (!(data[0] & 0x01)) 138883808c23SAbylay Ospan return 0; 138983808c23SAbylay Ospan 139083808c23SAbylay Ospan /* Layer A */ 139183808c23SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0xA2, data, sizeof(data)); 139283808c23SAbylay Ospan *penum = ((u32)data[0] << 8) | (u32)data[1]; 139383808c23SAbylay Ospan 139483808c23SAbylay Ospan /* Layer B */ 139583808c23SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0xA4, data, sizeof(data)); 139683808c23SAbylay Ospan *penum += ((u32)data[0] << 8) | (u32)data[1]; 139783808c23SAbylay Ospan 139883808c23SAbylay Ospan /* Layer C */ 139983808c23SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0xA6, data, sizeof(data)); 140083808c23SAbylay Ospan *penum += ((u32)data[0] << 8) | (u32)data[1]; 140183808c23SAbylay Ospan 140283808c23SAbylay Ospan return 0; 140383808c23SAbylay Ospan } 140483808c23SAbylay Ospan 1405a6f330cbSAbylay Ospan static int cxd2841er_read_ber_c(struct cxd2841er_priv *priv, 1406a6f330cbSAbylay Ospan u32 *bit_error, u32 *bit_count) 1407a6f330cbSAbylay Ospan { 1408a6f330cbSAbylay Ospan u8 data[3]; 1409a6f330cbSAbylay Ospan u32 bit_err, period_exp; 1410a6f330cbSAbylay Ospan 1411a6f330cbSAbylay Ospan dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 1412a6f330cbSAbylay Ospan if (priv->state != STATE_ACTIVE_TC) { 1413a6f330cbSAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 1414a6f330cbSAbylay Ospan __func__, priv->state); 1415a6f330cbSAbylay Ospan return -EINVAL; 1416a6f330cbSAbylay Ospan } 1417a6f330cbSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); 1418a6f330cbSAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0x62, data, sizeof(data)); 1419a6f330cbSAbylay Ospan if (!(data[0] & 0x80)) { 1420a6f330cbSAbylay Ospan dev_dbg(&priv->i2c->dev, 1421a6f330cbSAbylay Ospan "%s(): no valid BER data\n", __func__); 1422a6f330cbSAbylay Ospan return -EINVAL; 1423a6f330cbSAbylay Ospan } 1424a6f330cbSAbylay Ospan bit_err = ((u32)(data[0] & 0x3f) << 16) | 1425a6f330cbSAbylay Ospan ((u32)data[1] << 8) | 1426a6f330cbSAbylay Ospan (u32)data[2]; 1427a6f330cbSAbylay Ospan cxd2841er_read_reg(priv, I2C_SLVT, 0x60, data); 1428a6f330cbSAbylay Ospan period_exp = data[0] & 0x1f; 1429a6f330cbSAbylay Ospan 1430a6f330cbSAbylay Ospan if ((period_exp <= 11) && (bit_err > (1 << period_exp) * 204 * 8)) { 1431a6f330cbSAbylay Ospan dev_dbg(&priv->i2c->dev, 1432a6f330cbSAbylay Ospan "%s(): period_exp(%u) or bit_err(%u) not in range. no valid BER data\n", 1433a6f330cbSAbylay Ospan __func__, period_exp, bit_err); 1434a6f330cbSAbylay Ospan return -EINVAL; 1435a6f330cbSAbylay Ospan } 1436a6f330cbSAbylay Ospan 1437a6f330cbSAbylay Ospan dev_dbg(&priv->i2c->dev, 1438a6f330cbSAbylay Ospan "%s(): period_exp(%u) or bit_err(%u) count=%d\n", 1439a6f330cbSAbylay Ospan __func__, period_exp, bit_err, 1440a6f330cbSAbylay Ospan ((1 << period_exp) * 204 * 8)); 1441a6f330cbSAbylay Ospan 1442a6f330cbSAbylay Ospan *bit_error = bit_err; 1443a6f330cbSAbylay Ospan *bit_count = ((1 << period_exp) * 204 * 8); 1444a6f330cbSAbylay Ospan 1445a6f330cbSAbylay Ospan return 0; 1446a6f330cbSAbylay Ospan } 1447a6f330cbSAbylay Ospan 14480854df79SAbylay Ospan static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv, 14490854df79SAbylay Ospan u32 *bit_error, u32 *bit_count) 14500854df79SAbylay Ospan { 14510854df79SAbylay Ospan u8 data[3]; 14520854df79SAbylay Ospan u8 pktnum[2]; 14530854df79SAbylay Ospan 14540854df79SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 14550854df79SAbylay Ospan if (priv->state != STATE_ACTIVE_TC) { 14560854df79SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 14570854df79SAbylay Ospan __func__, priv->state); 14580854df79SAbylay Ospan return -EINVAL; 14590854df79SAbylay Ospan } 14600854df79SAbylay Ospan 14610854df79SAbylay Ospan cxd2841er_freeze_regs(priv); 14620854df79SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); 14630854df79SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0x5B, pktnum, sizeof(pktnum)); 14640854df79SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0x16, data, sizeof(data)); 14656ccf821cSDaniel Scheller cxd2841er_unfreeze_regs(priv); 14660854df79SAbylay Ospan 14670854df79SAbylay Ospan if (!pktnum[0] && !pktnum[1]) { 14680854df79SAbylay Ospan dev_dbg(&priv->i2c->dev, 14690854df79SAbylay Ospan "%s(): no valid BER data\n", __func__); 14700854df79SAbylay Ospan return -EINVAL; 14710854df79SAbylay Ospan } 14720854df79SAbylay Ospan 14730854df79SAbylay Ospan *bit_error = ((u32)(data[0] & 0x7F) << 16) | 14740854df79SAbylay Ospan ((u32)data[1] << 8) | data[2]; 14750854df79SAbylay Ospan *bit_count = ((((u32)pktnum[0] << 8) | pktnum[1]) * 204 * 8); 14760854df79SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): bit_error=%u bit_count=%u\n", 14770854df79SAbylay Ospan __func__, *bit_error, *bit_count); 14780854df79SAbylay Ospan 14790854df79SAbylay Ospan return 0; 14800854df79SAbylay Ospan } 14810854df79SAbylay Ospan 14824216be14SMauro Carvalho Chehab static int cxd2841er_mon_read_ber_s(struct cxd2841er_priv *priv, 14834216be14SMauro Carvalho Chehab u32 *bit_error, u32 *bit_count) 1484a6dc60ffSKozlov Sergey { 1485a6dc60ffSKozlov Sergey u8 data[11]; 1486a6dc60ffSKozlov Sergey 1487a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xA0 */ 1488a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0); 1489a6dc60ffSKozlov Sergey /* 1490a6dc60ffSKozlov Sergey * slave Bank Addr Bit Signal name 1491a6dc60ffSKozlov Sergey * <SLV-T> A0h 35h [0] IFVBER_VALID 1492a6dc60ffSKozlov Sergey * <SLV-T> A0h 36h [5:0] IFVBER_BITERR[21:16] 1493a6dc60ffSKozlov Sergey * <SLV-T> A0h 37h [7:0] IFVBER_BITERR[15:8] 1494a6dc60ffSKozlov Sergey * <SLV-T> A0h 38h [7:0] IFVBER_BITERR[7:0] 1495a6dc60ffSKozlov Sergey * <SLV-T> A0h 3Dh [5:0] IFVBER_BITNUM[21:16] 1496a6dc60ffSKozlov Sergey * <SLV-T> A0h 3Eh [7:0] IFVBER_BITNUM[15:8] 1497a6dc60ffSKozlov Sergey * <SLV-T> A0h 3Fh [7:0] IFVBER_BITNUM[7:0] 1498a6dc60ffSKozlov Sergey */ 1499a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x35, data, 11); 1500a6dc60ffSKozlov Sergey if (data[0] & 0x01) { 15014216be14SMauro Carvalho Chehab *bit_error = ((u32)(data[1] & 0x3F) << 16) | 1502a6dc60ffSKozlov Sergey ((u32)(data[2] & 0xFF) << 8) | 1503a6dc60ffSKozlov Sergey (u32)(data[3] & 0xFF); 15044216be14SMauro Carvalho Chehab *bit_count = ((u32)(data[8] & 0x3F) << 16) | 1505a6dc60ffSKozlov Sergey ((u32)(data[9] & 0xFF) << 8) | 1506a6dc60ffSKozlov Sergey (u32)(data[10] & 0xFF); 15074216be14SMauro Carvalho Chehab if ((*bit_count == 0) || (*bit_error > *bit_count)) { 1508a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1509a6dc60ffSKozlov Sergey "%s(): invalid bit_error %d, bit_count %d\n", 15104216be14SMauro Carvalho Chehab __func__, *bit_error, *bit_count); 1511f1b26622SMauro Carvalho Chehab return -EINVAL; 1512a6dc60ffSKozlov Sergey } 1513a6dc60ffSKozlov Sergey return 0; 1514a6dc60ffSKozlov Sergey } 1515f1b26622SMauro Carvalho Chehab dev_dbg(&priv->i2c->dev, "%s(): no data available\n", __func__); 1516f1b26622SMauro Carvalho Chehab return -EINVAL; 1517f1b26622SMauro Carvalho Chehab } 1518a6dc60ffSKozlov Sergey 1519a6dc60ffSKozlov Sergey 15204216be14SMauro Carvalho Chehab static int cxd2841er_mon_read_ber_s2(struct cxd2841er_priv *priv, 15214216be14SMauro Carvalho Chehab u32 *bit_error, u32 *bit_count) 1522a6dc60ffSKozlov Sergey { 1523a6dc60ffSKozlov Sergey u8 data[5]; 15244216be14SMauro Carvalho Chehab u32 period; 1525a6dc60ffSKozlov Sergey 1526a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xB2 */ 1527a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xb2); 1528a6dc60ffSKozlov Sergey /* 1529a6dc60ffSKozlov Sergey * slave Bank Addr Bit Signal name 1530a6dc60ffSKozlov Sergey * <SLV-T> B2h 30h [0] IFLBER_VALID 1531a6dc60ffSKozlov Sergey * <SLV-T> B2h 31h [3:0] IFLBER_BITERR[27:24] 1532a6dc60ffSKozlov Sergey * <SLV-T> B2h 32h [7:0] IFLBER_BITERR[23:16] 1533a6dc60ffSKozlov Sergey * <SLV-T> B2h 33h [7:0] IFLBER_BITERR[15:8] 1534a6dc60ffSKozlov Sergey * <SLV-T> B2h 34h [7:0] IFLBER_BITERR[7:0] 1535a6dc60ffSKozlov Sergey */ 1536a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x30, data, 5); 1537a6dc60ffSKozlov Sergey if (data[0] & 0x01) { 1538a6dc60ffSKozlov Sergey /* Bit error count */ 15394216be14SMauro Carvalho Chehab *bit_error = ((u32)(data[1] & 0x0F) << 24) | 1540a6dc60ffSKozlov Sergey ((u32)(data[2] & 0xFF) << 16) | 1541a6dc60ffSKozlov Sergey ((u32)(data[3] & 0xFF) << 8) | 1542a6dc60ffSKozlov Sergey (u32)(data[4] & 0xFF); 1543a6dc60ffSKozlov Sergey 1544a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xA0 */ 1545a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0); 1546a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x7a, data); 1547a6dc60ffSKozlov Sergey /* Measurement period */ 1548a6dc60ffSKozlov Sergey period = (u32)(1 << (data[0] & 0x0F)); 1549a6dc60ffSKozlov Sergey if (period == 0) { 1550a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1551a6dc60ffSKozlov Sergey "%s(): period is 0\n", __func__); 1552f1b26622SMauro Carvalho Chehab return -EINVAL; 1553a6dc60ffSKozlov Sergey } 15544216be14SMauro Carvalho Chehab if (*bit_error > (period * 64800)) { 1555a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1556a6dc60ffSKozlov Sergey "%s(): invalid bit_err 0x%x period 0x%x\n", 15574216be14SMauro Carvalho Chehab __func__, *bit_error, period); 1558f1b26622SMauro Carvalho Chehab return -EINVAL; 1559a6dc60ffSKozlov Sergey } 15604216be14SMauro Carvalho Chehab *bit_count = period * 64800; 15614216be14SMauro Carvalho Chehab 1562f1b26622SMauro Carvalho Chehab return 0; 1563a6dc60ffSKozlov Sergey } else { 1564a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1565a6dc60ffSKozlov Sergey "%s(): no data available\n", __func__); 1566a6dc60ffSKozlov Sergey } 1567f1b26622SMauro Carvalho Chehab return -EINVAL; 1568a6dc60ffSKozlov Sergey } 1569a6dc60ffSKozlov Sergey 15704216be14SMauro Carvalho Chehab static int cxd2841er_read_ber_t2(struct cxd2841er_priv *priv, 15714216be14SMauro Carvalho Chehab u32 *bit_error, u32 *bit_count) 1572a6dc60ffSKozlov Sergey { 1573a6dc60ffSKozlov Sergey u8 data[4]; 15744216be14SMauro Carvalho Chehab u32 period_exp, n_ldpc; 1575a6dc60ffSKozlov Sergey 1576a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 1577a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1578a6dc60ffSKozlov Sergey "%s(): invalid state %d\n", __func__, priv->state); 1579a6dc60ffSKozlov Sergey return -EINVAL; 1580a6dc60ffSKozlov Sergey } 1581a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); 1582a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x39, data, sizeof(data)); 1583a6dc60ffSKozlov Sergey if (!(data[0] & 0x10)) { 1584a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1585a6dc60ffSKozlov Sergey "%s(): no valid BER data\n", __func__); 15864216be14SMauro Carvalho Chehab return -EINVAL; 1587a6dc60ffSKozlov Sergey } 15884216be14SMauro Carvalho Chehab *bit_error = ((u32)(data[0] & 0x0f) << 24) | 1589a6dc60ffSKozlov Sergey ((u32)data[1] << 16) | 1590a6dc60ffSKozlov Sergey ((u32)data[2] << 8) | 1591a6dc60ffSKozlov Sergey (u32)data[3]; 1592a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x6f, data); 1593a6dc60ffSKozlov Sergey period_exp = data[0] & 0x0f; 1594a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x22); 1595a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x5e, data); 1596a6dc60ffSKozlov Sergey n_ldpc = ((data[0] & 0x03) == 0 ? 16200 : 64800); 15974216be14SMauro Carvalho Chehab if (*bit_error > ((1U << period_exp) * n_ldpc)) { 1598a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1599a6dc60ffSKozlov Sergey "%s(): invalid BER value\n", __func__); 1600a6dc60ffSKozlov Sergey return -EINVAL; 1601a6dc60ffSKozlov Sergey } 16024216be14SMauro Carvalho Chehab 16034216be14SMauro Carvalho Chehab /* 16044216be14SMauro Carvalho Chehab * FIXME: the right thing would be to return bit_error untouched, 16054216be14SMauro Carvalho Chehab * but, as we don't know the scale returned by the counters, let's 16064216be14SMauro Carvalho Chehab * at least preserver BER = bit_error/bit_count. 16074216be14SMauro Carvalho Chehab */ 1608a6dc60ffSKozlov Sergey if (period_exp >= 4) { 16094216be14SMauro Carvalho Chehab *bit_count = (1U << (period_exp - 4)) * (n_ldpc / 200); 16104216be14SMauro Carvalho Chehab *bit_error *= 3125ULL; 1611a6dc60ffSKozlov Sergey } else { 16124216be14SMauro Carvalho Chehab *bit_count = (1U << period_exp) * (n_ldpc / 200); 1613a6f330cbSAbylay Ospan *bit_error *= 50000ULL; 1614a6dc60ffSKozlov Sergey } 1615a6dc60ffSKozlov Sergey return 0; 1616a6dc60ffSKozlov Sergey } 1617a6dc60ffSKozlov Sergey 16184216be14SMauro Carvalho Chehab static int cxd2841er_read_ber_t(struct cxd2841er_priv *priv, 16194216be14SMauro Carvalho Chehab u32 *bit_error, u32 *bit_count) 1620a6dc60ffSKozlov Sergey { 1621a6dc60ffSKozlov Sergey u8 data[2]; 16224216be14SMauro Carvalho Chehab u32 period; 1623a6dc60ffSKozlov Sergey 1624a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 1625a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1626a6dc60ffSKozlov Sergey "%s(): invalid state %d\n", __func__, priv->state); 1627a6dc60ffSKozlov Sergey return -EINVAL; 1628a6dc60ffSKozlov Sergey } 1629a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 1630a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x39, data); 1631a6dc60ffSKozlov Sergey if (!(data[0] & 0x01)) { 1632a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1633a6dc60ffSKozlov Sergey "%s(): no valid BER data\n", __func__); 1634a6dc60ffSKozlov Sergey return 0; 1635a6dc60ffSKozlov Sergey } 1636a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x22, data, sizeof(data)); 16374216be14SMauro Carvalho Chehab *bit_error = ((u32)data[0] << 8) | (u32)data[1]; 1638a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x6f, data); 1639a6dc60ffSKozlov Sergey period = ((data[0] & 0x07) == 0) ? 256 : (4096 << (data[0] & 0x07)); 16404216be14SMauro Carvalho Chehab 16414216be14SMauro Carvalho Chehab /* 16424216be14SMauro Carvalho Chehab * FIXME: the right thing would be to return bit_error untouched, 16434216be14SMauro Carvalho Chehab * but, as we don't know the scale returned by the counters, let's 16444216be14SMauro Carvalho Chehab * at least preserver BER = bit_error/bit_count. 16454216be14SMauro Carvalho Chehab */ 16464216be14SMauro Carvalho Chehab *bit_count = period / 128; 16474216be14SMauro Carvalho Chehab *bit_error *= 78125ULL; 1648a6dc60ffSKozlov Sergey return 0; 1649a6dc60ffSKozlov Sergey } 1650a6dc60ffSKozlov Sergey 16514a86bc10SAbylay Ospan static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv) 16524a86bc10SAbylay Ospan { 16534a86bc10SAbylay Ospan /* 16544a86bc10SAbylay Ospan * Freeze registers: ensure multiple separate register reads 16554a86bc10SAbylay Ospan * are from the same snapshot 16564a86bc10SAbylay Ospan */ 16574a86bc10SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01); 16584a86bc10SAbylay Ospan return 0; 16594a86bc10SAbylay Ospan } 16604a86bc10SAbylay Ospan 16614a86bc10SAbylay Ospan static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv) 16624a86bc10SAbylay Ospan { 16634a86bc10SAbylay Ospan /* 16644a86bc10SAbylay Ospan * un-freeze registers 16654a86bc10SAbylay Ospan */ 16664a86bc10SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x00); 16674a86bc10SAbylay Ospan return 0; 16684a86bc10SAbylay Ospan } 16694a86bc10SAbylay Ospan 1670e05b1872SAbylay Ospan static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv, 1671e05b1872SAbylay Ospan u8 delsys, u32 *snr) 1672a6dc60ffSKozlov Sergey { 1673a6dc60ffSKozlov Sergey u8 data[3]; 1674a6dc60ffSKozlov Sergey u32 res = 0, value; 1675a6dc60ffSKozlov Sergey int min_index, max_index, index; 1676a6dc60ffSKozlov Sergey static const struct cxd2841er_cnr_data *cn_data; 1677a6dc60ffSKozlov Sergey 16784a86bc10SAbylay Ospan cxd2841er_freeze_regs(priv); 1679a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xA1 */ 1680a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa1); 1681a6dc60ffSKozlov Sergey /* 1682a6dc60ffSKozlov Sergey * slave Bank Addr Bit Signal name 1683a6dc60ffSKozlov Sergey * <SLV-T> A1h 10h [0] ICPM_QUICKRDY 1684a6dc60ffSKozlov Sergey * <SLV-T> A1h 11h [4:0] ICPM_QUICKCNDT[12:8] 1685a6dc60ffSKozlov Sergey * <SLV-T> A1h 12h [7:0] ICPM_QUICKCNDT[7:0] 1686a6dc60ffSKozlov Sergey */ 1687a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x10, data, 3); 16886ccf821cSDaniel Scheller cxd2841er_unfreeze_regs(priv); 16896ccf821cSDaniel Scheller 1690a6dc60ffSKozlov Sergey if (data[0] & 0x01) { 1691a6dc60ffSKozlov Sergey value = ((u32)(data[1] & 0x1F) << 8) | (u32)(data[2] & 0xFF); 1692a6dc60ffSKozlov Sergey min_index = 0; 1693a6dc60ffSKozlov Sergey if (delsys == SYS_DVBS) { 1694a6dc60ffSKozlov Sergey cn_data = s_cn_data; 1695a6dc60ffSKozlov Sergey max_index = sizeof(s_cn_data) / 1696a6dc60ffSKozlov Sergey sizeof(s_cn_data[0]) - 1; 1697a6dc60ffSKozlov Sergey } else { 1698a6dc60ffSKozlov Sergey cn_data = s2_cn_data; 1699a6dc60ffSKozlov Sergey max_index = sizeof(s2_cn_data) / 1700a6dc60ffSKozlov Sergey sizeof(s2_cn_data[0]) - 1; 1701a6dc60ffSKozlov Sergey } 1702a6dc60ffSKozlov Sergey if (value >= cn_data[min_index].value) { 1703a6dc60ffSKozlov Sergey res = cn_data[min_index].cnr_x1000; 1704a6dc60ffSKozlov Sergey goto done; 1705a6dc60ffSKozlov Sergey } 1706a6dc60ffSKozlov Sergey if (value <= cn_data[max_index].value) { 1707a6dc60ffSKozlov Sergey res = cn_data[max_index].cnr_x1000; 1708a6dc60ffSKozlov Sergey goto done; 1709a6dc60ffSKozlov Sergey } 1710a6dc60ffSKozlov Sergey while ((max_index - min_index) > 1) { 1711a6dc60ffSKozlov Sergey index = (max_index + min_index) / 2; 1712a6dc60ffSKozlov Sergey if (value == cn_data[index].value) { 1713a6dc60ffSKozlov Sergey res = cn_data[index].cnr_x1000; 1714a6dc60ffSKozlov Sergey goto done; 1715a6dc60ffSKozlov Sergey } else if (value > cn_data[index].value) 1716a6dc60ffSKozlov Sergey max_index = index; 1717a6dc60ffSKozlov Sergey else 1718a6dc60ffSKozlov Sergey min_index = index; 1719a6dc60ffSKozlov Sergey if ((max_index - min_index) <= 1) { 1720a6dc60ffSKozlov Sergey if (value == cn_data[max_index].value) { 1721a6dc60ffSKozlov Sergey res = cn_data[max_index].cnr_x1000; 1722a6dc60ffSKozlov Sergey goto done; 1723a6dc60ffSKozlov Sergey } else { 1724a6dc60ffSKozlov Sergey res = cn_data[min_index].cnr_x1000; 1725a6dc60ffSKozlov Sergey goto done; 1726a6dc60ffSKozlov Sergey } 1727a6dc60ffSKozlov Sergey } 1728a6dc60ffSKozlov Sergey } 1729a6dc60ffSKozlov Sergey } else { 1730a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1731a6dc60ffSKozlov Sergey "%s(): no data available\n", __func__); 1732e05b1872SAbylay Ospan return -EINVAL; 1733a6dc60ffSKozlov Sergey } 1734a6dc60ffSKozlov Sergey done: 1735e05b1872SAbylay Ospan *snr = res; 1736e05b1872SAbylay Ospan return 0; 1737e05b1872SAbylay Ospan } 1738e05b1872SAbylay Ospan 1739e05b1872SAbylay Ospan static uint32_t sony_log(uint32_t x) 1740e05b1872SAbylay Ospan { 1741e05b1872SAbylay Ospan return (((10000>>8)*(intlog2(x)>>16) + LOG2_E_100X/2)/LOG2_E_100X); 1742e05b1872SAbylay Ospan } 1743e05b1872SAbylay Ospan 1744e05b1872SAbylay Ospan static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr) 1745e05b1872SAbylay Ospan { 1746e05b1872SAbylay Ospan u32 reg; 1747e05b1872SAbylay Ospan u8 data[2]; 1748e05b1872SAbylay Ospan enum sony_dvbc_constellation_t qam = SONY_DVBC_CONSTELLATION_16QAM; 1749e05b1872SAbylay Ospan 1750e05b1872SAbylay Ospan *snr = 0; 1751e05b1872SAbylay Ospan if (priv->state != STATE_ACTIVE_TC) { 1752e05b1872SAbylay Ospan dev_dbg(&priv->i2c->dev, 1753e05b1872SAbylay Ospan "%s(): invalid state %d\n", 1754e05b1872SAbylay Ospan __func__, priv->state); 1755e05b1872SAbylay Ospan return -EINVAL; 1756e05b1872SAbylay Ospan } 1757e05b1872SAbylay Ospan 17584a86bc10SAbylay Ospan cxd2841er_freeze_regs(priv); 1759e05b1872SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); 1760e05b1872SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1); 1761e05b1872SAbylay Ospan qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07); 1762e05b1872SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0x4C, data, 2); 17636ccf821cSDaniel Scheller cxd2841er_unfreeze_regs(priv); 1764e05b1872SAbylay Ospan 1765e05b1872SAbylay Ospan reg = ((u32)(data[0]&0x1f) << 8) | (u32)data[1]; 1766e05b1872SAbylay Ospan if (reg == 0) { 1767e05b1872SAbylay Ospan dev_dbg(&priv->i2c->dev, 1768e05b1872SAbylay Ospan "%s(): reg value out of range\n", __func__); 1769e05b1872SAbylay Ospan return 0; 1770e05b1872SAbylay Ospan } 1771e05b1872SAbylay Ospan 1772e05b1872SAbylay Ospan switch (qam) { 1773e05b1872SAbylay Ospan case SONY_DVBC_CONSTELLATION_16QAM: 1774e05b1872SAbylay Ospan case SONY_DVBC_CONSTELLATION_64QAM: 1775e05b1872SAbylay Ospan case SONY_DVBC_CONSTELLATION_256QAM: 1776e05b1872SAbylay Ospan /* SNR(dB) = -9.50 * ln(IREG_SNR_ESTIMATE / (24320)) */ 1777e05b1872SAbylay Ospan if (reg < 126) 1778e05b1872SAbylay Ospan reg = 126; 1779e05b1872SAbylay Ospan *snr = -95 * (int32_t)sony_log(reg) + 95941; 1780e05b1872SAbylay Ospan break; 1781e05b1872SAbylay Ospan case SONY_DVBC_CONSTELLATION_32QAM: 1782e05b1872SAbylay Ospan case SONY_DVBC_CONSTELLATION_128QAM: 1783e05b1872SAbylay Ospan /* SNR(dB) = -8.75 * ln(IREG_SNR_ESTIMATE / (20800)) */ 1784e05b1872SAbylay Ospan if (reg < 69) 1785e05b1872SAbylay Ospan reg = 69; 1786e05b1872SAbylay Ospan *snr = -88 * (int32_t)sony_log(reg) + 86999; 1787e05b1872SAbylay Ospan break; 1788e05b1872SAbylay Ospan default: 1789e05b1872SAbylay Ospan return -EINVAL; 1790e05b1872SAbylay Ospan } 1791e05b1872SAbylay Ospan 1792e05b1872SAbylay Ospan return 0; 1793a6dc60ffSKozlov Sergey } 1794a6dc60ffSKozlov Sergey 1795a6dc60ffSKozlov Sergey static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr) 1796a6dc60ffSKozlov Sergey { 1797a6dc60ffSKozlov Sergey u32 reg; 1798a6dc60ffSKozlov Sergey u8 data[2]; 1799a6dc60ffSKozlov Sergey 1800a6dc60ffSKozlov Sergey *snr = 0; 1801a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 1802a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1803a6dc60ffSKozlov Sergey "%s(): invalid state %d\n", __func__, priv->state); 1804a6dc60ffSKozlov Sergey return -EINVAL; 1805a6dc60ffSKozlov Sergey } 18064a86bc10SAbylay Ospan 18074a86bc10SAbylay Ospan cxd2841er_freeze_regs(priv); 1808a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 1809a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); 18106ccf821cSDaniel Scheller cxd2841er_unfreeze_regs(priv); 18116ccf821cSDaniel Scheller 1812a6dc60ffSKozlov Sergey reg = ((u32)data[0] << 8) | (u32)data[1]; 1813a6dc60ffSKozlov Sergey if (reg == 0) { 1814a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1815a6dc60ffSKozlov Sergey "%s(): reg value out of range\n", __func__); 1816a6dc60ffSKozlov Sergey return 0; 1817a6dc60ffSKozlov Sergey } 1818a6dc60ffSKozlov Sergey if (reg > 4996) 1819a6dc60ffSKozlov Sergey reg = 4996; 1820a6dc60ffSKozlov Sergey *snr = 10000 * ((intlog10(reg) - intlog10(5350 - reg)) >> 24) + 28500; 1821a6dc60ffSKozlov Sergey return 0; 1822a6dc60ffSKozlov Sergey } 1823a6dc60ffSKozlov Sergey 1824c8946c8dSMauro Carvalho Chehab static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr) 1825a6dc60ffSKozlov Sergey { 1826a6dc60ffSKozlov Sergey u32 reg; 1827a6dc60ffSKozlov Sergey u8 data[2]; 1828a6dc60ffSKozlov Sergey 1829a6dc60ffSKozlov Sergey *snr = 0; 1830a6dc60ffSKozlov Sergey if (priv->state != STATE_ACTIVE_TC) { 1831a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1832a6dc60ffSKozlov Sergey "%s(): invalid state %d\n", __func__, priv->state); 1833a6dc60ffSKozlov Sergey return -EINVAL; 1834a6dc60ffSKozlov Sergey } 18354a86bc10SAbylay Ospan 18364a86bc10SAbylay Ospan cxd2841er_freeze_regs(priv); 1837a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); 1838a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); 18396ccf821cSDaniel Scheller cxd2841er_unfreeze_regs(priv); 18406ccf821cSDaniel Scheller 1841a6dc60ffSKozlov Sergey reg = ((u32)data[0] << 8) | (u32)data[1]; 1842a6dc60ffSKozlov Sergey if (reg == 0) { 1843a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 1844a6dc60ffSKozlov Sergey "%s(): reg value out of range\n", __func__); 1845a6dc60ffSKozlov Sergey return 0; 1846a6dc60ffSKozlov Sergey } 1847a6dc60ffSKozlov Sergey if (reg > 10876) 1848a6dc60ffSKozlov Sergey reg = 10876; 1849a6dc60ffSKozlov Sergey *snr = 10000 * ((intlog10(reg) - 1850a6dc60ffSKozlov Sergey intlog10(12600 - reg)) >> 24) + 32000; 1851a6dc60ffSKozlov Sergey return 0; 1852a6dc60ffSKozlov Sergey } 1853a6dc60ffSKozlov Sergey 185483808c23SAbylay Ospan static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr) 185583808c23SAbylay Ospan { 185683808c23SAbylay Ospan u32 reg; 185783808c23SAbylay Ospan u8 data[2]; 185883808c23SAbylay Ospan 185983808c23SAbylay Ospan *snr = 0; 186083808c23SAbylay Ospan if (priv->state != STATE_ACTIVE_TC) { 186183808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, 186283808c23SAbylay Ospan "%s(): invalid state %d\n", __func__, 186383808c23SAbylay Ospan priv->state); 186483808c23SAbylay Ospan return -EINVAL; 186583808c23SAbylay Ospan } 186683808c23SAbylay Ospan 18674a86bc10SAbylay Ospan cxd2841er_freeze_regs(priv); 186883808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); 186983808c23SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data)); 18706ccf821cSDaniel Scheller cxd2841er_unfreeze_regs(priv); 18716ccf821cSDaniel Scheller 187283808c23SAbylay Ospan reg = ((u32)data[0] << 8) | (u32)data[1]; 187383808c23SAbylay Ospan if (reg == 0) { 187483808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, 187583808c23SAbylay Ospan "%s(): reg value out of range\n", __func__); 187683808c23SAbylay Ospan return 0; 187783808c23SAbylay Ospan } 18780854df79SAbylay Ospan *snr = 10000 * (intlog10(reg) >> 24) - 9031; 187983808c23SAbylay Ospan return 0; 188083808c23SAbylay Ospan } 188183808c23SAbylay Ospan 1882d0998ce7SAbylay Ospan static u16 cxd2841er_read_agc_gain_c(struct cxd2841er_priv *priv, 1883d0998ce7SAbylay Ospan u8 delsys) 1884d0998ce7SAbylay Ospan { 1885d0998ce7SAbylay Ospan u8 data[2]; 1886d0998ce7SAbylay Ospan 1887d0998ce7SAbylay Ospan cxd2841er_write_reg( 1888d0998ce7SAbylay Ospan priv, I2C_SLVT, 0x00, 0x40); 1889d0998ce7SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0x49, data, 2); 1890d0998ce7SAbylay Ospan dev_dbg(&priv->i2c->dev, 1891d0998ce7SAbylay Ospan "%s(): AGC value=%u\n", 1892d0998ce7SAbylay Ospan __func__, (((u16)data[0] & 0x0F) << 8) | 1893d0998ce7SAbylay Ospan (u16)(data[1] & 0xFF)); 1894d0998ce7SAbylay Ospan return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4; 1895d0998ce7SAbylay Ospan } 1896d0998ce7SAbylay Ospan 1897a6dc60ffSKozlov Sergey static u16 cxd2841er_read_agc_gain_t_t2(struct cxd2841er_priv *priv, 1898a6dc60ffSKozlov Sergey u8 delsys) 1899a6dc60ffSKozlov Sergey { 1900a6dc60ffSKozlov Sergey u8 data[2]; 1901a6dc60ffSKozlov Sergey 1902a6dc60ffSKozlov Sergey cxd2841er_write_reg( 1903a6dc60ffSKozlov Sergey priv, I2C_SLVT, 0x00, (delsys == SYS_DVBT ? 0x10 : 0x20)); 1904a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x26, data, 2); 1905c5ea46daSAbylay Ospan dev_dbg(&priv->i2c->dev, 1906c5ea46daSAbylay Ospan "%s(): AGC value=%u\n", 1907c5ea46daSAbylay Ospan __func__, (((u16)data[0] & 0x0F) << 8) | 1908c5ea46daSAbylay Ospan (u16)(data[1] & 0xFF)); 1909a6dc60ffSKozlov Sergey return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4; 1910a6dc60ffSKozlov Sergey } 1911a6dc60ffSKozlov Sergey 191283808c23SAbylay Ospan static u16 cxd2841er_read_agc_gain_i(struct cxd2841er_priv *priv, 191383808c23SAbylay Ospan u8 delsys) 191483808c23SAbylay Ospan { 191583808c23SAbylay Ospan u8 data[2]; 191683808c23SAbylay Ospan 191783808c23SAbylay Ospan cxd2841er_write_reg( 191883808c23SAbylay Ospan priv, I2C_SLVT, 0x00, 0x60); 191983808c23SAbylay Ospan cxd2841er_read_regs(priv, I2C_SLVT, 0x26, data, 2); 192083808c23SAbylay Ospan 192183808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, 192283808c23SAbylay Ospan "%s(): AGC value=%u\n", 192383808c23SAbylay Ospan __func__, (((u16)data[0] & 0x0F) << 8) | 192483808c23SAbylay Ospan (u16)(data[1] & 0xFF)); 192583808c23SAbylay Ospan return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4; 192683808c23SAbylay Ospan } 192783808c23SAbylay Ospan 1928a6dc60ffSKozlov Sergey static u16 cxd2841er_read_agc_gain_s(struct cxd2841er_priv *priv) 1929a6dc60ffSKozlov Sergey { 1930a6dc60ffSKozlov Sergey u8 data[2]; 1931a6dc60ffSKozlov Sergey 1932a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0xA0 */ 1933a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0); 1934a6dc60ffSKozlov Sergey /* 1935a6dc60ffSKozlov Sergey * slave Bank Addr Bit Signal name 1936a6dc60ffSKozlov Sergey * <SLV-T> A0h 1Fh [4:0] IRFAGC_GAIN[12:8] 1937a6dc60ffSKozlov Sergey * <SLV-T> A0h 20h [7:0] IRFAGC_GAIN[7:0] 1938a6dc60ffSKozlov Sergey */ 1939a6dc60ffSKozlov Sergey cxd2841er_read_regs(priv, I2C_SLVT, 0x1f, data, 2); 1940a6dc60ffSKozlov Sergey return ((((u16)data[0] & 0x1F) << 8) | (u16)(data[1] & 0xFF)) << 3; 1941a6dc60ffSKozlov Sergey } 1942a6dc60ffSKozlov Sergey 1943f1b26622SMauro Carvalho Chehab static void cxd2841er_read_ber(struct dvb_frontend *fe) 1944a6dc60ffSKozlov Sergey { 1945a6dc60ffSKozlov Sergey struct dtv_frontend_properties *p = &fe->dtv_property_cache; 1946a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 19474216be14SMauro Carvalho Chehab u32 ret, bit_error = 0, bit_count = 0; 1948a6dc60ffSKozlov Sergey 1949a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 1950a6dc60ffSKozlov Sergey switch (p->delivery_system) { 1951a6f330cbSAbylay Ospan case SYS_DVBC_ANNEX_A: 1952a6f330cbSAbylay Ospan case SYS_DVBC_ANNEX_B: 1953a6f330cbSAbylay Ospan case SYS_DVBC_ANNEX_C: 1954a6f330cbSAbylay Ospan ret = cxd2841er_read_ber_c(priv, &bit_error, &bit_count); 1955a6f330cbSAbylay Ospan break; 19560854df79SAbylay Ospan case SYS_ISDBT: 19570854df79SAbylay Ospan ret = cxd2841er_read_ber_i(priv, &bit_error, &bit_count); 19580854df79SAbylay Ospan break; 1959a6dc60ffSKozlov Sergey case SYS_DVBS: 19604216be14SMauro Carvalho Chehab ret = cxd2841er_mon_read_ber_s(priv, &bit_error, &bit_count); 1961a6dc60ffSKozlov Sergey break; 1962a6dc60ffSKozlov Sergey case SYS_DVBS2: 19634216be14SMauro Carvalho Chehab ret = cxd2841er_mon_read_ber_s2(priv, &bit_error, &bit_count); 1964a6dc60ffSKozlov Sergey break; 1965a6dc60ffSKozlov Sergey case SYS_DVBT: 19664216be14SMauro Carvalho Chehab ret = cxd2841er_read_ber_t(priv, &bit_error, &bit_count); 1967a6dc60ffSKozlov Sergey break; 1968f1b26622SMauro Carvalho Chehab case SYS_DVBT2: 19694216be14SMauro Carvalho Chehab ret = cxd2841er_read_ber_t2(priv, &bit_error, &bit_count); 1970f1b26622SMauro Carvalho Chehab break; 1971f1b26622SMauro Carvalho Chehab default: 1972f1b26622SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 19734216be14SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 1974f1b26622SMauro Carvalho Chehab return; 1975a6dc60ffSKozlov Sergey } 1976f1b26622SMauro Carvalho Chehab 1977f1b26622SMauro Carvalho Chehab if (!ret) { 1978f1b26622SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 1979a6f330cbSAbylay Ospan p->post_bit_error.stat[0].uvalue += bit_error; 19804216be14SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 1981a6f330cbSAbylay Ospan p->post_bit_count.stat[0].uvalue += bit_count; 1982f1b26622SMauro Carvalho Chehab } else { 1983f1b26622SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 19844216be14SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 1985f1b26622SMauro Carvalho Chehab } 1986a6dc60ffSKozlov Sergey } 1987a6dc60ffSKozlov Sergey 19885fda1b65SMauro Carvalho Chehab static void cxd2841er_read_signal_strength(struct dvb_frontend *fe) 1989a6dc60ffSKozlov Sergey { 1990a6dc60ffSKozlov Sergey struct dtv_frontend_properties *p = &fe->dtv_property_cache; 1991a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 1992313a7dfbSMauro Carvalho Chehab s32 strength; 1993a6dc60ffSKozlov Sergey 1994a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 1995a6dc60ffSKozlov Sergey switch (p->delivery_system) { 1996a6dc60ffSKozlov Sergey case SYS_DVBT: 1997a6dc60ffSKozlov Sergey case SYS_DVBT2: 19985fda1b65SMauro Carvalho Chehab strength = cxd2841er_read_agc_gain_t_t2(priv, 19995fda1b65SMauro Carvalho Chehab p->delivery_system); 20005fda1b65SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_DECIBEL; 20015fda1b65SMauro Carvalho Chehab /* Formula was empirically determinated @ 410 MHz */ 2002313a7dfbSMauro Carvalho Chehab p->strength.stat[0].uvalue = strength * 366 / 100 - 89520; 20035fda1b65SMauro Carvalho Chehab break; /* Code moved out of the function */ 2004988bd281SMauro Carvalho Chehab case SYS_DVBC_ANNEX_A: 2005997bdc0cSAbylay Ospan case SYS_DVBC_ANNEX_B: 2006997bdc0cSAbylay Ospan case SYS_DVBC_ANNEX_C: 2007997bdc0cSAbylay Ospan strength = cxd2841er_read_agc_gain_c(priv, 2008988bd281SMauro Carvalho Chehab p->delivery_system); 2009d12b791eSMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_DECIBEL; 2010d12b791eSMauro Carvalho Chehab /* 2011d12b791eSMauro Carvalho Chehab * Formula was empirically determinated via linear regression, 2012d12b791eSMauro Carvalho Chehab * using frequencies: 175 MHz, 410 MHz and 800 MHz, and a 2013d12b791eSMauro Carvalho Chehab * stream modulated with QAM64 2014d12b791eSMauro Carvalho Chehab */ 2015313a7dfbSMauro Carvalho Chehab p->strength.stat[0].uvalue = strength * 4045 / 1000 - 85224; 2016988bd281SMauro Carvalho Chehab break; 201783808c23SAbylay Ospan case SYS_ISDBT: 2018313a7dfbSMauro Carvalho Chehab strength = cxd2841er_read_agc_gain_i(priv, p->delivery_system); 2019313a7dfbSMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_DECIBEL; 2020313a7dfbSMauro Carvalho Chehab /* 2021313a7dfbSMauro Carvalho Chehab * Formula was empirically determinated via linear regression, 2022313a7dfbSMauro Carvalho Chehab * using frequencies: 175 MHz, 410 MHz and 800 MHz. 2023313a7dfbSMauro Carvalho Chehab */ 2024313a7dfbSMauro Carvalho Chehab p->strength.stat[0].uvalue = strength * 3775 / 1000 - 90185; 202583808c23SAbylay Ospan break; 2026a6dc60ffSKozlov Sergey case SYS_DVBS: 2027a6dc60ffSKozlov Sergey case SYS_DVBS2: 20285fda1b65SMauro Carvalho Chehab strength = 65535 - cxd2841er_read_agc_gain_s(priv); 20295fda1b65SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_RELATIVE; 20305fda1b65SMauro Carvalho Chehab p->strength.stat[0].uvalue = strength; 2031a6dc60ffSKozlov Sergey break; 2032a6dc60ffSKozlov Sergey default: 2033f1b26622SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 2034a6dc60ffSKozlov Sergey break; 2035a6dc60ffSKozlov Sergey } 2036a6dc60ffSKozlov Sergey } 2037a6dc60ffSKozlov Sergey 2038f1b26622SMauro Carvalho Chehab static void cxd2841er_read_snr(struct dvb_frontend *fe) 2039a6dc60ffSKozlov Sergey { 2040a6dc60ffSKozlov Sergey u32 tmp = 0; 2041e05b1872SAbylay Ospan int ret = 0; 2042a6dc60ffSKozlov Sergey struct dtv_frontend_properties *p = &fe->dtv_property_cache; 2043a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 2044a6dc60ffSKozlov Sergey 2045a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 2046a6dc60ffSKozlov Sergey switch (p->delivery_system) { 2047e05b1872SAbylay Ospan case SYS_DVBC_ANNEX_A: 2048e05b1872SAbylay Ospan case SYS_DVBC_ANNEX_B: 2049e05b1872SAbylay Ospan case SYS_DVBC_ANNEX_C: 2050e05b1872SAbylay Ospan ret = cxd2841er_read_snr_c(priv, &tmp); 2051e05b1872SAbylay Ospan break; 2052a6dc60ffSKozlov Sergey case SYS_DVBT: 2053e05b1872SAbylay Ospan ret = cxd2841er_read_snr_t(priv, &tmp); 2054a6dc60ffSKozlov Sergey break; 2055a6dc60ffSKozlov Sergey case SYS_DVBT2: 2056e05b1872SAbylay Ospan ret = cxd2841er_read_snr_t2(priv, &tmp); 2057a6dc60ffSKozlov Sergey break; 205883808c23SAbylay Ospan case SYS_ISDBT: 2059e05b1872SAbylay Ospan ret = cxd2841er_read_snr_i(priv, &tmp); 206083808c23SAbylay Ospan break; 2061a6dc60ffSKozlov Sergey case SYS_DVBS: 2062a6dc60ffSKozlov Sergey case SYS_DVBS2: 2063e05b1872SAbylay Ospan ret = cxd2841er_dvbs_read_snr(priv, p->delivery_system, &tmp); 2064a6dc60ffSKozlov Sergey break; 2065a6dc60ffSKozlov Sergey default: 2066a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): unknown delivery system %d\n", 2067a6dc60ffSKozlov Sergey __func__, p->delivery_system); 2068f1b26622SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 2069f1b26622SMauro Carvalho Chehab return; 2070a6dc60ffSKozlov Sergey } 2071a6dc60ffSKozlov Sergey 20720854df79SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): snr=%d\n", 20730854df79SAbylay Ospan __func__, (int32_t)tmp); 20740854df79SAbylay Ospan 2075e05b1872SAbylay Ospan if (!ret) { 2076f1b26622SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_DECIBEL; 2077f1b26622SMauro Carvalho Chehab p->cnr.stat[0].svalue = tmp; 2078e05b1872SAbylay Ospan } else { 2079e05b1872SAbylay Ospan p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 2080e05b1872SAbylay Ospan } 2081f1b26622SMauro Carvalho Chehab } 2082f1b26622SMauro Carvalho Chehab 2083f1b26622SMauro Carvalho Chehab static void cxd2841er_read_ucblocks(struct dvb_frontend *fe) 2084a6dc60ffSKozlov Sergey { 2085a6dc60ffSKozlov Sergey struct dtv_frontend_properties *p = &fe->dtv_property_cache; 2086a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 20874a86bc10SAbylay Ospan u32 ucblocks = 0; 2088a6dc60ffSKozlov Sergey 2089a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 2090a6dc60ffSKozlov Sergey switch (p->delivery_system) { 2091a6f330cbSAbylay Ospan case SYS_DVBC_ANNEX_A: 2092a6f330cbSAbylay Ospan case SYS_DVBC_ANNEX_B: 2093a6f330cbSAbylay Ospan case SYS_DVBC_ANNEX_C: 2094a6f330cbSAbylay Ospan cxd2841er_read_packet_errors_c(priv, &ucblocks); 2095a6f330cbSAbylay Ospan break; 2096a6dc60ffSKozlov Sergey case SYS_DVBT: 2097f1b26622SMauro Carvalho Chehab cxd2841er_read_packet_errors_t(priv, &ucblocks); 2098a6dc60ffSKozlov Sergey break; 2099a6dc60ffSKozlov Sergey case SYS_DVBT2: 2100f1b26622SMauro Carvalho Chehab cxd2841er_read_packet_errors_t2(priv, &ucblocks); 2101a6dc60ffSKozlov Sergey break; 210283808c23SAbylay Ospan case SYS_ISDBT: 2103f1b26622SMauro Carvalho Chehab cxd2841er_read_packet_errors_i(priv, &ucblocks); 210483808c23SAbylay Ospan break; 2105a6dc60ffSKozlov Sergey default: 2106f1b26622SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 2107f1b26622SMauro Carvalho Chehab return; 2108a6dc60ffSKozlov Sergey } 21094a86bc10SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s() ucblocks=%u\n", __func__, ucblocks); 2110f1b26622SMauro Carvalho Chehab 2111f1b26622SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_COUNTER; 2112f1b26622SMauro Carvalho Chehab p->block_error.stat[0].uvalue = ucblocks; 2113a6dc60ffSKozlov Sergey } 2114a6dc60ffSKozlov Sergey 2115a6dc60ffSKozlov Sergey static int cxd2841er_dvbt2_set_profile( 2116a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv, enum cxd2841er_dvbt2_profile_t profile) 2117a6dc60ffSKozlov Sergey { 2118a6dc60ffSKozlov Sergey u8 tune_mode; 2119a6dc60ffSKozlov Sergey u8 seq_not2d_time; 2120a6dc60ffSKozlov Sergey 2121a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 2122a6dc60ffSKozlov Sergey switch (profile) { 2123a6dc60ffSKozlov Sergey case DVBT2_PROFILE_BASE: 2124a6dc60ffSKozlov Sergey tune_mode = 0x01; 21256c77161aSAbylay Ospan /* Set early unlock time */ 21266c77161aSAbylay Ospan seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x0E:0x0C; 2127a6dc60ffSKozlov Sergey break; 2128a6dc60ffSKozlov Sergey case DVBT2_PROFILE_LITE: 2129a6dc60ffSKozlov Sergey tune_mode = 0x05; 21306c77161aSAbylay Ospan /* Set early unlock time */ 21316c77161aSAbylay Ospan seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28; 2132a6dc60ffSKozlov Sergey break; 2133a6dc60ffSKozlov Sergey case DVBT2_PROFILE_ANY: 2134a6dc60ffSKozlov Sergey tune_mode = 0x00; 21356c77161aSAbylay Ospan /* Set early unlock time */ 21366c77161aSAbylay Ospan seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28; 2137a6dc60ffSKozlov Sergey break; 2138a6dc60ffSKozlov Sergey default: 2139a6dc60ffSKozlov Sergey return -EINVAL; 2140a6dc60ffSKozlov Sergey } 2141a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x2E */ 2142a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2e); 2143a6dc60ffSKozlov Sergey /* Set profile and tune mode */ 2144a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x10, tune_mode, 0x07); 2145a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x2B */ 2146a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); 2147a6dc60ffSKozlov Sergey /* Set early unlock detection time */ 2148a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x9d, seq_not2d_time); 2149a6dc60ffSKozlov Sergey return 0; 2150a6dc60ffSKozlov Sergey } 2151a6dc60ffSKozlov Sergey 2152a6dc60ffSKozlov Sergey static int cxd2841er_dvbt2_set_plp_config(struct cxd2841er_priv *priv, 2153a6dc60ffSKozlov Sergey u8 is_auto, u8 plp_id) 2154a6dc60ffSKozlov Sergey { 2155a6dc60ffSKozlov Sergey if (is_auto) { 2156a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 2157a6dc60ffSKozlov Sergey "%s() using auto PLP selection\n", __func__); 2158a6dc60ffSKozlov Sergey } else { 2159a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 2160a6dc60ffSKozlov Sergey "%s() using manual PLP selection, ID %d\n", 2161a6dc60ffSKozlov Sergey __func__, plp_id); 2162a6dc60ffSKozlov Sergey } 2163a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x23 */ 2164a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x23); 2165a6dc60ffSKozlov Sergey if (!is_auto) { 2166a6dc60ffSKozlov Sergey /* Manual PLP selection mode. Set the data PLP Id. */ 2167a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xaf, plp_id); 2168a6dc60ffSKozlov Sergey } 2169a6dc60ffSKozlov Sergey /* Auto PLP select (Scanning mode = 0x00). Data PLP select = 0x01. */ 2170a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xad, (is_auto ? 0x00 : 0x01)); 2171a6dc60ffSKozlov Sergey return 0; 2172a6dc60ffSKozlov Sergey } 2173a6dc60ffSKozlov Sergey 2174a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv, 2175a6dc60ffSKozlov Sergey u32 bandwidth) 2176a6dc60ffSKozlov Sergey { 21774b866c4eSDaniel Scheller u32 iffreq, ifhz; 21786c77161aSAbylay Ospan u8 data[MAX_WRITE_REGSIZE]; 2179a6dc60ffSKozlov Sergey 21806c77161aSAbylay Ospan const uint8_t nominalRate8bw[3][5] = { 21816c77161aSAbylay Ospan /* TRCG Nominal Rate [37:0] */ 21826c77161aSAbylay Ospan {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ 21836c77161aSAbylay Ospan {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ 21846c77161aSAbylay Ospan {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */ 21856c77161aSAbylay Ospan }; 21866c77161aSAbylay Ospan 21876c77161aSAbylay Ospan const uint8_t nominalRate7bw[3][5] = { 21886c77161aSAbylay Ospan /* TRCG Nominal Rate [37:0] */ 21896c77161aSAbylay Ospan {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ 21906c77161aSAbylay Ospan {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ 21916c77161aSAbylay Ospan {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */ 21926c77161aSAbylay Ospan }; 21936c77161aSAbylay Ospan 21946c77161aSAbylay Ospan const uint8_t nominalRate6bw[3][5] = { 21956c77161aSAbylay Ospan /* TRCG Nominal Rate [37:0] */ 21966c77161aSAbylay Ospan {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */ 21976c77161aSAbylay Ospan {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ 21986c77161aSAbylay Ospan {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */ 21996c77161aSAbylay Ospan }; 22006c77161aSAbylay Ospan 22016c77161aSAbylay Ospan const uint8_t nominalRate5bw[3][5] = { 22026c77161aSAbylay Ospan /* TRCG Nominal Rate [37:0] */ 22036c77161aSAbylay Ospan {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */ 22046c77161aSAbylay Ospan {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */ 22056c77161aSAbylay Ospan {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */ 22066c77161aSAbylay Ospan }; 22076c77161aSAbylay Ospan 22086c77161aSAbylay Ospan const uint8_t nominalRate17bw[3][5] = { 22096c77161aSAbylay Ospan /* TRCG Nominal Rate [37:0] */ 22106c77161aSAbylay Ospan {0x58, 0xE2, 0xAF, 0xE0, 0xBC}, /* 20.5MHz XTal */ 22116c77161aSAbylay Ospan {0x68, 0x0F, 0xA2, 0x32, 0xD0}, /* 24MHz XTal */ 22126c77161aSAbylay Ospan {0x58, 0xE2, 0xAF, 0xE0, 0xBC} /* 41MHz XTal */ 22136c77161aSAbylay Ospan }; 22146c77161aSAbylay Ospan 22156c77161aSAbylay Ospan const uint8_t itbCoef8bw[3][14] = { 22166c77161aSAbylay Ospan {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 22176c77161aSAbylay Ospan 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */ 22186c77161aSAbylay Ospan {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 22196c77161aSAbylay Ospan 0x29, 0xA5, 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz XTal */ 22206c77161aSAbylay Ospan {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 22216c77161aSAbylay Ospan 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */ 22226c77161aSAbylay Ospan }; 22236c77161aSAbylay Ospan 22246c77161aSAbylay Ospan const uint8_t itbCoef7bw[3][14] = { 22256c77161aSAbylay Ospan {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 22266c77161aSAbylay Ospan 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */ 22276c77161aSAbylay Ospan {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 22286c77161aSAbylay Ospan 0x29, 0xA2, 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz XTal */ 22296c77161aSAbylay Ospan {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 22306c77161aSAbylay Ospan 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */ 22316c77161aSAbylay Ospan }; 22326c77161aSAbylay Ospan 22336c77161aSAbylay Ospan const uint8_t itbCoef6bw[3][14] = { 22346c77161aSAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 22356c77161aSAbylay Ospan 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ 22366c77161aSAbylay Ospan {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 22376c77161aSAbylay Ospan 0x29, 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */ 22386c77161aSAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 22396c77161aSAbylay Ospan 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ 22406c77161aSAbylay Ospan }; 22416c77161aSAbylay Ospan 22426c77161aSAbylay Ospan const uint8_t itbCoef5bw[3][14] = { 22436c77161aSAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 22446c77161aSAbylay Ospan 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ 22456c77161aSAbylay Ospan {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 22466c77161aSAbylay Ospan 0x29, 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */ 22476c77161aSAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 22486c77161aSAbylay Ospan 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ 22496c77161aSAbylay Ospan }; 22506c77161aSAbylay Ospan 22516c77161aSAbylay Ospan const uint8_t itbCoef17bw[3][14] = { 22526c77161aSAbylay Ospan {0x25, 0xA0, 0x36, 0x8D, 0x2E, 0x94, 0x28, 0x9B, 22536c77161aSAbylay Ospan 0x32, 0x90, 0x2C, 0x9D, 0x29, 0x99}, /* 20.5MHz XTal */ 22546c77161aSAbylay Ospan {0x33, 0x8E, 0x2B, 0x97, 0x2D, 0x95, 0x37, 0x8B, 22556c77161aSAbylay Ospan 0x30, 0x97, 0x2D, 0x9A, 0x21, 0xA4}, /* 24MHz XTal */ 22566c77161aSAbylay Ospan {0x25, 0xA0, 0x36, 0x8D, 0x2E, 0x94, 0x28, 0x9B, 22576c77161aSAbylay Ospan 0x32, 0x90, 0x2C, 0x9D, 0x29, 0x99} /* 41MHz XTal */ 22586c77161aSAbylay Ospan }; 22596c77161aSAbylay Ospan 22606c77161aSAbylay Ospan /* Set SLV-T Bank : 0x20 */ 22616c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); 22626c77161aSAbylay Ospan 2263a6dc60ffSKozlov Sergey switch (bandwidth) { 2264a6dc60ffSKozlov Sergey case 8000000: 22656c77161aSAbylay Ospan /* <Timing Recovery setting> */ 22666c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 22676c77161aSAbylay Ospan 0x9F, nominalRate8bw[priv->xtal], 5); 22686c77161aSAbylay Ospan 22696c77161aSAbylay Ospan /* Set SLV-T Bank : 0x27 */ 22706c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); 22716c77161aSAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 22726c77161aSAbylay Ospan 0x7a, 0x00, 0x0f); 22736c77161aSAbylay Ospan 22746c77161aSAbylay Ospan /* Set SLV-T Bank : 0x10 */ 22756c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 22766c77161aSAbylay Ospan 22776c77161aSAbylay Ospan /* Group delay equaliser settings for 22786c77161aSAbylay Ospan * ASCOT2D, ASCOT2E and ASCOT3 tuners 22796c77161aSAbylay Ospan */ 22807afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 22816c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 22826c77161aSAbylay Ospan 0xA6, itbCoef8bw[priv->xtal], 14); 22836c77161aSAbylay Ospan /* <IF freq setting> */ 22844b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 4800000); 22854b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 22866c77161aSAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 22876c77161aSAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 22886c77161aSAbylay Ospan data[2] = (u8)(iffreq & 0xff); 22896c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 22906c77161aSAbylay Ospan /* System bandwidth setting */ 22916c77161aSAbylay Ospan cxd2841er_set_reg_bits( 22926c77161aSAbylay Ospan priv, I2C_SLVT, 0xD7, 0x00, 0x07); 2293a6dc60ffSKozlov Sergey break; 2294a6dc60ffSKozlov Sergey case 7000000: 22956c77161aSAbylay Ospan /* <Timing Recovery setting> */ 22966c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 22976c77161aSAbylay Ospan 0x9F, nominalRate7bw[priv->xtal], 5); 22986c77161aSAbylay Ospan 22996c77161aSAbylay Ospan /* Set SLV-T Bank : 0x27 */ 23006c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); 23016c77161aSAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 23026c77161aSAbylay Ospan 0x7a, 0x00, 0x0f); 23036c77161aSAbylay Ospan 23046c77161aSAbylay Ospan /* Set SLV-T Bank : 0x10 */ 23056c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 23066c77161aSAbylay Ospan 23076c77161aSAbylay Ospan /* Group delay equaliser settings for 23086c77161aSAbylay Ospan * ASCOT2D, ASCOT2E and ASCOT3 tuners 23096c77161aSAbylay Ospan */ 23107afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 23116c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 23126c77161aSAbylay Ospan 0xA6, itbCoef7bw[priv->xtal], 14); 23136c77161aSAbylay Ospan /* <IF freq setting> */ 23144b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 4200000); 23154b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 23166c77161aSAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 23176c77161aSAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 23186c77161aSAbylay Ospan data[2] = (u8)(iffreq & 0xff); 23196c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 23206c77161aSAbylay Ospan /* System bandwidth setting */ 23216c77161aSAbylay Ospan cxd2841er_set_reg_bits( 23226c77161aSAbylay Ospan priv, I2C_SLVT, 0xD7, 0x02, 0x07); 2323a6dc60ffSKozlov Sergey break; 2324a6dc60ffSKozlov Sergey case 6000000: 23256c77161aSAbylay Ospan /* <Timing Recovery setting> */ 23266c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 23276c77161aSAbylay Ospan 0x9F, nominalRate6bw[priv->xtal], 5); 23286c77161aSAbylay Ospan 23296c77161aSAbylay Ospan /* Set SLV-T Bank : 0x27 */ 23306c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); 23316c77161aSAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 23326c77161aSAbylay Ospan 0x7a, 0x00, 0x0f); 23336c77161aSAbylay Ospan 23346c77161aSAbylay Ospan /* Set SLV-T Bank : 0x10 */ 23356c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 23366c77161aSAbylay Ospan 23376c77161aSAbylay Ospan /* Group delay equaliser settings for 23386c77161aSAbylay Ospan * ASCOT2D, ASCOT2E and ASCOT3 tuners 23396c77161aSAbylay Ospan */ 23407afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 23416c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 23426c77161aSAbylay Ospan 0xA6, itbCoef6bw[priv->xtal], 14); 23436c77161aSAbylay Ospan /* <IF freq setting> */ 23444b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 3600000); 23454b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 23466c77161aSAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 23476c77161aSAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 23486c77161aSAbylay Ospan data[2] = (u8)(iffreq & 0xff); 23496c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 23506c77161aSAbylay Ospan /* System bandwidth setting */ 23516c77161aSAbylay Ospan cxd2841er_set_reg_bits( 23526c77161aSAbylay Ospan priv, I2C_SLVT, 0xD7, 0x04, 0x07); 2353a6dc60ffSKozlov Sergey break; 2354a6dc60ffSKozlov Sergey case 5000000: 23556c77161aSAbylay Ospan /* <Timing Recovery setting> */ 23566c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 23576c77161aSAbylay Ospan 0x9F, nominalRate5bw[priv->xtal], 5); 23586c77161aSAbylay Ospan 23596c77161aSAbylay Ospan /* Set SLV-T Bank : 0x27 */ 23606c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); 23616c77161aSAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 23626c77161aSAbylay Ospan 0x7a, 0x00, 0x0f); 23636c77161aSAbylay Ospan 23646c77161aSAbylay Ospan /* Set SLV-T Bank : 0x10 */ 23656c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 23666c77161aSAbylay Ospan 23676c77161aSAbylay Ospan /* Group delay equaliser settings for 23686c77161aSAbylay Ospan * ASCOT2D, ASCOT2E and ASCOT3 tuners 23696c77161aSAbylay Ospan */ 23707afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 23716c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 23726c77161aSAbylay Ospan 0xA6, itbCoef5bw[priv->xtal], 14); 23736c77161aSAbylay Ospan /* <IF freq setting> */ 23744b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 3600000); 23754b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 23766c77161aSAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 23776c77161aSAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 23786c77161aSAbylay Ospan data[2] = (u8)(iffreq & 0xff); 23796c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 23806c77161aSAbylay Ospan /* System bandwidth setting */ 23816c77161aSAbylay Ospan cxd2841er_set_reg_bits( 23826c77161aSAbylay Ospan priv, I2C_SLVT, 0xD7, 0x06, 0x07); 2383a6dc60ffSKozlov Sergey break; 2384a6dc60ffSKozlov Sergey case 1712000: 23856c77161aSAbylay Ospan /* <Timing Recovery setting> */ 23866c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 23876c77161aSAbylay Ospan 0x9F, nominalRate17bw[priv->xtal], 5); 23886c77161aSAbylay Ospan 23896c77161aSAbylay Ospan /* Set SLV-T Bank : 0x27 */ 23906c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); 23916c77161aSAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 23926c77161aSAbylay Ospan 0x7a, 0x03, 0x0f); 23936c77161aSAbylay Ospan 23946c77161aSAbylay Ospan /* Set SLV-T Bank : 0x10 */ 23956c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 23966c77161aSAbylay Ospan 23976c77161aSAbylay Ospan /* Group delay equaliser settings for 23986c77161aSAbylay Ospan * ASCOT2D, ASCOT2E and ASCOT3 tuners 23996c77161aSAbylay Ospan */ 24007afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 24016c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 24026c77161aSAbylay Ospan 0xA6, itbCoef17bw[priv->xtal], 14); 24036c77161aSAbylay Ospan /* <IF freq setting> */ 24044b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 3500000); 24054b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 24066c77161aSAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 24076c77161aSAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 24086c77161aSAbylay Ospan data[2] = (u8)(iffreq & 0xff); 24096c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 24106c77161aSAbylay Ospan /* System bandwidth setting */ 24116c77161aSAbylay Ospan cxd2841er_set_reg_bits( 24126c77161aSAbylay Ospan priv, I2C_SLVT, 0xD7, 0x03, 0x07); 2413a6dc60ffSKozlov Sergey break; 2414a6dc60ffSKozlov Sergey default: 2415a6dc60ffSKozlov Sergey return -EINVAL; 2416a6dc60ffSKozlov Sergey } 2417a6dc60ffSKozlov Sergey return 0; 2418a6dc60ffSKozlov Sergey } 2419a6dc60ffSKozlov Sergey 2420a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_active_t_band( 2421a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv, u32 bandwidth) 2422a6dc60ffSKozlov Sergey { 242383808c23SAbylay Ospan u8 data[MAX_WRITE_REGSIZE]; 24244b866c4eSDaniel Scheller u32 iffreq, ifhz; 242583808c23SAbylay Ospan u8 nominalRate8bw[3][5] = { 242683808c23SAbylay Ospan /* TRCG Nominal Rate [37:0] */ 242783808c23SAbylay Ospan {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ 242883808c23SAbylay Ospan {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ 242983808c23SAbylay Ospan {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */ 243083808c23SAbylay Ospan }; 243183808c23SAbylay Ospan u8 nominalRate7bw[3][5] = { 243283808c23SAbylay Ospan /* TRCG Nominal Rate [37:0] */ 243383808c23SAbylay Ospan {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ 243483808c23SAbylay Ospan {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ 243583808c23SAbylay Ospan {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */ 243683808c23SAbylay Ospan }; 243783808c23SAbylay Ospan u8 nominalRate6bw[3][5] = { 243883808c23SAbylay Ospan /* TRCG Nominal Rate [37:0] */ 243983808c23SAbylay Ospan {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */ 244083808c23SAbylay Ospan {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */ 244183808c23SAbylay Ospan {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */ 244283808c23SAbylay Ospan }; 244383808c23SAbylay Ospan u8 nominalRate5bw[3][5] = { 244483808c23SAbylay Ospan /* TRCG Nominal Rate [37:0] */ 244583808c23SAbylay Ospan {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */ 244683808c23SAbylay Ospan {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */ 244783808c23SAbylay Ospan {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */ 244883808c23SAbylay Ospan }; 2449a6dc60ffSKozlov Sergey 245083808c23SAbylay Ospan u8 itbCoef8bw[3][14] = { 245183808c23SAbylay Ospan {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9, 245283808c23SAbylay Ospan 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */ 245383808c23SAbylay Ospan {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29, 0xA5, 245483808c23SAbylay Ospan 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz XTal */ 245583808c23SAbylay Ospan {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9, 245683808c23SAbylay Ospan 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */ 245783808c23SAbylay Ospan }; 245883808c23SAbylay Ospan u8 itbCoef7bw[3][14] = { 245983808c23SAbylay Ospan {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0, 246083808c23SAbylay Ospan 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */ 246183808c23SAbylay Ospan {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29, 0xA2, 246283808c23SAbylay Ospan 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz XTal */ 246383808c23SAbylay Ospan {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0, 246483808c23SAbylay Ospan 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */ 246583808c23SAbylay Ospan }; 246683808c23SAbylay Ospan u8 itbCoef6bw[3][14] = { 246783808c23SAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 246883808c23SAbylay Ospan 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ 246983808c23SAbylay Ospan {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4, 247083808c23SAbylay Ospan 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */ 247183808c23SAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 247283808c23SAbylay Ospan 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ 247383808c23SAbylay Ospan }; 247483808c23SAbylay Ospan u8 itbCoef5bw[3][14] = { 247583808c23SAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 247683808c23SAbylay Ospan 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ 247783808c23SAbylay Ospan {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4, 247883808c23SAbylay Ospan 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */ 247983808c23SAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF, 248083808c23SAbylay Ospan 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */ 248183808c23SAbylay Ospan }; 248283808c23SAbylay Ospan 248383808c23SAbylay Ospan /* Set SLV-T Bank : 0x13 */ 2484a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13); 2485a6dc60ffSKozlov Sergey /* Echo performance optimization setting */ 248683808c23SAbylay Ospan data[0] = 0x01; 248783808c23SAbylay Ospan data[1] = 0x14; 248883808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x9C, data, 2); 248983808c23SAbylay Ospan 249083808c23SAbylay Ospan /* Set SLV-T Bank : 0x10 */ 2491a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 2492a6dc60ffSKozlov Sergey 2493a6dc60ffSKozlov Sergey switch (bandwidth) { 2494a6dc60ffSKozlov Sergey case 8000000: 249583808c23SAbylay Ospan /* <Timing Recovery setting> */ 249683808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 249783808c23SAbylay Ospan 0x9F, nominalRate8bw[priv->xtal], 5); 249883808c23SAbylay Ospan /* Group delay equaliser settings for 249983808c23SAbylay Ospan * ASCOT2D, ASCOT2E and ASCOT3 tuners 250083808c23SAbylay Ospan */ 25017afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 250283808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 250383808c23SAbylay Ospan 0xA6, itbCoef8bw[priv->xtal], 14); 250483808c23SAbylay Ospan /* <IF freq setting> */ 25054b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 4800000); 25064b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 250783808c23SAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 250883808c23SAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 250983808c23SAbylay Ospan data[2] = (u8)(iffreq & 0xff); 251083808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 251183808c23SAbylay Ospan /* System bandwidth setting */ 251283808c23SAbylay Ospan cxd2841er_set_reg_bits( 251383808c23SAbylay Ospan priv, I2C_SLVT, 0xD7, 0x00, 0x07); 251483808c23SAbylay Ospan 251583808c23SAbylay Ospan /* Demod core latency setting */ 251683808c23SAbylay Ospan if (priv->xtal == SONY_XTAL_24000) { 251783808c23SAbylay Ospan data[0] = 0x15; 251883808c23SAbylay Ospan data[1] = 0x28; 251983808c23SAbylay Ospan } else { 252083808c23SAbylay Ospan data[0] = 0x01; 252183808c23SAbylay Ospan data[1] = 0xE0; 252283808c23SAbylay Ospan } 252383808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); 252483808c23SAbylay Ospan 252583808c23SAbylay Ospan /* Notch filter setting */ 252683808c23SAbylay Ospan data[0] = 0x01; 252783808c23SAbylay Ospan data[1] = 0x02; 252883808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17); 252983808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2); 2530a6dc60ffSKozlov Sergey break; 2531a6dc60ffSKozlov Sergey case 7000000: 253283808c23SAbylay Ospan /* <Timing Recovery setting> */ 253383808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 253483808c23SAbylay Ospan 0x9F, nominalRate7bw[priv->xtal], 5); 253583808c23SAbylay Ospan /* Group delay equaliser settings for 253683808c23SAbylay Ospan * ASCOT2D, ASCOT2E and ASCOT3 tuners 253783808c23SAbylay Ospan */ 25387afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 253983808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 254083808c23SAbylay Ospan 0xA6, itbCoef7bw[priv->xtal], 14); 254183808c23SAbylay Ospan /* <IF freq setting> */ 25424b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 4200000); 25434b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 254483808c23SAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 254583808c23SAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 254683808c23SAbylay Ospan data[2] = (u8)(iffreq & 0xff); 254783808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 254883808c23SAbylay Ospan /* System bandwidth setting */ 254983808c23SAbylay Ospan cxd2841er_set_reg_bits( 255083808c23SAbylay Ospan priv, I2C_SLVT, 0xD7, 0x02, 0x07); 255183808c23SAbylay Ospan 255283808c23SAbylay Ospan /* Demod core latency setting */ 255383808c23SAbylay Ospan if (priv->xtal == SONY_XTAL_24000) { 255483808c23SAbylay Ospan data[0] = 0x1F; 255583808c23SAbylay Ospan data[1] = 0xF8; 255683808c23SAbylay Ospan } else { 255783808c23SAbylay Ospan data[0] = 0x12; 255883808c23SAbylay Ospan data[1] = 0xF8; 255983808c23SAbylay Ospan } 256083808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); 256183808c23SAbylay Ospan 256283808c23SAbylay Ospan /* Notch filter setting */ 256383808c23SAbylay Ospan data[0] = 0x00; 256483808c23SAbylay Ospan data[1] = 0x03; 256583808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17); 256683808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2); 2567a6dc60ffSKozlov Sergey break; 2568a6dc60ffSKozlov Sergey case 6000000: 256983808c23SAbylay Ospan /* <Timing Recovery setting> */ 257083808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 257183808c23SAbylay Ospan 0x9F, nominalRate6bw[priv->xtal], 5); 257283808c23SAbylay Ospan /* Group delay equaliser settings for 257383808c23SAbylay Ospan * ASCOT2D, ASCOT2E and ASCOT3 tuners 257483808c23SAbylay Ospan */ 25757afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 257683808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 257783808c23SAbylay Ospan 0xA6, itbCoef6bw[priv->xtal], 14); 257883808c23SAbylay Ospan /* <IF freq setting> */ 25794b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 3600000); 25804b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 258183808c23SAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 258283808c23SAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 258383808c23SAbylay Ospan data[2] = (u8)(iffreq & 0xff); 258483808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 258583808c23SAbylay Ospan /* System bandwidth setting */ 258683808c23SAbylay Ospan cxd2841er_set_reg_bits( 258783808c23SAbylay Ospan priv, I2C_SLVT, 0xD7, 0x04, 0x07); 258883808c23SAbylay Ospan 258983808c23SAbylay Ospan /* Demod core latency setting */ 259083808c23SAbylay Ospan if (priv->xtal == SONY_XTAL_24000) { 259183808c23SAbylay Ospan data[0] = 0x25; 259283808c23SAbylay Ospan data[1] = 0x4C; 259383808c23SAbylay Ospan } else { 259483808c23SAbylay Ospan data[0] = 0x1F; 259583808c23SAbylay Ospan data[1] = 0xDC; 259683808c23SAbylay Ospan } 259783808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); 259883808c23SAbylay Ospan 259983808c23SAbylay Ospan /* Notch filter setting */ 260083808c23SAbylay Ospan data[0] = 0x00; 260183808c23SAbylay Ospan data[1] = 0x03; 260283808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17); 260383808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2); 2604a6dc60ffSKozlov Sergey break; 2605a6dc60ffSKozlov Sergey case 5000000: 260683808c23SAbylay Ospan /* <Timing Recovery setting> */ 260783808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 260883808c23SAbylay Ospan 0x9F, nominalRate5bw[priv->xtal], 5); 260983808c23SAbylay Ospan /* Group delay equaliser settings for 261083808c23SAbylay Ospan * ASCOT2D, ASCOT2E and ASCOT3 tuners 261183808c23SAbylay Ospan */ 26127afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 261383808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 261483808c23SAbylay Ospan 0xA6, itbCoef5bw[priv->xtal], 14); 261583808c23SAbylay Ospan /* <IF freq setting> */ 26164b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 3600000); 26174b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 261883808c23SAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 261983808c23SAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 262083808c23SAbylay Ospan data[2] = (u8)(iffreq & 0xff); 262183808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 262283808c23SAbylay Ospan /* System bandwidth setting */ 262383808c23SAbylay Ospan cxd2841er_set_reg_bits( 262483808c23SAbylay Ospan priv, I2C_SLVT, 0xD7, 0x06, 0x07); 262583808c23SAbylay Ospan 262683808c23SAbylay Ospan /* Demod core latency setting */ 262783808c23SAbylay Ospan if (priv->xtal == SONY_XTAL_24000) { 262883808c23SAbylay Ospan data[0] = 0x2C; 262983808c23SAbylay Ospan data[1] = 0xC2; 263083808c23SAbylay Ospan } else { 263183808c23SAbylay Ospan data[0] = 0x26; 263283808c23SAbylay Ospan data[1] = 0x3C; 263383808c23SAbylay Ospan } 263483808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); 263583808c23SAbylay Ospan 263683808c23SAbylay Ospan /* Notch filter setting */ 263783808c23SAbylay Ospan data[0] = 0x00; 263883808c23SAbylay Ospan data[1] = 0x03; 263983808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17); 264083808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2); 264183808c23SAbylay Ospan break; 264283808c23SAbylay Ospan } 264383808c23SAbylay Ospan 264483808c23SAbylay Ospan return 0; 264583808c23SAbylay Ospan } 264683808c23SAbylay Ospan 264783808c23SAbylay Ospan static int cxd2841er_sleep_tc_to_active_i_band( 264883808c23SAbylay Ospan struct cxd2841er_priv *priv, u32 bandwidth) 264983808c23SAbylay Ospan { 26504b866c4eSDaniel Scheller u32 iffreq, ifhz; 265183808c23SAbylay Ospan u8 data[3]; 265283808c23SAbylay Ospan 265383808c23SAbylay Ospan /* TRCG Nominal Rate */ 265483808c23SAbylay Ospan u8 nominalRate8bw[3][5] = { 265583808c23SAbylay Ospan {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ 265683808c23SAbylay Ospan {0x11, 0xB8, 0x00, 0x00, 0x00}, /* 24MHz XTal */ 265783808c23SAbylay Ospan {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */ 265883808c23SAbylay Ospan }; 265983808c23SAbylay Ospan 266083808c23SAbylay Ospan u8 nominalRate7bw[3][5] = { 266183808c23SAbylay Ospan {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ 266283808c23SAbylay Ospan {0x14, 0x40, 0x00, 0x00, 0x00}, /* 24MHz XTal */ 266383808c23SAbylay Ospan {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */ 266483808c23SAbylay Ospan }; 266583808c23SAbylay Ospan 266683808c23SAbylay Ospan u8 nominalRate6bw[3][5] = { 266783808c23SAbylay Ospan {0x14, 0x2E, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */ 266883808c23SAbylay Ospan {0x17, 0xA0, 0x00, 0x00, 0x00}, /* 24MHz XTal */ 266983808c23SAbylay Ospan {0x14, 0x2E, 0x00, 0x00, 0x00} /* 41MHz XTal */ 267083808c23SAbylay Ospan }; 267183808c23SAbylay Ospan 267283808c23SAbylay Ospan u8 itbCoef8bw[3][14] = { 267383808c23SAbylay Ospan {0x00}, /* 20.5MHz XTal */ 267483808c23SAbylay Ospan {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29, 267583808c23SAbylay Ospan 0xA5, 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz Xtal */ 267683808c23SAbylay Ospan {0x0}, /* 41MHz XTal */ 267783808c23SAbylay Ospan }; 267883808c23SAbylay Ospan 267983808c23SAbylay Ospan u8 itbCoef7bw[3][14] = { 268083808c23SAbylay Ospan {0x00}, /* 20.5MHz XTal */ 268183808c23SAbylay Ospan {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29, 268283808c23SAbylay Ospan 0xA2, 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz Xtal */ 268383808c23SAbylay Ospan {0x00}, /* 41MHz XTal */ 268483808c23SAbylay Ospan }; 268583808c23SAbylay Ospan 268683808c23SAbylay Ospan u8 itbCoef6bw[3][14] = { 268783808c23SAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 268883808c23SAbylay Ospan 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */ 268983808c23SAbylay Ospan {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 269083808c23SAbylay Ospan 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz Xtal */ 269183808c23SAbylay Ospan {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 269283808c23SAbylay Ospan 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 41MHz XTal */ 269383808c23SAbylay Ospan }; 269483808c23SAbylay Ospan 269583808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s() bandwidth=%u\n", __func__, bandwidth); 269683808c23SAbylay Ospan /* Set SLV-T Bank : 0x10 */ 269783808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 269883808c23SAbylay Ospan 269983808c23SAbylay Ospan /* 20.5/41MHz Xtal support is not available 270083808c23SAbylay Ospan * on ISDB-T 7MHzBW and 8MHzBW 270183808c23SAbylay Ospan */ 270283808c23SAbylay Ospan if (priv->xtal != SONY_XTAL_24000 && bandwidth > 6000000) { 270383808c23SAbylay Ospan dev_err(&priv->i2c->dev, 270483808c23SAbylay Ospan "%s(): bandwidth %d supported only for 24MHz xtal\n", 270583808c23SAbylay Ospan __func__, bandwidth); 270683808c23SAbylay Ospan return -EINVAL; 270783808c23SAbylay Ospan } 270883808c23SAbylay Ospan 270983808c23SAbylay Ospan switch (bandwidth) { 271083808c23SAbylay Ospan case 8000000: 271183808c23SAbylay Ospan /* TRCG Nominal Rate */ 271283808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 271383808c23SAbylay Ospan 0x9F, nominalRate8bw[priv->xtal], 5); 271483808c23SAbylay Ospan /* Group delay equaliser settings for ASCOT tuners optimized */ 27157afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 271683808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 271783808c23SAbylay Ospan 0xA6, itbCoef8bw[priv->xtal], 14); 271883808c23SAbylay Ospan 271983808c23SAbylay Ospan /* IF freq setting */ 27204b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 4750000); 27214b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 272283808c23SAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 272383808c23SAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 272483808c23SAbylay Ospan data[2] = (u8)(iffreq & 0xff); 272583808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 272683808c23SAbylay Ospan 272783808c23SAbylay Ospan /* System bandwidth setting */ 272883808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x0, 0x7); 272983808c23SAbylay Ospan 273083808c23SAbylay Ospan /* Demod core latency setting */ 273183808c23SAbylay Ospan data[0] = 0x13; 273283808c23SAbylay Ospan data[1] = 0xFC; 273383808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); 273483808c23SAbylay Ospan 273583808c23SAbylay Ospan /* Acquisition optimization setting */ 273683808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12); 273783808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x03, 0x07); 273883808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15); 273983808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x03); 274083808c23SAbylay Ospan break; 274183808c23SAbylay Ospan case 7000000: 274283808c23SAbylay Ospan /* TRCG Nominal Rate */ 274383808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 274483808c23SAbylay Ospan 0x9F, nominalRate7bw[priv->xtal], 5); 274583808c23SAbylay Ospan /* Group delay equaliser settings for ASCOT tuners optimized */ 27467afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 274783808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 274883808c23SAbylay Ospan 0xA6, itbCoef7bw[priv->xtal], 14); 274983808c23SAbylay Ospan 275083808c23SAbylay Ospan /* IF freq setting */ 27514b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 4150000); 27524b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 275383808c23SAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 275483808c23SAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 275583808c23SAbylay Ospan data[2] = (u8)(iffreq & 0xff); 275683808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 275783808c23SAbylay Ospan 275883808c23SAbylay Ospan /* System bandwidth setting */ 275983808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x02, 0x7); 276083808c23SAbylay Ospan 276183808c23SAbylay Ospan /* Demod core latency setting */ 276283808c23SAbylay Ospan data[0] = 0x1A; 276383808c23SAbylay Ospan data[1] = 0xFA; 276483808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); 276583808c23SAbylay Ospan 276683808c23SAbylay Ospan /* Acquisition optimization setting */ 276783808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12); 276883808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x03, 0x07); 276983808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15); 277083808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x02); 277183808c23SAbylay Ospan break; 277283808c23SAbylay Ospan case 6000000: 277383808c23SAbylay Ospan /* TRCG Nominal Rate */ 277483808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 277583808c23SAbylay Ospan 0x9F, nominalRate6bw[priv->xtal], 5); 277683808c23SAbylay Ospan /* Group delay equaliser settings for ASCOT tuners optimized */ 27777afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 277883808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 277983808c23SAbylay Ospan 0xA6, itbCoef6bw[priv->xtal], 14); 278083808c23SAbylay Ospan 278183808c23SAbylay Ospan /* IF freq setting */ 27824b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 3550000); 27834b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz); 278483808c23SAbylay Ospan data[0] = (u8) ((iffreq >> 16) & 0xff); 278583808c23SAbylay Ospan data[1] = (u8)((iffreq >> 8) & 0xff); 278683808c23SAbylay Ospan data[2] = (u8)(iffreq & 0xff); 278783808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3); 278883808c23SAbylay Ospan 278983808c23SAbylay Ospan /* System bandwidth setting */ 279083808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x04, 0x7); 279183808c23SAbylay Ospan 279283808c23SAbylay Ospan /* Demod core latency setting */ 279383808c23SAbylay Ospan if (priv->xtal == SONY_XTAL_24000) { 279483808c23SAbylay Ospan data[0] = 0x1F; 279583808c23SAbylay Ospan data[1] = 0x79; 279683808c23SAbylay Ospan } else { 279783808c23SAbylay Ospan data[0] = 0x1A; 279883808c23SAbylay Ospan data[1] = 0xE2; 279983808c23SAbylay Ospan } 280083808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); 280183808c23SAbylay Ospan 280283808c23SAbylay Ospan /* Acquisition optimization setting */ 280383808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12); 280483808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x07, 0x07); 280583808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15); 280683808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x02); 2807a6dc60ffSKozlov Sergey break; 2808a6dc60ffSKozlov Sergey default: 2809a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n", 2810a6dc60ffSKozlov Sergey __func__, bandwidth); 2811a6dc60ffSKozlov Sergey return -EINVAL; 2812a6dc60ffSKozlov Sergey } 2813a6dc60ffSKozlov Sergey return 0; 2814a6dc60ffSKozlov Sergey } 2815a6dc60ffSKozlov Sergey 2816a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv, 2817a6dc60ffSKozlov Sergey u32 bandwidth) 2818a6dc60ffSKozlov Sergey { 2819a6dc60ffSKozlov Sergey u8 bw7_8mhz_b10_a6[] = { 2820a6dc60ffSKozlov Sergey 0x2D, 0xC7, 0x04, 0xF4, 0x07, 0xC5, 0x2A, 0xB8, 2821a6dc60ffSKozlov Sergey 0x27, 0x9E, 0x27, 0xA4, 0x29, 0xAB }; 2822a6dc60ffSKozlov Sergey u8 bw6mhz_b10_a6[] = { 2823a6dc60ffSKozlov Sergey 0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 2824a6dc60ffSKozlov Sergey 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4 }; 2825a6dc60ffSKozlov Sergey u8 b10_b6[3]; 28264b866c4eSDaniel Scheller u32 iffreq, ifhz; 2827a6dc60ffSKozlov Sergey 2828af4cc462SAbylay Ospan if (bandwidth != 6000000 && 2829af4cc462SAbylay Ospan bandwidth != 7000000 && 2830af4cc462SAbylay Ospan bandwidth != 8000000) { 2831af4cc462SAbylay Ospan dev_info(&priv->i2c->dev, "%s(): unsupported bandwidth %d. Forcing 8Mhz!\n", 2832af4cc462SAbylay Ospan __func__, bandwidth); 2833af4cc462SAbylay Ospan bandwidth = 8000000; 2834af4cc462SAbylay Ospan } 2835af4cc462SAbylay Ospan 28363f3b48a0SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s() bw=%d\n", __func__, bandwidth); 2837a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 2838a6dc60ffSKozlov Sergey switch (bandwidth) { 2839a6dc60ffSKozlov Sergey case 8000000: 2840a6dc60ffSKozlov Sergey case 7000000: 28417afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 2842a6dc60ffSKozlov Sergey cxd2841er_write_regs( 2843a6dc60ffSKozlov Sergey priv, I2C_SLVT, 0xa6, 2844a6dc60ffSKozlov Sergey bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6)); 28454b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 4900000); 28464b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq(ifhz); 2847a6dc60ffSKozlov Sergey break; 2848a6dc60ffSKozlov Sergey case 6000000: 28497afe510aSDaniel Scheller if (priv->flags & CXD2841ER_ASCOT) 2850a6dc60ffSKozlov Sergey cxd2841er_write_regs( 2851a6dc60ffSKozlov Sergey priv, I2C_SLVT, 0xa6, 2852a6dc60ffSKozlov Sergey bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6)); 28534b866c4eSDaniel Scheller ifhz = cxd2841er_get_if_hz(priv, 3700000); 28544b866c4eSDaniel Scheller iffreq = cxd2841er_calc_iffreq(ifhz); 2855a6dc60ffSKozlov Sergey break; 2856a6dc60ffSKozlov Sergey default: 28573f3b48a0SAbylay Ospan dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n", 2858a6dc60ffSKozlov Sergey __func__, bandwidth); 2859a6dc60ffSKozlov Sergey return -EINVAL; 2860a6dc60ffSKozlov Sergey } 2861a6dc60ffSKozlov Sergey /* <IF freq setting> */ 2862a6dc60ffSKozlov Sergey b10_b6[0] = (u8) ((iffreq >> 16) & 0xff); 2863a6dc60ffSKozlov Sergey b10_b6[1] = (u8)((iffreq >> 8) & 0xff); 2864a6dc60ffSKozlov Sergey b10_b6[2] = (u8)(iffreq & 0xff); 2865a6dc60ffSKozlov Sergey cxd2841er_write_regs(priv, I2C_SLVT, 0xb6, b10_b6, sizeof(b10_b6)); 2866a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x11 */ 2867a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); 2868a6dc60ffSKozlov Sergey switch (bandwidth) { 2869a6dc60ffSKozlov Sergey case 8000000: 2870a6dc60ffSKozlov Sergey case 7000000: 2871a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits( 2872a6dc60ffSKozlov Sergey priv, I2C_SLVT, 0xa3, 0x00, 0x1f); 2873a6dc60ffSKozlov Sergey break; 2874a6dc60ffSKozlov Sergey case 6000000: 2875a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits( 2876a6dc60ffSKozlov Sergey priv, I2C_SLVT, 0xa3, 0x14, 0x1f); 2877a6dc60ffSKozlov Sergey break; 2878a6dc60ffSKozlov Sergey } 2879a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x40 */ 2880a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); 2881a6dc60ffSKozlov Sergey switch (bandwidth) { 2882a6dc60ffSKozlov Sergey case 8000000: 2883a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits( 2884a6dc60ffSKozlov Sergey priv, I2C_SLVT, 0x26, 0x0b, 0x0f); 2885a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x27, 0x3e); 2886a6dc60ffSKozlov Sergey break; 2887a6dc60ffSKozlov Sergey case 7000000: 2888a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits( 2889a6dc60ffSKozlov Sergey priv, I2C_SLVT, 0x26, 0x09, 0x0f); 2890a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x27, 0xd6); 2891a6dc60ffSKozlov Sergey break; 2892a6dc60ffSKozlov Sergey case 6000000: 2893a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits( 2894a6dc60ffSKozlov Sergey priv, I2C_SLVT, 0x26, 0x08, 0x0f); 2895a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x27, 0x6e); 2896a6dc60ffSKozlov Sergey break; 2897a6dc60ffSKozlov Sergey } 2898a6dc60ffSKozlov Sergey return 0; 2899a6dc60ffSKozlov Sergey } 2900a6dc60ffSKozlov Sergey 2901a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv, 2902a6dc60ffSKozlov Sergey u32 bandwidth) 2903a6dc60ffSKozlov Sergey { 2904a6dc60ffSKozlov Sergey u8 data[2] = { 0x09, 0x54 }; 290583808c23SAbylay Ospan u8 data24m[3] = {0xDC, 0x6C, 0x00}; 2906a6dc60ffSKozlov Sergey 2907a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 2908a6dc60ffSKozlov Sergey cxd2841er_set_ts_clock_mode(priv, SYS_DVBT); 2909a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 2910a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 2911a6dc60ffSKozlov Sergey /* Set demod mode */ 2912a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01); 2913a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 2914a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 2915a6dc60ffSKozlov Sergey /* Enable demod clock */ 2916a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); 2917a6dc60ffSKozlov Sergey /* Disable RF level monitor */ 2918a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); 2919a6dc60ffSKozlov Sergey /* Enable ADC clock */ 2920a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 2921a6dc60ffSKozlov Sergey /* Enable ADC 1 */ 2922a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); 292383808c23SAbylay Ospan /* Enable ADC 2 & 3 */ 292483808c23SAbylay Ospan if (priv->xtal == SONY_XTAL_41000) { 292583808c23SAbylay Ospan data[0] = 0x0A; 292683808c23SAbylay Ospan data[1] = 0xD4; 292783808c23SAbylay Ospan } 2928a6dc60ffSKozlov Sergey cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); 2929a6dc60ffSKozlov Sergey /* Enable ADC 4 */ 2930a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); 2931a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x10 */ 2932a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 2933a6dc60ffSKozlov Sergey /* IFAGC gain settings */ 2934a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x0c, 0x1f); 2935a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x11 */ 2936a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); 2937a6dc60ffSKozlov Sergey /* BBAGC TARGET level setting */ 2938a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50); 2939a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x10 */ 2940a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 29417afe510aSDaniel Scheller /* ASCOT setting */ 29427afe510aSDaniel Scheller cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 29437afe510aSDaniel Scheller ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01); 2944a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x18 */ 2945a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18); 2946a6dc60ffSKozlov Sergey /* Pre-RS BER moniter setting */ 2947a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x36, 0x40, 0x07); 2948a6dc60ffSKozlov Sergey /* FEC Auto Recovery setting */ 2949a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01); 2950a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x01, 0x01); 2951a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 2952a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 2953a6dc60ffSKozlov Sergey /* TSIF setting */ 2954a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); 2955a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); 295683808c23SAbylay Ospan 295783808c23SAbylay Ospan if (priv->xtal == SONY_XTAL_24000) { 295883808c23SAbylay Ospan /* Set SLV-T Bank : 0x10 */ 295983808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 296083808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0xBF, 0x60); 296183808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18); 296283808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x24, data24m, 3); 296383808c23SAbylay Ospan } 296483808c23SAbylay Ospan 2965a6dc60ffSKozlov Sergey cxd2841er_sleep_tc_to_active_t_band(priv, bandwidth); 2966a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 2967a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 2968a6dc60ffSKozlov Sergey /* Disable HiZ Setting 1 */ 2969a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28); 2970a6dc60ffSKozlov Sergey /* Disable HiZ Setting 2 */ 2971a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00); 2972a6dc60ffSKozlov Sergey priv->state = STATE_ACTIVE_TC; 2973a6dc60ffSKozlov Sergey return 0; 2974a6dc60ffSKozlov Sergey } 2975a6dc60ffSKozlov Sergey 2976a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv, 2977a6dc60ffSKozlov Sergey u32 bandwidth) 2978a6dc60ffSKozlov Sergey { 29796c77161aSAbylay Ospan u8 data[MAX_WRITE_REGSIZE]; 2980a6dc60ffSKozlov Sergey 2981a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 2982a6dc60ffSKozlov Sergey cxd2841er_set_ts_clock_mode(priv, SYS_DVBT2); 2983a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 2984a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 2985a6dc60ffSKozlov Sergey /* Set demod mode */ 2986a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x02); 2987a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 2988a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 2989a6dc60ffSKozlov Sergey /* Enable demod clock */ 2990a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); 2991a6dc60ffSKozlov Sergey /* Disable RF level monitor */ 29926c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x00); 2993a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); 2994a6dc60ffSKozlov Sergey /* Enable ADC clock */ 2995a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 2996a6dc60ffSKozlov Sergey /* Enable ADC 1 */ 2997a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); 29986c77161aSAbylay Ospan 29996c77161aSAbylay Ospan if (priv->xtal == SONY_XTAL_41000) { 30006c77161aSAbylay Ospan data[0] = 0x0A; 30016c77161aSAbylay Ospan data[1] = 0xD4; 30026c77161aSAbylay Ospan } else { 30036c77161aSAbylay Ospan data[0] = 0x09; 30046c77161aSAbylay Ospan data[1] = 0x54; 30056c77161aSAbylay Ospan } 30066c77161aSAbylay Ospan 3007a6dc60ffSKozlov Sergey cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); 3008a6dc60ffSKozlov Sergey /* Enable ADC 4 */ 3009a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); 3010a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x10 */ 3011a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 3012a6dc60ffSKozlov Sergey /* IFAGC gain settings */ 3013a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x0c, 0x1f); 3014a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x11 */ 3015a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); 3016a6dc60ffSKozlov Sergey /* BBAGC TARGET level setting */ 3017a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50); 3018a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x10 */ 3019a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 30207afe510aSDaniel Scheller /* ASCOT setting */ 30217afe510aSDaniel Scheller cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 30227afe510aSDaniel Scheller ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01); 3023a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x20 */ 3024a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); 3025a6dc60ffSKozlov Sergey /* Acquisition optimization setting */ 3026a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x8b, 0x3c); 3027a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x2b */ 3028a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); 3029a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x76, 0x20, 0x70); 30306c77161aSAbylay Ospan /* Set SLV-T Bank : 0x23 */ 30316c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x23); 30326c77161aSAbylay Ospan /* L1 Control setting */ 30336c77161aSAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xE6, 0x00, 0x03); 3034a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 3035a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 3036a6dc60ffSKozlov Sergey /* TSIF setting */ 3037a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); 3038a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); 3039a6dc60ffSKozlov Sergey /* DVB-T2 initial setting */ 3040a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13); 3041a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x83, 0x10); 3042a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x86, 0x34); 3043a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9e, 0x09, 0x0f); 3044a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x9f, 0xd8); 3045a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x2a */ 3046a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2a); 3047a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x38, 0x04, 0x0f); 3048a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x2b */ 3049a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b); 3050a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x20, 0x3f); 3051a6dc60ffSKozlov Sergey 30526c77161aSAbylay Ospan /* 24MHz Xtal setting */ 30536c77161aSAbylay Ospan if (priv->xtal == SONY_XTAL_24000) { 30546c77161aSAbylay Ospan /* Set SLV-T Bank : 0x11 */ 30556c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); 30566c77161aSAbylay Ospan data[0] = 0xEB; 30576c77161aSAbylay Ospan data[1] = 0x03; 30586c77161aSAbylay Ospan data[2] = 0x3B; 30596c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x33, data, 3); 30606c77161aSAbylay Ospan 30616c77161aSAbylay Ospan /* Set SLV-T Bank : 0x20 */ 30626c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20); 30636c77161aSAbylay Ospan data[0] = 0x5E; 30646c77161aSAbylay Ospan data[1] = 0x5E; 30656c77161aSAbylay Ospan data[2] = 0x47; 30666c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x95, data, 3); 30676c77161aSAbylay Ospan 30686c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x99, 0x18); 30696c77161aSAbylay Ospan 30706c77161aSAbylay Ospan data[0] = 0x3F; 30716c77161aSAbylay Ospan data[1] = 0xFF; 30726c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2); 30736c77161aSAbylay Ospan 30746c77161aSAbylay Ospan /* Set SLV-T Bank : 0x24 */ 30756c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x24); 30766c77161aSAbylay Ospan data[0] = 0x0B; 30776c77161aSAbylay Ospan data[1] = 0x72; 30786c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x34, data, 2); 30796c77161aSAbylay Ospan 30806c77161aSAbylay Ospan data[0] = 0x93; 30816c77161aSAbylay Ospan data[1] = 0xF3; 30826c77161aSAbylay Ospan data[2] = 0x00; 30836c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xD2, data, 3); 30846c77161aSAbylay Ospan 30856c77161aSAbylay Ospan data[0] = 0x05; 30866c77161aSAbylay Ospan data[1] = 0xB8; 30876c77161aSAbylay Ospan data[2] = 0xD8; 30886c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xDD, data, 3); 30896c77161aSAbylay Ospan 30906c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0xE0, 0x00); 30916c77161aSAbylay Ospan 30926c77161aSAbylay Ospan /* Set SLV-T Bank : 0x25 */ 30936c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x25); 30946c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0xED, 0x60); 30956c77161aSAbylay Ospan 30966c77161aSAbylay Ospan /* Set SLV-T Bank : 0x27 */ 30976c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27); 30986c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0xFA, 0x34); 30996c77161aSAbylay Ospan 31006c77161aSAbylay Ospan /* Set SLV-T Bank : 0x2B */ 31016c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2B); 31026c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x4B, 0x2F); 31036c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x9E, 0x0E); 31046c77161aSAbylay Ospan 31056c77161aSAbylay Ospan /* Set SLV-T Bank : 0x2D */ 31066c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2D); 31076c77161aSAbylay Ospan data[0] = 0x89; 31086c77161aSAbylay Ospan data[1] = 0x89; 31096c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x24, data, 2); 31106c77161aSAbylay Ospan 31116c77161aSAbylay Ospan /* Set SLV-T Bank : 0x5E */ 31126c77161aSAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x5E); 31136c77161aSAbylay Ospan data[0] = 0x24; 31146c77161aSAbylay Ospan data[1] = 0x95; 31156c77161aSAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x8C, data, 2); 31166c77161aSAbylay Ospan } 31176c77161aSAbylay Ospan 3118a6dc60ffSKozlov Sergey cxd2841er_sleep_tc_to_active_t2_band(priv, bandwidth); 3119a6dc60ffSKozlov Sergey 3120a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 3121a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 3122a6dc60ffSKozlov Sergey /* Disable HiZ Setting 1 */ 3123a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28); 3124a6dc60ffSKozlov Sergey /* Disable HiZ Setting 2 */ 3125a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00); 3126a6dc60ffSKozlov Sergey priv->state = STATE_ACTIVE_TC; 3127a6dc60ffSKozlov Sergey return 0; 3128a6dc60ffSKozlov Sergey } 3129a6dc60ffSKozlov Sergey 313083808c23SAbylay Ospan /* ISDB-Tb part */ 313183808c23SAbylay Ospan static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv, 313283808c23SAbylay Ospan u32 bandwidth) 313383808c23SAbylay Ospan { 313483808c23SAbylay Ospan u8 data[2] = { 0x09, 0x54 }; 313583808c23SAbylay Ospan u8 data24m[2] = {0x60, 0x00}; 313683808c23SAbylay Ospan u8 data24m2[3] = {0xB7, 0x1B, 0x00}; 313783808c23SAbylay Ospan 313883808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 313983808c23SAbylay Ospan cxd2841er_set_ts_clock_mode(priv, SYS_DVBT); 314083808c23SAbylay Ospan /* Set SLV-X Bank : 0x00 */ 314183808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 314283808c23SAbylay Ospan /* Set demod mode */ 314383808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x06); 314483808c23SAbylay Ospan /* Set SLV-T Bank : 0x00 */ 314583808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 314683808c23SAbylay Ospan /* Enable demod clock */ 314783808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); 314883808c23SAbylay Ospan /* Enable RF level monitor */ 314983808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x01); 315083808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x01); 315183808c23SAbylay Ospan /* Enable ADC clock */ 315283808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 315383808c23SAbylay Ospan /* Enable ADC 1 */ 315483808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); 315583808c23SAbylay Ospan /* xtal freq 20.5MHz or 24M */ 315683808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); 315783808c23SAbylay Ospan /* Enable ADC 4 */ 315883808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); 31597afe510aSDaniel Scheller /* ASCOT setting */ 31607afe510aSDaniel Scheller cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 31617afe510aSDaniel Scheller ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01); 316283808c23SAbylay Ospan /* FEC Auto Recovery setting */ 316383808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01); 316483808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x00, 0x01); 316583808c23SAbylay Ospan /* ISDB-T initial setting */ 316683808c23SAbylay Ospan /* Set SLV-T Bank : 0x00 */ 316783808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 316883808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x00, 0x01); 316983808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x00, 0x01); 317083808c23SAbylay Ospan /* Set SLV-T Bank : 0x10 */ 317183808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 317283808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x69, 0x04, 0x07); 317383808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x6B, 0x03, 0x07); 317483808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9D, 0x50, 0xFF); 317583808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xD3, 0x06, 0x1F); 317683808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xED, 0x00, 0x01); 317783808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xE2, 0xCE, 0x80); 317883808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xF2, 0x13, 0x10); 317983808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xDE, 0x2E, 0x3F); 318083808c23SAbylay Ospan /* Set SLV-T Bank : 0x15 */ 318183808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15); 318283808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xDE, 0x02, 0x03); 318383808c23SAbylay Ospan /* Set SLV-T Bank : 0x1E */ 318483808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x1E); 318583808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x73, 0x68, 0xFF); 318683808c23SAbylay Ospan /* Set SLV-T Bank : 0x63 */ 318783808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x63); 318883808c23SAbylay Ospan cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x81, 0x00, 0x01); 318983808c23SAbylay Ospan 319083808c23SAbylay Ospan /* for xtal 24MHz */ 319183808c23SAbylay Ospan /* Set SLV-T Bank : 0x10 */ 319283808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 319383808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xBF, data24m, 2); 319483808c23SAbylay Ospan /* Set SLV-T Bank : 0x60 */ 319583808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60); 319683808c23SAbylay Ospan cxd2841er_write_regs(priv, I2C_SLVT, 0xA8, data24m2, 3); 319783808c23SAbylay Ospan 319883808c23SAbylay Ospan cxd2841er_sleep_tc_to_active_i_band(priv, bandwidth); 319983808c23SAbylay Ospan /* Set SLV-T Bank : 0x00 */ 320083808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 320183808c23SAbylay Ospan /* Disable HiZ Setting 1 */ 320283808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28); 320383808c23SAbylay Ospan /* Disable HiZ Setting 2 */ 320483808c23SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00); 320583808c23SAbylay Ospan priv->state = STATE_ACTIVE_TC; 320683808c23SAbylay Ospan return 0; 320783808c23SAbylay Ospan } 320883808c23SAbylay Ospan 3209a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv, 3210a6dc60ffSKozlov Sergey u32 bandwidth) 3211a6dc60ffSKozlov Sergey { 3212a6dc60ffSKozlov Sergey u8 data[2] = { 0x09, 0x54 }; 3213a6dc60ffSKozlov Sergey 3214a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3215a6dc60ffSKozlov Sergey cxd2841er_set_ts_clock_mode(priv, SYS_DVBC_ANNEX_A); 3216a6dc60ffSKozlov Sergey /* Set SLV-X Bank : 0x00 */ 3217a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00); 3218a6dc60ffSKozlov Sergey /* Set demod mode */ 3219a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x04); 3220a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 3221a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 3222a6dc60ffSKozlov Sergey /* Enable demod clock */ 3223a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01); 3224a6dc60ffSKozlov Sergey /* Disable RF level monitor */ 32254a86bc10SAbylay Ospan cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x00); 3226a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00); 3227a6dc60ffSKozlov Sergey /* Enable ADC clock */ 3228a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00); 3229a6dc60ffSKozlov Sergey /* Enable ADC 1 */ 3230a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a); 3231a6dc60ffSKozlov Sergey /* xtal freq 20.5MHz */ 3232a6dc60ffSKozlov Sergey cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2); 3233a6dc60ffSKozlov Sergey /* Enable ADC 4 */ 3234a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00); 3235a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x10 */ 3236a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 3237a6dc60ffSKozlov Sergey /* IFAGC gain settings */ 3238a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x09, 0x1f); 3239a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x11 */ 3240a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11); 3241a6dc60ffSKozlov Sergey /* BBAGC TARGET level setting */ 3242a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x48); 3243a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x10 */ 3244a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 32457afe510aSDaniel Scheller /* ASCOT setting */ 32467afe510aSDaniel Scheller cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5, 32477afe510aSDaniel Scheller ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01); 3248a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x40 */ 3249a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40); 3250a6dc60ffSKozlov Sergey /* Demod setting */ 3251a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc3, 0x00, 0x04); 3252a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 3253a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 3254a6dc60ffSKozlov Sergey /* TSIF setting */ 3255a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01); 3256a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01); 3257a6dc60ffSKozlov Sergey 32583f3b48a0SAbylay Ospan cxd2841er_sleep_tc_to_active_c_band(priv, bandwidth); 3259a6dc60ffSKozlov Sergey /* Set SLV-T Bank : 0x00 */ 3260a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 3261a6dc60ffSKozlov Sergey /* Disable HiZ Setting 1 */ 3262a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28); 3263a6dc60ffSKozlov Sergey /* Disable HiZ Setting 2 */ 3264a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00); 3265a6dc60ffSKozlov Sergey priv->state = STATE_ACTIVE_TC; 3266a6dc60ffSKozlov Sergey return 0; 3267a6dc60ffSKozlov Sergey } 3268a6dc60ffSKozlov Sergey 32697e3e68bcSMauro Carvalho Chehab static int cxd2841er_get_frontend(struct dvb_frontend *fe, 32707e3e68bcSMauro Carvalho Chehab struct dtv_frontend_properties *p) 3271a6dc60ffSKozlov Sergey { 3272a6dc60ffSKozlov Sergey enum fe_status status = 0; 3273a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3274a6dc60ffSKozlov Sergey 3275a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3276a6dc60ffSKozlov Sergey if (priv->state == STATE_ACTIVE_S) 3277a6dc60ffSKozlov Sergey cxd2841er_read_status_s(fe, &status); 3278a6dc60ffSKozlov Sergey else if (priv->state == STATE_ACTIVE_TC) 3279a6dc60ffSKozlov Sergey cxd2841er_read_status_tc(fe, &status); 3280a6dc60ffSKozlov Sergey 32815fda1b65SMauro Carvalho Chehab cxd2841er_read_signal_strength(fe); 3282d0e20e13SMauro Carvalho Chehab 3283d0e20e13SMauro Carvalho Chehab if (status & FE_HAS_LOCK) { 3284f1b26622SMauro Carvalho Chehab cxd2841er_read_snr(fe); 3285f1b26622SMauro Carvalho Chehab cxd2841er_read_ucblocks(fe); 3286d0e20e13SMauro Carvalho Chehab 3287f1b26622SMauro Carvalho Chehab cxd2841er_read_ber(fe); 3288a6dc60ffSKozlov Sergey } else { 3289a6dc60ffSKozlov Sergey p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3290a6dc60ffSKozlov Sergey p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3291a6dc60ffSKozlov Sergey p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 32924216be14SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3293a6dc60ffSKozlov Sergey } 3294a6dc60ffSKozlov Sergey return 0; 3295a6dc60ffSKozlov Sergey } 3296a6dc60ffSKozlov Sergey 3297a6dc60ffSKozlov Sergey static int cxd2841er_set_frontend_s(struct dvb_frontend *fe) 3298a6dc60ffSKozlov Sergey { 3299a6dc60ffSKozlov Sergey int ret = 0, i, timeout, carr_offset; 3300a6dc60ffSKozlov Sergey enum fe_status status; 3301a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3302a6dc60ffSKozlov Sergey struct dtv_frontend_properties *p = &fe->dtv_property_cache; 3303a6dc60ffSKozlov Sergey u32 symbol_rate = p->symbol_rate/1000; 3304a6dc60ffSKozlov Sergey 330583808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): %s frequency=%d symbol_rate=%d xtal=%d\n", 3306a6dc60ffSKozlov Sergey __func__, 3307a6dc60ffSKozlov Sergey (p->delivery_system == SYS_DVBS ? "DVB-S" : "DVB-S2"), 330883808c23SAbylay Ospan p->frequency, symbol_rate, priv->xtal); 3309763f857eSDaniel Scheller 3310763f857eSDaniel Scheller if (priv->flags & CXD2841ER_EARLY_TUNE) 3311763f857eSDaniel Scheller cxd2841er_tuner_set(fe); 3312763f857eSDaniel Scheller 3313a6dc60ffSKozlov Sergey switch (priv->state) { 3314a6dc60ffSKozlov Sergey case STATE_SLEEP_S: 3315a6dc60ffSKozlov Sergey ret = cxd2841er_sleep_s_to_active_s( 3316a6dc60ffSKozlov Sergey priv, p->delivery_system, symbol_rate); 3317a6dc60ffSKozlov Sergey break; 3318a6dc60ffSKozlov Sergey case STATE_ACTIVE_S: 3319a6dc60ffSKozlov Sergey ret = cxd2841er_retune_active(priv, p); 3320a6dc60ffSKozlov Sergey break; 3321a6dc60ffSKozlov Sergey default: 3322a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 3323a6dc60ffSKozlov Sergey __func__, priv->state); 3324a6dc60ffSKozlov Sergey ret = -EINVAL; 3325a6dc60ffSKozlov Sergey goto done; 3326a6dc60ffSKozlov Sergey } 3327a6dc60ffSKozlov Sergey if (ret) { 3328a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): tune failed\n", __func__); 3329a6dc60ffSKozlov Sergey goto done; 3330a6dc60ffSKozlov Sergey } 3331c7518d13SDaniel Scheller 3332763f857eSDaniel Scheller if (!(priv->flags & CXD2841ER_EARLY_TUNE)) 3333c7518d13SDaniel Scheller cxd2841er_tuner_set(fe); 3334c7518d13SDaniel Scheller 3335a6dc60ffSKozlov Sergey cxd2841er_tune_done(priv); 3336a6dc60ffSKozlov Sergey timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150; 3337a6dc60ffSKozlov Sergey for (i = 0; i < timeout / CXD2841ER_DVBS_POLLING_INVL; i++) { 3338a6dc60ffSKozlov Sergey usleep_range(CXD2841ER_DVBS_POLLING_INVL*1000, 3339a6dc60ffSKozlov Sergey (CXD2841ER_DVBS_POLLING_INVL + 2) * 1000); 3340a6dc60ffSKozlov Sergey cxd2841er_read_status_s(fe, &status); 3341a6dc60ffSKozlov Sergey if (status & FE_HAS_LOCK) 3342a6dc60ffSKozlov Sergey break; 3343a6dc60ffSKozlov Sergey } 3344a6dc60ffSKozlov Sergey if (status & FE_HAS_LOCK) { 3345a6dc60ffSKozlov Sergey if (cxd2841er_get_carrier_offset_s_s2( 3346a6dc60ffSKozlov Sergey priv, &carr_offset)) { 3347a6dc60ffSKozlov Sergey ret = -EINVAL; 3348a6dc60ffSKozlov Sergey goto done; 3349a6dc60ffSKozlov Sergey } 3350a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): carrier_offset=%d\n", 3351a6dc60ffSKozlov Sergey __func__, carr_offset); 3352a6dc60ffSKozlov Sergey } 3353a6dc60ffSKozlov Sergey done: 3354d0e20e13SMauro Carvalho Chehab /* Reset stats */ 3355d0e20e13SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_RELATIVE; 3356d0e20e13SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3357d0e20e13SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3358d0e20e13SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 33594216be14SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3360d0e20e13SMauro Carvalho Chehab 3361a6dc60ffSKozlov Sergey return ret; 3362a6dc60ffSKozlov Sergey } 3363a6dc60ffSKozlov Sergey 3364a6dc60ffSKozlov Sergey static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe) 3365a6dc60ffSKozlov Sergey { 3366a6dc60ffSKozlov Sergey int ret = 0, timeout; 3367a6dc60ffSKozlov Sergey enum fe_status status; 3368a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3369a6dc60ffSKozlov Sergey struct dtv_frontend_properties *p = &fe->dtv_property_cache; 3370a6dc60ffSKozlov Sergey 33713f3b48a0SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s() delivery_system=%d bandwidth_hz=%d\n", 33723f3b48a0SAbylay Ospan __func__, p->delivery_system, p->bandwidth_hz); 3373763f857eSDaniel Scheller 3374763f857eSDaniel Scheller if (priv->flags & CXD2841ER_EARLY_TUNE) 3375763f857eSDaniel Scheller cxd2841er_tuner_set(fe); 3376763f857eSDaniel Scheller 3377a6dc60ffSKozlov Sergey if (p->delivery_system == SYS_DVBT) { 3378a6dc60ffSKozlov Sergey priv->system = SYS_DVBT; 3379a6dc60ffSKozlov Sergey switch (priv->state) { 3380a6dc60ffSKozlov Sergey case STATE_SLEEP_TC: 3381a6dc60ffSKozlov Sergey ret = cxd2841er_sleep_tc_to_active_t( 3382a6dc60ffSKozlov Sergey priv, p->bandwidth_hz); 3383a6dc60ffSKozlov Sergey break; 3384a6dc60ffSKozlov Sergey case STATE_ACTIVE_TC: 3385a6dc60ffSKozlov Sergey ret = cxd2841er_retune_active(priv, p); 3386a6dc60ffSKozlov Sergey break; 3387a6dc60ffSKozlov Sergey default: 3388a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 3389a6dc60ffSKozlov Sergey __func__, priv->state); 3390a6dc60ffSKozlov Sergey ret = -EINVAL; 3391a6dc60ffSKozlov Sergey } 3392a6dc60ffSKozlov Sergey } else if (p->delivery_system == SYS_DVBT2) { 3393a6dc60ffSKozlov Sergey priv->system = SYS_DVBT2; 3394a6dc60ffSKozlov Sergey cxd2841er_dvbt2_set_plp_config(priv, 3395a6dc60ffSKozlov Sergey (int)(p->stream_id > 255), p->stream_id); 3396a6dc60ffSKozlov Sergey cxd2841er_dvbt2_set_profile(priv, DVBT2_PROFILE_BASE); 3397a6dc60ffSKozlov Sergey switch (priv->state) { 3398a6dc60ffSKozlov Sergey case STATE_SLEEP_TC: 3399a6dc60ffSKozlov Sergey ret = cxd2841er_sleep_tc_to_active_t2(priv, 3400a6dc60ffSKozlov Sergey p->bandwidth_hz); 3401a6dc60ffSKozlov Sergey break; 3402a6dc60ffSKozlov Sergey case STATE_ACTIVE_TC: 3403a6dc60ffSKozlov Sergey ret = cxd2841er_retune_active(priv, p); 3404a6dc60ffSKozlov Sergey break; 3405a6dc60ffSKozlov Sergey default: 3406a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 3407a6dc60ffSKozlov Sergey __func__, priv->state); 3408a6dc60ffSKozlov Sergey ret = -EINVAL; 3409a6dc60ffSKozlov Sergey } 341083808c23SAbylay Ospan } else if (p->delivery_system == SYS_ISDBT) { 341183808c23SAbylay Ospan priv->system = SYS_ISDBT; 341283808c23SAbylay Ospan switch (priv->state) { 341383808c23SAbylay Ospan case STATE_SLEEP_TC: 341483808c23SAbylay Ospan ret = cxd2841er_sleep_tc_to_active_i( 341583808c23SAbylay Ospan priv, p->bandwidth_hz); 341683808c23SAbylay Ospan break; 341783808c23SAbylay Ospan case STATE_ACTIVE_TC: 341883808c23SAbylay Ospan ret = cxd2841er_retune_active(priv, p); 341983808c23SAbylay Ospan break; 342083808c23SAbylay Ospan default: 342183808c23SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 342283808c23SAbylay Ospan __func__, priv->state); 342383808c23SAbylay Ospan ret = -EINVAL; 342483808c23SAbylay Ospan } 3425a6dc60ffSKozlov Sergey } else if (p->delivery_system == SYS_DVBC_ANNEX_A || 3426a6dc60ffSKozlov Sergey p->delivery_system == SYS_DVBC_ANNEX_C) { 3427a6dc60ffSKozlov Sergey priv->system = SYS_DVBC_ANNEX_A; 34283f3b48a0SAbylay Ospan /* correct bandwidth */ 34293f3b48a0SAbylay Ospan if (p->bandwidth_hz != 6000000 && 34303f3b48a0SAbylay Ospan p->bandwidth_hz != 7000000 && 34313f3b48a0SAbylay Ospan p->bandwidth_hz != 8000000) { 34323f3b48a0SAbylay Ospan p->bandwidth_hz = 8000000; 34333f3b48a0SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): forcing bandwidth to %d\n", 34343f3b48a0SAbylay Ospan __func__, p->bandwidth_hz); 34353f3b48a0SAbylay Ospan } 34363f3b48a0SAbylay Ospan 3437a6dc60ffSKozlov Sergey switch (priv->state) { 3438a6dc60ffSKozlov Sergey case STATE_SLEEP_TC: 3439a6dc60ffSKozlov Sergey ret = cxd2841er_sleep_tc_to_active_c( 3440a6dc60ffSKozlov Sergey priv, p->bandwidth_hz); 3441a6dc60ffSKozlov Sergey break; 3442a6dc60ffSKozlov Sergey case STATE_ACTIVE_TC: 3443a6dc60ffSKozlov Sergey ret = cxd2841er_retune_active(priv, p); 3444a6dc60ffSKozlov Sergey break; 3445a6dc60ffSKozlov Sergey default: 3446a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n", 3447a6dc60ffSKozlov Sergey __func__, priv->state); 3448a6dc60ffSKozlov Sergey ret = -EINVAL; 3449a6dc60ffSKozlov Sergey } 3450a6dc60ffSKozlov Sergey } else { 3451a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 3452a6dc60ffSKozlov Sergey "%s(): invalid delivery system %d\n", 3453a6dc60ffSKozlov Sergey __func__, p->delivery_system); 3454a6dc60ffSKozlov Sergey ret = -EINVAL; 3455a6dc60ffSKozlov Sergey } 3456a6dc60ffSKozlov Sergey if (ret) 3457a6dc60ffSKozlov Sergey goto done; 3458c7518d13SDaniel Scheller 3459763f857eSDaniel Scheller if (!(priv->flags & CXD2841ER_EARLY_TUNE)) 3460c7518d13SDaniel Scheller cxd2841er_tuner_set(fe); 3461c7518d13SDaniel Scheller 3462a6dc60ffSKozlov Sergey cxd2841er_tune_done(priv); 3463e3943aa6SDaniel Scheller 3464e3943aa6SDaniel Scheller if (priv->flags & CXD2841ER_NO_WAIT_LOCK) 3465e3943aa6SDaniel Scheller goto done; 3466e3943aa6SDaniel Scheller 3467a6dc60ffSKozlov Sergey timeout = 2500; 3468a6dc60ffSKozlov Sergey while (timeout > 0) { 3469a6dc60ffSKozlov Sergey ret = cxd2841er_read_status_tc(fe, &status); 3470a6dc60ffSKozlov Sergey if (ret) 3471a6dc60ffSKozlov Sergey goto done; 3472a6dc60ffSKozlov Sergey if (status & FE_HAS_LOCK) 3473a6dc60ffSKozlov Sergey break; 3474a6dc60ffSKozlov Sergey msleep(20); 3475a6dc60ffSKozlov Sergey timeout -= 20; 3476a6dc60ffSKozlov Sergey } 3477a6dc60ffSKozlov Sergey if (timeout < 0) 3478a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 3479a6dc60ffSKozlov Sergey "%s(): LOCK wait timeout\n", __func__); 3480a6dc60ffSKozlov Sergey done: 3481a6dc60ffSKozlov Sergey return ret; 3482a6dc60ffSKozlov Sergey } 3483a6dc60ffSKozlov Sergey 3484a6dc60ffSKozlov Sergey static int cxd2841er_tune_s(struct dvb_frontend *fe, 3485a6dc60ffSKozlov Sergey bool re_tune, 3486a6dc60ffSKozlov Sergey unsigned int mode_flags, 3487a6dc60ffSKozlov Sergey unsigned int *delay, 3488a6dc60ffSKozlov Sergey enum fe_status *status) 3489a6dc60ffSKozlov Sergey { 3490a6dc60ffSKozlov Sergey int ret, carrier_offset; 3491a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3492a6dc60ffSKozlov Sergey struct dtv_frontend_properties *p = &fe->dtv_property_cache; 3493a6dc60ffSKozlov Sergey 3494a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s() re_tune=%d\n", __func__, re_tune); 3495a6dc60ffSKozlov Sergey if (re_tune) { 3496a6dc60ffSKozlov Sergey ret = cxd2841er_set_frontend_s(fe); 3497a6dc60ffSKozlov Sergey if (ret) 3498a6dc60ffSKozlov Sergey return ret; 3499a6dc60ffSKozlov Sergey cxd2841er_read_status_s(fe, status); 3500a6dc60ffSKozlov Sergey if (*status & FE_HAS_LOCK) { 3501a6dc60ffSKozlov Sergey if (cxd2841er_get_carrier_offset_s_s2( 3502a6dc60ffSKozlov Sergey priv, &carrier_offset)) 3503a6dc60ffSKozlov Sergey return -EINVAL; 3504a6dc60ffSKozlov Sergey p->frequency += carrier_offset; 3505a6dc60ffSKozlov Sergey ret = cxd2841er_set_frontend_s(fe); 3506a6dc60ffSKozlov Sergey if (ret) 3507a6dc60ffSKozlov Sergey return ret; 3508a6dc60ffSKozlov Sergey } 3509a6dc60ffSKozlov Sergey } 3510a6dc60ffSKozlov Sergey *delay = HZ / 5; 3511a6dc60ffSKozlov Sergey return cxd2841er_read_status_s(fe, status); 3512a6dc60ffSKozlov Sergey } 3513a6dc60ffSKozlov Sergey 3514a6dc60ffSKozlov Sergey static int cxd2841er_tune_tc(struct dvb_frontend *fe, 3515a6dc60ffSKozlov Sergey bool re_tune, 3516a6dc60ffSKozlov Sergey unsigned int mode_flags, 3517a6dc60ffSKozlov Sergey unsigned int *delay, 3518a6dc60ffSKozlov Sergey enum fe_status *status) 3519a6dc60ffSKozlov Sergey { 3520a6dc60ffSKozlov Sergey int ret, carrier_offset; 3521a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3522a6dc60ffSKozlov Sergey struct dtv_frontend_properties *p = &fe->dtv_property_cache; 3523a6dc60ffSKozlov Sergey 35243f3b48a0SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s(): re_tune %d bandwidth=%d\n", __func__, 35253f3b48a0SAbylay Ospan re_tune, p->bandwidth_hz); 3526a6dc60ffSKozlov Sergey if (re_tune) { 3527a6dc60ffSKozlov Sergey ret = cxd2841er_set_frontend_tc(fe); 3528a6dc60ffSKozlov Sergey if (ret) 3529a6dc60ffSKozlov Sergey return ret; 3530a6dc60ffSKozlov Sergey cxd2841er_read_status_tc(fe, status); 3531a6dc60ffSKozlov Sergey if (*status & FE_HAS_LOCK) { 3532a6dc60ffSKozlov Sergey switch (priv->system) { 353376344a3fSMauro Carvalho Chehab case SYS_ISDBT: 353476344a3fSMauro Carvalho Chehab ret = cxd2841er_get_carrier_offset_i( 353576344a3fSMauro Carvalho Chehab priv, p->bandwidth_hz, 353676344a3fSMauro Carvalho Chehab &carrier_offset); 3537bb9bd878SArnd Bergmann if (ret) 3538bb9bd878SArnd Bergmann return ret; 353976344a3fSMauro Carvalho Chehab break; 3540a6dc60ffSKozlov Sergey case SYS_DVBT: 3541c5ea46daSAbylay Ospan ret = cxd2841er_get_carrier_offset_t( 3542c5ea46daSAbylay Ospan priv, p->bandwidth_hz, 3543c5ea46daSAbylay Ospan &carrier_offset); 3544bb9bd878SArnd Bergmann if (ret) 3545bb9bd878SArnd Bergmann return ret; 3546c5ea46daSAbylay Ospan break; 3547a6dc60ffSKozlov Sergey case SYS_DVBT2: 3548a6dc60ffSKozlov Sergey ret = cxd2841er_get_carrier_offset_t2( 3549a6dc60ffSKozlov Sergey priv, p->bandwidth_hz, 3550a6dc60ffSKozlov Sergey &carrier_offset); 3551bb9bd878SArnd Bergmann if (ret) 3552bb9bd878SArnd Bergmann return ret; 3553a6dc60ffSKozlov Sergey break; 3554a6dc60ffSKozlov Sergey case SYS_DVBC_ANNEX_A: 3555a6dc60ffSKozlov Sergey ret = cxd2841er_get_carrier_offset_c( 3556a6dc60ffSKozlov Sergey priv, &carrier_offset); 3557bb9bd878SArnd Bergmann if (ret) 3558bb9bd878SArnd Bergmann return ret; 3559a6dc60ffSKozlov Sergey break; 3560a6dc60ffSKozlov Sergey default: 3561a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 3562a6dc60ffSKozlov Sergey "%s(): invalid delivery system %d\n", 3563a6dc60ffSKozlov Sergey __func__, priv->system); 3564a6dc60ffSKozlov Sergey return -EINVAL; 3565a6dc60ffSKozlov Sergey } 3566a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): carrier offset %d\n", 3567a6dc60ffSKozlov Sergey __func__, carrier_offset); 3568a6dc60ffSKozlov Sergey p->frequency += carrier_offset; 3569a6dc60ffSKozlov Sergey ret = cxd2841er_set_frontend_tc(fe); 3570a6dc60ffSKozlov Sergey if (ret) 3571a6dc60ffSKozlov Sergey return ret; 3572a6dc60ffSKozlov Sergey } 3573a6dc60ffSKozlov Sergey } 3574a6dc60ffSKozlov Sergey *delay = HZ / 5; 3575a6dc60ffSKozlov Sergey return cxd2841er_read_status_tc(fe, status); 3576a6dc60ffSKozlov Sergey } 3577a6dc60ffSKozlov Sergey 3578a6dc60ffSKozlov Sergey static int cxd2841er_sleep_s(struct dvb_frontend *fe) 3579a6dc60ffSKozlov Sergey { 3580a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3581a6dc60ffSKozlov Sergey 3582a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3583a6dc60ffSKozlov Sergey cxd2841er_active_s_to_sleep_s(fe->demodulator_priv); 3584a6dc60ffSKozlov Sergey cxd2841er_sleep_s_to_shutdown(fe->demodulator_priv); 3585a6dc60ffSKozlov Sergey return 0; 3586a6dc60ffSKozlov Sergey } 3587a6dc60ffSKozlov Sergey 3588a6dc60ffSKozlov Sergey static int cxd2841er_sleep_tc(struct dvb_frontend *fe) 3589a6dc60ffSKozlov Sergey { 3590a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3591a6dc60ffSKozlov Sergey 3592a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3593a6dc60ffSKozlov Sergey if (priv->state == STATE_ACTIVE_TC) { 3594a6dc60ffSKozlov Sergey switch (priv->system) { 3595a6dc60ffSKozlov Sergey case SYS_DVBT: 3596a6dc60ffSKozlov Sergey cxd2841er_active_t_to_sleep_tc(priv); 3597a6dc60ffSKozlov Sergey break; 3598a6dc60ffSKozlov Sergey case SYS_DVBT2: 3599a6dc60ffSKozlov Sergey cxd2841er_active_t2_to_sleep_tc(priv); 3600a6dc60ffSKozlov Sergey break; 360183808c23SAbylay Ospan case SYS_ISDBT: 360283808c23SAbylay Ospan cxd2841er_active_i_to_sleep_tc(priv); 360383808c23SAbylay Ospan break; 3604a6dc60ffSKozlov Sergey case SYS_DVBC_ANNEX_A: 3605a6dc60ffSKozlov Sergey cxd2841er_active_c_to_sleep_tc(priv); 3606a6dc60ffSKozlov Sergey break; 3607a6dc60ffSKozlov Sergey default: 3608a6dc60ffSKozlov Sergey dev_warn(&priv->i2c->dev, 3609a6dc60ffSKozlov Sergey "%s(): unknown delivery system %d\n", 3610a6dc60ffSKozlov Sergey __func__, priv->system); 3611a6dc60ffSKozlov Sergey } 3612a6dc60ffSKozlov Sergey } 3613a6dc60ffSKozlov Sergey if (priv->state != STATE_SLEEP_TC) { 3614a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid state %d\n", 3615a6dc60ffSKozlov Sergey __func__, priv->state); 3616a6dc60ffSKozlov Sergey return -EINVAL; 3617a6dc60ffSKozlov Sergey } 3618a6dc60ffSKozlov Sergey cxd2841er_sleep_tc_to_shutdown(priv); 3619a6dc60ffSKozlov Sergey return 0; 3620a6dc60ffSKozlov Sergey } 3621a6dc60ffSKozlov Sergey 3622a6dc60ffSKozlov Sergey static int cxd2841er_send_burst(struct dvb_frontend *fe, 3623a6dc60ffSKozlov Sergey enum fe_sec_mini_cmd burst) 3624a6dc60ffSKozlov Sergey { 3625a6dc60ffSKozlov Sergey u8 data; 3626a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3627a6dc60ffSKozlov Sergey 3628a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): burst mode %s\n", __func__, 3629a6dc60ffSKozlov Sergey (burst == SEC_MINI_A ? "A" : "B")); 3630a6dc60ffSKozlov Sergey if (priv->state != STATE_SLEEP_S && 3631a6dc60ffSKozlov Sergey priv->state != STATE_ACTIVE_S) { 3632a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid demod state %d\n", 3633a6dc60ffSKozlov Sergey __func__, priv->state); 3634a6dc60ffSKozlov Sergey return -EINVAL; 3635a6dc60ffSKozlov Sergey } 3636a6dc60ffSKozlov Sergey data = (burst == SEC_MINI_A ? 0 : 1); 3637a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xbb); 3638a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x34, 0x01); 3639a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x35, data); 3640a6dc60ffSKozlov Sergey return 0; 3641a6dc60ffSKozlov Sergey } 3642a6dc60ffSKozlov Sergey 3643a6dc60ffSKozlov Sergey static int cxd2841er_set_tone(struct dvb_frontend *fe, 3644a6dc60ffSKozlov Sergey enum fe_sec_tone_mode tone) 3645a6dc60ffSKozlov Sergey { 3646a6dc60ffSKozlov Sergey u8 data; 3647a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3648a6dc60ffSKozlov Sergey 3649a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): tone %s\n", __func__, 3650a6dc60ffSKozlov Sergey (tone == SEC_TONE_ON ? "On" : "Off")); 3651a6dc60ffSKozlov Sergey if (priv->state != STATE_SLEEP_S && 3652a6dc60ffSKozlov Sergey priv->state != STATE_ACTIVE_S) { 3653a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid demod state %d\n", 3654a6dc60ffSKozlov Sergey __func__, priv->state); 3655a6dc60ffSKozlov Sergey return -EINVAL; 3656a6dc60ffSKozlov Sergey } 3657a6dc60ffSKozlov Sergey data = (tone == SEC_TONE_ON ? 1 : 0); 3658a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xbb); 3659a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x36, data); 3660a6dc60ffSKozlov Sergey return 0; 3661a6dc60ffSKozlov Sergey } 3662a6dc60ffSKozlov Sergey 3663a6dc60ffSKozlov Sergey static int cxd2841er_send_diseqc_msg(struct dvb_frontend *fe, 3664a6dc60ffSKozlov Sergey struct dvb_diseqc_master_cmd *cmd) 3665a6dc60ffSKozlov Sergey { 3666a6dc60ffSKozlov Sergey int i; 3667a6dc60ffSKozlov Sergey u8 data[12]; 3668a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3669a6dc60ffSKozlov Sergey 3670a6dc60ffSKozlov Sergey if (priv->state != STATE_SLEEP_S && 3671a6dc60ffSKozlov Sergey priv->state != STATE_ACTIVE_S) { 3672a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid demod state %d\n", 3673a6dc60ffSKozlov Sergey __func__, priv->state); 3674a6dc60ffSKozlov Sergey return -EINVAL; 3675a6dc60ffSKozlov Sergey } 3676a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 3677a6dc60ffSKozlov Sergey "%s(): cmd->len %d\n", __func__, cmd->msg_len); 3678a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xbb); 3679a6dc60ffSKozlov Sergey /* DiDEqC enable */ 3680a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x33, 0x01); 3681a6dc60ffSKozlov Sergey /* cmd1 length & data */ 3682a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x3d, cmd->msg_len); 3683a6dc60ffSKozlov Sergey memset(data, 0, sizeof(data)); 3684a6dc60ffSKozlov Sergey for (i = 0; i < cmd->msg_len && i < sizeof(data); i++) 3685a6dc60ffSKozlov Sergey data[i] = cmd->msg[i]; 3686a6dc60ffSKozlov Sergey cxd2841er_write_regs(priv, I2C_SLVT, 0x3e, data, sizeof(data)); 3687a6dc60ffSKozlov Sergey /* repeat count for cmd1 */ 3688a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x37, 1); 3689a6dc60ffSKozlov Sergey /* repeat count for cmd2: always 0 */ 3690a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x38, 0); 3691a6dc60ffSKozlov Sergey /* start transmit */ 3692a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x32, 0x01); 3693a6dc60ffSKozlov Sergey /* wait for 1 sec timeout */ 3694a6dc60ffSKozlov Sergey for (i = 0; i < 50; i++) { 3695a6dc60ffSKozlov Sergey cxd2841er_read_reg(priv, I2C_SLVT, 0x10, data); 3696a6dc60ffSKozlov Sergey if (!data[0]) { 3697a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 3698a6dc60ffSKozlov Sergey "%s(): DiSEqC cmd has been sent\n", __func__); 3699a6dc60ffSKozlov Sergey return 0; 3700a6dc60ffSKozlov Sergey } 3701a6dc60ffSKozlov Sergey msleep(20); 3702a6dc60ffSKozlov Sergey } 3703a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, 3704a6dc60ffSKozlov Sergey "%s(): DiSEqC cmd transmit timeout\n", __func__); 3705a6dc60ffSKozlov Sergey return -ETIMEDOUT; 3706a6dc60ffSKozlov Sergey } 3707a6dc60ffSKozlov Sergey 3708a6dc60ffSKozlov Sergey static void cxd2841er_release(struct dvb_frontend *fe) 3709a6dc60ffSKozlov Sergey { 3710a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3711a6dc60ffSKozlov Sergey 3712a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3713a6dc60ffSKozlov Sergey kfree(priv); 3714a6dc60ffSKozlov Sergey } 3715a6dc60ffSKozlov Sergey 3716a6dc60ffSKozlov Sergey static int cxd2841er_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 3717a6dc60ffSKozlov Sergey { 3718a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3719a6dc60ffSKozlov Sergey 3720a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s(): enable=%d\n", __func__, enable); 3721a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits( 3722a6dc60ffSKozlov Sergey priv, I2C_SLVX, 0x8, (enable ? 0x01 : 0x00), 0x01); 3723a6dc60ffSKozlov Sergey return 0; 3724a6dc60ffSKozlov Sergey } 3725a6dc60ffSKozlov Sergey 3726a6dc60ffSKozlov Sergey static enum dvbfe_algo cxd2841er_get_algo(struct dvb_frontend *fe) 3727a6dc60ffSKozlov Sergey { 3728a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3729a6dc60ffSKozlov Sergey 3730a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3731a6dc60ffSKozlov Sergey return DVBFE_ALGO_HW; 3732a6dc60ffSKozlov Sergey } 3733a6dc60ffSKozlov Sergey 3734d0e20e13SMauro Carvalho Chehab static void cxd2841er_init_stats(struct dvb_frontend *fe) 3735d0e20e13SMauro Carvalho Chehab { 3736d0e20e13SMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 3737d0e20e13SMauro Carvalho Chehab 3738d0e20e13SMauro Carvalho Chehab p->strength.len = 1; 3739d0e20e13SMauro Carvalho Chehab p->strength.stat[0].scale = FE_SCALE_RELATIVE; 3740d0e20e13SMauro Carvalho Chehab p->cnr.len = 1; 3741d0e20e13SMauro Carvalho Chehab p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3742d0e20e13SMauro Carvalho Chehab p->block_error.len = 1; 3743d0e20e13SMauro Carvalho Chehab p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3744d0e20e13SMauro Carvalho Chehab p->post_bit_error.len = 1; 3745d0e20e13SMauro Carvalho Chehab p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 37464216be14SMauro Carvalho Chehab p->post_bit_count.len = 1; 37474216be14SMauro Carvalho Chehab p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 3748d0e20e13SMauro Carvalho Chehab } 3749d0e20e13SMauro Carvalho Chehab 3750d0e20e13SMauro Carvalho Chehab 3751a6dc60ffSKozlov Sergey static int cxd2841er_init_s(struct dvb_frontend *fe) 3752a6dc60ffSKozlov Sergey { 3753a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 3754a6dc60ffSKozlov Sergey 375530ae3307SAbylay Ospan /* sanity. force demod to SHUTDOWN state */ 375630ae3307SAbylay Ospan if (priv->state == STATE_SLEEP_S) { 375730ae3307SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s() forcing sleep->shutdown\n", 375830ae3307SAbylay Ospan __func__); 375930ae3307SAbylay Ospan cxd2841er_sleep_s_to_shutdown(priv); 376030ae3307SAbylay Ospan } else if (priv->state == STATE_ACTIVE_S) { 376130ae3307SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s() forcing active->sleep->shutdown\n", 376230ae3307SAbylay Ospan __func__); 376330ae3307SAbylay Ospan cxd2841er_active_s_to_sleep_s(priv); 376430ae3307SAbylay Ospan cxd2841er_sleep_s_to_shutdown(priv); 376530ae3307SAbylay Ospan } 376630ae3307SAbylay Ospan 3767a6dc60ffSKozlov Sergey dev_dbg(&priv->i2c->dev, "%s()\n", __func__); 3768a6dc60ffSKozlov Sergey cxd2841er_shutdown_to_sleep_s(priv); 3769a6dc60ffSKozlov Sergey /* SONY_DEMOD_CONFIG_SAT_IFAGCNEG set to 1 */ 3770a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0); 3771a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xb9, 0x01, 0x01); 3772d0e20e13SMauro Carvalho Chehab 3773d0e20e13SMauro Carvalho Chehab cxd2841er_init_stats(fe); 3774d0e20e13SMauro Carvalho Chehab 3775a6dc60ffSKozlov Sergey return 0; 3776a6dc60ffSKozlov Sergey } 3777a6dc60ffSKozlov Sergey 3778a6dc60ffSKozlov Sergey static int cxd2841er_init_tc(struct dvb_frontend *fe) 3779a6dc60ffSKozlov Sergey { 3780a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = fe->demodulator_priv; 37813f3b48a0SAbylay Ospan struct dtv_frontend_properties *p = &fe->dtv_property_cache; 3782a6dc60ffSKozlov Sergey 37833f3b48a0SAbylay Ospan dev_dbg(&priv->i2c->dev, "%s() bandwidth_hz=%d\n", 37843f3b48a0SAbylay Ospan __func__, p->bandwidth_hz); 3785a6dc60ffSKozlov Sergey cxd2841er_shutdown_to_sleep_tc(priv); 3786a6dc60ffSKozlov Sergey /* SONY_DEMOD_CONFIG_IFAGCNEG = 1 */ 3787a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10); 3788a6dc60ffSKozlov Sergey cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcb, 0x40, 0x40); 3789a6dc60ffSKozlov Sergey /* SONY_DEMOD_CONFIG_IFAGC_ADC_FS = 0 */ 3790a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0xcd, 0x50); 3791a6dc60ffSKozlov Sergey /* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */ 3792a6dc60ffSKozlov Sergey cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00); 379303ab1bd5SDaniel Scheller cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 379403ab1bd5SDaniel Scheller ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x80 : 0x00), 0x80); 3795d0e20e13SMauro Carvalho Chehab 3796d0e20e13SMauro Carvalho Chehab cxd2841er_init_stats(fe); 3797d0e20e13SMauro Carvalho Chehab 3798a6dc60ffSKozlov Sergey return 0; 3799a6dc60ffSKozlov Sergey } 3800a6dc60ffSKozlov Sergey 3801bd336e63SMax Kellermann static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops; 38023f3b48a0SAbylay Ospan static struct dvb_frontend_ops cxd2841er_t_c_ops; 3803a6dc60ffSKozlov Sergey 3804a6dc60ffSKozlov Sergey static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg, 3805a6dc60ffSKozlov Sergey struct i2c_adapter *i2c, 3806a6dc60ffSKozlov Sergey u8 system) 3807a6dc60ffSKozlov Sergey { 3808a6dc60ffSKozlov Sergey u8 chip_id = 0; 3809a6dc60ffSKozlov Sergey const char *type; 38103f3b48a0SAbylay Ospan const char *name; 3811a6dc60ffSKozlov Sergey struct cxd2841er_priv *priv = NULL; 3812a6dc60ffSKozlov Sergey 3813a6dc60ffSKozlov Sergey /* allocate memory for the internal state */ 3814a6dc60ffSKozlov Sergey priv = kzalloc(sizeof(struct cxd2841er_priv), GFP_KERNEL); 3815a6dc60ffSKozlov Sergey if (!priv) 3816a6dc60ffSKozlov Sergey return NULL; 3817a6dc60ffSKozlov Sergey priv->i2c = i2c; 3818a6dc60ffSKozlov Sergey priv->config = cfg; 3819a6dc60ffSKozlov Sergey priv->i2c_addr_slvx = (cfg->i2c_addr + 4) >> 1; 3820a6dc60ffSKozlov Sergey priv->i2c_addr_slvt = (cfg->i2c_addr) >> 1; 382183808c23SAbylay Ospan priv->xtal = cfg->xtal; 3822050863aaSDaniel Scheller priv->flags = cfg->flags; 3823a6dc60ffSKozlov Sergey priv->frontend.demodulator_priv = priv; 3824a6dc60ffSKozlov Sergey dev_info(&priv->i2c->dev, 3825a6dc60ffSKozlov Sergey "%s(): I2C adapter %p SLVX addr %x SLVT addr %x\n", 3826a6dc60ffSKozlov Sergey __func__, priv->i2c, 3827a6dc60ffSKozlov Sergey priv->i2c_addr_slvx, priv->i2c_addr_slvt); 3828a6dc60ffSKozlov Sergey chip_id = cxd2841er_chip_id(priv); 38293f3b48a0SAbylay Ospan switch (chip_id) { 38301ecda28cSDaniel Scheller case CXD2837ER_CHIP_ID: 38311ecda28cSDaniel Scheller snprintf(cxd2841er_t_c_ops.info.name, 128, 38321ecda28cSDaniel Scheller "Sony CXD2837ER DVB-T/T2/C demodulator"); 38331ecda28cSDaniel Scheller name = "CXD2837ER"; 38341ecda28cSDaniel Scheller type = "C/T/T2"; 38351ecda28cSDaniel Scheller break; 38361ecda28cSDaniel Scheller case CXD2838ER_CHIP_ID: 38371ecda28cSDaniel Scheller snprintf(cxd2841er_t_c_ops.info.name, 128, 38381ecda28cSDaniel Scheller "Sony CXD2838ER ISDB-T demodulator"); 38391ecda28cSDaniel Scheller cxd2841er_t_c_ops.delsys[0] = SYS_ISDBT; 38401ecda28cSDaniel Scheller cxd2841er_t_c_ops.delsys[1] = SYS_UNDEFINED; 38411ecda28cSDaniel Scheller cxd2841er_t_c_ops.delsys[2] = SYS_UNDEFINED; 38421ecda28cSDaniel Scheller name = "CXD2838ER"; 38431ecda28cSDaniel Scheller type = "ISDB-T"; 38441ecda28cSDaniel Scheller break; 38453f3b48a0SAbylay Ospan case CXD2841ER_CHIP_ID: 38463f3b48a0SAbylay Ospan snprintf(cxd2841er_t_c_ops.info.name, 128, 38473f3b48a0SAbylay Ospan "Sony CXD2841ER DVB-T/T2/C demodulator"); 38483f3b48a0SAbylay Ospan name = "CXD2841ER"; 38491ecda28cSDaniel Scheller type = "T/T2/C/ISDB-T"; 38501ecda28cSDaniel Scheller break; 38511ecda28cSDaniel Scheller case CXD2843ER_CHIP_ID: 38521ecda28cSDaniel Scheller snprintf(cxd2841er_t_c_ops.info.name, 128, 38531ecda28cSDaniel Scheller "Sony CXD2843ER DVB-T/T2/C/C2 demodulator"); 38541ecda28cSDaniel Scheller name = "CXD2843ER"; 38551ecda28cSDaniel Scheller type = "C/C2/T/T2"; 38563f3b48a0SAbylay Ospan break; 38573f3b48a0SAbylay Ospan case CXD2854ER_CHIP_ID: 38583f3b48a0SAbylay Ospan snprintf(cxd2841er_t_c_ops.info.name, 128, 38593f3b48a0SAbylay Ospan "Sony CXD2854ER DVB-T/T2/C and ISDB-T demodulator"); 38603f3b48a0SAbylay Ospan cxd2841er_t_c_ops.delsys[3] = SYS_ISDBT; 38613f3b48a0SAbylay Ospan name = "CXD2854ER"; 38621ecda28cSDaniel Scheller type = "C/C2/T/T2/ISDB-T"; 38633f3b48a0SAbylay Ospan break; 38643f3b48a0SAbylay Ospan default: 3865a6dc60ffSKozlov Sergey dev_err(&priv->i2c->dev, "%s(): invalid chip ID 0x%02x\n", 3866a6dc60ffSKozlov Sergey __func__, chip_id); 3867a6dc60ffSKozlov Sergey priv->frontend.demodulator_priv = NULL; 3868a6dc60ffSKozlov Sergey kfree(priv); 3869a6dc60ffSKozlov Sergey return NULL; 3870a6dc60ffSKozlov Sergey } 38713f3b48a0SAbylay Ospan 38723f3b48a0SAbylay Ospan /* create dvb_frontend */ 38733f3b48a0SAbylay Ospan if (system == SYS_DVBS) { 38743f3b48a0SAbylay Ospan memcpy(&priv->frontend.ops, 38753f3b48a0SAbylay Ospan &cxd2841er_dvbs_s2_ops, 38763f3b48a0SAbylay Ospan sizeof(struct dvb_frontend_ops)); 38773f3b48a0SAbylay Ospan type = "S/S2"; 38783f3b48a0SAbylay Ospan } else { 38793f3b48a0SAbylay Ospan memcpy(&priv->frontend.ops, 38803f3b48a0SAbylay Ospan &cxd2841er_t_c_ops, 38813f3b48a0SAbylay Ospan sizeof(struct dvb_frontend_ops)); 38823f3b48a0SAbylay Ospan } 38833f3b48a0SAbylay Ospan 38843f3b48a0SAbylay Ospan dev_info(&priv->i2c->dev, 38853f3b48a0SAbylay Ospan "%s(): attaching %s DVB-%s frontend\n", 38863f3b48a0SAbylay Ospan __func__, name, type); 3887a6dc60ffSKozlov Sergey dev_info(&priv->i2c->dev, "%s(): chip ID 0x%02x OK.\n", 3888a6dc60ffSKozlov Sergey __func__, chip_id); 3889a6dc60ffSKozlov Sergey return &priv->frontend; 3890a6dc60ffSKozlov Sergey } 3891a6dc60ffSKozlov Sergey 3892a6dc60ffSKozlov Sergey struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg, 3893a6dc60ffSKozlov Sergey struct i2c_adapter *i2c) 3894a6dc60ffSKozlov Sergey { 3895a6dc60ffSKozlov Sergey return cxd2841er_attach(cfg, i2c, SYS_DVBS); 3896a6dc60ffSKozlov Sergey } 3897a6dc60ffSKozlov Sergey EXPORT_SYMBOL(cxd2841er_attach_s); 3898a6dc60ffSKozlov Sergey 38993f3b48a0SAbylay Ospan struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg, 3900a6dc60ffSKozlov Sergey struct i2c_adapter *i2c) 3901a6dc60ffSKozlov Sergey { 39023f3b48a0SAbylay Ospan return cxd2841er_attach(cfg, i2c, 0); 3903a6dc60ffSKozlov Sergey } 39043f3b48a0SAbylay Ospan EXPORT_SYMBOL(cxd2841er_attach_t_c); 3905a6dc60ffSKozlov Sergey 3906bd336e63SMax Kellermann static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = { 3907a6dc60ffSKozlov Sergey .delsys = { SYS_DVBS, SYS_DVBS2 }, 3908a6dc60ffSKozlov Sergey .info = { 3909a6dc60ffSKozlov Sergey .name = "Sony CXD2841ER DVB-S/S2 demodulator", 3910a6dc60ffSKozlov Sergey .frequency_min = 500000, 3911a6dc60ffSKozlov Sergey .frequency_max = 2500000, 3912a6dc60ffSKozlov Sergey .frequency_stepsize = 0, 3913a6dc60ffSKozlov Sergey .symbol_rate_min = 1000000, 3914a6dc60ffSKozlov Sergey .symbol_rate_max = 45000000, 3915a6dc60ffSKozlov Sergey .symbol_rate_tolerance = 500, 3916a6dc60ffSKozlov Sergey .caps = FE_CAN_INVERSION_AUTO | 3917a6dc60ffSKozlov Sergey FE_CAN_FEC_AUTO | 3918a6dc60ffSKozlov Sergey FE_CAN_QPSK, 3919a6dc60ffSKozlov Sergey }, 3920a6dc60ffSKozlov Sergey .init = cxd2841er_init_s, 3921a6dc60ffSKozlov Sergey .sleep = cxd2841er_sleep_s, 3922a6dc60ffSKozlov Sergey .release = cxd2841er_release, 3923a6dc60ffSKozlov Sergey .set_frontend = cxd2841er_set_frontend_s, 3924a6dc60ffSKozlov Sergey .get_frontend = cxd2841er_get_frontend, 3925a6dc60ffSKozlov Sergey .read_status = cxd2841er_read_status_s, 3926a6dc60ffSKozlov Sergey .i2c_gate_ctrl = cxd2841er_i2c_gate_ctrl, 3927a6dc60ffSKozlov Sergey .get_frontend_algo = cxd2841er_get_algo, 3928a6dc60ffSKozlov Sergey .set_tone = cxd2841er_set_tone, 3929a6dc60ffSKozlov Sergey .diseqc_send_burst = cxd2841er_send_burst, 3930a6dc60ffSKozlov Sergey .diseqc_send_master_cmd = cxd2841er_send_diseqc_msg, 3931a6dc60ffSKozlov Sergey .tune = cxd2841er_tune_s 3932a6dc60ffSKozlov Sergey }; 3933a6dc60ffSKozlov Sergey 39343f3b48a0SAbylay Ospan static struct dvb_frontend_ops cxd2841er_t_c_ops = { 39353f3b48a0SAbylay Ospan .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A }, 3936a6dc60ffSKozlov Sergey .info = { 39373f3b48a0SAbylay Ospan .name = "", /* will set in attach function */ 3938a6dc60ffSKozlov Sergey .caps = FE_CAN_FEC_1_2 | 3939a6dc60ffSKozlov Sergey FE_CAN_FEC_2_3 | 3940a6dc60ffSKozlov Sergey FE_CAN_FEC_3_4 | 3941a6dc60ffSKozlov Sergey FE_CAN_FEC_5_6 | 3942a6dc60ffSKozlov Sergey FE_CAN_FEC_7_8 | 3943a6dc60ffSKozlov Sergey FE_CAN_FEC_AUTO | 3944a6dc60ffSKozlov Sergey FE_CAN_QPSK | 3945a6dc60ffSKozlov Sergey FE_CAN_QAM_16 | 3946a6dc60ffSKozlov Sergey FE_CAN_QAM_32 | 3947a6dc60ffSKozlov Sergey FE_CAN_QAM_64 | 3948a6dc60ffSKozlov Sergey FE_CAN_QAM_128 | 3949a6dc60ffSKozlov Sergey FE_CAN_QAM_256 | 3950a6dc60ffSKozlov Sergey FE_CAN_QAM_AUTO | 3951a6dc60ffSKozlov Sergey FE_CAN_TRANSMISSION_MODE_AUTO | 3952a6dc60ffSKozlov Sergey FE_CAN_GUARD_INTERVAL_AUTO | 3953a6dc60ffSKozlov Sergey FE_CAN_HIERARCHY_AUTO | 3954a6dc60ffSKozlov Sergey FE_CAN_MUTE_TS | 3955a6dc60ffSKozlov Sergey FE_CAN_2G_MODULATION, 3956a6dc60ffSKozlov Sergey .frequency_min = 42000000, 3957158f0328SDaniel Scheller .frequency_max = 1002000000, 3958158f0328SDaniel Scheller .symbol_rate_min = 870000, 3959158f0328SDaniel Scheller .symbol_rate_max = 11700000 3960a6dc60ffSKozlov Sergey }, 3961a6dc60ffSKozlov Sergey .init = cxd2841er_init_tc, 3962a6dc60ffSKozlov Sergey .sleep = cxd2841er_sleep_tc, 3963a6dc60ffSKozlov Sergey .release = cxd2841er_release, 3964a6dc60ffSKozlov Sergey .set_frontend = cxd2841er_set_frontend_tc, 3965a6dc60ffSKozlov Sergey .get_frontend = cxd2841er_get_frontend, 3966a6dc60ffSKozlov Sergey .read_status = cxd2841er_read_status_tc, 3967a6dc60ffSKozlov Sergey .tune = cxd2841er_tune_tc, 3968a6dc60ffSKozlov Sergey .i2c_gate_ctrl = cxd2841er_i2c_gate_ctrl, 3969a6dc60ffSKozlov Sergey .get_frontend_algo = cxd2841er_get_algo 3970a6dc60ffSKozlov Sergey }; 3971a6dc60ffSKozlov Sergey 397283808c23SAbylay Ospan MODULE_DESCRIPTION("Sony CXD2841ER/CXD2854ER DVB-C/C2/T/T2/S/S2 demodulator driver"); 397383808c23SAbylay Ospan MODULE_AUTHOR("Sergey Kozlov <serjk@netup.ru>, Abylay Ospan <aospan@netup.ru>"); 3974a6dc60ffSKozlov Sergey MODULE_LICENSE("GPL"); 3975