2 * mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
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.
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.
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.
21 #include "mxl111sf-tuner.h"
22 #include "mxl111sf-phy.h"
23 #include "mxl111sf-reg.h"
26 static int mxl111sf_tuner_debug
;
27 module_param_named(debug
, mxl111sf_tuner_debug
, int, 0644);
28 MODULE_PARM_DESC(debug
, "set debugging level (1=info (or-able)).");
30 #define mxl_dbg(fmt, arg...) \
31 if (mxl111sf_tuner_debug) \
32 mxl_printk(KERN_DEBUG, fmt, ##arg)
34 /* ------------------------------------------------------------------------ */
36 struct mxl111sf_tuner_state
{
37 struct mxl111sf_state
*mxl_state
;
39 struct mxl111sf_tuner_config
*cfg
;
41 enum mxl_if_freq if_freq
;
47 static int mxl111sf_tuner_read_reg(struct mxl111sf_tuner_state
*state
,
50 return (state
->cfg
->read_reg
) ?
51 state
->cfg
->read_reg(state
->mxl_state
, addr
, data
) :
55 static int mxl111sf_tuner_write_reg(struct mxl111sf_tuner_state
*state
,
58 return (state
->cfg
->write_reg
) ?
59 state
->cfg
->write_reg(state
->mxl_state
, addr
, data
) :
63 static int mxl111sf_tuner_program_regs(struct mxl111sf_tuner_state
*state
,
64 struct mxl111sf_reg_ctrl_info
*ctrl_reg_info
)
66 return (state
->cfg
->program_regs
) ?
67 state
->cfg
->program_regs(state
->mxl_state
, ctrl_reg_info
) :
71 static int mxl1x1sf_tuner_top_master_ctrl(struct mxl111sf_tuner_state
*state
,
74 return (state
->cfg
->top_master_ctrl
) ?
75 state
->cfg
->top_master_ctrl(state
->mxl_state
, onoff
) :
79 /* ------------------------------------------------------------------------ */
81 static struct mxl111sf_reg_ctrl_info mxl_phy_tune_rf
[] = {
82 {0x1d, 0x7f, 0x00}, /* channel bandwidth section 1/2/3,
83 DIG_MODEINDEX, _A, _CSF, */
84 {0x1e, 0xff, 0x00}, /* channel frequency (lo and fractional) */
85 {0x1f, 0xff, 0x00}, /* channel frequency (hi for integer portion) */
89 /* ------------------------------------------------------------------------ */
91 static struct mxl111sf_reg_ctrl_info
*mxl111sf_calc_phy_tune_regs(u32 freq
,
96 /* set channel bandwidth */
114 err("%s: invalid bandwidth setting!", __func__
);
118 /* calculate RF channel */
127 mxl_phy_tune_rf
[0].data
= filt_bw
;
130 mxl_phy_tune_rf
[1].data
= (freq
& 0xff);
131 mxl_phy_tune_rf
[2].data
= (freq
>> 8) & 0xff;
134 return mxl_phy_tune_rf
;
137 static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state
*state
)
145 mxl_dbg("(IF polarity = %d, IF freq = 0x%02x)",
146 state
->cfg
->invert_spectrum
, state
->cfg
->if_freq
);
148 /* set IF polarity */
149 ctrl
= state
->cfg
->invert_spectrum
;
151 ctrl
|= state
->cfg
->if_freq
;
153 ret
= mxl111sf_tuner_write_reg(state
, V6_TUNER_IF_SEL_REG
, ctrl
);
163 if (MXL_IF_LO
== state
->cfg
->if_freq
) {
165 iffcw
= (u16
)(if_freq
/ (108 * 4096));
166 } else if (MXL_IF_HI
== state
->cfg
->if_freq
) {
168 iffcw
= (u16
)(if_freq
/ (216 * 4096));
174 ctrl
|= (iffcw
>> 8);
176 ret
= mxl111sf_tuner_read_reg(state
, V6_TUNER_IF_FCW_BYP_REG
, &ctrl
);
183 ret
= mxl111sf_tuner_write_reg(state
, V6_TUNER_IF_FCW_BYP_REG
, ctrl
);
188 ctrl
= iffcw
& 0x00ff;
190 ret
= mxl111sf_tuner_write_reg(state
, V6_TUNER_IF_FCW_REG
, ctrl
);
194 state
->if_freq
= state
->cfg
->if_freq
;
199 static int mxl1x1sf_tune_rf(struct dvb_frontend
*fe
, u32 freq
, u8 bw
)
201 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
202 static struct mxl111sf_reg_ctrl_info
*reg_ctrl_array
;
206 mxl_dbg("(freq = %d, bw = 0x%x)", freq
, bw
);
209 ret
= mxl111sf_tuner_write_reg(state
, START_TUNE_REG
, 0);
213 /* check device mode */
214 ret
= mxl111sf_tuner_read_reg(state
, MXL_MODE_REG
, &mxl_mode
);
218 /* Fill out registers for channel tune */
219 reg_ctrl_array
= mxl111sf_calc_phy_tune_regs(freq
, bw
);
223 ret
= mxl111sf_tuner_program_regs(state
, reg_ctrl_array
);
227 if ((mxl_mode
& MXL_DEV_MODE_MASK
) == MXL_TUNER_MODE
) {
228 /* IF tuner mode only */
229 mxl1x1sf_tuner_top_master_ctrl(state
, 0);
230 mxl1x1sf_tuner_top_master_ctrl(state
, 1);
231 mxl1x1sf_tuner_set_if_output_freq(state
);
234 ret
= mxl111sf_tuner_write_reg(state
, START_TUNE_REG
, 1);
238 if (state
->cfg
->ant_hunt
)
239 state
->cfg
->ant_hunt(fe
);
244 static int mxl1x1sf_tuner_get_lock_status(struct mxl111sf_tuner_state
*state
,
254 ret
= mxl111sf_tuner_read_reg(state
, V6_RF_LOCK_STATUS_REG
, &data
);
258 *ref_synth_lock
= ((data
& 0x03) == 0x03) ? 1 : 0;
259 *rf_synth_lock
= ((data
& 0x0c) == 0x0c) ? 1 : 0;
265 static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state
*state
,
268 return mxl111sf_tuner_write_reg(state
, V6_TUNER_LOOP_THRU_CTRL_REG
,
273 /* ------------------------------------------------------------------------ */
275 static int mxl111sf_tuner_set_params(struct dvb_frontend
*fe
)
277 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
278 u32 delsys
= c
->delivery_system
;
279 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
289 case SYS_DVBC_ANNEX_B
:
290 bw
= 1; /* US CABLE */
293 switch (c
->bandwidth_hz
) {
304 err("%s: bandwidth not set!", __func__
);
309 err("%s: modulation type not supported!", __func__
);
312 ret
= mxl1x1sf_tune_rf(fe
, c
->frequency
, bw
);
316 state
->frequency
= c
->frequency
;
317 state
->bandwidth
= c
->bandwidth_hz
;
322 /* ------------------------------------------------------------------------ */
325 static int mxl111sf_tuner_init(struct dvb_frontend
*fe
)
327 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
330 /* wake from standby handled by usb driver */
335 static int mxl111sf_tuner_sleep(struct dvb_frontend
*fe
)
337 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
340 /* enter standby mode handled by usb driver */
346 /* ------------------------------------------------------------------------ */
348 static int mxl111sf_tuner_get_status(struct dvb_frontend
*fe
, u32
*status
)
350 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
351 int rf_locked
, ref_locked
, ret
;
355 ret
= mxl1x1sf_tuner_get_lock_status(state
, &rf_locked
, &ref_locked
);
358 mxl_info("%s%s", rf_locked
? "rf locked " : "",
359 ref_locked
? "ref locked" : "");
361 if ((rf_locked
) || (ref_locked
))
362 *status
|= TUNER_STATUS_LOCKED
;
367 static int mxl111sf_get_rf_strength(struct dvb_frontend
*fe
, u16
*strength
)
369 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
375 ret
= mxl111sf_tuner_write_reg(state
, 0x00, 0x02);
378 ret
= mxl111sf_tuner_read_reg(state
, V6_DIG_RF_PWR_LSB_REG
, &val1
);
381 ret
= mxl111sf_tuner_read_reg(state
, V6_DIG_RF_PWR_MSB_REG
, &val2
);
385 *strength
= val1
| ((val2
& 0x07) << 8);
387 ret
= mxl111sf_tuner_write_reg(state
, 0x00, 0x00);
393 /* ------------------------------------------------------------------------ */
395 static int mxl111sf_tuner_get_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
397 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
398 *frequency
= state
->frequency
;
402 static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend
*fe
, u32
*bandwidth
)
404 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
405 *bandwidth
= state
->bandwidth
;
409 static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend
*fe
,
412 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
416 switch (state
->if_freq
) {
417 case MXL_IF_4_0
: /* 4.0 MHz */
418 *frequency
= 4000000;
420 case MXL_IF_4_5
: /* 4.5 MHz */
421 *frequency
= 4500000;
423 case MXL_IF_4_57
: /* 4.57 MHz */
424 *frequency
= 4570000;
426 case MXL_IF_5_0
: /* 5.0 MHz */
427 *frequency
= 5000000;
429 case MXL_IF_5_38
: /* 5.38 MHz */
430 *frequency
= 5380000;
432 case MXL_IF_6_0
: /* 6.0 MHz */
433 *frequency
= 6000000;
435 case MXL_IF_6_28
: /* 6.28 MHz */
436 *frequency
= 6280000;
438 case MXL_IF_7_2
: /* 7.2 MHz */
439 *frequency
= 7200000;
441 case MXL_IF_35_25
: /* 35.25 MHz */
442 *frequency
= 35250000;
444 case MXL_IF_36
: /* 36 MHz */
445 *frequency
= 36000000;
447 case MXL_IF_36_15
: /* 36.15 MHz */
448 *frequency
= 36150000;
450 case MXL_IF_44
: /* 44 MHz */
451 *frequency
= 44000000;
457 static int mxl111sf_tuner_release(struct dvb_frontend
*fe
)
459 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
462 fe
->tuner_priv
= NULL
;
466 /* ------------------------------------------------------------------------- */
468 static struct dvb_tuner_ops mxl111sf_tuner_tuner_ops
= {
470 .name
= "MaxLinear MxL111SF",
478 .init
= mxl111sf_tuner_init
,
479 .sleep
= mxl111sf_tuner_sleep
,
481 .set_params
= mxl111sf_tuner_set_params
,
482 .get_status
= mxl111sf_tuner_get_status
,
483 .get_rf_strength
= mxl111sf_get_rf_strength
,
484 .get_frequency
= mxl111sf_tuner_get_frequency
,
485 .get_bandwidth
= mxl111sf_tuner_get_bandwidth
,
486 .get_if_frequency
= mxl111sf_tuner_get_if_frequency
,
487 .release
= mxl111sf_tuner_release
,
490 struct dvb_frontend
*mxl111sf_tuner_attach(struct dvb_frontend
*fe
,
491 struct mxl111sf_state
*mxl_state
,
492 struct mxl111sf_tuner_config
*cfg
)
494 struct mxl111sf_tuner_state
*state
= NULL
;
498 state
= kzalloc(sizeof(struct mxl111sf_tuner_state
), GFP_KERNEL
);
502 state
->mxl_state
= mxl_state
;
505 memcpy(&fe
->ops
.tuner_ops
, &mxl111sf_tuner_tuner_ops
,
506 sizeof(struct dvb_tuner_ops
));
508 fe
->tuner_priv
= state
;
511 EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach
);
513 MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver");
514 MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
515 MODULE_LICENSE("GPL");
516 MODULE_VERSION("0.1");
519 * Overrides for Emacs so that we follow Linus's tabbing style.
520 * ---------------------------------------------------------------------------