root/drivers/media/tuners/mxl5007t.c

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

DEFINITIONS

This source file includes following definitions.
  1. set_reg_bits
  2. copy_reg_bits
  3. mxl5007t_set_mode_bits
  4. mxl5007t_set_if_freq_bits
  5. mxl5007t_set_xtal_freq_bits
  6. mxl5007t_calc_init_regs
  7. mxl5007t_set_bw_bits
  8. mxl5007t_calc_rf_tune_regs
  9. mxl5007t_write_reg
  10. mxl5007t_write_regs
  11. mxl5007t_read_reg
  12. mxl5007t_soft_reset
  13. mxl5007t_tuner_init
  14. mxl5007t_tuner_rf_tune
  15. mxl5007t_synth_lock_status
  16. mxl5007t_get_status
  17. mxl5007t_set_params
  18. mxl5007t_init
  19. mxl5007t_sleep
  20. mxl5007t_get_frequency
  21. mxl5007t_get_bandwidth
  22. mxl5007t_get_if_frequency
  23. mxl5007t_release
  24. mxl5007t_get_chip_id
  25. mxl5007t_attach

   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 
  14 static DEFINE_MUTEX(mxl5007t_list_mutex);
  15 static LIST_HEAD(hybrid_tuner_instance_list);
  16 
  17 static int mxl5007t_debug;
  18 module_param_named(debug, mxl5007t_debug, int, 0644);
  19 MODULE_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 
  53 enum mxl5007t_mode {
  54         MxL_MODE_ISDBT     =    0,
  55         MxL_MODE_DVBT      =    1,
  56         MxL_MODE_ATSC      =    2,
  57         MxL_MODE_CABLE     = 0x10,
  58 };
  59 
  60 enum 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 
  71 struct reg_pair_t {
  72         u8 reg;
  73         u8 val;
  74 };
  75 
  76 /* ------------------------------------------------------------------------- */
  77 
  78 static 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 
  98 static 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 
 123 static 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 
 139 struct 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 
 163 static 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 
 178 static 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 
 201 static 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 
 227 static 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 
 281 static 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 
 350 static 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 
 374 enum mxl5007t_bw_mhz {
 375         MxL_BW_6MHz = 6,
 376         MxL_BW_7MHz = 7,
 377         MxL_BW_8MHz = 8,
 378 };
 379 
 380 static 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 
 405 static struct
 406 reg_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 
 448 static 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 
 463 static 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 
 477 static 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 
 496 static 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 
 512 static 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);
 525 fail:
 526         return ret;
 527 }
 528 
 529 static 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);
 542 fail:
 543         return ret;
 544 }
 545 
 546 /* ------------------------------------------------------------------------- */
 547 
 548 static 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;
 566 fail:
 567         return ret;
 568 }
 569 
 570 /* ------------------------------------------------------------------------- */
 571 
 572 static 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;
 590 fail:
 591         if (fe->ops.i2c_gate_ctrl)
 592                 fe->ops.i2c_gate_ctrl(fe, 0);
 593 
 594         return ret;
 595 }
 596 
 597 /* ------------------------------------------------------------------------- */
 598 
 599 static 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;
 655 fail:
 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 
 666 static 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 
 684 static 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 
 706 static 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 
 713 static 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 
 720 static 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 
 764 static 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 
 780 static 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 
 794 static 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;
 836 fail:
 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 
 845 struct 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;
 913 fail:
 914         mutex_unlock(&mxl5007t_list_mutex);
 915 
 916         mxl5007t_release(fe);
 917         return NULL;
 918 }
 919 EXPORT_SYMBOL_GPL(mxl5007t_attach);
 920 MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
 921 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
 922 MODULE_LICENSE("GPL");
 923 MODULE_VERSION("0.2");

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