budget.c revision 32e4c3a5622e832938aa0272e21a292564ff090a
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * budget.c: driver for the SAA7146 based Budget DVB cards 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Compiled from various sources by Michael Hunold <michael@mihu.de> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999-2002 Ralph Metzler 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * & Marcus Metzler for convergence integrated media GmbH 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 26feb2004 Support for FS Activy Card (Grundig tuner) by 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Michael Dreher <michael@5dot1.de>, 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Oliver Endriss <o.endriss@gmx.de> and 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Andreas 'randy' Weinberger 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modify it under the terms of the GNU General Public License 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as published by the Free Software Foundation; either version 2 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the License, or (at your option) any later version. 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is distributed in the hope that it will be useful, 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * but WITHOUT ANY WARRANTY; without even the implied warranty of 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * GNU General Public License for more details. 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * along with this program; if not, write to the Free Software 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the project's page is at http://www.linuxtv.org/dvb/ 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "budget.h" 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "stv0299.h" 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ves1x93.h" 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ves1820.h" 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "l64781.h" 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "tda8083.h" 4396bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey#include "s5h1420.h" 442f27bdce972ceb97a2fd109a77546c37aa499fc9Oliver Endriss#include "lnbp21.h" 45265366e8fb8c31706711aea5f79d763816a968dbPerceval Anichini#include "bsru6.h" 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void Set22K (struct budget *budget, int state) 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct saa7146_dev *dev=budget->dev; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "budget: %p\n", budget); 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO)); 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Diseqc functions only for TT Budget card */ 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* taken from the Skyvision DVB driver by 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Ralph Metzler <rjkm@metzlerbros.de> */ 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void DiseqcSendBit (struct budget *budget, int data) 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct saa7146_dev *dev=budget->dev; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "budget: %p\n", budget); 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(data ? 500 : 1000); 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(data ? 1000 : 500); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void DiseqcSendByte (struct budget *budget, int data) 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, par=1, d; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "budget: %p\n", budget); 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=7; i>=0; i--) { 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds d = (data>>i)&1; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds par ^= d; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DiseqcSendBit(budget, d); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DiseqcSendBit(budget, par); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst) 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct saa7146_dev *dev=budget->dev; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "budget: %p\n", budget); 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(16); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i=0; i<len; i++) 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DiseqcSendByte(budget, msg[i]); 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mdelay(16); 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (burst!=-1) { 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (burst) 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DiseqcSendByte(budget, 0xff); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(12500); 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msleep(20); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Routines for the Fujitsu Siemens Activy budget card 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 22 kHz tone and DiSEqC are handled by the frontend. 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Voltage must be set here. 117f49cc15bbe37b767286fdd7abe65810e750cf70aOliver Endriss * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct saa7146_dev *dev=budget->dev; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "budget: %p\n", budget); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (voltage) { 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_VOLTAGE_13: 127f49cc15bbe37b767286fdd7abe65810e750cf70aOliver Endriss saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_VOLTAGE_18: 131f49cc15bbe37b767286fdd7abe65810e750cf70aOliver Endriss saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 134f49cc15bbe37b767286fdd7abe65810e750cf70aOliver Endriss case SEC_VOLTAGE_OFF: 135f49cc15bbe37b767286fdd7abe65810e750cf70aOliver Endriss saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); 136f49cc15bbe37b767286fdd7abe65810e750cf70aOliver Endriss break; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int siemens_budget_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget* budget = (struct budget*) fe->dvb->priv; 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SetVoltage_Activy (budget, voltage); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget* budget = (struct budget*) fe->dvb->priv; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (tone) { 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_TONE_ON: 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Set22K (budget, 1); 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SEC_TONE_OFF: 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Set22K (budget, 0); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget* budget = (struct budget*) fe->dvb->priv; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0); 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget* budget = (struct budget*) fe->dvb->priv; 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SendDiSEqCMsg (budget, 0, NULL, minicmd); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 189067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quinceystatic int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget* budget = (struct budget*) fe->dvb->priv; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 pwr = 0; 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 buf[4]; 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 div = (params->frequency + 479500) / 125; 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (params->frequency > 2000000) pwr = 3; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (params->frequency > 1800000) pwr = 2; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (params->frequency > 1600000) pwr = 1; 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (params->frequency > 1200000) pwr = 0; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (params->frequency >= 1100000) pwr = 1; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else pwr = 2; 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] = (div >> 8) & 0x7f; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[1] = div & 0xff; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[2] = ((div & 0x18000) >> 10) | 0x95; 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[3] = (pwr << 6) | 0x30; 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2099101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab // NOTE: since we're using a prescaler of 2, we set the 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // divisor frequency to 62.5kHz and divide by 125 above 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 212dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (fe->ops.i2c_gate_ctrl) 213dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher fe->ops.i2c_gate_ctrl(fe, 1); 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ves1x93_config alps_bsrv2_config = 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .demod_address = 0x08, 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .xin = 90100000UL, 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .invert_pwm = 0, 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 225067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quinceystatic int alps_tdbe2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget* budget = (struct budget*) fe->dvb->priv; 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 div; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 data[4]; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds div = (params->frequency + 35937500 + 31250) / 62500; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[0] = (div >> 8) & 0x7f; 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[1] = div & 0xff; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[2] = 0x85 | ((div >> 10) & 0x60); 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81); 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 239dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (fe->ops.i2c_gate_ctrl) 240dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher fe->ops.i2c_gate_ctrl(fe, 1); 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ves1820_config alps_tdbe2_config = { 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .demod_address = 0x09, 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .xin = 57840000UL, 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .invert = 1, 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .selagc = VES1820_SELAGC_SIGNAMPERR, 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 252067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quinceystatic int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget* budget = (struct budget*) fe->dvb->priv; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 div; 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 cfg, cpump, band_select; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 data[4]; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds div = (36125000 + params->frequency) / 166666; 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cfg = 0x88; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (params->frequency < 175000000) cpump = 2; 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (params->frequency < 390000000) cpump = 1; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (params->frequency < 470000000) cpump = 2; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (params->frequency < 750000000) cpump = 1; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else cpump = 3; 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (params->frequency < 175000000) band_select = 0x0e; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else if (params->frequency < 470000000) band_select = 0x05; 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else band_select = 0x03; 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[0] = (div >> 8) & 0x7f; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[1] = div & 0xff; 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[2] = ((div >> 10) & 0x60) | cfg; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[3] = (cpump << 6) | band_select; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 279dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (fe->ops.i2c_gate_ctrl) 280dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher fe->ops.i2c_gate_ctrl(fe, 1); 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct l64781_config grundig_29504_401_config = { 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .demod_address = 0x55, 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 289067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quinceystatic int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget* budget = (struct budget*) fe->dvb->priv; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 div; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 data[4]; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds div = params->frequency / 125; 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[0] = (div >> 8) & 0x7f; 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[1] = div & 0xff; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[2] = 0x8e; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[3] = 0x00; 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 302dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (fe->ops.i2c_gate_ctrl) 303dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher fe->ops.i2c_gate_ctrl(fe, 1); 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct tda8083_config grundig_29504_451_config = { 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .demod_address = 0x68, 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 312067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quinceystatic int s5h1420_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) 31396bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey{ 31496bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey struct budget* budget = (struct budget*) fe->dvb->priv; 31596bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey u32 div; 31696bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey u8 data[4]; 31796bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; 31896bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey 31996bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey div = params->frequency / 1000; 32096bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey data[0] = (div >> 8) & 0x7f; 32196bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey data[1] = div & 0xff; 32296bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey data[2] = 0xc2; 32396bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey 32496bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey if (div < 1450) 32596bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey data[3] = 0x00; 32696bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey else if (div < 1850) 32796bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey data[3] = 0x40; 32896bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey else if (div < 2000) 32996bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey data[3] = 0x80; 33096bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey else 33196bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey data[3] = 0xc0; 33296bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey 333dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (fe->ops.i2c_gate_ctrl) 334dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher fe->ops.i2c_gate_ctrl(fe, 1); 33596bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO; 33696bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey 33796bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey return 0; 33896bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey} 33996bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey 34096bf2f2b549aab918f4225841df54c3d58896822Andrew de Quinceystatic struct s5h1420_config s5h1420_config = { 34196bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey .demod_address = 0x53, 342a9d6a80b41c04e8ff4c7442cc35f5df610863841Andrew de Quincey .invert = 1, 34396bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey}; 34496bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u8 read_pwm(struct budget* budget) 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 b = 0xff; 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 pwm; 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 }, 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} }; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3529101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab if ((i2c_transfer(&budget->i2c_adap, msg, 2) != 2) || (pwm == 0xff)) 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pwm = 0x48; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return pwm; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void frontend_init(struct budget *budget) 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch(budget->dev->pci->subsystem_device) { 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1003: // Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1013: 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // try the ALPS BSRV2 first of all 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap); 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (budget->dvb_frontend) { 366dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params; 367dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd; 368dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst; 369dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.set_tone = budget_set_tone; 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // try the ALPS BSRU6 now 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (budget->dvb_frontend) { 376dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; 377067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quincey budget->dvb_frontend->tuner_priv = &budget->i2c_adap; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1004: // Hauppauge/TT DVB-C budget (ves1820/ALPS TDBE2(sp5659)) 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dvb_frontend = ves1820_attach(&alps_tdbe2_config, &budget->i2c_adap, read_pwm(budget)); 385067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quincey if (budget->dvb_frontend) { 386dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.tuner_ops.set_params = alps_tdbe2_tuner_set_params; 387067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quincey break; 388067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quincey } 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x1005: // Hauppauge/TT Nova-T budget (L64781/Grundig 29504-401(tsa5060)) 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dvb_frontend = l64781_attach(&grundig_29504_401_config, &budget->i2c_adap); 394067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quincey if (budget->dvb_frontend) { 395dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_401_tuner_set_params; 396067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quincey break; 397067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quincey } 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x4f60: // Fujitsu Siemens Activy Budget-S PCI rev AL (stv0299/ALPS BSRU6(tsa5059)) 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (budget->dvb_frontend) { 403dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params; 404067145bdd41bcb090510c73cc6ecd7b09213f038Andrew de Quincey budget->dvb_frontend->tuner_priv = &budget->i2c_adap; 405dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; 406dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0x4f61: // Fujitsu Siemens Activy Budget-S PCI rev GR (tda8083/Grundig 29504-451(tsa5522)) 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (budget->dvb_frontend) { 413dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params; 414dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.set_voltage = siemens_budget_set_voltage; 415dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 41896bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey 41996bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey case 0x1016: // Hauppauge/TT Nova-S SE (samsung s5h1420/????(tda8260)) 42096bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey budget->dvb_frontend = s5h1420_attach(&s5h1420_config, &budget->i2c_adap); 42196bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey if (budget->dvb_frontend) { 422dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params; 423d020542fdaaa69e3061e15d096f11fbc4aeeb93fAndrew de Quincey if (lnbp21_attach(budget->dvb_frontend, &budget->i2c_adap, 0, 0)) { 4249691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel printk("%s: No LNBP21 found!\n", __FUNCTION__); 4259691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel goto error_out; 4269691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel } 42796bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey break; 42896bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey } 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (budget->dvb_frontend == NULL) { 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("budget: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dev->pci->vendor, 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dev->pci->device, 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dev->pci->subsystem_vendor, 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget->dev->pci->subsystem_device); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4389691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) 4399691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel goto error_out; 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4419691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel return; 4429691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel 4439691bb14d9ab646868a6392e9419070c304a9590Martin Zwickelerror_out: 4449691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel printk("budget: Frontend registration failed!\n"); 445dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (budget->dvb_frontend->ops.release) 446dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher budget->dvb_frontend->ops.release(budget->dvb_frontend); 4479691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel budget->dvb_frontend = NULL; 4489691bb14d9ab646868a6392e9419070c304a9590Martin Zwickel return; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget *budget = NULL; 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds budget = kmalloc(sizeof(struct budget), GFP_KERNEL); 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if( NULL == budget ) { 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk(2, "dev:%p, info:%p, budget:%p\n", dev, info, budget); 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->ext_priv = budget; 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) { 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("==> failed\n"); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree (budget); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471fdc53a6dbfea18e621dd23ed5cfb160837d7ce52Johannes Stezenbach budget->dvb_adapter.priv = budget; 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frontend_init(budget); 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47432e4c3a5622e832938aa0272e21a292564ff090aOliver Endriss ttpci_budget_init_hooks(budget); 47532e4c3a5622e832938aa0272e21a292564ff090aOliver Endriss 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int budget_detach (struct saa7146_dev* dev) 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct budget *budget = (struct budget*) dev->ext_priv; 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int err; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend); 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err = ttpci_budget_deinit (budget); 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree (budget); 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->ext_priv = NULL; 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return err; 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct saa7146_extension budget_extension; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_device_id pci_tbl[] = { 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1003), 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAKE_EXTENSION_PCI(ttbc, 0x13c2, 0x1004), 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), 50896bf2f2b549aab918f4225841df54c3d58896822Andrew de Quincey MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .vendor = 0, 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DEVICE_TABLE(pci, pci_tbl); 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct saa7146_extension budget_extension = { 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "budget dvb\0", 52069459f3d2fb9eea370535ceba91dd8c9df3d94bcOliver Endriss .flags = SAA7146_I2C_SHORT_DELAY, 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .module = THIS_MODULE, 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .pci_tbl = pci_tbl, 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .attach = budget_attach, 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .detach = budget_detach, 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .irq_mask = MASK_10, 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .irq_func = ttpci_budget_irq10_handler, 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init budget_init(void) 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return saa7146_register_extension(&budget_extension); 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit budget_exit(void) 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_unregister_extension(&budget_extension); 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(budget_init); 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(budget_exit); 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("driver for the SAA7146 based so-called " 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "budget PCI DVB cards by Siemens, Technotrend, Hauppauge"); 548