cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cxd2880_tnrdmd_dvbt2.c (27431B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * cxd2880_tnrdmd_dvbt2.c
      4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver
      5 * control functions for DVB-T2
      6 *
      7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
      8 */
      9
     10#include <media/dvb_frontend.h>
     11
     12#include "cxd2880_tnrdmd_dvbt2.h"
     13#include "cxd2880_tnrdmd_dvbt2_mon.h"
     14
     15static const struct cxd2880_reg_value tune_dmd_setting_seq1[] = {
     16	{0x00, 0x00}, {0x31, 0x02},
     17};
     18
     19static const struct cxd2880_reg_value tune_dmd_setting_seq2[] = {
     20	{0x00, 0x04}, {0x5d, 0x0b},
     21};
     22
     23static int x_tune_dvbt2_demod_setting(struct cxd2880_tnrdmd
     24				      *tnr_dmd,
     25				      enum cxd2880_dtv_bandwidth
     26				      bandwidth,
     27				      enum cxd2880_tnrdmd_clockmode
     28				      clk_mode)
     29{
     30	static const u8 tsif_settings[2] = { 0x01, 0x01 };
     31	static const u8 init_settings[14] = {
     32		0x07, 0x06, 0x01, 0xf0,	0x00, 0x00, 0x04, 0xb0, 0x00, 0x00,
     33		0x09, 0x9c, 0x0e, 0x4c
     34	};
     35	static const u8 clk_mode_settings_a1[9] = {
     36		0x52, 0x49, 0x2c, 0x51,	0x51, 0x3d, 0x15, 0x29, 0x0c
     37	};
     38
     39	static const u8 clk_mode_settings_b1[9] = {
     40		0x5d, 0x55, 0x32, 0x5c,	0x5c, 0x45, 0x17, 0x2e, 0x0d
     41	};
     42
     43	static const u8 clk_mode_settings_c1[9] = {
     44		0x60, 0x00, 0x34, 0x5e,	0x5e, 0x47, 0x18, 0x2f, 0x0e
     45	};
     46
     47	static const u8 clk_mode_settings_a2[13] = {
     48		0x04, 0xe7, 0x94, 0x92,	0x09, 0xcf, 0x7e, 0xd0, 0x49,
     49		0xcd, 0xcd, 0x1f, 0x5b
     50	};
     51
     52	static const u8 clk_mode_settings_b2[13] = {
     53		0x05, 0x90, 0x27, 0x55,	0x0b, 0x20, 0x8f, 0xd6, 0xea,
     54		0xc8, 0xc8, 0x23, 0x91
     55	};
     56
     57	static const u8 clk_mode_settings_c2[13] = {
     58		0x05, 0xb8, 0xd8, 0x00,	0x0b, 0x72, 0x93, 0xf3, 0x00,
     59		0xcd, 0xcd, 0x24, 0x95
     60	};
     61
     62	static const u8 clk_mode_settings_a3[5] = {
     63		0x0b, 0x6a, 0xc9, 0x03, 0x33
     64	};
     65	static const u8 clk_mode_settings_b3[5] = {
     66		0x01, 0x02, 0xe4, 0x03, 0x39
     67	};
     68	static const u8 clk_mode_settings_c3[5] = {
     69		0x01, 0x02, 0xeb, 0x03, 0x3b
     70	};
     71
     72	static const u8 gtdofst[2] = { 0x3f, 0xff };
     73
     74	static const u8 bw8_gtdofst_a[2] = { 0x19, 0xd2 };
     75	static const u8 bw8_nomi_ac[6] = { 0x15, 0x00, 0x00, 0x00, 0x00, 0x00 };
     76	static const u8 bw8_nomi_b[6] = { 0x14, 0x6a, 0xaa, 0xaa, 0xab, 0x00 };
     77	static const u8 bw8_sst_a[2] = { 0x06, 0x2a };
     78	static const u8 bw8_sst_b[2] = { 0x06, 0x29 };
     79	static const u8 bw8_sst_c[2] = { 0x06, 0x28 };
     80	static const u8 bw8_mrc_a[9] = {
     81		0x28, 0x00, 0x50, 0x00, 0x60, 0x00, 0x00, 0x90, 0x00
     82	};
     83	static const u8 bw8_mrc_b[9] = {
     84		0x2d, 0x5e, 0x5a, 0xbd, 0x6c, 0xe3, 0x00, 0xa3, 0x55
     85	};
     86	static const u8 bw8_mrc_c[9] = {
     87		0x2e, 0xaa, 0x5d, 0x55, 0x70, 0x00, 0x00, 0xa8, 0x00
     88	};
     89
     90	static const u8 bw7_nomi_ac[6] = { 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 };
     91	static const u8 bw7_nomi_b[6] = { 0x17, 0x55, 0x55, 0x55, 0x55, 0x00 };
     92	static const u8 bw7_sst_a[2] = { 0x06, 0x23 };
     93	static const u8 bw7_sst_b[2] = { 0x06, 0x22 };
     94	static const u8 bw7_sst_c[2] = { 0x06, 0x21 };
     95	static const u8 bw7_mrc_a[9] = {
     96		0x2d, 0xb6, 0x5b, 0x6d,	0x6d, 0xb6, 0x00, 0xa4, 0x92
     97	};
     98	static const u8 bw7_mrc_b[9] = {
     99		0x33, 0xda, 0x67, 0xb4,	0x7c, 0x71, 0x00, 0xba, 0xaa
    100	};
    101	static const u8 bw7_mrc_c[9] = {
    102		0x35, 0x55, 0x6a, 0xaa,	0x80, 0x00, 0x00, 0xc0, 0x00
    103	};
    104
    105	static const u8 bw6_nomi_ac[6] = { 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00 };
    106	static const u8 bw6_nomi_b[6] = { 0x1b, 0x38, 0xe3, 0x8e, 0x39, 0x00 };
    107	static const u8 bw6_sst_a[2] = { 0x06, 0x1c };
    108	static const u8 bw6_sst_b[2] = { 0x06, 0x1b };
    109	static const u8 bw6_sst_c[2] = { 0x06, 0x1a };
    110	static const u8 bw6_mrc_a[9] = {
    111		0x35, 0x55, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xc0, 0x00
    112	};
    113	static const u8 bw6_mrc_b[9] = {
    114		0x3c, 0x7e, 0x78, 0xfc,	0x91, 0x2f, 0x00, 0xd9, 0xc7
    115	};
    116	static const u8 bw6_mrc_c[9] = {
    117		0x3e, 0x38, 0x7c, 0x71,	0x95, 0x55, 0x00, 0xdf, 0xff
    118	};
    119
    120	static const u8 bw5_nomi_ac[6] = { 0x21, 0x99, 0x99, 0x99, 0x9a, 0x00 };
    121	static const u8 bw5_nomi_b[6] = { 0x20, 0xaa, 0xaa, 0xaa, 0xab, 0x00 };
    122	static const u8 bw5_sst_a[2] = { 0x06, 0x15 };
    123	static const u8 bw5_sst_b[2] = { 0x06, 0x15 };
    124	static const u8 bw5_sst_c[2] = { 0x06, 0x14 };
    125	static const u8 bw5_mrc_a[9] = {
    126		0x40, 0x00, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xe6, 0x66
    127	};
    128	static const u8 bw5_mrc_b[9] = {
    129		0x48, 0x97, 0x78, 0xfc, 0x91, 0x2f, 0x01, 0x05, 0x55
    130	};
    131	static const u8 bw5_mrc_c[9] = {
    132		0x4a, 0xaa, 0x7c, 0x71, 0x95, 0x55, 0x01, 0x0c, 0xcc
    133	};
    134
    135	static const u8 bw1_7_nomi_a[6] = {
    136		0x68, 0x0f, 0xa2, 0x32, 0xcf, 0x03
    137	};
    138	static const u8 bw1_7_nomi_c[6] = {
    139		0x68, 0x0f, 0xa2, 0x32, 0xcf, 0x03
    140	};
    141	static const u8 bw1_7_nomi_b[6] = {
    142		0x65, 0x2b, 0xa4, 0xcd, 0xd8, 0x03
    143	};
    144	static const u8 bw1_7_sst_a[2] = { 0x06, 0x0c };
    145	static const u8 bw1_7_sst_b[2] = { 0x06, 0x0c };
    146	static const u8 bw1_7_sst_c[2] = { 0x06, 0x0b };
    147	static const u8 bw1_7_mrc_a[9] = {
    148		0x40, 0x00, 0x6a, 0xaa,	0x80, 0x00, 0x02, 0xc9, 0x8f
    149	};
    150	static const u8 bw1_7_mrc_b[9] = {
    151		0x48, 0x97, 0x78, 0xfc, 0x91, 0x2f, 0x03, 0x29, 0x5d
    152	};
    153	static const u8 bw1_7_mrc_c[9] = {
    154		0x4a, 0xaa, 0x7c, 0x71,	0x95, 0x55, 0x03, 0x40, 0x7d
    155	};
    156
    157	const u8 *data = NULL;
    158	const u8 *data2 = NULL;
    159	const u8 *data3 = NULL;
    160	int ret;
    161
    162	if (!tnr_dmd)
    163		return -EINVAL;
    164
    165	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    166					  CXD2880_IO_TGT_SYS,
    167					  tune_dmd_setting_seq1,
    168					  ARRAY_SIZE(tune_dmd_setting_seq1));
    169	if (ret)
    170		return ret;
    171
    172	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    173					  CXD2880_IO_TGT_DMD,
    174					  tune_dmd_setting_seq2,
    175					  ARRAY_SIZE(tune_dmd_setting_seq2));
    176	if (ret)
    177		return ret;
    178
    179	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) {
    180		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    181					     CXD2880_IO_TGT_DMD,
    182					     0x00, 0x00);
    183		if (ret)
    184			return ret;
    185
    186		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    187					      CXD2880_IO_TGT_DMD,
    188					      0xce, tsif_settings, 2);
    189		if (ret)
    190			return ret;
    191	}
    192
    193	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    194				     CXD2880_IO_TGT_DMD,
    195				     0x00, 0x20);
    196	if (ret)
    197		return ret;
    198
    199	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    200				     CXD2880_IO_TGT_DMD,
    201				     0x8a, init_settings[0]);
    202	if (ret)
    203		return ret;
    204
    205	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    206				     CXD2880_IO_TGT_DMD,
    207				     0x90, init_settings[1]);
    208	if (ret)
    209		return ret;
    210
    211	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    212				     CXD2880_IO_TGT_DMD,
    213				     0x00, 0x25);
    214	if (ret)
    215		return ret;
    216
    217	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    218				      CXD2880_IO_TGT_DMD,
    219				      0xf0, &init_settings[2], 2);
    220	if (ret)
    221		return ret;
    222
    223	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    224				     CXD2880_IO_TGT_DMD,
    225				     0x00, 0x2a);
    226	if (ret)
    227		return ret;
    228
    229	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    230				     CXD2880_IO_TGT_DMD,
    231				     0xdc, init_settings[4]);
    232	if (ret)
    233		return ret;
    234
    235	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    236				     CXD2880_IO_TGT_DMD,
    237				     0xde, init_settings[5]);
    238	if (ret)
    239		return ret;
    240
    241	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    242				     CXD2880_IO_TGT_DMD,
    243				     0x00, 0x2d);
    244	if (ret)
    245		return ret;
    246
    247	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    248				      CXD2880_IO_TGT_DMD,
    249				      0x73, &init_settings[6], 4);
    250	if (ret)
    251		return ret;
    252
    253	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    254				      CXD2880_IO_TGT_DMD,
    255				      0x8f, &init_settings[10], 4);
    256	if (ret)
    257		return ret;
    258
    259	switch (clk_mode) {
    260	case CXD2880_TNRDMD_CLOCKMODE_A:
    261		data = clk_mode_settings_a1;
    262		data2 = clk_mode_settings_a2;
    263		data3 = clk_mode_settings_a3;
    264		break;
    265	case CXD2880_TNRDMD_CLOCKMODE_B:
    266		data = clk_mode_settings_b1;
    267		data2 = clk_mode_settings_b2;
    268		data3 = clk_mode_settings_b3;
    269		break;
    270	case CXD2880_TNRDMD_CLOCKMODE_C:
    271		data = clk_mode_settings_c1;
    272		data2 = clk_mode_settings_c2;
    273		data3 = clk_mode_settings_c3;
    274		break;
    275	default:
    276		return -EINVAL;
    277	}
    278
    279	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    280				     CXD2880_IO_TGT_DMD,
    281				     0x00, 0x04);
    282	if (ret)
    283		return ret;
    284
    285	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    286				      CXD2880_IO_TGT_DMD,
    287				      0x1d, &data[0], 3);
    288	if (ret)
    289		return ret;
    290
    291	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    292				     CXD2880_IO_TGT_DMD,
    293				     0x22, data[3]);
    294	if (ret)
    295		return ret;
    296
    297	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    298				     CXD2880_IO_TGT_DMD,
    299				     0x24, data[4]);
    300	if (ret)
    301		return ret;
    302
    303	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    304				     CXD2880_IO_TGT_DMD,
    305				     0x26, data[5]);
    306	if (ret)
    307		return ret;
    308
    309	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    310				      CXD2880_IO_TGT_DMD,
    311				      0x29, &data[6], 2);
    312	if (ret)
    313		return ret;
    314
    315	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    316				     CXD2880_IO_TGT_DMD,
    317				     0x2d, data[8]);
    318	if (ret)
    319		return ret;
    320
    321	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) {
    322		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    323					      CXD2880_IO_TGT_DMD,
    324					      0x2e, &data2[0], 6);
    325		if (ret)
    326			return ret;
    327
    328		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    329					      CXD2880_IO_TGT_DMD,
    330					      0x35, &data2[6], 7);
    331		if (ret)
    332			return ret;
    333	}
    334
    335	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    336				      CXD2880_IO_TGT_DMD,
    337				      0x3c, &data3[0], 2);
    338	if (ret)
    339		return ret;
    340
    341	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    342				      CXD2880_IO_TGT_DMD,
    343				      0x56, &data3[2], 3);
    344	if (ret)
    345		return ret;
    346
    347	switch (bandwidth) {
    348	case CXD2880_DTV_BW_8_MHZ:
    349		switch (clk_mode) {
    350		case CXD2880_TNRDMD_CLOCKMODE_A:
    351		case CXD2880_TNRDMD_CLOCKMODE_C:
    352			data = bw8_nomi_ac;
    353			break;
    354		case CXD2880_TNRDMD_CLOCKMODE_B:
    355			data = bw8_nomi_b;
    356			break;
    357		default:
    358			return -EINVAL;
    359		}
    360
    361		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    362					      CXD2880_IO_TGT_DMD,
    363					      0x10, data, 6);
    364		if (ret)
    365			return ret;
    366
    367		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    368					     CXD2880_IO_TGT_DMD,
    369					     0x4a, 0x00);
    370		if (ret)
    371			return ret;
    372
    373		switch (clk_mode) {
    374		case CXD2880_TNRDMD_CLOCKMODE_A:
    375			data = bw8_gtdofst_a;
    376			break;
    377		case CXD2880_TNRDMD_CLOCKMODE_B:
    378		case CXD2880_TNRDMD_CLOCKMODE_C:
    379			data = gtdofst;
    380			break;
    381		default:
    382			return -EINVAL;
    383		}
    384
    385		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    386					      CXD2880_IO_TGT_DMD,
    387					      0x19, data, 2);
    388		if (ret)
    389			return ret;
    390
    391		switch (clk_mode) {
    392		case CXD2880_TNRDMD_CLOCKMODE_A:
    393			data = bw8_sst_a;
    394			break;
    395		case CXD2880_TNRDMD_CLOCKMODE_B:
    396			data = bw8_sst_b;
    397			break;
    398		case CXD2880_TNRDMD_CLOCKMODE_C:
    399			data = bw8_sst_c;
    400			break;
    401		default:
    402			return -EINVAL;
    403		}
    404
    405		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    406					      CXD2880_IO_TGT_DMD,
    407					      0x1b, data, 2);
    408		if (ret)
    409			return ret;
    410
    411		if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    412			switch (clk_mode) {
    413			case CXD2880_TNRDMD_CLOCKMODE_A:
    414				data = bw8_mrc_a;
    415				break;
    416			case CXD2880_TNRDMD_CLOCKMODE_B:
    417				data = bw8_mrc_b;
    418				break;
    419			case CXD2880_TNRDMD_CLOCKMODE_C:
    420				data = bw8_mrc_c;
    421				break;
    422			default:
    423				return -EINVAL;
    424			}
    425
    426			ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    427						      CXD2880_IO_TGT_DMD,
    428						      0x4b, data, 9);
    429			if (ret)
    430				return ret;
    431		}
    432		break;
    433
    434	case CXD2880_DTV_BW_7_MHZ:
    435		switch (clk_mode) {
    436		case CXD2880_TNRDMD_CLOCKMODE_A:
    437		case CXD2880_TNRDMD_CLOCKMODE_C:
    438			data = bw7_nomi_ac;
    439			break;
    440		case CXD2880_TNRDMD_CLOCKMODE_B:
    441			data = bw7_nomi_b;
    442			break;
    443		default:
    444			return -EINVAL;
    445		}
    446
    447		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    448					      CXD2880_IO_TGT_DMD,
    449					      0x10, data, 6);
    450		if (ret)
    451			return ret;
    452
    453		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    454					     CXD2880_IO_TGT_DMD,
    455					     0x4a, 0x02);
    456		if (ret)
    457			return ret;
    458
    459		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    460					      CXD2880_IO_TGT_DMD,
    461					      0x19, gtdofst, 2);
    462		if (ret)
    463			return ret;
    464
    465		switch (clk_mode) {
    466		case CXD2880_TNRDMD_CLOCKMODE_A:
    467			data = bw7_sst_a;
    468			break;
    469		case CXD2880_TNRDMD_CLOCKMODE_B:
    470			data = bw7_sst_b;
    471			break;
    472		case CXD2880_TNRDMD_CLOCKMODE_C:
    473			data = bw7_sst_c;
    474			break;
    475		default:
    476			return -EINVAL;
    477		}
    478
    479		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    480					      CXD2880_IO_TGT_DMD,
    481					      0x1b, data, 2);
    482		if (ret)
    483			return ret;
    484
    485		if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    486			switch (clk_mode) {
    487			case CXD2880_TNRDMD_CLOCKMODE_A:
    488				data = bw7_mrc_a;
    489				break;
    490			case CXD2880_TNRDMD_CLOCKMODE_B:
    491				data = bw7_mrc_b;
    492				break;
    493			case CXD2880_TNRDMD_CLOCKMODE_C:
    494				data = bw7_mrc_c;
    495				break;
    496			default:
    497				return -EINVAL;
    498			}
    499
    500			ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    501						      CXD2880_IO_TGT_DMD,
    502						      0x4b, data, 9);
    503			if (ret)
    504				return ret;
    505		}
    506		break;
    507
    508	case CXD2880_DTV_BW_6_MHZ:
    509		switch (clk_mode) {
    510		case CXD2880_TNRDMD_CLOCKMODE_A:
    511		case CXD2880_TNRDMD_CLOCKMODE_C:
    512			data = bw6_nomi_ac;
    513			break;
    514		case CXD2880_TNRDMD_CLOCKMODE_B:
    515			data = bw6_nomi_b;
    516			break;
    517		default:
    518			return -EINVAL;
    519		}
    520
    521		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    522					      CXD2880_IO_TGT_DMD,
    523					      0x10, data, 6);
    524		if (ret)
    525			return ret;
    526
    527		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    528					     CXD2880_IO_TGT_DMD,
    529					     0x4a, 0x04);
    530		if (ret)
    531			return ret;
    532
    533		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    534					      CXD2880_IO_TGT_DMD,
    535					      0x19, gtdofst, 2);
    536		if (ret)
    537			return ret;
    538
    539		switch (clk_mode) {
    540		case CXD2880_TNRDMD_CLOCKMODE_A:
    541			data = bw6_sst_a;
    542			break;
    543		case CXD2880_TNRDMD_CLOCKMODE_B:
    544			data = bw6_sst_b;
    545			break;
    546		case CXD2880_TNRDMD_CLOCKMODE_C:
    547			data = bw6_sst_c;
    548			break;
    549		default:
    550			return -EINVAL;
    551		}
    552
    553		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    554					      CXD2880_IO_TGT_DMD,
    555					      0x1b, data, 2);
    556		if (ret)
    557			return ret;
    558
    559		if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    560			switch (clk_mode) {
    561			case CXD2880_TNRDMD_CLOCKMODE_A:
    562				data = bw6_mrc_a;
    563				break;
    564			case CXD2880_TNRDMD_CLOCKMODE_B:
    565				data = bw6_mrc_b;
    566				break;
    567			case CXD2880_TNRDMD_CLOCKMODE_C:
    568				data = bw6_mrc_c;
    569				break;
    570			default:
    571				return -EINVAL;
    572			}
    573
    574			ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    575						      CXD2880_IO_TGT_DMD,
    576						      0x4b, data, 9);
    577			if (ret)
    578				return ret;
    579		}
    580		break;
    581
    582	case CXD2880_DTV_BW_5_MHZ:
    583		switch (clk_mode) {
    584		case CXD2880_TNRDMD_CLOCKMODE_A:
    585		case CXD2880_TNRDMD_CLOCKMODE_C:
    586			data = bw5_nomi_ac;
    587			break;
    588		case CXD2880_TNRDMD_CLOCKMODE_B:
    589			data = bw5_nomi_b;
    590			break;
    591		default:
    592			return -EINVAL;
    593		}
    594
    595		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    596					      CXD2880_IO_TGT_DMD,
    597					      0x10, data, 6);
    598		if (ret)
    599			return ret;
    600
    601		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    602					     CXD2880_IO_TGT_DMD,
    603					     0x4a, 0x06);
    604		if (ret)
    605			return ret;
    606
    607		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    608					      CXD2880_IO_TGT_DMD,
    609					      0x19, gtdofst, 2);
    610		if (ret)
    611			return ret;
    612
    613		switch (clk_mode) {
    614		case CXD2880_TNRDMD_CLOCKMODE_A:
    615			data = bw5_sst_a;
    616			break;
    617		case CXD2880_TNRDMD_CLOCKMODE_B:
    618			data = bw5_sst_b;
    619			break;
    620		case CXD2880_TNRDMD_CLOCKMODE_C:
    621			data = bw5_sst_c;
    622			break;
    623		default:
    624			return -EINVAL;
    625		}
    626
    627		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    628					      CXD2880_IO_TGT_DMD,
    629					      0x1b, data, 2);
    630		if (ret)
    631			return ret;
    632
    633		if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    634			switch (clk_mode) {
    635			case CXD2880_TNRDMD_CLOCKMODE_A:
    636				data = bw5_mrc_a;
    637				break;
    638			case CXD2880_TNRDMD_CLOCKMODE_B:
    639				data = bw5_mrc_b;
    640				break;
    641			case CXD2880_TNRDMD_CLOCKMODE_C:
    642				data = bw5_mrc_c;
    643				break;
    644			default:
    645				return -EINVAL;
    646			}
    647
    648			ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    649						      CXD2880_IO_TGT_DMD,
    650						      0x4b, data, 9);
    651			if (ret)
    652				return ret;
    653		}
    654		break;
    655
    656	case CXD2880_DTV_BW_1_7_MHZ:
    657
    658		switch (clk_mode) {
    659		case CXD2880_TNRDMD_CLOCKMODE_A:
    660			data = bw1_7_nomi_a;
    661			break;
    662		case CXD2880_TNRDMD_CLOCKMODE_C:
    663			data = bw1_7_nomi_c;
    664			break;
    665		case CXD2880_TNRDMD_CLOCKMODE_B:
    666			data = bw1_7_nomi_b;
    667			break;
    668		default:
    669			return -EINVAL;
    670		}
    671
    672		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    673					      CXD2880_IO_TGT_DMD,
    674					      0x10, data, 6);
    675		if (ret)
    676			return ret;
    677
    678		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    679					     CXD2880_IO_TGT_DMD,
    680					     0x4a, 0x03);
    681		if (ret)
    682			return ret;
    683
    684		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    685					      CXD2880_IO_TGT_DMD,
    686					      0x19, gtdofst, 2);
    687		if (ret)
    688			return ret;
    689
    690		switch (clk_mode) {
    691		case CXD2880_TNRDMD_CLOCKMODE_A:
    692			data = bw1_7_sst_a;
    693			break;
    694		case CXD2880_TNRDMD_CLOCKMODE_B:
    695			data = bw1_7_sst_b;
    696			break;
    697		case CXD2880_TNRDMD_CLOCKMODE_C:
    698			data = bw1_7_sst_c;
    699			break;
    700		default:
    701			return -EINVAL;
    702		}
    703
    704		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    705					      CXD2880_IO_TGT_DMD,
    706					      0x1b, data, 2);
    707		if (ret)
    708			return ret;
    709
    710		if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    711			switch (clk_mode) {
    712			case CXD2880_TNRDMD_CLOCKMODE_A:
    713				data = bw1_7_mrc_a;
    714				break;
    715			case CXD2880_TNRDMD_CLOCKMODE_B:
    716				data = bw1_7_mrc_b;
    717				break;
    718			case CXD2880_TNRDMD_CLOCKMODE_C:
    719				data = bw1_7_mrc_c;
    720				break;
    721			default:
    722				return -EINVAL;
    723			}
    724
    725			ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    726						      CXD2880_IO_TGT_DMD,
    727						      0x4b, data, 9);
    728			if (ret)
    729				return ret;
    730		}
    731		break;
    732
    733	default:
    734		return -EINVAL;
    735	}
    736
    737	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    738				     CXD2880_IO_TGT_DMD,
    739				     0x00, 0x00);
    740	if (ret)
    741		return ret;
    742
    743	return tnr_dmd->io->write_reg(tnr_dmd->io,
    744				      CXD2880_IO_TGT_DMD,
    745				      0xfd, 0x01);
    746}
    747
    748static int x_sleep_dvbt2_demod_setting(struct cxd2880_tnrdmd
    749				       *tnr_dmd)
    750{
    751	static const u8 difint_clip[] = {
    752		0, 1, 0, 2, 0, 4, 0, 8, 0, 16, 0, 32
    753	};
    754	int ret = 0;
    755
    756	if (!tnr_dmd)
    757		return -EINVAL;
    758
    759	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    760		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    761					     CXD2880_IO_TGT_DMD,
    762					     0x00, 0x1d);
    763		if (ret)
    764			return ret;
    765
    766		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    767					      CXD2880_IO_TGT_DMD,
    768					      0x47, difint_clip, 12);
    769	}
    770
    771	return ret;
    772}
    773
    774static int dvbt2_set_profile(struct cxd2880_tnrdmd *tnr_dmd,
    775			     enum cxd2880_dvbt2_profile profile)
    776{
    777	u8 t2_mode_tune_mode = 0;
    778	u8 seq_not2_dtime = 0;
    779	u8 dtime1 = 0;
    780	u8 dtime2 = 0;
    781	int ret;
    782
    783	if (!tnr_dmd)
    784		return -EINVAL;
    785
    786	switch (tnr_dmd->clk_mode) {
    787	case CXD2880_TNRDMD_CLOCKMODE_A:
    788		dtime1 = 0x27;
    789		dtime2 = 0x0c;
    790		break;
    791	case CXD2880_TNRDMD_CLOCKMODE_B:
    792		dtime1 = 0x2c;
    793		dtime2 = 0x0d;
    794		break;
    795	case CXD2880_TNRDMD_CLOCKMODE_C:
    796		dtime1 = 0x2e;
    797		dtime2 = 0x0e;
    798		break;
    799	default:
    800		return -EINVAL;
    801	}
    802
    803	switch (profile) {
    804	case CXD2880_DVBT2_PROFILE_BASE:
    805		t2_mode_tune_mode = 0x01;
    806		seq_not2_dtime = dtime2;
    807		break;
    808
    809	case CXD2880_DVBT2_PROFILE_LITE:
    810		t2_mode_tune_mode = 0x05;
    811		seq_not2_dtime = dtime1;
    812		break;
    813
    814	case CXD2880_DVBT2_PROFILE_ANY:
    815		t2_mode_tune_mode = 0x00;
    816		seq_not2_dtime = dtime1;
    817		break;
    818
    819	default:
    820		return -EINVAL;
    821	}
    822
    823	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    824				     CXD2880_IO_TGT_DMD,
    825				     0x00, 0x2e);
    826	if (ret)
    827		return ret;
    828
    829	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    830				     CXD2880_IO_TGT_DMD,
    831				     0x10, t2_mode_tune_mode);
    832	if (ret)
    833		return ret;
    834
    835	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    836				     CXD2880_IO_TGT_DMD,
    837				     0x00, 0x04);
    838	if (ret)
    839		return ret;
    840
    841	return tnr_dmd->io->write_reg(tnr_dmd->io,
    842				      CXD2880_IO_TGT_DMD,
    843				      0x2c, seq_not2_dtime);
    844}
    845
    846int cxd2880_tnrdmd_dvbt2_tune1(struct cxd2880_tnrdmd *tnr_dmd,
    847			       struct cxd2880_dvbt2_tune_param
    848			       *tune_param)
    849{
    850	int ret;
    851
    852	if (!tnr_dmd || !tune_param)
    853		return -EINVAL;
    854
    855	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
    856		return -EINVAL;
    857
    858	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
    859	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
    860		return -EINVAL;
    861
    862	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN &&
    863	    tune_param->profile == CXD2880_DVBT2_PROFILE_ANY)
    864		return -ENOTTY;
    865
    866	ret =
    867	    cxd2880_tnrdmd_common_tune_setting1(tnr_dmd, CXD2880_DTV_SYS_DVBT2,
    868						tune_param->center_freq_khz,
    869						tune_param->bandwidth, 0, 0);
    870	if (ret)
    871		return ret;
    872
    873	ret =
    874	    x_tune_dvbt2_demod_setting(tnr_dmd, tune_param->bandwidth,
    875				       tnr_dmd->clk_mode);
    876	if (ret)
    877		return ret;
    878
    879	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    880		ret =
    881		    x_tune_dvbt2_demod_setting(tnr_dmd->diver_sub,
    882					       tune_param->bandwidth,
    883					       tnr_dmd->diver_sub->clk_mode);
    884		if (ret)
    885			return ret;
    886	}
    887
    888	ret = dvbt2_set_profile(tnr_dmd, tune_param->profile);
    889	if (ret)
    890		return ret;
    891
    892	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    893		ret =
    894		    dvbt2_set_profile(tnr_dmd->diver_sub, tune_param->profile);
    895		if (ret)
    896			return ret;
    897	}
    898
    899	if (tune_param->data_plp_id == CXD2880_DVBT2_TUNE_PARAM_PLPID_AUTO)
    900		ret = cxd2880_tnrdmd_dvbt2_set_plp_cfg(tnr_dmd, 1, 0);
    901	else
    902		ret =
    903		    cxd2880_tnrdmd_dvbt2_set_plp_cfg(tnr_dmd, 0,
    904					     (u8)(tune_param->data_plp_id));
    905
    906	return ret;
    907}
    908
    909int cxd2880_tnrdmd_dvbt2_tune2(struct cxd2880_tnrdmd *tnr_dmd,
    910			       struct cxd2880_dvbt2_tune_param
    911			       *tune_param)
    912{
    913	u8 en_fef_intmtnt_ctrl = 1;
    914	int ret;
    915
    916	if (!tnr_dmd || !tune_param)
    917		return -EINVAL;
    918
    919	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
    920		return -EINVAL;
    921
    922	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
    923	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
    924		return -EINVAL;
    925
    926	switch (tune_param->profile) {
    927	case CXD2880_DVBT2_PROFILE_BASE:
    928		en_fef_intmtnt_ctrl = tnr_dmd->en_fef_intmtnt_base;
    929		break;
    930	case CXD2880_DVBT2_PROFILE_LITE:
    931		en_fef_intmtnt_ctrl = tnr_dmd->en_fef_intmtnt_lite;
    932		break;
    933	case CXD2880_DVBT2_PROFILE_ANY:
    934		if (tnr_dmd->en_fef_intmtnt_base &&
    935		    tnr_dmd->en_fef_intmtnt_lite)
    936			en_fef_intmtnt_ctrl = 1;
    937		else
    938			en_fef_intmtnt_ctrl = 0;
    939		break;
    940	default:
    941		return -EINVAL;
    942	}
    943
    944	ret =
    945	    cxd2880_tnrdmd_common_tune_setting2(tnr_dmd,
    946						CXD2880_DTV_SYS_DVBT2,
    947						en_fef_intmtnt_ctrl);
    948	if (ret)
    949		return ret;
    950
    951	tnr_dmd->state = CXD2880_TNRDMD_STATE_ACTIVE;
    952	tnr_dmd->frequency_khz = tune_param->center_freq_khz;
    953	tnr_dmd->sys = CXD2880_DTV_SYS_DVBT2;
    954	tnr_dmd->bandwidth = tune_param->bandwidth;
    955
    956	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    957		tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_ACTIVE;
    958		tnr_dmd->diver_sub->frequency_khz = tune_param->center_freq_khz;
    959		tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_DVBT2;
    960		tnr_dmd->diver_sub->bandwidth = tune_param->bandwidth;
    961	}
    962
    963	return 0;
    964}
    965
    966int cxd2880_tnrdmd_dvbt2_sleep_setting(struct cxd2880_tnrdmd
    967				       *tnr_dmd)
    968{
    969	int ret;
    970
    971	if (!tnr_dmd)
    972		return -EINVAL;
    973
    974	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
    975		return -EINVAL;
    976
    977	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
    978	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
    979		return -EINVAL;
    980
    981	ret = x_sleep_dvbt2_demod_setting(tnr_dmd);
    982	if (ret)
    983		return ret;
    984
    985	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
    986		ret = x_sleep_dvbt2_demod_setting(tnr_dmd->diver_sub);
    987
    988	return ret;
    989}
    990
    991int cxd2880_tnrdmd_dvbt2_check_demod_lock(struct cxd2880_tnrdmd
    992					  *tnr_dmd,
    993					  enum
    994					  cxd2880_tnrdmd_lock_result
    995					  *lock)
    996{
    997	int ret;
    998
    999	u8 sync_stat = 0;
   1000	u8 ts_lock = 0;
   1001	u8 unlock_detected = 0;
   1002	u8 unlock_detected_sub = 0;
   1003
   1004	if (!tnr_dmd || !lock)
   1005		return -EINVAL;
   1006
   1007	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   1008		return -EINVAL;
   1009
   1010	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   1011		return -EINVAL;
   1012
   1013	ret =
   1014	    cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock,
   1015					       &unlock_detected);
   1016	if (ret)
   1017		return ret;
   1018
   1019	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) {
   1020		if (sync_stat == 6)
   1021			*lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
   1022		else if (unlock_detected)
   1023			*lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
   1024		else
   1025			*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
   1026
   1027		return ret;
   1028	}
   1029
   1030	if (sync_stat == 6) {
   1031		*lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
   1032		return ret;
   1033	}
   1034
   1035	ret =
   1036	    cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(tnr_dmd, &sync_stat,
   1037						   &unlock_detected_sub);
   1038	if (ret)
   1039		return ret;
   1040
   1041	if (sync_stat == 6)
   1042		*lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
   1043	else if (unlock_detected && unlock_detected_sub)
   1044		*lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
   1045	else
   1046		*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
   1047
   1048	return ret;
   1049}
   1050
   1051int cxd2880_tnrdmd_dvbt2_check_ts_lock(struct cxd2880_tnrdmd
   1052				       *tnr_dmd,
   1053				       enum
   1054				       cxd2880_tnrdmd_lock_result
   1055				       *lock)
   1056{
   1057	int ret;
   1058
   1059	u8 sync_stat = 0;
   1060	u8 ts_lock = 0;
   1061	u8 unlock_detected = 0;
   1062	u8 unlock_detected_sub = 0;
   1063
   1064	if (!tnr_dmd || !lock)
   1065		return -EINVAL;
   1066
   1067	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   1068		return -EINVAL;
   1069
   1070	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   1071		return -EINVAL;
   1072
   1073	ret =
   1074	    cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock,
   1075					       &unlock_detected);
   1076	if (ret)
   1077		return ret;
   1078
   1079	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) {
   1080		if (ts_lock)
   1081			*lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
   1082		else if (unlock_detected)
   1083			*lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
   1084		else
   1085			*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
   1086
   1087		return ret;
   1088	}
   1089
   1090	if (ts_lock) {
   1091		*lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
   1092		return ret;
   1093	} else if (!unlock_detected) {
   1094		*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
   1095		return ret;
   1096	}
   1097
   1098	ret =
   1099	    cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(tnr_dmd, &sync_stat,
   1100						   &unlock_detected_sub);
   1101	if (ret)
   1102		return ret;
   1103
   1104	if (unlock_detected && unlock_detected_sub)
   1105		*lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
   1106	else
   1107		*lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
   1108
   1109	return ret;
   1110}
   1111
   1112int cxd2880_tnrdmd_dvbt2_set_plp_cfg(struct cxd2880_tnrdmd
   1113				     *tnr_dmd, u8 auto_plp,
   1114				     u8 plp_id)
   1115{
   1116	int ret;
   1117
   1118	if (!tnr_dmd)
   1119		return -EINVAL;
   1120
   1121	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   1122		return -EINVAL;
   1123
   1124	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   1125	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   1126		return -EINVAL;
   1127
   1128	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1129				     CXD2880_IO_TGT_DMD,
   1130				     0x00, 0x23);
   1131	if (ret)
   1132		return ret;
   1133
   1134	if (!auto_plp) {
   1135		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1136					     CXD2880_IO_TGT_DMD,
   1137					     0xaf, plp_id);
   1138		if (ret)
   1139			return ret;
   1140	}
   1141
   1142	return tnr_dmd->io->write_reg(tnr_dmd->io,
   1143				      CXD2880_IO_TGT_DMD,
   1144				      0xad, auto_plp ? 0x00 : 0x01);
   1145}
   1146
   1147int cxd2880_tnrdmd_dvbt2_diver_fef_setting(struct cxd2880_tnrdmd
   1148					   *tnr_dmd)
   1149{
   1150	struct cxd2880_dvbt2_ofdm ofdm;
   1151	static const u8 data[] = { 0, 8, 0, 16, 0, 32, 0, 64, 0, 128, 1, 0};
   1152	int ret;
   1153
   1154	if (!tnr_dmd)
   1155		return -EINVAL;
   1156
   1157	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   1158		return -EINVAL;
   1159
   1160	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   1161		return -EINVAL;
   1162
   1163	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE)
   1164		return 0;
   1165
   1166	ret = cxd2880_tnrdmd_dvbt2_mon_ofdm(tnr_dmd, &ofdm);
   1167	if (ret)
   1168		return ret;
   1169
   1170	if (!ofdm.mixed)
   1171		return 0;
   1172
   1173	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1174				     CXD2880_IO_TGT_DMD,
   1175				     0x00, 0x1d);
   1176	if (ret)
   1177		return ret;
   1178
   1179	return tnr_dmd->io->write_regs(tnr_dmd->io,
   1180				       CXD2880_IO_TGT_DMD,
   1181				       0x47, data, 12);
   1182}
   1183
   1184int cxd2880_tnrdmd_dvbt2_check_l1post_valid(struct cxd2880_tnrdmd
   1185					    *tnr_dmd,
   1186					    u8 *l1_post_valid)
   1187{
   1188	int ret;
   1189
   1190	u8 data;
   1191
   1192	if (!tnr_dmd || !l1_post_valid)
   1193		return -EINVAL;
   1194
   1195	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   1196		return -EINVAL;
   1197
   1198	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   1199	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   1200		return -EINVAL;
   1201
   1202	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1203				     CXD2880_IO_TGT_DMD,
   1204				     0x00, 0x0b);
   1205	if (ret)
   1206		return ret;
   1207
   1208	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   1209				     CXD2880_IO_TGT_DMD,
   1210				     0x86, &data, 1);
   1211	if (ret)
   1212		return ret;
   1213
   1214	*l1_post_valid = data & 0x01;
   1215
   1216	return ret;
   1217}