14c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/*
24c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  mxl111sf-tuner.c - driver for the MaxLinear MXL111SF CMOS tuner
34c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *
408e10972661db78d0e0a2d4a4c28fc3bf93617baMichael Krufky *  Copyright (C) 2010-2014 Michael Krufky <mkrufky@linuxtv.org>
54c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *
64c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  This program is free software; you can redistribute it and/or modify
74c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  it under the terms of the GNU General Public License as published by
84c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  the Free Software Foundation; either version 2 of the License, or
94c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  (at your option) any later version.
104c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *
114c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  This program is distributed in the hope that it will be useful,
124c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  but WITHOUT ANY WARRANTY; without even the implied warranty of
134c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  GNU General Public License for more details.
154c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *
164c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  You should have received a copy of the GNU General Public License
174c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  along with this program; if not, write to the Free Software
184c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
194c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky */
204c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
214c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#include "mxl111sf-tuner.h"
224c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#include "mxl111sf-phy.h"
234c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#include "mxl111sf-reg.h"
244c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
254c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/* debug */
264c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_debug;
274c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkymodule_param_named(debug, mxl111sf_tuner_debug, int, 0644);
284c66c9205c0788e18eb09d482461aa2f551ee046Michael KrufkyMODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
294c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
304c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#define mxl_dbg(fmt, arg...) \
314c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl111sf_tuner_debug) \
324c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		mxl_printk(KERN_DEBUG, fmt, ##arg)
334c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
344c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/* ------------------------------------------------------------------------ */
354c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
364c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystruct mxl111sf_tuner_state {
374c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_state *mxl_state;
384c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
394c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_config *cfg;
404c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
41f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	enum mxl_if_freq if_freq;
42f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky
434c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u32 frequency;
444c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u32 bandwidth;
454c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky};
464c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
474c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_read_reg(struct mxl111sf_tuner_state *state,
484c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky				   u8 addr, u8 *data)
494c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
504c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return (state->cfg->read_reg) ?
514c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		state->cfg->read_reg(state->mxl_state, addr, data) :
524c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		-EINVAL;
534c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
544c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
554c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_write_reg(struct mxl111sf_tuner_state *state,
564c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky				    u8 addr, u8 data)
574c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
584c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return (state->cfg->write_reg) ?
594c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		state->cfg->write_reg(state->mxl_state, addr, data) :
604c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		-EINVAL;
614c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
624c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
634c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_program_regs(struct mxl111sf_tuner_state *state,
644c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky			       struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
654c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
664c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return (state->cfg->program_regs) ?
674c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
684c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		-EINVAL;
694c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
704c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
714c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl1x1sf_tuner_top_master_ctrl(struct mxl111sf_tuner_state *state,
724c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky					  int onoff)
734c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
744c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return (state->cfg->top_master_ctrl) ?
754c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		state->cfg->top_master_ctrl(state->mxl_state, onoff) :
764c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		-EINVAL;
774c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
784c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
794c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/* ------------------------------------------------------------------------ */
804c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
814c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic struct mxl111sf_reg_ctrl_info mxl_phy_tune_rf[] = {
824c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	{0x1d, 0x7f, 0x00}, /* channel bandwidth section 1/2/3,
834c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky			       DIG_MODEINDEX, _A, _CSF, */
844c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	{0x1e, 0xff, 0x00}, /* channel frequency (lo and fractional) */
854c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	{0x1f, 0xff, 0x00}, /* channel frequency (hi for integer portion) */
864c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	{0,    0,    0}
874c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky};
884c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
894c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/* ------------------------------------------------------------------------ */
904c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
914c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic struct mxl111sf_reg_ctrl_info *mxl111sf_calc_phy_tune_regs(u32 freq,
924c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky								  u8 bw)
934c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
944c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u8 filt_bw;
954c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
964c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* set channel bandwidth */
974c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	switch (bw) {
984c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	case 0: /* ATSC */
994c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		filt_bw = 25;
1004c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		break;
1014c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	case 1: /* QAM */
1024c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		filt_bw = 69;
1034c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		break;
1044c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	case 6:
1054c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		filt_bw = 21;
1064c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		break;
1074c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	case 7:
1084c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		filt_bw = 42;
1094c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		break;
1104c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	case 8:
1114c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		filt_bw = 63;
1124c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		break;
1134c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	default:
114c778edb5bdb7a96712848493273762427a51e200Hans Verkuil		pr_err("%s: invalid bandwidth setting!", __func__);
1154c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		return NULL;
1164c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	}
1174c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1184c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* calculate RF channel */
1194c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	freq /= 1000000;
1204c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1214c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	freq *= 64;
1224c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#if 0
1234c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* do round */
1244c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	freq += 0.5;
1254c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#endif
1264c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* set bandwidth */
1274c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_phy_tune_rf[0].data = filt_bw;
1284c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1294c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* set RF */
1304c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_phy_tune_rf[1].data = (freq & 0xff);
1314c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_phy_tune_rf[2].data = (freq >> 8) & 0xff;
1324c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1334c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* start tune */
1344c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return mxl_phy_tune_rf;
1354c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
1364c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1374c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl1x1sf_tuner_set_if_output_freq(struct mxl111sf_tuner_state *state)
1384c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
1394c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	int ret;
1404c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u8 ctrl;
1414c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#if 0
1424c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u16 iffcw;
1434c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u32 if_freq;
1444c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#endif
1454c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_dbg("(IF polarity = %d, IF freq = 0x%02x)",
1464c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		state->cfg->invert_spectrum, state->cfg->if_freq);
1474c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1484c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* set IF polarity */
1494c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ctrl = state->cfg->invert_spectrum;
1504c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1514c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ctrl |= state->cfg->if_freq;
1524c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1534c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_SEL_REG, ctrl);
1544c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
1554c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
1564c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1574c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#if 0
1584c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if_freq /= 1000000;
1594c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1604c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* do round */
1614c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if_freq += 0.5;
1624c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1634c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (MXL_IF_LO == state->cfg->if_freq) {
1644c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		ctrl = 0x08;
1654c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		iffcw = (u16)(if_freq / (108 * 4096));
1664c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	} else if (MXL_IF_HI == state->cfg->if_freq) {
1674c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		ctrl = 0x08;
1684c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		iffcw = (u16)(if_freq / (216 * 4096));
1694c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	} else {
1704c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		ctrl = 0;
1714c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		iffcw = 0;
1724c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	}
1734c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1744c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ctrl |= (iffcw >> 8);
1754c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#endif
1764c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_read_reg(state, V6_TUNER_IF_FCW_BYP_REG, &ctrl);
1774c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
1784c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
1794c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1804c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ctrl &= 0xf0;
1814c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ctrl |= 0x90;
1824c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1834c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_BYP_REG, ctrl);
1844c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
1854c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
1864c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1874c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#if 0
1884c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ctrl = iffcw & 0x00ff;
1894c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#endif
1904c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_write_reg(state, V6_TUNER_IF_FCW_REG, ctrl);
191f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	if (mxl_fail(ret))
192f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		goto fail;
193f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky
194f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	state->if_freq = state->cfg->if_freq;
1954c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkyfail:
1964c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return ret;
1974c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
1984c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
1994c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl1x1sf_tune_rf(struct dvb_frontend *fe, u32 freq, u8 bw)
2004c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
2014c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
2024c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	static struct mxl111sf_reg_ctrl_info *reg_ctrl_array;
2034c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	int ret;
2044c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u8 mxl_mode;
2054c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2064c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_dbg("(freq = %d, bw = 0x%x)", freq, bw);
2074c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2084c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* stop tune */
2094c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 0);
2104c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
2114c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
2124c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2134c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* check device mode */
2144c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_read_reg(state, MXL_MODE_REG, &mxl_mode);
2154c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
2164c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
2174c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2184c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* Fill out registers for channel tune */
2194c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	reg_ctrl_array = mxl111sf_calc_phy_tune_regs(freq, bw);
2204c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (!reg_ctrl_array)
2214c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		return -EINVAL;
2224c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2234c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_program_regs(state, reg_ctrl_array);
2244c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
2254c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
2264c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2274c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if ((mxl_mode & MXL_DEV_MODE_MASK) == MXL_TUNER_MODE) {
2284c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		/* IF tuner mode only */
2294c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		mxl1x1sf_tuner_top_master_ctrl(state, 0);
2304c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		mxl1x1sf_tuner_top_master_ctrl(state, 1);
2314c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		mxl1x1sf_tuner_set_if_output_freq(state);
2324c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	}
2334c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2344c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_write_reg(state, START_TUNE_REG, 1);
2354c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
2364c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
2374c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2384c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (state->cfg->ant_hunt)
2394c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		state->cfg->ant_hunt(fe);
2404c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkyfail:
2414c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return ret;
2424c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
2434c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2444c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl1x1sf_tuner_get_lock_status(struct mxl111sf_tuner_state *state,
2454c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky					  int *rf_synth_lock,
2464c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky					  int *ref_synth_lock)
2474c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
2484c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	int ret;
2494c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u8 data;
2504c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2514c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	*rf_synth_lock = 0;
2524c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	*ref_synth_lock = 0;
2534c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2544c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_read_reg(state, V6_RF_LOCK_STATUS_REG, &data);
2554c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
2564c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
2574c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2584c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	*ref_synth_lock = ((data & 0x03) == 0x03) ? 1 : 0;
2594c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	*rf_synth_lock  = ((data & 0x0c) == 0x0c) ? 1 : 0;
2604c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkyfail:
2614c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return ret;
2624c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
2634c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2644c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#if 0
2654c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl1x1sf_tuner_loop_thru_ctrl(struct mxl111sf_tuner_state *state,
2664c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky					 int onoff)
2674c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
2684c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return mxl111sf_tuner_write_reg(state, V6_TUNER_LOOP_THRU_CTRL_REG,
2694c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky					onoff ? 1 : 0);
2704c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
2714c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#endif
2724c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2734c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/* ------------------------------------------------------------------------ */
2744c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
27514d24d148c7521b2b88b396652e36f55d061e195Mauro Carvalho Chehabstatic int mxl111sf_tuner_set_params(struct dvb_frontend *fe)
2764c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
27793ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
27893ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab	u32 delsys  = c->delivery_system;
2794c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
2804c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	int ret;
2814c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u8 bw;
2824c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
2834c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_dbg("()");
2844c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
28593ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab	switch (delsys) {
28693ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab	case SYS_ATSC:
2874ef70775070c28fdca34b967338aaff0b1f1e619Michael Krufky	case SYS_ATSCMH:
28893ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab		bw = 0; /* ATSC */
28993ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab		break;
29093ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab	case SYS_DVBC_ANNEX_B:
29193ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab		bw = 1; /* US CABLE */
29293ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab		break;
29393ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab	case SYS_DVBT:
29493ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab		switch (c->bandwidth_hz) {
29593ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab		case 6000000:
2964c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky			bw = 6;
2974c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky			break;
29893ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab		case 7000000:
2994c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky			bw = 7;
3004c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky			break;
30193ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab		case 8000000:
3024c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky			bw = 8;
3034c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky			break;
3044c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		default:
305c778edb5bdb7a96712848493273762427a51e200Hans Verkuil			pr_err("%s: bandwidth not set!", __func__);
3064c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky			return -EINVAL;
3074c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		}
30893ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab		break;
30993ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab	default:
310c778edb5bdb7a96712848493273762427a51e200Hans Verkuil		pr_err("%s: modulation type not supported!", __func__);
3114c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		return -EINVAL;
3124c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	}
31393ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab	ret = mxl1x1sf_tune_rf(fe, c->frequency, bw);
3144c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
3154c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
3164c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
31793ce675c5cc57cac37e32953fdd43179e02f5c54Mauro Carvalho Chehab	state->frequency = c->frequency;
318c6f56e7d794cba022353d464dfa3383d1b3e0125Mauro Carvalho Chehab	state->bandwidth = c->bandwidth_hz;
3194c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkyfail:
3204c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return ret;
3214c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
3224c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3234c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/* ------------------------------------------------------------------------ */
3244c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3254c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#if 0
3264c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_init(struct dvb_frontend *fe)
3274c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
3284c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
3294c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	int ret;
3304c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3314c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* wake from standby handled by usb driver */
3324c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3334c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return ret;
3344c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
3354c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3364c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_sleep(struct dvb_frontend *fe)
3374c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
3384c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
3394c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	int ret;
3404c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3414c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	/* enter standby mode handled by usb driver */
3424c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3434c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return ret;
3444c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
3454c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#endif
3464c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3474c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/* ------------------------------------------------------------------------ */
3484c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3494c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_get_status(struct dvb_frontend *fe, u32 *status)
3504c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
3514c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
3524c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	int rf_locked, ref_locked, ret;
3534c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3544c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	*status = 0;
3554c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3564c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl1x1sf_tuner_get_lock_status(state, &rf_locked, &ref_locked);
3574c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
3584c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
3594c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_info("%s%s", rf_locked ? "rf locked " : "",
3604c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		 ref_locked ? "ref locked" : "");
3614c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3624c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if ((rf_locked) || (ref_locked))
3634c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		*status |= TUNER_STATUS_LOCKED;
3644c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkyfail:
3654c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return ret;
3664c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
3674c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3684c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
3694c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
3704c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
3714c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	u8 val1, val2;
3724c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	int ret;
3734c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3744c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	*strength = 0;
3754c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3764c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_write_reg(state, 0x00, 0x02);
3774c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
3784c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
3794c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_LSB_REG, &val1);
3804c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
3814c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
3824c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_read_reg(state, V6_DIG_RF_PWR_MSB_REG, &val2);
3834c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (mxl_fail(ret))
3844c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		goto fail;
3854c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3864c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	*strength = val1 | ((val2 & 0x07) << 8);
3874c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkyfail:
3884c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	ret = mxl111sf_tuner_write_reg(state, 0x00, 0x00);
3894c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_fail(ret);
3904c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3914c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return ret;
3924c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
3934c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3944c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/* ------------------------------------------------------------------------ */
3954c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
3964c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_get_frequency(struct dvb_frontend *fe, u32 *frequency)
3974c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
3984c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
3994c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	*frequency = state->frequency;
4004c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return 0;
4014c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
4024c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
4034c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
4044c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
4054c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
4064c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	*bandwidth = state->bandwidth;
4074c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return 0;
4084c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
4094c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
410f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufkystatic int mxl111sf_tuner_get_if_frequency(struct dvb_frontend *fe,
411f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky					   u32 *frequency)
412f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky{
413f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
414f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky
415f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	*frequency = 0;
416f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky
417f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	switch (state->if_freq) {
418f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_4_0:   /* 4.0   MHz */
419f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 4000000;
420f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
421f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_4_5:   /* 4.5   MHz */
422f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 4500000;
423f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
424f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_4_57:  /* 4.57  MHz */
425f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 4570000;
426f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
427f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_5_0:   /* 5.0   MHz */
428f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 5000000;
429f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
430f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_5_38:  /* 5.38  MHz */
431f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 5380000;
432f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
433f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_6_0:   /* 6.0   MHz */
434f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 6000000;
435f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
436f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_6_28:  /* 6.28  MHz */
437f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 6280000;
438f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
439f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_7_2:   /* 7.2   MHz */
440f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 7200000;
441f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
442f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_35_25: /* 35.25 MHz */
443f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 35250000;
444f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
445f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_36:    /* 36    MHz */
446f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 36000000;
447f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
448f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_36_15: /* 36.15 MHz */
449f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 36150000;
450f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
451f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	case MXL_IF_44:    /* 44    MHz */
452f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		*frequency = 44000000;
453f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky		break;
454f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	}
455f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	return 0;
456f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky}
457f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky
4584c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic int mxl111sf_tuner_release(struct dvb_frontend *fe)
4594c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
4604c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = fe->tuner_priv;
4614c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_dbg("()");
4624c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	kfree(state);
4634c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	fe->tuner_priv = NULL;
4644c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return 0;
4654c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
4664c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
4674c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/* ------------------------------------------------------------------------- */
4684c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
4694c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystatic struct dvb_tuner_ops mxl111sf_tuner_tuner_ops = {
4704c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	.info = {
4714c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		.name = "MaxLinear MxL111SF",
4724c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#if 0
4734c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		.frequency_min  = ,
4744c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		.frequency_max  = ,
4754c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		.frequency_step = ,
4764c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#endif
4774c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	},
4784c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#if 0
4794c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	.init              = mxl111sf_tuner_init,
4804c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	.sleep             = mxl111sf_tuner_sleep,
4814c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky#endif
4824c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	.set_params        = mxl111sf_tuner_set_params,
4834c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	.get_status        = mxl111sf_tuner_get_status,
4844c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	.get_rf_strength   = mxl111sf_get_rf_strength,
4854c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	.get_frequency     = mxl111sf_tuner_get_frequency,
4864c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	.get_bandwidth     = mxl111sf_tuner_get_bandwidth,
487f7901f9b4ae06d65537ff3db8605e657f6d4afceMichael Krufky	.get_if_frequency  = mxl111sf_tuner_get_if_frequency,
4884c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	.release           = mxl111sf_tuner_release,
4894c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky};
4904c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
4914c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufkystruct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe,
4924c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky					   struct mxl111sf_state *mxl_state,
4934c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky					   struct mxl111sf_tuner_config *cfg)
4944c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky{
4954c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	struct mxl111sf_tuner_state *state = NULL;
4964c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
4974c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	mxl_dbg("()");
4984c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
4994c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	state = kzalloc(sizeof(struct mxl111sf_tuner_state), GFP_KERNEL);
5004c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	if (state == NULL)
5014c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky		return NULL;
5024c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
5034c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	state->mxl_state = mxl_state;
5044c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	state->cfg = cfg;
5054c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
5064c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	memcpy(&fe->ops.tuner_ops, &mxl111sf_tuner_tuner_ops,
5074c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	       sizeof(struct dvb_tuner_ops));
5084c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
5094c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	fe->tuner_priv = state;
5104c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky	return fe;
5114c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky}
5124c66c9205c0788e18eb09d482461aa2f551ee046Michael KrufkyEXPORT_SYMBOL_GPL(mxl111sf_tuner_attach);
5134c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
5144c66c9205c0788e18eb09d482461aa2f551ee046Michael KrufkyMODULE_DESCRIPTION("MaxLinear MxL111SF CMOS tuner driver");
51508e10972661db78d0e0a2d4a4c28fc3bf93617baMichael KrufkyMODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
5164c66c9205c0788e18eb09d482461aa2f551ee046Michael KrufkyMODULE_LICENSE("GPL");
5174c66c9205c0788e18eb09d482461aa2f551ee046Michael KrufkyMODULE_VERSION("0.1");
5184c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky
5194c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky/*
5204c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky * Overrides for Emacs so that we follow Linus's tabbing style.
5214c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky * ---------------------------------------------------------------------------
5224c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky * Local variables:
5234c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky * c-basic-offset: 8
5244c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky * End:
5254c66c9205c0788e18eb09d482461aa2f551ee046Michael Krufky */
526