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 
x_tune_dvbt2_demod_setting(struct cxd2880_tnrdmd * tnr_dmd,enum cxd2880_dtv_bandwidth bandwidth,enum cxd2880_tnrdmd_clockmode clk_mode)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 
x_sleep_dvbt2_demod_setting(struct cxd2880_tnrdmd * tnr_dmd)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 
dvbt2_set_profile(struct cxd2880_tnrdmd * tnr_dmd,enum cxd2880_dvbt2_profile profile)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 
cxd2880_tnrdmd_dvbt2_tune1(struct cxd2880_tnrdmd * tnr_dmd,struct cxd2880_dvbt2_tune_param * tune_param)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 
cxd2880_tnrdmd_dvbt2_tune2(struct cxd2880_tnrdmd * tnr_dmd,struct cxd2880_dvbt2_tune_param * tune_param)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 
cxd2880_tnrdmd_dvbt2_sleep_setting(struct cxd2880_tnrdmd * tnr_dmd)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 
cxd2880_tnrdmd_dvbt2_check_demod_lock(struct cxd2880_tnrdmd * tnr_dmd,enum cxd2880_tnrdmd_lock_result * lock)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 
cxd2880_tnrdmd_dvbt2_check_ts_lock(struct cxd2880_tnrdmd * tnr_dmd,enum cxd2880_tnrdmd_lock_result * lock)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 
cxd2880_tnrdmd_dvbt2_set_plp_cfg(struct cxd2880_tnrdmd * tnr_dmd,u8 auto_plp,u8 plp_id)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 
cxd2880_tnrdmd_dvbt2_diver_fef_setting(struct cxd2880_tnrdmd * tnr_dmd)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 
cxd2880_tnrdmd_dvbt2_check_l1post_valid(struct cxd2880_tnrdmd * tnr_dmd,u8 * l1_post_valid)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