Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * cxd2880_tnrdmd_dvbt2.c
0004  * Sony CXD2880 DVB-T2/T tuner + demodulator driver
0005  * control functions for DVB-T2
0006  *
0007  * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
0008  */
0009 
0010 #include <media/dvb_frontend.h>
0011 
0012 #include "cxd2880_tnrdmd_dvbt2.h"
0013 #include "cxd2880_tnrdmd_dvbt2_mon.h"
0014 
0015 static const struct cxd2880_reg_value tune_dmd_setting_seq1[] = {
0016     {0x00, 0x00}, {0x31, 0x02},
0017 };
0018 
0019 static const struct cxd2880_reg_value tune_dmd_setting_seq2[] = {
0020     {0x00, 0x04}, {0x5d, 0x0b},
0021 };
0022 
0023 static int x_tune_dvbt2_demod_setting(struct cxd2880_tnrdmd
0024                       *tnr_dmd,
0025                       enum cxd2880_dtv_bandwidth
0026                       bandwidth,
0027                       enum cxd2880_tnrdmd_clockmode
0028                       clk_mode)
0029 {
0030     static const u8 tsif_settings[2] = { 0x01, 0x01 };
0031     static const u8 init_settings[14] = {
0032         0x07, 0x06, 0x01, 0xf0, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x00,
0033         0x09, 0x9c, 0x0e, 0x4c
0034     };
0035     static const u8 clk_mode_settings_a1[9] = {
0036         0x52, 0x49, 0x2c, 0x51, 0x51, 0x3d, 0x15, 0x29, 0x0c
0037     };
0038 
0039     static const u8 clk_mode_settings_b1[9] = {
0040         0x5d, 0x55, 0x32, 0x5c, 0x5c, 0x45, 0x17, 0x2e, 0x0d
0041     };
0042 
0043     static const u8 clk_mode_settings_c1[9] = {
0044         0x60, 0x00, 0x34, 0x5e, 0x5e, 0x47, 0x18, 0x2f, 0x0e
0045     };
0046 
0047     static const u8 clk_mode_settings_a2[13] = {
0048         0x04, 0xe7, 0x94, 0x92, 0x09, 0xcf, 0x7e, 0xd0, 0x49,
0049         0xcd, 0xcd, 0x1f, 0x5b
0050     };
0051 
0052     static const u8 clk_mode_settings_b2[13] = {
0053         0x05, 0x90, 0x27, 0x55, 0x0b, 0x20, 0x8f, 0xd6, 0xea,
0054         0xc8, 0xc8, 0x23, 0x91
0055     };
0056 
0057     static const u8 clk_mode_settings_c2[13] = {
0058         0x05, 0xb8, 0xd8, 0x00, 0x0b, 0x72, 0x93, 0xf3, 0x00,
0059         0xcd, 0xcd, 0x24, 0x95
0060     };
0061 
0062     static const u8 clk_mode_settings_a3[5] = {
0063         0x0b, 0x6a, 0xc9, 0x03, 0x33
0064     };
0065     static const u8 clk_mode_settings_b3[5] = {
0066         0x01, 0x02, 0xe4, 0x03, 0x39
0067     };
0068     static const u8 clk_mode_settings_c3[5] = {
0069         0x01, 0x02, 0xeb, 0x03, 0x3b
0070     };
0071 
0072     static const u8 gtdofst[2] = { 0x3f, 0xff };
0073 
0074     static const u8 bw8_gtdofst_a[2] = { 0x19, 0xd2 };
0075     static const u8 bw8_nomi_ac[6] = { 0x15, 0x00, 0x00, 0x00, 0x00, 0x00 };
0076     static const u8 bw8_nomi_b[6] = { 0x14, 0x6a, 0xaa, 0xaa, 0xab, 0x00 };
0077     static const u8 bw8_sst_a[2] = { 0x06, 0x2a };
0078     static const u8 bw8_sst_b[2] = { 0x06, 0x29 };
0079     static const u8 bw8_sst_c[2] = { 0x06, 0x28 };
0080     static const u8 bw8_mrc_a[9] = {
0081         0x28, 0x00, 0x50, 0x00, 0x60, 0x00, 0x00, 0x90, 0x00
0082     };
0083     static const u8 bw8_mrc_b[9] = {
0084         0x2d, 0x5e, 0x5a, 0xbd, 0x6c, 0xe3, 0x00, 0xa3, 0x55
0085     };
0086     static const u8 bw8_mrc_c[9] = {
0087         0x2e, 0xaa, 0x5d, 0x55, 0x70, 0x00, 0x00, 0xa8, 0x00
0088     };
0089 
0090     static const u8 bw7_nomi_ac[6] = { 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 };
0091     static const u8 bw7_nomi_b[6] = { 0x17, 0x55, 0x55, 0x55, 0x55, 0x00 };
0092     static const u8 bw7_sst_a[2] = { 0x06, 0x23 };
0093     static const u8 bw7_sst_b[2] = { 0x06, 0x22 };
0094     static const u8 bw7_sst_c[2] = { 0x06, 0x21 };
0095     static const u8 bw7_mrc_a[9] = {
0096         0x2d, 0xb6, 0x5b, 0x6d, 0x6d, 0xb6, 0x00, 0xa4, 0x92
0097     };
0098     static const u8 bw7_mrc_b[9] = {
0099         0x33, 0xda, 0x67, 0xb4, 0x7c, 0x71, 0x00, 0xba, 0xaa
0100     };
0101     static const u8 bw7_mrc_c[9] = {
0102         0x35, 0x55, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xc0, 0x00
0103     };
0104 
0105     static const u8 bw6_nomi_ac[6] = { 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00 };
0106     static const u8 bw6_nomi_b[6] = { 0x1b, 0x38, 0xe3, 0x8e, 0x39, 0x00 };
0107     static const u8 bw6_sst_a[2] = { 0x06, 0x1c };
0108     static const u8 bw6_sst_b[2] = { 0x06, 0x1b };
0109     static const u8 bw6_sst_c[2] = { 0x06, 0x1a };
0110     static const u8 bw6_mrc_a[9] = {
0111         0x35, 0x55, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xc0, 0x00
0112     };
0113     static const u8 bw6_mrc_b[9] = {
0114         0x3c, 0x7e, 0x78, 0xfc, 0x91, 0x2f, 0x00, 0xd9, 0xc7
0115     };
0116     static const u8 bw6_mrc_c[9] = {
0117         0x3e, 0x38, 0x7c, 0x71, 0x95, 0x55, 0x00, 0xdf, 0xff
0118     };
0119 
0120     static const u8 bw5_nomi_ac[6] = { 0x21, 0x99, 0x99, 0x99, 0x9a, 0x00 };
0121     static const u8 bw5_nomi_b[6] = { 0x20, 0xaa, 0xaa, 0xaa, 0xab, 0x00 };
0122     static const u8 bw5_sst_a[2] = { 0x06, 0x15 };
0123     static const u8 bw5_sst_b[2] = { 0x06, 0x15 };
0124     static const u8 bw5_sst_c[2] = { 0x06, 0x14 };
0125     static const u8 bw5_mrc_a[9] = {
0126         0x40, 0x00, 0x6a, 0xaa, 0x80, 0x00, 0x00, 0xe6, 0x66
0127     };
0128     static const u8 bw5_mrc_b[9] = {
0129         0x48, 0x97, 0x78, 0xfc, 0x91, 0x2f, 0x01, 0x05, 0x55
0130     };
0131     static const u8 bw5_mrc_c[9] = {
0132         0x4a, 0xaa, 0x7c, 0x71, 0x95, 0x55, 0x01, 0x0c, 0xcc
0133     };
0134 
0135     static const u8 bw1_7_nomi_a[6] = {
0136         0x68, 0x0f, 0xa2, 0x32, 0xcf, 0x03
0137     };
0138     static const u8 bw1_7_nomi_c[6] = {
0139         0x68, 0x0f, 0xa2, 0x32, 0xcf, 0x03
0140     };
0141     static const u8 bw1_7_nomi_b[6] = {
0142         0x65, 0x2b, 0xa4, 0xcd, 0xd8, 0x03
0143     };
0144     static const u8 bw1_7_sst_a[2] = { 0x06, 0x0c };
0145     static const u8 bw1_7_sst_b[2] = { 0x06, 0x0c };
0146     static const u8 bw1_7_sst_c[2] = { 0x06, 0x0b };
0147     static const u8 bw1_7_mrc_a[9] = {
0148         0x40, 0x00, 0x6a, 0xaa, 0x80, 0x00, 0x02, 0xc9, 0x8f
0149     };
0150     static const u8 bw1_7_mrc_b[9] = {
0151         0x48, 0x97, 0x78, 0xfc, 0x91, 0x2f, 0x03, 0x29, 0x5d
0152     };
0153     static const u8 bw1_7_mrc_c[9] = {
0154         0x4a, 0xaa, 0x7c, 0x71, 0x95, 0x55, 0x03, 0x40, 0x7d
0155     };
0156 
0157     const u8 *data = NULL;
0158     const u8 *data2 = NULL;
0159     const u8 *data3 = NULL;
0160     int ret;
0161 
0162     if (!tnr_dmd)
0163         return -EINVAL;
0164 
0165     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0166                       CXD2880_IO_TGT_SYS,
0167                       tune_dmd_setting_seq1,
0168                       ARRAY_SIZE(tune_dmd_setting_seq1));
0169     if (ret)
0170         return ret;
0171 
0172     ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
0173                       CXD2880_IO_TGT_DMD,
0174                       tune_dmd_setting_seq2,
0175                       ARRAY_SIZE(tune_dmd_setting_seq2));
0176     if (ret)
0177         return ret;
0178 
0179     if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) {
0180         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0181                          CXD2880_IO_TGT_DMD,
0182                          0x00, 0x00);
0183         if (ret)
0184             return ret;
0185 
0186         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0187                           CXD2880_IO_TGT_DMD,
0188                           0xce, tsif_settings, 2);
0189         if (ret)
0190             return ret;
0191     }
0192 
0193     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0194                      CXD2880_IO_TGT_DMD,
0195                      0x00, 0x20);
0196     if (ret)
0197         return ret;
0198 
0199     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0200                      CXD2880_IO_TGT_DMD,
0201                      0x8a, init_settings[0]);
0202     if (ret)
0203         return ret;
0204 
0205     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0206                      CXD2880_IO_TGT_DMD,
0207                      0x90, init_settings[1]);
0208     if (ret)
0209         return ret;
0210 
0211     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0212                      CXD2880_IO_TGT_DMD,
0213                      0x00, 0x25);
0214     if (ret)
0215         return ret;
0216 
0217     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0218                       CXD2880_IO_TGT_DMD,
0219                       0xf0, &init_settings[2], 2);
0220     if (ret)
0221         return ret;
0222 
0223     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0224                      CXD2880_IO_TGT_DMD,
0225                      0x00, 0x2a);
0226     if (ret)
0227         return ret;
0228 
0229     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0230                      CXD2880_IO_TGT_DMD,
0231                      0xdc, init_settings[4]);
0232     if (ret)
0233         return ret;
0234 
0235     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0236                      CXD2880_IO_TGT_DMD,
0237                      0xde, init_settings[5]);
0238     if (ret)
0239         return ret;
0240 
0241     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0242                      CXD2880_IO_TGT_DMD,
0243                      0x00, 0x2d);
0244     if (ret)
0245         return ret;
0246 
0247     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0248                       CXD2880_IO_TGT_DMD,
0249                       0x73, &init_settings[6], 4);
0250     if (ret)
0251         return ret;
0252 
0253     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0254                       CXD2880_IO_TGT_DMD,
0255                       0x8f, &init_settings[10], 4);
0256     if (ret)
0257         return ret;
0258 
0259     switch (clk_mode) {
0260     case CXD2880_TNRDMD_CLOCKMODE_A:
0261         data = clk_mode_settings_a1;
0262         data2 = clk_mode_settings_a2;
0263         data3 = clk_mode_settings_a3;
0264         break;
0265     case CXD2880_TNRDMD_CLOCKMODE_B:
0266         data = clk_mode_settings_b1;
0267         data2 = clk_mode_settings_b2;
0268         data3 = clk_mode_settings_b3;
0269         break;
0270     case CXD2880_TNRDMD_CLOCKMODE_C:
0271         data = clk_mode_settings_c1;
0272         data2 = clk_mode_settings_c2;
0273         data3 = clk_mode_settings_c3;
0274         break;
0275     default:
0276         return -EINVAL;
0277     }
0278 
0279     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0280                      CXD2880_IO_TGT_DMD,
0281                      0x00, 0x04);
0282     if (ret)
0283         return ret;
0284 
0285     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0286                       CXD2880_IO_TGT_DMD,
0287                       0x1d, &data[0], 3);
0288     if (ret)
0289         return ret;
0290 
0291     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0292                      CXD2880_IO_TGT_DMD,
0293                      0x22, data[3]);
0294     if (ret)
0295         return ret;
0296 
0297     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0298                      CXD2880_IO_TGT_DMD,
0299                      0x24, data[4]);
0300     if (ret)
0301         return ret;
0302 
0303     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0304                      CXD2880_IO_TGT_DMD,
0305                      0x26, data[5]);
0306     if (ret)
0307         return ret;
0308 
0309     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0310                       CXD2880_IO_TGT_DMD,
0311                       0x29, &data[6], 2);
0312     if (ret)
0313         return ret;
0314 
0315     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0316                      CXD2880_IO_TGT_DMD,
0317                      0x2d, data[8]);
0318     if (ret)
0319         return ret;
0320 
0321     if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) {
0322         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0323                           CXD2880_IO_TGT_DMD,
0324                           0x2e, &data2[0], 6);
0325         if (ret)
0326             return ret;
0327 
0328         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0329                           CXD2880_IO_TGT_DMD,
0330                           0x35, &data2[6], 7);
0331         if (ret)
0332             return ret;
0333     }
0334 
0335     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0336                       CXD2880_IO_TGT_DMD,
0337                       0x3c, &data3[0], 2);
0338     if (ret)
0339         return ret;
0340 
0341     ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0342                       CXD2880_IO_TGT_DMD,
0343                       0x56, &data3[2], 3);
0344     if (ret)
0345         return ret;
0346 
0347     switch (bandwidth) {
0348     case CXD2880_DTV_BW_8_MHZ:
0349         switch (clk_mode) {
0350         case CXD2880_TNRDMD_CLOCKMODE_A:
0351         case CXD2880_TNRDMD_CLOCKMODE_C:
0352             data = bw8_nomi_ac;
0353             break;
0354         case CXD2880_TNRDMD_CLOCKMODE_B:
0355             data = bw8_nomi_b;
0356             break;
0357         default:
0358             return -EINVAL;
0359         }
0360 
0361         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0362                           CXD2880_IO_TGT_DMD,
0363                           0x10, data, 6);
0364         if (ret)
0365             return ret;
0366 
0367         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0368                          CXD2880_IO_TGT_DMD,
0369                          0x4a, 0x00);
0370         if (ret)
0371             return ret;
0372 
0373         switch (clk_mode) {
0374         case CXD2880_TNRDMD_CLOCKMODE_A:
0375             data = bw8_gtdofst_a;
0376             break;
0377         case CXD2880_TNRDMD_CLOCKMODE_B:
0378         case CXD2880_TNRDMD_CLOCKMODE_C:
0379             data = gtdofst;
0380             break;
0381         default:
0382             return -EINVAL;
0383         }
0384 
0385         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0386                           CXD2880_IO_TGT_DMD,
0387                           0x19, data, 2);
0388         if (ret)
0389             return ret;
0390 
0391         switch (clk_mode) {
0392         case CXD2880_TNRDMD_CLOCKMODE_A:
0393             data = bw8_sst_a;
0394             break;
0395         case CXD2880_TNRDMD_CLOCKMODE_B:
0396             data = bw8_sst_b;
0397             break;
0398         case CXD2880_TNRDMD_CLOCKMODE_C:
0399             data = bw8_sst_c;
0400             break;
0401         default:
0402             return -EINVAL;
0403         }
0404 
0405         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0406                           CXD2880_IO_TGT_DMD,
0407                           0x1b, data, 2);
0408         if (ret)
0409             return ret;
0410 
0411         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0412             switch (clk_mode) {
0413             case CXD2880_TNRDMD_CLOCKMODE_A:
0414                 data = bw8_mrc_a;
0415                 break;
0416             case CXD2880_TNRDMD_CLOCKMODE_B:
0417                 data = bw8_mrc_b;
0418                 break;
0419             case CXD2880_TNRDMD_CLOCKMODE_C:
0420                 data = bw8_mrc_c;
0421                 break;
0422             default:
0423                 return -EINVAL;
0424             }
0425 
0426             ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0427                               CXD2880_IO_TGT_DMD,
0428                               0x4b, data, 9);
0429             if (ret)
0430                 return ret;
0431         }
0432         break;
0433 
0434     case CXD2880_DTV_BW_7_MHZ:
0435         switch (clk_mode) {
0436         case CXD2880_TNRDMD_CLOCKMODE_A:
0437         case CXD2880_TNRDMD_CLOCKMODE_C:
0438             data = bw7_nomi_ac;
0439             break;
0440         case CXD2880_TNRDMD_CLOCKMODE_B:
0441             data = bw7_nomi_b;
0442             break;
0443         default:
0444             return -EINVAL;
0445         }
0446 
0447         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0448                           CXD2880_IO_TGT_DMD,
0449                           0x10, data, 6);
0450         if (ret)
0451             return ret;
0452 
0453         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0454                          CXD2880_IO_TGT_DMD,
0455                          0x4a, 0x02);
0456         if (ret)
0457             return ret;
0458 
0459         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0460                           CXD2880_IO_TGT_DMD,
0461                           0x19, gtdofst, 2);
0462         if (ret)
0463             return ret;
0464 
0465         switch (clk_mode) {
0466         case CXD2880_TNRDMD_CLOCKMODE_A:
0467             data = bw7_sst_a;
0468             break;
0469         case CXD2880_TNRDMD_CLOCKMODE_B:
0470             data = bw7_sst_b;
0471             break;
0472         case CXD2880_TNRDMD_CLOCKMODE_C:
0473             data = bw7_sst_c;
0474             break;
0475         default:
0476             return -EINVAL;
0477         }
0478 
0479         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0480                           CXD2880_IO_TGT_DMD,
0481                           0x1b, data, 2);
0482         if (ret)
0483             return ret;
0484 
0485         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0486             switch (clk_mode) {
0487             case CXD2880_TNRDMD_CLOCKMODE_A:
0488                 data = bw7_mrc_a;
0489                 break;
0490             case CXD2880_TNRDMD_CLOCKMODE_B:
0491                 data = bw7_mrc_b;
0492                 break;
0493             case CXD2880_TNRDMD_CLOCKMODE_C:
0494                 data = bw7_mrc_c;
0495                 break;
0496             default:
0497                 return -EINVAL;
0498             }
0499 
0500             ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0501                               CXD2880_IO_TGT_DMD,
0502                               0x4b, data, 9);
0503             if (ret)
0504                 return ret;
0505         }
0506         break;
0507 
0508     case CXD2880_DTV_BW_6_MHZ:
0509         switch (clk_mode) {
0510         case CXD2880_TNRDMD_CLOCKMODE_A:
0511         case CXD2880_TNRDMD_CLOCKMODE_C:
0512             data = bw6_nomi_ac;
0513             break;
0514         case CXD2880_TNRDMD_CLOCKMODE_B:
0515             data = bw6_nomi_b;
0516             break;
0517         default:
0518             return -EINVAL;
0519         }
0520 
0521         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0522                           CXD2880_IO_TGT_DMD,
0523                           0x10, data, 6);
0524         if (ret)
0525             return ret;
0526 
0527         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0528                          CXD2880_IO_TGT_DMD,
0529                          0x4a, 0x04);
0530         if (ret)
0531             return ret;
0532 
0533         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0534                           CXD2880_IO_TGT_DMD,
0535                           0x19, gtdofst, 2);
0536         if (ret)
0537             return ret;
0538 
0539         switch (clk_mode) {
0540         case CXD2880_TNRDMD_CLOCKMODE_A:
0541             data = bw6_sst_a;
0542             break;
0543         case CXD2880_TNRDMD_CLOCKMODE_B:
0544             data = bw6_sst_b;
0545             break;
0546         case CXD2880_TNRDMD_CLOCKMODE_C:
0547             data = bw6_sst_c;
0548             break;
0549         default:
0550             return -EINVAL;
0551         }
0552 
0553         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0554                           CXD2880_IO_TGT_DMD,
0555                           0x1b, data, 2);
0556         if (ret)
0557             return ret;
0558 
0559         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0560             switch (clk_mode) {
0561             case CXD2880_TNRDMD_CLOCKMODE_A:
0562                 data = bw6_mrc_a;
0563                 break;
0564             case CXD2880_TNRDMD_CLOCKMODE_B:
0565                 data = bw6_mrc_b;
0566                 break;
0567             case CXD2880_TNRDMD_CLOCKMODE_C:
0568                 data = bw6_mrc_c;
0569                 break;
0570             default:
0571                 return -EINVAL;
0572             }
0573 
0574             ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0575                               CXD2880_IO_TGT_DMD,
0576                               0x4b, data, 9);
0577             if (ret)
0578                 return ret;
0579         }
0580         break;
0581 
0582     case CXD2880_DTV_BW_5_MHZ:
0583         switch (clk_mode) {
0584         case CXD2880_TNRDMD_CLOCKMODE_A:
0585         case CXD2880_TNRDMD_CLOCKMODE_C:
0586             data = bw5_nomi_ac;
0587             break;
0588         case CXD2880_TNRDMD_CLOCKMODE_B:
0589             data = bw5_nomi_b;
0590             break;
0591         default:
0592             return -EINVAL;
0593         }
0594 
0595         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0596                           CXD2880_IO_TGT_DMD,
0597                           0x10, data, 6);
0598         if (ret)
0599             return ret;
0600 
0601         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0602                          CXD2880_IO_TGT_DMD,
0603                          0x4a, 0x06);
0604         if (ret)
0605             return ret;
0606 
0607         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0608                           CXD2880_IO_TGT_DMD,
0609                           0x19, gtdofst, 2);
0610         if (ret)
0611             return ret;
0612 
0613         switch (clk_mode) {
0614         case CXD2880_TNRDMD_CLOCKMODE_A:
0615             data = bw5_sst_a;
0616             break;
0617         case CXD2880_TNRDMD_CLOCKMODE_B:
0618             data = bw5_sst_b;
0619             break;
0620         case CXD2880_TNRDMD_CLOCKMODE_C:
0621             data = bw5_sst_c;
0622             break;
0623         default:
0624             return -EINVAL;
0625         }
0626 
0627         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0628                           CXD2880_IO_TGT_DMD,
0629                           0x1b, data, 2);
0630         if (ret)
0631             return ret;
0632 
0633         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0634             switch (clk_mode) {
0635             case CXD2880_TNRDMD_CLOCKMODE_A:
0636                 data = bw5_mrc_a;
0637                 break;
0638             case CXD2880_TNRDMD_CLOCKMODE_B:
0639                 data = bw5_mrc_b;
0640                 break;
0641             case CXD2880_TNRDMD_CLOCKMODE_C:
0642                 data = bw5_mrc_c;
0643                 break;
0644             default:
0645                 return -EINVAL;
0646             }
0647 
0648             ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0649                               CXD2880_IO_TGT_DMD,
0650                               0x4b, data, 9);
0651             if (ret)
0652                 return ret;
0653         }
0654         break;
0655 
0656     case CXD2880_DTV_BW_1_7_MHZ:
0657 
0658         switch (clk_mode) {
0659         case CXD2880_TNRDMD_CLOCKMODE_A:
0660             data = bw1_7_nomi_a;
0661             break;
0662         case CXD2880_TNRDMD_CLOCKMODE_C:
0663             data = bw1_7_nomi_c;
0664             break;
0665         case CXD2880_TNRDMD_CLOCKMODE_B:
0666             data = bw1_7_nomi_b;
0667             break;
0668         default:
0669             return -EINVAL;
0670         }
0671 
0672         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0673                           CXD2880_IO_TGT_DMD,
0674                           0x10, data, 6);
0675         if (ret)
0676             return ret;
0677 
0678         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0679                          CXD2880_IO_TGT_DMD,
0680                          0x4a, 0x03);
0681         if (ret)
0682             return ret;
0683 
0684         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0685                           CXD2880_IO_TGT_DMD,
0686                           0x19, gtdofst, 2);
0687         if (ret)
0688             return ret;
0689 
0690         switch (clk_mode) {
0691         case CXD2880_TNRDMD_CLOCKMODE_A:
0692             data = bw1_7_sst_a;
0693             break;
0694         case CXD2880_TNRDMD_CLOCKMODE_B:
0695             data = bw1_7_sst_b;
0696             break;
0697         case CXD2880_TNRDMD_CLOCKMODE_C:
0698             data = bw1_7_sst_c;
0699             break;
0700         default:
0701             return -EINVAL;
0702         }
0703 
0704         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0705                           CXD2880_IO_TGT_DMD,
0706                           0x1b, data, 2);
0707         if (ret)
0708             return ret;
0709 
0710         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0711             switch (clk_mode) {
0712             case CXD2880_TNRDMD_CLOCKMODE_A:
0713                 data = bw1_7_mrc_a;
0714                 break;
0715             case CXD2880_TNRDMD_CLOCKMODE_B:
0716                 data = bw1_7_mrc_b;
0717                 break;
0718             case CXD2880_TNRDMD_CLOCKMODE_C:
0719                 data = bw1_7_mrc_c;
0720                 break;
0721             default:
0722                 return -EINVAL;
0723             }
0724 
0725             ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0726                               CXD2880_IO_TGT_DMD,
0727                               0x4b, data, 9);
0728             if (ret)
0729                 return ret;
0730         }
0731         break;
0732 
0733     default:
0734         return -EINVAL;
0735     }
0736 
0737     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0738                      CXD2880_IO_TGT_DMD,
0739                      0x00, 0x00);
0740     if (ret)
0741         return ret;
0742 
0743     return tnr_dmd->io->write_reg(tnr_dmd->io,
0744                       CXD2880_IO_TGT_DMD,
0745                       0xfd, 0x01);
0746 }
0747 
0748 static int x_sleep_dvbt2_demod_setting(struct cxd2880_tnrdmd
0749                        *tnr_dmd)
0750 {
0751     static const u8 difint_clip[] = {
0752         0, 1, 0, 2, 0, 4, 0, 8, 0, 16, 0, 32
0753     };
0754     int ret = 0;
0755 
0756     if (!tnr_dmd)
0757         return -EINVAL;
0758 
0759     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0760         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0761                          CXD2880_IO_TGT_DMD,
0762                          0x00, 0x1d);
0763         if (ret)
0764             return ret;
0765 
0766         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
0767                           CXD2880_IO_TGT_DMD,
0768                           0x47, difint_clip, 12);
0769     }
0770 
0771     return ret;
0772 }
0773 
0774 static int dvbt2_set_profile(struct cxd2880_tnrdmd *tnr_dmd,
0775                  enum cxd2880_dvbt2_profile profile)
0776 {
0777     u8 t2_mode_tune_mode = 0;
0778     u8 seq_not2_dtime = 0;
0779     u8 dtime1 = 0;
0780     u8 dtime2 = 0;
0781     int ret;
0782 
0783     if (!tnr_dmd)
0784         return -EINVAL;
0785 
0786     switch (tnr_dmd->clk_mode) {
0787     case CXD2880_TNRDMD_CLOCKMODE_A:
0788         dtime1 = 0x27;
0789         dtime2 = 0x0c;
0790         break;
0791     case CXD2880_TNRDMD_CLOCKMODE_B:
0792         dtime1 = 0x2c;
0793         dtime2 = 0x0d;
0794         break;
0795     case CXD2880_TNRDMD_CLOCKMODE_C:
0796         dtime1 = 0x2e;
0797         dtime2 = 0x0e;
0798         break;
0799     default:
0800         return -EINVAL;
0801     }
0802 
0803     switch (profile) {
0804     case CXD2880_DVBT2_PROFILE_BASE:
0805         t2_mode_tune_mode = 0x01;
0806         seq_not2_dtime = dtime2;
0807         break;
0808 
0809     case CXD2880_DVBT2_PROFILE_LITE:
0810         t2_mode_tune_mode = 0x05;
0811         seq_not2_dtime = dtime1;
0812         break;
0813 
0814     case CXD2880_DVBT2_PROFILE_ANY:
0815         t2_mode_tune_mode = 0x00;
0816         seq_not2_dtime = dtime1;
0817         break;
0818 
0819     default:
0820         return -EINVAL;
0821     }
0822 
0823     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0824                      CXD2880_IO_TGT_DMD,
0825                      0x00, 0x2e);
0826     if (ret)
0827         return ret;
0828 
0829     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0830                      CXD2880_IO_TGT_DMD,
0831                      0x10, t2_mode_tune_mode);
0832     if (ret)
0833         return ret;
0834 
0835     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
0836                      CXD2880_IO_TGT_DMD,
0837                      0x00, 0x04);
0838     if (ret)
0839         return ret;
0840 
0841     return tnr_dmd->io->write_reg(tnr_dmd->io,
0842                       CXD2880_IO_TGT_DMD,
0843                       0x2c, seq_not2_dtime);
0844 }
0845 
0846 int cxd2880_tnrdmd_dvbt2_tune1(struct cxd2880_tnrdmd *tnr_dmd,
0847                    struct cxd2880_dvbt2_tune_param
0848                    *tune_param)
0849 {
0850     int ret;
0851 
0852     if (!tnr_dmd || !tune_param)
0853         return -EINVAL;
0854 
0855     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
0856         return -EINVAL;
0857 
0858     if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
0859         tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
0860         return -EINVAL;
0861 
0862     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN &&
0863         tune_param->profile == CXD2880_DVBT2_PROFILE_ANY)
0864         return -ENOTTY;
0865 
0866     ret =
0867         cxd2880_tnrdmd_common_tune_setting1(tnr_dmd, CXD2880_DTV_SYS_DVBT2,
0868                         tune_param->center_freq_khz,
0869                         tune_param->bandwidth, 0, 0);
0870     if (ret)
0871         return ret;
0872 
0873     ret =
0874         x_tune_dvbt2_demod_setting(tnr_dmd, tune_param->bandwidth,
0875                        tnr_dmd->clk_mode);
0876     if (ret)
0877         return ret;
0878 
0879     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0880         ret =
0881             x_tune_dvbt2_demod_setting(tnr_dmd->diver_sub,
0882                            tune_param->bandwidth,
0883                            tnr_dmd->diver_sub->clk_mode);
0884         if (ret)
0885             return ret;
0886     }
0887 
0888     ret = dvbt2_set_profile(tnr_dmd, tune_param->profile);
0889     if (ret)
0890         return ret;
0891 
0892     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0893         ret =
0894             dvbt2_set_profile(tnr_dmd->diver_sub, tune_param->profile);
0895         if (ret)
0896             return ret;
0897     }
0898 
0899     if (tune_param->data_plp_id == CXD2880_DVBT2_TUNE_PARAM_PLPID_AUTO)
0900         ret = cxd2880_tnrdmd_dvbt2_set_plp_cfg(tnr_dmd, 1, 0);
0901     else
0902         ret =
0903             cxd2880_tnrdmd_dvbt2_set_plp_cfg(tnr_dmd, 0,
0904                          (u8)(tune_param->data_plp_id));
0905 
0906     return ret;
0907 }
0908 
0909 int cxd2880_tnrdmd_dvbt2_tune2(struct cxd2880_tnrdmd *tnr_dmd,
0910                    struct cxd2880_dvbt2_tune_param
0911                    *tune_param)
0912 {
0913     u8 en_fef_intmtnt_ctrl = 1;
0914     int ret;
0915 
0916     if (!tnr_dmd || !tune_param)
0917         return -EINVAL;
0918 
0919     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
0920         return -EINVAL;
0921 
0922     if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
0923         tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
0924         return -EINVAL;
0925 
0926     switch (tune_param->profile) {
0927     case CXD2880_DVBT2_PROFILE_BASE:
0928         en_fef_intmtnt_ctrl = tnr_dmd->en_fef_intmtnt_base;
0929         break;
0930     case CXD2880_DVBT2_PROFILE_LITE:
0931         en_fef_intmtnt_ctrl = tnr_dmd->en_fef_intmtnt_lite;
0932         break;
0933     case CXD2880_DVBT2_PROFILE_ANY:
0934         if (tnr_dmd->en_fef_intmtnt_base &&
0935             tnr_dmd->en_fef_intmtnt_lite)
0936             en_fef_intmtnt_ctrl = 1;
0937         else
0938             en_fef_intmtnt_ctrl = 0;
0939         break;
0940     default:
0941         return -EINVAL;
0942     }
0943 
0944     ret =
0945         cxd2880_tnrdmd_common_tune_setting2(tnr_dmd,
0946                         CXD2880_DTV_SYS_DVBT2,
0947                         en_fef_intmtnt_ctrl);
0948     if (ret)
0949         return ret;
0950 
0951     tnr_dmd->state = CXD2880_TNRDMD_STATE_ACTIVE;
0952     tnr_dmd->frequency_khz = tune_param->center_freq_khz;
0953     tnr_dmd->sys = CXD2880_DTV_SYS_DVBT2;
0954     tnr_dmd->bandwidth = tune_param->bandwidth;
0955 
0956     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
0957         tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_ACTIVE;
0958         tnr_dmd->diver_sub->frequency_khz = tune_param->center_freq_khz;
0959         tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_DVBT2;
0960         tnr_dmd->diver_sub->bandwidth = tune_param->bandwidth;
0961     }
0962 
0963     return 0;
0964 }
0965 
0966 int cxd2880_tnrdmd_dvbt2_sleep_setting(struct cxd2880_tnrdmd
0967                        *tnr_dmd)
0968 {
0969     int ret;
0970 
0971     if (!tnr_dmd)
0972         return -EINVAL;
0973 
0974     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
0975         return -EINVAL;
0976 
0977     if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
0978         tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
0979         return -EINVAL;
0980 
0981     ret = x_sleep_dvbt2_demod_setting(tnr_dmd);
0982     if (ret)
0983         return ret;
0984 
0985     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
0986         ret = x_sleep_dvbt2_demod_setting(tnr_dmd->diver_sub);
0987 
0988     return ret;
0989 }
0990 
0991 int cxd2880_tnrdmd_dvbt2_check_demod_lock(struct cxd2880_tnrdmd
0992                       *tnr_dmd,
0993                       enum
0994                       cxd2880_tnrdmd_lock_result
0995                       *lock)
0996 {
0997     int ret;
0998 
0999     u8 sync_stat = 0;
1000     u8 ts_lock = 0;
1001     u8 unlock_detected = 0;
1002     u8 unlock_detected_sub = 0;
1003 
1004     if (!tnr_dmd || !lock)
1005         return -EINVAL;
1006 
1007     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
1008         return -EINVAL;
1009 
1010     if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
1011         return -EINVAL;
1012 
1013     ret =
1014         cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock,
1015                            &unlock_detected);
1016     if (ret)
1017         return ret;
1018 
1019     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) {
1020         if (sync_stat == 6)
1021             *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
1022         else if (unlock_detected)
1023             *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
1024         else
1025             *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
1026 
1027         return ret;
1028     }
1029 
1030     if (sync_stat == 6) {
1031         *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
1032         return ret;
1033     }
1034 
1035     ret =
1036         cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(tnr_dmd, &sync_stat,
1037                            &unlock_detected_sub);
1038     if (ret)
1039         return ret;
1040 
1041     if (sync_stat == 6)
1042         *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
1043     else if (unlock_detected && unlock_detected_sub)
1044         *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
1045     else
1046         *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
1047 
1048     return ret;
1049 }
1050 
1051 int cxd2880_tnrdmd_dvbt2_check_ts_lock(struct cxd2880_tnrdmd
1052                        *tnr_dmd,
1053                        enum
1054                        cxd2880_tnrdmd_lock_result
1055                        *lock)
1056 {
1057     int ret;
1058 
1059     u8 sync_stat = 0;
1060     u8 ts_lock = 0;
1061     u8 unlock_detected = 0;
1062     u8 unlock_detected_sub = 0;
1063 
1064     if (!tnr_dmd || !lock)
1065         return -EINVAL;
1066 
1067     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
1068         return -EINVAL;
1069 
1070     if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
1071         return -EINVAL;
1072 
1073     ret =
1074         cxd2880_tnrdmd_dvbt2_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock,
1075                            &unlock_detected);
1076     if (ret)
1077         return ret;
1078 
1079     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) {
1080         if (ts_lock)
1081             *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
1082         else if (unlock_detected)
1083             *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
1084         else
1085             *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
1086 
1087         return ret;
1088     }
1089 
1090     if (ts_lock) {
1091         *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
1092         return ret;
1093     } else if (!unlock_detected) {
1094         *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
1095         return ret;
1096     }
1097 
1098     ret =
1099         cxd2880_tnrdmd_dvbt2_mon_sync_stat_sub(tnr_dmd, &sync_stat,
1100                            &unlock_detected_sub);
1101     if (ret)
1102         return ret;
1103 
1104     if (unlock_detected && unlock_detected_sub)
1105         *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
1106     else
1107         *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
1108 
1109     return ret;
1110 }
1111 
1112 int cxd2880_tnrdmd_dvbt2_set_plp_cfg(struct cxd2880_tnrdmd
1113                      *tnr_dmd, u8 auto_plp,
1114                      u8 plp_id)
1115 {
1116     int ret;
1117 
1118     if (!tnr_dmd)
1119         return -EINVAL;
1120 
1121     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
1122         return -EINVAL;
1123 
1124     if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
1125         tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
1126         return -EINVAL;
1127 
1128     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1129                      CXD2880_IO_TGT_DMD,
1130                      0x00, 0x23);
1131     if (ret)
1132         return ret;
1133 
1134     if (!auto_plp) {
1135         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1136                          CXD2880_IO_TGT_DMD,
1137                          0xaf, plp_id);
1138         if (ret)
1139             return ret;
1140     }
1141 
1142     return tnr_dmd->io->write_reg(tnr_dmd->io,
1143                       CXD2880_IO_TGT_DMD,
1144                       0xad, auto_plp ? 0x00 : 0x01);
1145 }
1146 
1147 int cxd2880_tnrdmd_dvbt2_diver_fef_setting(struct cxd2880_tnrdmd
1148                        *tnr_dmd)
1149 {
1150     struct cxd2880_dvbt2_ofdm ofdm;
1151     static const u8 data[] = { 0, 8, 0, 16, 0, 32, 0, 64, 0, 128, 1, 0};
1152     int ret;
1153 
1154     if (!tnr_dmd)
1155         return -EINVAL;
1156 
1157     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
1158         return -EINVAL;
1159 
1160     if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
1161         return -EINVAL;
1162 
1163     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE)
1164         return 0;
1165 
1166     ret = cxd2880_tnrdmd_dvbt2_mon_ofdm(tnr_dmd, &ofdm);
1167     if (ret)
1168         return ret;
1169 
1170     if (!ofdm.mixed)
1171         return 0;
1172 
1173     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1174                      CXD2880_IO_TGT_DMD,
1175                      0x00, 0x1d);
1176     if (ret)
1177         return ret;
1178 
1179     return tnr_dmd->io->write_regs(tnr_dmd->io,
1180                        CXD2880_IO_TGT_DMD,
1181                        0x47, data, 12);
1182 }
1183 
1184 int cxd2880_tnrdmd_dvbt2_check_l1post_valid(struct cxd2880_tnrdmd
1185                         *tnr_dmd,
1186                         u8 *l1_post_valid)
1187 {
1188     int ret;
1189 
1190     u8 data;
1191 
1192     if (!tnr_dmd || !l1_post_valid)
1193         return -EINVAL;
1194 
1195     if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
1196         return -EINVAL;
1197 
1198     if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
1199         tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
1200         return -EINVAL;
1201 
1202     ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1203                      CXD2880_IO_TGT_DMD,
1204                      0x00, 0x0b);
1205     if (ret)
1206         return ret;
1207 
1208     ret = tnr_dmd->io->read_regs(tnr_dmd->io,
1209                      CXD2880_IO_TGT_DMD,
1210                      0x86, &data, 1);
1211     if (ret)
1212         return ret;
1213 
1214     *l1_post_valid = data & 0x01;
1215 
1216     return ret;
1217 }