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