mt2131.c revision 6d8976164dd7d10d25fe940b8546265f60ad52cd
1f47623a04dab402fb2c18fe516a174bc02005629Steven Toth/* 2f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * Driver for Microtune MT2131 "QAM/8VSB single chip tuner" 3f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * 46d8976164dd7d10d25fe940b8546265f60ad52cdSteven Toth * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org> 5f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * 6f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * This program is free software; you can redistribute it and/or modify 7f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * it under the terms of the GNU General Public License as published by 8f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * the Free Software Foundation; either version 2 of the License, or 9f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * (at your option) any later version. 10f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * 11f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * This program is distributed in the hope that it will be useful, 12f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * but WITHOUT ANY WARRANTY; without even the implied warranty of 13f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * 15f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * GNU General Public License for more details. 16f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * 17f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * You should have received a copy of the GNU General Public License 18f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * along with this program; if not, write to the Free Software 19f47623a04dab402fb2c18fe516a174bc02005629Steven Toth * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20f47623a04dab402fb2c18fe516a174bc02005629Steven Toth */ 21f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 22f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include <linux/module.h> 23f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include <linux/delay.h> 24f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include <linux/dvb/frontend.h> 25f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include <linux/i2c.h> 26f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 27f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include "dvb_frontend.h" 28f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 29f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include "mt2131.h" 30f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#include "mt2131_priv.h" 31f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 32f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int debug; 33f47623a04dab402fb2c18fe516a174bc02005629Steven Tothmodule_param(debug, int, 0644); 34f47623a04dab402fb2c18fe516a174bc02005629Steven TothMODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); 35f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 36f47623a04dab402fb2c18fe516a174bc02005629Steven Toth#define dprintk(level,fmt, arg...) if (debug >= level) \ 37f47623a04dab402fb2c18fe516a174bc02005629Steven Toth printk(KERN_INFO "%s: " fmt, "mt2131", ## arg) 38f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 39f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic u8 mt2131_config1[] = { 40f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 0x01, 41f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88, 42f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32, 43f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80, 44f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00 45f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}; 46f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 47f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic u8 mt2131_config2[] = { 48f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 0x10, 49f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04 50f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}; 51f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 52f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val) 53f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 54f47623a04dab402fb2c18fe516a174bc02005629Steven Toth struct i2c_msg msg[2] = { 553873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky { .addr = priv->cfg->i2c_address, .flags = 0, 563873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky .buf = ®, .len = 1 }, 573873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, 583873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky .buf = val, .len = 1 }, 59f47623a04dab402fb2c18fe516a174bc02005629Steven Toth }; 60f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 61f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (i2c_transfer(priv->i2c, msg, 2) != 2) { 62f47623a04dab402fb2c18fe516a174bc02005629Steven Toth printk(KERN_WARNING "mt2131 I2C read failed\n"); 63f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return -EREMOTEIO; 64f47623a04dab402fb2c18fe516a174bc02005629Steven Toth } 65f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return 0; 66f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 67f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 68f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val) 69f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 70f47623a04dab402fb2c18fe516a174bc02005629Steven Toth u8 buf[2] = { reg, val }; 713873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0, 723873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky .buf = buf, .len = 2 }; 73f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 74f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (i2c_transfer(priv->i2c, &msg, 1) != 1) { 75f47623a04dab402fb2c18fe516a174bc02005629Steven Toth printk(KERN_WARNING "mt2131 I2C write failed\n"); 76f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return -EREMOTEIO; 77f47623a04dab402fb2c18fe516a174bc02005629Steven Toth } 78f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return 0; 79f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 80f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 81f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len) 82f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 833873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky struct i2c_msg msg = { .addr = priv->cfg->i2c_address, 843873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky .flags = 0, .buf = buf, .len = len }; 85f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 86f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (i2c_transfer(priv->i2c, &msg, 1) != 1) { 873873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n", 883873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky (int)len); 89f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return -EREMOTEIO; 90f47623a04dab402fb2c18fe516a174bc02005629Steven Toth } 91f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return 0; 92f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 93f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 943873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufkystatic int mt2131_set_params(struct dvb_frontend *fe, 953873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky struct dvb_frontend_parameters *params) 96f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 97f47623a04dab402fb2c18fe516a174bc02005629Steven Toth struct mt2131_priv *priv; 98f47623a04dab402fb2c18fe516a174bc02005629Steven Toth int ret=0, i; 99f47623a04dab402fb2c18fe516a174bc02005629Steven Toth u32 freq; 100f47623a04dab402fb2c18fe516a174bc02005629Steven Toth u8 if_band_center; 1013873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky u32 f_lo1, f_lo2; 1023873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky u32 div1, num1, div2, num2; 103f47623a04dab402fb2c18fe516a174bc02005629Steven Toth u8 b[8]; 104f47623a04dab402fb2c18fe516a174bc02005629Steven Toth u8 lockval = 0; 105f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 106f47623a04dab402fb2c18fe516a174bc02005629Steven Toth priv = fe->tuner_priv; 107f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (fe->ops.info.type == FE_OFDM) 108f47623a04dab402fb2c18fe516a174bc02005629Steven Toth priv->bandwidth = params->u.ofdm.bandwidth; 109f47623a04dab402fb2c18fe516a174bc02005629Steven Toth else 110f47623a04dab402fb2c18fe516a174bc02005629Steven Toth priv->bandwidth = 0; 111f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 112f47623a04dab402fb2c18fe516a174bc02005629Steven Toth freq = params->frequency / 1000; // Hz -> kHz 113271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison dprintk(1, "%s() freq=%d\n", __func__, freq); 114f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 115f47623a04dab402fb2c18fe516a174bc02005629Steven Toth f_lo1 = freq + MT2131_IF1 * 1000; 116f47623a04dab402fb2c18fe516a174bc02005629Steven Toth f_lo1 = (f_lo1 / 250) * 250; 117f47623a04dab402fb2c18fe516a174bc02005629Steven Toth f_lo2 = f_lo1 - freq - MT2131_IF2; 118f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 119195ccf67738f41eae557ba0322b33b15a39fd88fSteven Toth priv->frequency = (f_lo1 - f_lo2 - MT2131_IF2) * 1000; 120f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 121f47623a04dab402fb2c18fe516a174bc02005629Steven Toth /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */ 122f47623a04dab402fb2c18fe516a174bc02005629Steven Toth num1 = f_lo1 * 64 / (MT2131_FREF / 128); 123f47623a04dab402fb2c18fe516a174bc02005629Steven Toth div1 = num1 / 8192; 124f47623a04dab402fb2c18fe516a174bc02005629Steven Toth num1 &= 0x1fff; 125f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 126f47623a04dab402fb2c18fe516a174bc02005629Steven Toth /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */ 127f47623a04dab402fb2c18fe516a174bc02005629Steven Toth num2 = f_lo2 * 64 / (MT2131_FREF / 128); 128f47623a04dab402fb2c18fe516a174bc02005629Steven Toth div2 = num2 / 8192; 129f47623a04dab402fb2c18fe516a174bc02005629Steven Toth num2 &= 0x1fff; 130f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 131f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 82500) if_band_center = 0x00; else 132f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 137500) if_band_center = 0x01; else 133f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 192500) if_band_center = 0x02; else 134f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 247500) if_band_center = 0x03; else 135f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 302500) if_band_center = 0x04; else 136f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 357500) if_band_center = 0x05; else 137f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 412500) if_band_center = 0x06; else 138f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 467500) if_band_center = 0x07; else 139f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 522500) if_band_center = 0x08; else 140f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 577500) if_band_center = 0x09; else 141f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 632500) if_band_center = 0x0A; else 142f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 687500) if_band_center = 0x0B; else 143f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 742500) if_band_center = 0x0C; else 144f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 797500) if_band_center = 0x0D; else 145f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 852500) if_band_center = 0x0E; else 146f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 907500) if_band_center = 0x0F; else 147f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 962500) if_band_center = 0x10; else 148f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 1017500) if_band_center = 0x11; else 149f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13; 150f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 151f47623a04dab402fb2c18fe516a174bc02005629Steven Toth b[0] = 1; 152f47623a04dab402fb2c18fe516a174bc02005629Steven Toth b[1] = (num1 >> 5) & 0xFF; 153f47623a04dab402fb2c18fe516a174bc02005629Steven Toth b[2] = (num1 & 0x1F); 154f47623a04dab402fb2c18fe516a174bc02005629Steven Toth b[3] = div1; 155f47623a04dab402fb2c18fe516a174bc02005629Steven Toth b[4] = (num2 >> 5) & 0xFF; 156f47623a04dab402fb2c18fe516a174bc02005629Steven Toth b[5] = num2 & 0x1F; 157f47623a04dab402fb2c18fe516a174bc02005629Steven Toth b[6] = div2; 158f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 159f47623a04dab402fb2c18fe516a174bc02005629Steven Toth dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2); 160f47623a04dab402fb2c18fe516a174bc02005629Steven Toth dprintk(1, "PLL freq=%dkHz band=%d\n", (int)freq, (int)if_band_center); 161f47623a04dab402fb2c18fe516a174bc02005629Steven Toth dprintk(1, "PLL f_lo1=%dkHz f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2); 162f47623a04dab402fb2c18fe516a174bc02005629Steven Toth dprintk(1, "PLL div1=%d num1=%d div2=%d num2=%d\n", 163f47623a04dab402fb2c18fe516a174bc02005629Steven Toth (int)div1, (int)num1, (int)div2, (int)num2); 164f47623a04dab402fb2c18fe516a174bc02005629Steven Toth dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n", 165f47623a04dab402fb2c18fe516a174bc02005629Steven Toth (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5], 166f47623a04dab402fb2c18fe516a174bc02005629Steven Toth (int)b[6]); 167f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 168f47623a04dab402fb2c18fe516a174bc02005629Steven Toth ret = mt2131_writeregs(priv,b,7); 169f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (ret < 0) 170f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return ret; 171f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 172f47623a04dab402fb2c18fe516a174bc02005629Steven Toth mt2131_writereg(priv, 0x0b, if_band_center); 173f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 174f47623a04dab402fb2c18fe516a174bc02005629Steven Toth /* Wait for lock */ 175f47623a04dab402fb2c18fe516a174bc02005629Steven Toth i = 0; 176f47623a04dab402fb2c18fe516a174bc02005629Steven Toth do { 177f47623a04dab402fb2c18fe516a174bc02005629Steven Toth mt2131_readreg(priv, 0x08, &lockval); 178f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if ((lockval & 0x88) == 0x88) 179f47623a04dab402fb2c18fe516a174bc02005629Steven Toth break; 180f47623a04dab402fb2c18fe516a174bc02005629Steven Toth msleep(4); 181f47623a04dab402fb2c18fe516a174bc02005629Steven Toth i++; 182f47623a04dab402fb2c18fe516a174bc02005629Steven Toth } while (i < 10); 183f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 184f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return ret; 185f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 186f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 187f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency) 188f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 189f47623a04dab402fb2c18fe516a174bc02005629Steven Toth struct mt2131_priv *priv = fe->tuner_priv; 190271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison dprintk(1, "%s()\n", __func__); 191f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *frequency = priv->frequency; 192f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return 0; 193f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 194f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 195f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) 196f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 197f47623a04dab402fb2c18fe516a174bc02005629Steven Toth struct mt2131_priv *priv = fe->tuner_priv; 198271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison dprintk(1, "%s()\n", __func__); 199f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *bandwidth = priv->bandwidth; 200f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return 0; 201f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 202f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 203f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_get_status(struct dvb_frontend *fe, u32 *status) 204f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 205f47623a04dab402fb2c18fe516a174bc02005629Steven Toth struct mt2131_priv *priv = fe->tuner_priv; 206f47623a04dab402fb2c18fe516a174bc02005629Steven Toth u8 lock_status = 0; 207f47623a04dab402fb2c18fe516a174bc02005629Steven Toth u8 afc_status = 0; 208f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 209f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *status = 0; 210f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 211f47623a04dab402fb2c18fe516a174bc02005629Steven Toth mt2131_readreg(priv, 0x08, &lock_status); 212f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if ((lock_status & 0x88) == 0x88) 213f47623a04dab402fb2c18fe516a174bc02005629Steven Toth *status = TUNER_STATUS_LOCKED; 214f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 215f47623a04dab402fb2c18fe516a174bc02005629Steven Toth mt2131_readreg(priv, 0x09, &afc_status); 216f47623a04dab402fb2c18fe516a174bc02005629Steven Toth dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n", 217271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison __func__, lock_status, afc_status); 218f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 219f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return 0; 220f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 221f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 222f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_init(struct dvb_frontend *fe) 223f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 224f47623a04dab402fb2c18fe516a174bc02005629Steven Toth struct mt2131_priv *priv = fe->tuner_priv; 225f47623a04dab402fb2c18fe516a174bc02005629Steven Toth int ret; 226271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison dprintk(1, "%s()\n", __func__); 227f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 2283873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky if ((ret = mt2131_writeregs(priv, mt2131_config1, 2293873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky sizeof(mt2131_config1))) < 0) 230f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return ret; 231f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 232f47623a04dab402fb2c18fe516a174bc02005629Steven Toth mt2131_writereg(priv, 0x0b, 0x09); 233f47623a04dab402fb2c18fe516a174bc02005629Steven Toth mt2131_writereg(priv, 0x15, 0x47); 234f47623a04dab402fb2c18fe516a174bc02005629Steven Toth mt2131_writereg(priv, 0x07, 0xf2); 235f47623a04dab402fb2c18fe516a174bc02005629Steven Toth mt2131_writereg(priv, 0x0b, 0x01); 236f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 2373873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky if ((ret = mt2131_writeregs(priv, mt2131_config2, 2383873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky sizeof(mt2131_config2))) < 0) 239f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return ret; 240f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 241f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return ret; 242f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 243f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 244f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic int mt2131_release(struct dvb_frontend *fe) 245f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 246271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison dprintk(1, "%s()\n", __func__); 247f47623a04dab402fb2c18fe516a174bc02005629Steven Toth kfree(fe->tuner_priv); 248f47623a04dab402fb2c18fe516a174bc02005629Steven Toth fe->tuner_priv = NULL; 249f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return 0; 250f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 251f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 252f47623a04dab402fb2c18fe516a174bc02005629Steven Tothstatic const struct dvb_tuner_ops mt2131_tuner_ops = { 253f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .info = { 254f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .name = "Microtune MT2131", 255f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .frequency_min = 48000000, 256f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .frequency_max = 860000000, 257f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .frequency_step = 50000, 258f47623a04dab402fb2c18fe516a174bc02005629Steven Toth }, 259f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 260f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .release = mt2131_release, 261f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .init = mt2131_init, 262f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 263f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .set_params = mt2131_set_params, 264f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .get_frequency = mt2131_get_frequency, 265f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .get_bandwidth = mt2131_get_bandwidth, 266f47623a04dab402fb2c18fe516a174bc02005629Steven Toth .get_status = mt2131_get_status 267f47623a04dab402fb2c18fe516a174bc02005629Steven Toth}; 268f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 2693873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufkystruct dvb_frontend * mt2131_attach(struct dvb_frontend *fe, 2703873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky struct i2c_adapter *i2c, 2713873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky struct mt2131_config *cfg, u16 if1) 272f47623a04dab402fb2c18fe516a174bc02005629Steven Toth{ 273f47623a04dab402fb2c18fe516a174bc02005629Steven Toth struct mt2131_priv *priv = NULL; 274f47623a04dab402fb2c18fe516a174bc02005629Steven Toth u8 id = 0; 275f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 276271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison dprintk(1, "%s()\n", __func__); 277f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 278f47623a04dab402fb2c18fe516a174bc02005629Steven Toth priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL); 279f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (priv == NULL) 280f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return NULL; 281f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 282f47623a04dab402fb2c18fe516a174bc02005629Steven Toth priv->cfg = cfg; 283f47623a04dab402fb2c18fe516a174bc02005629Steven Toth priv->bandwidth = 6000000; /* 6MHz */ 284f47623a04dab402fb2c18fe516a174bc02005629Steven Toth priv->i2c = i2c; 285f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 286f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if (mt2131_readreg(priv, 0, &id) != 0) { 287f47623a04dab402fb2c18fe516a174bc02005629Steven Toth kfree(priv); 288f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return NULL; 289f47623a04dab402fb2c18fe516a174bc02005629Steven Toth } 290f47623a04dab402fb2c18fe516a174bc02005629Steven Toth if ( (id != 0x3E) && (id != 0x3F) ) { 2913873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n", 2923873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky cfg->i2c_address); 293f47623a04dab402fb2c18fe516a174bc02005629Steven Toth kfree(priv); 294f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return NULL; 295f47623a04dab402fb2c18fe516a174bc02005629Steven Toth } 296f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 2973873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n", 2983873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky cfg->i2c_address); 2993873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops, 3003873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky sizeof(struct dvb_tuner_ops)); 301f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 302f47623a04dab402fb2c18fe516a174bc02005629Steven Toth fe->tuner_priv = priv; 303f47623a04dab402fb2c18fe516a174bc02005629Steven Toth return fe; 304f47623a04dab402fb2c18fe516a174bc02005629Steven Toth} 305f47623a04dab402fb2c18fe516a174bc02005629Steven TothEXPORT_SYMBOL(mt2131_attach); 306f47623a04dab402fb2c18fe516a174bc02005629Steven Toth 307f47623a04dab402fb2c18fe516a174bc02005629Steven TothMODULE_AUTHOR("Steven Toth"); 308f47623a04dab402fb2c18fe516a174bc02005629Steven TothMODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver"); 309f47623a04dab402fb2c18fe516a174bc02005629Steven TothMODULE_LICENSE("GPL"); 3103873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky 3113873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky/* 3123873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky * Local variables: 3133873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky * c-basic-offset: 8 3143873dd041465799cfdeb642531c0ade4fb6614e5Michael Krufky */ 315