19e049346SYasunari Takiguchi // SPDX-License-Identifier: GPL-2.0 29e049346SYasunari Takiguchi /* 39e049346SYasunari Takiguchi * cxd2880_tnrdmd_dvbt2.c 49e049346SYasunari Takiguchi * Sony CXD2880 DVB-T2/T tuner + demodulator driver 59e049346SYasunari Takiguchi * control functions for DVB-T2 69e049346SYasunari Takiguchi * 79e049346SYasunari Takiguchi * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation 89e049346SYasunari Takiguchi */ 99e049346SYasunari Takiguchi 107cbc3013SMauro Carvalho Chehab #include <media/dvb_frontend.h> 119e049346SYasunari Takiguchi 129e049346SYasunari Takiguchi #include "cxd2880_tnrdmd_dvbt2.h" 139e049346SYasunari Takiguchi #include "cxd2880_tnrdmd_dvbt2_mon.h" 149e049346SYasunari Takiguchi 159e049346SYasunari Takiguchi static const struct cxd2880_reg_value tune_dmd_setting_seq1[] = { 169e049346SYasunari Takiguchi {0x00, 0x00}, {0x31, 0x02}, 179e049346SYasunari Takiguchi }; 189e049346SYasunari Takiguchi 199e049346SYasunari Takiguchi static const struct cxd2880_reg_value tune_dmd_setting_seq2[] = { 209e049346SYasunari Takiguchi {0x00, 0x04}, {0x5d, 0x0b}, 219e049346SYasunari Takiguchi }; 229e049346SYasunari Takiguchi 239e049346SYasunari Takiguchi static int x_tune_dvbt2_demod_setting(struct cxd2880_tnrdmd 249e049346SYasunari Takiguchi *tnr_dmd, 259e049346SYasunari Takiguchi enum cxd2880_dtv_bandwidth 269e049346SYasunari Takiguchi bandwidth, 279e049346SYasunari Takiguchi enum cxd2880_tnrdmd_clockmode 289e049346SYasunari Takiguchi clk_mode) 299e049346SYasunari Takiguchi { 309e049346SYasunari Takiguchi static const u8 tsif_settings[2] = { 0x01, 0x01 }; 319e049346SYasunari Takiguchi static const u8 init_settings[14] = { 329e049346SYasunari Takiguchi 0x07, 0x06, 0x01, 0xf0, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x00, 339e049346SYasunari Takiguchi 0x09, 0x9c, 0x0e, 0x4c 349e049346SYasunari Takiguchi }; 359e049346SYasunari Takiguchi static const u8 clk_mode_settings_a1[9] = { 369e049346SYasunari Takiguchi 0x52, 0x49, 0x2c, 0x51, 0x51, 0x3d, 0x15, 0x29, 0x0c 379e049346SYasunari Takiguchi }; 389e049346SYasunari Takiguchi 399e049346SYasunari Takiguchi static const u8 clk_mode_settings_b1[9] = { 409e049346SYasunari Takiguchi 0x5d, 0x55, 0x32, 0x5c, 0x5c, 0x45, 0x17, 0x2e, 0x0d 419e049346SYasunari Takiguchi }; 429e049346SYasunari Takiguchi 439e049346SYasunari Takiguchi static const u8 clk_mode_settings_c1[9] = { 449e049346SYasunari Takiguchi 0x60, 0x00, 0x34, 0x5e, 0x5e, 0x47, 0x18, 0x2f, 0x0e 459e049346SYasunari Takiguchi }; 469e049346SYasunari Takiguchi 479e049346SYasunari Takiguchi static const u8 clk_mode_settings_a2[13] = { 489e049346SYasunari Takiguchi 0x04, 0xe7, 0x94, 0x92, 0x09, 0xcf, 0x7e, 0xd0, 0x49, 499e049346SYasunari Takiguchi 0xcd, 0xcd, 0x1f, 0x5b 509e049346SYasunari Takiguchi }; 519e049346SYasunari Takiguchi 529e049346SYasunari Takiguchi static const u8 clk_mode_settings_b2[13] = { 539e049346SYasunari Takiguchi 0x05, 0x90, 0x27, 0x55, 0x0b, 0x20, 0x8f, 0xd6, 0xea, 549e049346SYasunari Takiguchi 0xc8, 0xc8, 0x23, 0x91 559e049346SYasunari Takiguchi }; 569e049346SYasunari Takiguchi 579e049346SYasunari Takiguchi static const u8 clk_mode_settings_c2[13] = { 589e049346SYasunari Takiguchi 0x05, 0xb8, 0xd8, 0x00, 0x0b, 0x72, 0x93, 0xf3, 0x00, 599e049346SYasunari Takiguchi 0xcd, 0xcd, 0x24, 0x95 609e049346SYasunari Takiguchi }; 619e049346SYasunari Takiguchi 629e049346SYasunari Takiguchi static const u8 clk_mode_settings_a3[5] = { 639e049346SYasunari Takiguchi 0x0b, 0x6a, 0xc9, 0x03, 0x33 649e049346SYasunari Takiguchi }; 659e049346SYasunari Takiguchi static const u8 clk_mode_settings_b3[5] = { 669e049346SYasunari Takiguchi 0x01, 0x02, 0xe4, 0x03, 0x39 679e049346SYasunari Takiguchi }; 689e049346SYasunari Takiguchi static const u8 clk_mode_settings_c3[5] = { 699e049346SYasunari Takiguchi 0x01, 0x02, 0xeb, 0x03, 0x3b 709e049346SYasunari Takiguchi }; 719e049346SYasunari Takiguchi 729e049346SYasunari Takiguchi static const u8 gtdofst[2] = { 0x3f, 0xff }; 739e049346SYasunari Takiguchi 749e049346SYasunari Takiguchi static const u8 bw8_gtdofst_a[2] = { 0x19, 0xd2 }; 759e049346SYasunari Takiguchi static const u8 bw8_nomi_ac[6] = { 0x15, 0x00, 0x00, 0x00, 0x00, 0x00 }; 769e049346SYasunari Takiguchi static const u8 bw8_nomi_b[6] = { 0x14, 0x6a, 0xaa, 0xaa, 0xab, 0x00 }; 779e049346SYasunari Takiguchi static const u8 bw8_sst_a[2] = { 0x06, 0x2a }; 789e049346SYasunari Takiguchi static const u8 bw8_sst_b[2] = { 0x06, 0x29 }; 799e049346SYasunari Takiguchi static const u8 bw8_sst_c[2] = { 0x06, 0x28 }; 809e049346SYasunari Takiguchi static const u8 bw8_mrc_a[9] = { 819e049346SYasunari Takiguchi 0x28, 0x00, 0x50, 0x00, 0x60, 0x00, 0x00, 0x90, 0x00 829e049346SYasunari Takiguchi }; 839e049346SYasunari Takiguchi static const u8 bw8_mrc_b[9] = { 849e049346SYasunari Takiguchi 0x2d, 0x5e, 0x5a, 0xbd, 0x6c, 0xe3, 0x00, 0xa3, 0x55 859e049346SYasunari Takiguchi }; 869e049346SYasunari Takiguchi static const u8 bw8_mrc_c[9] = { 879e049346SYasunari Takiguchi 0x2e, 0xaa, 0x5d, 0x55, 0x70, 0x00, 0x00, 0xa8, 0x00 889e049346SYasunari Takiguchi }; 899e049346SYasunari Takiguchi 909e049346SYasunari Takiguchi static const u8 bw7_nomi_ac[6] = { 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }; 919e049346SYasunari Takiguchi static const u8 bw7_nomi_b[6] = { 0x17, 0x55, 0x55, 0x55, 0x55, 0x00 }; 929e049346SYasunari Takiguchi static const u8 bw7_sst_a[2] = { 0x06, 0x23 }; 939e049346SYasunari Takiguchi static const u8 bw7_sst_b[2] = { 0x06, 0x22 }; 949e049346SYasunari Takiguchi static const u8 bw7_sst_c[2] = { 0x06, 0x21 }; 959e049346SYasunari Takiguchi static const u8 bw7_mrc_a[9] = { 969e049346SYasunari Takiguchi 0x2d, 0xb6, 0x5b, 0x6d, 0x6d, 0xb6, 0x00, 0xa4, 0x92 979e049346SYasunari Takiguchi }; 989e049346SYasunari Takiguchi static const u8 bw7_mrc_b[9] = { 999e049346SYasunari Takiguchi 0x33, 0xda, 0x67, 0xb4, 0x7c, 0x71, 0x00, 0xba, 0xaa 1009e049346SYasunari Takiguchi }; 1019e049346SYasunari Takiguchi static const u8 bw7_mrc_c[9] = { 1029e049346SYasunari Takiguchi 0x35, 0x55, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xc0, 0x00 1039e049346SYasunari Takiguchi }; 1049e049346SYasunari Takiguchi 1059e049346SYasunari Takiguchi static const u8 bw6_nomi_ac[6] = { 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00 }; 1069e049346SYasunari Takiguchi static const u8 bw6_nomi_b[6] = { 0x1b, 0x38, 0xe3, 0x8e, 0x39, 0x00 }; 1079e049346SYasunari Takiguchi static const u8 bw6_sst_a[2] = { 0x06, 0x1c }; 1089e049346SYasunari Takiguchi static const u8 bw6_sst_b[2] = { 0x06, 0x1b }; 1099e049346SYasunari Takiguchi static const u8 bw6_sst_c[2] = { 0x06, 0x1a }; 1109e049346SYasunari Takiguchi static const u8 bw6_mrc_a[9] = { 1119e049346SYasunari Takiguchi 0x35, 0x55, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xc0, 0x00 1129e049346SYasunari Takiguchi }; 1139e049346SYasunari Takiguchi static const u8 bw6_mrc_b[9] = { 1149e049346SYasunari Takiguchi 0x3c, 0x7e, 0x78, 0xfc, 0x91, 0x2f, 0x00, 0xd9, 0xc7 1159e049346SYasunari Takiguchi }; 1169e049346SYasunari Takiguchi static const u8 bw6_mrc_c[9] = { 1179e049346SYasunari Takiguchi 0x3e, 0x38, 0x7c, 0x71, 0x95, 0x55, 0x00, 0xdf, 0xff 1189e049346SYasunari Takiguchi }; 1199e049346SYasunari Takiguchi 1209e049346SYasunari Takiguchi static const u8 bw5_nomi_ac[6] = { 0x21, 0x99, 0x99, 0x99, 0x9a, 0x00 }; 1219e049346SYasunari Takiguchi static const u8 bw5_nomi_b[6] = { 0x20, 0xaa, 0xaa, 0xaa, 0xab, 0x00 }; 1229e049346SYasunari Takiguchi static const u8 bw5_sst_a[2] = { 0x06, 0x15 }; 1239e049346SYasunari Takiguchi static const u8 bw5_sst_b[2] = { 0x06, 0x15 }; 1249e049346SYasunari Takiguchi static const u8 bw5_sst_c[2] = { 0x06, 0x14 }; 1259e049346SYasunari Takiguchi static const u8 bw5_mrc_a[9] = { 1269e049346SYasunari Takiguchi 0x40, 0x00, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xe6, 0x66 1279e049346SYasunari Takiguchi }; 1289e049346SYasunari Takiguchi static const u8 bw5_mrc_b[9] = { 1299e049346SYasunari Takiguchi 0x48, 0x97, 0x78, 0xfc, 0x91, 0x2f, 0x01, 0x05, 0x55 1309e049346SYasunari Takiguchi }; 1319e049346SYasunari Takiguchi static const u8 bw5_mrc_c[9] = { 1329e049346SYasunari Takiguchi 0x4a, 0xaa, 0x7c, 0x71, 0x95, 0x55, 0x01, 0x0c, 0xcc 1339e049346SYasunari Takiguchi }; 1349e049346SYasunari Takiguchi 1359e049346SYasunari Takiguchi static const u8 bw1_7_nomi_a[6] = { 1369e049346SYasunari Takiguchi 0x68, 0x0f, 0xa2, 0x32, 0xcf, 0x03 1379e049346SYasunari Takiguchi }; 1389e049346SYasunari Takiguchi static const u8 bw1_7_nomi_c[6] = { 1399e049346SYasunari Takiguchi 0x68, 0x0f, 0xa2, 0x32, 0xcf, 0x03 1409e049346SYasunari Takiguchi }; 1419e049346SYasunari Takiguchi static const u8 bw1_7_nomi_b[6] = { 1429e049346SYasunari Takiguchi 0x65, 0x2b, 0xa4, 0xcd, 0xd8, 0x03 1439e049346SYasunari Takiguchi }; 1449e049346SYasunari Takiguchi static const u8 bw1_7_sst_a[2] = { 0x06, 0x0c }; 1459e049346SYasunari Takiguchi static const u8 bw1_7_sst_b[2] = { 0x06, 0x0c }; 1469e049346SYasunari Takiguchi static const u8 bw1_7_sst_c[2] = { 0x06, 0x0b }; 1479e049346SYasunari Takiguchi static const u8 bw1_7_mrc_a[9] = { 1489e049346SYasunari Takiguchi 0x40, 0x00, 0x6a, 0xaa, 0x80, 0x00, 0x02, 0xc9, 0x8f 1499e049346SYasunari Takiguchi }; 1509e049346SYasunari Takiguchi static const u8 bw1_7_mrc_b[9] = { 1519e049346SYasunari Takiguchi 0x48, 0x97, 0x78, 0xfc, 0x91, 0x2f, 0x03, 0x29, 0x5d 1529e049346SYasunari Takiguchi }; 1539e049346SYasunari Takiguchi static const u8 bw1_7_mrc_c[9] = { 1549e049346SYasunari Takiguchi 0x4a, 0xaa, 0x7c, 0x71, 0x95, 0x55, 0x03, 0x40, 0x7d 1559e049346SYasunari Takiguchi }; 1569e049346SYasunari Takiguchi 1579e049346SYasunari Takiguchi const u8 *data = NULL; 1589e049346SYasunari Takiguchi const u8 *data2 = NULL; 1599e049346SYasunari Takiguchi const u8 *data3 = NULL; 1609e049346SYasunari Takiguchi int ret; 1619e049346SYasunari Takiguchi 1629e049346SYasunari Takiguchi if (!tnr_dmd) 1639e049346SYasunari Takiguchi return -EINVAL; 1649e049346SYasunari Takiguchi 1659e049346SYasunari Takiguchi ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1669e049346SYasunari Takiguchi CXD2880_IO_TGT_SYS, 1679e049346SYasunari Takiguchi tune_dmd_setting_seq1, 1689e049346SYasunari Takiguchi ARRAY_SIZE(tune_dmd_setting_seq1)); 1699e049346SYasunari Takiguchi if (ret) 1709e049346SYasunari Takiguchi return ret; 1719e049346SYasunari Takiguchi 1729e049346SYasunari Takiguchi ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1739e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 1749e049346SYasunari Takiguchi tune_dmd_setting_seq2, 1759e049346SYasunari Takiguchi ARRAY_SIZE(tune_dmd_setting_seq2)); 1769e049346SYasunari Takiguchi if (ret) 1779e049346SYasunari Takiguchi return ret; 1789e049346SYasunari Takiguchi 1799e049346SYasunari Takiguchi if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) { 1809e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1819e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 1829e049346SYasunari Takiguchi 0x00, 0x00); 1839e049346SYasunari Takiguchi if (ret) 1849e049346SYasunari Takiguchi return ret; 1859e049346SYasunari Takiguchi 1869e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 1879e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 1889e049346SYasunari Takiguchi 0xce, tsif_settings, 2); 1899e049346SYasunari Takiguchi if (ret) 1909e049346SYasunari Takiguchi return ret; 1919e049346SYasunari Takiguchi } 1929e049346SYasunari Takiguchi 1939e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1949e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 1959e049346SYasunari Takiguchi 0x00, 0x20); 1969e049346SYasunari Takiguchi if (ret) 1979e049346SYasunari Takiguchi return ret; 1989e049346SYasunari Takiguchi 1999e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2009e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2019e049346SYasunari Takiguchi 0x8a, init_settings[0]); 2029e049346SYasunari Takiguchi if (ret) 2039e049346SYasunari Takiguchi return ret; 2049e049346SYasunari Takiguchi 2059e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2069e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2079e049346SYasunari Takiguchi 0x90, init_settings[1]); 2089e049346SYasunari Takiguchi if (ret) 2099e049346SYasunari Takiguchi return ret; 2109e049346SYasunari Takiguchi 2119e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2129e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2139e049346SYasunari Takiguchi 0x00, 0x25); 2149e049346SYasunari Takiguchi if (ret) 2159e049346SYasunari Takiguchi return ret; 2169e049346SYasunari Takiguchi 2179e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 2189e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2199e049346SYasunari Takiguchi 0xf0, &init_settings[2], 2); 2209e049346SYasunari Takiguchi if (ret) 2219e049346SYasunari Takiguchi return ret; 2229e049346SYasunari Takiguchi 2239e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2249e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2259e049346SYasunari Takiguchi 0x00, 0x2a); 2269e049346SYasunari Takiguchi if (ret) 2279e049346SYasunari Takiguchi return ret; 2289e049346SYasunari Takiguchi 2299e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2309e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2319e049346SYasunari Takiguchi 0xdc, init_settings[4]); 2329e049346SYasunari Takiguchi if (ret) 2339e049346SYasunari Takiguchi return ret; 2349e049346SYasunari Takiguchi 2359e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2369e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2379e049346SYasunari Takiguchi 0xde, init_settings[5]); 2389e049346SYasunari Takiguchi if (ret) 2399e049346SYasunari Takiguchi return ret; 2409e049346SYasunari Takiguchi 2419e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2429e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2439e049346SYasunari Takiguchi 0x00, 0x2d); 2449e049346SYasunari Takiguchi if (ret) 2459e049346SYasunari Takiguchi return ret; 2469e049346SYasunari Takiguchi 2479e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 2489e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2499e049346SYasunari Takiguchi 0x73, &init_settings[6], 4); 2509e049346SYasunari Takiguchi if (ret) 2519e049346SYasunari Takiguchi return ret; 2529e049346SYasunari Takiguchi 2539e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 2549e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2559e049346SYasunari Takiguchi 0x8f, &init_settings[10], 4); 2569e049346SYasunari Takiguchi if (ret) 2579e049346SYasunari Takiguchi return ret; 2589e049346SYasunari Takiguchi 2599e049346SYasunari Takiguchi switch (clk_mode) { 2609e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 2619e049346SYasunari Takiguchi data = clk_mode_settings_a1; 2629e049346SYasunari Takiguchi data2 = clk_mode_settings_a2; 2639e049346SYasunari Takiguchi data3 = clk_mode_settings_a3; 2649e049346SYasunari Takiguchi break; 2659e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 2669e049346SYasunari Takiguchi data = clk_mode_settings_b1; 2679e049346SYasunari Takiguchi data2 = clk_mode_settings_b2; 2689e049346SYasunari Takiguchi data3 = clk_mode_settings_b3; 2699e049346SYasunari Takiguchi break; 2709e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 2719e049346SYasunari Takiguchi data = clk_mode_settings_c1; 2729e049346SYasunari Takiguchi data2 = clk_mode_settings_c2; 2739e049346SYasunari Takiguchi data3 = clk_mode_settings_c3; 2749e049346SYasunari Takiguchi break; 2759e049346SYasunari Takiguchi default: 2769e049346SYasunari Takiguchi return -EINVAL; 2779e049346SYasunari Takiguchi } 2789e049346SYasunari Takiguchi 2799e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2809e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2819e049346SYasunari Takiguchi 0x00, 0x04); 2829e049346SYasunari Takiguchi if (ret) 2839e049346SYasunari Takiguchi return ret; 2849e049346SYasunari Takiguchi 2859e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 2869e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2879e049346SYasunari Takiguchi 0x1d, &data[0], 3); 2889e049346SYasunari Takiguchi if (ret) 2899e049346SYasunari Takiguchi return ret; 2909e049346SYasunari Takiguchi 2919e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2929e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2939e049346SYasunari Takiguchi 0x22, data[3]); 2949e049346SYasunari Takiguchi if (ret) 2959e049346SYasunari Takiguchi return ret; 2969e049346SYasunari Takiguchi 2979e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2989e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 2999e049346SYasunari Takiguchi 0x24, data[4]); 3009e049346SYasunari Takiguchi if (ret) 3019e049346SYasunari Takiguchi return ret; 3029e049346SYasunari Takiguchi 3039e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3049e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3059e049346SYasunari Takiguchi 0x26, data[5]); 3069e049346SYasunari Takiguchi if (ret) 3079e049346SYasunari Takiguchi return ret; 3089e049346SYasunari Takiguchi 3099e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 3109e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3119e049346SYasunari Takiguchi 0x29, &data[6], 2); 3129e049346SYasunari Takiguchi if (ret) 3139e049346SYasunari Takiguchi return ret; 3149e049346SYasunari Takiguchi 3159e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3169e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3179e049346SYasunari Takiguchi 0x2d, data[8]); 3189e049346SYasunari Takiguchi if (ret) 3199e049346SYasunari Takiguchi return ret; 3209e049346SYasunari Takiguchi 3219e049346SYasunari Takiguchi if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) { 3229e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 3239e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3249e049346SYasunari Takiguchi 0x2e, &data2[0], 6); 3259e049346SYasunari Takiguchi if (ret) 3269e049346SYasunari Takiguchi return ret; 3279e049346SYasunari Takiguchi 3289e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 3299e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3309e049346SYasunari Takiguchi 0x35, &data2[6], 7); 3319e049346SYasunari Takiguchi if (ret) 3329e049346SYasunari Takiguchi return ret; 3339e049346SYasunari Takiguchi } 3349e049346SYasunari Takiguchi 3359e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 3369e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3379e049346SYasunari Takiguchi 0x3c, &data3[0], 2); 3389e049346SYasunari Takiguchi if (ret) 3399e049346SYasunari Takiguchi return ret; 3409e049346SYasunari Takiguchi 3419e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 3429e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3439e049346SYasunari Takiguchi 0x56, &data3[2], 3); 3449e049346SYasunari Takiguchi if (ret) 3459e049346SYasunari Takiguchi return ret; 3469e049346SYasunari Takiguchi 3479e049346SYasunari Takiguchi switch (bandwidth) { 3489e049346SYasunari Takiguchi case CXD2880_DTV_BW_8_MHZ: 3499e049346SYasunari Takiguchi switch (clk_mode) { 3509e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 3519e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 3529e049346SYasunari Takiguchi data = bw8_nomi_ac; 3539e049346SYasunari Takiguchi break; 3549e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 3559e049346SYasunari Takiguchi data = bw8_nomi_b; 3569e049346SYasunari Takiguchi break; 3579e049346SYasunari Takiguchi default: 3589e049346SYasunari Takiguchi return -EINVAL; 3599e049346SYasunari Takiguchi } 3609e049346SYasunari Takiguchi 3619e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 3629e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3639e049346SYasunari Takiguchi 0x10, data, 6); 3649e049346SYasunari Takiguchi if (ret) 3659e049346SYasunari Takiguchi return ret; 3669e049346SYasunari Takiguchi 3679e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3689e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3699e049346SYasunari Takiguchi 0x4a, 0x00); 3709e049346SYasunari Takiguchi if (ret) 3719e049346SYasunari Takiguchi return ret; 3729e049346SYasunari Takiguchi 3739e049346SYasunari Takiguchi switch (clk_mode) { 3749e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 3759e049346SYasunari Takiguchi data = bw8_gtdofst_a; 3769e049346SYasunari Takiguchi break; 3779e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 3789e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 3799e049346SYasunari Takiguchi data = gtdofst; 3809e049346SYasunari Takiguchi break; 3819e049346SYasunari Takiguchi default: 3829e049346SYasunari Takiguchi return -EINVAL; 3839e049346SYasunari Takiguchi } 3849e049346SYasunari Takiguchi 3859e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 3869e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 3879e049346SYasunari Takiguchi 0x19, data, 2); 3889e049346SYasunari Takiguchi if (ret) 3899e049346SYasunari Takiguchi return ret; 3909e049346SYasunari Takiguchi 3919e049346SYasunari Takiguchi switch (clk_mode) { 3929e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 3939e049346SYasunari Takiguchi data = bw8_sst_a; 3949e049346SYasunari Takiguchi break; 3959e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 3969e049346SYasunari Takiguchi data = bw8_sst_b; 3979e049346SYasunari Takiguchi break; 3989e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 3999e049346SYasunari Takiguchi data = bw8_sst_c; 4009e049346SYasunari Takiguchi break; 4019e049346SYasunari Takiguchi default: 4029e049346SYasunari Takiguchi return -EINVAL; 4039e049346SYasunari Takiguchi } 4049e049346SYasunari Takiguchi 4059e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 4069e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 4079e049346SYasunari Takiguchi 0x1b, data, 2); 4089e049346SYasunari Takiguchi if (ret) 4099e049346SYasunari Takiguchi return ret; 4109e049346SYasunari Takiguchi 4119e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 4129e049346SYasunari Takiguchi switch (clk_mode) { 4139e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 4149e049346SYasunari Takiguchi data = bw8_mrc_a; 4159e049346SYasunari Takiguchi break; 4169e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 4179e049346SYasunari Takiguchi data = bw8_mrc_b; 4189e049346SYasunari Takiguchi break; 4199e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 4209e049346SYasunari Takiguchi data = bw8_mrc_c; 4219e049346SYasunari Takiguchi break; 4229e049346SYasunari Takiguchi default: 4239e049346SYasunari Takiguchi return -EINVAL; 4249e049346SYasunari Takiguchi } 4259e049346SYasunari Takiguchi 4269e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 4279e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 4289e049346SYasunari Takiguchi 0x4b, data, 9); 4299e049346SYasunari Takiguchi if (ret) 4309e049346SYasunari Takiguchi return ret; 4319e049346SYasunari Takiguchi } 4329e049346SYasunari Takiguchi break; 4339e049346SYasunari Takiguchi 4349e049346SYasunari Takiguchi case CXD2880_DTV_BW_7_MHZ: 4359e049346SYasunari Takiguchi switch (clk_mode) { 4369e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 4379e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 4389e049346SYasunari Takiguchi data = bw7_nomi_ac; 4399e049346SYasunari Takiguchi break; 4409e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 4419e049346SYasunari Takiguchi data = bw7_nomi_b; 4429e049346SYasunari Takiguchi break; 4439e049346SYasunari Takiguchi default: 4449e049346SYasunari Takiguchi return -EINVAL; 4459e049346SYasunari Takiguchi } 4469e049346SYasunari Takiguchi 4479e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 4489e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 4499e049346SYasunari Takiguchi 0x10, data, 6); 4509e049346SYasunari Takiguchi if (ret) 4519e049346SYasunari Takiguchi return ret; 4529e049346SYasunari Takiguchi 4539e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 4549e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 4559e049346SYasunari Takiguchi 0x4a, 0x02); 4569e049346SYasunari Takiguchi if (ret) 4579e049346SYasunari Takiguchi return ret; 4589e049346SYasunari Takiguchi 4599e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 4609e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 4619e049346SYasunari Takiguchi 0x19, gtdofst, 2); 4629e049346SYasunari Takiguchi if (ret) 4639e049346SYasunari Takiguchi return ret; 4649e049346SYasunari Takiguchi 4659e049346SYasunari Takiguchi switch (clk_mode) { 4669e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 4679e049346SYasunari Takiguchi data = bw7_sst_a; 4689e049346SYasunari Takiguchi break; 4699e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 4709e049346SYasunari Takiguchi data = bw7_sst_b; 4719e049346SYasunari Takiguchi break; 4729e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 4739e049346SYasunari Takiguchi data = bw7_sst_c; 4749e049346SYasunari Takiguchi break; 4759e049346SYasunari Takiguchi default: 4769e049346SYasunari Takiguchi return -EINVAL; 4779e049346SYasunari Takiguchi } 4789e049346SYasunari Takiguchi 4799e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 4809e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 4819e049346SYasunari Takiguchi 0x1b, data, 2); 4829e049346SYasunari Takiguchi if (ret) 4839e049346SYasunari Takiguchi return ret; 4849e049346SYasunari Takiguchi 4859e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 4869e049346SYasunari Takiguchi switch (clk_mode) { 4879e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 4889e049346SYasunari Takiguchi data = bw7_mrc_a; 4899e049346SYasunari Takiguchi break; 4909e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 4919e049346SYasunari Takiguchi data = bw7_mrc_b; 4929e049346SYasunari Takiguchi break; 4939e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 4949e049346SYasunari Takiguchi data = bw7_mrc_c; 4959e049346SYasunari Takiguchi break; 4969e049346SYasunari Takiguchi default: 4979e049346SYasunari Takiguchi return -EINVAL; 4989e049346SYasunari Takiguchi } 4999e049346SYasunari Takiguchi 5009e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 5019e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 5029e049346SYasunari Takiguchi 0x4b, data, 9); 5039e049346SYasunari Takiguchi if (ret) 5049e049346SYasunari Takiguchi return ret; 5059e049346SYasunari Takiguchi } 5069e049346SYasunari Takiguchi break; 5079e049346SYasunari Takiguchi 5089e049346SYasunari Takiguchi case CXD2880_DTV_BW_6_MHZ: 5099e049346SYasunari Takiguchi switch (clk_mode) { 5109e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 5119e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 5129e049346SYasunari Takiguchi data = bw6_nomi_ac; 5139e049346SYasunari Takiguchi break; 5149e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 5159e049346SYasunari Takiguchi data = bw6_nomi_b; 5169e049346SYasunari Takiguchi break; 5179e049346SYasunari Takiguchi default: 5189e049346SYasunari Takiguchi return -EINVAL; 5199e049346SYasunari Takiguchi } 5209e049346SYasunari Takiguchi 5219e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 5229e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 5239e049346SYasunari Takiguchi 0x10, data, 6); 5249e049346SYasunari Takiguchi if (ret) 5259e049346SYasunari Takiguchi return ret; 5269e049346SYasunari Takiguchi 5279e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 5289e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 5299e049346SYasunari Takiguchi 0x4a, 0x04); 5309e049346SYasunari Takiguchi if (ret) 5319e049346SYasunari Takiguchi return ret; 5329e049346SYasunari Takiguchi 5339e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 5349e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 5359e049346SYasunari Takiguchi 0x19, gtdofst, 2); 5369e049346SYasunari Takiguchi if (ret) 5379e049346SYasunari Takiguchi return ret; 5389e049346SYasunari Takiguchi 5399e049346SYasunari Takiguchi switch (clk_mode) { 5409e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 5419e049346SYasunari Takiguchi data = bw6_sst_a; 5429e049346SYasunari Takiguchi break; 5439e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 5449e049346SYasunari Takiguchi data = bw6_sst_b; 5459e049346SYasunari Takiguchi break; 5469e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 5479e049346SYasunari Takiguchi data = bw6_sst_c; 5489e049346SYasunari Takiguchi break; 5499e049346SYasunari Takiguchi default: 5509e049346SYasunari Takiguchi return -EINVAL; 5519e049346SYasunari Takiguchi } 5529e049346SYasunari Takiguchi 5539e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 5549e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 5559e049346SYasunari Takiguchi 0x1b, data, 2); 5569e049346SYasunari Takiguchi if (ret) 5579e049346SYasunari Takiguchi return ret; 5589e049346SYasunari Takiguchi 5599e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 5609e049346SYasunari Takiguchi switch (clk_mode) { 5619e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 5629e049346SYasunari Takiguchi data = bw6_mrc_a; 5639e049346SYasunari Takiguchi break; 5649e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 5659e049346SYasunari Takiguchi data = bw6_mrc_b; 5669e049346SYasunari Takiguchi break; 5679e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 5689e049346SYasunari Takiguchi data = bw6_mrc_c; 5699e049346SYasunari Takiguchi break; 5709e049346SYasunari Takiguchi default: 5719e049346SYasunari Takiguchi return -EINVAL; 5729e049346SYasunari Takiguchi } 5739e049346SYasunari Takiguchi 5749e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 5759e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 5769e049346SYasunari Takiguchi 0x4b, data, 9); 5779e049346SYasunari Takiguchi if (ret) 5789e049346SYasunari Takiguchi return ret; 5799e049346SYasunari Takiguchi } 5809e049346SYasunari Takiguchi break; 5819e049346SYasunari Takiguchi 5829e049346SYasunari Takiguchi case CXD2880_DTV_BW_5_MHZ: 5839e049346SYasunari Takiguchi switch (clk_mode) { 5849e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 5859e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 5869e049346SYasunari Takiguchi data = bw5_nomi_ac; 5879e049346SYasunari Takiguchi break; 5889e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 5899e049346SYasunari Takiguchi data = bw5_nomi_b; 5909e049346SYasunari Takiguchi break; 5919e049346SYasunari Takiguchi default: 5929e049346SYasunari Takiguchi return -EINVAL; 5939e049346SYasunari Takiguchi } 5949e049346SYasunari Takiguchi 5959e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 5969e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 5979e049346SYasunari Takiguchi 0x10, data, 6); 5989e049346SYasunari Takiguchi if (ret) 5999e049346SYasunari Takiguchi return ret; 6009e049346SYasunari Takiguchi 6019e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 6029e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 6039e049346SYasunari Takiguchi 0x4a, 0x06); 6049e049346SYasunari Takiguchi if (ret) 6059e049346SYasunari Takiguchi return ret; 6069e049346SYasunari Takiguchi 6079e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 6089e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 6099e049346SYasunari Takiguchi 0x19, gtdofst, 2); 6109e049346SYasunari Takiguchi if (ret) 6119e049346SYasunari Takiguchi return ret; 6129e049346SYasunari Takiguchi 6139e049346SYasunari Takiguchi switch (clk_mode) { 6149e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 6159e049346SYasunari Takiguchi data = bw5_sst_a; 6169e049346SYasunari Takiguchi break; 6179e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 6189e049346SYasunari Takiguchi data = bw5_sst_b; 6199e049346SYasunari Takiguchi break; 6209e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 6219e049346SYasunari Takiguchi data = bw5_sst_c; 6229e049346SYasunari Takiguchi break; 6239e049346SYasunari Takiguchi default: 6249e049346SYasunari Takiguchi return -EINVAL; 6259e049346SYasunari Takiguchi } 6269e049346SYasunari Takiguchi 6279e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 6289e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 6299e049346SYasunari Takiguchi 0x1b, data, 2); 6309e049346SYasunari Takiguchi if (ret) 6319e049346SYasunari Takiguchi return ret; 6329e049346SYasunari Takiguchi 6339e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 6349e049346SYasunari Takiguchi switch (clk_mode) { 6359e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 6369e049346SYasunari Takiguchi data = bw5_mrc_a; 6379e049346SYasunari Takiguchi break; 6389e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 6399e049346SYasunari Takiguchi data = bw5_mrc_b; 6409e049346SYasunari Takiguchi break; 6419e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 6429e049346SYasunari Takiguchi data = bw5_mrc_c; 6439e049346SYasunari Takiguchi break; 6449e049346SYasunari Takiguchi default: 6459e049346SYasunari Takiguchi return -EINVAL; 6469e049346SYasunari Takiguchi } 6479e049346SYasunari Takiguchi 6489e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 6499e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 6509e049346SYasunari Takiguchi 0x4b, data, 9); 6519e049346SYasunari Takiguchi if (ret) 6529e049346SYasunari Takiguchi return ret; 6539e049346SYasunari Takiguchi } 6549e049346SYasunari Takiguchi break; 6559e049346SYasunari Takiguchi 6569e049346SYasunari Takiguchi case CXD2880_DTV_BW_1_7_MHZ: 6579e049346SYasunari Takiguchi 6589e049346SYasunari Takiguchi switch (clk_mode) { 6599e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 6609e049346SYasunari Takiguchi data = bw1_7_nomi_a; 6619e049346SYasunari Takiguchi break; 6629e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 6639e049346SYasunari Takiguchi data = bw1_7_nomi_c; 6649e049346SYasunari Takiguchi break; 6659e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 6669e049346SYasunari Takiguchi data = bw1_7_nomi_b; 6679e049346SYasunari Takiguchi break; 6689e049346SYasunari Takiguchi default: 6699e049346SYasunari Takiguchi return -EINVAL; 6709e049346SYasunari Takiguchi } 6719e049346SYasunari Takiguchi 6729e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 6739e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 6749e049346SYasunari Takiguchi 0x10, data, 6); 6759e049346SYasunari Takiguchi if (ret) 6769e049346SYasunari Takiguchi return ret; 6779e049346SYasunari Takiguchi 6789e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 6799e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 6809e049346SYasunari Takiguchi 0x4a, 0x03); 6819e049346SYasunari Takiguchi if (ret) 6829e049346SYasunari Takiguchi return ret; 6839e049346SYasunari Takiguchi 6849e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 6859e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 6869e049346SYasunari Takiguchi 0x19, gtdofst, 2); 6879e049346SYasunari Takiguchi if (ret) 6889e049346SYasunari Takiguchi return ret; 6899e049346SYasunari Takiguchi 6909e049346SYasunari Takiguchi switch (clk_mode) { 6919e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 6929e049346SYasunari Takiguchi data = bw1_7_sst_a; 6939e049346SYasunari Takiguchi break; 6949e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 6959e049346SYasunari Takiguchi data = bw1_7_sst_b; 6969e049346SYasunari Takiguchi break; 6979e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 6989e049346SYasunari Takiguchi data = bw1_7_sst_c; 6999e049346SYasunari Takiguchi break; 7009e049346SYasunari Takiguchi default: 7019e049346SYasunari Takiguchi return -EINVAL; 7029e049346SYasunari Takiguchi } 7039e049346SYasunari Takiguchi 7049e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 7059e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 7069e049346SYasunari Takiguchi 0x1b, data, 2); 7079e049346SYasunari Takiguchi if (ret) 7089e049346SYasunari Takiguchi return ret; 7099e049346SYasunari Takiguchi 7109e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 7119e049346SYasunari Takiguchi switch (clk_mode) { 7129e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 7139e049346SYasunari Takiguchi data = bw1_7_mrc_a; 7149e049346SYasunari Takiguchi break; 7159e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 7169e049346SYasunari Takiguchi data = bw1_7_mrc_b; 7179e049346SYasunari Takiguchi break; 7189e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 7199e049346SYasunari Takiguchi data = bw1_7_mrc_c; 7209e049346SYasunari Takiguchi break; 7219e049346SYasunari Takiguchi default: 7229e049346SYasunari Takiguchi return -EINVAL; 7239e049346SYasunari Takiguchi } 7249e049346SYasunari Takiguchi 7259e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 7269e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 7279e049346SYasunari Takiguchi 0x4b, data, 9); 7289e049346SYasunari Takiguchi if (ret) 7299e049346SYasunari Takiguchi return ret; 7309e049346SYasunari Takiguchi } 7319e049346SYasunari Takiguchi break; 7329e049346SYasunari Takiguchi 7339e049346SYasunari Takiguchi default: 7349e049346SYasunari Takiguchi return -EINVAL; 7359e049346SYasunari Takiguchi } 7369e049346SYasunari Takiguchi 7379e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 7389e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 7399e049346SYasunari Takiguchi 0x00, 0x00); 7409e049346SYasunari Takiguchi if (ret) 7419e049346SYasunari Takiguchi return ret; 7429e049346SYasunari Takiguchi 7439e049346SYasunari Takiguchi return tnr_dmd->io->write_reg(tnr_dmd->io, 7449e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 7459e049346SYasunari Takiguchi 0xfd, 0x01); 7469e049346SYasunari Takiguchi } 7479e049346SYasunari Takiguchi 7489e049346SYasunari Takiguchi static int x_sleep_dvbt2_demod_setting(struct cxd2880_tnrdmd 7499e049346SYasunari Takiguchi *tnr_dmd) 7509e049346SYasunari Takiguchi { 7519e049346SYasunari Takiguchi static const u8 difint_clip[] = { 7529e049346SYasunari Takiguchi 0, 1, 0, 2, 0, 4, 0, 8, 0, 16, 0, 32 7539e049346SYasunari Takiguchi }; 7549e049346SYasunari Takiguchi int ret = 0; 7559e049346SYasunari Takiguchi 7569e049346SYasunari Takiguchi if (!tnr_dmd) 7579e049346SYasunari Takiguchi return -EINVAL; 7589e049346SYasunari Takiguchi 7599e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 7609e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 7619e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 7629e049346SYasunari Takiguchi 0x00, 0x1d); 7639e049346SYasunari Takiguchi if (ret) 7649e049346SYasunari Takiguchi return ret; 7659e049346SYasunari Takiguchi 7669e049346SYasunari Takiguchi ret = tnr_dmd->io->write_regs(tnr_dmd->io, 7679e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 7689e049346SYasunari Takiguchi 0x47, difint_clip, 12); 7699e049346SYasunari Takiguchi } 7709e049346SYasunari Takiguchi 7719e049346SYasunari Takiguchi return ret; 7729e049346SYasunari Takiguchi } 7739e049346SYasunari Takiguchi 7749e049346SYasunari Takiguchi static int dvbt2_set_profile(struct cxd2880_tnrdmd *tnr_dmd, 7759e049346SYasunari Takiguchi enum cxd2880_dvbt2_profile profile) 7769e049346SYasunari Takiguchi { 7779e049346SYasunari Takiguchi u8 t2_mode_tune_mode = 0; 7789e049346SYasunari Takiguchi u8 seq_not2_dtime = 0; 7799e049346SYasunari Takiguchi u8 dtime1 = 0; 7809e049346SYasunari Takiguchi u8 dtime2 = 0; 7819e049346SYasunari Takiguchi int ret; 7829e049346SYasunari Takiguchi 7839e049346SYasunari Takiguchi if (!tnr_dmd) 7849e049346SYasunari Takiguchi return -EINVAL; 7859e049346SYasunari Takiguchi 7869e049346SYasunari Takiguchi switch (tnr_dmd->clk_mode) { 7879e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_A: 7889e049346SYasunari Takiguchi dtime1 = 0x27; 7899e049346SYasunari Takiguchi dtime2 = 0x0c; 7909e049346SYasunari Takiguchi break; 7919e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_B: 7929e049346SYasunari Takiguchi dtime1 = 0x2c; 7939e049346SYasunari Takiguchi dtime2 = 0x0d; 7949e049346SYasunari Takiguchi break; 7959e049346SYasunari Takiguchi case CXD2880_TNRDMD_CLOCKMODE_C: 7969e049346SYasunari Takiguchi dtime1 = 0x2e; 7979e049346SYasunari Takiguchi dtime2 = 0x0e; 7989e049346SYasunari Takiguchi break; 7999e049346SYasunari Takiguchi default: 8009e049346SYasunari Takiguchi return -EINVAL; 8019e049346SYasunari Takiguchi } 8029e049346SYasunari Takiguchi 8039e049346SYasunari Takiguchi switch (profile) { 8049e049346SYasunari Takiguchi case CXD2880_DVBT2_PROFILE_BASE: 8059e049346SYasunari Takiguchi t2_mode_tune_mode = 0x01; 8069e049346SYasunari Takiguchi seq_not2_dtime = dtime2; 8079e049346SYasunari Takiguchi break; 8089e049346SYasunari Takiguchi 8099e049346SYasunari Takiguchi case CXD2880_DVBT2_PROFILE_LITE: 8109e049346SYasunari Takiguchi t2_mode_tune_mode = 0x05; 8119e049346SYasunari Takiguchi seq_not2_dtime = dtime1; 8129e049346SYasunari Takiguchi break; 8139e049346SYasunari Takiguchi 8149e049346SYasunari Takiguchi case CXD2880_DVBT2_PROFILE_ANY: 8159e049346SYasunari Takiguchi t2_mode_tune_mode = 0x00; 8169e049346SYasunari Takiguchi seq_not2_dtime = dtime1; 8179e049346SYasunari Takiguchi break; 8189e049346SYasunari Takiguchi 8199e049346SYasunari Takiguchi default: 8209e049346SYasunari Takiguchi return -EINVAL; 8219e049346SYasunari Takiguchi } 8229e049346SYasunari Takiguchi 8239e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 8249e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 8259e049346SYasunari Takiguchi 0x00, 0x2e); 8269e049346SYasunari Takiguchi if (ret) 8279e049346SYasunari Takiguchi return ret; 8289e049346SYasunari Takiguchi 8299e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 8309e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 8319e049346SYasunari Takiguchi 0x10, t2_mode_tune_mode); 8329e049346SYasunari Takiguchi if (ret) 8339e049346SYasunari Takiguchi return ret; 8349e049346SYasunari Takiguchi 8359e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 8369e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 8379e049346SYasunari Takiguchi 0x00, 0x04); 8389e049346SYasunari Takiguchi if (ret) 8399e049346SYasunari Takiguchi return ret; 8409e049346SYasunari Takiguchi 8419e049346SYasunari Takiguchi return tnr_dmd->io->write_reg(tnr_dmd->io, 8429e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 8439e049346SYasunari Takiguchi 0x2c, seq_not2_dtime); 8449e049346SYasunari Takiguchi } 8459e049346SYasunari Takiguchi 8469e049346SYasunari Takiguchi int cxd2880_tnrdmd_dvbt2_tune1(struct cxd2880_tnrdmd *tnr_dmd, 8479e049346SYasunari Takiguchi struct cxd2880_dvbt2_tune_param 8489e049346SYasunari Takiguchi *tune_param) 8499e049346SYasunari Takiguchi { 8509e049346SYasunari Takiguchi int ret; 8519e049346SYasunari Takiguchi 8529e049346SYasunari Takiguchi if (!tnr_dmd || !tune_param) 8539e049346SYasunari Takiguchi return -EINVAL; 8549e049346SYasunari Takiguchi 8559e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 8569e049346SYasunari Takiguchi return -EINVAL; 8579e049346SYasunari Takiguchi 8589e049346SYasunari Takiguchi if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 8599e049346SYasunari Takiguchi tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 8609e049346SYasunari Takiguchi return -EINVAL; 8619e049346SYasunari Takiguchi 8629e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN && 8639e049346SYasunari Takiguchi tune_param->profile == CXD2880_DVBT2_PROFILE_ANY) 8649e049346SYasunari Takiguchi return -ENOTTY; 8659e049346SYasunari Takiguchi 8669e049346SYasunari Takiguchi ret = 8679e049346SYasunari Takiguchi cxd2880_tnrdmd_common_tune_setting1(tnr_dmd, CXD2880_DTV_SYS_DVBT2, 8689e049346SYasunari Takiguchi tune_param->center_freq_khz, 8699e049346SYasunari Takiguchi tune_param->bandwidth, 0, 0); 8709e049346SYasunari Takiguchi if (ret) 8719e049346SYasunari Takiguchi return ret; 8729e049346SYasunari Takiguchi 8739e049346SYasunari Takiguchi ret = 8749e049346SYasunari Takiguchi x_tune_dvbt2_demod_setting(tnr_dmd, tune_param->bandwidth, 8759e049346SYasunari Takiguchi tnr_dmd->clk_mode); 8769e049346SYasunari Takiguchi if (ret) 8779e049346SYasunari Takiguchi return ret; 8789e049346SYasunari Takiguchi 8799e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 8809e049346SYasunari Takiguchi ret = 8819e049346SYasunari Takiguchi x_tune_dvbt2_demod_setting(tnr_dmd->diver_sub, 8829e049346SYasunari Takiguchi tune_param->bandwidth, 8839e049346SYasunari Takiguchi tnr_dmd->diver_sub->clk_mode); 8849e049346SYasunari Takiguchi if (ret) 8859e049346SYasunari Takiguchi return ret; 8869e049346SYasunari Takiguchi } 8879e049346SYasunari Takiguchi 8889e049346SYasunari Takiguchi ret = dvbt2_set_profile(tnr_dmd, tune_param->profile); 8899e049346SYasunari Takiguchi if (ret) 8909e049346SYasunari Takiguchi return ret; 8919e049346SYasunari Takiguchi 8929e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 8939e049346SYasunari Takiguchi ret = 8949e049346SYasunari Takiguchi dvbt2_set_profile(tnr_dmd->diver_sub, tune_param->profile); 8959e049346SYasunari Takiguchi if (ret) 8969e049346SYasunari Takiguchi return ret; 8979e049346SYasunari Takiguchi } 8989e049346SYasunari Takiguchi 8999e049346SYasunari Takiguchi if (tune_param->data_plp_id == CXD2880_DVBT2_TUNE_PARAM_PLPID_AUTO) 9009e049346SYasunari Takiguchi ret = cxd2880_tnrdmd_dvbt2_set_plp_cfg(tnr_dmd, 1, 0); 9019e049346SYasunari Takiguchi else 9029e049346SYasunari Takiguchi ret = 9039e049346SYasunari Takiguchi cxd2880_tnrdmd_dvbt2_set_plp_cfg(tnr_dmd, 0, 9049e049346SYasunari Takiguchi (u8)(tune_param->data_plp_id)); 9059e049346SYasunari Takiguchi 9069e049346SYasunari Takiguchi return ret; 9079e049346SYasunari Takiguchi } 9089e049346SYasunari Takiguchi 9099e049346SYasunari Takiguchi int cxd2880_tnrdmd_dvbt2_tune2(struct cxd2880_tnrdmd *tnr_dmd, 9109e049346SYasunari Takiguchi struct cxd2880_dvbt2_tune_param 9119e049346SYasunari Takiguchi *tune_param) 9129e049346SYasunari Takiguchi { 9139e049346SYasunari Takiguchi u8 en_fef_intmtnt_ctrl = 1; 9149e049346SYasunari Takiguchi int ret; 9159e049346SYasunari Takiguchi 9169e049346SYasunari Takiguchi if (!tnr_dmd || !tune_param) 9179e049346SYasunari Takiguchi return -EINVAL; 9189e049346SYasunari Takiguchi 9199e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 9209e049346SYasunari Takiguchi return -EINVAL; 9219e049346SYasunari Takiguchi 9229e049346SYasunari Takiguchi if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 9239e049346SYasunari Takiguchi tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 9249e049346SYasunari Takiguchi return -EINVAL; 9259e049346SYasunari Takiguchi 9269e049346SYasunari Takiguchi switch (tune_param->profile) { 9279e049346SYasunari Takiguchi case CXD2880_DVBT2_PROFILE_BASE: 9289e049346SYasunari Takiguchi en_fef_intmtnt_ctrl = tnr_dmd->en_fef_intmtnt_base; 9299e049346SYasunari Takiguchi break; 9309e049346SYasunari Takiguchi case CXD2880_DVBT2_PROFILE_LITE: 9319e049346SYasunari Takiguchi en_fef_intmtnt_ctrl = tnr_dmd->en_fef_intmtnt_lite; 9329e049346SYasunari Takiguchi break; 9339e049346SYasunari Takiguchi case CXD2880_DVBT2_PROFILE_ANY: 9349e049346SYasunari Takiguchi if (tnr_dmd->en_fef_intmtnt_base && 9359e049346SYasunari Takiguchi tnr_dmd->en_fef_intmtnt_lite) 9369e049346SYasunari Takiguchi en_fef_intmtnt_ctrl = 1; 9379e049346SYasunari Takiguchi else 9389e049346SYasunari Takiguchi en_fef_intmtnt_ctrl = 0; 9399e049346SYasunari Takiguchi break; 9409e049346SYasunari Takiguchi default: 9419e049346SYasunari Takiguchi return -EINVAL; 9429e049346SYasunari Takiguchi } 9439e049346SYasunari Takiguchi 9449e049346SYasunari Takiguchi ret = 9459e049346SYasunari Takiguchi cxd2880_tnrdmd_common_tune_setting2(tnr_dmd, 9469e049346SYasunari Takiguchi CXD2880_DTV_SYS_DVBT2, 9479e049346SYasunari Takiguchi en_fef_intmtnt_ctrl); 9489e049346SYasunari Takiguchi if (ret) 9499e049346SYasunari Takiguchi return ret; 9509e049346SYasunari Takiguchi 9519e049346SYasunari Takiguchi tnr_dmd->state = CXD2880_TNRDMD_STATE_ACTIVE; 9529e049346SYasunari Takiguchi tnr_dmd->frequency_khz = tune_param->center_freq_khz; 9539e049346SYasunari Takiguchi tnr_dmd->sys = CXD2880_DTV_SYS_DVBT2; 9549e049346SYasunari Takiguchi tnr_dmd->bandwidth = tune_param->bandwidth; 9559e049346SYasunari Takiguchi 9569e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 9579e049346SYasunari Takiguchi tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_ACTIVE; 9589e049346SYasunari Takiguchi tnr_dmd->diver_sub->frequency_khz = tune_param->center_freq_khz; 9599e049346SYasunari Takiguchi tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_DVBT2; 9609e049346SYasunari Takiguchi tnr_dmd->diver_sub->bandwidth = tune_param->bandwidth; 9619e049346SYasunari Takiguchi } 9629e049346SYasunari Takiguchi 9639e049346SYasunari Takiguchi return 0; 9649e049346SYasunari Takiguchi } 9659e049346SYasunari Takiguchi 9669e049346SYasunari Takiguchi int cxd2880_tnrdmd_dvbt2_sleep_setting(struct cxd2880_tnrdmd 9679e049346SYasunari Takiguchi *tnr_dmd) 9689e049346SYasunari Takiguchi { 9699e049346SYasunari Takiguchi int ret; 9709e049346SYasunari Takiguchi 9719e049346SYasunari Takiguchi if (!tnr_dmd) 9729e049346SYasunari Takiguchi return -EINVAL; 9739e049346SYasunari Takiguchi 9749e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 9759e049346SYasunari Takiguchi return -EINVAL; 9769e049346SYasunari Takiguchi 9779e049346SYasunari Takiguchi if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 9789e049346SYasunari Takiguchi tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 9799e049346SYasunari Takiguchi return -EINVAL; 9809e049346SYasunari Takiguchi 9819e049346SYasunari Takiguchi ret = x_sleep_dvbt2_demod_setting(tnr_dmd); 9829e049346SYasunari Takiguchi if (ret) 9839e049346SYasunari Takiguchi return ret; 9849e049346SYasunari Takiguchi 9859e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) 9869e049346SYasunari Takiguchi ret = x_sleep_dvbt2_demod_setting(tnr_dmd->diver_sub); 9879e049346SYasunari Takiguchi 9889e049346SYasunari Takiguchi return ret; 9899e049346SYasunari Takiguchi } 9909e049346SYasunari Takiguchi 9919e049346SYasunari Takiguchi int cxd2880_tnrdmd_dvbt2_check_demod_lock(struct cxd2880_tnrdmd 9929e049346SYasunari Takiguchi *tnr_dmd, 9939e049346SYasunari Takiguchi enum 9949e049346SYasunari Takiguchi cxd2880_tnrdmd_lock_result 9959e049346SYasunari Takiguchi *lock) 9969e049346SYasunari Takiguchi { 9979e049346SYasunari Takiguchi int ret; 9989e049346SYasunari Takiguchi 9999e049346SYasunari Takiguchi u8 sync_stat = 0; 10009e049346SYasunari Takiguchi u8 ts_lock = 0; 10019e049346SYasunari Takiguchi u8 unlock_detected = 0; 10029e049346SYasunari Takiguchi u8 unlock_detected_sub = 0; 10039e049346SYasunari Takiguchi 10049e049346SYasunari Takiguchi if (!tnr_dmd || !lock) 10059e049346SYasunari Takiguchi return -EINVAL; 10069e049346SYasunari Takiguchi 10079e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 10089e049346SYasunari Takiguchi return -EINVAL; 10099e049346SYasunari Takiguchi 10109e049346SYasunari Takiguchi if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 10119e049346SYasunari Takiguchi return -EINVAL; 10129e049346SYasunari Takiguchi 10139e049346SYasunari Takiguchi ret = 10149e049346SYasunari Takiguchi cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock, 10159e049346SYasunari Takiguchi &unlock_detected); 10169e049346SYasunari Takiguchi if (ret) 10179e049346SYasunari Takiguchi return ret; 10189e049346SYasunari Takiguchi 10199e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { 10209e049346SYasunari Takiguchi if (sync_stat == 6) 10219e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; 10229e049346SYasunari Takiguchi else if (unlock_detected) 10239e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; 10249e049346SYasunari Takiguchi else 10259e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; 10269e049346SYasunari Takiguchi 1027*e670d7e3SHans Verkuil return 0; 10289e049346SYasunari Takiguchi } 10299e049346SYasunari Takiguchi 10309e049346SYasunari Takiguchi if (sync_stat == 6) { 10319e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; 1032*e670d7e3SHans Verkuil return 0; 10339e049346SYasunari Takiguchi } 10349e049346SYasunari Takiguchi 10359e049346SYasunari Takiguchi ret = 10369e049346SYasunari Takiguchi cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(tnr_dmd, &sync_stat, 10379e049346SYasunari Takiguchi &unlock_detected_sub); 10389e049346SYasunari Takiguchi if (ret) 10399e049346SYasunari Takiguchi return ret; 10409e049346SYasunari Takiguchi 10419e049346SYasunari Takiguchi if (sync_stat == 6) 10429e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; 10439e049346SYasunari Takiguchi else if (unlock_detected && unlock_detected_sub) 10449e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; 10459e049346SYasunari Takiguchi else 10469e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; 10479e049346SYasunari Takiguchi 1048*e670d7e3SHans Verkuil return 0; 10499e049346SYasunari Takiguchi } 10509e049346SYasunari Takiguchi 10519e049346SYasunari Takiguchi int cxd2880_tnrdmd_dvbt2_check_ts_lock(struct cxd2880_tnrdmd 10529e049346SYasunari Takiguchi *tnr_dmd, 10539e049346SYasunari Takiguchi enum 10549e049346SYasunari Takiguchi cxd2880_tnrdmd_lock_result 10559e049346SYasunari Takiguchi *lock) 10569e049346SYasunari Takiguchi { 10579e049346SYasunari Takiguchi int ret; 10589e049346SYasunari Takiguchi 10599e049346SYasunari Takiguchi u8 sync_stat = 0; 10609e049346SYasunari Takiguchi u8 ts_lock = 0; 10619e049346SYasunari Takiguchi u8 unlock_detected = 0; 10629e049346SYasunari Takiguchi u8 unlock_detected_sub = 0; 10639e049346SYasunari Takiguchi 10649e049346SYasunari Takiguchi if (!tnr_dmd || !lock) 10659e049346SYasunari Takiguchi return -EINVAL; 10669e049346SYasunari Takiguchi 10679e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 10689e049346SYasunari Takiguchi return -EINVAL; 10699e049346SYasunari Takiguchi 10709e049346SYasunari Takiguchi if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 10719e049346SYasunari Takiguchi return -EINVAL; 10729e049346SYasunari Takiguchi 10739e049346SYasunari Takiguchi ret = 10749e049346SYasunari Takiguchi cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock, 10759e049346SYasunari Takiguchi &unlock_detected); 10769e049346SYasunari Takiguchi if (ret) 10779e049346SYasunari Takiguchi return ret; 10789e049346SYasunari Takiguchi 10799e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { 10809e049346SYasunari Takiguchi if (ts_lock) 10819e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; 10829e049346SYasunari Takiguchi else if (unlock_detected) 10839e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; 10849e049346SYasunari Takiguchi else 10859e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; 10869e049346SYasunari Takiguchi 1087*e670d7e3SHans Verkuil return 0; 10889e049346SYasunari Takiguchi } 10899e049346SYasunari Takiguchi 10909e049346SYasunari Takiguchi if (ts_lock) { 10919e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED; 1092*e670d7e3SHans Verkuil return 0; 10939e049346SYasunari Takiguchi } else if (!unlock_detected) { 10949e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; 1095*e670d7e3SHans Verkuil return 0; 10969e049346SYasunari Takiguchi } 10979e049346SYasunari Takiguchi 10989e049346SYasunari Takiguchi ret = 10999e049346SYasunari Takiguchi cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(tnr_dmd, &sync_stat, 11009e049346SYasunari Takiguchi &unlock_detected_sub); 11019e049346SYasunari Takiguchi if (ret) 11029e049346SYasunari Takiguchi return ret; 11039e049346SYasunari Takiguchi 11049e049346SYasunari Takiguchi if (unlock_detected && unlock_detected_sub) 11059e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED; 11069e049346SYasunari Takiguchi else 11079e049346SYasunari Takiguchi *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT; 11089e049346SYasunari Takiguchi 1109*e670d7e3SHans Verkuil return 0; 11109e049346SYasunari Takiguchi } 11119e049346SYasunari Takiguchi 11129e049346SYasunari Takiguchi int cxd2880_tnrdmd_dvbt2_set_plp_cfg(struct cxd2880_tnrdmd 11139e049346SYasunari Takiguchi *tnr_dmd, u8 auto_plp, 11149e049346SYasunari Takiguchi u8 plp_id) 11159e049346SYasunari Takiguchi { 11169e049346SYasunari Takiguchi int ret; 11179e049346SYasunari Takiguchi 11189e049346SYasunari Takiguchi if (!tnr_dmd) 11199e049346SYasunari Takiguchi return -EINVAL; 11209e049346SYasunari Takiguchi 11219e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 11229e049346SYasunari Takiguchi return -EINVAL; 11239e049346SYasunari Takiguchi 11249e049346SYasunari Takiguchi if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 11259e049346SYasunari Takiguchi tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 11269e049346SYasunari Takiguchi return -EINVAL; 11279e049346SYasunari Takiguchi 11289e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 11299e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 11309e049346SYasunari Takiguchi 0x00, 0x23); 11319e049346SYasunari Takiguchi if (ret) 11329e049346SYasunari Takiguchi return ret; 11339e049346SYasunari Takiguchi 11349e049346SYasunari Takiguchi if (!auto_plp) { 11359e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 11369e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 11379e049346SYasunari Takiguchi 0xaf, plp_id); 11389e049346SYasunari Takiguchi if (ret) 11399e049346SYasunari Takiguchi return ret; 11409e049346SYasunari Takiguchi } 11419e049346SYasunari Takiguchi 11429e049346SYasunari Takiguchi return tnr_dmd->io->write_reg(tnr_dmd->io, 11439e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 11449e049346SYasunari Takiguchi 0xad, auto_plp ? 0x00 : 0x01); 11459e049346SYasunari Takiguchi } 11469e049346SYasunari Takiguchi 11479e049346SYasunari Takiguchi int cxd2880_tnrdmd_dvbt2_diver_fef_setting(struct cxd2880_tnrdmd 11489e049346SYasunari Takiguchi *tnr_dmd) 11499e049346SYasunari Takiguchi { 11509e049346SYasunari Takiguchi struct cxd2880_dvbt2_ofdm ofdm; 11519e049346SYasunari Takiguchi static const u8 data[] = { 0, 8, 0, 16, 0, 32, 0, 64, 0, 128, 1, 0}; 11529e049346SYasunari Takiguchi int ret; 11539e049346SYasunari Takiguchi 11549e049346SYasunari Takiguchi if (!tnr_dmd) 11559e049346SYasunari Takiguchi return -EINVAL; 11569e049346SYasunari Takiguchi 11579e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 11589e049346SYasunari Takiguchi return -EINVAL; 11599e049346SYasunari Takiguchi 11609e049346SYasunari Takiguchi if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 11619e049346SYasunari Takiguchi return -EINVAL; 11629e049346SYasunari Takiguchi 11639e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) 11649e049346SYasunari Takiguchi return 0; 11659e049346SYasunari Takiguchi 11669e049346SYasunari Takiguchi ret = cxd2880_tnrdmd_dvbt2_mon_ofdm(tnr_dmd, &ofdm); 11679e049346SYasunari Takiguchi if (ret) 11689e049346SYasunari Takiguchi return ret; 11699e049346SYasunari Takiguchi 11709e049346SYasunari Takiguchi if (!ofdm.mixed) 11719e049346SYasunari Takiguchi return 0; 11729e049346SYasunari Takiguchi 11739e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 11749e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 11759e049346SYasunari Takiguchi 0x00, 0x1d); 11769e049346SYasunari Takiguchi if (ret) 11779e049346SYasunari Takiguchi return ret; 11789e049346SYasunari Takiguchi 11799e049346SYasunari Takiguchi return tnr_dmd->io->write_regs(tnr_dmd->io, 11809e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 11819e049346SYasunari Takiguchi 0x47, data, 12); 11829e049346SYasunari Takiguchi } 11839e049346SYasunari Takiguchi 11849e049346SYasunari Takiguchi int cxd2880_tnrdmd_dvbt2_check_l1post_valid(struct cxd2880_tnrdmd 11859e049346SYasunari Takiguchi *tnr_dmd, 11869e049346SYasunari Takiguchi u8 *l1_post_valid) 11879e049346SYasunari Takiguchi { 11889e049346SYasunari Takiguchi int ret; 11899e049346SYasunari Takiguchi 11909e049346SYasunari Takiguchi u8 data; 11919e049346SYasunari Takiguchi 11929e049346SYasunari Takiguchi if (!tnr_dmd || !l1_post_valid) 11939e049346SYasunari Takiguchi return -EINVAL; 11949e049346SYasunari Takiguchi 11959e049346SYasunari Takiguchi if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 11969e049346SYasunari Takiguchi return -EINVAL; 11979e049346SYasunari Takiguchi 11989e049346SYasunari Takiguchi if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 11999e049346SYasunari Takiguchi tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 12009e049346SYasunari Takiguchi return -EINVAL; 12019e049346SYasunari Takiguchi 12029e049346SYasunari Takiguchi ret = tnr_dmd->io->write_reg(tnr_dmd->io, 12039e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 12049e049346SYasunari Takiguchi 0x00, 0x0b); 12059e049346SYasunari Takiguchi if (ret) 12069e049346SYasunari Takiguchi return ret; 12079e049346SYasunari Takiguchi 12089e049346SYasunari Takiguchi ret = tnr_dmd->io->read_regs(tnr_dmd->io, 12099e049346SYasunari Takiguchi CXD2880_IO_TGT_DMD, 12109e049346SYasunari Takiguchi 0x86, &data, 1); 12119e049346SYasunari Takiguchi if (ret) 12129e049346SYasunari Takiguchi return ret; 12139e049346SYasunari Takiguchi 12149e049346SYasunari Takiguchi *l1_post_valid = data & 0x01; 12159e049346SYasunari Takiguchi 12169e049346SYasunari Takiguchi return ret; 12179e049346SYasunari Takiguchi } 1218