2 * mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner
4 * Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org>
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.
17 #include "mxl111sf-tuner.h"
18 #include "mxl111sf-phy.h"
19 #include "mxl111sf-reg.h"
22 static int mxl111sf_tuner_debug
;
23 module_param_named(debug
, mxl111sf_tuner_debug
, int, 0644);
24 MODULE_PARM_DESC(debug
, "set debugging level (1=info (or-able)).");
26 #define mxl_dbg(fmt, arg...) \
27 if (mxl111sf_tuner_debug) \
28 mxl_printk(KERN_DEBUG, fmt, ##arg)
30 /* ------------------------------------------------------------------------ */
32 struct mxl111sf_tuner_state
{
33 struct mxl111sf_state
*mxl_state
;
35 const struct mxl111sf_tuner_config
*cfg
;
37 enum mxl_if_freq if_freq
;
43 static int mxl111sf_tuner_read_reg(struct mxl111sf_tuner_state
*state
,
46 return (state
->cfg
->read_reg
) ?
47 state
->cfg
->read_reg(state
->mxl_state
, addr
, data
) :
51 static int mxl111sf_tuner_write_reg(struct mxl111sf_tuner_state
*state
,
54 return (state
->cfg
->write_reg
) ?
55 state
->cfg
->write_reg(state
->mxl_state
, addr
, data
) :
59 static int mxl111sf_tuner_program_regs(struct mxl111sf_tuner_state
*state
,
60 struct mxl111sf_reg_ctrl_info
*ctrl_reg_info
)
62 return (state
->cfg
->program_regs
) ?
63 state
->cfg
->program_regs(state
->mxl_state
, ctrl_reg_info
) :
67 static int mxl1x1sf_tuner_top_master_ctrl(struct mxl111sf_tuner_state
*state
,
70 return (state
->cfg
->top_master_ctrl
) ?
71 state
->cfg
->top_master_ctrl(state
->mxl_state
, onoff
) :
75 /* ------------------------------------------------------------------------ */
77 static struct mxl111sf_reg_ctrl_info mxl_phy_tune_rf
[] = {
78 {0x1d, 0x7f, 0x00}, /* channel bandwidth section 1/2/3,
79 DIG_MODEINDEX, _A, _CSF, */
80 {0x1e, 0xff, 0x00}, /* channel frequency (lo and fractional) */
81 {0x1f, 0xff, 0x00}, /* channel frequency (hi for integer portion) */
85 /* ------------------------------------------------------------------------ */
87 static struct mxl111sf_reg_ctrl_info
*mxl111sf_calc_phy_tune_regs(u32 freq
,
92 /* set channel bandwidth */
110 pr_err("%s: invalid bandwidth setting!", __func__
);
114 /* calculate RF channel */
123 mxl_phy_tune_rf
[0].data
= filt_bw
;
126 mxl_phy_tune_rf
[1].data
= (freq
& 0xff);
127 mxl_phy_tune_rf
[2].data
= (freq
>> 8) & 0xff;
130 return mxl_phy_tune_rf
;
133 static int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state
*state
)
141 mxl_dbg("(IF polarity = %d, IF freq = 0x%02x)",
142 state
->cfg
->invert_spectrum
, state
->cfg
->if_freq
);
144 /* set IF polarity */
145 ctrl
= state
->cfg
->invert_spectrum
;
147 ctrl
|= state
->cfg
->if_freq
;
149 ret
= mxl111sf_tuner_write_reg(state
, V6_TUNER_IF_SEL_REG
, ctrl
);
159 if (MXL_IF_LO
== state
->cfg
->if_freq
) {
161 iffcw
= (u16
)(if_freq
/ (108 * 4096));
162 } else if (MXL_IF_HI
== state
->cfg
->if_freq
) {
164 iffcw
= (u16
)(if_freq
/ (216 * 4096));
170 ctrl
|= (iffcw
>> 8);
172 ret
= mxl111sf_tuner_read_reg(state
, V6_TUNER_IF_FCW_BYP_REG
, &ctrl
);
179 ret
= mxl111sf_tuner_write_reg(state
, V6_TUNER_IF_FCW_BYP_REG
, ctrl
);
184 ctrl
= iffcw
& 0x00ff;
186 ret
= mxl111sf_tuner_write_reg(state
, V6_TUNER_IF_FCW_REG
, ctrl
);
190 state
->if_freq
= state
->cfg
->if_freq
;
195 static int mxl1x1sf_tune_rf(struct dvb_frontend
*fe
, u32 freq
, u8 bw
)
197 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
198 static struct mxl111sf_reg_ctrl_info
*reg_ctrl_array
;
202 mxl_dbg("(freq = %d, bw = 0x%x)", freq
, bw
);
205 ret
= mxl111sf_tuner_write_reg(state
, START_TUNE_REG
, 0);
209 /* check device mode */
210 ret
= mxl111sf_tuner_read_reg(state
, MXL_MODE_REG
, &mxl_mode
);
214 /* Fill out registers for channel tune */
215 reg_ctrl_array
= mxl111sf_calc_phy_tune_regs(freq
, bw
);
219 ret
= mxl111sf_tuner_program_regs(state
, reg_ctrl_array
);
223 if ((mxl_mode
& MXL_DEV_MODE_MASK
) == MXL_TUNER_MODE
) {
224 /* IF tuner mode only */
225 mxl1x1sf_tuner_top_master_ctrl(state
, 0);
226 mxl1x1sf_tuner_top_master_ctrl(state
, 1);
227 mxl1x1sf_tuner_set_if_output_freq(state
);
230 ret
= mxl111sf_tuner_write_reg(state
, START_TUNE_REG
, 1);
234 if (state
->cfg
->ant_hunt
)
235 state
->cfg
->ant_hunt(fe
);
240 static int mxl1x1sf_tuner_get_lock_status(struct mxl111sf_tuner_state
*state
,
250 ret
= mxl111sf_tuner_read_reg(state
, V6_RF_LOCK_STATUS_REG
, &data
);
254 *ref_synth_lock
= ((data
& 0x03) == 0x03) ? 1 : 0;
255 *rf_synth_lock
= ((data
& 0x0c) == 0x0c) ? 1 : 0;
261 static int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state
*state
,
264 return mxl111sf_tuner_write_reg(state
, V6_TUNER_LOOP_THRU_CTRL_REG
,
269 /* ------------------------------------------------------------------------ */
271 static int mxl111sf_tuner_set_params(struct dvb_frontend
*fe
)
273 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
274 u32 delsys
= c
->delivery_system
;
275 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
286 case SYS_DVBC_ANNEX_B
:
287 bw
= 1; /* US CABLE */
290 switch (c
->bandwidth_hz
) {
301 pr_err("%s: bandwidth not set!", __func__
);
306 pr_err("%s: modulation type not supported!", __func__
);
309 ret
= mxl1x1sf_tune_rf(fe
, c
->frequency
, bw
);
313 state
->frequency
= c
->frequency
;
314 state
->bandwidth
= c
->bandwidth_hz
;
319 /* ------------------------------------------------------------------------ */
322 static int mxl111sf_tuner_init(struct dvb_frontend
*fe
)
324 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
327 /* wake from standby handled by usb driver */
332 static int mxl111sf_tuner_sleep(struct dvb_frontend
*fe
)
334 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
337 /* enter standby mode handled by usb driver */
343 /* ------------------------------------------------------------------------ */
345 static int mxl111sf_tuner_get_status(struct dvb_frontend
*fe
, u32
*status
)
347 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
348 int rf_locked
, ref_locked
, ret
;
352 ret
= mxl1x1sf_tuner_get_lock_status(state
, &rf_locked
, &ref_locked
);
355 mxl_info("%s%s", rf_locked
? "rf locked " : "",
356 ref_locked
? "ref locked" : "");
358 if ((rf_locked
) || (ref_locked
))
359 *status
|= TUNER_STATUS_LOCKED
;
364 static int mxl111sf_get_rf_strength(struct dvb_frontend
*fe
, u16
*strength
)
366 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
372 ret
= mxl111sf_tuner_write_reg(state
, 0x00, 0x02);
375 ret
= mxl111sf_tuner_read_reg(state
, V6_DIG_RF_PWR_LSB_REG
, &val1
);
378 ret
= mxl111sf_tuner_read_reg(state
, V6_DIG_RF_PWR_MSB_REG
, &val2
);
382 *strength
= val1
| ((val2
& 0x07) << 8);
384 ret
= mxl111sf_tuner_write_reg(state
, 0x00, 0x00);
390 /* ------------------------------------------------------------------------ */
392 static int mxl111sf_tuner_get_frequency(struct dvb_frontend
*fe
, u32
*frequency
)
394 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
395 *frequency
= state
->frequency
;
399 static int mxl111sf_tuner_get_bandwidth(struct dvb_frontend
*fe
, u32
*bandwidth
)
401 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
402 *bandwidth
= state
->bandwidth
;
406 static int mxl111sf_tuner_get_if_frequency(struct dvb_frontend
*fe
,
409 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
413 switch (state
->if_freq
) {
414 case MXL_IF_4_0
: /* 4.0 MHz */
415 *frequency
= 4000000;
417 case MXL_IF_4_5
: /* 4.5 MHz */
418 *frequency
= 4500000;
420 case MXL_IF_4_57
: /* 4.57 MHz */
421 *frequency
= 4570000;
423 case MXL_IF_5_0
: /* 5.0 MHz */
424 *frequency
= 5000000;
426 case MXL_IF_5_38
: /* 5.38 MHz */
427 *frequency
= 5380000;
429 case MXL_IF_6_0
: /* 6.0 MHz */
430 *frequency
= 6000000;
432 case MXL_IF_6_28
: /* 6.28 MHz */
433 *frequency
= 6280000;
435 case MXL_IF_7_2
: /* 7.2 MHz */
436 *frequency
= 7200000;
438 case MXL_IF_35_25
: /* 35.25 MHz */
439 *frequency
= 35250000;
441 case MXL_IF_36
: /* 36 MHz */
442 *frequency
= 36000000;
444 case MXL_IF_36_15
: /* 36.15 MHz */
445 *frequency
= 36150000;
447 case MXL_IF_44
: /* 44 MHz */
448 *frequency
= 44000000;
454 static void mxl111sf_tuner_release(struct dvb_frontend
*fe
)
456 struct mxl111sf_tuner_state
*state
= fe
->tuner_priv
;
459 fe
->tuner_priv
= NULL
;
462 /* ------------------------------------------------------------------------- */
464 static const struct dvb_tuner_ops mxl111sf_tuner_tuner_ops
= {
466 .name
= "MaxLinear MxL111SF",
474 .init
= mxl111sf_tuner_init
,
475 .sleep
= mxl111sf_tuner_sleep
,
477 .set_params
= mxl111sf_tuner_set_params
,
478 .get_status
= mxl111sf_tuner_get_status
,
479 .get_rf_strength
= mxl111sf_get_rf_strength
,
480 .get_frequency
= mxl111sf_tuner_get_frequency
,
481 .get_bandwidth
= mxl111sf_tuner_get_bandwidth
,
482 .get_if_frequency
= mxl111sf_tuner_get_if_frequency
,
483 .release
= mxl111sf_tuner_release
,
486 struct dvb_frontend
*mxl111sf_tuner_attach(struct dvb_frontend
*fe
,
487 struct mxl111sf_state
*mxl_state
,
488 const struct mxl111sf_tuner_config
*cfg
)
490 struct mxl111sf_tuner_state
*state
= NULL
;
494 state
= kzalloc(sizeof(struct mxl111sf_tuner_state
), GFP_KERNEL
);
498 state
->mxl_state
= mxl_state
;
501 memcpy(&fe
->ops
.tuner_ops
, &mxl111sf_tuner_tuner_ops
,
502 sizeof(struct dvb_tuner_ops
));
504 fe
->tuner_priv
= state
;
507 EXPORT_SYMBOL_GPL(mxl111sf_tuner_attach
);
509 MODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver");
510 MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
511 MODULE_LICENSE("GPL");
512 MODULE_VERSION("0.1");