0001
0002
0003
0004
0005
0006
0007
0008 #include "mxl111sf-tuner.h"
0009 #include "mxl111sf-phy.h"
0010 #include "mxl111sf-reg.h"
0011
0012
0013 static int mxl111sf_tuner_debug;
0014 module_param_named(debug, mxl111sf_tuner_debug, int, 0644);
0015 MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
0016
0017 #define mxl_dbg(fmt, arg...) \
0018 if (mxl111sf_tuner_debug) \
0019 mxl_printk(KERN_DEBUG, fmt, ##arg)
0020
0021
0022
0023 struct mxl111sf_tuner_state {
0024 struct mxl111sf_state *mxl_state;
0025
0026 const struct mxl111sf_tuner_config *cfg;
0027
0028 enum mxl_if_freq if_freq;
0029
0030 u32 frequency;
0031 u32 bandwidth;
0032 };
0033
0034 static int mxl111sf_tuner_read_reg(struct mxl111sf_tuner_state *state,
0035 u8 addr, u8 *data)
0036 {
0037 return (state->cfg->read_reg) ?
0038 state->cfg->read_reg(state->mxl_state, addr, data) :
0039 -EINVAL;
0040 }
0041
0042 static int mxl111sf_tuner_write_reg(struct mxl111sf_tuner_state *state,
0043 u8 addr, u8 data)
0044 {
0045 return (state->cfg->write_reg) ?
0046 state->cfg->write_reg(state->mxl_state, addr, data) :
0047 -EINVAL;
0048 }
0049
0050 static int mxl111sf_tuner_program_regs(struct mxl111sf_tuner_state *state,
0051 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
0052 {
0053 return (state->cfg->program_regs) ?
0054 state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
0055 -EINVAL;
0056 }
0057
0058 static int mxl1x1sf_tuner_top_master_ctrl(struct mxl111sf_tuner_state *state,
0059 int onoff)
0060 {
0061 return (state->cfg->top_master_ctrl) ?
0062 state->cfg->top_master_ctrl(state->mxl_state, onoff) :
0063 -EINVAL;
0064 }
0065
0066
0067
0068 static struct mxl111sf_reg_ctrl_info mxl_phy_tune_rf[] = {
0069 {0x1d, 0x7f, 0x00},
0070
0071 {0x1e, 0xff, 0x00},
0072 {0x1f, 0xff, 0x00},
0073 {0, 0, 0}
0074 };
0075
0076
0077
0078 static struct mxl111sf_reg_ctrl_info *mxl111sf_calc_phy_tune_regs(u32 freq,
0079 u8 bw)
0080 {
0081 u8 filt_bw;
0082
0083
0084 switch (bw) {
0085 case 0:
0086 filt_bw = 25;
0087 break;
0088 case 1:
0089 filt_bw = 69;
0090 break;
0091 case 6:
0092 filt_bw = 21;
0093 break;
0094 case 7:
0095 filt_bw = 42;
0096 break;
0097 case 8:
0098 filt_bw = 63;
0099 break;
0100 default:
0101 pr_err("%s: invalid bandwidth setting!", __func__);
0102 return NULL;
0103 }
0104
0105
0106 freq /= 1000000;
0107
0108 freq *= 64;
0109 #if 0
0110
0111 freq += 0.5;
0112 #endif
0113
0114 mxl_phy_tune_rf[0].data = filt_bw;
0115
0116
0117 mxl_phy_tune_rf[1].data = (freq & 0xff);
0118 mxl_phy_tune_rf[2].data = (freq >> 8) & 0xff;
0119
0120
0121 return mxl_phy_tune_rf;
0122 }
0123
0124 static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state)
0125 {
0126 int ret;
0127 u8 ctrl;
0128 #if 0
0129 u16 iffcw;
0130 u32 if_freq;
0131 #endif
0132 mxl_dbg("(IF polarity = %d, IF freq = 0x%02x)",
0133 state->cfg->invert_spectrum, state->cfg->if_freq);
0134
0135
0136 ctrl = state->cfg->invert_spectrum;
0137
0138 ctrl |= state->cfg->if_freq;
0139
0140 ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_SEL_REG, ctrl);
0141 if (mxl_fail(ret))
0142 goto fail;
0143
0144 #if 0
0145 if_freq /= 1000000;
0146
0147
0148 if_freq += 0.5;
0149
0150 if (MXL_IF_LO == state->cfg->if_freq) {
0151 ctrl = 0x08;
0152 iffcw = (u16)(if_freq / (108 * 4096));
0153 } else if (MXL_IF_HI == state->cfg->if_freq) {
0154 ctrl = 0x08;
0155 iffcw = (u16)(if_freq / (216 * 4096));
0156 } else {
0157 ctrl = 0;
0158 iffcw = 0;
0159 }
0160
0161 ctrl |= (iffcw >> 8);
0162 #endif
0163 ret = mxl111sf_tuner_read_reg(state, V6_TUNER_IF_FCW_BYP_REG, &ctrl);
0164 if (mxl_fail(ret))
0165 goto fail;
0166
0167 ctrl &= 0xf0;
0168 ctrl |= 0x90;
0169
0170 ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_BYP_REG, ctrl);
0171 if (mxl_fail(ret))
0172 goto fail;
0173
0174 #if 0
0175 ctrl = iffcw & 0x00ff;
0176 #endif
0177 ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl);
0178 if (mxl_fail(ret))
0179 goto fail;
0180
0181 state->if_freq = state->cfg->if_freq;
0182 fail:
0183 return ret;
0184 }
0185
0186 static int mxl1x1sf_tune_rf(struct dvb_frontend *fe, u32 freq, u8 bw)
0187 {
0188 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0189 static struct mxl111sf_reg_ctrl_info *reg_ctrl_array;
0190 int ret;
0191 u8 mxl_mode;
0192
0193 mxl_dbg("(freq = %d, bw = 0x%x)", freq, bw);
0194
0195
0196 ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 0);
0197 if (mxl_fail(ret))
0198 goto fail;
0199
0200
0201 ret = mxl111sf_tuner_read_reg(state, MXL_MODE_REG, &mxl_mode);
0202 if (mxl_fail(ret))
0203 goto fail;
0204
0205
0206 reg_ctrl_array = mxl111sf_calc_phy_tune_regs(freq, bw);
0207 if (!reg_ctrl_array)
0208 return -EINVAL;
0209
0210 ret = mxl111sf_tuner_program_regs(state, reg_ctrl_array);
0211 if (mxl_fail(ret))
0212 goto fail;
0213
0214 if ((mxl_mode & MXL_DEV_MODE_MASK) == MXL_TUNER_MODE) {
0215
0216 mxl1x1sf_tuner_top_master_ctrl(state, 0);
0217 mxl1x1sf_tuner_top_master_ctrl(state, 1);
0218 mxl1x1sf_tuner_set_if_output_freq(state);
0219 }
0220
0221 ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 1);
0222 if (mxl_fail(ret))
0223 goto fail;
0224
0225 if (state->cfg->ant_hunt)
0226 state->cfg->ant_hunt(fe);
0227 fail:
0228 return ret;
0229 }
0230
0231 static int mxl1x1sf_tuner_get_lock_status(struct mxl111sf_tuner_state *state,
0232 int *rf_synth_lock,
0233 int *ref_synth_lock)
0234 {
0235 int ret;
0236 u8 data;
0237
0238 *rf_synth_lock = 0;
0239 *ref_synth_lock = 0;
0240
0241 ret = mxl111sf_tuner_read_reg(state, V6_RF_LOCK_STATUS_REG, &data);
0242 if (mxl_fail(ret))
0243 goto fail;
0244
0245 *ref_synth_lock = ((data & 0x03) == 0x03) ? 1 : 0;
0246 *rf_synth_lock = ((data & 0x0c) == 0x0c) ? 1 : 0;
0247 fail:
0248 return ret;
0249 }
0250
0251 #if 0
0252 static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state *state,
0253 int onoff)
0254 {
0255 return mxl111sf_tuner_write_reg(state, V6_TUNER_LOOP_THRU_CTRL_REG,
0256 onoff ? 1 : 0);
0257 }
0258 #endif
0259
0260
0261
0262 static int mxl111sf_tuner_set_params(struct dvb_frontend *fe)
0263 {
0264 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0265 u32 delsys = c->delivery_system;
0266 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0267 int ret;
0268 u8 bw;
0269
0270 mxl_dbg("()");
0271
0272 switch (delsys) {
0273 case SYS_ATSC:
0274 case SYS_ATSCMH:
0275 bw = 0;
0276 break;
0277 case SYS_DVBC_ANNEX_B:
0278 bw = 1;
0279 break;
0280 case SYS_DVBT:
0281 switch (c->bandwidth_hz) {
0282 case 6000000:
0283 bw = 6;
0284 break;
0285 case 7000000:
0286 bw = 7;
0287 break;
0288 case 8000000:
0289 bw = 8;
0290 break;
0291 default:
0292 pr_err("%s: bandwidth not set!", __func__);
0293 return -EINVAL;
0294 }
0295 break;
0296 default:
0297 pr_err("%s: modulation type not supported!", __func__);
0298 return -EINVAL;
0299 }
0300 ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
0301 if (mxl_fail(ret))
0302 goto fail;
0303
0304 state->frequency = c->frequency;
0305 state->bandwidth = c->bandwidth_hz;
0306 fail:
0307 return ret;
0308 }
0309
0310
0311
0312 #if 0
0313 static int mxl111sf_tuner_init(struct dvb_frontend *fe)
0314 {
0315 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0316 int ret;
0317
0318
0319
0320 return ret;
0321 }
0322
0323 static int mxl111sf_tuner_sleep(struct dvb_frontend *fe)
0324 {
0325 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0326 int ret;
0327
0328
0329
0330 return ret;
0331 }
0332 #endif
0333
0334
0335
0336 static int mxl111sf_tuner_get_status(struct dvb_frontend *fe, u32 *status)
0337 {
0338 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0339 int rf_locked, ref_locked, ret;
0340
0341 *status = 0;
0342
0343 ret = mxl1x1sf_tuner_get_lock_status(state, &rf_locked, &ref_locked);
0344 if (mxl_fail(ret))
0345 goto fail;
0346 mxl_info("%s%s", rf_locked ? "rf locked " : "",
0347 ref_locked ? "ref locked" : "");
0348
0349 if ((rf_locked) || (ref_locked))
0350 *status |= TUNER_STATUS_LOCKED;
0351 fail:
0352 return ret;
0353 }
0354
0355 static int mxl111sf_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
0356 {
0357 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0358 u8 val1, val2;
0359 int ret;
0360
0361 *strength = 0;
0362
0363 ret = mxl111sf_tuner_write_reg(state, 0x00, 0x02);
0364 if (mxl_fail(ret))
0365 goto fail;
0366 ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_LSB_REG, &val1);
0367 if (mxl_fail(ret))
0368 goto fail;
0369 ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_MSB_REG, &val2);
0370 if (mxl_fail(ret))
0371 goto fail;
0372
0373 *strength = val1 | ((val2 & 0x07) << 8);
0374 fail:
0375 ret = mxl111sf_tuner_write_reg(state, 0x00, 0x00);
0376 mxl_fail(ret);
0377
0378 return ret;
0379 }
0380
0381
0382
0383 static int mxl111sf_tuner_get_frequency(struct dvb_frontend *fe, u32 *frequency)
0384 {
0385 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0386 *frequency = state->frequency;
0387 return 0;
0388 }
0389
0390 static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
0391 {
0392 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0393 *bandwidth = state->bandwidth;
0394 return 0;
0395 }
0396
0397 static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe,
0398 u32 *frequency)
0399 {
0400 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0401
0402 *frequency = 0;
0403
0404 switch (state->if_freq) {
0405 case MXL_IF_4_0:
0406 *frequency = 4000000;
0407 break;
0408 case MXL_IF_4_5:
0409 *frequency = 4500000;
0410 break;
0411 case MXL_IF_4_57:
0412 *frequency = 4570000;
0413 break;
0414 case MXL_IF_5_0:
0415 *frequency = 5000000;
0416 break;
0417 case MXL_IF_5_38:
0418 *frequency = 5380000;
0419 break;
0420 case MXL_IF_6_0:
0421 *frequency = 6000000;
0422 break;
0423 case MXL_IF_6_28:
0424 *frequency = 6280000;
0425 break;
0426 case MXL_IF_7_2:
0427 *frequency = 7200000;
0428 break;
0429 case MXL_IF_35_25:
0430 *frequency = 35250000;
0431 break;
0432 case MXL_IF_36:
0433 *frequency = 36000000;
0434 break;
0435 case MXL_IF_36_15:
0436 *frequency = 36150000;
0437 break;
0438 case MXL_IF_44:
0439 *frequency = 44000000;
0440 break;
0441 }
0442 return 0;
0443 }
0444
0445 static void mxl111sf_tuner_release(struct dvb_frontend *fe)
0446 {
0447 struct mxl111sf_tuner_state *state = fe->tuner_priv;
0448 mxl_dbg("()");
0449 kfree(state);
0450 fe->tuner_priv = NULL;
0451 }
0452
0453
0454
0455 static const struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
0456 .info = {
0457 .name = "MaxLinear MxL111SF",
0458 #if 0
0459 .frequency_min_hz = ,
0460 .frequency_max_hz = ,
0461 .frequency_step_hz = ,
0462 #endif
0463 },
0464 #if 0
0465 .init = mxl111sf_tuner_init,
0466 .sleep = mxl111sf_tuner_sleep,
0467 #endif
0468 .set_params = mxl111sf_tuner_set_params,
0469 .get_status = mxl111sf_tuner_get_status,
0470 .get_rf_strength = mxl111sf_get_rf_strength,
0471 .get_frequency = mxl111sf_tuner_get_frequency,
0472 .get_bandwidth = mxl111sf_tuner_get_bandwidth,
0473 .get_if_frequency = mxl111sf_tuner_get_if_frequency,
0474 .release = mxl111sf_tuner_release,
0475 };
0476
0477 struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
0478 struct mxl111sf_state *mxl_state,
0479 const struct mxl111sf_tuner_config *cfg)
0480 {
0481 struct mxl111sf_tuner_state *state = NULL;
0482
0483 mxl_dbg("()");
0484
0485 state = kzalloc(sizeof(struct mxl111sf_tuner_state), GFP_KERNEL);
0486 if (state == NULL)
0487 return NULL;
0488
0489 state->mxl_state = mxl_state;
0490 state->cfg = cfg;
0491
0492 memcpy(&fe->ops.tuner_ops, &mxl111sf_tuner_tuner_ops,
0493 sizeof(struct dvb_tuner_ops));
0494
0495 fe->tuner_priv = state;
0496 return fe;
0497 }
0498 EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach);
0499
0500 MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver");
0501 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
0502 MODULE_LICENSE("GPL");
0503 MODULE_VERSION("0.1");