root/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd_dvbt2.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. x_tune_dvbt2_demod_setting
  2. x_sleep_dvbt2_demod_setting
  3. dvbt2_set_profile
  4. cxd2880_tnrdmd_dvbt2_tune1
  5. cxd2880_tnrdmd_dvbt2_tune2
  6. cxd2880_tnrdmd_dvbt2_sleep_setting
  7. cxd2880_tnrdmd_dvbt2_check_demod_lock
  8. cxd2880_tnrdmd_dvbt2_check_ts_lock
  9. cxd2880_tnrdmd_dvbt2_set_plp_cfg
  10. cxd2880_tnrdmd_dvbt2_diver_fef_setting
  11. cxd2880_tnrdmd_dvbt2_check_l1post_valid

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

/* [<][>][^][v][top][bottom][index][help] */