11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Driver for Philips TDA8083 based QPSK Demodulator 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Copyright (C) 2001 Convergence Integrated Media GmbH 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds written by Ralph Metzler <ralph@convergence.de> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds adoption to the new DVB frontend API and diagnostic ioctl's 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds by Holger Waechtler <holger@convergence.de> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is free software; you can redistribute it and/or modify 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it under the terms of the GNU General Public License as published by 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds the Free Software Foundation; either version 2 of the License, or 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (at your option) any later version. 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is distributed in the hope that it will be useful, 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds but WITHOUT ANY WARRANTY; without even the implied warranty of 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GNU General Public License for more details. 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds You should have received a copy of the GNU General Public License 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds along with this program; if not, write to the Free Software 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 324e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/jiffies.h> 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "dvb_frontend.h" 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "tda8083.h" 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct tda8083_state { 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_adapter* i2c; 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* configuration settings */ 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct tda8083_config* config; 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_frontend frontend; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug; 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define dprintk(args...) \ 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { \ 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (debug) printk(KERN_DEBUG "tda8083: " args); \ 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while (0) 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 tda8083_init_tab [] = { 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea, 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10, 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8, 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00, 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 0x00, 0x00, 0x00, 0x00 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data) 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 buf [] = { reg, data }; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 679101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab ret = i2c_transfer(state->i2c, &msg, 1); 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 699101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab if (ret != 1) 709101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab dprintk ("%s: writereg error (reg %02x, ret == %i)\n", 71271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison __func__, reg, ret); 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 739101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab return (ret != 1) ? -1 : 0; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len) 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = ®1, .len = 1 }, 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } }; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = i2c_transfer(state->i2c, msg, 2); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret != 2) 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk ("%s: readreg error (reg %02x, ret == %i)\n", 86271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison __func__, reg1, ret); 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 889101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab return ret == 2 ? 0 : -1; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg) 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 val; 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_readregs (state, reg, &val, 1); 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return val; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_set_inversion (struct tda8083_state* state, fe_spectral_inversion_t inversion) 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* XXX FIXME: implement other modes than FEC_AUTO */ 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (inversion == INVERSION_AUTO) 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_set_fec (struct tda8083_state* state, fe_code_rate_t fec) 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fec == FEC_AUTO) 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tda8083_writereg (state, 0x07, 0xff); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (fec >= FEC_1_2 && fec <= FEC_8_9) 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec)); 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic fe_code_rate_t tda8083_get_fec (struct tda8083_state* state) 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 index; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4, 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 }; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds index = tda8083_readreg(state, 0x0e) & 0x07; 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return fec_tab [index]; 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate) 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1339101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab u32 ratio; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 tmp; 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 filter; 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (srate > 32000000) 1389101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab srate = 32000000; 1399101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab if (srate < 500000) 1409101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab srate = 500000; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds filter = 0; 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (srate < 24000000) 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds filter = 2; 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (srate < 16000000) 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds filter = 3; 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = 31250 << 16; 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ratio = tmp / srate; 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = (tmp % srate) << 8; 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ratio = (ratio << 8) + tmp / srate; 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = (tmp % srate) << 8; 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ratio = (ratio << 8) + tmp / srate; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio); 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x05, filter); 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x03, (ratio >> 8) & 0xff); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x04, (ratio ) & 0xff); 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x3c); 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x04); 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long start = jiffies; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (jiffies - start < timeout && 1759101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab !(tda8083_readreg(state, 0x02) & 0x80)) 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(50); 178c2c1b4156a447f113ef4d167decce29399c2667cPeter Senna Tschudin } 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_set_tone (struct tda8083_state* state, fe_sec_tone_mode_t tone) 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x26, 0xf1); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (tone) { 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_TONE_OFF: 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tda8083_writereg (state, 0x29, 0x00); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_TONE_ON: 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tda8083_writereg (state, 0x29, 0x80); 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1922028c71d54e7bd7eb4470d5968f581f9f9284406Joe Perches } 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_set_voltage (struct tda8083_state* state, fe_sec_voltage_t voltage) 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (voltage) { 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_VOLTAGE_13: 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tda8083_writereg (state, 0x20, 0x00); 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_VOLTAGE_18: 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tda8083_writereg (state, 0x20, 0x11); 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 2042028c71d54e7bd7eb4470d5968f581f9f9284406Joe Perches } 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_cmd_t burst) 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (burst) { 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_MINI_A: 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x29, (5 << 2)); /* send burst A */ 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_MINI_B: 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x29, (7 << 2)); /* send B */ 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 218c2c1b4156a447f113ef4d167decce29399c2667cPeter Senna Tschudin } 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_wait_diseqc_fifo (state, 100); 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_send_diseqc_msg (struct dvb_frontend* fe, 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_diseqc_master_cmd *m) 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 228b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */ 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0; i<m->msg_len; i++) 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x23 + i, m->msg[i]); 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */ 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_wait_diseqc_fifo (state, 100); 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status) 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 245b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 signal = ~tda8083_readreg (state, 0x01); 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 sync = tda8083_readreg (state, 0x02); 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *status = 0; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (signal > 10) 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *status |= FE_HAS_SIGNAL; 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sync & 0x01) 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *status |= FE_HAS_CARRIER; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sync & 0x02) 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *status |= FE_HAS_VITERBI; 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sync & 0x10) 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *status |= FE_HAS_SYNC; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 264dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich if (sync & 0x20) /* frontend can not lock */ 265dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich *status |= FE_TIMEDOUT; 266dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((sync & 0x1f) == 0x1f) 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *status |= FE_HAS_LOCK; 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 273dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrichstatic int tda8083_read_ber(struct dvb_frontend* fe, u32* ber) 274dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich{ 275dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich struct tda8083_state* state = fe->demodulator_priv; 276dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich int ret; 277dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich u8 buf[3]; 278dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich 279dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich if ((ret = tda8083_readregs(state, 0x0b, buf, sizeof(buf)))) 280dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich return ret; 281dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich 282dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2]; 283dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich 284dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich return 0; 285dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich} 286dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength) 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 289b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 signal = ~tda8083_readreg (state, 0x01); 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *strength = (signal << 8) | signal; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_read_snr(struct dvb_frontend* fe, u16* snr) 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 299b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 _snr = tda8083_readreg (state, 0x08); 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *snr = (_snr << 8) | _snr; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 307dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrichstatic int tda8083_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) 308dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich{ 309dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich struct tda8083_state* state = fe->demodulator_priv; 310dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich 311dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich *ucblocks = tda8083_readreg(state, 0x0f); 312dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich if (*ucblocks == 0xff) 313dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich *ucblocks = 0xffffffff; 314dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich 315dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich return 0; 316dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich} 317dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich 318042e5eb79f3c9eba2ad382f079834af20cbecc17Mauro Carvalho Chehabstatic int tda8083_set_frontend(struct dvb_frontend *fe) 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 320042e5eb79f3c9eba2ad382f079834af20cbecc17Mauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 321b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 323dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (fe->ops.tuner_ops.set_params) { 32414d24d148c7521b2b88b396652e36f55d061e195Mauro Carvalho Chehab fe->ops.tuner_ops.set_params(fe); 325dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 326d21eac0385dd11d3118ffd374451916fa413c0dfAndrew de Quincey } 327d21eac0385dd11d3118ffd374451916fa413c0dfAndrew de Quincey 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_set_inversion (state, p->inversion); 329042e5eb79f3c9eba2ad382f079834af20cbecc17Mauro Carvalho Chehab tda8083_set_fec(state, p->fec_inner); 330042e5eb79f3c9eba2ad382f079834af20cbecc17Mauro Carvalho Chehab tda8083_set_symbolrate(state, p->symbol_rate); 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x3c); 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x04); 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3387c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehabstatic int tda8083_get_frontend(struct dvb_frontend *fe) 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3407c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 341b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: get symbolrate & frequency offset...*/ 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /*p->frequency = ???;*/ 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ? 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds INVERSION_ON : INVERSION_OFF; 347042e5eb79f3c9eba2ad382f079834af20cbecc17Mauro Carvalho Chehab p->fec_inner = tda8083_get_fec(state); 348042e5eb79f3c9eba2ad382f079834af20cbecc17Mauro Carvalho Chehab /*p->symbol_rate = tda8083_get_symbolrate (state);*/ 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_sleep(struct dvb_frontend* fe) 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 355b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x02); 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_init(struct dvb_frontend* fe) 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 363b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0; i<44; i++) 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, i, tda8083_init_tab[i]); 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x3c); 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x04); 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 377b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_send_diseqc_burst (state, burst); 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x3c); 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x04); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 388b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_set_tone (state, tone); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x3c); 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x04); 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 399b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_set_voltage (state, voltage); 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x3c); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tda8083_writereg (state, 0x00, 0x04); 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void tda8083_release(struct dvb_frontend* fe) 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 410b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct tda8083_state* state = fe->demodulator_priv; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(state); 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_frontend_ops tda8083_ops; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct dvb_frontend* tda8083_attach(const struct tda8083_config* config, 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_adapter* i2c) 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct tda8083_state* state = NULL; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* allocate memory for the internal state */ 422084e24acc906c162c92de7df807190856ae60928Matthias Schwarzott state = kzalloc(sizeof(struct tda8083_state), GFP_KERNEL); 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (state == NULL) goto error; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* setup the state */ 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds state->config = config; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds state->i2c = i2c; 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the demod is there */ 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((tda8083_readreg(state, 0x00)) != 0x05) goto error; 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* create dvb_frontend */ 433dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops)); 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds state->frontend.demodulator_priv = state; 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return &state->frontend; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldserror: 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(state); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_frontend_ops tda8083_ops = { 443042e5eb79f3c9eba2ad382f079834af20cbecc17Mauro Carvalho Chehab .delsys = { SYS_DVBS }, 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .info = { 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "Philips TDA8083 DVB-S", 4464f76b672c4f9ceb9e7e0aa6224293da0ae7430daOliver Endriss .frequency_min = 920000, /* TDA8060 */ 4474f76b672c4f9ceb9e7e0aa6224293da0ae7430daOliver Endriss .frequency_max = 2200000, /* TDA8060 */ 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .frequency_stepsize = 125, /* kHz for QPSK frontends */ 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* .frequency_tolerance = ???,*/ 4504f76b672c4f9ceb9e7e0aa6224293da0ae7430daOliver Endriss .symbol_rate_min = 12000000, 4514f76b672c4f9ceb9e7e0aa6224293da0ae7430daOliver Endriss .symbol_rate_max = 30000000, 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* .symbol_rate_tolerance = ???,*/ 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .caps = FE_CAN_INVERSION_AUTO | 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FE_CAN_QPSK | FE_CAN_MUTE_TS 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = tda8083_release, 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = tda8083_init, 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .sleep = tda8083_sleep, 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 465042e5eb79f3c9eba2ad382f079834af20cbecc17Mauro Carvalho Chehab .set_frontend = tda8083_set_frontend, 466042e5eb79f3c9eba2ad382f079834af20cbecc17Mauro Carvalho Chehab .get_frontend = tda8083_get_frontend, 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_status = tda8083_read_status, 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_signal_strength = tda8083_read_signal_strength, 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_snr = tda8083_read_snr, 471dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich .read_ber = tda8083_read_ber, 472dbb2e6392b4fe350e549cdc2d42cebf3b3574a6aChristoph Haubrich .read_ucblocks = tda8083_read_ucblocks, 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .diseqc_send_master_cmd = tda8083_send_diseqc_msg, 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .diseqc_send_burst = tda8083_diseqc_send_burst, 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .set_tone = tda8083_diseqc_set_tone, 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .set_voltage = tda8083_diseqc_set_voltage, 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(debug, int, 0644); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator"); 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(tda8083_attach); 488