Showing error 1631

User: Jiri Slaby
Error type: Invalid Pointer Dereference
Error type description: A pointer which is invalid is being dereferenced
File location: drivers/media/common/tuners/mxl5007t.c
Line in file: 984
Project: Linux Kernel
Project version: 2.6.28
Tools: Smatch (1.59)
Entered: 2013-09-10 07:54:05 UTC


Source:

   1/*
   2 *  mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
   3 *
   4 *  Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
   5 *
   6 *  This program is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; either version 2 of the License, or
   9 *  (at your option) any later version.
  10 *
  11 *  This program is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *  GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License
  17 *  along with this program; if not, write to the Free Software
  18 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 */
  20
  21#include <linux/i2c.h>
  22#include <linux/types.h>
  23#include <linux/videodev2.h>
  24#include "tuner-i2c.h"
  25#include "mxl5007t.h"
  26
  27static DEFINE_MUTEX(mxl5007t_list_mutex);
  28static LIST_HEAD(hybrid_tuner_instance_list);
  29
  30static int mxl5007t_debug;
  31module_param_named(debug, mxl5007t_debug, int, 0644);
  32MODULE_PARM_DESC(debug, "set debug level");
  33
  34/* ------------------------------------------------------------------------- */
  35
  36#define mxl_printk(kern, fmt, arg...) \
  37        printk(kern "%s: " fmt "\n", __func__, ##arg)
  38
  39#define mxl_err(fmt, arg...) \
  40        mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg)
  41
  42#define mxl_warn(fmt, arg...) \
  43        mxl_printk(KERN_WARNING, fmt, ##arg)
  44
  45#define mxl_info(fmt, arg...) \
  46        mxl_printk(KERN_INFO, fmt, ##arg)
  47
  48#define mxl_debug(fmt, arg...)                                \
  49({                                                        \
  50        if (mxl5007t_debug)                                \
  51                mxl_printk(KERN_DEBUG, fmt, ##arg);        \
  52})
  53
  54#define mxl_fail(ret)                                                        \
  55({                                                                        \
  56        int __ret;                                                        \
  57        __ret = (ret < 0);                                                \
  58        if (__ret)                                                        \
  59                mxl_printk(KERN_ERR, "error %d on line %d",                \
  60                           ret, __LINE__);                                \
  61        __ret;                                                                \
  62})
  63
  64/* ------------------------------------------------------------------------- */
  65
  66#define MHz 1000000
  67
  68enum mxl5007t_mode {
  69        MxL_MODE_OTA_DVBT_ATSC        =    0,
  70        MxL_MODE_OTA_NTSC_PAL_GH      =    1,
  71        MxL_MODE_OTA_PAL_IB           =    2,
  72        MxL_MODE_OTA_PAL_D_SECAM_KL   =    3,
  73        MxL_MODE_OTA_ISDBT            =    4,
  74        MxL_MODE_CABLE_DIGITAL        = 0x10,
  75        MxL_MODE_CABLE_NTSC_PAL_GH    = 0x11,
  76        MxL_MODE_CABLE_PAL_IB         = 0x12,
  77        MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13,
  78        MxL_MODE_CABLE_SCTE40         = 0x14,
  79};
  80
  81enum mxl5007t_chip_version {
  82        MxL_UNKNOWN_ID     = 0x00,
  83        MxL_5007_V1_F1     = 0x11,
  84        MxL_5007_V1_F2     = 0x12,
  85        MxL_5007_V2_100_F1 = 0x21,
  86        MxL_5007_V2_100_F2 = 0x22,
  87        MxL_5007_V2_200_F1 = 0x23,
  88        MxL_5007_V2_200_F2 = 0x24,
  89};
  90
  91struct reg_pair_t {
  92        u8 reg;
  93        u8 val;
  94};
  95
  96/* ------------------------------------------------------------------------- */
  97
  98static struct reg_pair_t init_tab[] = {
  99        { 0x0b, 0x44 }, /* XTAL */
 100        { 0x0c, 0x60 }, /* IF */
 101        { 0x10, 0x00 }, /* MISC */
 102        { 0x12, 0xca }, /* IDAC */
 103        { 0x16, 0x90 }, /* MODE */
 104        { 0x32, 0x38 }, /* MODE Analog/Digital */
 105        { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
 106        { 0x2c, 0x34 }, /* OVERRIDE */
 107        { 0x4d, 0x40 }, /* OVERRIDE */
 108        { 0x7f, 0x02 }, /* OVERRIDE */
 109        { 0x9a, 0x52 }, /* OVERRIDE */
 110        { 0x48, 0x5a }, /* OVERRIDE */
 111        { 0x76, 0x1a }, /* OVERRIDE */
 112        { 0x6a, 0x48 }, /* OVERRIDE */
 113        { 0x64, 0x28 }, /* OVERRIDE */
 114        { 0x66, 0xe6 }, /* OVERRIDE */
 115        { 0x35, 0x0e }, /* OVERRIDE */
 116        { 0x7e, 0x01 }, /* OVERRIDE */
 117        { 0x83, 0x00 }, /* OVERRIDE */
 118        { 0x04, 0x0b }, /* OVERRIDE */
 119        { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
 120        { 0, 0 }
 121};
 122
 123static struct reg_pair_t init_tab_cable[] = {
 124        { 0x0b, 0x44 }, /* XTAL */
 125        { 0x0c, 0x60 }, /* IF */
 126        { 0x10, 0x00 }, /* MISC */
 127        { 0x12, 0xca }, /* IDAC */
 128        { 0x16, 0x90 }, /* MODE */
 129        { 0x32, 0x38 }, /* MODE A/D */
 130        { 0x71, 0x3f }, /* TOP1 */
 131        { 0x72, 0x3f }, /* TOP2 */
 132        { 0x74, 0x3f }, /* TOP3 */
 133        { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
 134        { 0x2c, 0x34 }, /* OVERRIDE */
 135        { 0x4d, 0x40 }, /* OVERRIDE */
 136        { 0x7f, 0x02 }, /* OVERRIDE */
 137        { 0x9a, 0x52 }, /* OVERRIDE */
 138        { 0x48, 0x5a }, /* OVERRIDE */
 139        { 0x76, 0x1a }, /* OVERRIDE */
 140        { 0x6a, 0x48 }, /* OVERRIDE */
 141        { 0x64, 0x28 }, /* OVERRIDE */
 142        { 0x66, 0xe6 }, /* OVERRIDE */
 143        { 0x35, 0x0e }, /* OVERRIDE */
 144        { 0x7e, 0x01 }, /* OVERRIDE */
 145        { 0x04, 0x0b }, /* OVERRIDE */
 146        { 0x68, 0xb4 }, /* OVERRIDE */
 147        { 0x36, 0x00 }, /* OVERRIDE */
 148        { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
 149        { 0, 0 }
 150};
 151
 152/* ------------------------------------------------------------------------- */
 153
 154static struct reg_pair_t reg_pair_rftune[] = {
 155        { 0x11, 0x00 }, /* abort tune */
 156        { 0x13, 0x15 },
 157        { 0x14, 0x40 },
 158        { 0x15, 0x0e },
 159        { 0x11, 0x02 }, /* start tune */
 160        { 0, 0 }
 161};
 162
 163/* ------------------------------------------------------------------------- */
 164
 165struct mxl5007t_state {
 166        struct list_head hybrid_tuner_instance_list;
 167        struct tuner_i2c_props i2c_props;
 168
 169        struct mutex lock;
 170
 171        struct mxl5007t_config *config;
 172
 173        enum mxl5007t_chip_version chip_id;
 174
 175        struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)];
 176        struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
 177        struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
 178
 179        u32 frequency;
 180        u32 bandwidth;
 181};
 182
 183/* ------------------------------------------------------------------------- */
 184
 185/* called by _init and _rftun to manipulate the register arrays */
 186
 187static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val)
 188{
 189        unsigned int i = 0;
 190
 191        while (reg_pair[i].reg || reg_pair[i].val) {
 192                if (reg_pair[i].reg == reg) {
 193                        reg_pair[i].val &= ~mask;
 194                        reg_pair[i].val |= val;
 195                }
 196                i++;
 197
 198        }
 199        return;
 200}
 201
 202static void copy_reg_bits(struct reg_pair_t *reg_pair1,
 203                          struct reg_pair_t *reg_pair2)
 204{
 205        unsigned int i, j;
 206
 207        i = j = 0;
 208
 209        while (reg_pair1[i].reg || reg_pair1[i].val) {
 210                while (reg_pair2[j].reg || reg_pair2[j].reg) {
 211                        if (reg_pair1[i].reg != reg_pair2[j].reg) {
 212                                j++;
 213                                continue;
 214                        }
 215                        reg_pair2[j].val = reg_pair1[i].val;
 216                        break;
 217                }
 218                i++;
 219        }
 220        return;
 221}
 222
 223/* ------------------------------------------------------------------------- */
 224
 225static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
 226                                   enum mxl5007t_mode mode,
 227                                   s32 if_diff_out_level)
 228{
 229        switch (mode) {
 230        case MxL_MODE_OTA_DVBT_ATSC:
 231                set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
 232                set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e);
 233                break;
 234        case MxL_MODE_OTA_ISDBT:
 235                set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
 236                set_reg_bits(state->tab_init, 0x35, 0xff, 0x12);
 237                break;
 238        case MxL_MODE_OTA_NTSC_PAL_GH:
 239                set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
 240                set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
 241                break;
 242        case MxL_MODE_OTA_PAL_IB:
 243                set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
 244                set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
 245                break;
 246        case MxL_MODE_OTA_PAL_D_SECAM_KL:
 247                set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
 248                set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
 249                break;
 250        case MxL_MODE_CABLE_DIGITAL:
 251                set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
 252                set_reg_bits(state->tab_init_cable, 0x72, 0xff,
 253                             8 - if_diff_out_level);
 254                set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
 255                break;
 256        case MxL_MODE_CABLE_NTSC_PAL_GH:
 257                set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
 258                set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
 259                set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
 260                set_reg_bits(state->tab_init_cable, 0x72, 0xff,
 261                             8 - if_diff_out_level);
 262                set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
 263                break;
 264        case MxL_MODE_CABLE_PAL_IB:
 265                set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
 266                set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
 267                set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
 268                set_reg_bits(state->tab_init_cable, 0x72, 0xff,
 269                             8 - if_diff_out_level);
 270                set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
 271                break;
 272        case MxL_MODE_CABLE_PAL_D_SECAM_KL:
 273                set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
 274                set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
 275                set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
 276                set_reg_bits(state->tab_init_cable, 0x72, 0xff,
 277                             8 - if_diff_out_level);
 278                set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
 279                break;
 280        case MxL_MODE_CABLE_SCTE40:
 281                set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08);
 282                set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc);
 283                set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
 284                set_reg_bits(state->tab_init_cable, 0x72, 0xff,
 285                             8 - if_diff_out_level);
 286                set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
 287                break;
 288        default:
 289                mxl_fail(-EINVAL);
 290        }
 291        return;
 292}
 293
 294static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
 295                                      enum mxl5007t_if_freq if_freq,
 296                                      int invert_if)
 297{
 298        u8 val;
 299
 300        switch (if_freq) {
 301        case MxL_IF_4_MHZ:
 302                val = 0x00;
 303                break;
 304        case MxL_IF_4_5_MHZ:
 305                val = 0x20;
 306                break;
 307        case MxL_IF_4_57_MHZ:
 308                val = 0x30;
 309                break;
 310        case MxL_IF_5_MHZ:
 311                val = 0x40;
 312                break;
 313        case MxL_IF_5_38_MHZ:
 314                val = 0x50;
 315                break;
 316        case MxL_IF_6_MHZ:
 317                val = 0x60;
 318                break;
 319        case MxL_IF_6_28_MHZ:
 320                val = 0x70;
 321                break;
 322        case MxL_IF_9_1915_MHZ:
 323                val = 0x80;
 324                break;
 325        case MxL_IF_35_25_MHZ:
 326                val = 0x90;
 327                break;
 328        case MxL_IF_36_15_MHZ:
 329                val = 0xa0;
 330                break;
 331        case MxL_IF_44_MHZ:
 332                val = 0xb0;
 333                break;
 334        default:
 335                mxl_fail(-EINVAL);
 336                return;
 337        }
 338        set_reg_bits(state->tab_init, 0x0c, 0xf0, val);
 339
 340        /* set inverted IF or normal IF */
 341        set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00);
 342
 343        return;
 344}
 345
 346static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
 347                                        enum mxl5007t_xtal_freq xtal_freq)
 348{
 349        u8 val;
 350
 351        switch (xtal_freq) {
 352        case MxL_XTAL_16_MHZ:
 353                val = 0x00; /* select xtal freq & Ref Freq */
 354                break;
 355        case MxL_XTAL_20_MHZ:
 356                val = 0x11;
 357                break;
 358        case MxL_XTAL_20_25_MHZ:
 359                val = 0x22;
 360                break;
 361        case MxL_XTAL_20_48_MHZ:
 362                val = 0x33;
 363                break;
 364        case MxL_XTAL_24_MHZ:
 365                val = 0x44;
 366                break;
 367        case MxL_XTAL_25_MHZ:
 368                val = 0x55;
 369                break;
 370        case MxL_XTAL_25_14_MHZ:
 371                val = 0x66;
 372                break;
 373        case MxL_XTAL_27_MHZ:
 374                val = 0x77;
 375                break;
 376        case MxL_XTAL_28_8_MHZ:
 377                val = 0x88;
 378                break;
 379        case MxL_XTAL_32_MHZ:
 380                val = 0x99;
 381                break;
 382        case MxL_XTAL_40_MHZ:
 383                val = 0xaa;
 384                break;
 385        case MxL_XTAL_44_MHZ:
 386                val = 0xbb;
 387                break;
 388        case MxL_XTAL_48_MHZ:
 389                val = 0xcc;
 390                break;
 391        case MxL_XTAL_49_3811_MHZ:
 392                val = 0xdd;
 393                break;
 394        default:
 395                mxl_fail(-EINVAL);
 396                return;
 397        }
 398        set_reg_bits(state->tab_init, 0x0b, 0xff, val);
 399
 400        return;
 401}
 402
 403static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
 404                                                  enum mxl5007t_mode mode)
 405{
 406        struct mxl5007t_config *cfg = state->config;
 407
 408        memcpy(&state->tab_init, &init_tab, sizeof(init_tab));
 409        memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable));
 410
 411        mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level);
 412        mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
 413        mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
 414
 415        set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6);
 416
 417        set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3);
 418
 419        set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp);
 420
 421        /* set IDAC to automatic mode control by AGC */
 422        set_reg_bits(state->tab_init, 0x12, 0x80, 0x00);
 423
 424        if (mode >= MxL_MODE_CABLE_DIGITAL) {
 425                copy_reg_bits(state->tab_init, state->tab_init_cable);
 426                return state->tab_init_cable;
 427        } else
 428                return state->tab_init;
 429}
 430
 431/* ------------------------------------------------------------------------- */
 432
 433enum mxl5007t_bw_mhz {
 434        MxL_BW_6MHz = 6,
 435        MxL_BW_7MHz = 7,
 436        MxL_BW_8MHz = 8,
 437};
 438
 439static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
 440                                 enum mxl5007t_bw_mhz bw)
 441{
 442        u8 val;
 443
 444        switch (bw) {
 445        case MxL_BW_6MHz:
 446                val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A,
 447                             * and DIG_MODEINDEX_CSF */
 448                break;
 449        case MxL_BW_7MHz:
 450                val = 0x21;
 451                break;
 452        case MxL_BW_8MHz:
 453                val = 0x3f;
 454                break;
 455        default:
 456                mxl_fail(-EINVAL);
 457                return;
 458        }
 459        set_reg_bits(state->tab_rftune, 0x13, 0x3f, val);
 460
 461        return;
 462}
 463
 464static struct
 465reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
 466                                       u32 rf_freq, enum mxl5007t_bw_mhz bw)
 467{
 468        u32 dig_rf_freq = 0;
 469        u32 temp;
 470        u32 frac_divider = 1000000;
 471        unsigned int i;
 472
 473        memcpy(&state->tab_rftune, &reg_pair_rftune, sizeof(reg_pair_rftune));
 474
 475        mxl5007t_set_bw_bits(state, bw);
 476
 477        /* Convert RF frequency into 16 bits =>
 478         * 10 bit integer (MHz) + 6 bit fraction */
 479        dig_rf_freq = rf_freq / MHz;
 480
 481        temp = rf_freq % MHz;
 482
 483        for (i = 0; i < 6; i++) {
 484                dig_rf_freq <<= 1;
 485                frac_divider /= 2;
 486                if (temp > frac_divider) {
 487                        temp -= frac_divider;
 488                        dig_rf_freq++;
 489                }
 490        }
 491
 492        /* add to have shift center point by 7.8124 kHz */
 493        if (temp > 7812)
 494                dig_rf_freq++;
 495
 496        set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq);
 497        set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8));
 498
 499        return state->tab_rftune;
 500}
 501
 502/* ------------------------------------------------------------------------- */
 503
 504static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val)
 505{
 506        u8 buf[] = { reg, val };
 507        struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
 508                               .buf = buf, .len = 2 };
 509        int ret;
 510
 511        ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
 512        if (ret != 1) {
 513                mxl_err("failed!");
 514                return -EREMOTEIO;
 515        }
 516        return 0;
 517}
 518
 519static int mxl5007t_write_regs(struct mxl5007t_state *state,
 520                               struct reg_pair_t *reg_pair)
 521{
 522        unsigned int i = 0;
 523        int ret = 0;
 524
 525        while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) {
 526                ret = mxl5007t_write_reg(state,
 527                                         reg_pair[i].reg, reg_pair[i].val);
 528                i++;
 529        }
 530        return ret;
 531}
 532
 533static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
 534{
 535        struct i2c_msg msg[] = {
 536                { .addr = state->i2c_props.addr, .flags = 0,
 537                  .buf = &reg, .len = 1 },
 538                { .addr = state->i2c_props.addr, .flags = I2C_M_RD,
 539                  .buf = val, .len = 1 },
 540        };
 541        int ret;
 542
 543        ret = i2c_transfer(state->i2c_props.adap, msg, 2);
 544        if (ret != 2) {
 545                mxl_err("failed!");
 546                return -EREMOTEIO;
 547        }
 548        return 0;
 549}
 550
 551static int mxl5007t_soft_reset(struct mxl5007t_state *state)
 552{
 553        u8 d = 0xff;
 554        struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
 555                               .buf = &d, .len = 1 };
 556
 557        int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
 558
 559        if (ret != 1) {
 560                mxl_err("failed!");
 561                return -EREMOTEIO;
 562        }
 563        return 0;
 564}
 565
 566static int mxl5007t_tuner_init(struct mxl5007t_state *state,
 567                               enum mxl5007t_mode mode)
 568{
 569        struct reg_pair_t *init_regs;
 570        int ret;
 571
 572        ret = mxl5007t_soft_reset(state);
 573        if (mxl_fail(ret))
 574                goto fail;
 575
 576        /* calculate initialization reg array */
 577        init_regs = mxl5007t_calc_init_regs(state, mode);
 578
 579        ret = mxl5007t_write_regs(state, init_regs);
 580        if (mxl_fail(ret))
 581                goto fail;
 582        mdelay(1);
 583
 584        ret = mxl5007t_write_reg(state, 0x2c, 0x35);
 585        mxl_fail(ret);
 586fail:
 587        return ret;
 588}
 589
 590static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz,
 591                                  enum mxl5007t_bw_mhz bw)
 592{
 593        struct reg_pair_t *rf_tune_regs;
 594        int ret;
 595
 596        /* calculate channel change reg array */
 597        rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw);
 598
 599        ret = mxl5007t_write_regs(state, rf_tune_regs);
 600        if (mxl_fail(ret))
 601                goto fail;
 602        msleep(3);
 603fail:
 604        return ret;
 605}
 606
 607/* ------------------------------------------------------------------------- */
 608
 609static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
 610                                      int *rf_locked, int *ref_locked)
 611{
 612        u8 d;
 613        int ret;
 614
 615        *rf_locked = 0;
 616        *ref_locked = 0;
 617
 618        ret = mxl5007t_read_reg(state, 0xcf, &d);
 619        if (mxl_fail(ret))
 620                goto fail;
 621
 622        if ((d & 0x0c) == 0x0c)
 623                *rf_locked = 1;
 624
 625        if ((d & 0x03) == 0x03)
 626                *ref_locked = 1;
 627fail:
 628        return ret;
 629}
 630
 631static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state,
 632                                         s32 *rf_input_level)
 633{
 634        u8 d1, d2;
 635        int ret;
 636
 637        ret = mxl5007t_read_reg(state, 0xb7, &d1);
 638        if (mxl_fail(ret))
 639                goto fail;
 640
 641        ret = mxl5007t_read_reg(state, 0xbf, &d2);
 642        if (mxl_fail(ret))
 643                goto fail;
 644
 645        d2 = d2 >> 4;
 646        if (d2 > 7)
 647                d2 += 0xf0;
 648
 649        *rf_input_level = (s32)(d1 + d2 - 113);
 650fail:
 651        return ret;
 652}
 653
 654/* ------------------------------------------------------------------------- */
 655
 656static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
 657{
 658        struct mxl5007t_state *state = fe->tuner_priv;
 659        int rf_locked, ref_locked;
 660        s32 rf_input_level;
 661        int ret;
 662
 663        if (fe->ops.i2c_gate_ctrl)
 664                fe->ops.i2c_gate_ctrl(fe, 1);
 665
 666        ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked);
 667        if (mxl_fail(ret))
 668                goto fail;
 669        mxl_debug("%s%s", rf_locked ? "rf locked " : "",
 670                  ref_locked ? "ref locked" : "");
 671
 672        ret = mxl5007t_check_rf_input_power(state, &rf_input_level);
 673        if (mxl_fail(ret))
 674                goto fail;
 675        mxl_debug("rf input power: %d", rf_input_level);
 676fail:
 677        if (fe->ops.i2c_gate_ctrl)
 678                fe->ops.i2c_gate_ctrl(fe, 0);
 679
 680        return ret;
 681}
 682
 683/* ------------------------------------------------------------------------- */
 684
 685static int mxl5007t_set_params(struct dvb_frontend *fe,
 686                               struct dvb_frontend_parameters *params)
 687{
 688        struct mxl5007t_state *state = fe->tuner_priv;
 689        enum mxl5007t_bw_mhz bw;
 690        enum mxl5007t_mode mode;
 691        int ret;
 692        u32 freq = params->frequency;
 693
 694        if (fe->ops.info.type == FE_ATSC) {
 695                switch (params->u.vsb.modulation) {
 696                case VSB_8:
 697                case VSB_16:
 698                        mode = MxL_MODE_OTA_DVBT_ATSC;
 699                        break;
 700                case QAM_64:
 701                case QAM_256:
 702                        mode = MxL_MODE_CABLE_DIGITAL;
 703                        break;
 704                default:
 705                        mxl_err("modulation not set!");
 706                        return -EINVAL;
 707                }
 708                bw = MxL_BW_6MHz;
 709        } else if (fe->ops.info.type == FE_OFDM) {
 710                switch (params->u.ofdm.bandwidth) {
 711                case BANDWIDTH_6_MHZ:
 712                        bw = MxL_BW_6MHz;
 713                        break;
 714                case BANDWIDTH_7_MHZ:
 715                        bw = MxL_BW_7MHz;
 716                        break;
 717                case BANDWIDTH_8_MHZ:
 718                        bw = MxL_BW_8MHz;
 719                        break;
 720                default:
 721                        mxl_err("bandwidth not set!");
 722                        return -EINVAL;
 723                }
 724                mode = MxL_MODE_OTA_DVBT_ATSC;
 725        } else {
 726                mxl_err("modulation type not supported!");
 727                return -EINVAL;
 728        }
 729
 730        if (fe->ops.i2c_gate_ctrl)
 731                fe->ops.i2c_gate_ctrl(fe, 1);
 732
 733        mutex_lock(&state->lock);
 734
 735        ret = mxl5007t_tuner_init(state, mode);
 736        if (mxl_fail(ret))
 737                goto fail;
 738
 739        ret = mxl5007t_tuner_rf_tune(state, freq, bw);
 740        if (mxl_fail(ret))
 741                goto fail;
 742
 743        state->frequency = freq;
 744        state->bandwidth = (fe->ops.info.type == FE_OFDM) ?
 745                params->u.ofdm.bandwidth : 0;
 746fail:
 747        mutex_unlock(&state->lock);
 748
 749        if (fe->ops.i2c_gate_ctrl)
 750                fe->ops.i2c_gate_ctrl(fe, 0);
 751
 752        return ret;
 753}
 754
 755static int mxl5007t_set_analog_params(struct dvb_frontend *fe,
 756                                      struct analog_parameters *params)
 757{
 758        struct mxl5007t_state *state = fe->tuner_priv;
 759        enum mxl5007t_bw_mhz bw = 0; /* FIXME */
 760        enum mxl5007t_mode cbl_mode;
 761        enum mxl5007t_mode ota_mode;
 762        char *mode_name;
 763        int ret;
 764        u32 freq = params->frequency * 62500;
 765
 766#define cable 1
 767        if (params->std & V4L2_STD_MN) {
 768                cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
 769                ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
 770                mode_name = "MN";
 771        } else if (params->std & V4L2_STD_B) {
 772                cbl_mode = MxL_MODE_CABLE_PAL_IB;
 773                ota_mode = MxL_MODE_OTA_PAL_IB;
 774                mode_name = "B";
 775        } else if (params->std & V4L2_STD_GH) {
 776                cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
 777                ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
 778                mode_name = "GH";
 779        } else if (params->std & V4L2_STD_PAL_I) {
 780                cbl_mode = MxL_MODE_CABLE_PAL_IB;
 781                ota_mode = MxL_MODE_OTA_PAL_IB;
 782                mode_name = "I";
 783        } else if (params->std & V4L2_STD_DK) {
 784                cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
 785                ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
 786                mode_name = "DK";
 787        } else if (params->std & V4L2_STD_SECAM_L) {
 788                cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
 789                ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
 790                mode_name = "L";
 791        } else if (params->std & V4L2_STD_SECAM_LC) {
 792                cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
 793                ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
 794                mode_name = "L'";
 795        } else {
 796                mode_name = "xx";
 797                /* FIXME */
 798                cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
 799                ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
 800        }
 801        mxl_debug("setting mxl5007 to system %s", mode_name);
 802
 803        if (fe->ops.i2c_gate_ctrl)
 804                fe->ops.i2c_gate_ctrl(fe, 1);
 805
 806        mutex_lock(&state->lock);
 807
 808        ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode);
 809        if (mxl_fail(ret))
 810                goto fail;
 811
 812        ret = mxl5007t_tuner_rf_tune(state, freq, bw);
 813        if (mxl_fail(ret))
 814                goto fail;
 815
 816        state->frequency = freq;
 817        state->bandwidth = 0;
 818fail:
 819        mutex_unlock(&state->lock);
 820
 821        if (fe->ops.i2c_gate_ctrl)
 822                fe->ops.i2c_gate_ctrl(fe, 0);
 823
 824        return ret;
 825}
 826
 827/* ------------------------------------------------------------------------- */
 828
 829static int mxl5007t_init(struct dvb_frontend *fe)
 830{
 831        struct mxl5007t_state *state = fe->tuner_priv;
 832        int ret;
 833        u8 d;
 834
 835        if (fe->ops.i2c_gate_ctrl)
 836                fe->ops.i2c_gate_ctrl(fe, 1);
 837
 838        ret = mxl5007t_read_reg(state, 0x05, &d);
 839        if (mxl_fail(ret))
 840                goto fail;
 841
 842        ret = mxl5007t_write_reg(state, 0x05, d | 0x01);
 843        mxl_fail(ret);
 844fail:
 845        if (fe->ops.i2c_gate_ctrl)
 846                fe->ops.i2c_gate_ctrl(fe, 0);
 847
 848        return ret;
 849}
 850
 851static int mxl5007t_sleep(struct dvb_frontend *fe)
 852{
 853        struct mxl5007t_state *state = fe->tuner_priv;
 854        int ret;
 855        u8 d;
 856
 857        if (fe->ops.i2c_gate_ctrl)
 858                fe->ops.i2c_gate_ctrl(fe, 1);
 859
 860        ret = mxl5007t_read_reg(state, 0x05, &d);
 861        if (mxl_fail(ret))
 862                goto fail;
 863
 864        ret = mxl5007t_write_reg(state, 0x05, d & ~0x01);
 865        mxl_fail(ret);
 866fail:
 867        if (fe->ops.i2c_gate_ctrl)
 868                fe->ops.i2c_gate_ctrl(fe, 0);
 869
 870        return ret;
 871}
 872
 873/* ------------------------------------------------------------------------- */
 874
 875static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
 876{
 877        struct mxl5007t_state *state = fe->tuner_priv;
 878        *frequency = state->frequency;
 879        return 0;
 880}
 881
 882static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
 883{
 884        struct mxl5007t_state *state = fe->tuner_priv;
 885        *bandwidth = state->bandwidth;
 886        return 0;
 887}
 888
 889static int mxl5007t_release(struct dvb_frontend *fe)
 890{
 891        struct mxl5007t_state *state = fe->tuner_priv;
 892
 893        mutex_lock(&mxl5007t_list_mutex);
 894
 895        if (state)
 896                hybrid_tuner_release_state(state);
 897
 898        mutex_unlock(&mxl5007t_list_mutex);
 899
 900        fe->tuner_priv = NULL;
 901
 902        return 0;
 903}
 904
 905/* ------------------------------------------------------------------------- */
 906
 907static struct dvb_tuner_ops mxl5007t_tuner_ops = {
 908        .info = {
 909                .name = "MaxLinear MxL5007T",
 910        },
 911        .init              = mxl5007t_init,
 912        .sleep             = mxl5007t_sleep,
 913        .set_params        = mxl5007t_set_params,
 914        .set_analog_params = mxl5007t_set_analog_params,
 915        .get_status        = mxl5007t_get_status,
 916        .get_frequency     = mxl5007t_get_frequency,
 917        .get_bandwidth     = mxl5007t_get_bandwidth,
 918        .release           = mxl5007t_release,
 919};
 920
 921static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
 922{
 923        char *name;
 924        int ret;
 925        u8 id;
 926
 927        ret = mxl5007t_read_reg(state, 0xd3, &id);
 928        if (mxl_fail(ret))
 929                goto fail;
 930
 931        switch (id) {
 932        case MxL_5007_V1_F1:
 933                name = "MxL5007.v1.f1";
 934                break;
 935        case MxL_5007_V1_F2:
 936                name = "MxL5007.v1.f2";
 937                break;
 938        case MxL_5007_V2_100_F1:
 939                name = "MxL5007.v2.100.f1";
 940                break;
 941        case MxL_5007_V2_100_F2:
 942                name = "MxL5007.v2.100.f2";
 943                break;
 944        case MxL_5007_V2_200_F1:
 945                name = "MxL5007.v2.200.f1";
 946                break;
 947        case MxL_5007_V2_200_F2:
 948                name = "MxL5007.v2.200.f2";
 949                break;
 950        default:
 951                name = "MxL5007T";
 952                id = MxL_UNKNOWN_ID;
 953        }
 954        state->chip_id = id;
 955        mxl_info("%s detected @ %d-%04x", name,
 956                 i2c_adapter_id(state->i2c_props.adap),
 957                 state->i2c_props.addr);
 958        return 0;
 959fail:
 960        mxl_warn("unable to identify device @ %d-%04x",
 961                 i2c_adapter_id(state->i2c_props.adap),
 962                 state->i2c_props.addr);
 963
 964        state->chip_id = MxL_UNKNOWN_ID;
 965        return ret;
 966}
 967
 968struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
 969                                     struct i2c_adapter *i2c, u8 addr,
 970                                     struct mxl5007t_config *cfg)
 971{
 972        struct mxl5007t_state *state = NULL;
 973        int instance, ret;
 974
 975        mutex_lock(&mxl5007t_list_mutex);
 976        instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
 977                                              hybrid_tuner_instance_list,
 978                                              i2c, addr, "mxl5007");
 979        switch (instance) {
 980        case 0:
 981                goto fail;
 982        case 1:
 983                /* new tuner instance */
 984                state->config = cfg;
 985
 986                mutex_init(&state->lock);
 987
 988                if (fe->ops.i2c_gate_ctrl)
 989                        fe->ops.i2c_gate_ctrl(fe, 1);
 990
 991                ret = mxl5007t_get_chip_id(state);
 992
 993                if (fe->ops.i2c_gate_ctrl)
 994                        fe->ops.i2c_gate_ctrl(fe, 0);
 995
 996                /* check return value of mxl5007t_get_chip_id */
 997                if (mxl_fail(ret))
 998                        goto fail;
 999                break;
1000        default:
1001                /* existing tuner instance */
1002                break;
1003        }
1004        fe->tuner_priv = state;
1005        mutex_unlock(&mxl5007t_list_mutex);
1006
1007        memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops,
1008               sizeof(struct dvb_tuner_ops));
1009
1010        return fe;
1011fail:
1012        mutex_unlock(&mxl5007t_list_mutex);
1013
1014        mxl5007t_release(fe);
1015        return NULL;
1016}
1017EXPORT_SYMBOL_GPL(mxl5007t_attach);
1018MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
1019MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1020MODULE_LICENSE("GPL");
1021MODULE_VERSION("0.1");
1022
1023/*
1024 * Overrides for Emacs so that we follow Linus's tabbing style.
1025 * ---------------------------------------------------------------------------
1026 * Local variables:
1027 * c-basic-offset: 8
1028 * End:
1029 */