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.c (77019B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * cxd2880_tnrdmd.c
      4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver
      5 * common control functions
      6 *
      7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
      8 */
      9
     10#include <media/dvb_frontend.h>
     11#include "cxd2880_common.h"
     12#include "cxd2880_tnrdmd.h"
     13#include "cxd2880_tnrdmd_mon.h"
     14#include "cxd2880_tnrdmd_dvbt.h"
     15#include "cxd2880_tnrdmd_dvbt2.h"
     16
     17static const struct cxd2880_reg_value p_init1_seq[] = {
     18	{0x11, 0x16}, {0x00, 0x10},
     19};
     20
     21static const struct cxd2880_reg_value rf_init1_seq1[] = {
     22	{0x4f, 0x18}, {0x61, 0x00}, {0x71, 0x00}, {0x9d, 0x01},
     23	{0x7d, 0x02}, {0x8f, 0x01}, {0x8b, 0xc6}, {0x9a, 0x03},
     24	{0x1c, 0x00},
     25};
     26
     27static const struct cxd2880_reg_value rf_init1_seq2[] = {
     28	{0xb9, 0x07}, {0x33, 0x01}, {0xc1, 0x01}, {0xc4, 0x1e},
     29};
     30
     31static const struct cxd2880_reg_value rf_init1_seq3[] = {
     32	{0x00, 0x10}, {0x51, 0x01}, {0xc5, 0x07}, {0x00, 0x11},
     33	{0x70, 0xe9}, {0x76, 0x0a}, {0x78, 0x32}, {0x7a, 0x46},
     34	{0x7c, 0x86}, {0x7e, 0xa4}, {0x00, 0x10}, {0xe1, 0x01},
     35};
     36
     37static const struct cxd2880_reg_value rf_init1_seq4[] = {
     38	{0x15, 0x00}, {0x00, 0x16}
     39};
     40
     41static const struct cxd2880_reg_value rf_init1_seq5[] = {
     42	{0x00, 0x00}, {0x25, 0x00}
     43};
     44
     45static const struct cxd2880_reg_value rf_init1_seq6[] = {
     46	{0x02, 0x00}, {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1},
     47	{0x8f, 0x16}, {0x67, 0x60}, {0x6a, 0x0f}, {0x6c, 0x17}
     48};
     49
     50static const struct cxd2880_reg_value rf_init1_seq7[] = {
     51	{0x00, 0xe2}, {0x41, 0xa0}, {0x4b, 0x68}, {0x00, 0x00},
     52	{0x21, 0x00}, {0x10, 0x01},
     53};
     54
     55static const struct cxd2880_reg_value rf_init1_seq8[] = {
     56	{0x00, 0x10}, {0x25, 0x01},
     57};
     58
     59static const struct cxd2880_reg_value rf_init1_seq9[] = {
     60	{0x00, 0x10}, {0x14, 0x01}, {0x00, 0x00}, {0x26, 0x00},
     61};
     62
     63static const struct cxd2880_reg_value rf_init2_seq1[] = {
     64	{0x00, 0x14}, {0x1b, 0x01},
     65};
     66
     67static const struct cxd2880_reg_value rf_init2_seq2[] = {
     68	{0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1}, {0xd3, 0x00},
     69	{0x00, 0x00}, {0x21, 0x00},
     70};
     71
     72static const struct cxd2880_reg_value x_tune1_seq1[] = {
     73	{0x00, 0x00}, {0x10, 0x01},
     74};
     75
     76static const struct cxd2880_reg_value x_tune1_seq2[] = {
     77	{0x62, 0x00}, {0x00, 0x15},
     78};
     79
     80static const struct cxd2880_reg_value x_tune2_seq1[] = {
     81	{0x00, 0x1a}, {0x29, 0x01},
     82};
     83
     84static const struct cxd2880_reg_value x_tune2_seq2[] = {
     85	{0x62, 0x01}, {0x00, 0x11}, {0x2d, 0x00}, {0x2f, 0x00},
     86};
     87
     88static const struct cxd2880_reg_value x_tune2_seq3[] = {
     89	{0x00, 0x00}, {0x10, 0x00}, {0x21, 0x01},
     90};
     91
     92static const struct cxd2880_reg_value x_tune2_seq4[] = {
     93	{0x00, 0xe1}, {0x8a, 0x87},
     94};
     95
     96static const struct cxd2880_reg_value x_tune2_seq5[] = {
     97	{0x00, 0x00}, {0x21, 0x00},
     98};
     99
    100static const struct cxd2880_reg_value x_tune3_seq[] = {
    101	{0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0xa0},
    102	{0x00, 0x00}, {0x21, 0x00}, {0xfe, 0x01},
    103};
    104
    105static const struct cxd2880_reg_value x_tune4_seq[] = {
    106	{0x00, 0x00}, {0xfe, 0x01},
    107};
    108
    109static const struct cxd2880_reg_value x_sleep1_seq[] = {
    110	{0x00, 0x00}, {0x57, 0x03},
    111};
    112
    113static const struct cxd2880_reg_value x_sleep2_seq1[] = {
    114	{0x00, 0x2d}, {0xb1, 0x01},
    115};
    116
    117static const struct cxd2880_reg_value x_sleep2_seq2[] = {
    118	{0x00, 0x10}, {0xf4, 0x00}, {0xf3, 0x00}, {0xf2, 0x00},
    119	{0xf1, 0x00}, {0xf0, 0x00}, {0xef, 0x00},
    120};
    121
    122static const struct cxd2880_reg_value x_sleep3_seq[] = {
    123	{0x00, 0x00}, {0xfd, 0x00},
    124};
    125
    126static const struct cxd2880_reg_value x_sleep4_seq[] = {
    127	{0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0x00},
    128	{0x00, 0x00}, {0x21, 0x00},
    129};
    130
    131static const struct cxd2880_reg_value spll_reset_seq1[] = {
    132	{0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01},
    133	{0x26, 0x01},
    134};
    135
    136static const struct cxd2880_reg_value spll_reset_seq2[] = {
    137	{0x00, 0x00}, {0x10, 0x00},
    138};
    139
    140static const struct cxd2880_reg_value spll_reset_seq3[] = {
    141	{0x00, 0x00}, {0x27, 0x00}, {0x22, 0x01},
    142};
    143
    144static const struct cxd2880_reg_value spll_reset_seq4[] = {
    145	{0x00, 0x00}, {0x27, 0x01},
    146};
    147
    148static const struct cxd2880_reg_value spll_reset_seq5[] = {
    149	{0x00, 0x00}, {0x10, 0x01},
    150};
    151
    152static const struct cxd2880_reg_value t_power_x_seq1[] = {
    153	{0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01},
    154};
    155
    156static const struct cxd2880_reg_value t_power_x_seq2[] = {
    157	{0x00, 0x00}, {0x10, 0x00},
    158};
    159
    160static const struct cxd2880_reg_value t_power_x_seq3[] = {
    161	{0x00, 0x00}, {0x27, 0x00}, {0x25, 0x01},
    162};
    163
    164static const struct cxd2880_reg_value t_power_x_seq4[] = {
    165	{0x00, 0x00}, {0x2a, 0x00},
    166};
    167
    168static const struct cxd2880_reg_value t_power_x_seq5[] = {
    169	{0x00, 0x00}, {0x25, 0x00},
    170};
    171
    172static const struct cxd2880_reg_value t_power_x_seq6[] = {
    173	{0x00, 0x00}, {0x27, 0x01},
    174};
    175
    176static const struct cxd2880_reg_value t_power_x_seq7[] = {
    177	{0x00, 0x00}, {0x10, 0x01},
    178};
    179
    180static const struct cxd2880_reg_value set_ts_pin_seq[] = {
    181	{0x50, 0x3f}, {0x52, 0x1f},
    182
    183};
    184
    185static const struct cxd2880_reg_value set_ts_output_seq1[] = {
    186	{0x00, 0x00}, {0x52, 0x00},
    187};
    188
    189static const struct cxd2880_reg_value set_ts_output_seq2[] = {
    190	{0x00, 0x00}, {0xc3, 0x00},
    191
    192};
    193
    194static const struct cxd2880_reg_value set_ts_output_seq3[] = {
    195	{0x00, 0x00}, {0xc3, 0x01},
    196
    197};
    198
    199static const struct cxd2880_reg_value set_ts_output_seq4[] = {
    200	{0x00, 0x00}, {0x52, 0x1f},
    201
    202};
    203
    204static int p_init1(struct cxd2880_tnrdmd *tnr_dmd)
    205{
    206	u8 data = 0;
    207	int ret;
    208
    209	if (!tnr_dmd)
    210		return -EINVAL;
    211
    212	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    213				     CXD2880_IO_TGT_SYS,
    214				     0x00, 0x00);
    215	if (ret)
    216		return ret;
    217
    218	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE ||
    219	    tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
    220		switch (tnr_dmd->create_param.ts_output_if) {
    221		case CXD2880_TNRDMD_TSOUT_IF_TS:
    222			data = 0x00;
    223			break;
    224		case CXD2880_TNRDMD_TSOUT_IF_SPI:
    225			data = 0x01;
    226			break;
    227		case CXD2880_TNRDMD_TSOUT_IF_SDIO:
    228			data = 0x02;
    229			break;
    230		default:
    231			return -EINVAL;
    232		}
    233		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    234					     CXD2880_IO_TGT_SYS,
    235					     0x10, data);
    236		if (ret)
    237			return ret;
    238	}
    239
    240	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    241					  CXD2880_IO_TGT_SYS,
    242					  p_init1_seq,
    243					  ARRAY_SIZE(p_init1_seq));
    244	if (ret)
    245		return ret;
    246
    247	switch (tnr_dmd->chip_id) {
    248	case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X:
    249		data = 0x1a;
    250		break;
    251	case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11:
    252		data = 0x16;
    253		break;
    254	default:
    255		return -ENOTTY;
    256	}
    257
    258	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    259				     CXD2880_IO_TGT_SYS,
    260				     0x10, data);
    261	if (ret)
    262		return ret;
    263
    264	if (tnr_dmd->create_param.en_internal_ldo)
    265		data = 0x01;
    266	else
    267		data = 0x00;
    268
    269	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    270				     CXD2880_IO_TGT_SYS,
    271				     0x11, data);
    272	if (ret)
    273		return ret;
    274	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    275				     CXD2880_IO_TGT_SYS,
    276				     0x13, data);
    277	if (ret)
    278		return ret;
    279
    280	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    281				     CXD2880_IO_TGT_SYS,
    282				     0x00, 0x00);
    283	if (ret)
    284		return ret;
    285	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    286				     CXD2880_IO_TGT_SYS,
    287				     0x12, data);
    288	if (ret)
    289		return ret;
    290
    291	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    292				     CXD2880_IO_TGT_SYS,
    293				     0x00, 0x10);
    294	if (ret)
    295		return ret;
    296
    297	switch (tnr_dmd->chip_id) {
    298	case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X:
    299		data = 0x01;
    300		break;
    301	case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11:
    302		data = 0x00;
    303		break;
    304	default:
    305		return -ENOTTY;
    306	}
    307
    308	return tnr_dmd->io->write_reg(tnr_dmd->io,
    309				      CXD2880_IO_TGT_SYS,
    310				      0x69, data);
    311}
    312
    313static int p_init2(struct cxd2880_tnrdmd *tnr_dmd)
    314{
    315	u8 data[6] = { 0 };
    316	int ret;
    317
    318	if (!tnr_dmd)
    319		return -EINVAL;
    320
    321	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    322				     CXD2880_IO_TGT_SYS,
    323				     0x00, 0x00);
    324	if (ret)
    325		return ret;
    326	data[0] = tnr_dmd->create_param.xosc_cap;
    327	data[1] = tnr_dmd->create_param.xosc_i;
    328	switch (tnr_dmd->create_param.xtal_share_type) {
    329	case CXD2880_TNRDMD_XTAL_SHARE_NONE:
    330		data[2] = 0x01;
    331		data[3] = 0x00;
    332		break;
    333	case CXD2880_TNRDMD_XTAL_SHARE_EXTREF:
    334		data[2] = 0x00;
    335		data[3] = 0x00;
    336		break;
    337	case CXD2880_TNRDMD_XTAL_SHARE_MASTER:
    338		data[2] = 0x01;
    339		data[3] = 0x01;
    340		break;
    341	case CXD2880_TNRDMD_XTAL_SHARE_SLAVE:
    342		data[2] = 0x00;
    343		data[3] = 0x01;
    344		break;
    345	default:
    346		return -EINVAL;
    347	}
    348	data[4] = 0x06;
    349	data[5] = 0x00;
    350
    351	return tnr_dmd->io->write_regs(tnr_dmd->io,
    352				       CXD2880_IO_TGT_SYS,
    353				       0x13, data, 6);
    354}
    355
    356static int p_init3(struct cxd2880_tnrdmd *tnr_dmd)
    357{
    358	u8 data[2] = { 0 };
    359	int ret;
    360
    361	if (!tnr_dmd)
    362		return -EINVAL;
    363
    364	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    365				     CXD2880_IO_TGT_SYS,
    366				     0x00, 0x00);
    367	if (ret)
    368		return ret;
    369
    370	switch (tnr_dmd->diver_mode) {
    371	case CXD2880_TNRDMD_DIVERMODE_SINGLE:
    372		data[0] = 0x00;
    373		break;
    374	case CXD2880_TNRDMD_DIVERMODE_MAIN:
    375		data[0] = 0x03;
    376		break;
    377	case CXD2880_TNRDMD_DIVERMODE_SUB:
    378		data[0] = 0x02;
    379		break;
    380	default:
    381		return -EINVAL;
    382	}
    383
    384	data[1] = 0x01;
    385
    386	return tnr_dmd->io->write_regs(tnr_dmd->io,
    387				       CXD2880_IO_TGT_SYS,
    388				       0x1f, data, 2);
    389}
    390
    391static int rf_init1(struct cxd2880_tnrdmd *tnr_dmd)
    392{
    393	u8 data[8] = { 0 };
    394	static const u8 rf_init1_cdata1[40] = {
    395		0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
    396		0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03,
    397		0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x02,
    398		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
    399		0x02, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02,
    400		0x02, 0x03, 0x04, 0x04, 0x04
    401	};
    402
    403	static const u8 rf_init1_cdata2[5] = {0xff, 0x00, 0x00, 0x00, 0x00};
    404	static const u8 rf_init1_cdata3[80] = {
    405		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
    406		0x01, 0x00, 0x02, 0x00, 0x63, 0x00, 0x00,
    407		0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
    408		0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x09,
    409		0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0d, 0x00,
    410		0x0d, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f,
    411		0x00, 0x10, 0x00, 0x79, 0x00, 0x00, 0x00,
    412		0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01,
    413		0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
    414		0x04, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05,
    415		0x00, 0x07, 0x00, 0x07, 0x00, 0x08, 0x00,
    416		0x0a, 0x03, 0xe0
    417	};
    418
    419	static const u8 rf_init1_cdata4[8] = {
    420		0x20, 0x20, 0x30, 0x41, 0x50, 0x5f, 0x6f, 0x80
    421	};
    422
    423	static const u8 rf_init1_cdata5[50] = {
    424		0x00, 0x09, 0x00, 0x08, 0x00, 0x07, 0x00,
    425		0x06, 0x00, 0x05, 0x00, 0x03, 0x00, 0x02,
    426		0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
    427		0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0c,
    428		0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0f, 0x00,
    429		0x0e, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f,
    430		0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f, 0x00,
    431		0x0e
    432	};
    433
    434	u8 addr = 0;
    435	int ret;
    436
    437	if (!tnr_dmd)
    438		return -EINVAL;
    439
    440	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    441				     CXD2880_IO_TGT_SYS,
    442				     0x00, 0x00);
    443	if (ret)
    444		return ret;
    445	data[0] = 0x01;
    446	data[1] = 0x00;
    447	data[2] = 0x01;
    448	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    449				      CXD2880_IO_TGT_SYS,
    450				      0x21, data, 3);
    451	if (ret)
    452		return ret;
    453
    454	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    455				     CXD2880_IO_TGT_SYS,
    456				     0x00, 0x10);
    457	if (ret)
    458		return ret;
    459	data[0] = 0x01;
    460	data[1] = 0x01;
    461	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    462				      CXD2880_IO_TGT_SYS,
    463				      0x17, data, 2);
    464	if (ret)
    465		return ret;
    466
    467	if (tnr_dmd->create_param.stationary_use) {
    468		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    469					     CXD2880_IO_TGT_SYS,
    470					     0x1a, 0x06);
    471		if (ret)
    472			return ret;
    473	}
    474
    475	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    476					  CXD2880_IO_TGT_SYS,
    477					  rf_init1_seq1,
    478					  ARRAY_SIZE(rf_init1_seq1));
    479	if (ret)
    480		return ret;
    481
    482	data[0] = 0x00;
    483	if (tnr_dmd->create_param.is_cxd2881gg &&
    484	    tnr_dmd->create_param.xtal_share_type ==
    485		CXD2880_TNRDMD_XTAL_SHARE_SLAVE)
    486		data[1] = 0x00;
    487	else
    488		data[1] = 0x1f;
    489	data[2] = 0x0a;
    490	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    491				      CXD2880_IO_TGT_SYS,
    492				      0xb5, data, 3);
    493	if (ret)
    494		return ret;
    495
    496	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    497					  CXD2880_IO_TGT_SYS,
    498					  rf_init1_seq2,
    499					  ARRAY_SIZE(rf_init1_seq2));
    500	if (ret)
    501		return ret;
    502
    503	if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) {
    504		data[0] = 0x34;
    505		data[1] = 0x2c;
    506	} else {
    507		data[0] = 0x2f;
    508		data[1] = 0x25;
    509	}
    510	data[2] = 0x15;
    511	data[3] = 0x19;
    512	data[4] = 0x1b;
    513	data[5] = 0x15;
    514	data[6] = 0x19;
    515	data[7] = 0x1b;
    516	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    517				      CXD2880_IO_TGT_SYS,
    518				      0xd9, data, 8);
    519	if (ret)
    520		return ret;
    521
    522	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    523				     CXD2880_IO_TGT_SYS,
    524				     0x00, 0x11);
    525	if (ret)
    526		return ret;
    527	data[0] = 0x6c;
    528	data[1] = 0x10;
    529	data[2] = 0xa6;
    530	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    531				      CXD2880_IO_TGT_SYS,
    532				      0x44, data, 3);
    533	if (ret)
    534		return ret;
    535	data[0] = 0x16;
    536	data[1] = 0xa8;
    537	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    538				      CXD2880_IO_TGT_SYS,
    539				      0x50, data, 2);
    540	if (ret)
    541		return ret;
    542	data[0] = 0x00;
    543	data[1] = 0x22;
    544	data[2] = 0x00;
    545	data[3] = 0x88;
    546	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    547				      CXD2880_IO_TGT_SYS,
    548				      0x62, data, 4);
    549	if (ret)
    550		return ret;
    551	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    552				     CXD2880_IO_TGT_SYS,
    553				     0x74, 0x75);
    554	if (ret)
    555		return ret;
    556	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    557				      CXD2880_IO_TGT_SYS,
    558				      0x7f, rf_init1_cdata1, 40);
    559	if (ret)
    560		return ret;
    561
    562	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    563				     CXD2880_IO_TGT_SYS,
    564				     0x00, 0x16);
    565	if (ret)
    566		return ret;
    567	data[0] = 0x00;
    568	data[1] = 0x71;
    569	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    570				      CXD2880_IO_TGT_SYS,
    571				      0x10, data, 2);
    572	if (ret)
    573		return ret;
    574	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    575				     CXD2880_IO_TGT_SYS,
    576				     0x23, 0x89);
    577	if (ret)
    578		return ret;
    579
    580	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    581				      CXD2880_IO_TGT_SYS,
    582				      0x27, rf_init1_cdata2, 5);
    583	if (ret)
    584		return ret;
    585
    586	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    587				      CXD2880_IO_TGT_SYS,
    588				      0x3a, rf_init1_cdata3, 80);
    589	if (ret)
    590		return ret;
    591
    592	data[0] = 0x03;
    593	data[1] = 0xe0;
    594	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    595				      CXD2880_IO_TGT_SYS,
    596				      0xbc, data, 2);
    597	if (ret)
    598		return ret;
    599
    600	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    601					  CXD2880_IO_TGT_SYS,
    602					  rf_init1_seq3,
    603					  ARRAY_SIZE(rf_init1_seq3));
    604	if (ret)
    605		return ret;
    606
    607	if (tnr_dmd->create_param.stationary_use) {
    608		data[0] = 0x06;
    609		data[1] = 0x07;
    610		data[2] = 0x1a;
    611	} else {
    612		data[0] = 0x00;
    613		data[1] = 0x08;
    614		data[2] = 0x19;
    615	}
    616	data[3] = 0x0e;
    617	data[4] = 0x09;
    618	data[5] = 0x0e;
    619
    620	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    621				     CXD2880_IO_TGT_SYS,
    622				     0x00, 0x12);
    623	if (ret)
    624		return ret;
    625	for (addr = 0x10; addr < 0x9f; addr += 6) {
    626		if (tnr_dmd->lna_thrs_tbl_air) {
    627			u8 idx = 0;
    628
    629			idx = (addr - 0x10) / 6;
    630			data[0] =
    631			    tnr_dmd->lna_thrs_tbl_air->thrs[idx].off_on;
    632			data[1] =
    633			    tnr_dmd->lna_thrs_tbl_air->thrs[idx].on_off;
    634		}
    635		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    636					      CXD2880_IO_TGT_SYS,
    637					      addr, data, 6);
    638		if (ret)
    639			return ret;
    640	}
    641
    642	data[0] = 0x00;
    643	data[1] = 0x08;
    644	if (tnr_dmd->create_param.stationary_use)
    645		data[2] = 0x1a;
    646	else
    647		data[2] = 0x19;
    648	data[3] = 0x0e;
    649	data[4] = 0x09;
    650	data[5] = 0x0e;
    651
    652	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    653				     CXD2880_IO_TGT_SYS,
    654				     0x00, 0x13);
    655	if (ret)
    656		return ret;
    657	for (addr = 0x10; addr < 0xcf; addr += 6) {
    658		if (tnr_dmd->lna_thrs_tbl_cable) {
    659			u8 idx = 0;
    660
    661			idx = (addr - 0x10) / 6;
    662			data[0] =
    663			    tnr_dmd->lna_thrs_tbl_cable->thrs[idx].off_on;
    664			data[1] =
    665			    tnr_dmd->lna_thrs_tbl_cable->thrs[idx].on_off;
    666		}
    667		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    668					      CXD2880_IO_TGT_SYS,
    669					      addr, data, 6);
    670		if (ret)
    671			return ret;
    672	}
    673
    674	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    675				     CXD2880_IO_TGT_SYS,
    676				     0x00, 0x11);
    677	if (ret)
    678		return ret;
    679	data[0] = 0x08;
    680	data[1] = 0x09;
    681	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    682				      CXD2880_IO_TGT_SYS,
    683				      0xbd, data, 2);
    684	if (ret)
    685		return ret;
    686	data[0] = 0x08;
    687	data[1] = 0x09;
    688	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    689				      CXD2880_IO_TGT_SYS,
    690				      0xc4, data, 2);
    691	if (ret)
    692		return ret;
    693
    694	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    695				      CXD2880_IO_TGT_SYS,
    696				      0xc9, rf_init1_cdata4, 8);
    697	if (ret)
    698		return ret;
    699
    700	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    701				     CXD2880_IO_TGT_SYS,
    702				     0x00, 0x14);
    703	if (ret)
    704		return ret;
    705	data[0] = 0x15;
    706	data[1] = 0x18;
    707	data[2] = 0x00;
    708	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    709				      CXD2880_IO_TGT_SYS,
    710				      0x10, data, 3);
    711	if (ret)
    712		return ret;
    713
    714	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    715					  CXD2880_IO_TGT_SYS,
    716					  rf_init1_seq4,
    717					  ARRAY_SIZE(rf_init1_seq4));
    718	if (ret)
    719		return ret;
    720
    721	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    722				      CXD2880_IO_TGT_SYS,
    723				      0x12, rf_init1_cdata5, 50);
    724	if (ret)
    725		return ret;
    726
    727	usleep_range(1000, 2000);
    728
    729	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    730				     CXD2880_IO_TGT_SYS,
    731				     0x00, 0x0a);
    732	if (ret)
    733		return ret;
    734	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
    735				     CXD2880_IO_TGT_SYS,
    736				     0x10, data, 1);
    737	if (ret)
    738		return ret;
    739	if ((data[0] & 0x01) == 0x00)
    740		return -EINVAL;
    741
    742	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    743					  CXD2880_IO_TGT_SYS,
    744					  rf_init1_seq5,
    745					  ARRAY_SIZE(rf_init1_seq5));
    746	if (ret)
    747		return ret;
    748
    749	usleep_range(1000, 2000);
    750
    751	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    752				     CXD2880_IO_TGT_SYS,
    753				     0x00, 0x0a);
    754	if (ret)
    755		return ret;
    756	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
    757				     CXD2880_IO_TGT_SYS,
    758				     0x11, data, 1);
    759	if (ret)
    760		return ret;
    761	if ((data[0] & 0x01) == 0x00)
    762		return -EINVAL;
    763
    764	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    765					  CXD2880_IO_TGT_DMD,
    766					  rf_init1_seq6,
    767					  ARRAY_SIZE(rf_init1_seq6));
    768	if (ret)
    769		return ret;
    770
    771	data[0] = 0x00;
    772	data[1] = 0xfe;
    773	data[2] = 0xee;
    774	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    775				      CXD2880_IO_TGT_DMD,
    776				      0x6e, data, 3);
    777	if (ret)
    778		return ret;
    779	data[0] = 0xa1;
    780	data[1] = 0x8b;
    781	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    782				      CXD2880_IO_TGT_DMD,
    783				      0x8d, data, 2);
    784	if (ret)
    785		return ret;
    786	data[0] = 0x08;
    787	data[1] = 0x09;
    788	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    789				      CXD2880_IO_TGT_DMD,
    790				      0x77, data, 2);
    791	if (ret)
    792		return ret;
    793
    794	if (tnr_dmd->create_param.stationary_use) {
    795		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    796					     CXD2880_IO_TGT_DMD,
    797					     0x80, 0xaa);
    798		if (ret)
    799			return ret;
    800	}
    801
    802	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    803					  CXD2880_IO_TGT_DMD,
    804					  rf_init1_seq7,
    805					  ARRAY_SIZE(rf_init1_seq7));
    806	if (ret)
    807		return ret;
    808
    809	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    810					  CXD2880_IO_TGT_SYS,
    811					  rf_init1_seq8,
    812					  ARRAY_SIZE(rf_init1_seq8));
    813	if (ret)
    814		return ret;
    815
    816	usleep_range(1000, 2000);
    817
    818	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    819				     CXD2880_IO_TGT_SYS,
    820				     0x00, 0x1a);
    821	if (ret)
    822		return ret;
    823	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
    824				     CXD2880_IO_TGT_SYS,
    825				     0x10, data, 1);
    826	if (ret)
    827		return ret;
    828	if ((data[0] & 0x01) == 0x00)
    829		return -EINVAL;
    830
    831	return cxd2880_io_write_multi_regs(tnr_dmd->io,
    832					   CXD2880_IO_TGT_SYS,
    833					   rf_init1_seq9,
    834					   ARRAY_SIZE(rf_init1_seq9));
    835}
    836
    837static int rf_init2(struct cxd2880_tnrdmd *tnr_dmd)
    838{
    839	u8 data[5] = { 0 };
    840	int ret;
    841
    842	if (!tnr_dmd)
    843		return -EINVAL;
    844
    845	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    846				     CXD2880_IO_TGT_SYS,
    847				     0x00, 0x10);
    848	if (ret)
    849		return ret;
    850	data[0] = 0x40;
    851	data[1] = 0x40;
    852	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    853				      CXD2880_IO_TGT_SYS,
    854				      0xea, data, 2);
    855	if (ret)
    856		return ret;
    857
    858	usleep_range(1000, 2000);
    859
    860	data[0] = 0x00;
    861	if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X)
    862		data[1] = 0x00;
    863	else
    864		data[1] = 0x01;
    865	data[2] = 0x01;
    866	data[3] = 0x03;
    867	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    868				      CXD2880_IO_TGT_SYS,
    869				      0x30, data, 4);
    870	if (ret)
    871		return ret;
    872
    873	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    874					  CXD2880_IO_TGT_SYS,
    875					  rf_init2_seq1,
    876					  ARRAY_SIZE(rf_init2_seq1));
    877	if (ret)
    878		return ret;
    879
    880	return cxd2880_io_write_multi_regs(tnr_dmd->io,
    881					   CXD2880_IO_TGT_DMD,
    882					   rf_init2_seq2,
    883					   ARRAY_SIZE(rf_init2_seq2));
    884}
    885
    886static int x_tune1(struct cxd2880_tnrdmd *tnr_dmd,
    887		   enum cxd2880_dtv_sys sys, u32 freq_khz,
    888		   enum cxd2880_dtv_bandwidth bandwidth,
    889		   u8 is_cable, int shift_frequency_khz)
    890{
    891	u8 data[11] = { 0 };
    892	int ret;
    893
    894	if (!tnr_dmd)
    895		return -EINVAL;
    896
    897	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    898					  CXD2880_IO_TGT_DMD,
    899					  x_tune1_seq1,
    900					  ARRAY_SIZE(x_tune1_seq1));
    901	if (ret)
    902		return ret;
    903
    904	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    905				     CXD2880_IO_TGT_SYS,
    906				     0x00, 0x10);
    907	if (ret)
    908		return ret;
    909
    910	data[2] = 0x0e;
    911	data[4] = 0x03;
    912	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    913				      CXD2880_IO_TGT_SYS,
    914				      0xe7, data, 5);
    915	if (ret)
    916		return ret;
    917
    918	data[0] = 0x1f;
    919	data[1] = 0x80;
    920	data[2] = 0x18;
    921	data[3] = 0x00;
    922	data[4] = 0x07;
    923	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    924				      CXD2880_IO_TGT_SYS,
    925				      0xe7, data, 5);
    926	if (ret)
    927		return ret;
    928
    929	usleep_range(1000, 2000);
    930
    931	data[0] = 0x72;
    932	data[1] = 0x81;
    933	data[3] = 0x1d;
    934	data[4] = 0x6f;
    935	data[5] = 0x7e;
    936	data[7] = 0x1c;
    937	switch (sys) {
    938	case CXD2880_DTV_SYS_DVBT:
    939		data[2] = 0x94;
    940		data[6] = 0x91;
    941		break;
    942	case CXD2880_DTV_SYS_DVBT2:
    943		data[2] = 0x96;
    944		data[6] = 0x93;
    945		break;
    946	default:
    947		return -EINVAL;
    948	}
    949	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    950				      CXD2880_IO_TGT_SYS,
    951				      0x44, data, 8);
    952	if (ret)
    953		return ret;
    954
    955	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
    956					  CXD2880_IO_TGT_SYS,
    957					  x_tune1_seq2,
    958					  ARRAY_SIZE(x_tune1_seq2));
    959	if (ret)
    960		return ret;
    961
    962	data[0] = 0x03;
    963	data[1] = 0xe2;
    964	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
    965				      CXD2880_IO_TGT_SYS,
    966				      0x1e, data, 2);
    967	if (ret)
    968		return ret;
    969
    970	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
    971				     CXD2880_IO_TGT_SYS,
    972				     0x00, 0x10);
    973	if (ret)
    974		return ret;
    975
    976	data[0] = is_cable ? 0x01 : 0x00;
    977	data[1] = 0x00;
    978	data[2] = 0x6b;
    979	data[3] = 0x4d;
    980
    981	switch (bandwidth) {
    982	case CXD2880_DTV_BW_1_7_MHZ:
    983		data[4] = 0x03;
    984		break;
    985	case CXD2880_DTV_BW_5_MHZ:
    986	case CXD2880_DTV_BW_6_MHZ:
    987		data[4] = 0x00;
    988		break;
    989	case CXD2880_DTV_BW_7_MHZ:
    990		data[4] = 0x01;
    991		break;
    992	case CXD2880_DTV_BW_8_MHZ:
    993		data[4] = 0x02;
    994		break;
    995	default:
    996		return -EINVAL;
    997	}
    998
    999	data[5] = 0x00;
   1000
   1001	freq_khz += shift_frequency_khz;
   1002
   1003	data[6] = (freq_khz >> 16) & 0x0f;
   1004	data[7] = (freq_khz >> 8) & 0xff;
   1005	data[8] = freq_khz & 0xff;
   1006	data[9] = 0xff;
   1007	data[10] = 0xfe;
   1008
   1009	return tnr_dmd->io->write_regs(tnr_dmd->io,
   1010				       CXD2880_IO_TGT_SYS,
   1011				       0x52, data, 11);
   1012}
   1013
   1014static int x_tune2(struct cxd2880_tnrdmd *tnr_dmd,
   1015		   enum cxd2880_dtv_bandwidth bandwidth,
   1016		   enum cxd2880_tnrdmd_clockmode clk_mode,
   1017		   int shift_frequency_khz)
   1018{
   1019	u8 data[3] = { 0 };
   1020	int ret;
   1021
   1022	if (!tnr_dmd)
   1023		return -EINVAL;
   1024
   1025	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1026				     CXD2880_IO_TGT_SYS,
   1027				     0x00, 0x11);
   1028	if (ret)
   1029		return ret;
   1030
   1031	data[0] = 0x01;
   1032	data[1] = 0x0e;
   1033	data[2] = 0x01;
   1034	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
   1035				      CXD2880_IO_TGT_SYS,
   1036				      0x2d, data, 3);
   1037	if (ret)
   1038		return ret;
   1039
   1040	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1041					  CXD2880_IO_TGT_SYS,
   1042					  x_tune2_seq1,
   1043					  ARRAY_SIZE(x_tune2_seq1));
   1044	if (ret)
   1045		return ret;
   1046
   1047	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   1048				     CXD2880_IO_TGT_SYS,
   1049				     0x2c, data, 1);
   1050	if (ret)
   1051		return ret;
   1052
   1053	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1054				     CXD2880_IO_TGT_SYS,
   1055				     0x00, 0x10);
   1056	if (ret)
   1057		return ret;
   1058
   1059	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1060				     CXD2880_IO_TGT_SYS,
   1061				     0x60, data[0]);
   1062	if (ret)
   1063		return ret;
   1064
   1065	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1066					  CXD2880_IO_TGT_SYS,
   1067					  x_tune2_seq2,
   1068					  ARRAY_SIZE(x_tune2_seq2));
   1069	if (ret)
   1070		return ret;
   1071
   1072	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1073					  CXD2880_IO_TGT_DMD,
   1074					  x_tune2_seq3,
   1075					  ARRAY_SIZE(x_tune2_seq3));
   1076	if (ret)
   1077		return ret;
   1078
   1079	if (shift_frequency_khz != 0) {
   1080		int shift_freq = 0;
   1081
   1082		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1083					     CXD2880_IO_TGT_DMD,
   1084					     0x00, 0xe1);
   1085		if (ret)
   1086			return ret;
   1087
   1088		ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   1089					     CXD2880_IO_TGT_DMD,
   1090					     0x60, data, 2);
   1091		if (ret)
   1092			return ret;
   1093
   1094		shift_freq = shift_frequency_khz * 1000;
   1095
   1096		switch (clk_mode) {
   1097		case CXD2880_TNRDMD_CLOCKMODE_A:
   1098		case CXD2880_TNRDMD_CLOCKMODE_C:
   1099		default:
   1100			if (shift_freq >= 0)
   1101				shift_freq = (shift_freq + 183 / 2) / 183;
   1102			else
   1103				shift_freq = (shift_freq - 183 / 2) / 183;
   1104			break;
   1105		case CXD2880_TNRDMD_CLOCKMODE_B:
   1106			if (shift_freq >= 0)
   1107				shift_freq = (shift_freq + 178 / 2) / 178;
   1108			else
   1109				shift_freq = (shift_freq - 178 / 2) / 178;
   1110			break;
   1111		}
   1112
   1113		shift_freq +=
   1114		    cxd2880_convert2s_complement((data[0] << 8) | data[1], 16);
   1115
   1116		if (shift_freq > 32767)
   1117			shift_freq = 32767;
   1118		else if (shift_freq < -32768)
   1119			shift_freq = -32768;
   1120
   1121		data[0] = (shift_freq >> 8) & 0xff;
   1122		data[1] = shift_freq & 0xff;
   1123
   1124		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
   1125					      CXD2880_IO_TGT_DMD,
   1126					      0x60, data, 2);
   1127		if (ret)
   1128			return ret;
   1129
   1130		ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   1131					     CXD2880_IO_TGT_DMD,
   1132					     0x69, data, 1);
   1133		if (ret)
   1134			return ret;
   1135
   1136		shift_freq = -shift_frequency_khz;
   1137
   1138		if (bandwidth == CXD2880_DTV_BW_1_7_MHZ) {
   1139			switch (clk_mode) {
   1140			case CXD2880_TNRDMD_CLOCKMODE_A:
   1141			case CXD2880_TNRDMD_CLOCKMODE_C:
   1142			default:
   1143				if (shift_freq >= 0)
   1144					shift_freq =
   1145					    (shift_freq * 1000 +
   1146					     17578 / 2) / 17578;
   1147				else
   1148					shift_freq =
   1149					    (shift_freq * 1000 -
   1150					     17578 / 2) / 17578;
   1151				break;
   1152			case CXD2880_TNRDMD_CLOCKMODE_B:
   1153				if (shift_freq >= 0)
   1154					shift_freq =
   1155					    (shift_freq * 1000 +
   1156					     17090 / 2) / 17090;
   1157				else
   1158					shift_freq =
   1159					    (shift_freq * 1000 -
   1160					     17090 / 2) / 17090;
   1161				break;
   1162			}
   1163		} else {
   1164			switch (clk_mode) {
   1165			case CXD2880_TNRDMD_CLOCKMODE_A:
   1166			case CXD2880_TNRDMD_CLOCKMODE_C:
   1167			default:
   1168				if (shift_freq >= 0)
   1169					shift_freq =
   1170					    (shift_freq * 1000 +
   1171					     35156 / 2) / 35156;
   1172				else
   1173					shift_freq =
   1174					    (shift_freq * 1000 -
   1175					     35156 / 2) / 35156;
   1176				break;
   1177			case CXD2880_TNRDMD_CLOCKMODE_B:
   1178				if (shift_freq >= 0)
   1179					shift_freq =
   1180					    (shift_freq * 1000 +
   1181					     34180 / 2) / 34180;
   1182				else
   1183					shift_freq =
   1184					    (shift_freq * 1000 -
   1185					     34180 / 2) / 34180;
   1186				break;
   1187			}
   1188		}
   1189
   1190		shift_freq += cxd2880_convert2s_complement(data[0], 8);
   1191
   1192		if (shift_freq > 127)
   1193			shift_freq = 127;
   1194		else if (shift_freq < -128)
   1195			shift_freq = -128;
   1196
   1197		data[0] = shift_freq & 0xff;
   1198
   1199		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1200					     CXD2880_IO_TGT_DMD,
   1201					     0x69, data[0]);
   1202		if (ret)
   1203			return ret;
   1204	}
   1205
   1206	if (tnr_dmd->create_param.stationary_use) {
   1207		ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1208						  CXD2880_IO_TGT_DMD,
   1209						  x_tune2_seq4,
   1210						  ARRAY_SIZE(x_tune2_seq4));
   1211		if (ret)
   1212			return ret;
   1213	}
   1214
   1215	return cxd2880_io_write_multi_regs(tnr_dmd->io,
   1216					   CXD2880_IO_TGT_DMD,
   1217					   x_tune2_seq5,
   1218					   ARRAY_SIZE(x_tune2_seq5));
   1219}
   1220
   1221static int x_tune3(struct cxd2880_tnrdmd *tnr_dmd,
   1222		   enum cxd2880_dtv_sys sys,
   1223		   u8 en_fef_intmtnt_ctrl)
   1224{
   1225	u8 data[6] = { 0 };
   1226	int ret;
   1227
   1228	if (!tnr_dmd)
   1229		return -EINVAL;
   1230
   1231	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1232					  CXD2880_IO_TGT_DMD,
   1233					  x_tune3_seq,
   1234					  ARRAY_SIZE(x_tune3_seq));
   1235	if (ret)
   1236		return ret;
   1237
   1238	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1239				     CXD2880_IO_TGT_SYS,
   1240				     0x00, 0x10);
   1241	if (ret)
   1242		return ret;
   1243
   1244	if (sys == CXD2880_DTV_SYS_DVBT2 && en_fef_intmtnt_ctrl)
   1245		memset(data, 0x01, sizeof(data));
   1246	else
   1247		memset(data, 0x00, sizeof(data));
   1248
   1249	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
   1250				      CXD2880_IO_TGT_SYS,
   1251				      0xef, data, 6);
   1252	if (ret)
   1253		return ret;
   1254
   1255	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1256				     CXD2880_IO_TGT_DMD,
   1257				     0x00, 0x2d);
   1258	if (ret)
   1259		return ret;
   1260	if (sys == CXD2880_DTV_SYS_DVBT2 && en_fef_intmtnt_ctrl)
   1261		data[0] = 0x00;
   1262	else
   1263		data[0] = 0x01;
   1264
   1265	return tnr_dmd->io->write_reg(tnr_dmd->io,
   1266				      CXD2880_IO_TGT_DMD,
   1267				      0xb1, data[0]);
   1268}
   1269
   1270static int x_tune4(struct cxd2880_tnrdmd *tnr_dmd)
   1271{
   1272	u8 data[2] = { 0 };
   1273	int ret;
   1274
   1275	if (!tnr_dmd)
   1276		return -EINVAL;
   1277
   1278	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
   1279		return -EINVAL;
   1280
   1281	ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
   1282						CXD2880_IO_TGT_SYS,
   1283						0x00, 0x00);
   1284	if (ret)
   1285		return ret;
   1286	data[0] = 0x14;
   1287	data[1] = 0x00;
   1288	ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
   1289						CXD2880_IO_TGT_SYS,
   1290						0x55, data, 2);
   1291	if (ret)
   1292		return ret;
   1293
   1294	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1295				     CXD2880_IO_TGT_SYS,
   1296				     0x00, 0x00);
   1297	if (ret)
   1298		return ret;
   1299	data[0] = 0x0b;
   1300	data[1] = 0xff;
   1301	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
   1302				      CXD2880_IO_TGT_SYS,
   1303				      0x53, data, 2);
   1304	if (ret)
   1305		return ret;
   1306	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1307				     CXD2880_IO_TGT_SYS,
   1308				     0x57, 0x01);
   1309	if (ret)
   1310		return ret;
   1311	data[0] = 0x0b;
   1312	data[1] = 0xff;
   1313	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
   1314				      CXD2880_IO_TGT_SYS,
   1315				      0x55, data, 2);
   1316	if (ret)
   1317		return ret;
   1318
   1319	ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
   1320						CXD2880_IO_TGT_SYS,
   1321						0x00, 0x00);
   1322	if (ret)
   1323		return ret;
   1324	data[0] = 0x14;
   1325	data[1] = 0x00;
   1326	ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
   1327						 CXD2880_IO_TGT_SYS,
   1328						 0x53, data, 2);
   1329	if (ret)
   1330		return ret;
   1331	ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
   1332						CXD2880_IO_TGT_SYS,
   1333						0x57, 0x02);
   1334	if (ret)
   1335		return ret;
   1336
   1337	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1338					  CXD2880_IO_TGT_DMD,
   1339					  x_tune4_seq,
   1340					  ARRAY_SIZE(x_tune4_seq));
   1341	if (ret)
   1342		return ret;
   1343
   1344	return cxd2880_io_write_multi_regs(tnr_dmd->diver_sub->io,
   1345					   CXD2880_IO_TGT_DMD,
   1346					   x_tune4_seq,
   1347					   ARRAY_SIZE(x_tune4_seq));
   1348}
   1349
   1350static int x_sleep1(struct cxd2880_tnrdmd *tnr_dmd)
   1351{
   1352	u8 data[3] = { 0 };
   1353	int ret;
   1354
   1355	if (!tnr_dmd)
   1356		return -EINVAL;
   1357
   1358	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
   1359		return -EINVAL;
   1360
   1361	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1362					  CXD2880_IO_TGT_SYS,
   1363					  x_sleep1_seq,
   1364					  ARRAY_SIZE(x_sleep1_seq));
   1365	if (ret)
   1366		return ret;
   1367
   1368	data[0] = 0x00;
   1369	data[1] = 0x00;
   1370	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
   1371				      CXD2880_IO_TGT_SYS,
   1372				      0x53, data, 2);
   1373	if (ret)
   1374		return ret;
   1375
   1376	ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
   1377						CXD2880_IO_TGT_SYS,
   1378						0x00, 0x00);
   1379	if (ret)
   1380		return ret;
   1381	data[0] = 0x1f;
   1382	data[1] = 0xff;
   1383	data[2] = 0x03;
   1384	ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
   1385						 CXD2880_IO_TGT_SYS,
   1386						 0x55, data, 3);
   1387	if (ret)
   1388		return ret;
   1389	data[0] = 0x00;
   1390	data[1] = 0x00;
   1391	ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
   1392						 CXD2880_IO_TGT_SYS,
   1393						 0x53, data, 2);
   1394	if (ret)
   1395		return ret;
   1396
   1397	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1398				     CXD2880_IO_TGT_SYS,
   1399				     0x00, 0x00);
   1400	if (ret)
   1401		return ret;
   1402	data[0] = 0x1f;
   1403	data[1] = 0xff;
   1404
   1405	return tnr_dmd->io->write_regs(tnr_dmd->io,
   1406				       CXD2880_IO_TGT_SYS,
   1407				       0x55, data, 2);
   1408}
   1409
   1410static int x_sleep2(struct cxd2880_tnrdmd *tnr_dmd)
   1411{
   1412	u8 data = 0;
   1413	int ret;
   1414
   1415	if (!tnr_dmd)
   1416		return -EINVAL;
   1417
   1418	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1419					  CXD2880_IO_TGT_DMD,
   1420					  x_sleep2_seq1,
   1421					  ARRAY_SIZE(x_sleep2_seq1));
   1422	if (ret)
   1423		return ret;
   1424
   1425	usleep_range(1000, 2000);
   1426
   1427	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   1428				     CXD2880_IO_TGT_DMD,
   1429				     0xb2, &data, 1);
   1430	if (ret)
   1431		return ret;
   1432
   1433	if ((data & 0x01) == 0x00)
   1434		return -EINVAL;
   1435
   1436	return cxd2880_io_write_multi_regs(tnr_dmd->io,
   1437					   CXD2880_IO_TGT_SYS,
   1438					   x_sleep2_seq2,
   1439					   ARRAY_SIZE(x_sleep2_seq2));
   1440}
   1441
   1442static int x_sleep3(struct cxd2880_tnrdmd *tnr_dmd)
   1443{
   1444	if (!tnr_dmd)
   1445		return -EINVAL;
   1446
   1447	return cxd2880_io_write_multi_regs(tnr_dmd->io,
   1448					   CXD2880_IO_TGT_DMD,
   1449					   x_sleep3_seq,
   1450					   ARRAY_SIZE(x_sleep3_seq));
   1451}
   1452
   1453static int x_sleep4(struct cxd2880_tnrdmd *tnr_dmd)
   1454{
   1455	if (!tnr_dmd)
   1456		return -EINVAL;
   1457
   1458	return cxd2880_io_write_multi_regs(tnr_dmd->io,
   1459					   CXD2880_IO_TGT_DMD,
   1460					   x_sleep4_seq,
   1461					   ARRAY_SIZE(x_sleep4_seq));
   1462}
   1463
   1464static int spll_reset(struct cxd2880_tnrdmd *tnr_dmd,
   1465		      enum cxd2880_tnrdmd_clockmode clockmode)
   1466{
   1467	u8 data[4] = { 0 };
   1468	int ret;
   1469
   1470	if (!tnr_dmd)
   1471		return -EINVAL;
   1472
   1473	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1474					  CXD2880_IO_TGT_SYS,
   1475					  spll_reset_seq1,
   1476					  ARRAY_SIZE(spll_reset_seq1));
   1477	if (ret)
   1478		return ret;
   1479
   1480	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1481					  CXD2880_IO_TGT_DMD,
   1482					  spll_reset_seq2,
   1483					  ARRAY_SIZE(spll_reset_seq2));
   1484	if (ret)
   1485		return ret;
   1486
   1487	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1488					  CXD2880_IO_TGT_SYS,
   1489					  spll_reset_seq3,
   1490					  ARRAY_SIZE(spll_reset_seq3));
   1491	if (ret)
   1492		return ret;
   1493
   1494	switch (clockmode) {
   1495	case CXD2880_TNRDMD_CLOCKMODE_A:
   1496		data[0] = 0x00;
   1497		break;
   1498
   1499	case CXD2880_TNRDMD_CLOCKMODE_B:
   1500		data[0] = 0x01;
   1501		break;
   1502
   1503	case CXD2880_TNRDMD_CLOCKMODE_C:
   1504		data[0] = 0x02;
   1505		break;
   1506
   1507	default:
   1508		return -EINVAL;
   1509	}
   1510	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1511				     CXD2880_IO_TGT_SYS,
   1512				     0x30, data[0]);
   1513	if (ret)
   1514		return ret;
   1515	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1516				     CXD2880_IO_TGT_SYS,
   1517				     0x22, 0x00);
   1518	if (ret)
   1519		return ret;
   1520
   1521	usleep_range(2000, 3000);
   1522
   1523	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1524				     CXD2880_IO_TGT_SYS,
   1525				     0x00, 0x0a);
   1526	if (ret)
   1527		return ret;
   1528	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   1529				     CXD2880_IO_TGT_SYS,
   1530				     0x10, data, 1);
   1531	if (ret)
   1532		return ret;
   1533	if ((data[0] & 0x01) == 0x00)
   1534		return -EINVAL;
   1535
   1536	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1537					  CXD2880_IO_TGT_SYS,
   1538					  spll_reset_seq4,
   1539					  ARRAY_SIZE(spll_reset_seq4));
   1540	if (ret)
   1541		return ret;
   1542
   1543	usleep_range(1000, 2000);
   1544
   1545	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1546					  CXD2880_IO_TGT_DMD,
   1547					  spll_reset_seq5,
   1548					  ARRAY_SIZE(spll_reset_seq5));
   1549	if (ret)
   1550		return ret;
   1551
   1552	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1553				     CXD2880_IO_TGT_SYS,
   1554				     0x00, 0x10);
   1555	if (ret)
   1556		return ret;
   1557
   1558	memset(data, 0x00, sizeof(data));
   1559
   1560	return tnr_dmd->io->write_regs(tnr_dmd->io,
   1561				       CXD2880_IO_TGT_SYS,
   1562				       0x26, data, 4);
   1563}
   1564
   1565static int t_power_x(struct cxd2880_tnrdmd *tnr_dmd, u8 on)
   1566{
   1567	u8 data[3] = { 0 };
   1568	int ret;
   1569
   1570	if (!tnr_dmd)
   1571		return -EINVAL;
   1572
   1573	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1574					  CXD2880_IO_TGT_SYS,
   1575					  t_power_x_seq1,
   1576					  ARRAY_SIZE(t_power_x_seq1));
   1577	if (ret)
   1578		return ret;
   1579
   1580	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1581					  CXD2880_IO_TGT_DMD,
   1582					  t_power_x_seq2,
   1583					  ARRAY_SIZE(t_power_x_seq2));
   1584	if (ret)
   1585		return ret;
   1586
   1587	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1588					  CXD2880_IO_TGT_SYS,
   1589					  t_power_x_seq3,
   1590					  ARRAY_SIZE(t_power_x_seq3));
   1591	if (ret)
   1592		return ret;
   1593
   1594	if (on) {
   1595		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1596					     CXD2880_IO_TGT_SYS,
   1597					     0x2b, 0x01);
   1598		if (ret)
   1599			return ret;
   1600
   1601		usleep_range(1000, 2000);
   1602
   1603		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1604					     CXD2880_IO_TGT_SYS,
   1605					     0x00, 0x0a);
   1606		if (ret)
   1607			return ret;
   1608		ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   1609					     CXD2880_IO_TGT_SYS,
   1610					     0x12, data, 1);
   1611		if (ret)
   1612			return ret;
   1613		if ((data[0] & 0x01) == 0)
   1614			return -EINVAL;
   1615
   1616		ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1617						  CXD2880_IO_TGT_SYS,
   1618						  t_power_x_seq4,
   1619						  ARRAY_SIZE(t_power_x_seq4));
   1620		if (ret)
   1621			return ret;
   1622	} else {
   1623		data[0] = 0x03;
   1624		data[1] = 0x00;
   1625		ret = tnr_dmd->io->write_regs(tnr_dmd->io,
   1626					      CXD2880_IO_TGT_SYS,
   1627					      0x2a, data, 2);
   1628		if (ret)
   1629			return ret;
   1630
   1631		usleep_range(1000, 2000);
   1632
   1633		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1634					     CXD2880_IO_TGT_SYS,
   1635					     0x00, 0x0a);
   1636		if (ret)
   1637			return ret;
   1638		ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   1639					     CXD2880_IO_TGT_SYS,
   1640					     0x13, data, 1);
   1641		if (ret)
   1642			return ret;
   1643		if ((data[0] & 0x01) == 0)
   1644			return -EINVAL;
   1645	}
   1646
   1647	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1648					  CXD2880_IO_TGT_SYS,
   1649					  t_power_x_seq5,
   1650					  ARRAY_SIZE(t_power_x_seq5));
   1651	if (ret)
   1652		return ret;
   1653
   1654	usleep_range(1000, 2000);
   1655
   1656	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1657				     CXD2880_IO_TGT_SYS,
   1658				     0x00, 0x0a);
   1659	if (ret)
   1660		return ret;
   1661	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   1662				     CXD2880_IO_TGT_SYS,
   1663				     0x11, data, 1);
   1664	if (ret)
   1665		return ret;
   1666	if ((data[0] & 0x01) == 0)
   1667		return -EINVAL;
   1668
   1669	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1670					  CXD2880_IO_TGT_SYS,
   1671					  t_power_x_seq6,
   1672					  ARRAY_SIZE(t_power_x_seq6));
   1673	if (ret)
   1674		return ret;
   1675
   1676	usleep_range(1000, 2000);
   1677
   1678	ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   1679					  CXD2880_IO_TGT_DMD,
   1680					  t_power_x_seq7,
   1681					  ARRAY_SIZE(t_power_x_seq7));
   1682	if (ret)
   1683		return ret;
   1684
   1685	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1686				     CXD2880_IO_TGT_SYS,
   1687				     0x00, 0x10);
   1688	if (ret)
   1689		return ret;
   1690
   1691	memset(data, 0x00, sizeof(data));
   1692
   1693	return tnr_dmd->io->write_regs(tnr_dmd->io,
   1694				       CXD2880_IO_TGT_SYS,
   1695				       0x27, data, 3);
   1696}
   1697
   1698struct cxd2880_tnrdmd_ts_clk_cfg {
   1699	u8 srl_clk_mode;
   1700	u8 srl_duty_mode;
   1701	u8 ts_clk_period;
   1702};
   1703
   1704static int set_ts_clk_mode_and_freq(struct cxd2880_tnrdmd *tnr_dmd,
   1705				    enum cxd2880_dtv_sys sys)
   1706{
   1707	int ret;
   1708	u8 backwards_compatible = 0;
   1709	struct cxd2880_tnrdmd_ts_clk_cfg ts_clk_cfg;
   1710	u8 ts_rate_ctrl_off = 0;
   1711	u8 ts_in_off = 0;
   1712	u8 ts_clk_manaul_on = 0;
   1713	u8 data = 0;
   1714
   1715	static const struct cxd2880_tnrdmd_ts_clk_cfg srl_ts_clk_stgs[2][2] = {
   1716		{
   1717			{3, 1, 8,},
   1718			{0, 2, 16,}
   1719		}, {
   1720			{1, 1, 8,},
   1721			{2, 2, 16,}
   1722		}
   1723	};
   1724
   1725	if (!tnr_dmd)
   1726		return -EINVAL;
   1727
   1728	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1729				     CXD2880_IO_TGT_DMD,
   1730				     0x00, 0x00);
   1731	if (ret)
   1732		return ret;
   1733
   1734	if (tnr_dmd->is_ts_backwards_compatible_mode) {
   1735		backwards_compatible = 1;
   1736		ts_rate_ctrl_off = 1;
   1737		ts_in_off = 1;
   1738	} else {
   1739		backwards_compatible = 0;
   1740		ts_rate_ctrl_off = 0;
   1741		ts_in_off = 0;
   1742	}
   1743
   1744	if (tnr_dmd->ts_byte_clk_manual_setting) {
   1745		ts_clk_manaul_on = 1;
   1746		ts_rate_ctrl_off = 0;
   1747	}
   1748
   1749	ret = cxd2880_io_set_reg_bits(tnr_dmd->io,
   1750				      CXD2880_IO_TGT_DMD,
   1751				      0xd3, ts_rate_ctrl_off, 0x01);
   1752	if (ret)
   1753		return ret;
   1754
   1755	ret = cxd2880_io_set_reg_bits(tnr_dmd->io,
   1756				      CXD2880_IO_TGT_DMD,
   1757				      0xde, ts_in_off, 0x01);
   1758	if (ret)
   1759		return ret;
   1760
   1761	ret = cxd2880_io_set_reg_bits(tnr_dmd->io,
   1762				      CXD2880_IO_TGT_DMD,
   1763				      0xda, ts_clk_manaul_on, 0x01);
   1764	if (ret)
   1765		return ret;
   1766
   1767	ts_clk_cfg = srl_ts_clk_stgs[tnr_dmd->srl_ts_clk_mod_cnts]
   1768				    [tnr_dmd->srl_ts_clk_frq];
   1769
   1770	if (tnr_dmd->ts_byte_clk_manual_setting)
   1771		ts_clk_cfg.ts_clk_period = tnr_dmd->ts_byte_clk_manual_setting;
   1772
   1773	ret = cxd2880_io_set_reg_bits(tnr_dmd->io,
   1774				      CXD2880_IO_TGT_DMD,
   1775				      0xc4, ts_clk_cfg.srl_clk_mode, 0x03);
   1776	if (ret)
   1777		return ret;
   1778
   1779	ret = cxd2880_io_set_reg_bits(tnr_dmd->io,
   1780				      CXD2880_IO_TGT_DMD,
   1781				      0xd1, ts_clk_cfg.srl_duty_mode, 0x03);
   1782	if (ret)
   1783		return ret;
   1784
   1785	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1786				     CXD2880_IO_TGT_DMD, 0xd9,
   1787				     ts_clk_cfg.ts_clk_period);
   1788	if (ret)
   1789		return ret;
   1790
   1791	data = backwards_compatible ? 0x00 : 0x01;
   1792
   1793	if (sys == CXD2880_DTV_SYS_DVBT) {
   1794		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1795					     CXD2880_IO_TGT_DMD,
   1796					     0x00, 0x10);
   1797		if (ret)
   1798			return ret;
   1799
   1800		ret =
   1801		    cxd2880_io_set_reg_bits(tnr_dmd->io,
   1802					    CXD2880_IO_TGT_DMD,
   1803					    0x66, data, 0x01);
   1804	}
   1805
   1806	return ret;
   1807}
   1808
   1809static int pid_ftr_setting(struct cxd2880_tnrdmd *tnr_dmd,
   1810			   struct cxd2880_tnrdmd_pid_ftr_cfg
   1811			   *pid_ftr_cfg)
   1812{
   1813	int i;
   1814	int ret;
   1815	u8 data[65];
   1816
   1817	if (!tnr_dmd)
   1818		return -EINVAL;
   1819
   1820	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1821				     CXD2880_IO_TGT_DMD,
   1822				     0x00, 0x00);
   1823	if (ret)
   1824		return ret;
   1825
   1826	if (!pid_ftr_cfg)
   1827		return tnr_dmd->io->write_reg(tnr_dmd->io,
   1828					      CXD2880_IO_TGT_DMD,
   1829					      0x50, 0x02);
   1830
   1831	data[0] = pid_ftr_cfg->is_negative ? 0x01 : 0x00;
   1832
   1833	for (i = 0; i < 32; i++) {
   1834		if (pid_ftr_cfg->pid_cfg[i].is_en) {
   1835			data[1 + (i * 2)] = (pid_ftr_cfg->pid_cfg[i].pid >> 8) | 0x20;
   1836			data[2 + (i * 2)] =  pid_ftr_cfg->pid_cfg[i].pid & 0xff;
   1837		} else {
   1838			data[1 + (i * 2)] = 0x00;
   1839			data[2 + (i * 2)] = 0x00;
   1840		}
   1841	}
   1842
   1843	return tnr_dmd->io->write_regs(tnr_dmd->io,
   1844				       CXD2880_IO_TGT_DMD,
   1845				       0x50, data, 65);
   1846}
   1847
   1848static int load_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd)
   1849{
   1850	int ret;
   1851	u8 i;
   1852
   1853	if (!tnr_dmd)
   1854		return -EINVAL;
   1855
   1856	for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) {
   1857		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   1858					     tnr_dmd->cfg_mem[i].tgt,
   1859					     0x00, tnr_dmd->cfg_mem[i].bank);
   1860		if (ret)
   1861			return ret;
   1862
   1863		ret = cxd2880_io_set_reg_bits(tnr_dmd->io,
   1864					      tnr_dmd->cfg_mem[i].tgt,
   1865					      tnr_dmd->cfg_mem[i].address,
   1866					      tnr_dmd->cfg_mem[i].value,
   1867					      tnr_dmd->cfg_mem[i].bit_mask);
   1868		if (ret)
   1869			return ret;
   1870	}
   1871
   1872	return 0;
   1873}
   1874
   1875static int set_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd,
   1876		       enum cxd2880_io_tgt tgt,
   1877		       u8 bank, u8 address, u8 value, u8 bit_mask)
   1878{
   1879	u8 i;
   1880	u8 value_stored = 0;
   1881
   1882	if (!tnr_dmd)
   1883		return -EINVAL;
   1884
   1885	for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) {
   1886		if (value_stored == 0 &&
   1887		    tnr_dmd->cfg_mem[i].tgt == tgt &&
   1888		    tnr_dmd->cfg_mem[i].bank == bank &&
   1889		    tnr_dmd->cfg_mem[i].address == address) {
   1890			tnr_dmd->cfg_mem[i].value &= ~bit_mask;
   1891			tnr_dmd->cfg_mem[i].value |= (value & bit_mask);
   1892
   1893			tnr_dmd->cfg_mem[i].bit_mask |= bit_mask;
   1894
   1895			value_stored = 1;
   1896		}
   1897	}
   1898
   1899	if (value_stored)
   1900		return 0;
   1901
   1902	if (tnr_dmd->cfg_mem_last_entry < CXD2880_TNRDMD_MAX_CFG_MEM_COUNT) {
   1903		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].tgt = tgt;
   1904		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bank = bank;
   1905		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].address = address;
   1906		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].value = (value & bit_mask);
   1907		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bit_mask = bit_mask;
   1908		tnr_dmd->cfg_mem_last_entry++;
   1909	} else {
   1910		return -ENOMEM;
   1911	}
   1912
   1913	return 0;
   1914}
   1915
   1916int cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd,
   1917			  struct cxd2880_io *io,
   1918			  struct cxd2880_tnrdmd_create_param
   1919			  *create_param)
   1920{
   1921	if (!tnr_dmd || !io || !create_param)
   1922		return -EINVAL;
   1923
   1924	memset(tnr_dmd, 0, sizeof(struct cxd2880_tnrdmd));
   1925
   1926	tnr_dmd->io = io;
   1927	tnr_dmd->create_param = *create_param;
   1928
   1929	tnr_dmd->diver_mode = CXD2880_TNRDMD_DIVERMODE_SINGLE;
   1930	tnr_dmd->diver_sub = NULL;
   1931
   1932	tnr_dmd->srl_ts_clk_mod_cnts = 1;
   1933	tnr_dmd->en_fef_intmtnt_base = 1;
   1934	tnr_dmd->en_fef_intmtnt_lite = 1;
   1935	tnr_dmd->rf_lvl_cmpstn = NULL;
   1936	tnr_dmd->lna_thrs_tbl_air = NULL;
   1937	tnr_dmd->lna_thrs_tbl_cable = NULL;
   1938	atomic_set(&tnr_dmd->cancel, 0);
   1939
   1940	return 0;
   1941}
   1942
   1943int cxd2880_tnrdmd_diver_create(struct cxd2880_tnrdmd
   1944				*tnr_dmd_main,
   1945				struct cxd2880_io *io_main,
   1946				struct cxd2880_tnrdmd *tnr_dmd_sub,
   1947				struct cxd2880_io *io_sub,
   1948				struct
   1949				cxd2880_tnrdmd_diver_create_param
   1950				*create_param)
   1951{
   1952	struct cxd2880_tnrdmd_create_param *main_param, *sub_param;
   1953
   1954	if (!tnr_dmd_main || !io_main || !tnr_dmd_sub || !io_sub ||
   1955	    !create_param)
   1956		return -EINVAL;
   1957
   1958	memset(tnr_dmd_main, 0, sizeof(struct cxd2880_tnrdmd));
   1959	memset(tnr_dmd_sub, 0, sizeof(struct cxd2880_tnrdmd));
   1960
   1961	main_param = &tnr_dmd_main->create_param;
   1962	sub_param = &tnr_dmd_sub->create_param;
   1963
   1964	tnr_dmd_main->io = io_main;
   1965	tnr_dmd_main->diver_mode = CXD2880_TNRDMD_DIVERMODE_MAIN;
   1966	tnr_dmd_main->diver_sub = tnr_dmd_sub;
   1967	tnr_dmd_main->create_param.en_internal_ldo =
   1968	    create_param->en_internal_ldo;
   1969
   1970	main_param->ts_output_if = create_param->ts_output_if;
   1971	main_param->xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_MASTER;
   1972	main_param->xosc_cap = create_param->xosc_cap_main;
   1973	main_param->xosc_i = create_param->xosc_i_main;
   1974	main_param->is_cxd2881gg = create_param->is_cxd2881gg;
   1975	main_param->stationary_use = create_param->stationary_use;
   1976
   1977	tnr_dmd_sub->io = io_sub;
   1978	tnr_dmd_sub->diver_mode = CXD2880_TNRDMD_DIVERMODE_SUB;
   1979	tnr_dmd_sub->diver_sub = NULL;
   1980
   1981	sub_param->en_internal_ldo = create_param->en_internal_ldo;
   1982	sub_param->ts_output_if = create_param->ts_output_if;
   1983	sub_param->xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_SLAVE;
   1984	sub_param->xosc_cap = 0;
   1985	sub_param->xosc_i = create_param->xosc_i_sub;
   1986	sub_param->is_cxd2881gg = create_param->is_cxd2881gg;
   1987	sub_param->stationary_use = create_param->stationary_use;
   1988
   1989	tnr_dmd_main->srl_ts_clk_mod_cnts = 1;
   1990	tnr_dmd_main->en_fef_intmtnt_base = 1;
   1991	tnr_dmd_main->en_fef_intmtnt_lite = 1;
   1992	tnr_dmd_main->rf_lvl_cmpstn = NULL;
   1993	tnr_dmd_main->lna_thrs_tbl_air = NULL;
   1994	tnr_dmd_main->lna_thrs_tbl_cable = NULL;
   1995
   1996	tnr_dmd_sub->srl_ts_clk_mod_cnts = 1;
   1997	tnr_dmd_sub->en_fef_intmtnt_base = 1;
   1998	tnr_dmd_sub->en_fef_intmtnt_lite = 1;
   1999	tnr_dmd_sub->rf_lvl_cmpstn = NULL;
   2000	tnr_dmd_sub->lna_thrs_tbl_air = NULL;
   2001	tnr_dmd_sub->lna_thrs_tbl_cable = NULL;
   2002
   2003	return 0;
   2004}
   2005
   2006int cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd)
   2007{
   2008	int ret;
   2009
   2010	if (!tnr_dmd || tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   2011		return -EINVAL;
   2012
   2013	tnr_dmd->chip_id = CXD2880_TNRDMD_CHIP_ID_UNKNOWN;
   2014	tnr_dmd->state = CXD2880_TNRDMD_STATE_UNKNOWN;
   2015	tnr_dmd->clk_mode = CXD2880_TNRDMD_CLOCKMODE_UNKNOWN;
   2016	tnr_dmd->frequency_khz = 0;
   2017	tnr_dmd->sys = CXD2880_DTV_SYS_UNKNOWN;
   2018	tnr_dmd->bandwidth = CXD2880_DTV_BW_UNKNOWN;
   2019	tnr_dmd->scan_mode = 0;
   2020	atomic_set(&tnr_dmd->cancel, 0);
   2021
   2022	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2023		tnr_dmd->diver_sub->chip_id = CXD2880_TNRDMD_CHIP_ID_UNKNOWN;
   2024		tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_UNKNOWN;
   2025		tnr_dmd->diver_sub->clk_mode = CXD2880_TNRDMD_CLOCKMODE_UNKNOWN;
   2026		tnr_dmd->diver_sub->frequency_khz = 0;
   2027		tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_UNKNOWN;
   2028		tnr_dmd->diver_sub->bandwidth = CXD2880_DTV_BW_UNKNOWN;
   2029		tnr_dmd->diver_sub->scan_mode = 0;
   2030		atomic_set(&tnr_dmd->diver_sub->cancel, 0);
   2031	}
   2032
   2033	ret = cxd2880_tnrdmd_chip_id(tnr_dmd, &tnr_dmd->chip_id);
   2034	if (ret)
   2035		return ret;
   2036
   2037	if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->chip_id))
   2038		return -ENOTTY;
   2039
   2040	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2041		ret =
   2042		    cxd2880_tnrdmd_chip_id(tnr_dmd->diver_sub,
   2043					   &tnr_dmd->diver_sub->chip_id);
   2044		if (ret)
   2045			return ret;
   2046
   2047		if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->diver_sub->chip_id))
   2048			return -ENOTTY;
   2049	}
   2050
   2051	ret = p_init1(tnr_dmd);
   2052	if (ret)
   2053		return ret;
   2054
   2055	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2056		ret = p_init1(tnr_dmd->diver_sub);
   2057		if (ret)
   2058			return ret;
   2059	}
   2060
   2061	usleep_range(1000, 2000);
   2062
   2063	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2064		ret = p_init2(tnr_dmd->diver_sub);
   2065		if (ret)
   2066			return ret;
   2067	}
   2068
   2069	ret = p_init2(tnr_dmd);
   2070	if (ret)
   2071		return ret;
   2072
   2073	usleep_range(5000, 6000);
   2074
   2075	ret = p_init3(tnr_dmd);
   2076	if (ret)
   2077		return ret;
   2078
   2079	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2080		ret = p_init3(tnr_dmd->diver_sub);
   2081		if (ret)
   2082			return ret;
   2083	}
   2084
   2085	ret = rf_init1(tnr_dmd);
   2086	if (ret)
   2087		return ret;
   2088
   2089	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
   2090		ret = rf_init1(tnr_dmd->diver_sub);
   2091
   2092	return ret;
   2093}
   2094
   2095int cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd)
   2096{
   2097	u8 cpu_task_completed;
   2098	int ret;
   2099
   2100	if (!tnr_dmd)
   2101		return -EINVAL;
   2102
   2103	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   2104		return -EINVAL;
   2105
   2106	ret = cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
   2107						     &cpu_task_completed);
   2108	if (ret)
   2109		return ret;
   2110
   2111	if (!cpu_task_completed)
   2112		return -EINVAL;
   2113
   2114	ret = rf_init2(tnr_dmd);
   2115	if (ret)
   2116		return ret;
   2117
   2118	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2119		ret = rf_init2(tnr_dmd->diver_sub);
   2120		if (ret)
   2121			return ret;
   2122	}
   2123
   2124	ret = load_cfg_mem(tnr_dmd);
   2125	if (ret)
   2126		return ret;
   2127
   2128	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2129		ret = load_cfg_mem(tnr_dmd->diver_sub);
   2130		if (ret)
   2131			return ret;
   2132	}
   2133
   2134	tnr_dmd->state = CXD2880_TNRDMD_STATE_SLEEP;
   2135
   2136	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
   2137		tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_SLEEP;
   2138
   2139	return ret;
   2140}
   2141
   2142int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd
   2143					     *tnr_dmd,
   2144					     u8 *task_completed)
   2145{
   2146	u16 cpu_status = 0;
   2147	int ret;
   2148
   2149	if (!tnr_dmd || !task_completed)
   2150		return -EINVAL;
   2151
   2152	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   2153		return -EINVAL;
   2154
   2155	ret = cxd2880_tnrdmd_mon_internal_cpu_status(tnr_dmd, &cpu_status);
   2156	if (ret)
   2157		return ret;
   2158
   2159	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) {
   2160		if (cpu_status == 0)
   2161			*task_completed = 1;
   2162		else
   2163			*task_completed = 0;
   2164
   2165		return ret;
   2166	}
   2167	if (cpu_status != 0) {
   2168		*task_completed = 0;
   2169		return ret;
   2170	}
   2171
   2172	ret = cxd2880_tnrdmd_mon_internal_cpu_status_sub(tnr_dmd, &cpu_status);
   2173	if (ret)
   2174		return ret;
   2175
   2176	if (cpu_status == 0)
   2177		*task_completed = 1;
   2178	else
   2179		*task_completed = 0;
   2180
   2181	return ret;
   2182}
   2183
   2184int cxd2880_tnrdmd_common_tune_setting1(struct cxd2880_tnrdmd *tnr_dmd,
   2185					enum cxd2880_dtv_sys sys,
   2186					u32 frequency_khz,
   2187					enum cxd2880_dtv_bandwidth
   2188					bandwidth, u8 one_seg_opt,
   2189					u8 one_seg_opt_shft_dir)
   2190{
   2191	u8 data;
   2192	enum cxd2880_tnrdmd_clockmode new_clk_mode =
   2193				CXD2880_TNRDMD_CLOCKMODE_A;
   2194	int shift_frequency_khz;
   2195	u8 cpu_task_completed;
   2196	int ret;
   2197
   2198	if (!tnr_dmd)
   2199		return -EINVAL;
   2200
   2201	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   2202		return -EINVAL;
   2203
   2204	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   2205	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   2206		return -EINVAL;
   2207
   2208	if (frequency_khz < 4000)
   2209		return -EINVAL;
   2210
   2211	ret = cxd2880_tnrdmd_sleep(tnr_dmd);
   2212	if (ret)
   2213		return ret;
   2214
   2215	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   2216				     CXD2880_IO_TGT_SYS,
   2217				     0x00,
   2218				     0x00);
   2219	if (ret)
   2220		return ret;
   2221
   2222	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   2223				     CXD2880_IO_TGT_SYS,
   2224				     0x2b,
   2225				     &data,
   2226				     1);
   2227	if (ret)
   2228		return ret;
   2229
   2230	switch (sys) {
   2231	case CXD2880_DTV_SYS_DVBT:
   2232		if (data == 0x00) {
   2233			ret = t_power_x(tnr_dmd, 1);
   2234			if (ret)
   2235				return ret;
   2236
   2237			if (tnr_dmd->diver_mode ==
   2238			    CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2239				ret = t_power_x(tnr_dmd->diver_sub, 1);
   2240				if (ret)
   2241					return ret;
   2242			}
   2243		}
   2244		break;
   2245
   2246	case CXD2880_DTV_SYS_DVBT2:
   2247		if (data == 0x01) {
   2248			ret = t_power_x(tnr_dmd, 0);
   2249			if (ret)
   2250				return ret;
   2251
   2252			if (tnr_dmd->diver_mode ==
   2253			    CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2254				ret = t_power_x(tnr_dmd->diver_sub, 0);
   2255				if (ret)
   2256					return ret;
   2257			}
   2258		}
   2259		break;
   2260
   2261	default:
   2262		return -EINVAL;
   2263	}
   2264
   2265	ret = spll_reset(tnr_dmd, new_clk_mode);
   2266	if (ret)
   2267		return ret;
   2268
   2269	tnr_dmd->clk_mode = new_clk_mode;
   2270
   2271	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2272		ret = spll_reset(tnr_dmd->diver_sub, new_clk_mode);
   2273		if (ret)
   2274			return ret;
   2275
   2276		tnr_dmd->diver_sub->clk_mode = new_clk_mode;
   2277	}
   2278
   2279	ret = load_cfg_mem(tnr_dmd);
   2280	if (ret)
   2281		return ret;
   2282
   2283	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2284		ret = load_cfg_mem(tnr_dmd->diver_sub);
   2285		if (ret)
   2286			return ret;
   2287	}
   2288
   2289	if (one_seg_opt) {
   2290		if (tnr_dmd->diver_mode ==
   2291		    CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2292			shift_frequency_khz = 350;
   2293		} else {
   2294			if (one_seg_opt_shft_dir)
   2295				shift_frequency_khz = 350;
   2296			else
   2297				shift_frequency_khz = -350;
   2298
   2299			if (tnr_dmd->create_param.xtal_share_type ==
   2300			    CXD2880_TNRDMD_XTAL_SHARE_SLAVE)
   2301				shift_frequency_khz *= -1;
   2302		}
   2303	} else {
   2304		if (tnr_dmd->diver_mode ==
   2305		    CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2306			shift_frequency_khz = 150;
   2307		} else {
   2308			switch (tnr_dmd->create_param.xtal_share_type) {
   2309			case CXD2880_TNRDMD_XTAL_SHARE_NONE:
   2310			case CXD2880_TNRDMD_XTAL_SHARE_EXTREF:
   2311			default:
   2312				shift_frequency_khz = 0;
   2313				break;
   2314			case CXD2880_TNRDMD_XTAL_SHARE_MASTER:
   2315				shift_frequency_khz = 150;
   2316				break;
   2317			case CXD2880_TNRDMD_XTAL_SHARE_SLAVE:
   2318				shift_frequency_khz = -150;
   2319				break;
   2320			}
   2321		}
   2322	}
   2323
   2324	ret =
   2325	    x_tune1(tnr_dmd, sys, frequency_khz, bandwidth,
   2326		    tnr_dmd->is_cable_input, shift_frequency_khz);
   2327	if (ret)
   2328		return ret;
   2329
   2330	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2331		ret =
   2332		    x_tune1(tnr_dmd->diver_sub, sys, frequency_khz,
   2333			    bandwidth, tnr_dmd->is_cable_input,
   2334			    -shift_frequency_khz);
   2335		if (ret)
   2336			return ret;
   2337	}
   2338
   2339	usleep_range(10000, 11000);
   2340
   2341	ret =
   2342	    cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
   2343					     &cpu_task_completed);
   2344	if (ret)
   2345		return ret;
   2346
   2347	if (!cpu_task_completed)
   2348		return -EINVAL;
   2349
   2350	ret =
   2351	    x_tune2(tnr_dmd, bandwidth, tnr_dmd->clk_mode,
   2352		    shift_frequency_khz);
   2353	if (ret)
   2354		return ret;
   2355
   2356	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2357		ret =
   2358		    x_tune2(tnr_dmd->diver_sub, bandwidth,
   2359			    tnr_dmd->diver_sub->clk_mode,
   2360			    -shift_frequency_khz);
   2361		if (ret)
   2362			return ret;
   2363	}
   2364
   2365	if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS) {
   2366		ret = set_ts_clk_mode_and_freq(tnr_dmd, sys);
   2367	} else {
   2368		struct cxd2880_tnrdmd_pid_ftr_cfg *pid_ftr_cfg;
   2369
   2370		if (tnr_dmd->pid_ftr_cfg_en)
   2371			pid_ftr_cfg = &tnr_dmd->pid_ftr_cfg;
   2372		else
   2373			pid_ftr_cfg = NULL;
   2374
   2375		ret = pid_ftr_setting(tnr_dmd, pid_ftr_cfg);
   2376	}
   2377
   2378	return ret;
   2379}
   2380
   2381int cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd
   2382					*tnr_dmd,
   2383					enum cxd2880_dtv_sys sys,
   2384					u8 en_fef_intmtnt_ctrl)
   2385{
   2386	int ret;
   2387
   2388	if (!tnr_dmd)
   2389		return -EINVAL;
   2390
   2391	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   2392		return -EINVAL;
   2393
   2394	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   2395	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   2396		return -EINVAL;
   2397
   2398	ret = x_tune3(tnr_dmd, sys, en_fef_intmtnt_ctrl);
   2399	if (ret)
   2400		return ret;
   2401
   2402	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2403		ret = x_tune3(tnr_dmd->diver_sub, sys, en_fef_intmtnt_ctrl);
   2404		if (ret)
   2405			return ret;
   2406		ret = x_tune4(tnr_dmd);
   2407		if (ret)
   2408			return ret;
   2409	}
   2410
   2411	return cxd2880_tnrdmd_set_ts_output(tnr_dmd, 1);
   2412}
   2413
   2414int cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd)
   2415{
   2416	int ret;
   2417
   2418	if (!tnr_dmd)
   2419		return -EINVAL;
   2420
   2421	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   2422		return -EINVAL;
   2423
   2424	if (tnr_dmd->state == CXD2880_TNRDMD_STATE_SLEEP)
   2425		return 0;
   2426
   2427	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   2428		return -EINVAL;
   2429
   2430	ret = cxd2880_tnrdmd_set_ts_output(tnr_dmd, 0);
   2431	if (ret)
   2432		return ret;
   2433
   2434	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2435		ret = x_sleep1(tnr_dmd);
   2436		if (ret)
   2437			return ret;
   2438	}
   2439
   2440	ret = x_sleep2(tnr_dmd);
   2441	if (ret)
   2442		return ret;
   2443
   2444	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2445		ret = x_sleep2(tnr_dmd->diver_sub);
   2446		if (ret)
   2447			return ret;
   2448	}
   2449
   2450	switch (tnr_dmd->sys) {
   2451	case CXD2880_DTV_SYS_DVBT:
   2452		ret = cxd2880_tnrdmd_dvbt_sleep_setting(tnr_dmd);
   2453		if (ret)
   2454			return ret;
   2455		break;
   2456
   2457	case CXD2880_DTV_SYS_DVBT2:
   2458		ret = cxd2880_tnrdmd_dvbt2_sleep_setting(tnr_dmd);
   2459		if (ret)
   2460			return ret;
   2461		break;
   2462
   2463	default:
   2464		return -EINVAL;
   2465	}
   2466
   2467	ret = x_sleep3(tnr_dmd);
   2468	if (ret)
   2469		return ret;
   2470
   2471	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2472		ret = x_sleep3(tnr_dmd->diver_sub);
   2473		if (ret)
   2474			return ret;
   2475	}
   2476
   2477	ret = x_sleep4(tnr_dmd);
   2478	if (ret)
   2479		return ret;
   2480
   2481	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2482		ret = x_sleep4(tnr_dmd->diver_sub);
   2483		if (ret)
   2484			return ret;
   2485	}
   2486
   2487	tnr_dmd->state = CXD2880_TNRDMD_STATE_SLEEP;
   2488	tnr_dmd->frequency_khz = 0;
   2489	tnr_dmd->sys = CXD2880_DTV_SYS_UNKNOWN;
   2490	tnr_dmd->bandwidth = CXD2880_DTV_BW_UNKNOWN;
   2491
   2492	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
   2493		tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_SLEEP;
   2494		tnr_dmd->diver_sub->frequency_khz = 0;
   2495		tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_UNKNOWN;
   2496		tnr_dmd->diver_sub->bandwidth = CXD2880_DTV_BW_UNKNOWN;
   2497	}
   2498
   2499	return 0;
   2500}
   2501
   2502int cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
   2503			   enum cxd2880_tnrdmd_cfg_id id,
   2504			   int value)
   2505{
   2506	int ret = 0;
   2507	u8 data[2] = { 0 };
   2508	u8 need_sub_setting = 0;
   2509
   2510	if (!tnr_dmd)
   2511		return -EINVAL;
   2512
   2513	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   2514	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   2515		return -EINVAL;
   2516
   2517	switch (id) {
   2518	case CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB:
   2519		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2520			return -EINVAL;
   2521
   2522		ret =
   2523		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2524							 CXD2880_IO_TGT_DMD,
   2525							 0x00, 0xc4,
   2526							 value ? 0x00 : 0x10,
   2527							 0x10);
   2528		if (ret)
   2529			return ret;
   2530		break;
   2531
   2532	case CXD2880_TNRDMD_CFG_TSVALID_ACTIVE_HI:
   2533		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2534			return -EINVAL;
   2535
   2536		ret =
   2537		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2538							 CXD2880_IO_TGT_DMD,
   2539							 0x00, 0xc5,
   2540							 value ? 0x00 : 0x02,
   2541							 0x02);
   2542		if (ret)
   2543			return ret;
   2544		break;
   2545
   2546	case CXD2880_TNRDMD_CFG_TSSYNC_ACTIVE_HI:
   2547		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2548			return -EINVAL;
   2549
   2550		ret =
   2551		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2552							 CXD2880_IO_TGT_DMD,
   2553							 0x00, 0xc5,
   2554							 value ? 0x00 : 0x04,
   2555							 0x04);
   2556		if (ret)
   2557			return ret;
   2558		break;
   2559
   2560	case CXD2880_TNRDMD_CFG_TSERR_ACTIVE_HI:
   2561		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2562			return -EINVAL;
   2563
   2564		ret =
   2565		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2566							 CXD2880_IO_TGT_DMD,
   2567							 0x00, 0xcb,
   2568							 value ? 0x00 : 0x01,
   2569							 0x01);
   2570		if (ret)
   2571			return ret;
   2572		break;
   2573
   2574	case CXD2880_TNRDMD_CFG_LATCH_ON_POSEDGE:
   2575		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2576			return -EINVAL;
   2577
   2578		ret =
   2579		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2580							 CXD2880_IO_TGT_DMD,
   2581							 0x00, 0xc5,
   2582							 value ? 0x01 : 0x00,
   2583							 0x01);
   2584		if (ret)
   2585			return ret;
   2586		break;
   2587
   2588	case CXD2880_TNRDMD_CFG_TSCLK_CONT:
   2589		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2590			return -EINVAL;
   2591
   2592		tnr_dmd->srl_ts_clk_mod_cnts = value ? 0x01 : 0x00;
   2593		break;
   2594
   2595	case CXD2880_TNRDMD_CFG_TSCLK_MASK:
   2596		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2597			return -EINVAL;
   2598
   2599		if (value < 0 || value > 0x1f)
   2600			return -EINVAL;
   2601
   2602		ret =
   2603		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2604							 CXD2880_IO_TGT_DMD,
   2605							 0x00, 0xc6, value,
   2606							 0x1f);
   2607		if (ret)
   2608			return ret;
   2609		break;
   2610
   2611	case CXD2880_TNRDMD_CFG_TSVALID_MASK:
   2612		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2613			return -EINVAL;
   2614
   2615		if (value < 0 || value > 0x1f)
   2616			return -EINVAL;
   2617
   2618		ret =
   2619		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2620							 CXD2880_IO_TGT_DMD,
   2621							 0x00, 0xc8, value,
   2622							 0x1f);
   2623		if (ret)
   2624			return ret;
   2625		break;
   2626
   2627	case CXD2880_TNRDMD_CFG_TSERR_MASK:
   2628		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2629			return -EINVAL;
   2630
   2631		if (value < 0 || value > 0x1f)
   2632			return -EINVAL;
   2633
   2634		ret =
   2635		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2636							 CXD2880_IO_TGT_DMD,
   2637							 0x00, 0xc9, value,
   2638							 0x1f);
   2639		if (ret)
   2640			return ret;
   2641		break;
   2642
   2643	case CXD2880_TNRDMD_CFG_TSERR_VALID_DIS:
   2644		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2645			return -EINVAL;
   2646
   2647		ret =
   2648		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2649							 CXD2880_IO_TGT_DMD,
   2650							 0x00, 0x91,
   2651							 value ? 0x01 : 0x00,
   2652							 0x01);
   2653		if (ret)
   2654			return ret;
   2655		break;
   2656
   2657	case CXD2880_TNRDMD_CFG_TSPIN_CURRENT:
   2658		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2659			return -EINVAL;
   2660
   2661		ret =
   2662		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2663							 CXD2880_IO_TGT_SYS,
   2664							 0x00, 0x51, value,
   2665							 0x3f);
   2666		if (ret)
   2667			return ret;
   2668		break;
   2669
   2670	case CXD2880_TNRDMD_CFG_TSPIN_PULLUP_MANUAL:
   2671		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2672			return -EINVAL;
   2673
   2674		ret =
   2675		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2676							 CXD2880_IO_TGT_SYS,
   2677							 0x00, 0x50,
   2678							 value ? 0x80 : 0x00,
   2679							 0x80);
   2680		if (ret)
   2681			return ret;
   2682		break;
   2683
   2684	case CXD2880_TNRDMD_CFG_TSPIN_PULLUP:
   2685		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2686			return -EINVAL;
   2687
   2688		ret =
   2689		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2690							 CXD2880_IO_TGT_SYS,
   2691							 0x00, 0x50, value,
   2692							 0x3f);
   2693		if (ret)
   2694			return ret;
   2695		break;
   2696
   2697	case CXD2880_TNRDMD_CFG_TSCLK_FREQ:
   2698		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2699			return -EINVAL;
   2700
   2701		if (value < 0 || value > 1)
   2702			return -EINVAL;
   2703
   2704		tnr_dmd->srl_ts_clk_frq =
   2705		    (enum cxd2880_tnrdmd_serial_ts_clk)value;
   2706		break;
   2707
   2708	case CXD2880_TNRDMD_CFG_TSBYTECLK_MANUAL:
   2709		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2710			return -EINVAL;
   2711
   2712		if (value < 0 || value > 0xff)
   2713			return -EINVAL;
   2714
   2715		tnr_dmd->ts_byte_clk_manual_setting = value;
   2716
   2717		break;
   2718
   2719	case CXD2880_TNRDMD_CFG_TS_PACKET_GAP:
   2720		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2721			return -EINVAL;
   2722
   2723		if (value < 0 || value > 7)
   2724			return -EINVAL;
   2725
   2726		ret =
   2727		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2728							 CXD2880_IO_TGT_DMD,
   2729							 0x00, 0xd6, value,
   2730							 0x07);
   2731		if (ret)
   2732			return ret;
   2733
   2734		break;
   2735
   2736	case CXD2880_TNRDMD_CFG_TS_BACKWARDS_COMPATIBLE:
   2737		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   2738			return -EINVAL;
   2739
   2740		tnr_dmd->is_ts_backwards_compatible_mode = value ? 1 : 0;
   2741
   2742		break;
   2743
   2744	case CXD2880_TNRDMD_CFG_PWM_VALUE:
   2745		if (value < 0 || value > 0x1000)
   2746			return -EINVAL;
   2747
   2748		ret =
   2749		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2750							 CXD2880_IO_TGT_DMD,
   2751							 0x00, 0x22,
   2752							 value ? 0x01 : 0x00,
   2753							 0x01);
   2754		if (ret)
   2755			return ret;
   2756
   2757		data[0] = (value >> 8) & 0x1f;
   2758		data[1] = value & 0xff;
   2759
   2760		ret =
   2761		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2762							 CXD2880_IO_TGT_DMD,
   2763							 0x00, 0x23,
   2764							 data[0], 0x1f);
   2765		if (ret)
   2766			return ret;
   2767
   2768		ret =
   2769		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2770							 CXD2880_IO_TGT_DMD,
   2771							 0x00, 0x24,
   2772							 data[1], 0xff);
   2773		if (ret)
   2774			return ret;
   2775
   2776		break;
   2777
   2778	case CXD2880_TNRDMD_CFG_INTERRUPT:
   2779		data[0] = (value >> 8) & 0xff;
   2780		data[1] = value & 0xff;
   2781		ret =
   2782		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2783							 CXD2880_IO_TGT_SYS,
   2784							 0x00, 0x48, data[0],
   2785							 0xff);
   2786		if (ret)
   2787			return ret;
   2788		ret =
   2789		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2790							 CXD2880_IO_TGT_SYS,
   2791							 0x00, 0x49, data[1],
   2792							 0xff);
   2793		if (ret)
   2794			return ret;
   2795		break;
   2796
   2797	case CXD2880_TNRDMD_CFG_INTERRUPT_LOCK_SEL:
   2798		data[0] = value & 0x07;
   2799		ret =
   2800		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2801							 CXD2880_IO_TGT_SYS,
   2802							 0x00, 0x4a, data[0],
   2803							 0x07);
   2804		if (ret)
   2805			return ret;
   2806		break;
   2807
   2808	case CXD2880_TNRDMD_CFG_INTERRUPT_INV_LOCK_SEL:
   2809		data[0] = (value & 0x07) << 3;
   2810		ret =
   2811		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2812							 CXD2880_IO_TGT_SYS,
   2813							 0x00, 0x4a, data[0],
   2814							 0x38);
   2815		if (ret)
   2816			return ret;
   2817		break;
   2818
   2819	case CXD2880_TNRDMD_CFG_FIXED_CLOCKMODE:
   2820		if (value < CXD2880_TNRDMD_CLOCKMODE_UNKNOWN ||
   2821		    value > CXD2880_TNRDMD_CLOCKMODE_C)
   2822			return -EINVAL;
   2823		tnr_dmd->fixed_clk_mode = (enum cxd2880_tnrdmd_clockmode)value;
   2824		break;
   2825
   2826	case CXD2880_TNRDMD_CFG_CABLE_INPUT:
   2827		tnr_dmd->is_cable_input = value ? 1 : 0;
   2828		break;
   2829
   2830	case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_BASE:
   2831		tnr_dmd->en_fef_intmtnt_base = value ? 1 : 0;
   2832		break;
   2833
   2834	case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_LITE:
   2835		tnr_dmd->en_fef_intmtnt_lite = value ? 1 : 0;
   2836		break;
   2837
   2838	case CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_EMPTY_THRS:
   2839		data[0] = (value >> 8) & 0x07;
   2840		data[1] = value & 0xff;
   2841		ret =
   2842		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2843							 CXD2880_IO_TGT_DMD,
   2844							 0x00, 0x99, data[0],
   2845							 0x07);
   2846		if (ret)
   2847			return ret;
   2848		ret =
   2849		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2850							 CXD2880_IO_TGT_DMD,
   2851							 0x00, 0x9a, data[1],
   2852							 0xff);
   2853		if (ret)
   2854			return ret;
   2855		break;
   2856
   2857	case CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_FULL_THRS:
   2858		data[0] = (value >> 8) & 0x07;
   2859		data[1] = value & 0xff;
   2860		ret =
   2861		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2862							 CXD2880_IO_TGT_DMD,
   2863							 0x00, 0x9b, data[0],
   2864							 0x07);
   2865		if (ret)
   2866			return ret;
   2867		ret =
   2868		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2869							 CXD2880_IO_TGT_DMD,
   2870							 0x00, 0x9c, data[1],
   2871							 0xff);
   2872		if (ret)
   2873			return ret;
   2874		break;
   2875
   2876	case CXD2880_TNRDMD_CFG_TS_BUF_RRDY_THRS:
   2877		data[0] = (value >> 8) & 0x07;
   2878		data[1] = value & 0xff;
   2879		ret =
   2880		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2881							 CXD2880_IO_TGT_DMD,
   2882							 0x00, 0x9d, data[0],
   2883							 0x07);
   2884		if (ret)
   2885			return ret;
   2886		ret =
   2887		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2888							 CXD2880_IO_TGT_DMD,
   2889							 0x00, 0x9e, data[1],
   2890							 0xff);
   2891		if (ret)
   2892			return ret;
   2893		break;
   2894
   2895	case CXD2880_TNRDMD_CFG_BLINDTUNE_DVBT2_FIRST:
   2896		tnr_dmd->blind_tune_dvbt2_first = value ? 1 : 0;
   2897		break;
   2898
   2899	case CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD:
   2900		if (value < 0 || value > 31)
   2901			return -EINVAL;
   2902
   2903		ret =
   2904		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2905							 CXD2880_IO_TGT_DMD,
   2906							 0x10, 0x60,
   2907							 value & 0x1f, 0x1f);
   2908		if (ret)
   2909			return ret;
   2910		break;
   2911
   2912	case CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD:
   2913		if (value < 0 || value > 7)
   2914			return -EINVAL;
   2915
   2916		ret =
   2917		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2918							 CXD2880_IO_TGT_DMD,
   2919							 0x10, 0x6f,
   2920							 value & 0x07, 0x07);
   2921		if (ret)
   2922			return ret;
   2923		break;
   2924
   2925	case CXD2880_TNRDMD_CFG_DVBT2_BBER_MES:
   2926		if (value < 0 || value > 15)
   2927			return -EINVAL;
   2928
   2929		ret =
   2930		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2931							 CXD2880_IO_TGT_DMD,
   2932							 0x20, 0x72,
   2933							 value & 0x0f, 0x0f);
   2934		if (ret)
   2935			return ret;
   2936		break;
   2937
   2938	case CXD2880_TNRDMD_CFG_DVBT2_LBER_MES:
   2939		if (value < 0 || value > 15)
   2940			return -EINVAL;
   2941
   2942		ret =
   2943		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2944							 CXD2880_IO_TGT_DMD,
   2945							 0x20, 0x6f,
   2946							 value & 0x0f, 0x0f);
   2947		if (ret)
   2948			return ret;
   2949		break;
   2950
   2951	case CXD2880_TNRDMD_CFG_DVBT_PER_MES:
   2952		if (value < 0 || value > 15)
   2953			return -EINVAL;
   2954
   2955		ret =
   2956		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2957							 CXD2880_IO_TGT_DMD,
   2958							 0x10, 0x5c,
   2959							 value & 0x0f, 0x0f);
   2960		if (ret)
   2961			return ret;
   2962		break;
   2963
   2964	case CXD2880_TNRDMD_CFG_DVBT2_PER_MES:
   2965		if (value < 0 || value > 15)
   2966			return -EINVAL;
   2967
   2968		ret =
   2969		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   2970							 CXD2880_IO_TGT_DMD,
   2971							 0x24, 0xdc,
   2972							 value & 0x0f, 0x0f);
   2973		if (ret)
   2974			return ret;
   2975		break;
   2976
   2977	default:
   2978		return -EINVAL;
   2979	}
   2980
   2981	if (need_sub_setting &&
   2982	    tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
   2983		ret = cxd2880_tnrdmd_set_cfg(tnr_dmd->diver_sub, id, value);
   2984
   2985	return ret;
   2986}
   2987
   2988int cxd2880_tnrdmd_gpio_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
   2989				u8 id,
   2990				u8 en,
   2991				enum cxd2880_tnrdmd_gpio_mode mode,
   2992				u8 open_drain, u8 invert)
   2993{
   2994	int ret;
   2995
   2996	if (!tnr_dmd)
   2997		return -EINVAL;
   2998
   2999	if (id > 2)
   3000		return -EINVAL;
   3001
   3002	if (mode > CXD2880_TNRDMD_GPIO_MODE_EEW)
   3003		return -EINVAL;
   3004
   3005	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3006	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3007		return -EINVAL;
   3008
   3009	ret =
   3010	    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS,
   3011						 0x00, 0x40 + id, mode,
   3012						 0x0f);
   3013	if (ret)
   3014		return ret;
   3015
   3016	ret =
   3017	    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS,
   3018						 0x00, 0x43,
   3019						 open_drain ? (1 << id) : 0,
   3020						 1 << id);
   3021	if (ret)
   3022		return ret;
   3023
   3024	ret =
   3025	    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS,
   3026						 0x00, 0x44,
   3027						 invert ? (1 << id) : 0,
   3028						 1 << id);
   3029	if (ret)
   3030		return ret;
   3031
   3032	return cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   3033						    CXD2880_IO_TGT_SYS,
   3034						    0x00, 0x45,
   3035						    en ? 0 : (1 << id),
   3036						    1 << id);
   3037}
   3038
   3039int cxd2880_tnrdmd_gpio_set_cfg_sub(struct cxd2880_tnrdmd *tnr_dmd,
   3040				    u8 id,
   3041				    u8 en,
   3042				    enum cxd2880_tnrdmd_gpio_mode
   3043				    mode, u8 open_drain, u8 invert)
   3044{
   3045	if (!tnr_dmd)
   3046		return -EINVAL;
   3047
   3048	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
   3049		return -EINVAL;
   3050
   3051	return cxd2880_tnrdmd_gpio_set_cfg(tnr_dmd->diver_sub, id, en, mode,
   3052					   open_drain, invert);
   3053}
   3054
   3055int cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd,
   3056			     u8 id, u8 *value)
   3057{
   3058	u8 data = 0;
   3059	int ret;
   3060
   3061	if (!tnr_dmd || !value)
   3062		return -EINVAL;
   3063
   3064	if (id > 2)
   3065		return -EINVAL;
   3066
   3067	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3068	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3069		return -EINVAL;
   3070
   3071	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   3072				     CXD2880_IO_TGT_SYS,
   3073				     0x00, 0x0a);
   3074	if (ret)
   3075		return ret;
   3076	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   3077				     CXD2880_IO_TGT_SYS,
   3078				     0x20, &data, 1);
   3079	if (ret)
   3080		return ret;
   3081
   3082	*value = (data >> id) & 0x01;
   3083
   3084	return 0;
   3085}
   3086
   3087int cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd,
   3088				 u8 id, u8 *value)
   3089{
   3090	if (!tnr_dmd)
   3091		return -EINVAL;
   3092
   3093	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
   3094		return -EINVAL;
   3095
   3096	return cxd2880_tnrdmd_gpio_read(tnr_dmd->diver_sub, id, value);
   3097}
   3098
   3099int cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd,
   3100			      u8 id, u8 value)
   3101{
   3102	if (!tnr_dmd)
   3103		return -EINVAL;
   3104
   3105	if (id > 2)
   3106		return -EINVAL;
   3107
   3108	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3109	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3110		return -EINVAL;
   3111
   3112	return cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
   3113						    CXD2880_IO_TGT_SYS,
   3114						    0x00, 0x46,
   3115						    value ? (1 << id) : 0,
   3116						    1 << id);
   3117}
   3118
   3119int cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd,
   3120				  u8 id, u8 value)
   3121{
   3122	if (!tnr_dmd)
   3123		return -EINVAL;
   3124
   3125	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
   3126		return -EINVAL;
   3127
   3128	return cxd2880_tnrdmd_gpio_write(tnr_dmd->diver_sub, id, value);
   3129}
   3130
   3131int cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd,
   3132				  u16 *value)
   3133{
   3134	int ret;
   3135	u8 data[2] = { 0 };
   3136
   3137	if (!tnr_dmd || !value)
   3138		return -EINVAL;
   3139
   3140	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3141	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3142		return -EINVAL;
   3143
   3144	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   3145				     CXD2880_IO_TGT_SYS,
   3146				     0x00, 0x0a);
   3147	if (ret)
   3148		return ret;
   3149	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   3150				     CXD2880_IO_TGT_SYS,
   3151				     0x15, data, 2);
   3152	if (ret)
   3153		return ret;
   3154
   3155	*value = (data[0] << 8) | data[1];
   3156
   3157	return 0;
   3158}
   3159
   3160int cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd,
   3161				   u16 value)
   3162{
   3163	int ret;
   3164	u8 data[2] = { 0 };
   3165
   3166	if (!tnr_dmd)
   3167		return -EINVAL;
   3168
   3169	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3170	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3171		return -EINVAL;
   3172
   3173	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   3174				     CXD2880_IO_TGT_SYS,
   3175				     0x00, 0x00);
   3176	if (ret)
   3177		return ret;
   3178
   3179	data[0] = (value >> 8) & 0xff;
   3180	data[1] = value & 0xff;
   3181
   3182	return tnr_dmd->io->write_regs(tnr_dmd->io,
   3183				       CXD2880_IO_TGT_SYS,
   3184				       0x3c, data, 2);
   3185}
   3186
   3187int cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd,
   3188				u8 clear_overflow_flag,
   3189				u8 clear_underflow_flag,
   3190				u8 clear_buf)
   3191{
   3192	int ret;
   3193	u8 data[2] = { 0 };
   3194
   3195	if (!tnr_dmd)
   3196		return -EINVAL;
   3197
   3198	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   3199		return -EINVAL;
   3200
   3201	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3202	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3203		return -EINVAL;
   3204
   3205	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   3206				     CXD2880_IO_TGT_DMD,
   3207				     0x00, 0x00);
   3208	if (ret)
   3209		return ret;
   3210
   3211	data[0] = clear_overflow_flag ? 0x02 : 0x00;
   3212	data[0] |= clear_underflow_flag ? 0x01 : 0x00;
   3213	data[1] = clear_buf ? 0x01 : 0x00;
   3214
   3215	return tnr_dmd->io->write_regs(tnr_dmd->io,
   3216				       CXD2880_IO_TGT_DMD,
   3217				       0x9f, data, 2);
   3218}
   3219
   3220int cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd,
   3221			   enum cxd2880_tnrdmd_chip_id *chip_id)
   3222{
   3223	int ret;
   3224	u8 data = 0;
   3225
   3226	if (!tnr_dmd || !chip_id)
   3227		return -EINVAL;
   3228
   3229	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   3230				     CXD2880_IO_TGT_SYS,
   3231				     0x00, 0x00);
   3232	if (ret)
   3233		return ret;
   3234	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   3235				     CXD2880_IO_TGT_SYS,
   3236				     0xfd, &data, 1);
   3237	if (ret)
   3238		return ret;
   3239
   3240	*chip_id = (enum cxd2880_tnrdmd_chip_id)data;
   3241
   3242	return 0;
   3243}
   3244
   3245int cxd2880_tnrdmd_set_and_save_reg_bits(struct cxd2880_tnrdmd
   3246					 *tnr_dmd,
   3247					 enum cxd2880_io_tgt tgt,
   3248					 u8 bank, u8 address,
   3249					 u8 value, u8 bit_mask)
   3250{
   3251	int ret;
   3252
   3253	if (!tnr_dmd)
   3254		return -EINVAL;
   3255
   3256	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3257	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3258		return -EINVAL;
   3259
   3260	ret = tnr_dmd->io->write_reg(tnr_dmd->io, tgt, 0x00, bank);
   3261	if (ret)
   3262		return ret;
   3263
   3264	ret = cxd2880_io_set_reg_bits(tnr_dmd->io,
   3265				      tgt, address, value, bit_mask);
   3266	if (ret)
   3267		return ret;
   3268
   3269	return set_cfg_mem(tnr_dmd, tgt, bank, address, value, bit_mask);
   3270}
   3271
   3272int cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd,
   3273				 enum cxd2880_dtv_sys sys,
   3274				 u8 scan_mode_end)
   3275{
   3276	if (!tnr_dmd)
   3277		return -EINVAL;
   3278
   3279	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3280	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3281		return -EINVAL;
   3282
   3283	tnr_dmd->scan_mode = scan_mode_end;
   3284
   3285	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
   3286		return cxd2880_tnrdmd_set_scan_mode(tnr_dmd->diver_sub, sys,
   3287						    scan_mode_end);
   3288	else
   3289		return 0;
   3290}
   3291
   3292int cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd,
   3293			       struct cxd2880_tnrdmd_pid_ftr_cfg
   3294			       *pid_ftr_cfg)
   3295{
   3296	if (!tnr_dmd)
   3297		return -EINVAL;
   3298
   3299	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   3300		return -EINVAL;
   3301
   3302	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3303	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3304		return -EINVAL;
   3305
   3306	if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS)
   3307		return -ENOTTY;
   3308
   3309	if (pid_ftr_cfg) {
   3310		tnr_dmd->pid_ftr_cfg = *pid_ftr_cfg;
   3311		tnr_dmd->pid_ftr_cfg_en = 1;
   3312	} else {
   3313		tnr_dmd->pid_ftr_cfg_en = 0;
   3314	}
   3315
   3316	if (tnr_dmd->state == CXD2880_TNRDMD_STATE_ACTIVE)
   3317		return pid_ftr_setting(tnr_dmd, pid_ftr_cfg);
   3318	else
   3319		return 0;
   3320}
   3321
   3322int cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd
   3323				     *tnr_dmd,
   3324				     int (*rf_lvl_cmpstn)
   3325				     (struct cxd2880_tnrdmd *,
   3326				     int *))
   3327{
   3328	if (!tnr_dmd)
   3329		return -EINVAL;
   3330
   3331	tnr_dmd->rf_lvl_cmpstn = rf_lvl_cmpstn;
   3332
   3333	return 0;
   3334}
   3335
   3336int cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd
   3337					 *tnr_dmd,
   3338					 int (*rf_lvl_cmpstn)
   3339					 (struct cxd2880_tnrdmd *,
   3340					 int *))
   3341{
   3342	if (!tnr_dmd)
   3343		return -EINVAL;
   3344
   3345	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
   3346		return -EINVAL;
   3347
   3348	return cxd2880_tnrdmd_set_rf_lvl_cmpstn(tnr_dmd->diver_sub,
   3349						rf_lvl_cmpstn);
   3350}
   3351
   3352int cxd2880_tnrdmd_set_lna_thrs(struct cxd2880_tnrdmd *tnr_dmd,
   3353				struct cxd2880_tnrdmd_lna_thrs_tbl_air
   3354				*tbl_air,
   3355				struct cxd2880_tnrdmd_lna_thrs_tbl_cable
   3356				*tbl_cable)
   3357{
   3358	if (!tnr_dmd)
   3359		return -EINVAL;
   3360
   3361	tnr_dmd->lna_thrs_tbl_air = tbl_air;
   3362	tnr_dmd->lna_thrs_tbl_cable = tbl_cable;
   3363
   3364	return 0;
   3365}
   3366
   3367int cxd2880_tnrdmd_set_lna_thrs_sub(struct cxd2880_tnrdmd *tnr_dmd,
   3368				    struct
   3369				    cxd2880_tnrdmd_lna_thrs_tbl_air
   3370				    *tbl_air,
   3371				    struct cxd2880_tnrdmd_lna_thrs_tbl_cable
   3372				    *tbl_cable)
   3373{
   3374	if (!tnr_dmd)
   3375		return -EINVAL;
   3376
   3377	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
   3378		return -EINVAL;
   3379
   3380	return cxd2880_tnrdmd_set_lna_thrs(tnr_dmd->diver_sub,
   3381					   tbl_air, tbl_cable);
   3382}
   3383
   3384int cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd
   3385				       *tnr_dmd, u8 en, u8 value)
   3386{
   3387	int ret;
   3388
   3389	if (!tnr_dmd)
   3390		return -EINVAL;
   3391
   3392	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   3393		return -EINVAL;
   3394
   3395	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
   3396		return -EINVAL;
   3397
   3398	if (tnr_dmd->create_param.ts_output_if != CXD2880_TNRDMD_TSOUT_IF_TS)
   3399		return -ENOTTY;
   3400
   3401	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   3402				     CXD2880_IO_TGT_SYS,
   3403				     0x00, 0x00);
   3404	if (ret)
   3405		return ret;
   3406
   3407	if (en) {
   3408		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   3409					     CXD2880_IO_TGT_SYS,
   3410					     0x50, ((value & 0x1f) | 0x80));
   3411		if (ret)
   3412			return ret;
   3413
   3414		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
   3415					     CXD2880_IO_TGT_SYS,
   3416					     0x52, (value & 0x1f));
   3417	} else {
   3418		ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   3419						  CXD2880_IO_TGT_SYS,
   3420						  set_ts_pin_seq,
   3421						  ARRAY_SIZE(set_ts_pin_seq));
   3422		if (ret)
   3423			return ret;
   3424
   3425		ret = load_cfg_mem(tnr_dmd);
   3426	}
   3427
   3428	return ret;
   3429}
   3430
   3431int cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd,
   3432				 u8 en)
   3433{
   3434	int ret;
   3435
   3436	if (!tnr_dmd)
   3437		return -EINVAL;
   3438
   3439	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
   3440		return -EINVAL;
   3441
   3442	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
   3443	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
   3444		return -EINVAL;
   3445
   3446	switch (tnr_dmd->create_param.ts_output_if) {
   3447	case CXD2880_TNRDMD_TSOUT_IF_TS:
   3448		if (en) {
   3449			ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   3450							  CXD2880_IO_TGT_SYS,
   3451							  set_ts_output_seq1,
   3452							  ARRAY_SIZE(set_ts_output_seq1));
   3453			if (ret)
   3454				return ret;
   3455
   3456			ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   3457							  CXD2880_IO_TGT_DMD,
   3458							  set_ts_output_seq2,
   3459							  ARRAY_SIZE(set_ts_output_seq2));
   3460			if (ret)
   3461				return ret;
   3462		} else {
   3463			ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   3464							  CXD2880_IO_TGT_DMD,
   3465							  set_ts_output_seq3,
   3466							  ARRAY_SIZE(set_ts_output_seq3));
   3467			if (ret)
   3468				return ret;
   3469
   3470			ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
   3471							  CXD2880_IO_TGT_SYS,
   3472							  set_ts_output_seq4,
   3473							  ARRAY_SIZE(set_ts_output_seq4));
   3474			if (ret)
   3475				return ret;
   3476		}
   3477		break;
   3478
   3479	case CXD2880_TNRDMD_TSOUT_IF_SPI:
   3480		break;
   3481
   3482	case CXD2880_TNRDMD_TSOUT_IF_SDIO:
   3483		break;
   3484
   3485	default:
   3486		return -EINVAL;
   3487	}
   3488
   3489	return 0;
   3490}
   3491
   3492int slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd)
   3493{
   3494	u8 data;
   3495	int ret;
   3496
   3497	if (!tnr_dmd)
   3498		return -EINVAL;
   3499
   3500	switch (tnr_dmd->create_param.ts_output_if) {
   3501	case CXD2880_TNRDMD_TSOUT_IF_SPI:
   3502	case CXD2880_TNRDMD_TSOUT_IF_SDIO:
   3503
   3504		ret = tnr_dmd->io->read_regs(tnr_dmd->io,
   3505					     CXD2880_IO_TGT_DMD,
   3506					     0x00, &data, 1);
   3507		if (ret)
   3508			return ret;
   3509
   3510		break;
   3511	case CXD2880_TNRDMD_TSOUT_IF_TS:
   3512	default:
   3513		break;
   3514	}
   3515
   3516	return tnr_dmd->io->write_reg(tnr_dmd->io,
   3517				      CXD2880_IO_TGT_DMD,
   3518				      0x01, 0x01);
   3519}