linux/drivers/media/tuners/mxl5007t.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
   4 *
   5 *  Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
   6 */
   7
   8#include <linux/i2c.h>
   9#include <linux/types.h>
  10#include <linux/videodev2.h>
  11#include "tuner-i2c.h"
  12#include "mxl5007t.h"
  13
  14static DEFINE_MUTEX(mxl5007t_list_mutex);
  15static LIST_HEAD(hybrid_tuner_instance_list);
  16
  17static int mxl5007t_debug;
  18module_param_named(debug, mxl5007t_debug, int, 0644);
  19MODULE_PARM_DESC(debug, "set debug level");
  20
  21/* ------------------------------------------------------------------------- */
  22
  23#define mxl_printk(kern, fmt, arg...) \
  24        printk(kern "%s: " fmt "\n", __func__, ##arg)
  25
  26#define mxl_err(fmt, arg...) \
  27        mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg)
  28
  29#define mxl_warn(fmt, arg...) \
  30        mxl_printk(KERN_WARNING, fmt, ##arg)
  31
  32#define mxl_info(fmt, arg...) \
  33        mxl_printk(KERN_INFO, fmt, ##arg)
  34
  35#define mxl_debug(fmt, arg...)                          \
  36({                                                      \
  37        if (mxl5007t_debug)                             \
  38                mxl_printk(KERN_DEBUG, fmt, ##arg);     \
  39})
  40
  41#define mxl_fail(ret)                                                   \
  42({                                                                      \
  43        int __ret;                                                      \
  44        __ret = (ret < 0);                                              \
  45        if (__ret)                                                      \
  46                mxl_printk(KERN_ERR, "error %d on line %d",             \
  47                           ret, __LINE__);                              \
  48        __ret;                                                          \
  49})
  50
  51/* ------------------------------------------------------------------------- */
  52
  53enum mxl5007t_mode {
  54        MxL_MODE_ISDBT     =    0,
  55        MxL_MODE_DVBT      =    1,
  56        MxL_MODE_ATSC      =    2,
  57        MxL_MODE_CABLE     = 0x10,
  58};
  59
  60enum mxl5007t_chip_version {
  61        MxL_UNKNOWN_ID     = 0x00,
  62        MxL_5007_V1_F1     = 0x11,
  63        MxL_5007_V1_F2     = 0x12,
  64        MxL_5007_V4        = 0x14,
  65        MxL_5007_V2_100_F1 = 0x21,
  66        MxL_5007_V2_100_F2 = 0x22,
  67        MxL_5007_V2_200_F1 = 0x23,
  68        MxL_5007_V2_200_F2 = 0x24,
  69};
  70
  71struct reg_pair_t {
  72        u8 reg;
  73        u8 val;
  74};
  75
  76/* ------------------------------------------------------------------------- */
  77
  78static struct reg_pair_t init_tab[] = {
  79        { 0x02, 0x06 },
  80        { 0x03, 0x48 },
  81        { 0x05, 0x04 },
  82        { 0x06, 0x10 },
  83        { 0x2e, 0x15 }, /* OVERRIDE */
  84        { 0x30, 0x10 }, /* OVERRIDE */
  85        { 0x45, 0x58 }, /* OVERRIDE */
  86        { 0x48, 0x19 }, /* OVERRIDE */
  87        { 0x52, 0x03 }, /* OVERRIDE */
  88        { 0x53, 0x44 }, /* OVERRIDE */
  89        { 0x6a, 0x4b }, /* OVERRIDE */
  90        { 0x76, 0x00 }, /* OVERRIDE */
  91        { 0x78, 0x18 }, /* OVERRIDE */
  92        { 0x7a, 0x17 }, /* OVERRIDE */
  93        { 0x85, 0x06 }, /* OVERRIDE */
  94        { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
  95        { 0, 0 }
  96};
  97
  98static struct reg_pair_t init_tab_cable[] = {
  99        { 0x02, 0x06 },
 100        { 0x03, 0x48 },
 101        { 0x05, 0x04 },
 102        { 0x06, 0x10 },
 103        { 0x09, 0x3f },
 104        { 0x0a, 0x3f },
 105        { 0x0b, 0x3f },
 106        { 0x2e, 0x15 }, /* OVERRIDE */
 107        { 0x30, 0x10 }, /* OVERRIDE */
 108        { 0x45, 0x58 }, /* OVERRIDE */
 109        { 0x48, 0x19 }, /* OVERRIDE */
 110        { 0x52, 0x03 }, /* OVERRIDE */
 111        { 0x53, 0x44 }, /* OVERRIDE */
 112        { 0x6a, 0x4b }, /* OVERRIDE */
 113        { 0x76, 0x00 }, /* OVERRIDE */
 114        { 0x78, 0x18 }, /* OVERRIDE */
 115        { 0x7a, 0x17 }, /* OVERRIDE */
 116        { 0x85, 0x06 }, /* OVERRIDE */
 117        { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
 118        { 0, 0 }
 119};
 120
 121/* ------------------------------------------------------------------------- */
 122
 123static struct reg_pair_t reg_pair_rftune[] = {
 124        { 0x0f, 0x00 }, /* abort tune */
 125        { 0x0c, 0x15 },
 126        { 0x0d, 0x40 },
 127        { 0x0e, 0x0e },
 128        { 0x1f, 0x87 }, /* OVERRIDE */
 129        { 0x20, 0x1f }, /* OVERRIDE */
 130        { 0x21, 0x87 }, /* OVERRIDE */
 131        { 0x22, 0x1f }, /* OVERRIDE */
 132        { 0x80, 0x01 }, /* freq dependent */
 133        { 0x0f, 0x01 }, /* start tune */
 134        { 0, 0 }
 135};
 136
 137/* ------------------------------------------------------------------------- */
 138
 139struct mxl5007t_state {
 140        struct list_head hybrid_tuner_instance_list;
 141        struct tuner_i2c_props i2c_props;
 142
 143        struct mutex lock;
 144
 145        struct mxl5007t_config *config;
 146
 147        enum mxl5007t_chip_version chip_id;
 148
 149        struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)];
 150        struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
 151        struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
 152
 153        enum mxl5007t_if_freq if_freq;
 154
 155        u32 frequency;
 156        u32 bandwidth;
 157};
 158
 159/* ------------------------------------------------------------------------- */
 160
 161/* called by _init and _rftun to manipulate the register arrays */
 162
 163static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val)
 164{
 165        unsigned int i = 0;
 166
 167        while (reg_pair[i].reg || reg_pair[i].val) {
 168                if (reg_pair[i].reg == reg) {
 169                        reg_pair[i].val &= ~mask;
 170                        reg_pair[i].val |= val;
 171                }
 172                i++;
 173
 174        }
 175        return;
 176}
 177
 178static void copy_reg_bits(struct reg_pair_t *reg_pair1,
 179                          struct reg_pair_t *reg_pair2)
 180{
 181        unsigned int i, j;
 182
 183        i = j = 0;
 184
 185        while (reg_pair1[i].reg || reg_pair1[i].val) {
 186                while (reg_pair2[j].reg || reg_pair2[j].val) {
 187                        if (reg_pair1[i].reg != reg_pair2[j].reg) {
 188                                j++;
 189                                continue;
 190                        }
 191                        reg_pair2[j].val = reg_pair1[i].val;
 192                        break;
 193                }
 194                i++;
 195        }
 196        return;
 197}
 198
 199/* ------------------------------------------------------------------------- */
 200
 201static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
 202                                   enum mxl5007t_mode mode,
 203                                   s32 if_diff_out_level)
 204{
 205        switch (mode) {
 206        case MxL_MODE_ATSC:
 207                set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
 208                break;
 209        case MxL_MODE_DVBT:
 210                set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
 211                break;
 212        case MxL_MODE_ISDBT:
 213                set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
 214                break;
 215        case MxL_MODE_CABLE:
 216                set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
 217                set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
 218                             8 - if_diff_out_level);
 219                set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
 220                break;
 221        default:
 222                mxl_fail(-EINVAL);
 223        }
 224        return;
 225}
 226
 227static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
 228                                      enum mxl5007t_if_freq if_freq,
 229                                      int invert_if)
 230{
 231        u8 val;
 232
 233        switch (if_freq) {
 234        case MxL_IF_4_MHZ:
 235                val = 0x00;
 236                break;
 237        case MxL_IF_4_5_MHZ:
 238                val = 0x02;
 239                break;
 240        case MxL_IF_4_57_MHZ:
 241                val = 0x03;
 242                break;
 243        case MxL_IF_5_MHZ:
 244                val = 0x04;
 245                break;
 246        case MxL_IF_5_38_MHZ:
 247                val = 0x05;
 248                break;
 249        case MxL_IF_6_MHZ:
 250                val = 0x06;
 251                break;
 252        case MxL_IF_6_28_MHZ:
 253                val = 0x07;
 254                break;
 255        case MxL_IF_9_1915_MHZ:
 256                val = 0x08;
 257                break;
 258        case MxL_IF_35_25_MHZ:
 259                val = 0x09;
 260                break;
 261        case MxL_IF_36_15_MHZ:
 262                val = 0x0a;
 263                break;
 264        case MxL_IF_44_MHZ:
 265                val = 0x0b;
 266                break;
 267        default:
 268                mxl_fail(-EINVAL);
 269                return;
 270        }
 271        set_reg_bits(state->tab_init, 0x02, 0x0f, val);
 272
 273        /* set inverted IF or normal IF */
 274        set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
 275
 276        state->if_freq = if_freq;
 277
 278        return;
 279}
 280
 281static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
 282                                        enum mxl5007t_xtal_freq xtal_freq)
 283{
 284        switch (xtal_freq) {
 285        case MxL_XTAL_16_MHZ:
 286                /* select xtal freq & ref freq */
 287                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
 288                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
 289                break;
 290        case MxL_XTAL_20_MHZ:
 291                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
 292                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
 293                break;
 294        case MxL_XTAL_20_25_MHZ:
 295                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
 296                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
 297                break;
 298        case MxL_XTAL_20_48_MHZ:
 299                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
 300                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
 301                break;
 302        case MxL_XTAL_24_MHZ:
 303                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
 304                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
 305                break;
 306        case MxL_XTAL_25_MHZ:
 307                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
 308                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
 309                break;
 310        case MxL_XTAL_25_14_MHZ:
 311                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
 312                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
 313                break;
 314        case MxL_XTAL_27_MHZ:
 315                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
 316                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
 317                break;
 318        case MxL_XTAL_28_8_MHZ:
 319                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
 320                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
 321                break;
 322        case MxL_XTAL_32_MHZ:
 323                set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
 324                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
 325                break;
 326        case MxL_XTAL_40_MHZ:
 327                set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
 328                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
 329                break;
 330        case MxL_XTAL_44_MHZ:
 331                set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
 332                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
 333                break;
 334        case MxL_XTAL_48_MHZ:
 335                set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
 336                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
 337                break;
 338        case MxL_XTAL_49_3811_MHZ:
 339                set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
 340                set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
 341                break;
 342        default:
 343                mxl_fail(-EINVAL);
 344                return;
 345        }
 346
 347        return;
 348}
 349
 350static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
 351                                                  enum mxl5007t_mode mode)
 352{
 353        struct mxl5007t_config *cfg = state->config;
 354
 355        memcpy(&state->tab_init, &init_tab, sizeof(init_tab));
 356        memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable));
 357
 358        mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level);
 359        mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
 360        mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
 361
 362        set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
 363        set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
 364
 365        if (mode >= MxL_MODE_CABLE) {
 366                copy_reg_bits(state->tab_init, state->tab_init_cable);
 367                return state->tab_init_cable;
 368        } else
 369                return state->tab_init;
 370}
 371
 372/* ------------------------------------------------------------------------- */
 373
 374enum mxl5007t_bw_mhz {
 375        MxL_BW_6MHz = 6,
 376        MxL_BW_7MHz = 7,
 377        MxL_BW_8MHz = 8,
 378};
 379
 380static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
 381                                 enum mxl5007t_bw_mhz bw)
 382{
 383        u8 val;
 384
 385        switch (bw) {
 386        case MxL_BW_6MHz:
 387                val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A,
 388                             * and DIG_MODEINDEX_CSF */
 389                break;
 390        case MxL_BW_7MHz:
 391                val = 0x2a;
 392                break;
 393        case MxL_BW_8MHz:
 394                val = 0x3f;
 395                break;
 396        default:
 397                mxl_fail(-EINVAL);
 398                return;
 399        }
 400        set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
 401
 402        return;
 403}
 404
 405static struct
 406reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
 407                                       u32 rf_freq, enum mxl5007t_bw_mhz bw)
 408{
 409        u32 dig_rf_freq = 0;
 410        u32 temp;
 411        u32 frac_divider = 1000000;
 412        unsigned int i;
 413
 414        memcpy(&state->tab_rftune, &reg_pair_rftune, sizeof(reg_pair_rftune));
 415
 416        mxl5007t_set_bw_bits(state, bw);
 417
 418        /* Convert RF frequency into 16 bits =>
 419         * 10 bit integer (MHz) + 6 bit fraction */
 420        dig_rf_freq = rf_freq / MHz;
 421
 422        temp = rf_freq % MHz;
 423
 424        for (i = 0; i < 6; i++) {
 425                dig_rf_freq <<= 1;
 426                frac_divider /= 2;
 427                if (temp > frac_divider) {
 428                        temp -= frac_divider;
 429                        dig_rf_freq++;
 430                }
 431        }
 432
 433        /* add to have shift center point by 7.8124 kHz */
 434        if (temp > 7812)
 435                dig_rf_freq++;
 436
 437        set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
 438        set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
 439
 440        if (rf_freq >= 333000000)
 441                set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
 442
 443        return state->tab_rftune;
 444}
 445
 446/* ------------------------------------------------------------------------- */
 447
 448static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val)
 449{
 450        u8 buf[] = { reg, val };
 451        struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
 452                               .buf = buf, .len = 2 };
 453        int ret;
 454
 455        ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
 456        if (ret != 1) {
 457                mxl_err("failed!");
 458                return -EREMOTEIO;
 459        }
 460        return 0;
 461}
 462
 463static int mxl5007t_write_regs(struct mxl5007t_state *state,
 464                               struct reg_pair_t *reg_pair)
 465{
 466        unsigned int i = 0;
 467        int ret = 0;
 468
 469        while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) {
 470                ret = mxl5007t_write_reg(state,
 471                                         reg_pair[i].reg, reg_pair[i].val);
 472                i++;
 473        }
 474        return ret;
 475}
 476
 477static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
 478{
 479        u8 buf[2] = { 0xfb, reg };
 480        struct i2c_msg msg[] = {
 481                { .addr = state->i2c_props.addr, .flags = 0,
 482                  .buf = buf, .len = 2 },
 483                { .addr = state->i2c_props.addr, .flags = I2C_M_RD,
 484                  .buf = val, .len = 1 },
 485        };
 486        int ret;
 487
 488        ret = i2c_transfer(state->i2c_props.adap, msg, 2);
 489        if (ret != 2) {
 490                mxl_err("failed!");
 491                return -EREMOTEIO;
 492        }
 493        return 0;
 494}
 495
 496static int mxl5007t_soft_reset(struct mxl5007t_state *state)
 497{
 498        u8 d = 0xff;
 499        struct i2c_msg msg = {
 500                .addr = state->i2c_props.addr, .flags = 0,
 501                .buf = &d, .len = 1
 502        };
 503        int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
 504
 505        if (ret != 1) {
 506                mxl_err("failed!");
 507                return -EREMOTEIO;
 508        }
 509        return 0;
 510}
 511
 512static int mxl5007t_tuner_init(struct mxl5007t_state *state,
 513                               enum mxl5007t_mode mode)
 514{
 515        struct reg_pair_t *init_regs;
 516        int ret;
 517
 518        /* calculate initialization reg array */
 519        init_regs = mxl5007t_calc_init_regs(state, mode);
 520
 521        ret = mxl5007t_write_regs(state, init_regs);
 522        if (mxl_fail(ret))
 523                goto fail;
 524        mdelay(1);
 525fail:
 526        return ret;
 527}
 528
 529static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz,
 530                                  enum mxl5007t_bw_mhz bw)
 531{
 532        struct reg_pair_t *rf_tune_regs;
 533        int ret;
 534
 535        /* calculate channel change reg array */
 536        rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw);
 537
 538        ret = mxl5007t_write_regs(state, rf_tune_regs);
 539        if (mxl_fail(ret))
 540                goto fail;
 541        msleep(3);
 542fail:
 543        return ret;
 544}
 545
 546/* ------------------------------------------------------------------------- */
 547
 548static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
 549                                      int *rf_locked, int *ref_locked)
 550{
 551        u8 d;
 552        int ret;
 553
 554        *rf_locked = 0;
 555        *ref_locked = 0;
 556
 557        ret = mxl5007t_read_reg(state, 0xd8, &d);
 558        if (mxl_fail(ret))
 559                goto fail;
 560
 561        if ((d & 0x0c) == 0x0c)
 562                *rf_locked = 1;
 563
 564        if ((d & 0x03) == 0x03)
 565                *ref_locked = 1;
 566fail:
 567        return ret;
 568}
 569
 570/* ------------------------------------------------------------------------- */
 571
 572static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
 573{
 574        struct mxl5007t_state *state = fe->tuner_priv;
 575        int rf_locked, ref_locked, ret;
 576
 577        *status = 0;
 578
 579        if (fe->ops.i2c_gate_ctrl)
 580                fe->ops.i2c_gate_ctrl(fe, 1);
 581
 582        ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked);
 583        if (mxl_fail(ret))
 584                goto fail;
 585        mxl_debug("%s%s", rf_locked ? "rf locked " : "",
 586                  ref_locked ? "ref locked" : "");
 587
 588        if ((rf_locked) || (ref_locked))
 589                *status |= TUNER_STATUS_LOCKED;
 590fail:
 591        if (fe->ops.i2c_gate_ctrl)
 592                fe->ops.i2c_gate_ctrl(fe, 0);
 593
 594        return ret;
 595}
 596
 597/* ------------------------------------------------------------------------- */
 598
 599static int mxl5007t_set_params(struct dvb_frontend *fe)
 600{
 601        struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 602        u32 delsys = c->delivery_system;
 603        struct mxl5007t_state *state = fe->tuner_priv;
 604        enum mxl5007t_bw_mhz bw;
 605        enum mxl5007t_mode mode;
 606        int ret;
 607        u32 freq = c->frequency;
 608
 609        switch (delsys) {
 610        case SYS_ATSC:
 611                mode = MxL_MODE_ATSC;
 612                bw = MxL_BW_6MHz;
 613                break;
 614        case SYS_DVBC_ANNEX_B:
 615                mode = MxL_MODE_CABLE;
 616                bw = MxL_BW_6MHz;
 617                break;
 618        case SYS_DVBT:
 619        case SYS_DVBT2:
 620                mode = MxL_MODE_DVBT;
 621                switch (c->bandwidth_hz) {
 622                case 6000000:
 623                        bw = MxL_BW_6MHz;
 624                        break;
 625                case 7000000:
 626                        bw = MxL_BW_7MHz;
 627                        break;
 628                case 8000000:
 629                        bw = MxL_BW_8MHz;
 630                        break;
 631                default:
 632                        return -EINVAL;
 633                }
 634                break;
 635        default:
 636                mxl_err("modulation type not supported!");
 637                return -EINVAL;
 638        }
 639
 640        if (fe->ops.i2c_gate_ctrl)
 641                fe->ops.i2c_gate_ctrl(fe, 1);
 642
 643        mutex_lock(&state->lock);
 644
 645        ret = mxl5007t_tuner_init(state, mode);
 646        if (mxl_fail(ret))
 647                goto fail;
 648
 649        ret = mxl5007t_tuner_rf_tune(state, freq, bw);
 650        if (mxl_fail(ret))
 651                goto fail;
 652
 653        state->frequency = freq;
 654        state->bandwidth = c->bandwidth_hz;
 655fail:
 656        mutex_unlock(&state->lock);
 657
 658        if (fe->ops.i2c_gate_ctrl)
 659                fe->ops.i2c_gate_ctrl(fe, 0);
 660
 661        return ret;
 662}
 663
 664/* ------------------------------------------------------------------------- */
 665
 666static int mxl5007t_init(struct dvb_frontend *fe)
 667{
 668        struct mxl5007t_state *state = fe->tuner_priv;
 669        int ret;
 670
 671        if (fe->ops.i2c_gate_ctrl)
 672                fe->ops.i2c_gate_ctrl(fe, 1);
 673
 674        /* wake from standby */
 675        ret = mxl5007t_write_reg(state, 0x01, 0x01);
 676        mxl_fail(ret);
 677
 678        if (fe->ops.i2c_gate_ctrl)
 679                fe->ops.i2c_gate_ctrl(fe, 0);
 680
 681        return ret;
 682}
 683
 684static int mxl5007t_sleep(struct dvb_frontend *fe)
 685{
 686        struct mxl5007t_state *state = fe->tuner_priv;
 687        int ret;
 688
 689        if (fe->ops.i2c_gate_ctrl)
 690                fe->ops.i2c_gate_ctrl(fe, 1);
 691
 692        /* enter standby mode */
 693        ret = mxl5007t_write_reg(state, 0x01, 0x00);
 694        mxl_fail(ret);
 695        ret = mxl5007t_write_reg(state, 0x0f, 0x00);
 696        mxl_fail(ret);
 697
 698        if (fe->ops.i2c_gate_ctrl)
 699                fe->ops.i2c_gate_ctrl(fe, 0);
 700
 701        return ret;
 702}
 703
 704/* ------------------------------------------------------------------------- */
 705
 706static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 707{
 708        struct mxl5007t_state *state = fe->tuner_priv;
 709        *frequency = state->frequency;
 710        return 0;
 711}
 712
 713static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
 714{
 715        struct mxl5007t_state *state = fe->tuner_priv;
 716        *bandwidth = state->bandwidth;
 717        return 0;
 718}
 719
 720static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
 721{
 722        struct mxl5007t_state *state = fe->tuner_priv;
 723
 724        *frequency = 0;
 725
 726        switch (state->if_freq) {
 727        case MxL_IF_4_MHZ:
 728                *frequency = 4000000;
 729                break;
 730        case MxL_IF_4_5_MHZ:
 731                *frequency = 4500000;
 732                break;
 733        case MxL_IF_4_57_MHZ:
 734                *frequency = 4570000;
 735                break;
 736        case MxL_IF_5_MHZ:
 737                *frequency = 5000000;
 738                break;
 739        case MxL_IF_5_38_MHZ:
 740                *frequency = 5380000;
 741                break;
 742        case MxL_IF_6_MHZ:
 743                *frequency = 6000000;
 744                break;
 745        case MxL_IF_6_28_MHZ:
 746                *frequency = 6280000;
 747                break;
 748        case MxL_IF_9_1915_MHZ:
 749                *frequency = 9191500;
 750                break;
 751        case MxL_IF_35_25_MHZ:
 752                *frequency = 35250000;
 753                break;
 754        case MxL_IF_36_15_MHZ:
 755                *frequency = 36150000;
 756                break;
 757        case MxL_IF_44_MHZ:
 758                *frequency = 44000000;
 759                break;
 760        }
 761        return 0;
 762}
 763
 764static void mxl5007t_release(struct dvb_frontend *fe)
 765{
 766        struct mxl5007t_state *state = fe->tuner_priv;
 767
 768        mutex_lock(&mxl5007t_list_mutex);
 769
 770        if (state)
 771                hybrid_tuner_release_state(state);
 772
 773        mutex_unlock(&mxl5007t_list_mutex);
 774
 775        fe->tuner_priv = NULL;
 776}
 777
 778/* ------------------------------------------------------------------------- */
 779
 780static const struct dvb_tuner_ops mxl5007t_tuner_ops = {
 781        .info = {
 782                .name = "MaxLinear MxL5007T",
 783        },
 784        .init              = mxl5007t_init,
 785        .sleep             = mxl5007t_sleep,
 786        .set_params        = mxl5007t_set_params,
 787        .get_status        = mxl5007t_get_status,
 788        .get_frequency     = mxl5007t_get_frequency,
 789        .get_bandwidth     = mxl5007t_get_bandwidth,
 790        .release           = mxl5007t_release,
 791        .get_if_frequency  = mxl5007t_get_if_frequency,
 792};
 793
 794static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
 795{
 796        char *name;
 797        int ret;
 798        u8 id;
 799
 800        ret = mxl5007t_read_reg(state, 0xd9, &id);
 801        if (mxl_fail(ret))
 802                goto fail;
 803
 804        switch (id) {
 805        case MxL_5007_V1_F1:
 806                name = "MxL5007.v1.f1";
 807                break;
 808        case MxL_5007_V1_F2:
 809                name = "MxL5007.v1.f2";
 810                break;
 811        case MxL_5007_V2_100_F1:
 812                name = "MxL5007.v2.100.f1";
 813                break;
 814        case MxL_5007_V2_100_F2:
 815                name = "MxL5007.v2.100.f2";
 816                break;
 817        case MxL_5007_V2_200_F1:
 818                name = "MxL5007.v2.200.f1";
 819                break;
 820        case MxL_5007_V2_200_F2:
 821                name = "MxL5007.v2.200.f2";
 822                break;
 823        case MxL_5007_V4:
 824                name = "MxL5007T.v4";
 825                break;
 826        default:
 827                name = "MxL5007T";
 828                printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
 829                id = MxL_UNKNOWN_ID;
 830        }
 831        state->chip_id = id;
 832        mxl_info("%s detected @ %d-%04x", name,
 833                 i2c_adapter_id(state->i2c_props.adap),
 834                 state->i2c_props.addr);
 835        return 0;
 836fail:
 837        mxl_warn("unable to identify device @ %d-%04x",
 838                 i2c_adapter_id(state->i2c_props.adap),
 839                 state->i2c_props.addr);
 840
 841        state->chip_id = MxL_UNKNOWN_ID;
 842        return ret;
 843}
 844
 845struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
 846                                     struct i2c_adapter *i2c, u8 addr,
 847                                     struct mxl5007t_config *cfg)
 848{
 849        struct mxl5007t_state *state = NULL;
 850        int instance, ret;
 851
 852        mutex_lock(&mxl5007t_list_mutex);
 853        instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
 854                                              hybrid_tuner_instance_list,
 855                                              i2c, addr, "mxl5007t");
 856        switch (instance) {
 857        case 0:
 858                goto fail;
 859        case 1:
 860                /* new tuner instance */
 861                state->config = cfg;
 862
 863                mutex_init(&state->lock);
 864
 865                if (fe->ops.i2c_gate_ctrl)
 866                        fe->ops.i2c_gate_ctrl(fe, 1);
 867
 868                ret = mxl5007t_get_chip_id(state);
 869
 870                if (fe->ops.i2c_gate_ctrl)
 871                        fe->ops.i2c_gate_ctrl(fe, 0);
 872
 873                /* check return value of mxl5007t_get_chip_id */
 874                if (mxl_fail(ret))
 875                        goto fail;
 876                break;
 877        default:
 878                /* existing tuner instance */
 879                break;
 880        }
 881
 882        if (fe->ops.i2c_gate_ctrl)
 883                fe->ops.i2c_gate_ctrl(fe, 1);
 884
 885        ret = mxl5007t_soft_reset(state);
 886
 887        if (fe->ops.i2c_gate_ctrl)
 888                fe->ops.i2c_gate_ctrl(fe, 0);
 889
 890        if (mxl_fail(ret))
 891                goto fail;
 892
 893        if (fe->ops.i2c_gate_ctrl)
 894                fe->ops.i2c_gate_ctrl(fe, 1);
 895
 896        ret = mxl5007t_write_reg(state, 0x04,
 897                state->config->loop_thru_enable);
 898
 899        if (fe->ops.i2c_gate_ctrl)
 900                fe->ops.i2c_gate_ctrl(fe, 0);
 901
 902        if (mxl_fail(ret))
 903                goto fail;
 904
 905        fe->tuner_priv = state;
 906
 907        mutex_unlock(&mxl5007t_list_mutex);
 908
 909        memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops,
 910               sizeof(struct dvb_tuner_ops));
 911
 912        return fe;
 913fail:
 914        mutex_unlock(&mxl5007t_list_mutex);
 915
 916        mxl5007t_release(fe);
 917        return NULL;
 918}
 919EXPORT_SYMBOL_GPL(mxl5007t_attach);
 920MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
 921MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
 922MODULE_LICENSE("GPL");
 923MODULE_VERSION("0.2");
 924