19a0bf528SMauro Carvalho Chehab /* 29a0bf528SMauro Carvalho Chehab * isl6421.h - driver for lnb supply and control ic ISL6421 39a0bf528SMauro Carvalho Chehab * 49a0bf528SMauro Carvalho Chehab * Copyright (C) 2006 Andrew de Quincey 59a0bf528SMauro Carvalho Chehab * Copyright (C) 2006 Oliver Endriss 69a0bf528SMauro Carvalho Chehab * 79a0bf528SMauro Carvalho Chehab * This program is free software; you can redistribute it and/or 89a0bf528SMauro Carvalho Chehab * modify it under the terms of the GNU General Public License 99a0bf528SMauro Carvalho Chehab * as published by the Free Software Foundation; either version 2 109a0bf528SMauro Carvalho Chehab * of the License, or (at your option) any later version. 119a0bf528SMauro Carvalho Chehab * 129a0bf528SMauro Carvalho Chehab * 139a0bf528SMauro Carvalho Chehab * This program is distributed in the hope that it will be useful, 149a0bf528SMauro Carvalho Chehab * but WITHOUT ANY WARRANTY; without even the implied warranty of 159a0bf528SMauro Carvalho Chehab * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 169a0bf528SMauro Carvalho Chehab * GNU General Public License for more details. 179a0bf528SMauro Carvalho Chehab * 189a0bf528SMauro Carvalho Chehab * 199a0bf528SMauro Carvalho Chehab * You should have received a copy of the GNU General Public License 209a0bf528SMauro Carvalho Chehab * along with this program; if not, write to the Free Software 219a0bf528SMauro Carvalho Chehab * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 229a0bf528SMauro Carvalho Chehab * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 239a0bf528SMauro Carvalho Chehab * 249a0bf528SMauro Carvalho Chehab * 259a0bf528SMauro Carvalho Chehab * the project's page is at http://www.linuxtv.org 269a0bf528SMauro Carvalho Chehab */ 279a0bf528SMauro Carvalho Chehab #include <linux/delay.h> 289a0bf528SMauro Carvalho Chehab #include <linux/errno.h> 299a0bf528SMauro Carvalho Chehab #include <linux/init.h> 309a0bf528SMauro Carvalho Chehab #include <linux/kernel.h> 319a0bf528SMauro Carvalho Chehab #include <linux/module.h> 329a0bf528SMauro Carvalho Chehab #include <linux/string.h> 339a0bf528SMauro Carvalho Chehab #include <linux/slab.h> 349a0bf528SMauro Carvalho Chehab 359a0bf528SMauro Carvalho Chehab #include "dvb_frontend.h" 369a0bf528SMauro Carvalho Chehab #include "isl6421.h" 379a0bf528SMauro Carvalho Chehab 389a0bf528SMauro Carvalho Chehab struct isl6421 { 399a0bf528SMauro Carvalho Chehab u8 config; 409a0bf528SMauro Carvalho Chehab u8 override_or; 419a0bf528SMauro Carvalho Chehab u8 override_and; 429a0bf528SMauro Carvalho Chehab struct i2c_adapter *i2c; 439a0bf528SMauro Carvalho Chehab u8 i2c_addr; 449a0bf528SMauro Carvalho Chehab }; 459a0bf528SMauro Carvalho Chehab 469a0bf528SMauro Carvalho Chehab static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 479a0bf528SMauro Carvalho Chehab { 489a0bf528SMauro Carvalho Chehab struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv; 499a0bf528SMauro Carvalho Chehab struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, 509a0bf528SMauro Carvalho Chehab .buf = &isl6421->config, 519a0bf528SMauro Carvalho Chehab .len = sizeof(isl6421->config) }; 529a0bf528SMauro Carvalho Chehab 539a0bf528SMauro Carvalho Chehab isl6421->config &= ~(ISL6421_VSEL1 | ISL6421_EN1); 549a0bf528SMauro Carvalho Chehab 559a0bf528SMauro Carvalho Chehab switch(voltage) { 569a0bf528SMauro Carvalho Chehab case SEC_VOLTAGE_OFF: 579a0bf528SMauro Carvalho Chehab break; 589a0bf528SMauro Carvalho Chehab case SEC_VOLTAGE_13: 599a0bf528SMauro Carvalho Chehab isl6421->config |= ISL6421_EN1; 609a0bf528SMauro Carvalho Chehab break; 619a0bf528SMauro Carvalho Chehab case SEC_VOLTAGE_18: 629a0bf528SMauro Carvalho Chehab isl6421->config |= (ISL6421_EN1 | ISL6421_VSEL1); 639a0bf528SMauro Carvalho Chehab break; 649a0bf528SMauro Carvalho Chehab default: 659a0bf528SMauro Carvalho Chehab return -EINVAL; 669a0bf528SMauro Carvalho Chehab }; 679a0bf528SMauro Carvalho Chehab 689a0bf528SMauro Carvalho Chehab isl6421->config |= isl6421->override_or; 699a0bf528SMauro Carvalho Chehab isl6421->config &= isl6421->override_and; 709a0bf528SMauro Carvalho Chehab 719a0bf528SMauro Carvalho Chehab return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; 729a0bf528SMauro Carvalho Chehab } 739a0bf528SMauro Carvalho Chehab 749a0bf528SMauro Carvalho Chehab static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) 759a0bf528SMauro Carvalho Chehab { 769a0bf528SMauro Carvalho Chehab struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv; 779a0bf528SMauro Carvalho Chehab struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, 789a0bf528SMauro Carvalho Chehab .buf = &isl6421->config, 799a0bf528SMauro Carvalho Chehab .len = sizeof(isl6421->config) }; 809a0bf528SMauro Carvalho Chehab 819a0bf528SMauro Carvalho Chehab if (arg) 829a0bf528SMauro Carvalho Chehab isl6421->config |= ISL6421_LLC1; 839a0bf528SMauro Carvalho Chehab else 849a0bf528SMauro Carvalho Chehab isl6421->config &= ~ISL6421_LLC1; 859a0bf528SMauro Carvalho Chehab 869a0bf528SMauro Carvalho Chehab isl6421->config |= isl6421->override_or; 879a0bf528SMauro Carvalho Chehab isl6421->config &= isl6421->override_and; 889a0bf528SMauro Carvalho Chehab 899a0bf528SMauro Carvalho Chehab return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO; 909a0bf528SMauro Carvalho Chehab } 919a0bf528SMauro Carvalho Chehab 929a0bf528SMauro Carvalho Chehab static void isl6421_release(struct dvb_frontend *fe) 939a0bf528SMauro Carvalho Chehab { 949a0bf528SMauro Carvalho Chehab /* power off */ 959a0bf528SMauro Carvalho Chehab isl6421_set_voltage(fe, SEC_VOLTAGE_OFF); 969a0bf528SMauro Carvalho Chehab 979a0bf528SMauro Carvalho Chehab /* free */ 989a0bf528SMauro Carvalho Chehab kfree(fe->sec_priv); 999a0bf528SMauro Carvalho Chehab fe->sec_priv = NULL; 1009a0bf528SMauro Carvalho Chehab } 1019a0bf528SMauro Carvalho Chehab 1029a0bf528SMauro Carvalho Chehab struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, 1039a0bf528SMauro Carvalho Chehab u8 override_set, u8 override_clear) 1049a0bf528SMauro Carvalho Chehab { 1059a0bf528SMauro Carvalho Chehab struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL); 1069a0bf528SMauro Carvalho Chehab if (!isl6421) 1079a0bf528SMauro Carvalho Chehab return NULL; 1089a0bf528SMauro Carvalho Chehab 1099a0bf528SMauro Carvalho Chehab /* default configuration */ 1109a0bf528SMauro Carvalho Chehab isl6421->config = ISL6421_ISEL1; 1119a0bf528SMauro Carvalho Chehab isl6421->i2c = i2c; 1129a0bf528SMauro Carvalho Chehab isl6421->i2c_addr = i2c_addr; 1139a0bf528SMauro Carvalho Chehab fe->sec_priv = isl6421; 1149a0bf528SMauro Carvalho Chehab 1159a0bf528SMauro Carvalho Chehab /* bits which should be forced to '1' */ 1169a0bf528SMauro Carvalho Chehab isl6421->override_or = override_set; 1179a0bf528SMauro Carvalho Chehab 1189a0bf528SMauro Carvalho Chehab /* bits which should be forced to '0' */ 1199a0bf528SMauro Carvalho Chehab isl6421->override_and = ~override_clear; 1209a0bf528SMauro Carvalho Chehab 1219a0bf528SMauro Carvalho Chehab /* detect if it is present or not */ 1229a0bf528SMauro Carvalho Chehab if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) { 1239a0bf528SMauro Carvalho Chehab kfree(isl6421); 1249a0bf528SMauro Carvalho Chehab fe->sec_priv = NULL; 1259a0bf528SMauro Carvalho Chehab return NULL; 1269a0bf528SMauro Carvalho Chehab } 1279a0bf528SMauro Carvalho Chehab 1289a0bf528SMauro Carvalho Chehab /* install release callback */ 1299a0bf528SMauro Carvalho Chehab fe->ops.release_sec = isl6421_release; 1309a0bf528SMauro Carvalho Chehab 1319a0bf528SMauro Carvalho Chehab /* override frontend ops */ 1329a0bf528SMauro Carvalho Chehab fe->ops.set_voltage = isl6421_set_voltage; 1339a0bf528SMauro Carvalho Chehab fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage; 1349a0bf528SMauro Carvalho Chehab 1359a0bf528SMauro Carvalho Chehab return fe; 1369a0bf528SMauro Carvalho Chehab } 1379a0bf528SMauro Carvalho Chehab EXPORT_SYMBOL(isl6421_attach); 1389a0bf528SMauro Carvalho Chehab 1399a0bf528SMauro Carvalho Chehab MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421"); 1409a0bf528SMauro Carvalho Chehab MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss"); 1419a0bf528SMauro Carvalho Chehab MODULE_LICENSE("GPL"); 142