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

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

DEFINITIONS

This source file includes following definitions.
  1. x_tune_dvbt_demod_setting
  2. x_sleep_dvbt_demod_setting
  3. dvbt_set_profile
  4. cxd2880_tnrdmd_dvbt_tune1
  5. cxd2880_tnrdmd_dvbt_tune2
  6. cxd2880_tnrdmd_dvbt_sleep_setting
  7. cxd2880_tnrdmd_dvbt_check_demod_lock
  8. cxd2880_tnrdmd_dvbt_check_ts_lock

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * cxd2880_tnrdmd_dvbt.c
   4  * Sony CXD2880 DVB-T2/T tuner + demodulator driver
   5  * control functions for DVB-T
   6  *
   7  * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
   8  */
   9 
  10 #include <media/dvb_frontend.h>
  11 
  12 #include "cxd2880_tnrdmd_dvbt.h"
  13 #include "cxd2880_tnrdmd_dvbt_mon.h"
  14 
  15 static const struct cxd2880_reg_value tune_dmd_setting_seq1[] = {
  16         {0x00, 0x00}, {0x31, 0x01},
  17 };
  18 
  19 static const struct cxd2880_reg_value tune_dmd_setting_seq2[] = {
  20         {0x00, 0x04}, {0x5c, 0xfb}, {0x00, 0x10}, {0xa4, 0x03},
  21         {0x00, 0x14}, {0xb0, 0x00}, {0x00, 0x25},
  22 };
  23 
  24 static const struct cxd2880_reg_value tune_dmd_setting_seq3[] = {
  25         {0x00, 0x12}, {0x44, 0x00},
  26 };
  27 
  28 static const struct cxd2880_reg_value tune_dmd_setting_seq4[] = {
  29         {0x00, 0x11}, {0x87, 0xd2},
  30 };
  31 
  32 static const struct cxd2880_reg_value tune_dmd_setting_seq5[] = {
  33         {0x00, 0x00}, {0xfd, 0x01},
  34 };
  35 
  36 static const struct cxd2880_reg_value sleep_dmd_setting_seq1[] = {
  37         {0x00, 0x04}, {0x5c, 0xd8}, {0x00, 0x10}, {0xa4, 0x00},
  38 };
  39 
  40 static const struct cxd2880_reg_value sleep_dmd_setting_seq2[] = {
  41         {0x00, 0x11}, {0x87, 0x04},
  42 };
  43 
  44 static int x_tune_dvbt_demod_setting(struct cxd2880_tnrdmd
  45                                      *tnr_dmd,
  46                                      enum cxd2880_dtv_bandwidth
  47                                      bandwidth,
  48                                      enum cxd2880_tnrdmd_clockmode
  49                                      clk_mode)
  50 {
  51         static const u8 clk_mode_ckffrq_a[2] = { 0x52, 0x49 };
  52         static const u8 clk_mode_ckffrq_b[2] = { 0x5d, 0x55 };
  53         static const u8 clk_mode_ckffrq_c[2] = { 0x60, 0x00 };
  54         static const u8 ratectl_margin[2] = { 0x01, 0xf0 };
  55         static const u8 maxclkcnt_a[3] = { 0x73, 0xca, 0x49 };
  56         static const u8 maxclkcnt_b[3] = { 0xc8, 0x13, 0xaa };
  57         static const u8 maxclkcnt_c[3] = { 0xdc, 0x6c, 0x00 };
  58 
  59         static const u8 bw8_nomi_ac[5] = { 0x15, 0x00, 0x00, 0x00, 0x00};
  60         static const u8 bw8_nomi_b[5] = { 0x14, 0x6a, 0xaa, 0xaa, 0xaa};
  61         static const u8 bw8_gtdofst_a[2] = { 0x01, 0x28 };
  62         static const u8 bw8_gtdofst_b[2] = { 0x11, 0x44 };
  63         static const u8 bw8_gtdofst_c[2] = { 0x15, 0x28 };
  64         static const u8 bw8_mrc_a[5] = { 0x30, 0x00, 0x00, 0x90, 0x00 };
  65         static const u8 bw8_mrc_b[5] = { 0x36, 0x71, 0x00, 0xa3, 0x55 };
  66         static const u8 bw8_mrc_c[5] = { 0x38, 0x00, 0x00, 0xa8, 0x00 };
  67         static const u8 bw8_notch[4] = { 0xb3, 0x00, 0x01, 0x02 };
  68 
  69         static const u8 bw7_nomi_ac[5] = { 0x18, 0x00, 0x00, 0x00, 0x00};
  70         static const u8 bw7_nomi_b[5] = { 0x17, 0x55, 0x55, 0x55, 0x55};
  71         static const u8 bw7_gtdofst_a[2] = { 0x12, 0x4c };
  72         static const u8 bw7_gtdofst_b[2] = { 0x1f, 0x15 };
  73         static const u8 bw7_gtdofst_c[2] = { 0x1f, 0xf8 };
  74         static const u8 bw7_mrc_a[5] = { 0x36, 0xdb, 0x00, 0xa4, 0x92 };
  75         static const u8 bw7_mrc_b[5] = { 0x3e, 0x38, 0x00, 0xba, 0xaa };
  76         static const u8 bw7_mrc_c[5] = { 0x40, 0x00, 0x00, 0xc0, 0x00 };
  77         static const u8 bw7_notch[4] = { 0xb8, 0x00, 0x00, 0x03 };
  78 
  79         static const u8 bw6_nomi_ac[5] = { 0x1c, 0x00, 0x00, 0x00, 0x00};
  80         static const u8 bw6_nomi_b[5] = { 0x1b, 0x38, 0xe3, 0x8e, 0x38};
  81         static const u8 bw6_gtdofst_a[2] = { 0x1f, 0xf8 };
  82         static const u8 bw6_gtdofst_b[2] = { 0x24, 0x43 };
  83         static const u8 bw6_gtdofst_c[2] = { 0x25, 0x4c };
  84         static const u8 bw6_mrc_a[5] = { 0x40, 0x00, 0x00, 0xc0, 0x00 };
  85         static const u8 bw6_mrc_b[5] = { 0x48, 0x97, 0x00, 0xd9, 0xc7 };
  86         static const u8 bw6_mrc_c[5] = { 0x4a, 0xaa, 0x00, 0xdf, 0xff };
  87         static const u8 bw6_notch[4] = { 0xbe, 0xab, 0x00, 0x03 };
  88 
  89         static const u8 bw5_nomi_ac[5] = { 0x21, 0x99, 0x99, 0x99, 0x99};
  90         static const u8 bw5_nomi_b[5] = { 0x20, 0xaa, 0xaa, 0xaa, 0xaa};
  91         static const u8 bw5_gtdofst_a[2] = { 0x26, 0x5d };
  92         static const u8 bw5_gtdofst_b[2] = { 0x2b, 0x84 };
  93         static const u8 bw5_gtdofst_c[2] = { 0x2c, 0xc2 };
  94         static const u8 bw5_mrc_a[5] = { 0x4c, 0xcc, 0x00, 0xe6, 0x66 };
  95         static const u8 bw5_mrc_b[5] = { 0x57, 0x1c, 0x01, 0x05, 0x55 };
  96         static const u8 bw5_mrc_c[5] = { 0x59, 0x99, 0x01, 0x0c, 0xcc };
  97         static const u8 bw5_notch[4] = { 0xc8, 0x01, 0x00, 0x03 };
  98         const u8 *data = NULL;
  99         u8 sst_data;
 100         int ret;
 101 
 102         if (!tnr_dmd)
 103                 return -EINVAL;
 104 
 105         ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
 106                                           CXD2880_IO_TGT_SYS,
 107                                           tune_dmd_setting_seq1,
 108                                           ARRAY_SIZE(tune_dmd_setting_seq1));
 109         if (ret)
 110                 return ret;
 111 
 112         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 113                                      CXD2880_IO_TGT_DMD,
 114                                      0x00, 0x04);
 115         if (ret)
 116                 return ret;
 117 
 118         switch (clk_mode) {
 119         case CXD2880_TNRDMD_CLOCKMODE_A:
 120                 data = clk_mode_ckffrq_a;
 121                 break;
 122         case CXD2880_TNRDMD_CLOCKMODE_B:
 123                 data = clk_mode_ckffrq_b;
 124                 break;
 125         case CXD2880_TNRDMD_CLOCKMODE_C:
 126                 data = clk_mode_ckffrq_c;
 127                 break;
 128         default:
 129                 return -EINVAL;
 130         }
 131 
 132         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 133                                       CXD2880_IO_TGT_DMD,
 134                                       0x65, data, 2);
 135         if (ret)
 136                 return ret;
 137 
 138         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 139                                      CXD2880_IO_TGT_DMD,
 140                                      0x5d, 0x07);
 141         if (ret)
 142                 return ret;
 143 
 144         if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) {
 145                 u8 data[2] = { 0x01, 0x01 };
 146 
 147                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 148                                              CXD2880_IO_TGT_DMD,
 149                                              0x00, 0x00);
 150                 if (ret)
 151                         return ret;
 152 
 153                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 154                                               CXD2880_IO_TGT_DMD,
 155                                               0xce, data, 2);
 156                 if (ret)
 157                         return ret;
 158         }
 159 
 160         ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
 161                                           CXD2880_IO_TGT_DMD,
 162                                           tune_dmd_setting_seq2,
 163                                           ARRAY_SIZE(tune_dmd_setting_seq2));
 164         if (ret)
 165                 return ret;
 166 
 167         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 168                                       CXD2880_IO_TGT_DMD,
 169                                       0xf0, ratectl_margin, 2);
 170         if (ret)
 171                 return ret;
 172 
 173         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN ||
 174             tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) {
 175                 ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
 176                                                   CXD2880_IO_TGT_DMD,
 177                                                   tune_dmd_setting_seq3,
 178                                                   ARRAY_SIZE(tune_dmd_setting_seq3));
 179                 if (ret)
 180                         return ret;
 181         }
 182 
 183         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) {
 184                 ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
 185                                                   CXD2880_IO_TGT_DMD,
 186                                                   tune_dmd_setting_seq4,
 187                                                   ARRAY_SIZE(tune_dmd_setting_seq4));
 188                 if (ret)
 189                         return ret;
 190         }
 191 
 192         if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_SUB) {
 193                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 194                                              CXD2880_IO_TGT_DMD,
 195                                              0x00, 0x04);
 196                 if (ret)
 197                         return ret;
 198 
 199                 switch (clk_mode) {
 200                 case CXD2880_TNRDMD_CLOCKMODE_A:
 201                         data = maxclkcnt_a;
 202                         break;
 203                 case CXD2880_TNRDMD_CLOCKMODE_B:
 204                         data = maxclkcnt_b;
 205                         break;
 206                 case CXD2880_TNRDMD_CLOCKMODE_C:
 207                         data = maxclkcnt_c;
 208                         break;
 209                 default:
 210                         return -EINVAL;
 211                 }
 212 
 213                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 214                                               CXD2880_IO_TGT_DMD,
 215                                               0x68, data, 3);
 216                 if (ret)
 217                         return ret;
 218         }
 219 
 220         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 221                                      CXD2880_IO_TGT_DMD,
 222                                      0x00, 0x04);
 223         if (ret)
 224                 return ret;
 225 
 226         switch (bandwidth) {
 227         case CXD2880_DTV_BW_8_MHZ:
 228                 switch (clk_mode) {
 229                 case CXD2880_TNRDMD_CLOCKMODE_A:
 230                 case CXD2880_TNRDMD_CLOCKMODE_C:
 231                         data = bw8_nomi_ac;
 232                         break;
 233                 case CXD2880_TNRDMD_CLOCKMODE_B:
 234                         data = bw8_nomi_b;
 235                         break;
 236                 default:
 237                         return -EINVAL;
 238                 }
 239 
 240                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 241                                               CXD2880_IO_TGT_DMD,
 242                                               0x60, data, 5);
 243                 if (ret)
 244                         return ret;
 245 
 246                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 247                                              CXD2880_IO_TGT_DMD,
 248                                              0x4a, 0x00);
 249                 if (ret)
 250                         return ret;
 251 
 252                 switch (clk_mode) {
 253                 case CXD2880_TNRDMD_CLOCKMODE_A:
 254                         data = bw8_gtdofst_a;
 255                         break;
 256                 case CXD2880_TNRDMD_CLOCKMODE_B:
 257                         data = bw8_gtdofst_b;
 258                         break;
 259                 case CXD2880_TNRDMD_CLOCKMODE_C:
 260                         data = bw8_gtdofst_c;
 261                         break;
 262                 default:
 263                         return -EINVAL;
 264                 }
 265 
 266                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 267                                               CXD2880_IO_TGT_DMD,
 268                                               0x7d, data, 2);
 269                 if (ret)
 270                         return ret;
 271 
 272                 switch (clk_mode) {
 273                 case CXD2880_TNRDMD_CLOCKMODE_A:
 274                 case CXD2880_TNRDMD_CLOCKMODE_B:
 275                         sst_data = 0x35;
 276                         break;
 277                 case CXD2880_TNRDMD_CLOCKMODE_C:
 278                         sst_data = 0x34;
 279                         break;
 280                 default:
 281                         return -EINVAL;
 282                 }
 283 
 284                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 285                                              CXD2880_IO_TGT_DMD,
 286                                              0x71, sst_data);
 287                 if (ret)
 288                         return ret;
 289 
 290                 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
 291                         switch (clk_mode) {
 292                         case CXD2880_TNRDMD_CLOCKMODE_A:
 293                                 data = bw8_mrc_a;
 294                                 break;
 295                         case CXD2880_TNRDMD_CLOCKMODE_B:
 296                                 data = bw8_mrc_b;
 297                                 break;
 298                         case CXD2880_TNRDMD_CLOCKMODE_C:
 299                                 data = bw8_mrc_c;
 300                                 break;
 301                         default:
 302                                 return -EINVAL;
 303                         }
 304 
 305                         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 306                                                       CXD2880_IO_TGT_DMD,
 307                                                       0x4b, &data[0], 2);
 308                         if (ret)
 309                                 return ret;
 310 
 311                         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 312                                                       CXD2880_IO_TGT_DMD,
 313                                                       0x51, &data[2], 3);
 314                         if (ret)
 315                                 return ret;
 316                 }
 317 
 318                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 319                                               CXD2880_IO_TGT_DMD,
 320                                               0x72, &bw8_notch[0], 2);
 321                 if (ret)
 322                         return ret;
 323 
 324                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 325                                               CXD2880_IO_TGT_DMD,
 326                                               0x6b, &bw8_notch[2], 2);
 327                 if (ret)
 328                         return ret;
 329                 break;
 330 
 331         case CXD2880_DTV_BW_7_MHZ:
 332                 switch (clk_mode) {
 333                 case CXD2880_TNRDMD_CLOCKMODE_A:
 334                 case CXD2880_TNRDMD_CLOCKMODE_C:
 335                         data = bw7_nomi_ac;
 336                         break;
 337                 case CXD2880_TNRDMD_CLOCKMODE_B:
 338                         data = bw7_nomi_b;
 339                         break;
 340                 default:
 341                         return -EINVAL;
 342                 }
 343 
 344                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 345                                               CXD2880_IO_TGT_DMD,
 346                                               0x60, data, 5);
 347                 if (ret)
 348                         return ret;
 349 
 350                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 351                                              CXD2880_IO_TGT_DMD,
 352                                              0x4a, 0x02);
 353                 if (ret)
 354                         return ret;
 355 
 356                 switch (clk_mode) {
 357                 case CXD2880_TNRDMD_CLOCKMODE_A:
 358                         data = bw7_gtdofst_a;
 359                         break;
 360                 case CXD2880_TNRDMD_CLOCKMODE_B:
 361                         data = bw7_gtdofst_b;
 362                         break;
 363                 case CXD2880_TNRDMD_CLOCKMODE_C:
 364                         data = bw7_gtdofst_c;
 365                         break;
 366                 default:
 367                         return -EINVAL;
 368                 }
 369 
 370                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 371                                               CXD2880_IO_TGT_DMD,
 372                                               0x7d, data, 2);
 373                 if (ret)
 374                         return ret;
 375 
 376                 switch (clk_mode) {
 377                 case CXD2880_TNRDMD_CLOCKMODE_A:
 378                 case CXD2880_TNRDMD_CLOCKMODE_B:
 379                         sst_data = 0x2f;
 380                         break;
 381                 case CXD2880_TNRDMD_CLOCKMODE_C:
 382                         sst_data = 0x2e;
 383                         break;
 384                 default:
 385                         return -EINVAL;
 386                 }
 387 
 388                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 389                                              CXD2880_IO_TGT_DMD,
 390                                              0x71, sst_data);
 391                 if (ret)
 392                         return ret;
 393 
 394                 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
 395                         switch (clk_mode) {
 396                         case CXD2880_TNRDMD_CLOCKMODE_A:
 397                                 data = bw7_mrc_a;
 398                                 break;
 399                         case CXD2880_TNRDMD_CLOCKMODE_B:
 400                                 data = bw7_mrc_b;
 401                                 break;
 402                         case CXD2880_TNRDMD_CLOCKMODE_C:
 403                                 data = bw7_mrc_c;
 404                                 break;
 405                         default:
 406                                 return -EINVAL;
 407                         }
 408 
 409                         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 410                                                       CXD2880_IO_TGT_DMD,
 411                                                       0x4b, &data[0], 2);
 412                         if (ret)
 413                                 return ret;
 414 
 415                         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 416                                                       CXD2880_IO_TGT_DMD,
 417                                                       0x51, &data[2], 3);
 418                         if (ret)
 419                                 return ret;
 420                 }
 421 
 422                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 423                                               CXD2880_IO_TGT_DMD,
 424                                               0x72, &bw7_notch[0], 2);
 425                 if (ret)
 426                         return ret;
 427 
 428                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 429                                               CXD2880_IO_TGT_DMD,
 430                                               0x6b, &bw7_notch[2], 2);
 431                 if (ret)
 432                         return ret;
 433                 break;
 434 
 435         case CXD2880_DTV_BW_6_MHZ:
 436                 switch (clk_mode) {
 437                 case CXD2880_TNRDMD_CLOCKMODE_A:
 438                 case CXD2880_TNRDMD_CLOCKMODE_C:
 439                         data = bw6_nomi_ac;
 440                         break;
 441                 case CXD2880_TNRDMD_CLOCKMODE_B:
 442                         data = bw6_nomi_b;
 443                         break;
 444                 default:
 445                         return -EINVAL;
 446                 }
 447 
 448                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 449                                               CXD2880_IO_TGT_DMD,
 450                                               0x60, data, 5);
 451                 if (ret)
 452                         return ret;
 453 
 454                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 455                                              CXD2880_IO_TGT_DMD,
 456                                              0x4a, 0x04);
 457                 if (ret)
 458                         return ret;
 459 
 460                 switch (clk_mode) {
 461                 case CXD2880_TNRDMD_CLOCKMODE_A:
 462                         data = bw6_gtdofst_a;
 463                         break;
 464                 case CXD2880_TNRDMD_CLOCKMODE_B:
 465                         data = bw6_gtdofst_b;
 466                         break;
 467                 case CXD2880_TNRDMD_CLOCKMODE_C:
 468                         data = bw6_gtdofst_c;
 469                         break;
 470                 default:
 471                         return -EINVAL;
 472                 }
 473 
 474                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 475                                               CXD2880_IO_TGT_DMD,
 476                                               0x7d, data, 2);
 477                 if (ret)
 478                         return ret;
 479 
 480                 switch (clk_mode) {
 481                 case CXD2880_TNRDMD_CLOCKMODE_A:
 482                 case CXD2880_TNRDMD_CLOCKMODE_C:
 483                         sst_data = 0x29;
 484                         break;
 485                 case CXD2880_TNRDMD_CLOCKMODE_B:
 486                         sst_data = 0x2a;
 487                         break;
 488                 default:
 489                         return -EINVAL;
 490                 }
 491 
 492                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 493                                              CXD2880_IO_TGT_DMD,
 494                                              0x71, sst_data);
 495                 if (ret)
 496                         return ret;
 497 
 498                 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
 499                         switch (clk_mode) {
 500                         case CXD2880_TNRDMD_CLOCKMODE_A:
 501                                 data = bw6_mrc_a;
 502                                 break;
 503                         case CXD2880_TNRDMD_CLOCKMODE_B:
 504                                 data = bw6_mrc_b;
 505                                 break;
 506                         case CXD2880_TNRDMD_CLOCKMODE_C:
 507                                 data = bw6_mrc_c;
 508                                 break;
 509                         default:
 510                                 return -EINVAL;
 511                         }
 512 
 513                         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 514                                                       CXD2880_IO_TGT_DMD,
 515                                                       0x4b, &data[0], 2);
 516                         if (ret)
 517                                 return ret;
 518 
 519                         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 520                                                       CXD2880_IO_TGT_DMD,
 521                                                       0x51, &data[2], 3);
 522                         if (ret)
 523                                 return ret;
 524                 }
 525 
 526                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 527                                               CXD2880_IO_TGT_DMD,
 528                                               0x72, &bw6_notch[0], 2);
 529                 if (ret)
 530                         return ret;
 531 
 532                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 533                                               CXD2880_IO_TGT_DMD,
 534                                               0x6b, &bw6_notch[2], 2);
 535                 if (ret)
 536                         return ret;
 537                 break;
 538 
 539         case CXD2880_DTV_BW_5_MHZ:
 540                 switch (clk_mode) {
 541                 case CXD2880_TNRDMD_CLOCKMODE_A:
 542                 case CXD2880_TNRDMD_CLOCKMODE_C:
 543                         data = bw5_nomi_ac;
 544                         break;
 545                 case CXD2880_TNRDMD_CLOCKMODE_B:
 546                         data = bw5_nomi_b;
 547                         break;
 548                 default:
 549                         return -EINVAL;
 550                 }
 551 
 552                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 553                                               CXD2880_IO_TGT_DMD,
 554                                               0x60, data, 5);
 555                 if (ret)
 556                         return ret;
 557 
 558                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 559                                              CXD2880_IO_TGT_DMD,
 560                                              0x4a, 0x06);
 561                 if (ret)
 562                         return ret;
 563 
 564                 switch (clk_mode) {
 565                 case CXD2880_TNRDMD_CLOCKMODE_A:
 566                         data = bw5_gtdofst_a;
 567                         break;
 568                 case CXD2880_TNRDMD_CLOCKMODE_B:
 569                         data = bw5_gtdofst_b;
 570                         break;
 571                 case CXD2880_TNRDMD_CLOCKMODE_C:
 572                         data = bw5_gtdofst_c;
 573                         break;
 574                 default:
 575                         return -EINVAL;
 576                 }
 577 
 578                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 579                                               CXD2880_IO_TGT_DMD,
 580                                               0x7d, data, 2);
 581                 if (ret)
 582                         return ret;
 583 
 584                 switch (clk_mode) {
 585                 case CXD2880_TNRDMD_CLOCKMODE_A:
 586                 case CXD2880_TNRDMD_CLOCKMODE_B:
 587                         sst_data = 0x24;
 588                         break;
 589                 case CXD2880_TNRDMD_CLOCKMODE_C:
 590                         sst_data = 0x23;
 591                         break;
 592                 default:
 593                         return -EINVAL;
 594                 }
 595 
 596                 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 597                                              CXD2880_IO_TGT_DMD,
 598                                              0x71, sst_data);
 599                 if (ret)
 600                         return ret;
 601 
 602                 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
 603                         switch (clk_mode) {
 604                         case CXD2880_TNRDMD_CLOCKMODE_A:
 605                                 data = bw5_mrc_a;
 606                                 break;
 607                         case CXD2880_TNRDMD_CLOCKMODE_B:
 608                                 data = bw5_mrc_b;
 609                                 break;
 610                         case CXD2880_TNRDMD_CLOCKMODE_C:
 611                                 data = bw5_mrc_c;
 612                                 break;
 613                         default:
 614                                 return -EINVAL;
 615                         }
 616 
 617                         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 618                                                       CXD2880_IO_TGT_DMD,
 619                                                       0x4b, &data[0], 2);
 620                         if (ret)
 621                                 return ret;
 622 
 623                         ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 624                                                       CXD2880_IO_TGT_DMD,
 625                                                       0x51, &data[2], 3);
 626                         if (ret)
 627                                 return ret;
 628                 }
 629 
 630                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 631                                               CXD2880_IO_TGT_DMD,
 632                                               0x72, &bw5_notch[0], 2);
 633                 if (ret)
 634                         return ret;
 635 
 636                 ret = tnr_dmd->io->write_regs(tnr_dmd->io,
 637                                               CXD2880_IO_TGT_DMD,
 638                                               0x6b, &bw5_notch[2], 2);
 639                 if (ret)
 640                         return ret;
 641                 break;
 642 
 643         default:
 644                 return -EINVAL;
 645         }
 646 
 647         return cxd2880_io_write_multi_regs(tnr_dmd->io,
 648                                            CXD2880_IO_TGT_DMD,
 649                                            tune_dmd_setting_seq5,
 650                                            ARRAY_SIZE(tune_dmd_setting_seq5));
 651 }
 652 
 653 static int x_sleep_dvbt_demod_setting(struct cxd2880_tnrdmd
 654                                                    *tnr_dmd)
 655 {
 656         int ret;
 657 
 658         if (!tnr_dmd)
 659                 return -EINVAL;
 660 
 661         ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
 662                                           CXD2880_IO_TGT_DMD,
 663                                           sleep_dmd_setting_seq1,
 664                                           ARRAY_SIZE(sleep_dmd_setting_seq1));
 665         if (ret)
 666                 return ret;
 667 
 668         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 669                 ret = cxd2880_io_write_multi_regs(tnr_dmd->io,
 670                                                   CXD2880_IO_TGT_DMD,
 671                                                   sleep_dmd_setting_seq2,
 672                                                   ARRAY_SIZE(sleep_dmd_setting_seq2));
 673 
 674         return ret;
 675 }
 676 
 677 static int dvbt_set_profile(struct cxd2880_tnrdmd *tnr_dmd,
 678                             enum cxd2880_dvbt_profile profile)
 679 {
 680         int ret;
 681 
 682         if (!tnr_dmd)
 683                 return -EINVAL;
 684 
 685         ret = tnr_dmd->io->write_reg(tnr_dmd->io,
 686                                      CXD2880_IO_TGT_DMD,
 687                                      0x00, 0x10);
 688         if (ret)
 689                 return ret;
 690 
 691         return tnr_dmd->io->write_reg(tnr_dmd->io,
 692                                       CXD2880_IO_TGT_DMD,
 693                                       0x67,
 694                                       (profile == CXD2880_DVBT_PROFILE_HP)
 695                                       ? 0x00 : 0x01);
 696 }
 697 
 698 int cxd2880_tnrdmd_dvbt_tune1(struct cxd2880_tnrdmd *tnr_dmd,
 699                               struct cxd2880_dvbt_tune_param
 700                               *tune_param)
 701 {
 702         int ret;
 703 
 704         if (!tnr_dmd || !tune_param)
 705                 return -EINVAL;
 706 
 707         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 708                 return -EINVAL;
 709 
 710         if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
 711             tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 712                 return -EINVAL;
 713 
 714         ret =
 715             cxd2880_tnrdmd_common_tune_setting1(tnr_dmd, CXD2880_DTV_SYS_DVBT,
 716                                                 tune_param->center_freq_khz,
 717                                                 tune_param->bandwidth, 0, 0);
 718         if (ret)
 719                 return ret;
 720 
 721         ret =
 722             x_tune_dvbt_demod_setting(tnr_dmd, tune_param->bandwidth,
 723                                       tnr_dmd->clk_mode);
 724         if (ret)
 725                 return ret;
 726 
 727         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
 728                 ret =
 729                     x_tune_dvbt_demod_setting(tnr_dmd->diver_sub,
 730                                               tune_param->bandwidth,
 731                                               tnr_dmd->diver_sub->clk_mode);
 732                 if (ret)
 733                         return ret;
 734         }
 735 
 736         return dvbt_set_profile(tnr_dmd, tune_param->profile);
 737 }
 738 
 739 int cxd2880_tnrdmd_dvbt_tune2(struct cxd2880_tnrdmd *tnr_dmd,
 740                               struct cxd2880_dvbt_tune_param
 741                               *tune_param)
 742 {
 743         int ret;
 744 
 745         if (!tnr_dmd || !tune_param)
 746                 return -EINVAL;
 747 
 748         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 749                 return -EINVAL;
 750 
 751         if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
 752             tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 753                 return -EINVAL;
 754 
 755         ret =
 756             cxd2880_tnrdmd_common_tune_setting2(tnr_dmd, CXD2880_DTV_SYS_DVBT,
 757                                                 0);
 758         if (ret)
 759                 return ret;
 760 
 761         tnr_dmd->state = CXD2880_TNRDMD_STATE_ACTIVE;
 762         tnr_dmd->frequency_khz = tune_param->center_freq_khz;
 763         tnr_dmd->sys = CXD2880_DTV_SYS_DVBT;
 764         tnr_dmd->bandwidth = tune_param->bandwidth;
 765 
 766         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
 767                 tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_ACTIVE;
 768                 tnr_dmd->diver_sub->frequency_khz = tune_param->center_freq_khz;
 769                 tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_DVBT;
 770                 tnr_dmd->diver_sub->bandwidth = tune_param->bandwidth;
 771         }
 772 
 773         return 0;
 774 }
 775 
 776 int cxd2880_tnrdmd_dvbt_sleep_setting(struct cxd2880_tnrdmd *tnr_dmd)
 777 {
 778         int ret;
 779 
 780         if (!tnr_dmd)
 781                 return -EINVAL;
 782 
 783         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 784                 return -EINVAL;
 785 
 786         if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
 787             tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 788                 return -EINVAL;
 789 
 790         ret = x_sleep_dvbt_demod_setting(tnr_dmd);
 791         if (ret)
 792                 return ret;
 793 
 794         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
 795                 ret = x_sleep_dvbt_demod_setting(tnr_dmd->diver_sub);
 796 
 797         return ret;
 798 }
 799 
 800 int cxd2880_tnrdmd_dvbt_check_demod_lock(struct cxd2880_tnrdmd
 801                                          *tnr_dmd,
 802                                          enum
 803                                          cxd2880_tnrdmd_lock_result
 804                                          *lock)
 805 {
 806         int ret;
 807 
 808         u8 sync_stat = 0;
 809         u8 ts_lock = 0;
 810         u8 unlock_detected = 0;
 811         u8 unlock_detected_sub = 0;
 812 
 813         if (!tnr_dmd || !lock)
 814                 return -EINVAL;
 815 
 816         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 817                 return -EINVAL;
 818 
 819         if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 820                 return -EINVAL;
 821 
 822         ret =
 823             cxd2880_tnrdmd_dvbt_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock,
 824                                               &unlock_detected);
 825         if (ret)
 826                 return ret;
 827 
 828         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) {
 829                 if (sync_stat == 6)
 830                         *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
 831                 else if (unlock_detected)
 832                         *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
 833                 else
 834                         *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
 835 
 836                 return ret;
 837         }
 838 
 839         if (sync_stat == 6) {
 840                 *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
 841                 return ret;
 842         }
 843 
 844         ret =
 845             cxd2880_tnrdmd_dvbt_mon_sync_stat_sub(tnr_dmd, &sync_stat,
 846                                                   &unlock_detected_sub);
 847         if (ret)
 848                 return ret;
 849 
 850         if (sync_stat == 6)
 851                 *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
 852         else if (unlock_detected && unlock_detected_sub)
 853                 *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
 854         else
 855                 *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
 856 
 857         return ret;
 858 }
 859 
 860 int cxd2880_tnrdmd_dvbt_check_ts_lock(struct cxd2880_tnrdmd
 861                                       *tnr_dmd,
 862                                       enum
 863                                       cxd2880_tnrdmd_lock_result
 864                                       *lock)
 865 {
 866         int ret;
 867 
 868         u8 sync_stat = 0;
 869         u8 ts_lock = 0;
 870         u8 unlock_detected = 0;
 871         u8 unlock_detected_sub = 0;
 872 
 873         if (!tnr_dmd || !lock)
 874                 return -EINVAL;
 875 
 876         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
 877                 return -EINVAL;
 878 
 879         if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
 880                 return -EINVAL;
 881 
 882         ret =
 883             cxd2880_tnrdmd_dvbt_mon_sync_stat(tnr_dmd, &sync_stat, &ts_lock,
 884                                               &unlock_detected);
 885         if (ret)
 886                 return ret;
 887 
 888         if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) {
 889                 if (ts_lock)
 890                         *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
 891                 else if (unlock_detected)
 892                         *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
 893                 else
 894                         *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
 895 
 896                 return ret;
 897         }
 898 
 899         if (ts_lock) {
 900                 *lock = CXD2880_TNRDMD_LOCK_RESULT_LOCKED;
 901                 return ret;
 902         } else if (!unlock_detected) {
 903                 *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
 904                 return ret;
 905         }
 906 
 907         ret =
 908             cxd2880_tnrdmd_dvbt_mon_sync_stat_sub(tnr_dmd, &sync_stat,
 909                                                   &unlock_detected_sub);
 910         if (ret)
 911                 return ret;
 912 
 913         if (unlock_detected && unlock_detected_sub)
 914                 *lock = CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED;
 915         else
 916                 *lock = CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT;
 917 
 918         return ret;
 919 }

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