0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/i2c.h>
0009 #include <linux/types.h>
0010 #include <linux/videodev2.h>
0011 #include "tuner-i2c.h"
0012 #include "mxl5007t.h"
0013
0014 static DEFINE_MUTEX(mxl5007t_list_mutex);
0015 static LIST_HEAD(hybrid_tuner_instance_list);
0016
0017 static int mxl5007t_debug;
0018 module_param_named(debug, mxl5007t_debug, int, 0644);
0019 MODULE_PARM_DESC(debug, "set debug level");
0020
0021
0022
0023 #define mxl_printk(kern, fmt, arg...) \
0024 printk(kern "%s: " fmt "\n", __func__, ##arg)
0025
0026 #define mxl_err(fmt, arg...) \
0027 mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg)
0028
0029 #define mxl_warn(fmt, arg...) \
0030 mxl_printk(KERN_WARNING, fmt, ##arg)
0031
0032 #define mxl_info(fmt, arg...) \
0033 mxl_printk(KERN_INFO, fmt, ##arg)
0034
0035 #define mxl_debug(fmt, arg...) \
0036 ({ \
0037 if (mxl5007t_debug) \
0038 mxl_printk(KERN_DEBUG, fmt, ##arg); \
0039 })
0040
0041 #define mxl_fail(ret) \
0042 ({ \
0043 int __ret; \
0044 __ret = (ret < 0); \
0045 if (__ret) \
0046 mxl_printk(KERN_ERR, "error %d on line %d", \
0047 ret, __LINE__); \
0048 __ret; \
0049 })
0050
0051
0052
0053 enum mxl5007t_mode {
0054 MxL_MODE_ISDBT = 0,
0055 MxL_MODE_DVBT = 1,
0056 MxL_MODE_ATSC = 2,
0057 MxL_MODE_CABLE = 0x10,
0058 };
0059
0060 enum mxl5007t_chip_version {
0061 MxL_UNKNOWN_ID = 0x00,
0062 MxL_5007_V1_F1 = 0x11,
0063 MxL_5007_V1_F2 = 0x12,
0064 MxL_5007_V4 = 0x14,
0065 MxL_5007_V2_100_F1 = 0x21,
0066 MxL_5007_V2_100_F2 = 0x22,
0067 MxL_5007_V2_200_F1 = 0x23,
0068 MxL_5007_V2_200_F2 = 0x24,
0069 };
0070
0071 struct reg_pair_t {
0072 u8 reg;
0073 u8 val;
0074 };
0075
0076
0077
0078 static struct reg_pair_t init_tab[] = {
0079 { 0x02, 0x06 },
0080 { 0x03, 0x48 },
0081 { 0x05, 0x04 },
0082 { 0x06, 0x10 },
0083 { 0x2e, 0x15 },
0084 { 0x30, 0x10 },
0085 { 0x45, 0x58 },
0086 { 0x48, 0x19 },
0087 { 0x52, 0x03 },
0088 { 0x53, 0x44 },
0089 { 0x6a, 0x4b },
0090 { 0x76, 0x00 },
0091 { 0x78, 0x18 },
0092 { 0x7a, 0x17 },
0093 { 0x85, 0x06 },
0094 { 0x01, 0x01 },
0095 { 0, 0 }
0096 };
0097
0098 static struct reg_pair_t init_tab_cable[] = {
0099 { 0x02, 0x06 },
0100 { 0x03, 0x48 },
0101 { 0x05, 0x04 },
0102 { 0x06, 0x10 },
0103 { 0x09, 0x3f },
0104 { 0x0a, 0x3f },
0105 { 0x0b, 0x3f },
0106 { 0x2e, 0x15 },
0107 { 0x30, 0x10 },
0108 { 0x45, 0x58 },
0109 { 0x48, 0x19 },
0110 { 0x52, 0x03 },
0111 { 0x53, 0x44 },
0112 { 0x6a, 0x4b },
0113 { 0x76, 0x00 },
0114 { 0x78, 0x18 },
0115 { 0x7a, 0x17 },
0116 { 0x85, 0x06 },
0117 { 0x01, 0x01 },
0118 { 0, 0 }
0119 };
0120
0121
0122
0123 static struct reg_pair_t reg_pair_rftune[] = {
0124 { 0x0f, 0x00 },
0125 { 0x0c, 0x15 },
0126 { 0x0d, 0x40 },
0127 { 0x0e, 0x0e },
0128 { 0x1f, 0x87 },
0129 { 0x20, 0x1f },
0130 { 0x21, 0x87 },
0131 { 0x22, 0x1f },
0132 { 0x80, 0x01 },
0133 { 0x0f, 0x01 },
0134 { 0, 0 }
0135 };
0136
0137
0138
0139 struct mxl5007t_state {
0140 struct list_head hybrid_tuner_instance_list;
0141 struct tuner_i2c_props i2c_props;
0142
0143 struct mutex lock;
0144
0145 struct mxl5007t_config *config;
0146
0147 enum mxl5007t_chip_version chip_id;
0148
0149 struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)];
0150 struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
0151 struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
0152
0153 enum mxl5007t_if_freq if_freq;
0154
0155 u32 frequency;
0156 u32 bandwidth;
0157 };
0158
0159
0160
0161
0162
0163 static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val)
0164 {
0165 unsigned int i = 0;
0166
0167 while (reg_pair[i].reg || reg_pair[i].val) {
0168 if (reg_pair[i].reg == reg) {
0169 reg_pair[i].val &= ~mask;
0170 reg_pair[i].val |= val;
0171 }
0172 i++;
0173
0174 }
0175 }
0176
0177 static void copy_reg_bits(struct reg_pair_t *reg_pair1,
0178 struct reg_pair_t *reg_pair2)
0179 {
0180 unsigned int i, j;
0181
0182 i = j = 0;
0183
0184 while (reg_pair1[i].reg || reg_pair1[i].val) {
0185 while (reg_pair2[j].reg || reg_pair2[j].val) {
0186 if (reg_pair1[i].reg != reg_pair2[j].reg) {
0187 j++;
0188 continue;
0189 }
0190 reg_pair2[j].val = reg_pair1[i].val;
0191 break;
0192 }
0193 i++;
0194 }
0195 }
0196
0197
0198
0199 static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
0200 enum mxl5007t_mode mode,
0201 s32 if_diff_out_level)
0202 {
0203 switch (mode) {
0204 case MxL_MODE_ATSC:
0205 set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
0206 break;
0207 case MxL_MODE_DVBT:
0208 set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
0209 break;
0210 case MxL_MODE_ISDBT:
0211 set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
0212 break;
0213 case MxL_MODE_CABLE:
0214 set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
0215 set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
0216 8 - if_diff_out_level);
0217 set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
0218 break;
0219 default:
0220 mxl_fail(-EINVAL);
0221 }
0222 }
0223
0224 static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
0225 enum mxl5007t_if_freq if_freq,
0226 int invert_if)
0227 {
0228 u8 val;
0229
0230 switch (if_freq) {
0231 case MxL_IF_4_MHZ:
0232 val = 0x00;
0233 break;
0234 case MxL_IF_4_5_MHZ:
0235 val = 0x02;
0236 break;
0237 case MxL_IF_4_57_MHZ:
0238 val = 0x03;
0239 break;
0240 case MxL_IF_5_MHZ:
0241 val = 0x04;
0242 break;
0243 case MxL_IF_5_38_MHZ:
0244 val = 0x05;
0245 break;
0246 case MxL_IF_6_MHZ:
0247 val = 0x06;
0248 break;
0249 case MxL_IF_6_28_MHZ:
0250 val = 0x07;
0251 break;
0252 case MxL_IF_9_1915_MHZ:
0253 val = 0x08;
0254 break;
0255 case MxL_IF_35_25_MHZ:
0256 val = 0x09;
0257 break;
0258 case MxL_IF_36_15_MHZ:
0259 val = 0x0a;
0260 break;
0261 case MxL_IF_44_MHZ:
0262 val = 0x0b;
0263 break;
0264 default:
0265 mxl_fail(-EINVAL);
0266 return;
0267 }
0268 set_reg_bits(state->tab_init, 0x02, 0x0f, val);
0269
0270
0271 set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
0272
0273 state->if_freq = if_freq;
0274 }
0275
0276 static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
0277 enum mxl5007t_xtal_freq xtal_freq)
0278 {
0279 switch (xtal_freq) {
0280 case MxL_XTAL_16_MHZ:
0281
0282 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
0283 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
0284 break;
0285 case MxL_XTAL_20_MHZ:
0286 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
0287 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
0288 break;
0289 case MxL_XTAL_20_25_MHZ:
0290 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
0291 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
0292 break;
0293 case MxL_XTAL_20_48_MHZ:
0294 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
0295 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
0296 break;
0297 case MxL_XTAL_24_MHZ:
0298 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
0299 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
0300 break;
0301 case MxL_XTAL_25_MHZ:
0302 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
0303 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
0304 break;
0305 case MxL_XTAL_25_14_MHZ:
0306 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
0307 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
0308 break;
0309 case MxL_XTAL_27_MHZ:
0310 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
0311 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
0312 break;
0313 case MxL_XTAL_28_8_MHZ:
0314 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
0315 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
0316 break;
0317 case MxL_XTAL_32_MHZ:
0318 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
0319 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
0320 break;
0321 case MxL_XTAL_40_MHZ:
0322 set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
0323 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
0324 break;
0325 case MxL_XTAL_44_MHZ:
0326 set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
0327 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
0328 break;
0329 case MxL_XTAL_48_MHZ:
0330 set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
0331 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
0332 break;
0333 case MxL_XTAL_49_3811_MHZ:
0334 set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
0335 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
0336 break;
0337 default:
0338 mxl_fail(-EINVAL);
0339 return;
0340 }
0341 }
0342
0343 static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
0344 enum mxl5007t_mode mode)
0345 {
0346 struct mxl5007t_config *cfg = state->config;
0347
0348 memcpy(&state->tab_init, &init_tab, sizeof(init_tab));
0349 memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable));
0350
0351 mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level);
0352 mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
0353 mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
0354
0355 set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
0356 set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
0357
0358 if (mode >= MxL_MODE_CABLE) {
0359 copy_reg_bits(state->tab_init, state->tab_init_cable);
0360 return state->tab_init_cable;
0361 } else
0362 return state->tab_init;
0363 }
0364
0365
0366
0367 enum mxl5007t_bw_mhz {
0368 MxL_BW_6MHz = 6,
0369 MxL_BW_7MHz = 7,
0370 MxL_BW_8MHz = 8,
0371 };
0372
0373 static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
0374 enum mxl5007t_bw_mhz bw)
0375 {
0376 u8 val;
0377
0378 switch (bw) {
0379 case MxL_BW_6MHz:
0380 val = 0x15;
0381
0382 break;
0383 case MxL_BW_7MHz:
0384 val = 0x2a;
0385 break;
0386 case MxL_BW_8MHz:
0387 val = 0x3f;
0388 break;
0389 default:
0390 mxl_fail(-EINVAL);
0391 return;
0392 }
0393 set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
0394 }
0395
0396 static struct
0397 reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
0398 u32 rf_freq, enum mxl5007t_bw_mhz bw)
0399 {
0400 u32 dig_rf_freq = 0;
0401 u32 temp;
0402 u32 frac_divider = 1000000;
0403 unsigned int i;
0404
0405 memcpy(&state->tab_rftune, ®_pair_rftune, sizeof(reg_pair_rftune));
0406
0407 mxl5007t_set_bw_bits(state, bw);
0408
0409
0410
0411 dig_rf_freq = rf_freq / MHz;
0412
0413 temp = rf_freq % MHz;
0414
0415 for (i = 0; i < 6; i++) {
0416 dig_rf_freq <<= 1;
0417 frac_divider /= 2;
0418 if (temp > frac_divider) {
0419 temp -= frac_divider;
0420 dig_rf_freq++;
0421 }
0422 }
0423
0424
0425 if (temp > 7812)
0426 dig_rf_freq++;
0427
0428 set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
0429 set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
0430
0431 if (rf_freq >= 333000000)
0432 set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
0433
0434 return state->tab_rftune;
0435 }
0436
0437
0438
0439 static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val)
0440 {
0441 u8 buf[] = { reg, val };
0442 struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
0443 .buf = buf, .len = 2 };
0444 int ret;
0445
0446 ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
0447 if (ret != 1) {
0448 mxl_err("failed!");
0449 return -EREMOTEIO;
0450 }
0451 return 0;
0452 }
0453
0454 static int mxl5007t_write_regs(struct mxl5007t_state *state,
0455 struct reg_pair_t *reg_pair)
0456 {
0457 unsigned int i = 0;
0458 int ret = 0;
0459
0460 while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) {
0461 ret = mxl5007t_write_reg(state,
0462 reg_pair[i].reg, reg_pair[i].val);
0463 i++;
0464 }
0465 return ret;
0466 }
0467
0468 static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
0469 {
0470 u8 buf[2] = { 0xfb, reg };
0471 struct i2c_msg msg[] = {
0472 { .addr = state->i2c_props.addr, .flags = 0,
0473 .buf = buf, .len = 2 },
0474 { .addr = state->i2c_props.addr, .flags = I2C_M_RD,
0475 .buf = val, .len = 1 },
0476 };
0477 int ret;
0478
0479 ret = i2c_transfer(state->i2c_props.adap, msg, 2);
0480 if (ret != 2) {
0481 mxl_err("failed!");
0482 return -EREMOTEIO;
0483 }
0484 return 0;
0485 }
0486
0487 static int mxl5007t_soft_reset(struct mxl5007t_state *state)
0488 {
0489 u8 d = 0xff;
0490 struct i2c_msg msg = {
0491 .addr = state->i2c_props.addr, .flags = 0,
0492 .buf = &d, .len = 1
0493 };
0494 int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
0495
0496 if (ret != 1) {
0497 mxl_err("failed!");
0498 return -EREMOTEIO;
0499 }
0500 return 0;
0501 }
0502
0503 static int mxl5007t_tuner_init(struct mxl5007t_state *state,
0504 enum mxl5007t_mode mode)
0505 {
0506 struct reg_pair_t *init_regs;
0507 int ret;
0508
0509
0510 init_regs = mxl5007t_calc_init_regs(state, mode);
0511
0512 ret = mxl5007t_write_regs(state, init_regs);
0513 if (mxl_fail(ret))
0514 goto fail;
0515 mdelay(1);
0516 fail:
0517 return ret;
0518 }
0519
0520 static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz,
0521 enum mxl5007t_bw_mhz bw)
0522 {
0523 struct reg_pair_t *rf_tune_regs;
0524 int ret;
0525
0526
0527 rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw);
0528
0529 ret = mxl5007t_write_regs(state, rf_tune_regs);
0530 if (mxl_fail(ret))
0531 goto fail;
0532 msleep(3);
0533 fail:
0534 return ret;
0535 }
0536
0537
0538
0539 static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
0540 int *rf_locked, int *ref_locked)
0541 {
0542 u8 d;
0543 int ret;
0544
0545 *rf_locked = 0;
0546 *ref_locked = 0;
0547
0548 ret = mxl5007t_read_reg(state, 0xd8, &d);
0549 if (mxl_fail(ret))
0550 goto fail;
0551
0552 if ((d & 0x0c) == 0x0c)
0553 *rf_locked = 1;
0554
0555 if ((d & 0x03) == 0x03)
0556 *ref_locked = 1;
0557 fail:
0558 return ret;
0559 }
0560
0561
0562
0563 static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
0564 {
0565 struct mxl5007t_state *state = fe->tuner_priv;
0566 int rf_locked, ref_locked, ret;
0567
0568 *status = 0;
0569
0570 if (fe->ops.i2c_gate_ctrl)
0571 fe->ops.i2c_gate_ctrl(fe, 1);
0572
0573 ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked);
0574 if (mxl_fail(ret))
0575 goto fail;
0576 mxl_debug("%s%s", rf_locked ? "rf locked " : "",
0577 ref_locked ? "ref locked" : "");
0578
0579 if ((rf_locked) || (ref_locked))
0580 *status |= TUNER_STATUS_LOCKED;
0581 fail:
0582 if (fe->ops.i2c_gate_ctrl)
0583 fe->ops.i2c_gate_ctrl(fe, 0);
0584
0585 return ret;
0586 }
0587
0588
0589
0590 static int mxl5007t_set_params(struct dvb_frontend *fe)
0591 {
0592 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0593 u32 delsys = c->delivery_system;
0594 struct mxl5007t_state *state = fe->tuner_priv;
0595 enum mxl5007t_bw_mhz bw;
0596 enum mxl5007t_mode mode;
0597 int ret;
0598 u32 freq = c->frequency;
0599
0600 switch (delsys) {
0601 case SYS_ATSC:
0602 mode = MxL_MODE_ATSC;
0603 bw = MxL_BW_6MHz;
0604 break;
0605 case SYS_DVBC_ANNEX_B:
0606 mode = MxL_MODE_CABLE;
0607 bw = MxL_BW_6MHz;
0608 break;
0609 case SYS_DVBT:
0610 case SYS_DVBT2:
0611 mode = MxL_MODE_DVBT;
0612 switch (c->bandwidth_hz) {
0613 case 6000000:
0614 bw = MxL_BW_6MHz;
0615 break;
0616 case 7000000:
0617 bw = MxL_BW_7MHz;
0618 break;
0619 case 8000000:
0620 bw = MxL_BW_8MHz;
0621 break;
0622 default:
0623 return -EINVAL;
0624 }
0625 break;
0626 default:
0627 mxl_err("modulation type not supported!");
0628 return -EINVAL;
0629 }
0630
0631 if (fe->ops.i2c_gate_ctrl)
0632 fe->ops.i2c_gate_ctrl(fe, 1);
0633
0634 mutex_lock(&state->lock);
0635
0636 ret = mxl5007t_tuner_init(state, mode);
0637 if (mxl_fail(ret))
0638 goto fail;
0639
0640 ret = mxl5007t_tuner_rf_tune(state, freq, bw);
0641 if (mxl_fail(ret))
0642 goto fail;
0643
0644 state->frequency = freq;
0645 state->bandwidth = c->bandwidth_hz;
0646 fail:
0647 mutex_unlock(&state->lock);
0648
0649 if (fe->ops.i2c_gate_ctrl)
0650 fe->ops.i2c_gate_ctrl(fe, 0);
0651
0652 return ret;
0653 }
0654
0655
0656
0657 static int mxl5007t_init(struct dvb_frontend *fe)
0658 {
0659 struct mxl5007t_state *state = fe->tuner_priv;
0660 int ret;
0661
0662 if (fe->ops.i2c_gate_ctrl)
0663 fe->ops.i2c_gate_ctrl(fe, 1);
0664
0665
0666 ret = mxl5007t_write_reg(state, 0x01, 0x01);
0667 mxl_fail(ret);
0668
0669 if (fe->ops.i2c_gate_ctrl)
0670 fe->ops.i2c_gate_ctrl(fe, 0);
0671
0672 return ret;
0673 }
0674
0675 static int mxl5007t_sleep(struct dvb_frontend *fe)
0676 {
0677 struct mxl5007t_state *state = fe->tuner_priv;
0678 int ret;
0679
0680 if (fe->ops.i2c_gate_ctrl)
0681 fe->ops.i2c_gate_ctrl(fe, 1);
0682
0683
0684 ret = mxl5007t_write_reg(state, 0x01, 0x00);
0685 mxl_fail(ret);
0686 ret = mxl5007t_write_reg(state, 0x0f, 0x00);
0687 mxl_fail(ret);
0688
0689 if (fe->ops.i2c_gate_ctrl)
0690 fe->ops.i2c_gate_ctrl(fe, 0);
0691
0692 return ret;
0693 }
0694
0695
0696
0697 static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0698 {
0699 struct mxl5007t_state *state = fe->tuner_priv;
0700 *frequency = state->frequency;
0701 return 0;
0702 }
0703
0704 static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
0705 {
0706 struct mxl5007t_state *state = fe->tuner_priv;
0707 *bandwidth = state->bandwidth;
0708 return 0;
0709 }
0710
0711 static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
0712 {
0713 struct mxl5007t_state *state = fe->tuner_priv;
0714
0715 *frequency = 0;
0716
0717 switch (state->if_freq) {
0718 case MxL_IF_4_MHZ:
0719 *frequency = 4000000;
0720 break;
0721 case MxL_IF_4_5_MHZ:
0722 *frequency = 4500000;
0723 break;
0724 case MxL_IF_4_57_MHZ:
0725 *frequency = 4570000;
0726 break;
0727 case MxL_IF_5_MHZ:
0728 *frequency = 5000000;
0729 break;
0730 case MxL_IF_5_38_MHZ:
0731 *frequency = 5380000;
0732 break;
0733 case MxL_IF_6_MHZ:
0734 *frequency = 6000000;
0735 break;
0736 case MxL_IF_6_28_MHZ:
0737 *frequency = 6280000;
0738 break;
0739 case MxL_IF_9_1915_MHZ:
0740 *frequency = 9191500;
0741 break;
0742 case MxL_IF_35_25_MHZ:
0743 *frequency = 35250000;
0744 break;
0745 case MxL_IF_36_15_MHZ:
0746 *frequency = 36150000;
0747 break;
0748 case MxL_IF_44_MHZ:
0749 *frequency = 44000000;
0750 break;
0751 }
0752 return 0;
0753 }
0754
0755 static void mxl5007t_release(struct dvb_frontend *fe)
0756 {
0757 struct mxl5007t_state *state = fe->tuner_priv;
0758
0759 mutex_lock(&mxl5007t_list_mutex);
0760
0761 if (state)
0762 hybrid_tuner_release_state(state);
0763
0764 mutex_unlock(&mxl5007t_list_mutex);
0765
0766 fe->tuner_priv = NULL;
0767 }
0768
0769
0770
0771 static const struct dvb_tuner_ops mxl5007t_tuner_ops = {
0772 .info = {
0773 .name = "MaxLinear MxL5007T",
0774 },
0775 .init = mxl5007t_init,
0776 .sleep = mxl5007t_sleep,
0777 .set_params = mxl5007t_set_params,
0778 .get_status = mxl5007t_get_status,
0779 .get_frequency = mxl5007t_get_frequency,
0780 .get_bandwidth = mxl5007t_get_bandwidth,
0781 .release = mxl5007t_release,
0782 .get_if_frequency = mxl5007t_get_if_frequency,
0783 };
0784
0785 static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
0786 {
0787 char *name;
0788 int ret;
0789 u8 id;
0790
0791 ret = mxl5007t_read_reg(state, 0xd9, &id);
0792 if (mxl_fail(ret))
0793 goto fail;
0794
0795 switch (id) {
0796 case MxL_5007_V1_F1:
0797 name = "MxL5007.v1.f1";
0798 break;
0799 case MxL_5007_V1_F2:
0800 name = "MxL5007.v1.f2";
0801 break;
0802 case MxL_5007_V2_100_F1:
0803 name = "MxL5007.v2.100.f1";
0804 break;
0805 case MxL_5007_V2_100_F2:
0806 name = "MxL5007.v2.100.f2";
0807 break;
0808 case MxL_5007_V2_200_F1:
0809 name = "MxL5007.v2.200.f1";
0810 break;
0811 case MxL_5007_V2_200_F2:
0812 name = "MxL5007.v2.200.f2";
0813 break;
0814 case MxL_5007_V4:
0815 name = "MxL5007T.v4";
0816 break;
0817 default:
0818 name = "MxL5007T";
0819 printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
0820 id = MxL_UNKNOWN_ID;
0821 }
0822 state->chip_id = id;
0823 mxl_info("%s detected @ %d-%04x", name,
0824 i2c_adapter_id(state->i2c_props.adap),
0825 state->i2c_props.addr);
0826 return 0;
0827 fail:
0828 mxl_warn("unable to identify device @ %d-%04x",
0829 i2c_adapter_id(state->i2c_props.adap),
0830 state->i2c_props.addr);
0831
0832 state->chip_id = MxL_UNKNOWN_ID;
0833 return ret;
0834 }
0835
0836 struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
0837 struct i2c_adapter *i2c, u8 addr,
0838 struct mxl5007t_config *cfg)
0839 {
0840 struct mxl5007t_state *state = NULL;
0841 int instance, ret;
0842
0843 mutex_lock(&mxl5007t_list_mutex);
0844 instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
0845 hybrid_tuner_instance_list,
0846 i2c, addr, "mxl5007t");
0847 switch (instance) {
0848 case 0:
0849 goto fail;
0850 case 1:
0851
0852 state->config = cfg;
0853
0854 mutex_init(&state->lock);
0855
0856 if (fe->ops.i2c_gate_ctrl)
0857 fe->ops.i2c_gate_ctrl(fe, 1);
0858
0859 ret = mxl5007t_get_chip_id(state);
0860
0861 if (fe->ops.i2c_gate_ctrl)
0862 fe->ops.i2c_gate_ctrl(fe, 0);
0863
0864
0865 if (mxl_fail(ret))
0866 goto fail;
0867 break;
0868 default:
0869
0870 break;
0871 }
0872
0873 if (fe->ops.i2c_gate_ctrl)
0874 fe->ops.i2c_gate_ctrl(fe, 1);
0875
0876 ret = mxl5007t_soft_reset(state);
0877
0878 if (fe->ops.i2c_gate_ctrl)
0879 fe->ops.i2c_gate_ctrl(fe, 0);
0880
0881 if (mxl_fail(ret))
0882 goto fail;
0883
0884 if (fe->ops.i2c_gate_ctrl)
0885 fe->ops.i2c_gate_ctrl(fe, 1);
0886
0887 ret = mxl5007t_write_reg(state, 0x04,
0888 state->config->loop_thru_enable);
0889
0890 if (fe->ops.i2c_gate_ctrl)
0891 fe->ops.i2c_gate_ctrl(fe, 0);
0892
0893 if (mxl_fail(ret))
0894 goto fail;
0895
0896 fe->tuner_priv = state;
0897
0898 mutex_unlock(&mxl5007t_list_mutex);
0899
0900 memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops,
0901 sizeof(struct dvb_tuner_ops));
0902
0903 return fe;
0904 fail:
0905 mutex_unlock(&mxl5007t_list_mutex);
0906
0907 mxl5007t_release(fe);
0908 return NULL;
0909 }
0910 EXPORT_SYMBOL_GPL(mxl5007t_attach);
0911 MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
0912 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
0913 MODULE_LICENSE("GPL");
0914 MODULE_VERSION("0.2");