Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * cxd2880_tnrdmd.c
0004  * Sony CXD2880 DVB-T2/T tuner + demodulator driver
0005  * common control functions
0006  *
0007  * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
0008  */
0009 
0010 #include <media/dvb_frontend.h>
0011 #include "cxd2880_common.h"
0012 #include "cxd2880_tnrdmd.h"
0013 #include "cxd2880_tnrdmd_mon.h"
0014 #include "cxd2880_tnrdmd_dvbt.h"
0015 #include "cxd2880_tnrdmd_dvbt2.h"
0016 
0017 static const struct cxd2880_reg_value p_init1_seq[] = {
0018     {0x11, 0x16}, {0x00, 0x10},
0019 };
0020 
0021 static const struct cxd2880_reg_value rf_init1_seq1[] = {
0022     {0x4f, 0x18}, {0x61, 0x00}, {0x71, 0x00}, {0x9d, 0x01},
0023     {0x7d, 0x02}, {0x8f, 0x01}, {0x8b, 0xc6}, {0x9a, 0x03},
0024     {0x1c, 0x00},
0025 };
0026 
0027 static const struct cxd2880_reg_value rf_init1_seq2[] = {
0028     {0xb9, 0x07}, {0x33, 0x01}, {0xc1, 0x01}, {0xc4, 0x1e},
0029 };
0030 
0031 static const struct cxd2880_reg_value rf_init1_seq3[] = {
0032     {0x00, 0x10}, {0x51, 0x01}, {0xc5, 0x07}, {0x00, 0x11},
0033     {0x70, 0xe9}, {0x76, 0x0a}, {0x78, 0x32}, {0x7a, 0x46},
0034     {0x7c, 0x86}, {0x7e, 0xa4}, {0x00, 0x10}, {0xe1, 0x01},
0035 };
0036 
0037 static const struct cxd2880_reg_value rf_init1_seq4[] = {
0038     {0x15, 0x00}, {0x00, 0x16}
0039 };
0040 
0041 static const struct cxd2880_reg_value rf_init1_seq5[] = {
0042     {0x00, 0x00}, {0x25, 0x00}
0043 };
0044 
0045 static const struct cxd2880_reg_value rf_init1_seq6[] = {
0046     {0x02, 0x00}, {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1},
0047     {0x8f, 0x16}, {0x67, 0x60}, {0x6a, 0x0f}, {0x6c, 0x17}
0048 };
0049 
0050 static const struct cxd2880_reg_value rf_init1_seq7[] = {
0051     {0x00, 0xe2}, {0x41, 0xa0}, {0x4b, 0x68}, {0x00, 0x00},
0052     {0x21, 0x00}, {0x10, 0x01},
0053 };
0054 
0055 static const struct cxd2880_reg_value rf_init1_seq8[] = {
0056     {0x00, 0x10}, {0x25, 0x01},
0057 };
0058 
0059 static const struct cxd2880_reg_value rf_init1_seq9[] = {
0060     {0x00, 0x10}, {0x14, 0x01}, {0x00, 0x00}, {0x26, 0x00},
0061 };
0062 
0063 static const struct cxd2880_reg_value rf_init2_seq1[] = {
0064     {0x00, 0x14}, {0x1b, 0x01},
0065 };
0066 
0067 static const struct cxd2880_reg_value rf_init2_seq2[] = {
0068     {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1}, {0xd3, 0x00},
0069     {0x00, 0x00}, {0x21, 0x00},
0070 };
0071 
0072 static const struct cxd2880_reg_value x_tune1_seq1[] = {
0073     {0x00, 0x00}, {0x10, 0x01},
0074 };
0075 
0076 static const struct cxd2880_reg_value x_tune1_seq2[] = {
0077     {0x62, 0x00}, {0x00, 0x15},
0078 };
0079 
0080 static const struct cxd2880_reg_value x_tune2_seq1[] = {
0081     {0x00, 0x1a}, {0x29, 0x01},
0082 };
0083 
0084 static const struct cxd2880_reg_value x_tune2_seq2[] = {
0085     {0x62, 0x01}, {0x00, 0x11}, {0x2d, 0x00}, {0x2f, 0x00},
0086 };
0087 
0088 static const struct cxd2880_reg_value x_tune2_seq3[] = {
0089     {0x00, 0x00}, {0x10, 0x00}, {0x21, 0x01},
0090 };
0091 
0092 static const struct cxd2880_reg_value x_tune2_seq4[] = {
0093     {0x00, 0xe1}, {0x8a, 0x87},
0094 };
0095 
0096 static const struct cxd2880_reg_value x_tune2_seq5[] = {
0097     {0x00, 0x00}, {0x21, 0x00},
0098 };
0099 
0100 static const struct cxd2880_reg_value x_tune3_seq[] = {
0101     {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0xa0},
0102     {0x00, 0x00}, {0x21, 0x00}, {0xfe, 0x01},
0103 };
0104 
0105 static const struct cxd2880_reg_value x_tune4_seq[] = {
0106     {0x00, 0x00}, {0xfe, 0x01},
0107 };
0108 
0109 static const struct cxd2880_reg_value x_sleep1_seq[] = {
0110     {0x00, 0x00}, {0x57, 0x03},
0111 };
0112 
0113 static const struct cxd2880_reg_value x_sleep2_seq1[] = {
0114     {0x00, 0x2d}, {0xb1, 0x01},
0115 };
0116 
0117 static const struct cxd2880_reg_value x_sleep2_seq2[] = {
0118     {0x00, 0x10}, {0xf4, 0x00}, {0xf3, 0x00}, {0xf2, 0x00},
0119     {0xf1, 0x00}, {0xf0, 0x00}, {0xef, 0x00},
0120 };
0121 
0122 static const struct cxd2880_reg_value x_sleep3_seq[] = {
0123     {0x00, 0x00}, {0xfd, 0x00},
0124 };
0125 
0126 static const struct cxd2880_reg_value x_sleep4_seq[] = {
0127     {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0x00},
0128     {0x00, 0x00}, {0x21, 0x00},
0129 };
0130 
0131 static const struct cxd2880_reg_value spll_reset_seq1[] = {
0132     {0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01},
0133     {0x26, 0x01},
0134 };
0135 
0136 static const struct cxd2880_reg_value spll_reset_seq2[] = {
0137     {0x00, 0x00}, {0x10, 0x00},
0138 };
0139 
0140 static const struct cxd2880_reg_value spll_reset_seq3[] = {
0141     {0x00, 0x00}, {0x27, 0x00}, {0x22, 0x01},
0142 };
0143 
0144 static const struct cxd2880_reg_value spll_reset_seq4[] = {
0145     {0x00, 0x00}, {0x27, 0x01},
0146 };
0147 
0148 static const struct cxd2880_reg_value spll_reset_seq5[] = {
0149     {0x00, 0x00}, {0x10, 0x01},
0150 };
0151 
0152 static const struct cxd2880_reg_value t_power_x_seq1[] = {
0153     {0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01},
0154 };
0155 
0156 static const struct cxd2880_reg_value t_power_x_seq2[] = {
0157     {0x00, 0x00}, {0x10, 0x00},
0158 };
0159 
0160 static const struct cxd2880_reg_value t_power_x_seq3[] = {
0161     {0x00, 0x00}, {0x27, 0x00}, {0x25, 0x01},
0162 };
0163 
0164 static const struct cxd2880_reg_value t_power_x_seq4[] = {
0165     {0x00, 0x00}, {0x2a, 0x00},
0166 };
0167 
0168 static const struct cxd2880_reg_value t_power_x_seq5[] = {
0169     {0x00, 0x00}, {0x25, 0x00},
0170 };
0171 
0172 static const struct cxd2880_reg_value t_power_x_seq6[] = {
0173     {0x00, 0x00}, {0x27, 0x01},
0174 };
0175 
0176 static const struct cxd2880_reg_value t_power_x_seq7[] = {
0177     {0x00, 0x00}, {0x10, 0x01},
0178 };
0179 
0180 static const struct cxd2880_reg_value set_ts_pin_seq[] = {
0181     {0x50, 0x3f}, {0x52, 0x1f},
0182 
0183 };
0184 
0185 static const struct cxd2880_reg_value set_ts_output_seq1[] = {
0186     {0x00, 0x00}, {0x52, 0x00},
0187 };
0188 
0189 static const struct cxd2880_reg_value set_ts_output_seq2[] = {
0190     {0x00, 0x00}, {0xc3, 0x00},
0191 
0192 };
0193 
0194 static const struct cxd2880_reg_value set_ts_output_seq3[] = {
0195     {0x00, 0x00}, {0xc3, 0x01},
0196 
0197 };
0198 
0199 static const struct cxd2880_reg_value set_ts_output_seq4[] = {
0200     {0x00, 0x00}, {0x52, 0x1f},
0201 
0202 };
0203 
0204 static int p_init1(struct cxd2880_tnrdmd *tnr_dmd)
0205 {
0206     u8 data = 0;
0207     int ret;
0208 
0209     if (!tnr_dmd)
0210         return -EINVAL;
0211 
0212     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0213                      CXD2880_IO_TGT_SYS,
0214                      0x00, 0x00);
0215     if (ret)
0216         return ret;
0217 
0218     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE ||
0219         tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0220         switch (tnr_dmd->create_param.ts_output_if) {
0221         case CXD2880_TNRDMD_TSOUT_IF_TS:
0222             data = 0x00;
0223             break;
0224         case CXD2880_TNRDMD_TSOUT_IF_SPI:
0225             data = 0x01;
0226             break;
0227         case CXD2880_TNRDMD_TSOUT_IF_SDIO:
0228             data = 0x02;
0229             break;
0230         default:
0231             return -EINVAL;
0232         }
0233         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0234                          CXD2880_IO_TGT_SYS,
0235                          0x10, data);
0236         if (ret)
0237             return ret;
0238     }
0239 
0240     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0241                       CXD2880_IO_TGT_SYS,
0242                       p_init1_seq,
0243                       ARRAY_SIZE(p_init1_seq));
0244     if (ret)
0245         return ret;
0246 
0247     switch (tnr_dmd->chip_id) {
0248     case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X:
0249         data = 0x1a;
0250         break;
0251     case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11:
0252         data = 0x16;
0253         break;
0254     default:
0255         return -ENOTTY;
0256     }
0257 
0258     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0259                      CXD2880_IO_TGT_SYS,
0260                      0x10, data);
0261     if (ret)
0262         return ret;
0263 
0264     if (tnr_dmd->create_param.en_internal_ldo)
0265         data = 0x01;
0266     else
0267         data = 0x00;
0268 
0269     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0270                      CXD2880_IO_TGT_SYS,
0271                      0x11, data);
0272     if (ret)
0273         return ret;
0274     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0275                      CXD2880_IO_TGT_SYS,
0276                      0x13, data);
0277     if (ret)
0278         return ret;
0279 
0280     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0281                      CXD2880_IO_TGT_SYS,
0282                      0x00, 0x00);
0283     if (ret)
0284         return ret;
0285     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0286                      CXD2880_IO_TGT_SYS,
0287                      0x12, data);
0288     if (ret)
0289         return ret;
0290 
0291     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0292                      CXD2880_IO_TGT_SYS,
0293                      0x00, 0x10);
0294     if (ret)
0295         return ret;
0296 
0297     switch (tnr_dmd->chip_id) {
0298     case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X:
0299         data = 0x01;
0300         break;
0301     case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11:
0302         data = 0x00;
0303         break;
0304     default:
0305         return -ENOTTY;
0306     }
0307 
0308     return tnr_dmd->io->write_reg(tnr_dmd->io,
0309                       CXD2880_IO_TGT_SYS,
0310                       0x69, data);
0311 }
0312 
0313 static int p_init2(struct cxd2880_tnrdmd *tnr_dmd)
0314 {
0315     u8 data[6] = { 0 };
0316     int ret;
0317 
0318     if (!tnr_dmd)
0319         return -EINVAL;
0320 
0321     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0322                      CXD2880_IO_TGT_SYS,
0323                      0x00, 0x00);
0324     if (ret)
0325         return ret;
0326     data[0] = tnr_dmd->create_param.xosc_cap;
0327     data[1] = tnr_dmd->create_param.xosc_i;
0328     switch (tnr_dmd->create_param.xtal_share_type) {
0329     case CXD2880_TNRDMD_XTAL_SHARE_NONE:
0330         data[2] = 0x01;
0331         data[3] = 0x00;
0332         break;
0333     case CXD2880_TNRDMD_XTAL_SHARE_EXTREF:
0334         data[2] = 0x00;
0335         data[3] = 0x00;
0336         break;
0337     case CXD2880_TNRDMD_XTAL_SHARE_MASTER:
0338         data[2] = 0x01;
0339         data[3] = 0x01;
0340         break;
0341     case CXD2880_TNRDMD_XTAL_SHARE_SLAVE:
0342         data[2] = 0x00;
0343         data[3] = 0x01;
0344         break;
0345     default:
0346         return -EINVAL;
0347     }
0348     data[4] = 0x06;
0349     data[5] = 0x00;
0350 
0351     return tnr_dmd->io->write_regs(tnr_dmd->io,
0352                        CXD2880_IO_TGT_SYS,
0353                        0x13, data, 6);
0354 }
0355 
0356 static int p_init3(struct cxd2880_tnrdmd *tnr_dmd)
0357 {
0358     u8 data[2] = { 0 };
0359     int ret;
0360 
0361     if (!tnr_dmd)
0362         return -EINVAL;
0363 
0364     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0365                      CXD2880_IO_TGT_SYS,
0366                      0x00, 0x00);
0367     if (ret)
0368         return ret;
0369 
0370     switch (tnr_dmd->diver_mode) {
0371     case CXD2880_TNRDMD_DIVERMODE_SINGLE:
0372         data[0] = 0x00;
0373         break;
0374     case CXD2880_TNRDMD_DIVERMODE_MAIN:
0375         data[0] = 0x03;
0376         break;
0377     case CXD2880_TNRDMD_DIVERMODE_SUB:
0378         data[0] = 0x02;
0379         break;
0380     default:
0381         return -EINVAL;
0382     }
0383 
0384     data[1] = 0x01;
0385 
0386     return tnr_dmd->io->write_regs(tnr_dmd->io,
0387                        CXD2880_IO_TGT_SYS,
0388                        0x1f, data, 2);
0389 }
0390 
0391 static int rf_init1(struct cxd2880_tnrdmd *tnr_dmd)
0392 {
0393     u8 data[8] = { 0 };
0394     static const u8 rf_init1_cdata1[40] = {
0395         0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0396         0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03,
0397         0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x02,
0398         0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0399         0x02, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02,
0400         0x02, 0x03, 0x04, 0x04, 0x04
0401     };
0402 
0403     static const u8 rf_init1_cdata2[5] = {0xff, 0x00, 0x00, 0x00, 0x00};
0404     static const u8 rf_init1_cdata3[80] = {
0405         0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0406         0x01, 0x00, 0x02, 0x00, 0x63, 0x00, 0x00,
0407         0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
0408         0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x09,
0409         0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0d, 0x00,
0410         0x0d, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f,
0411         0x00, 0x10, 0x00, 0x79, 0x00, 0x00, 0x00,
0412         0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01,
0413         0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
0414         0x04, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05,
0415         0x00, 0x07, 0x00, 0x07, 0x00, 0x08, 0x00,
0416         0x0a, 0x03, 0xe0
0417     };
0418 
0419     static const u8 rf_init1_cdata4[8] = {
0420         0x20, 0x20, 0x30, 0x41, 0x50, 0x5f, 0x6f, 0x80
0421     };
0422 
0423     static const u8 rf_init1_cdata5[50] = {
0424         0x00, 0x09, 0x00, 0x08, 0x00, 0x07, 0x00,
0425         0x06, 0x00, 0x05, 0x00, 0x03, 0x00, 0x02,
0426         0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
0427         0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0c,
0428         0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0f, 0x00,
0429         0x0e, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f,
0430         0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f, 0x00,
0431         0x0e
0432     };
0433 
0434     u8 addr = 0;
0435     int ret;
0436 
0437     if (!tnr_dmd)
0438         return -EINVAL;
0439 
0440     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0441                      CXD2880_IO_TGT_SYS,
0442                      0x00, 0x00);
0443     if (ret)
0444         return ret;
0445     data[0] = 0x01;
0446     data[1] = 0x00;
0447     data[2] = 0x01;
0448     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0449                       CXD2880_IO_TGT_SYS,
0450                       0x21, data, 3);
0451     if (ret)
0452         return ret;
0453 
0454     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0455                      CXD2880_IO_TGT_SYS,
0456                      0x00, 0x10);
0457     if (ret)
0458         return ret;
0459     data[0] = 0x01;
0460     data[1] = 0x01;
0461     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0462                       CXD2880_IO_TGT_SYS,
0463                       0x17, data, 2);
0464     if (ret)
0465         return ret;
0466 
0467     if (tnr_dmd->create_param.stationary_use) {
0468         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0469                          CXD2880_IO_TGT_SYS,
0470                          0x1a, 0x06);
0471         if (ret)
0472             return ret;
0473     }
0474 
0475     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0476                       CXD2880_IO_TGT_SYS,
0477                       rf_init1_seq1,
0478                       ARRAY_SIZE(rf_init1_seq1));
0479     if (ret)
0480         return ret;
0481 
0482     data[0] = 0x00;
0483     if (tnr_dmd->create_param.is_cxd2881gg &&
0484         tnr_dmd->create_param.xtal_share_type ==
0485         CXD2880_TNRDMD_XTAL_SHARE_SLAVE)
0486         data[1] = 0x00;
0487     else
0488         data[1] = 0x1f;
0489     data[2] = 0x0a;
0490     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0491                       CXD2880_IO_TGT_SYS,
0492                       0xb5, data, 3);
0493     if (ret)
0494         return ret;
0495 
0496     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0497                       CXD2880_IO_TGT_SYS,
0498                       rf_init1_seq2,
0499                       ARRAY_SIZE(rf_init1_seq2));
0500     if (ret)
0501         return ret;
0502 
0503     if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) {
0504         data[0] = 0x34;
0505         data[1] = 0x2c;
0506     } else {
0507         data[0] = 0x2f;
0508         data[1] = 0x25;
0509     }
0510     data[2] = 0x15;
0511     data[3] = 0x19;
0512     data[4] = 0x1b;
0513     data[5] = 0x15;
0514     data[6] = 0x19;
0515     data[7] = 0x1b;
0516     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0517                       CXD2880_IO_TGT_SYS,
0518                       0xd9, data, 8);
0519     if (ret)
0520         return ret;
0521 
0522     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0523                      CXD2880_IO_TGT_SYS,
0524                      0x00, 0x11);
0525     if (ret)
0526         return ret;
0527     data[0] = 0x6c;
0528     data[1] = 0x10;
0529     data[2] = 0xa6;
0530     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0531                       CXD2880_IO_TGT_SYS,
0532                       0x44, data, 3);
0533     if (ret)
0534         return ret;
0535     data[0] = 0x16;
0536     data[1] = 0xa8;
0537     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0538                       CXD2880_IO_TGT_SYS,
0539                       0x50, data, 2);
0540     if (ret)
0541         return ret;
0542     data[0] = 0x00;
0543     data[1] = 0x22;
0544     data[2] = 0x00;
0545     data[3] = 0x88;
0546     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0547                       CXD2880_IO_TGT_SYS,
0548                       0x62, data, 4);
0549     if (ret)
0550         return ret;
0551     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0552                      CXD2880_IO_TGT_SYS,
0553                      0x74, 0x75);
0554     if (ret)
0555         return ret;
0556     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0557                       CXD2880_IO_TGT_SYS,
0558                       0x7f, rf_init1_cdata1, 40);
0559     if (ret)
0560         return ret;
0561 
0562     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0563                      CXD2880_IO_TGT_SYS,
0564                      0x00, 0x16);
0565     if (ret)
0566         return ret;
0567     data[0] = 0x00;
0568     data[1] = 0x71;
0569     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0570                       CXD2880_IO_TGT_SYS,
0571                       0x10, data, 2);
0572     if (ret)
0573         return ret;
0574     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0575                      CXD2880_IO_TGT_SYS,
0576                      0x23, 0x89);
0577     if (ret)
0578         return ret;
0579 
0580     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0581                       CXD2880_IO_TGT_SYS,
0582                       0x27, rf_init1_cdata2, 5);
0583     if (ret)
0584         return ret;
0585 
0586     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0587                       CXD2880_IO_TGT_SYS,
0588                       0x3a, rf_init1_cdata3, 80);
0589     if (ret)
0590         return ret;
0591 
0592     data[0] = 0x03;
0593     data[1] = 0xe0;
0594     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0595                       CXD2880_IO_TGT_SYS,
0596                       0xbc, data, 2);
0597     if (ret)
0598         return ret;
0599 
0600     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0601                       CXD2880_IO_TGT_SYS,
0602                       rf_init1_seq3,
0603                       ARRAY_SIZE(rf_init1_seq3));
0604     if (ret)
0605         return ret;
0606 
0607     if (tnr_dmd->create_param.stationary_use) {
0608         data[0] = 0x06;
0609         data[1] = 0x07;
0610         data[2] = 0x1a;
0611     } else {
0612         data[0] = 0x00;
0613         data[1] = 0x08;
0614         data[2] = 0x19;
0615     }
0616     data[3] = 0x0e;
0617     data[4] = 0x09;
0618     data[5] = 0x0e;
0619 
0620     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0621                      CXD2880_IO_TGT_SYS,
0622                      0x00, 0x12);
0623     if (ret)
0624         return ret;
0625     for (addr = 0x10; addr < 0x9f; addr += 6) {
0626         if (tnr_dmd->lna_thrs_tbl_air) {
0627             u8 idx = 0;
0628 
0629             idx = (addr - 0x10) / 6;
0630             data[0] =
0631                 tnr_dmd->lna_thrs_tbl_air->thrs[idx].off_on;
0632             data[1] =
0633                 tnr_dmd->lna_thrs_tbl_air->thrs[idx].on_off;
0634         }
0635         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0636                           CXD2880_IO_TGT_SYS,
0637                           addr, data, 6);
0638         if (ret)
0639             return ret;
0640     }
0641 
0642     data[0] = 0x00;
0643     data[1] = 0x08;
0644     if (tnr_dmd->create_param.stationary_use)
0645         data[2] = 0x1a;
0646     else
0647         data[2] = 0x19;
0648     data[3] = 0x0e;
0649     data[4] = 0x09;
0650     data[5] = 0x0e;
0651 
0652     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0653                      CXD2880_IO_TGT_SYS,
0654                      0x00, 0x13);
0655     if (ret)
0656         return ret;
0657     for (addr = 0x10; addr < 0xcf; addr += 6) {
0658         if (tnr_dmd->lna_thrs_tbl_cable) {
0659             u8 idx = 0;
0660 
0661             idx = (addr - 0x10) / 6;
0662             data[0] =
0663                 tnr_dmd->lna_thrs_tbl_cable->thrs[idx].off_on;
0664             data[1] =
0665                 tnr_dmd->lna_thrs_tbl_cable->thrs[idx].on_off;
0666         }
0667         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0668                           CXD2880_IO_TGT_SYS,
0669                           addr, data, 6);
0670         if (ret)
0671             return ret;
0672     }
0673 
0674     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0675                      CXD2880_IO_TGT_SYS,
0676                      0x00, 0x11);
0677     if (ret)
0678         return ret;
0679     data[0] = 0x08;
0680     data[1] = 0x09;
0681     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0682                       CXD2880_IO_TGT_SYS,
0683                       0xbd, data, 2);
0684     if (ret)
0685         return ret;
0686     data[0] = 0x08;
0687     data[1] = 0x09;
0688     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0689                       CXD2880_IO_TGT_SYS,
0690                       0xc4, data, 2);
0691     if (ret)
0692         return ret;
0693 
0694     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0695                       CXD2880_IO_TGT_SYS,
0696                       0xc9, rf_init1_cdata4, 8);
0697     if (ret)
0698         return ret;
0699 
0700     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0701                      CXD2880_IO_TGT_SYS,
0702                      0x00, 0x14);
0703     if (ret)
0704         return ret;
0705     data[0] = 0x15;
0706     data[1] = 0x18;
0707     data[2] = 0x00;
0708     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0709                       CXD2880_IO_TGT_SYS,
0710                       0x10, data, 3);
0711     if (ret)
0712         return ret;
0713 
0714     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0715                       CXD2880_IO_TGT_SYS,
0716                       rf_init1_seq4,
0717                       ARRAY_SIZE(rf_init1_seq4));
0718     if (ret)
0719         return ret;
0720 
0721     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0722                       CXD2880_IO_TGT_SYS,
0723                       0x12, rf_init1_cdata5, 50);
0724     if (ret)
0725         return ret;
0726 
0727     usleep_range(1000, 2000);
0728 
0729     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0730                      CXD2880_IO_TGT_SYS,
0731                      0x00, 0x0a);
0732     if (ret)
0733         return ret;
0734     ret = tnr_dmd->io->read_regs(tnr_dmd->io,
0735                      CXD2880_IO_TGT_SYS,
0736                      0x10, data, 1);
0737     if (ret)
0738         return ret;
0739     if ((data[0] & 0x01) == 0x00)
0740         return -EINVAL;
0741 
0742     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0743                       CXD2880_IO_TGT_SYS,
0744                       rf_init1_seq5,
0745                       ARRAY_SIZE(rf_init1_seq5));
0746     if (ret)
0747         return ret;
0748 
0749     usleep_range(1000, 2000);
0750 
0751     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0752                      CXD2880_IO_TGT_SYS,
0753                      0x00, 0x0a);
0754     if (ret)
0755         return ret;
0756     ret = tnr_dmd->io->read_regs(tnr_dmd->io,
0757                      CXD2880_IO_TGT_SYS,
0758                      0x11, data, 1);
0759     if (ret)
0760         return ret;
0761     if ((data[0] & 0x01) == 0x00)
0762         return -EINVAL;
0763 
0764     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0765                       CXD2880_IO_TGT_DMD,
0766                       rf_init1_seq6,
0767                       ARRAY_SIZE(rf_init1_seq6));
0768     if (ret)
0769         return ret;
0770 
0771     data[0] = 0x00;
0772     data[1] = 0xfe;
0773     data[2] = 0xee;
0774     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0775                       CXD2880_IO_TGT_DMD,
0776                       0x6e, data, 3);
0777     if (ret)
0778         return ret;
0779     data[0] = 0xa1;
0780     data[1] = 0x8b;
0781     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0782                       CXD2880_IO_TGT_DMD,
0783                       0x8d, data, 2);
0784     if (ret)
0785         return ret;
0786     data[0] = 0x08;
0787     data[1] = 0x09;
0788     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0789                       CXD2880_IO_TGT_DMD,
0790                       0x77, data, 2);
0791     if (ret)
0792         return ret;
0793 
0794     if (tnr_dmd->create_param.stationary_use) {
0795         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0796                          CXD2880_IO_TGT_DMD,
0797                          0x80, 0xaa);
0798         if (ret)
0799             return ret;
0800     }
0801 
0802     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0803                       CXD2880_IO_TGT_DMD,
0804                       rf_init1_seq7,
0805                       ARRAY_SIZE(rf_init1_seq7));
0806     if (ret)
0807         return ret;
0808 
0809     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0810                       CXD2880_IO_TGT_SYS,
0811                       rf_init1_seq8,
0812                       ARRAY_SIZE(rf_init1_seq8));
0813     if (ret)
0814         return ret;
0815 
0816     usleep_range(1000, 2000);
0817 
0818     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0819                      CXD2880_IO_TGT_SYS,
0820                      0x00, 0x1a);
0821     if (ret)
0822         return ret;
0823     ret = tnr_dmd->io->read_regs(tnr_dmd->io,
0824                      CXD2880_IO_TGT_SYS,
0825                      0x10, data, 1);
0826     if (ret)
0827         return ret;
0828     if ((data[0] & 0x01) == 0x00)
0829         return -EINVAL;
0830 
0831     return cxd2880_io_write_multi_regs(tnr_dmd->io,
0832                        CXD2880_IO_TGT_SYS,
0833                        rf_init1_seq9,
0834                        ARRAY_SIZE(rf_init1_seq9));
0835 }
0836 
0837 static int rf_init2(struct cxd2880_tnrdmd *tnr_dmd)
0838 {
0839     u8 data[5] = { 0 };
0840     int ret;
0841 
0842     if (!tnr_dmd)
0843         return -EINVAL;
0844 
0845     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0846                      CXD2880_IO_TGT_SYS,
0847                      0x00, 0x10);
0848     if (ret)
0849         return ret;
0850     data[0] = 0x40;
0851     data[1] = 0x40;
0852     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0853                       CXD2880_IO_TGT_SYS,
0854                       0xea, data, 2);
0855     if (ret)
0856         return ret;
0857 
0858     usleep_range(1000, 2000);
0859 
0860     data[0] = 0x00;
0861     if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X)
0862         data[1] = 0x00;
0863     else
0864         data[1] = 0x01;
0865     data[2] = 0x01;
0866     data[3] = 0x03;
0867     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0868                       CXD2880_IO_TGT_SYS,
0869                       0x30, data, 4);
0870     if (ret)
0871         return ret;
0872 
0873     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0874                       CXD2880_IO_TGT_SYS,
0875                       rf_init2_seq1,
0876                       ARRAY_SIZE(rf_init2_seq1));
0877     if (ret)
0878         return ret;
0879 
0880     return cxd2880_io_write_multi_regs(tnr_dmd->io,
0881                        CXD2880_IO_TGT_DMD,
0882                        rf_init2_seq2,
0883                        ARRAY_SIZE(rf_init2_seq2));
0884 }
0885 
0886 static int x_tune1(struct cxd2880_tnrdmd *tnr_dmd,
0887            enum cxd2880_dtv_sys sys, u32 freq_khz,
0888            enum cxd2880_dtv_bandwidth bandwidth,
0889            u8 is_cable, int shift_frequency_khz)
0890 {
0891     u8 data[11] = { 0 };
0892     int ret;
0893 
0894     if (!tnr_dmd)
0895         return -EINVAL;
0896 
0897     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0898                       CXD2880_IO_TGT_DMD,
0899                       x_tune1_seq1,
0900                       ARRAY_SIZE(x_tune1_seq1));
0901     if (ret)
0902         return ret;
0903 
0904     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0905                      CXD2880_IO_TGT_SYS,
0906                      0x00, 0x10);
0907     if (ret)
0908         return ret;
0909 
0910     data[2] = 0x0e;
0911     data[4] = 0x03;
0912     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0913                       CXD2880_IO_TGT_SYS,
0914                       0xe7, data, 5);
0915     if (ret)
0916         return ret;
0917 
0918     data[0] = 0x1f;
0919     data[1] = 0x80;
0920     data[2] = 0x18;
0921     data[3] = 0x00;
0922     data[4] = 0x07;
0923     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0924                       CXD2880_IO_TGT_SYS,
0925                       0xe7, data, 5);
0926     if (ret)
0927         return ret;
0928 
0929     usleep_range(1000, 2000);
0930 
0931     data[0] = 0x72;
0932     data[1] = 0x81;
0933     data[3] = 0x1d;
0934     data[4] = 0x6f;
0935     data[5] = 0x7e;
0936     data[7] = 0x1c;
0937     switch (sys) {
0938     case CXD2880_DTV_SYS_DVBT:
0939         data[2] = 0x94;
0940         data[6] = 0x91;
0941         break;
0942     case CXD2880_DTV_SYS_DVBT2:
0943         data[2] = 0x96;
0944         data[6] = 0x93;
0945         break;
0946     default:
0947         return -EINVAL;
0948     }
0949     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0950                       CXD2880_IO_TGT_SYS,
0951                       0x44, data, 8);
0952     if (ret)
0953         return ret;
0954 
0955     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0956                       CXD2880_IO_TGT_SYS,
0957                       x_tune1_seq2,
0958                       ARRAY_SIZE(x_tune1_seq2));
0959     if (ret)
0960         return ret;
0961 
0962     data[0] = 0x03;
0963     data[1] = 0xe2;
0964     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0965                       CXD2880_IO_TGT_SYS,
0966                       0x1e, data, 2);
0967     if (ret)
0968         return ret;
0969 
0970     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0971                      CXD2880_IO_TGT_SYS,
0972                      0x00, 0x10);
0973     if (ret)
0974         return ret;
0975 
0976     data[0] = is_cable ? 0x01 : 0x00;
0977     data[1] = 0x00;
0978     data[2] = 0x6b;
0979     data[3] = 0x4d;
0980 
0981     switch (bandwidth) {
0982     case CXD2880_DTV_BW_1_7_MHZ:
0983         data[4] = 0x03;
0984         break;
0985     case CXD2880_DTV_BW_5_MHZ:
0986     case CXD2880_DTV_BW_6_MHZ:
0987         data[4] = 0x00;
0988         break;
0989     case CXD2880_DTV_BW_7_MHZ:
0990         data[4] = 0x01;
0991         break;
0992     case CXD2880_DTV_BW_8_MHZ:
0993         data[4] = 0x02;
0994         break;
0995     default:
0996         return -EINVAL;
0997     }
0998 
0999     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 
1014 static 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 
1221 static 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 
1270 static 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 
1350 static 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 
1410 static 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 
1442 static 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 
1453 static 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 
1464 static 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 
1565 static 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 
1698 struct cxd2880_tnrdmd_ts_clk_cfg {
1699     u8 srl_clk_mode;
1700     u8 srl_duty_mode;
1701     u8 ts_clk_period;
1702 };
1703 
1704 static 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 
1809 static 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 
1848 static 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 
1875 static 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 
1916 int 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 
1943 int 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 
2006 int 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 
2095 int 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 
2142 int 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 
2184 int 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 
2381 int 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 
2414 int 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 
2502 int 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 
2988 int 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 
3039 int 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 
3055 int 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 
3087 int 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 
3099 int 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 
3119 int 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 
3131 int 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 
3160 int 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 
3187 int 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 
3220 int 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 
3245 int 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 
3272 int 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 
3292 int 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 
3322 int 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 
3336 int 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 
3352 int 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 
3367 int 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 
3384 int 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 
3431 int 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 
3492 int 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 }