| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * budget-av.c: driver for the SAA7146 based Budget DVB cards | 
 | 3 |  *              with analog video in | 
 | 4 |  * | 
 | 5 |  * Compiled from various sources by Michael Hunold <michael@mihu.de> | 
 | 6 |  * | 
 | 7 |  * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> & | 
 | 8 |  *                               Andrew de Quincey <adq_dvb@lidskialf.net> | 
 | 9 |  * | 
 | 10 |  * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de> | 
 | 11 |  * | 
 | 12 |  * Copyright (C) 1999-2002 Ralph  Metzler | 
 | 13 |  *                       & Marcus Metzler for convergence integrated media GmbH | 
 | 14 |  * | 
 | 15 |  * This program is free software; you can redistribute it and/or | 
 | 16 |  * modify it under the terms of the GNU General Public License | 
 | 17 |  * as published by the Free Software Foundation; either version 2 | 
 | 18 |  * of the License, or (at your option) any later version. | 
 | 19 |  * | 
 | 20 |  * | 
 | 21 |  * This program is distributed in the hope that it will be useful, | 
 | 22 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 23 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | 24 |  * GNU General Public License for more details. | 
 | 25 |  * | 
 | 26 |  * | 
 | 27 |  * You should have received a copy of the GNU General Public License | 
 | 28 |  * along with this program; if not, write to the Free Software | 
 | 29 |  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 
 | 30 |  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | 
 | 31 |  * | 
 | 32 |  * | 
 | 33 |  * the project's page is at http://www.linuxtv.org/dvb/ | 
 | 34 |  */ | 
 | 35 |  | 
 | 36 | #include "budget.h" | 
 | 37 | #include "stv0299.h" | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 38 | #include "stb0899_drv.h" | 
 | 39 | #include "stb0899_reg.h" | 
| Manu Abraham | 8be969b | 2008-01-25 18:20:48 -0300 | [diff] [blame] | 40 | #include "stb0899_cfg.h" | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 41 | #include "tda8261.h" | 
| Manu Abraham | 8be969b | 2008-01-25 18:20:48 -0300 | [diff] [blame] | 42 | #include "tda8261_cfg.h" | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 43 | #include "tda1002x.h" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 44 | #include "tda1004x.h" | 
| Andrew de Quincey | 1c72cfdc | 2006-09-05 17:58:20 -0300 | [diff] [blame] | 45 | #include "tua6100.h" | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 46 | #include "dvb-pll.h" | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 47 | #include <media/saa7146_vv.h> | 
 | 48 | #include <linux/module.h> | 
 | 49 | #include <linux/errno.h> | 
 | 50 | #include <linux/slab.h> | 
 | 51 | #include <linux/interrupt.h> | 
 | 52 | #include <linux/input.h> | 
 | 53 | #include <linux/spinlock.h> | 
 | 54 |  | 
 | 55 | #include "dvb_ca_en50221.h" | 
 | 56 |  | 
 | 57 | #define DEBICICAM		0x02420000 | 
 | 58 |  | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 59 | #define SLOTSTATUS_NONE         1 | 
 | 60 | #define SLOTSTATUS_PRESENT      2 | 
 | 61 | #define SLOTSTATUS_RESET        4 | 
 | 62 | #define SLOTSTATUS_READY        8 | 
 | 63 | #define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY) | 
 | 64 |  | 
| Janne Grunau | 26dc4d0 | 2008-09-21 20:50:11 -0300 | [diff] [blame] | 65 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | 
 | 66 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | struct budget_av { | 
 | 68 | 	struct budget budget; | 
 | 69 | 	struct video_device *vd; | 
 | 70 | 	int cur_input; | 
 | 71 | 	int has_saa7113; | 
 | 72 | 	struct tasklet_struct ciintf_irq_tasklet; | 
 | 73 | 	int slot_status; | 
 | 74 | 	struct dvb_ca_en50221 ca; | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 75 | 	u8 reinitialise_demod:1; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 76 | }; | 
 | 77 |  | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 78 | static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot); | 
 | 79 |  | 
 | 80 |  | 
| Andrew de Quincey | 86f40cc | 2006-03-30 15:53:35 -0300 | [diff] [blame] | 81 | /* GPIO Connections: | 
 | 82 |  * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*! | 
 | 83 |  * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory | 
 | 84 |  * 2 - CI Card Enable (Active Low) | 
 | 85 |  * 3 - CI Card Detect | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 86 |  */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 87 |  | 
 | 88 | /**************************************************************************** | 
 | 89 |  * INITIALIZATION | 
 | 90 |  ****************************************************************************/ | 
 | 91 |  | 
 | 92 | static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg) | 
 | 93 | { | 
 | 94 | 	u8 mm1[] = { 0x00 }; | 
 | 95 | 	u8 mm2[] = { 0x00 }; | 
 | 96 | 	struct i2c_msg msgs[2]; | 
 | 97 |  | 
 | 98 | 	msgs[0].flags = 0; | 
 | 99 | 	msgs[1].flags = I2C_M_RD; | 
 | 100 | 	msgs[0].addr = msgs[1].addr = id / 2; | 
 | 101 | 	mm1[0] = reg; | 
 | 102 | 	msgs[0].len = 1; | 
 | 103 | 	msgs[1].len = 1; | 
 | 104 | 	msgs[0].buf = mm1; | 
 | 105 | 	msgs[1].buf = mm2; | 
 | 106 |  | 
 | 107 | 	i2c_transfer(i2c, msgs, 2); | 
 | 108 |  | 
 | 109 | 	return mm2[0]; | 
 | 110 | } | 
 | 111 |  | 
 | 112 | static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len) | 
 | 113 | { | 
 | 114 | 	u8 mm1[] = { reg }; | 
 | 115 | 	struct i2c_msg msgs[2] = { | 
 | 116 | 		{.addr = id / 2,.flags = 0,.buf = mm1,.len = 1}, | 
 | 117 | 		{.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len} | 
 | 118 | 	}; | 
 | 119 |  | 
 | 120 | 	if (i2c_transfer(i2c, msgs, 2) != 2) | 
 | 121 | 		return -EIO; | 
 | 122 |  | 
 | 123 | 	return 0; | 
 | 124 | } | 
 | 125 |  | 
 | 126 | static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val) | 
 | 127 | { | 
 | 128 | 	u8 msg[2] = { reg, val }; | 
 | 129 | 	struct i2c_msg msgs; | 
 | 130 |  | 
 | 131 | 	msgs.flags = 0; | 
 | 132 | 	msgs.addr = id / 2; | 
 | 133 | 	msgs.len = 2; | 
 | 134 | 	msgs.buf = msg; | 
 | 135 | 	return i2c_transfer(i2c, &msgs, 1); | 
 | 136 | } | 
 | 137 |  | 
 | 138 | static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) | 
 | 139 | { | 
 | 140 | 	struct budget_av *budget_av = (struct budget_av *) ca->data; | 
 | 141 | 	int result; | 
 | 142 |  | 
 | 143 | 	if (slot != 0) | 
 | 144 | 		return -EINVAL; | 
 | 145 |  | 
 | 146 | 	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); | 
 | 147 | 	udelay(1); | 
 | 148 |  | 
| Andrew de Quincey | 2d0235d | 2006-01-09 15:25:05 -0200 | [diff] [blame] | 149 | 	result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 150 | 	if (result == -ETIMEDOUT) { | 
 | 151 | 		ciintf_slot_shutdown(ca, slot); | 
 | 152 | 		printk(KERN_INFO "budget-av: cam ejected 1\n"); | 
 | 153 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 154 | 	return result; | 
 | 155 | } | 
 | 156 |  | 
 | 157 | static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value) | 
 | 158 | { | 
 | 159 | 	struct budget_av *budget_av = (struct budget_av *) ca->data; | 
 | 160 | 	int result; | 
 | 161 |  | 
 | 162 | 	if (slot != 0) | 
 | 163 | 		return -EINVAL; | 
 | 164 |  | 
 | 165 | 	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); | 
 | 166 | 	udelay(1); | 
 | 167 |  | 
| Andrew de Quincey | 2d0235d | 2006-01-09 15:25:05 -0200 | [diff] [blame] | 168 | 	result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 169 | 	if (result == -ETIMEDOUT) { | 
 | 170 | 		ciintf_slot_shutdown(ca, slot); | 
 | 171 | 		printk(KERN_INFO "budget-av: cam ejected 2\n"); | 
 | 172 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 173 | 	return result; | 
 | 174 | } | 
 | 175 |  | 
 | 176 | static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) | 
 | 177 | { | 
 | 178 | 	struct budget_av *budget_av = (struct budget_av *) ca->data; | 
 | 179 | 	int result; | 
 | 180 |  | 
 | 181 | 	if (slot != 0) | 
 | 182 | 		return -EINVAL; | 
 | 183 |  | 
 | 184 | 	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | 
 | 185 | 	udelay(1); | 
 | 186 |  | 
 | 187 | 	result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); | 
| Christoph Pfister | 8727073 | 2008-04-09 17:34:09 -0300 | [diff] [blame] | 188 | 	if (result == -ETIMEDOUT) { | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 189 | 		ciintf_slot_shutdown(ca, slot); | 
 | 190 | 		printk(KERN_INFO "budget-av: cam ejected 3\n"); | 
 | 191 | 		return -ETIMEDOUT; | 
 | 192 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 193 | 	return result; | 
 | 194 | } | 
 | 195 |  | 
 | 196 | static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value) | 
 | 197 | { | 
 | 198 | 	struct budget_av *budget_av = (struct budget_av *) ca->data; | 
 | 199 | 	int result; | 
 | 200 |  | 
 | 201 | 	if (slot != 0) | 
 | 202 | 		return -EINVAL; | 
 | 203 |  | 
 | 204 | 	saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | 
 | 205 | 	udelay(1); | 
 | 206 |  | 
 | 207 | 	result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 208 | 	if (result == -ETIMEDOUT) { | 
 | 209 | 		ciintf_slot_shutdown(ca, slot); | 
 | 210 | 		printk(KERN_INFO "budget-av: cam ejected 5\n"); | 
 | 211 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 212 | 	return result; | 
 | 213 | } | 
 | 214 |  | 
 | 215 | static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | 
 | 216 | { | 
 | 217 | 	struct budget_av *budget_av = (struct budget_av *) ca->data; | 
 | 218 | 	struct saa7146_dev *saa = budget_av->budget.dev; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 219 |  | 
 | 220 | 	if (slot != 0) | 
 | 221 | 		return -EINVAL; | 
 | 222 |  | 
 | 223 | 	dprintk(1, "ciintf_slot_reset\n"); | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 224 | 	budget_av->slot_status = SLOTSTATUS_RESET; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 225 |  | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 226 | 	saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 227 |  | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 228 | 	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ | 
 | 229 | 	msleep(2); | 
 | 230 | 	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */ | 
 | 231 | 	msleep(20); /* 20 ms Vcc settling time */ | 
 | 232 |  | 
 | 233 | 	saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 234 | 	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | 
 | 235 | 	msleep(20); | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 236 |  | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 237 | 	/* reinitialise the frontend if necessary */ | 
 | 238 | 	if (budget_av->reinitialise_demod) | 
 | 239 | 		dvb_frontend_reinitialise(budget_av->budget.dvb_frontend); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 240 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 241 | 	return 0; | 
 | 242 | } | 
 | 243 |  | 
 | 244 | static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | 
 | 245 | { | 
 | 246 | 	struct budget_av *budget_av = (struct budget_av *) ca->data; | 
 | 247 | 	struct saa7146_dev *saa = budget_av->budget.dev; | 
 | 248 |  | 
 | 249 | 	if (slot != 0) | 
 | 250 | 		return -EINVAL; | 
 | 251 |  | 
 | 252 | 	dprintk(1, "ciintf_slot_shutdown\n"); | 
 | 253 |  | 
 | 254 | 	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 255 | 	budget_av->slot_status = SLOTSTATUS_NONE; | 
 | 256 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 257 | 	return 0; | 
 | 258 | } | 
 | 259 |  | 
 | 260 | static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) | 
 | 261 | { | 
 | 262 | 	struct budget_av *budget_av = (struct budget_av *) ca->data; | 
 | 263 | 	struct saa7146_dev *saa = budget_av->budget.dev; | 
 | 264 |  | 
 | 265 | 	if (slot != 0) | 
 | 266 | 		return -EINVAL; | 
 | 267 |  | 
 | 268 | 	dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status); | 
 | 269 |  | 
 | 270 | 	ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA); | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 271 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 272 | 	return 0; | 
 | 273 | } | 
 | 274 |  | 
 | 275 | static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) | 
 | 276 | { | 
 | 277 | 	struct budget_av *budget_av = (struct budget_av *) ca->data; | 
 | 278 | 	struct saa7146_dev *saa = budget_av->budget.dev; | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 279 | 	int result; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 280 |  | 
 | 281 | 	if (slot != 0) | 
 | 282 | 		return -EINVAL; | 
 | 283 |  | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 284 | 	/* test the card detect line - needs to be done carefully | 
 | 285 | 	 * since it never goes high for some CAMs on this interface (e.g. topuptv) */ | 
 | 286 | 	if (budget_av->slot_status == SLOTSTATUS_NONE) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 287 | 		saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | 
 | 288 | 		udelay(1); | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 289 | 		if (saa7146_read(saa, PSR) & MASK_06) { | 
 | 290 | 			if (budget_av->slot_status == SLOTSTATUS_NONE) { | 
 | 291 | 				budget_av->slot_status = SLOTSTATUS_PRESENT; | 
 | 292 | 				printk(KERN_INFO "budget-av: cam inserted A\n"); | 
| Andrew de Quincey | 2d0235d | 2006-01-09 15:25:05 -0200 | [diff] [blame] | 293 | 			} | 
 | 294 | 		} | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 295 | 		saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | 
 | 296 | 	} | 
| Andrew de Quincey | 2d0235d | 2006-01-09 15:25:05 -0200 | [diff] [blame] | 297 |  | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 298 | 	/* We also try and read from IO memory to work round the above detection bug. If | 
 | 299 | 	 * there is no CAM, we will get a timeout. Only done if there is no cam | 
 | 300 | 	 * present, since this test actually breaks some cams :( | 
 | 301 | 	 * | 
 | 302 | 	 * if the CI interface is not open, we also do the above test since we | 
 | 303 | 	 * don't care if the cam has problems - we'll be resetting it on open() anyway */ | 
 | 304 | 	if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 305 | 		saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 306 | 		result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1); | 
 | 307 | 		if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) { | 
 | 308 | 			budget_av->slot_status = SLOTSTATUS_PRESENT; | 
 | 309 | 			printk(KERN_INFO "budget-av: cam inserted B\n"); | 
 | 310 | 		} else if (result < 0) { | 
 | 311 | 			if (budget_av->slot_status != SLOTSTATUS_NONE) { | 
 | 312 | 				ciintf_slot_shutdown(ca, slot); | 
 | 313 | 				printk(KERN_INFO "budget-av: cam ejected 5\n"); | 
 | 314 | 				return 0; | 
 | 315 | 			} | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 316 | 		} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 317 | 	} | 
 | 318 |  | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 319 | 	/* read from attribute memory in reset/ready state to know when the CAM is ready */ | 
 | 320 | 	if (budget_av->slot_status == SLOTSTATUS_RESET) { | 
 | 321 | 		result = ciintf_read_attribute_mem(ca, slot, 0); | 
 | 322 | 		if (result == 0x1d) { | 
 | 323 | 			budget_av->slot_status = SLOTSTATUS_READY; | 
 | 324 | 		} | 
 | 325 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 326 |  | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 327 | 	/* work out correct return code */ | 
 | 328 | 	if (budget_av->slot_status != SLOTSTATUS_NONE) { | 
 | 329 | 		if (budget_av->slot_status & SLOTSTATUS_READY) { | 
 | 330 | 			return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY; | 
 | 331 | 		} | 
 | 332 | 		return DVB_CA_EN50221_POLL_CAM_PRESENT; | 
 | 333 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 334 | 	return 0; | 
 | 335 | } | 
 | 336 |  | 
 | 337 | static int ciintf_init(struct budget_av *budget_av) | 
 | 338 | { | 
 | 339 | 	struct saa7146_dev *saa = budget_av->budget.dev; | 
 | 340 | 	int result; | 
 | 341 |  | 
 | 342 | 	memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221)); | 
 | 343 |  | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 344 | 	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | 
 | 345 | 	saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 346 | 	saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); | 
 | 347 | 	saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | 
 | 348 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 349 | 	/* Enable DEBI pins */ | 
| Hartmut Birr | 2a893de | 2006-12-03 21:08:08 -0300 | [diff] [blame] | 350 | 	saa7146_write(saa, MC1, MASK_27 | MASK_11); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 351 |  | 
 | 352 | 	/* register CI interface */ | 
 | 353 | 	budget_av->ca.owner = THIS_MODULE; | 
 | 354 | 	budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem; | 
 | 355 | 	budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem; | 
 | 356 | 	budget_av->ca.read_cam_control = ciintf_read_cam_control; | 
 | 357 | 	budget_av->ca.write_cam_control = ciintf_write_cam_control; | 
 | 358 | 	budget_av->ca.slot_reset = ciintf_slot_reset; | 
 | 359 | 	budget_av->ca.slot_shutdown = ciintf_slot_shutdown; | 
 | 360 | 	budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; | 
 | 361 | 	budget_av->ca.poll_slot_status = ciintf_poll_slot_status; | 
 | 362 | 	budget_av->ca.data = budget_av; | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 363 | 	budget_av->budget.ci_present = 1; | 
 | 364 | 	budget_av->slot_status = SLOTSTATUS_NONE; | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 365 |  | 
| Johannes Stezenbach | fdc53a6 | 2005-05-16 21:54:39 -0700 | [diff] [blame] | 366 | 	if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 367 | 					  &budget_av->ca, 0, 1)) != 0) { | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 368 | 		printk(KERN_ERR "budget-av: ci initialisation failed.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 369 | 		goto error; | 
 | 370 | 	} | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 371 |  | 
 | 372 | 	printk(KERN_INFO "budget-av: ci interface initialised.\n"); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 373 | 	return 0; | 
 | 374 |  | 
 | 375 | error: | 
| Hartmut Birr | 2a893de | 2006-12-03 21:08:08 -0300 | [diff] [blame] | 376 | 	saa7146_write(saa, MC1, MASK_27); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 377 | 	return result; | 
 | 378 | } | 
 | 379 |  | 
 | 380 | static void ciintf_deinit(struct budget_av *budget_av) | 
 | 381 | { | 
 | 382 | 	struct saa7146_dev *saa = budget_av->budget.dev; | 
 | 383 |  | 
 | 384 | 	saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); | 
 | 385 | 	saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT); | 
 | 386 | 	saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); | 
 | 387 | 	saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | 
 | 388 |  | 
 | 389 | 	/* release the CA device */ | 
 | 390 | 	dvb_ca_en50221_release(&budget_av->ca); | 
 | 391 |  | 
 | 392 | 	/* disable DEBI pins */ | 
| Hartmut Birr | 2a893de | 2006-12-03 21:08:08 -0300 | [diff] [blame] | 393 | 	saa7146_write(saa, MC1, MASK_27); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 394 | } | 
 | 395 |  | 
 | 396 |  | 
 | 397 | static const u8 saa7113_tab[] = { | 
 | 398 | 	0x01, 0x08, | 
 | 399 | 	0x02, 0xc0, | 
 | 400 | 	0x03, 0x33, | 
 | 401 | 	0x04, 0x00, | 
 | 402 | 	0x05, 0x00, | 
 | 403 | 	0x06, 0xeb, | 
 | 404 | 	0x07, 0xe0, | 
 | 405 | 	0x08, 0x28, | 
 | 406 | 	0x09, 0x00, | 
 | 407 | 	0x0a, 0x80, | 
 | 408 | 	0x0b, 0x47, | 
 | 409 | 	0x0c, 0x40, | 
 | 410 | 	0x0d, 0x00, | 
 | 411 | 	0x0e, 0x01, | 
 | 412 | 	0x0f, 0x44, | 
 | 413 |  | 
 | 414 | 	0x10, 0x08, | 
 | 415 | 	0x11, 0x0c, | 
 | 416 | 	0x12, 0x7b, | 
 | 417 | 	0x13, 0x00, | 
 | 418 | 	0x15, 0x00, 0x16, 0x00, 0x17, 0x00, | 
 | 419 |  | 
 | 420 | 	0x57, 0xff, | 
 | 421 | 	0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07, | 
 | 422 | 	0x5b, 0x83, 0x5e, 0x00, | 
 | 423 | 	0xff | 
 | 424 | }; | 
 | 425 |  | 
 | 426 | static int saa7113_init(struct budget_av *budget_av) | 
 | 427 | { | 
 | 428 | 	struct budget *budget = &budget_av->budget; | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 429 | 	struct saa7146_dev *saa = budget->dev; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 430 | 	const u8 *data = saa7113_tab; | 
 | 431 |  | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 432 | 	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); | 
 | 433 | 	msleep(200); | 
 | 434 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 435 | 	if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) { | 
 | 436 | 		dprintk(1, "saa7113 not found on KNC card\n"); | 
 | 437 | 		return -ENODEV; | 
 | 438 | 	} | 
 | 439 |  | 
 | 440 | 	dprintk(1, "saa7113 detected and initializing\n"); | 
 | 441 |  | 
 | 442 | 	while (*data != 0xff) { | 
 | 443 | 		i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1)); | 
 | 444 | 		data += 2; | 
 | 445 | 	} | 
 | 446 |  | 
 | 447 | 	dprintk(1, "saa7113  status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f)); | 
 | 448 |  | 
 | 449 | 	return 0; | 
 | 450 | } | 
 | 451 |  | 
 | 452 | static int saa7113_setinput(struct budget_av *budget_av, int input) | 
 | 453 | { | 
 | 454 | 	struct budget *budget = &budget_av->budget; | 
 | 455 |  | 
 | 456 | 	if (1 != budget_av->has_saa7113) | 
 | 457 | 		return -ENODEV; | 
 | 458 |  | 
 | 459 | 	if (input == 1) { | 
 | 460 | 		i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7); | 
 | 461 | 		i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80); | 
 | 462 | 	} else if (input == 0) { | 
 | 463 | 		i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0); | 
 | 464 | 		i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00); | 
 | 465 | 	} else | 
 | 466 | 		return -EINVAL; | 
 | 467 |  | 
 | 468 | 	budget_av->cur_input = input; | 
 | 469 | 	return 0; | 
 | 470 | } | 
 | 471 |  | 
 | 472 |  | 
 | 473 | static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio) | 
 | 474 | { | 
 | 475 | 	u8 aclk = 0; | 
 | 476 | 	u8 bclk = 0; | 
 | 477 | 	u8 m1; | 
 | 478 |  | 
 | 479 | 	aclk = 0xb5; | 
 | 480 | 	if (srate < 2000000) | 
 | 481 | 		bclk = 0x86; | 
 | 482 | 	else if (srate < 5000000) | 
 | 483 | 		bclk = 0x89; | 
 | 484 | 	else if (srate < 15000000) | 
 | 485 | 		bclk = 0x8f; | 
 | 486 | 	else if (srate < 45000000) | 
 | 487 | 		bclk = 0x95; | 
 | 488 |  | 
 | 489 | 	m1 = 0x14; | 
 | 490 | 	if (srate < 4000000) | 
 | 491 | 		m1 = 0x10; | 
 | 492 |  | 
 | 493 | 	stv0299_writereg(fe, 0x13, aclk); | 
 | 494 | 	stv0299_writereg(fe, 0x14, bclk); | 
 | 495 | 	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | 
 | 496 | 	stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | 
 | 497 | 	stv0299_writereg(fe, 0x21, (ratio) & 0xf0); | 
 | 498 | 	stv0299_writereg(fe, 0x0f, 0x80 | m1); | 
 | 499 |  | 
 | 500 | 	return 0; | 
 | 501 | } | 
 | 502 |  | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 503 | static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe, | 
 | 504 | 						 struct dvb_frontend_parameters *params) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 505 | { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 506 | 	u32 div; | 
 | 507 | 	u8 buf[4]; | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 508 | 	struct budget *budget = (struct budget *) fe->dvb->priv; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 509 | 	struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) }; | 
 | 510 |  | 
 | 511 | 	if ((params->frequency < 950000) || (params->frequency > 2150000)) | 
 | 512 | 		return -EINVAL; | 
 | 513 |  | 
 | 514 | 	div = (params->frequency + (125 - 1)) / 125;	// round correctly | 
 | 515 | 	buf[0] = (div >> 8) & 0x7f; | 
 | 516 | 	buf[1] = div & 0xff; | 
 | 517 | 	buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | 
 | 518 | 	buf[3] = 0x20; | 
 | 519 |  | 
 | 520 | 	if (params->u.qpsk.symbol_rate < 4000000) | 
 | 521 | 		buf[3] |= 1; | 
 | 522 |  | 
 | 523 | 	if (params->frequency < 1250000) | 
 | 524 | 		buf[3] |= 0; | 
 | 525 | 	else if (params->frequency < 1550000) | 
 | 526 | 		buf[3] |= 0x40; | 
 | 527 | 	else if (params->frequency < 2050000) | 
 | 528 | 		buf[3] |= 0x80; | 
 | 529 | 	else if (params->frequency < 2150000) | 
 | 530 | 		buf[3] |= 0xC0; | 
 | 531 |  | 
| Patrick Boettcher | dea7486 | 2006-05-14 05:01:31 -0300 | [diff] [blame] | 532 | 	if (fe->ops.i2c_gate_ctrl) | 
 | 533 | 		fe->ops.i2c_gate_ctrl(fe, 1); | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 534 | 	if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 535 | 		return -EIO; | 
 | 536 | 	return 0; | 
 | 537 | } | 
 | 538 |  | 
 | 539 | static u8 typhoon_cinergy1200s_inittab[] = { | 
 | 540 | 	0x01, 0x15, | 
 | 541 | 	0x02, 0x30, | 
 | 542 | 	0x03, 0x00, | 
 | 543 | 	0x04, 0x7d,		/* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | 
 | 544 | 	0x05, 0x35,		/* I2CT = 0, SCLT = 1, SDAT = 1 */ | 
 | 545 | 	0x06, 0x40,		/* DAC not used, set to high impendance mode */ | 
 | 546 | 	0x07, 0x00,		/* DAC LSB */ | 
 | 547 | 	0x08, 0x40,		/* DiSEqC off */ | 
 | 548 | 	0x09, 0x00,		/* FIFO */ | 
 | 549 | 	0x0c, 0x51,		/* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | 
 | 550 | 	0x0d, 0x82,		/* DC offset compensation = ON, beta_agc1 = 2 */ | 
 | 551 | 	0x0e, 0x23,		/* alpha_tmg = 2, beta_tmg = 3 */ | 
 | 552 | 	0x10, 0x3f,		// AGC2  0x3d | 
 | 553 | 	0x11, 0x84, | 
| Oliver Endriss | ff29d06 | 2005-11-08 21:35:43 -0800 | [diff] [blame] | 554 | 	0x12, 0xb9, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 555 | 	0x15, 0xc9,		// lock detector threshold | 
 | 556 | 	0x16, 0x00, | 
 | 557 | 	0x17, 0x00, | 
 | 558 | 	0x18, 0x00, | 
 | 559 | 	0x19, 0x00, | 
 | 560 | 	0x1a, 0x00, | 
 | 561 | 	0x1f, 0x50, | 
 | 562 | 	0x20, 0x00, | 
 | 563 | 	0x21, 0x00, | 
 | 564 | 	0x22, 0x00, | 
 | 565 | 	0x23, 0x00, | 
 | 566 | 	0x28, 0x00,		// out imp: normal  out type: parallel FEC mode:0 | 
 | 567 | 	0x29, 0x1e,		// 1/2 threshold | 
 | 568 | 	0x2a, 0x14,		// 2/3 threshold | 
 | 569 | 	0x2b, 0x0f,		// 3/4 threshold | 
 | 570 | 	0x2c, 0x09,		// 5/6 threshold | 
 | 571 | 	0x2d, 0x05,		// 7/8 threshold | 
 | 572 | 	0x2e, 0x01, | 
 | 573 | 	0x31, 0x1f,		// test all FECs | 
 | 574 | 	0x32, 0x19,		// viterbi and synchro search | 
 | 575 | 	0x33, 0xfc,		// rs control | 
 | 576 | 	0x34, 0x93,		// error control | 
 | 577 | 	0x0f, 0x92, | 
 | 578 | 	0xff, 0xff | 
 | 579 | }; | 
 | 580 |  | 
 | 581 | static struct stv0299_config typhoon_config = { | 
 | 582 | 	.demod_address = 0x68, | 
 | 583 | 	.inittab = typhoon_cinergy1200s_inittab, | 
 | 584 | 	.mclk = 88000000UL, | 
 | 585 | 	.invert = 0, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 586 | 	.skip_reinit = 0, | 
| Oliver Endriss | da2c7f6 | 2008-04-20 22:13:37 -0300 | [diff] [blame] | 587 | 	.lock_output = STV0299_LOCKOUTPUT_1, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 588 | 	.volt13_op0_op1 = STV0299_VOLT13_OP0, | 
 | 589 | 	.min_delay_ms = 100, | 
 | 590 | 	.set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 591 | }; | 
 | 592 |  | 
 | 593 |  | 
 | 594 | static struct stv0299_config cinergy_1200s_config = { | 
 | 595 | 	.demod_address = 0x68, | 
 | 596 | 	.inittab = typhoon_cinergy1200s_inittab, | 
 | 597 | 	.mclk = 88000000UL, | 
 | 598 | 	.invert = 0, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 599 | 	.skip_reinit = 0, | 
| Oliver Endriss | da2c7f6 | 2008-04-20 22:13:37 -0300 | [diff] [blame] | 600 | 	.lock_output = STV0299_LOCKOUTPUT_0, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 601 | 	.volt13_op0_op1 = STV0299_VOLT13_OP0, | 
 | 602 | 	.min_delay_ms = 100, | 
 | 603 | 	.set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 604 | }; | 
 | 605 |  | 
| Andrew de Quincey | effa791 | 2006-01-09 15:25:09 -0200 | [diff] [blame] | 606 | static struct stv0299_config cinergy_1200s_1894_0010_config = { | 
 | 607 | 	.demod_address = 0x68, | 
 | 608 | 	.inittab = typhoon_cinergy1200s_inittab, | 
 | 609 | 	.mclk = 88000000UL, | 
 | 610 | 	.invert = 1, | 
 | 611 | 	.skip_reinit = 0, | 
| Oliver Endriss | da2c7f6 | 2008-04-20 22:13:37 -0300 | [diff] [blame] | 612 | 	.lock_output = STV0299_LOCKOUTPUT_1, | 
| Andrew de Quincey | effa791 | 2006-01-09 15:25:09 -0200 | [diff] [blame] | 613 | 	.volt13_op0_op1 = STV0299_VOLT13_OP0, | 
 | 614 | 	.min_delay_ms = 100, | 
 | 615 | 	.set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, | 
| Andrew de Quincey | effa791 | 2006-01-09 15:25:09 -0200 | [diff] [blame] | 616 | }; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 617 |  | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 618 | static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 619 | { | 
 | 620 | 	struct budget *budget = (struct budget *) fe->dvb->priv; | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 621 | 	u8 buf[6]; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 622 | 	struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) }; | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 623 | 	int i; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 624 |  | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 625 | #define CU1216_IF 36125000 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 626 | #define TUNER_MUL 62500 | 
 | 627 |  | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 628 | 	u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 629 |  | 
 | 630 | 	buf[0] = (div >> 8) & 0x7f; | 
 | 631 | 	buf[1] = div & 0xff; | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 632 | 	buf[2] = 0xce; | 
| Johannes Stezenbach | eef5764 | 2005-07-07 17:57:58 -0700 | [diff] [blame] | 633 | 	buf[3] = (params->frequency < 150000000 ? 0x01 : | 
 | 634 | 		  params->frequency < 445000000 ? 0x02 : 0x04); | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 635 | 	buf[4] = 0xde; | 
 | 636 | 	buf[5] = 0x20; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 637 |  | 
| Patrick Boettcher | dea7486 | 2006-05-14 05:01:31 -0300 | [diff] [blame] | 638 | 	if (fe->ops.i2c_gate_ctrl) | 
 | 639 | 		fe->ops.i2c_gate_ctrl(fe, 1); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 640 | 	if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | 
 | 641 | 		return -EIO; | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 642 |  | 
 | 643 | 	/* wait for the pll lock */ | 
 | 644 | 	msg.flags = I2C_M_RD; | 
 | 645 | 	msg.len = 1; | 
 | 646 | 	for (i = 0; i < 20; i++) { | 
 | 647 | 		if (fe->ops.i2c_gate_ctrl) | 
 | 648 | 			fe->ops.i2c_gate_ctrl(fe, 1); | 
 | 649 | 		if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40)) | 
 | 650 | 			break; | 
 | 651 | 		msleep(10); | 
 | 652 | 	} | 
 | 653 |  | 
 | 654 | 	/* switch the charge pump to the lower current */ | 
 | 655 | 	msg.flags = 0; | 
 | 656 | 	msg.len = 2; | 
 | 657 | 	msg.buf = &buf[2]; | 
 | 658 | 	buf[2] &= ~0x40; | 
 | 659 | 	if (fe->ops.i2c_gate_ctrl) | 
 | 660 | 		fe->ops.i2c_gate_ctrl(fe, 1); | 
 | 661 | 	if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1) | 
 | 662 | 		return -EIO; | 
 | 663 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 664 | 	return 0; | 
 | 665 | } | 
 | 666 |  | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 667 | static struct tda1002x_config philips_cu1216_config = { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 668 | 	.demod_address = 0x0c, | 
| Hartmut Birr | dc120b07 | 2007-04-21 19:44:10 -0300 | [diff] [blame] | 669 | 	.invert = 1, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 670 | }; | 
 | 671 |  | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 672 | static struct tda1002x_config philips_cu1216_config_altaddress = { | 
| Andrew de Quincey | 61cebe9 | 2006-11-19 14:10:59 -0300 | [diff] [blame] | 673 | 	.demod_address = 0x0d, | 
| Hartmut Birr | dc120b07 | 2007-04-21 19:44:10 -0300 | [diff] [blame] | 674 | 	.invert = 0, | 
| Andrew de Quincey | 61cebe9 | 2006-11-19 14:10:59 -0300 | [diff] [blame] | 675 | }; | 
 | 676 |  | 
| Antti Palosaari | 4388c3b | 2008-05-17 22:58:04 -0300 | [diff] [blame] | 677 | static struct tda10023_config philips_cu1216_tda10023_config = { | 
 | 678 | 	.demod_address = 0x0c, | 
 | 679 | 	.invert = 1, | 
 | 680 | }; | 
 | 681 |  | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 682 | static int philips_tu1216_tuner_init(struct dvb_frontend *fe) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 683 | { | 
 | 684 | 	struct budget *budget = (struct budget *) fe->dvb->priv; | 
 | 685 | 	static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; | 
 | 686 | 	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) }; | 
 | 687 |  | 
 | 688 | 	// setup PLL configuration | 
| Patrick Boettcher | dea7486 | 2006-05-14 05:01:31 -0300 | [diff] [blame] | 689 | 	if (fe->ops.i2c_gate_ctrl) | 
 | 690 | 		fe->ops.i2c_gate_ctrl(fe, 1); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 691 | 	if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | 
 | 692 | 		return -EIO; | 
 | 693 | 	msleep(1); | 
 | 694 |  | 
 | 695 | 	return 0; | 
 | 696 | } | 
 | 697 |  | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 698 | static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 699 | { | 
 | 700 | 	struct budget *budget = (struct budget *) fe->dvb->priv; | 
 | 701 | 	u8 tuner_buf[4]; | 
 | 702 | 	struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len = | 
 | 703 | 			sizeof(tuner_buf) }; | 
 | 704 | 	int tuner_frequency = 0; | 
 | 705 | 	u8 band, cp, filter; | 
 | 706 |  | 
 | 707 | 	// determine charge pump | 
 | 708 | 	tuner_frequency = params->frequency + 36166000; | 
 | 709 | 	if (tuner_frequency < 87000000) | 
 | 710 | 		return -EINVAL; | 
 | 711 | 	else if (tuner_frequency < 130000000) | 
 | 712 | 		cp = 3; | 
 | 713 | 	else if (tuner_frequency < 160000000) | 
 | 714 | 		cp = 5; | 
 | 715 | 	else if (tuner_frequency < 200000000) | 
 | 716 | 		cp = 6; | 
 | 717 | 	else if (tuner_frequency < 290000000) | 
 | 718 | 		cp = 3; | 
 | 719 | 	else if (tuner_frequency < 420000000) | 
 | 720 | 		cp = 5; | 
 | 721 | 	else if (tuner_frequency < 480000000) | 
 | 722 | 		cp = 6; | 
 | 723 | 	else if (tuner_frequency < 620000000) | 
 | 724 | 		cp = 3; | 
 | 725 | 	else if (tuner_frequency < 830000000) | 
 | 726 | 		cp = 5; | 
 | 727 | 	else if (tuner_frequency < 895000000) | 
 | 728 | 		cp = 7; | 
 | 729 | 	else | 
 | 730 | 		return -EINVAL; | 
 | 731 |  | 
 | 732 | 	// determine band | 
 | 733 | 	if (params->frequency < 49000000) | 
 | 734 | 		return -EINVAL; | 
 | 735 | 	else if (params->frequency < 161000000) | 
 | 736 | 		band = 1; | 
 | 737 | 	else if (params->frequency < 444000000) | 
 | 738 | 		band = 2; | 
 | 739 | 	else if (params->frequency < 861000000) | 
 | 740 | 		band = 4; | 
 | 741 | 	else | 
 | 742 | 		return -EINVAL; | 
 | 743 |  | 
 | 744 | 	// setup PLL filter | 
 | 745 | 	switch (params->u.ofdm.bandwidth) { | 
 | 746 | 	case BANDWIDTH_6_MHZ: | 
 | 747 | 		filter = 0; | 
 | 748 | 		break; | 
 | 749 |  | 
 | 750 | 	case BANDWIDTH_7_MHZ: | 
 | 751 | 		filter = 0; | 
 | 752 | 		break; | 
 | 753 |  | 
 | 754 | 	case BANDWIDTH_8_MHZ: | 
 | 755 | 		filter = 1; | 
 | 756 | 		break; | 
 | 757 |  | 
 | 758 | 	default: | 
 | 759 | 		return -EINVAL; | 
 | 760 | 	} | 
 | 761 |  | 
 | 762 | 	// calculate divisor | 
 | 763 | 	// ((36166000+((1000000/6)/2)) + Finput)/(1000000/6) | 
 | 764 | 	tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000; | 
 | 765 |  | 
 | 766 | 	// setup tuner buffer | 
 | 767 | 	tuner_buf[0] = (tuner_frequency >> 8) & 0x7f; | 
 | 768 | 	tuner_buf[1] = tuner_frequency & 0xff; | 
 | 769 | 	tuner_buf[2] = 0xca; | 
 | 770 | 	tuner_buf[3] = (cp << 5) | (filter << 3) | band; | 
 | 771 |  | 
| Patrick Boettcher | dea7486 | 2006-05-14 05:01:31 -0300 | [diff] [blame] | 772 | 	if (fe->ops.i2c_gate_ctrl) | 
 | 773 | 		fe->ops.i2c_gate_ctrl(fe, 1); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 774 | 	if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) | 
 | 775 | 		return -EIO; | 
 | 776 |  | 
 | 777 | 	msleep(1); | 
 | 778 | 	return 0; | 
 | 779 | } | 
 | 780 |  | 
 | 781 | static int philips_tu1216_request_firmware(struct dvb_frontend *fe, | 
 | 782 | 					   const struct firmware **fw, char *name) | 
 | 783 | { | 
 | 784 | 	struct budget *budget = (struct budget *) fe->dvb->priv; | 
 | 785 |  | 
 | 786 | 	return request_firmware(fw, name, &budget->dev->pci->dev); | 
 | 787 | } | 
 | 788 |  | 
 | 789 | static struct tda1004x_config philips_tu1216_config = { | 
 | 790 |  | 
 | 791 | 	.demod_address = 0x8, | 
 | 792 | 	.invert = 1, | 
 | 793 | 	.invert_oclk = 1, | 
| Hartmut Hackmann | ecb60de | 2005-07-07 17:57:40 -0700 | [diff] [blame] | 794 | 	.xtal_freq = TDA10046_XTAL_4M, | 
 | 795 | 	.agc_config = TDA10046_AGC_DEFAULT, | 
 | 796 | 	.if_freq = TDA10046_FREQ_3617, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 797 | 	.request_firmware = philips_tu1216_request_firmware, | 
 | 798 | }; | 
 | 799 |  | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 800 | static u8 philips_sd1878_inittab[] = { | 
 | 801 | 	0x01, 0x15, | 
 | 802 | 	0x02, 0x30, | 
 | 803 | 	0x03, 0x00, | 
 | 804 | 	0x04, 0x7d, | 
 | 805 | 	0x05, 0x35, | 
 | 806 | 	0x06, 0x40, | 
 | 807 | 	0x07, 0x00, | 
 | 808 | 	0x08, 0x43, | 
 | 809 | 	0x09, 0x02, | 
 | 810 | 	0x0C, 0x51, | 
 | 811 | 	0x0D, 0x82, | 
 | 812 | 	0x0E, 0x23, | 
 | 813 | 	0x10, 0x3f, | 
 | 814 | 	0x11, 0x84, | 
 | 815 | 	0x12, 0xb9, | 
 | 816 | 	0x15, 0xc9, | 
 | 817 | 	0x16, 0x19, | 
 | 818 | 	0x17, 0x8c, | 
 | 819 | 	0x18, 0x59, | 
 | 820 | 	0x19, 0xf8, | 
 | 821 | 	0x1a, 0xfe, | 
 | 822 | 	0x1c, 0x7f, | 
 | 823 | 	0x1d, 0x00, | 
 | 824 | 	0x1e, 0x00, | 
 | 825 | 	0x1f, 0x50, | 
 | 826 | 	0x20, 0x00, | 
 | 827 | 	0x21, 0x00, | 
 | 828 | 	0x22, 0x00, | 
 | 829 | 	0x23, 0x00, | 
 | 830 | 	0x28, 0x00, | 
 | 831 | 	0x29, 0x28, | 
 | 832 | 	0x2a, 0x14, | 
 | 833 | 	0x2b, 0x0f, | 
 | 834 | 	0x2c, 0x09, | 
 | 835 | 	0x2d, 0x09, | 
 | 836 | 	0x31, 0x1f, | 
 | 837 | 	0x32, 0x19, | 
 | 838 | 	0x33, 0xfc, | 
 | 839 | 	0x34, 0x93, | 
 | 840 | 	0xff, 0xff | 
 | 841 | }; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 842 |  | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 843 | static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe, | 
 | 844 | 		u32 srate, u32 ratio) | 
 | 845 | { | 
 | 846 | 	u8 aclk = 0; | 
 | 847 | 	u8 bclk = 0; | 
 | 848 | 	u8 m1; | 
 | 849 |  | 
 | 850 | 	aclk = 0xb5; | 
 | 851 | 	if (srate < 2000000) | 
 | 852 | 		bclk = 0x86; | 
 | 853 | 	else if (srate < 5000000) | 
 | 854 | 		bclk = 0x89; | 
 | 855 | 	else if (srate < 15000000) | 
 | 856 | 		bclk = 0x8f; | 
 | 857 | 	else if (srate < 45000000) | 
 | 858 | 		bclk = 0x95; | 
 | 859 |  | 
 | 860 | 	m1 = 0x14; | 
 | 861 | 	if (srate < 4000000) | 
 | 862 | 		m1 = 0x10; | 
 | 863 |  | 
 | 864 | 	stv0299_writereg(fe, 0x0e, 0x23); | 
 | 865 | 	stv0299_writereg(fe, 0x0f, 0x94); | 
 | 866 | 	stv0299_writereg(fe, 0x10, 0x39); | 
 | 867 | 	stv0299_writereg(fe, 0x13, aclk); | 
 | 868 | 	stv0299_writereg(fe, 0x14, bclk); | 
 | 869 | 	stv0299_writereg(fe, 0x15, 0xc9); | 
 | 870 | 	stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff); | 
 | 871 | 	stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff); | 
 | 872 | 	stv0299_writereg(fe, 0x21, (ratio) & 0xf0); | 
 | 873 | 	stv0299_writereg(fe, 0x0f, 0x80 | m1); | 
 | 874 |  | 
 | 875 | 	return 0; | 
 | 876 | } | 
 | 877 |  | 
 | 878 | static struct stv0299_config philips_sd1878_config = { | 
 | 879 | 	.demod_address = 0x68, | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 880 |      .inittab = philips_sd1878_inittab, | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 881 | 	.mclk = 88000000UL, | 
 | 882 | 	.invert = 0, | 
 | 883 | 	.skip_reinit = 0, | 
| Oliver Endriss | da2c7f6 | 2008-04-20 22:13:37 -0300 | [diff] [blame] | 884 | 	.lock_output = STV0299_LOCKOUTPUT_1, | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 885 | 	.volt13_op0_op1 = STV0299_VOLT13_OP0, | 
 | 886 | 	.min_delay_ms = 100, | 
 | 887 | 	.set_symbol_rate = philips_sd1878_ci_set_symbol_rate, | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 888 | }; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 889 |  | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 890 | /* KNC1 DVB-S (STB0899) Inittab	*/ | 
 | 891 | static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = { | 
 | 892 |  | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 893 | 	{ STB0899_DEV_ID		, 0x81 }, | 
 | 894 | 	{ STB0899_DISCNTRL1		, 0x32 }, | 
 | 895 | 	{ STB0899_DISCNTRL2		, 0x80 }, | 
 | 896 | 	{ STB0899_DISRX_ST0		, 0x04 }, | 
 | 897 | 	{ STB0899_DISRX_ST1		, 0x00 }, | 
 | 898 | 	{ STB0899_DISPARITY		, 0x00 }, | 
 | 899 | 	{ STB0899_DISFIFO		, 0x00 }, | 
 | 900 | 	{ STB0899_DISSTATUS		, 0x20 }, | 
 | 901 | 	{ STB0899_DISF22		, 0x8c }, | 
 | 902 | 	{ STB0899_DISF22RX		, 0x9a }, | 
| Manu Abraham | ef3052b | 2008-10-23 18:45:17 -0300 | [diff] [blame] | 903 | 	{ STB0899_SYSREG		, 0x0b }, | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 904 | 	{ STB0899_ACRPRESC		, 0x11 }, | 
 | 905 | 	{ STB0899_ACRDIV1		, 0x0a }, | 
 | 906 | 	{ STB0899_ACRDIV2		, 0x05 }, | 
 | 907 | 	{ STB0899_DACR1			, 0x00 }, | 
 | 908 | 	{ STB0899_DACR2			, 0x00 }, | 
 | 909 | 	{ STB0899_OUTCFG		, 0x00 }, | 
 | 910 | 	{ STB0899_MODECFG		, 0x00 }, | 
 | 911 | 	{ STB0899_IRQSTATUS_3		, 0x30 }, | 
 | 912 | 	{ STB0899_IRQSTATUS_2		, 0x00 }, | 
 | 913 | 	{ STB0899_IRQSTATUS_1		, 0x00 }, | 
 | 914 | 	{ STB0899_IRQSTATUS_0		, 0x00 }, | 
 | 915 | 	{ STB0899_IRQMSK_3		, 0xf3 }, | 
 | 916 | 	{ STB0899_IRQMSK_2		, 0xfc }, | 
 | 917 | 	{ STB0899_IRQMSK_1		, 0xff }, | 
 | 918 | 	{ STB0899_IRQMSK_0		, 0xff }, | 
 | 919 | 	{ STB0899_IRQCFG		, 0x00 }, | 
 | 920 | 	{ STB0899_I2CCFG		, 0x88 }, | 
| Manu Abraham | 40e8ce3 | 2008-02-03 19:37:02 -0300 | [diff] [blame] | 921 | 	{ STB0899_I2CRPT		, 0x58 }, /* Repeater=8, Stop=disabled */ | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 922 | 	{ STB0899_IOPVALUE5		, 0x00 }, | 
 | 923 | 	{ STB0899_IOPVALUE4		, 0x20 }, | 
 | 924 | 	{ STB0899_IOPVALUE3		, 0xc9 }, | 
 | 925 | 	{ STB0899_IOPVALUE2		, 0x90 }, | 
 | 926 | 	{ STB0899_IOPVALUE1		, 0x40 }, | 
 | 927 | 	{ STB0899_IOPVALUE0		, 0x00 }, | 
 | 928 | 	{ STB0899_GPIO00CFG		, 0x82 }, | 
 | 929 | 	{ STB0899_GPIO01CFG		, 0x82 }, | 
 | 930 | 	{ STB0899_GPIO02CFG		, 0x82 }, | 
 | 931 | 	{ STB0899_GPIO03CFG		, 0x82 }, | 
 | 932 | 	{ STB0899_GPIO04CFG		, 0x82 }, | 
 | 933 | 	{ STB0899_GPIO05CFG		, 0x82 }, | 
 | 934 | 	{ STB0899_GPIO06CFG		, 0x82 }, | 
 | 935 | 	{ STB0899_GPIO07CFG		, 0x82 }, | 
 | 936 | 	{ STB0899_GPIO08CFG		, 0x82 }, | 
 | 937 | 	{ STB0899_GPIO09CFG		, 0x82 }, | 
 | 938 | 	{ STB0899_GPIO10CFG		, 0x82 }, | 
 | 939 | 	{ STB0899_GPIO11CFG		, 0x82 }, | 
 | 940 | 	{ STB0899_GPIO12CFG		, 0x82 }, | 
 | 941 | 	{ STB0899_GPIO13CFG		, 0x82 }, | 
 | 942 | 	{ STB0899_GPIO14CFG		, 0x82 }, | 
 | 943 | 	{ STB0899_GPIO15CFG		, 0x82 }, | 
 | 944 | 	{ STB0899_GPIO16CFG		, 0x82 }, | 
 | 945 | 	{ STB0899_GPIO17CFG		, 0x82 }, | 
 | 946 | 	{ STB0899_GPIO18CFG		, 0x82 }, | 
 | 947 | 	{ STB0899_GPIO19CFG		, 0x82 }, | 
 | 948 | 	{ STB0899_GPIO20CFG		, 0x82 }, | 
 | 949 | 	{ STB0899_SDATCFG		, 0xb8 }, | 
 | 950 | 	{ STB0899_SCLTCFG		, 0xba }, | 
| Manu Abraham | 947881a | 2007-10-30 10:25:26 -0300 | [diff] [blame] | 951 | 	{ STB0899_AGCRFCFG		, 0x08 }, /* 0x1c */ | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 952 | 	{ STB0899_GPIO22		, 0x82 }, /* AGCBB2CFG */ | 
 | 953 | 	{ STB0899_GPIO21		, 0x91 }, /* AGCBB1CFG */ | 
 | 954 | 	{ STB0899_DIRCLKCFG		, 0x82 }, | 
 | 955 | 	{ STB0899_CLKOUT27CFG		, 0x7e }, | 
 | 956 | 	{ STB0899_STDBYCFG		, 0x82 }, | 
 | 957 | 	{ STB0899_CS0CFG		, 0x82 }, | 
 | 958 | 	{ STB0899_CS1CFG		, 0x82 }, | 
 | 959 | 	{ STB0899_DISEQCOCFG		, 0x20 }, | 
 | 960 | 	{ STB0899_GPIO32CFG		, 0x82 }, | 
 | 961 | 	{ STB0899_GPIO33CFG		, 0x82 }, | 
 | 962 | 	{ STB0899_GPIO34CFG		, 0x82 }, | 
 | 963 | 	{ STB0899_GPIO35CFG		, 0x82 }, | 
 | 964 | 	{ STB0899_GPIO36CFG		, 0x82 }, | 
 | 965 | 	{ STB0899_GPIO37CFG		, 0x82 }, | 
 | 966 | 	{ STB0899_GPIO38CFG		, 0x82 }, | 
 | 967 | 	{ STB0899_GPIO39CFG		, 0x82 }, | 
| Manu Abraham | f2e52cd | 2007-11-19 16:44:47 -0300 | [diff] [blame] | 968 | 	{ STB0899_NCOARSE		, 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */ | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 969 | 	{ STB0899_SYNTCTRL		, 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */ | 
 | 970 | 	{ STB0899_FILTCTRL		, 0x00 }, | 
 | 971 | 	{ STB0899_SYSCTRL		, 0x00 }, | 
 | 972 | 	{ STB0899_STOPCLK1		, 0x20 }, | 
 | 973 | 	{ STB0899_STOPCLK2		, 0x00 }, | 
 | 974 | 	{ STB0899_INTBUFSTATUS		, 0x00 }, | 
 | 975 | 	{ STB0899_INTBUFCTRL		, 0x0a }, | 
 | 976 | 	{ 0xffff			, 0xff }, | 
 | 977 | }; | 
 | 978 |  | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 979 | static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = { | 
 | 980 | 	{ STB0899_DEMOD			, 0x00 }, | 
 | 981 | 	{ STB0899_RCOMPC		, 0xc9 }, | 
 | 982 | 	{ STB0899_AGC1CN		, 0x41 }, | 
| Arvo Jarve | b2fe5c6 | 2007-10-30 09:46:04 -0300 | [diff] [blame] | 983 | 	{ STB0899_AGC1REF		, 0x08 }, | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 984 | 	{ STB0899_RTC			, 0x7a }, | 
 | 985 | 	{ STB0899_TMGCFG		, 0x4e }, | 
| Arvo Jarve | b2fe5c6 | 2007-10-30 09:46:04 -0300 | [diff] [blame] | 986 | 	{ STB0899_AGC2REF		, 0x33 }, | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 987 | 	{ STB0899_TLSR			, 0x84 }, | 
 | 988 | 	{ STB0899_CFD			, 0xee }, | 
 | 989 | 	{ STB0899_ACLC			, 0x87 }, | 
 | 990 | 	{ STB0899_BCLC			, 0x94 }, | 
 | 991 | 	{ STB0899_EQON			, 0x41 }, | 
 | 992 | 	{ STB0899_LDT			, 0xdd }, | 
 | 993 | 	{ STB0899_LDT2			, 0xc9 }, | 
 | 994 | 	{ STB0899_EQUALREF		, 0xb4 }, | 
 | 995 | 	{ STB0899_TMGRAMP		, 0x10 }, | 
 | 996 | 	{ STB0899_TMGTHD		, 0x30 }, | 
 | 997 | 	{ STB0899_IDCCOMP		, 0xfb }, | 
 | 998 | 	{ STB0899_QDCCOMP		, 0x03 }, | 
 | 999 | 	{ STB0899_POWERI		, 0x3b }, | 
 | 1000 | 	{ STB0899_POWERQ		, 0x3d }, | 
 | 1001 | 	{ STB0899_RCOMP			, 0x81 }, | 
 | 1002 | 	{ STB0899_AGCIQIN		, 0x80 }, | 
 | 1003 | 	{ STB0899_AGC2I1		, 0x04 }, | 
 | 1004 | 	{ STB0899_AGC2I2		, 0xf5 }, | 
 | 1005 | 	{ STB0899_TLIR			, 0x25 }, | 
 | 1006 | 	{ STB0899_RTF			, 0x80 }, | 
 | 1007 | 	{ STB0899_DSTATUS		, 0x00 }, | 
 | 1008 | 	{ STB0899_LDI			, 0xca }, | 
 | 1009 | 	{ STB0899_CFRM			, 0xf1 }, | 
 | 1010 | 	{ STB0899_CFRL			, 0xf3 }, | 
 | 1011 | 	{ STB0899_NIRM			, 0x2a }, | 
 | 1012 | 	{ STB0899_NIRL			, 0x05 }, | 
 | 1013 | 	{ STB0899_ISYMB			, 0x17 }, | 
 | 1014 | 	{ STB0899_QSYMB			, 0xfa }, | 
 | 1015 | 	{ STB0899_SFRH			, 0x2f }, | 
 | 1016 | 	{ STB0899_SFRM			, 0x68 }, | 
 | 1017 | 	{ STB0899_SFRL			, 0x40 }, | 
 | 1018 | 	{ STB0899_SFRUPH		, 0x2f }, | 
 | 1019 | 	{ STB0899_SFRUPM		, 0x68 }, | 
 | 1020 | 	{ STB0899_SFRUPL		, 0x40 }, | 
 | 1021 | 	{ STB0899_EQUAI1		, 0xfd }, | 
 | 1022 | 	{ STB0899_EQUAQ1		, 0x04 }, | 
 | 1023 | 	{ STB0899_EQUAI2		, 0x0f }, | 
 | 1024 | 	{ STB0899_EQUAQ2		, 0xff }, | 
 | 1025 | 	{ STB0899_EQUAI3		, 0xdf }, | 
 | 1026 | 	{ STB0899_EQUAQ3		, 0xfa }, | 
 | 1027 | 	{ STB0899_EQUAI4		, 0x37 }, | 
 | 1028 | 	{ STB0899_EQUAQ4		, 0x0d }, | 
 | 1029 | 	{ STB0899_EQUAI5		, 0xbd }, | 
 | 1030 | 	{ STB0899_EQUAQ5		, 0xf7 }, | 
 | 1031 | 	{ STB0899_DSTATUS2		, 0x00 }, | 
 | 1032 | 	{ STB0899_VSTATUS		, 0x00 }, | 
 | 1033 | 	{ STB0899_VERROR		, 0xff }, | 
 | 1034 | 	{ STB0899_IQSWAP		, 0x2a }, | 
 | 1035 | 	{ STB0899_ECNT1M		, 0x00 }, | 
 | 1036 | 	{ STB0899_ECNT1L		, 0x00 }, | 
 | 1037 | 	{ STB0899_ECNT2M		, 0x00 }, | 
 | 1038 | 	{ STB0899_ECNT2L		, 0x00 }, | 
 | 1039 | 	{ STB0899_ECNT3M		, 0x00 }, | 
 | 1040 | 	{ STB0899_ECNT3L		, 0x00 }, | 
 | 1041 | 	{ STB0899_FECAUTO1		, 0x06 }, | 
 | 1042 | 	{ STB0899_FECM			, 0x01 }, | 
 | 1043 | 	{ STB0899_VTH12			, 0xf0 }, | 
 | 1044 | 	{ STB0899_VTH23			, 0xa0 }, | 
 | 1045 | 	{ STB0899_VTH34			, 0x78 }, | 
 | 1046 | 	{ STB0899_VTH56			, 0x4e }, | 
 | 1047 | 	{ STB0899_VTH67			, 0x48 }, | 
 | 1048 | 	{ STB0899_VTH78			, 0x38 }, | 
 | 1049 | 	{ STB0899_PRVIT			, 0xff }, | 
 | 1050 | 	{ STB0899_VITSYNC		, 0x19 }, | 
 | 1051 | 	{ STB0899_RSULC			, 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */ | 
 | 1052 | 	{ STB0899_TSULC			, 0x42 }, | 
 | 1053 | 	{ STB0899_RSLLC			, 0x40 }, | 
 | 1054 | 	{ STB0899_TSLPL			, 0x12 }, | 
 | 1055 | 	{ STB0899_TSCFGH		, 0x0c }, | 
 | 1056 | 	{ STB0899_TSCFGM		, 0x00 }, | 
 | 1057 | 	{ STB0899_TSCFGL		, 0x0c }, | 
 | 1058 | 	{ STB0899_TSOUT			, 0x0d }, /* 0x0d for CAM */ | 
 | 1059 | 	{ STB0899_RSSYNCDEL		, 0x00 }, | 
 | 1060 | 	{ STB0899_TSINHDELH		, 0x02 }, | 
 | 1061 | 	{ STB0899_TSINHDELM		, 0x00 }, | 
 | 1062 | 	{ STB0899_TSINHDELL		, 0x00 }, | 
 | 1063 | 	{ STB0899_TSLLSTKM		, 0x00 }, | 
 | 1064 | 	{ STB0899_TSLLSTKL		, 0x00 }, | 
 | 1065 | 	{ STB0899_TSULSTKM		, 0x00 }, | 
 | 1066 | 	{ STB0899_TSULSTKL		, 0xab }, | 
 | 1067 | 	{ STB0899_PCKLENUL		, 0x00 }, | 
 | 1068 | 	{ STB0899_PCKLENLL		, 0xcc }, | 
 | 1069 | 	{ STB0899_RSPCKLEN		, 0xcc }, | 
 | 1070 | 	{ STB0899_TSSTATUS		, 0x80 }, | 
 | 1071 | 	{ STB0899_ERRCTRL1		, 0xb6 }, | 
 | 1072 | 	{ STB0899_ERRCTRL2		, 0x96 }, | 
 | 1073 | 	{ STB0899_ERRCTRL3		, 0x89 }, | 
 | 1074 | 	{ STB0899_DMONMSK1		, 0x27 }, | 
 | 1075 | 	{ STB0899_DMONMSK0		, 0x03 }, | 
 | 1076 | 	{ STB0899_DEMAPVIT		, 0x5c }, | 
 | 1077 | 	{ STB0899_PLPARM		, 0x1f }, | 
 | 1078 | 	{ STB0899_PDELCTRL		, 0x48 }, | 
 | 1079 | 	{ STB0899_PDELCTRL2		, 0x00 }, | 
 | 1080 | 	{ STB0899_BBHCTRL1		, 0x00 }, | 
 | 1081 | 	{ STB0899_BBHCTRL2		, 0x00 }, | 
 | 1082 | 	{ STB0899_HYSTTHRESH		, 0x77 }, | 
 | 1083 | 	{ STB0899_MATCSTM		, 0x00 }, | 
 | 1084 | 	{ STB0899_MATCSTL		, 0x00 }, | 
 | 1085 | 	{ STB0899_UPLCSTM		, 0x00 }, | 
 | 1086 | 	{ STB0899_UPLCSTL		, 0x00 }, | 
 | 1087 | 	{ STB0899_DFLCSTM		, 0x00 }, | 
 | 1088 | 	{ STB0899_DFLCSTL		, 0x00 }, | 
 | 1089 | 	{ STB0899_SYNCCST		, 0x00 }, | 
 | 1090 | 	{ STB0899_SYNCDCSTM		, 0x00 }, | 
 | 1091 | 	{ STB0899_SYNCDCSTL		, 0x00 }, | 
 | 1092 | 	{ STB0899_ISI_ENTRY		, 0x00 }, | 
 | 1093 | 	{ STB0899_ISI_BIT_EN		, 0x00 }, | 
 | 1094 | 	{ STB0899_MATSTRM		, 0x00 }, | 
 | 1095 | 	{ STB0899_MATSTRL		, 0x00 }, | 
 | 1096 | 	{ STB0899_UPLSTRM		, 0x00 }, | 
 | 1097 | 	{ STB0899_UPLSTRL		, 0x00 }, | 
 | 1098 | 	{ STB0899_DFLSTRM		, 0x00 }, | 
 | 1099 | 	{ STB0899_DFLSTRL		, 0x00 }, | 
 | 1100 | 	{ STB0899_SYNCSTR		, 0x00 }, | 
 | 1101 | 	{ STB0899_SYNCDSTRM		, 0x00 }, | 
 | 1102 | 	{ STB0899_SYNCDSTRL		, 0x00 }, | 
 | 1103 | 	{ STB0899_CFGPDELSTATUS1	, 0x10 }, | 
 | 1104 | 	{ STB0899_CFGPDELSTATUS2	, 0x00 }, | 
 | 1105 | 	{ STB0899_BBFERRORM		, 0x00 }, | 
 | 1106 | 	{ STB0899_BBFERRORL		, 0x00 }, | 
 | 1107 | 	{ STB0899_UPKTERRORM		, 0x00 }, | 
 | 1108 | 	{ STB0899_UPKTERRORL		, 0x00 }, | 
 | 1109 | 	{ 0xffff			, 0xff }, | 
 | 1110 | }; | 
 | 1111 |  | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1112 | /* STB0899 demodulator config for the KNC1 and clones */ | 
 | 1113 | static struct stb0899_config knc1_dvbs2_config = { | 
 | 1114 | 	.init_dev		= knc1_stb0899_s1_init_1, | 
| Manu Abraham | 8be969b | 2008-01-25 18:20:48 -0300 | [diff] [blame] | 1115 | 	.init_s2_demod		= stb0899_s2_init_2, | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1116 | 	.init_s1_demod		= knc1_stb0899_s1_init_3, | 
| Manu Abraham | 8be969b | 2008-01-25 18:20:48 -0300 | [diff] [blame] | 1117 | 	.init_s2_fec		= stb0899_s2_init_4, | 
 | 1118 | 	.init_tst		= stb0899_s1_init_5, | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1119 |  | 
| Manu Abraham | 043a68b | 2008-01-18 14:15:17 -0300 | [diff] [blame] | 1120 | 	.postproc		= NULL, | 
 | 1121 |  | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1122 | 	.demod_address		= 0x68, | 
 | 1123 | //	.ts_output_mode		= STB0899_OUT_PARALLEL,	/* types = SERIAL/PARALLEL	*/ | 
 | 1124 | 	.block_sync_mode	= STB0899_SYNC_FORCED,	/* DSS, SYNC_FORCED/UNSYNCED	*/ | 
 | 1125 | //	.ts_pfbit_toggle	= STB0899_MPEG_NORMAL,	/* DirecTV, MPEG toggling seq	*/ | 
 | 1126 |  | 
 | 1127 | 	.xtal_freq		= 27000000, | 
| Manu Abraham | 7dd82f7 | 2007-09-25 14:57:19 -0300 | [diff] [blame] | 1128 | 	.inversion		= IQ_SWAP_OFF, /* 1 */ | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1129 |  | 
| Manu Abraham | b91a7cb | 2008-03-04 19:19:58 -0300 | [diff] [blame] | 1130 | 	.lo_clk			= 76500000, | 
 | 1131 | 	.hi_clk			= 90000000, | 
 | 1132 |  | 
| Manu Abraham | 8be969b | 2008-01-25 18:20:48 -0300 | [diff] [blame] | 1133 | 	.esno_ave		= STB0899_DVBS2_ESNO_AVE, | 
 | 1134 | 	.esno_quant		= STB0899_DVBS2_ESNO_QUANT, | 
 | 1135 | 	.avframes_coarse	= STB0899_DVBS2_AVFRAMES_COARSE, | 
 | 1136 | 	.avframes_fine		= STB0899_DVBS2_AVFRAMES_FINE, | 
 | 1137 | 	.miss_threshold		= STB0899_DVBS2_MISS_THRESHOLD, | 
 | 1138 | 	.uwp_threshold_acq	= STB0899_DVBS2_UWP_THRESHOLD_ACQ, | 
 | 1139 | 	.uwp_threshold_track	= STB0899_DVBS2_UWP_THRESHOLD_TRACK, | 
 | 1140 | 	.uwp_threshold_sof	= STB0899_DVBS2_UWP_THRESHOLD_SOF, | 
 | 1141 | 	.sof_search_timeout	= STB0899_DVBS2_SOF_SEARCH_TIMEOUT, | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1142 |  | 
| Manu Abraham | 8be969b | 2008-01-25 18:20:48 -0300 | [diff] [blame] | 1143 | 	.btr_nco_bits		= STB0899_DVBS2_BTR_NCO_BITS, | 
 | 1144 | 	.btr_gain_shift_offset	= STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET, | 
 | 1145 | 	.crl_nco_bits		= STB0899_DVBS2_CRL_NCO_BITS, | 
 | 1146 | 	.ldpc_max_iter		= STB0899_DVBS2_LDPC_MAX_ITER, | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1147 |  | 
 | 1148 | 	.tuner_get_frequency	= tda8261_get_frequency, | 
 | 1149 | 	.tuner_set_frequency	= tda8261_set_frequency, | 
 | 1150 | 	.tuner_set_bandwidth	= NULL, | 
 | 1151 | 	.tuner_get_bandwidth	= tda8261_get_bandwidth, | 
| Manu Abraham | 043a68b | 2008-01-18 14:15:17 -0300 | [diff] [blame] | 1152 | 	.tuner_set_rfsiggain	= NULL | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1153 | }; | 
 | 1154 |  | 
| Manu Abraham | b11eb46 | 2007-10-05 01:57:59 -0300 | [diff] [blame] | 1155 | /* | 
 | 1156 |  * SD1878/SHA tuner config | 
 | 1157 |  * 1F, Single I/P, Horizontal mount, High Sensitivity | 
 | 1158 |  */ | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1159 | static const struct tda8261_config sd1878c_config = { | 
| Manu Abraham | b11eb46 | 2007-10-05 01:57:59 -0300 | [diff] [blame] | 1160 | //	.name		= "SD1878/SHA", | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1161 | 	.addr		= 0x60, | 
 | 1162 | 	.step_size	= TDA8261_STEP_1000 /* kHz */ | 
 | 1163 | }; | 
 | 1164 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1165 | static u8 read_pwm(struct budget_av *budget_av) | 
 | 1166 | { | 
 | 1167 | 	u8 b = 0xff; | 
 | 1168 | 	u8 pwm; | 
 | 1169 | 	struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1}, | 
 | 1170 | 	{.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} | 
 | 1171 | 	}; | 
 | 1172 |  | 
 | 1173 | 	if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2) | 
 | 1174 | 	    || (pwm == 0xff)) | 
 | 1175 | 		pwm = 0x48; | 
 | 1176 |  | 
 | 1177 | 	return pwm; | 
 | 1178 | } | 
 | 1179 |  | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1180 | #define SUBID_DVBS_KNC1			0x0010 | 
 | 1181 | #define SUBID_DVBS_KNC1_PLUS		0x0011 | 
 | 1182 | #define SUBID_DVBS_TYPHOON		0x4f56 | 
 | 1183 | #define SUBID_DVBS_CINERGY1200		0x1154 | 
 | 1184 | #define SUBID_DVBS_CYNERGY1200N 	0x1155 | 
 | 1185 | #define SUBID_DVBS_TV_STAR		0x0014 | 
| Oliver Endriss | 03aa73c | 2008-01-29 23:56:51 -0300 | [diff] [blame] | 1186 | #define SUBID_DVBS_TV_STAR_PLUS_X4	0x0015 | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1187 | #define SUBID_DVBS_TV_STAR_CI		0x0016 | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1188 | #define SUBID_DVBS2_KNC1		0x0018 | 
 | 1189 | #define SUBID_DVBS2_KNC1_OEM		0x0019 | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1190 | #define SUBID_DVBS_EASYWATCH_1  	0x001a | 
| Oliver Endriss | f72ce64 | 2007-05-13 23:25:57 -0300 | [diff] [blame] | 1191 | #define SUBID_DVBS_EASYWATCH_2  	0x001b | 
| Arvo Jarve | 5dc1611 | 2007-10-25 13:25:23 -0300 | [diff] [blame] | 1192 | #define SUBID_DVBS2_EASYWATCH		0x001d | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1193 | #define SUBID_DVBS_EASYWATCH		0x001e | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1194 |  | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1195 | #define SUBID_DVBC_EASYWATCH		0x002a | 
 | 1196 | #define SUBID_DVBC_EASYWATCH_MK3	0x002c | 
 | 1197 | #define SUBID_DVBC_KNC1			0x0020 | 
 | 1198 | #define SUBID_DVBC_KNC1_PLUS		0x0021 | 
 | 1199 | #define SUBID_DVBC_KNC1_MK3		0x0022 | 
 | 1200 | #define SUBID_DVBC_KNC1_PLUS_MK3	0x0023 | 
 | 1201 | #define SUBID_DVBC_CINERGY1200		0x1156 | 
 | 1202 | #define SUBID_DVBC_CINERGY1200_MK3	0x1176 | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1203 |  | 
| Kim Sandberg | 251130b | 2008-01-30 00:42:01 -0300 | [diff] [blame] | 1204 | #define SUBID_DVBT_EASYWATCH		0x003a | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1205 | #define SUBID_DVBT_KNC1_PLUS		0x0031 | 
 | 1206 | #define SUBID_DVBT_KNC1			0x0030 | 
 | 1207 | #define SUBID_DVBT_CINERGY1200		0x1157 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1208 |  | 
 | 1209 | static void frontend_init(struct budget_av *budget_av) | 
 | 1210 | { | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1211 | 	struct saa7146_dev * saa = budget_av->budget.dev; | 
 | 1212 | 	struct dvb_frontend * fe = NULL; | 
 | 1213 |  | 
| Andrew de Quincey | 473f542 | 2006-04-13 17:29:07 -0300 | [diff] [blame] | 1214 | 	/* Enable / PowerON Frontend */ | 
 | 1215 | 	saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | 
 | 1216 |  | 
| Hartmut Birr | 740cf9e | 2006-11-03 15:34:18 -0300 | [diff] [blame] | 1217 | 	/* Wait for PowerON */ | 
 | 1218 | 	msleep(100); | 
 | 1219 |  | 
| Andrew de Quincey | 473f542 | 2006-04-13 17:29:07 -0300 | [diff] [blame] | 1220 | 	/* additional setup necessary for the PLUS cards */ | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1221 | 	switch (saa->pci->subsystem_device) { | 
 | 1222 | 		case SUBID_DVBS_KNC1_PLUS: | 
 | 1223 | 		case SUBID_DVBC_KNC1_PLUS: | 
 | 1224 | 		case SUBID_DVBT_KNC1_PLUS: | 
| Thomas Hamm | c01d1e4 | 2006-11-17 07:12:58 -0300 | [diff] [blame] | 1225 | 		case SUBID_DVBC_EASYWATCH: | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1226 | 		case SUBID_DVBC_KNC1_PLUS_MK3: | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1227 | 		case SUBID_DVBS2_KNC1: | 
 | 1228 | 		case SUBID_DVBS2_KNC1_OEM: | 
| Arvo Jarve | 5dc1611 | 2007-10-25 13:25:23 -0300 | [diff] [blame] | 1229 | 		case SUBID_DVBS2_EASYWATCH: | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1230 | 			saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1231 | 			break; | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1232 | 	} | 
 | 1233 |  | 
 | 1234 | 	switch (saa->pci->subsystem_device) { | 
 | 1235 |  | 
 | 1236 | 	case SUBID_DVBS_KNC1: | 
| Christoph Pfister | c4e3bcb | 2008-04-09 17:37:36 -0300 | [diff] [blame] | 1237 | 		/* | 
 | 1238 | 		 * maybe that setting is needed for other dvb-s cards as well, | 
 | 1239 | 		 * but so far it has been only confirmed for this type | 
 | 1240 | 		 */ | 
 | 1241 | 		budget_av->reinitialise_demod = 1; | 
 | 1242 | 		/* fall through */ | 
| Christoph Pfister | 4e318be | 2006-08-12 09:13:35 -0300 | [diff] [blame] | 1243 | 	case SUBID_DVBS_KNC1_PLUS: | 
| Lothar Englisch | 60110ce | 2006-06-06 16:13:46 -0300 | [diff] [blame] | 1244 | 	case SUBID_DVBS_EASYWATCH_1: | 
| Andrew de Quincey | effa791 | 2006-01-09 15:25:09 -0200 | [diff] [blame] | 1245 | 		if (saa->pci->subsystem_vendor == 0x1894) { | 
| Andrew de Quincey | 2bfe031 | 2006-08-08 09:10:08 -0300 | [diff] [blame] | 1246 | 			fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config, | 
| Andrew de Quincey | effa791 | 2006-01-09 15:25:09 -0200 | [diff] [blame] | 1247 | 					     &budget_av->budget.i2c_adap); | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1248 | 			if (fe) { | 
| Andrew de Quincey | 1c72cfdc | 2006-09-05 17:58:20 -0300 | [diff] [blame] | 1249 | 				dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap); | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1250 | 			} | 
| Andrew de Quincey | effa791 | 2006-01-09 15:25:09 -0200 | [diff] [blame] | 1251 | 		} else { | 
| Andrew de Quincey | 2bfe031 | 2006-08-08 09:10:08 -0300 | [diff] [blame] | 1252 | 			fe = dvb_attach(stv0299_attach, &typhoon_config, | 
| Andrew de Quincey | effa791 | 2006-01-09 15:25:09 -0200 | [diff] [blame] | 1253 | 					     &budget_av->budget.i2c_adap); | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1254 | 			if (fe) { | 
| Patrick Boettcher | dea7486 | 2006-05-14 05:01:31 -0300 | [diff] [blame] | 1255 | 				fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1256 | 			} | 
| Andrew de Quincey | effa791 | 2006-01-09 15:25:09 -0200 | [diff] [blame] | 1257 | 		} | 
 | 1258 | 		break; | 
 | 1259 |  | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 1260 | 	case SUBID_DVBS_TV_STAR: | 
| Oliver Endriss | 03aa73c | 2008-01-29 23:56:51 -0300 | [diff] [blame] | 1261 | 	case SUBID_DVBS_TV_STAR_PLUS_X4: | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 1262 | 	case SUBID_DVBS_TV_STAR_CI: | 
 | 1263 | 	case SUBID_DVBS_CYNERGY1200N: | 
| Thilo Berger | 36f4f33 | 2006-02-27 00:09:08 -0300 | [diff] [blame] | 1264 | 	case SUBID_DVBS_EASYWATCH: | 
| Oliver Endriss | f72ce64 | 2007-05-13 23:25:57 -0300 | [diff] [blame] | 1265 | 	case SUBID_DVBS_EASYWATCH_2: | 
| Andrew de Quincey | 2bfe031 | 2006-08-08 09:10:08 -0300 | [diff] [blame] | 1266 | 		fe = dvb_attach(stv0299_attach, &philips_sd1878_config, | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 1267 | 				&budget_av->budget.i2c_adap); | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1268 | 		if (fe) { | 
| Michael Krufky | 9b98fd2 | 2007-05-07 01:48:56 -0300 | [diff] [blame] | 1269 | 			dvb_attach(dvb_pll_attach, fe, 0x60, | 
 | 1270 | 				   &budget_av->budget.i2c_adap, | 
| Michael Krufky | 47a9991 | 2007-06-12 16:10:51 -0300 | [diff] [blame] | 1271 | 				   DVB_PLL_PHILIPS_SD1878_TDA8261); | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1272 | 		} | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 1273 | 		break; | 
 | 1274 |  | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1275 | 	case SUBID_DVBS_TYPHOON: | 
| Andrew de Quincey | 2bfe031 | 2006-08-08 09:10:08 -0300 | [diff] [blame] | 1276 | 		fe = dvb_attach(stv0299_attach, &typhoon_config, | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1277 | 				    &budget_av->budget.i2c_adap); | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1278 | 		if (fe) { | 
| Patrick Boettcher | dea7486 | 2006-05-14 05:01:31 -0300 | [diff] [blame] | 1279 | 			fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1280 | 		} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1281 | 		break; | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1282 | 	case SUBID_DVBS2_KNC1: | 
 | 1283 | 	case SUBID_DVBS2_KNC1_OEM: | 
| Arvo Jarve | 5dc1611 | 2007-10-25 13:25:23 -0300 | [diff] [blame] | 1284 | 	case SUBID_DVBS2_EASYWATCH: | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1285 | 		budget_av->reinitialise_demod = 1; | 
| Manu Abraham | ae9902d | 2007-10-08 18:51:54 -0300 | [diff] [blame] | 1286 | 		if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap))) | 
 | 1287 | 			dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1288 |  | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1289 | 		break; | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1290 | 	case SUBID_DVBS_CINERGY1200: | 
| Andrew de Quincey | 2bfe031 | 2006-08-08 09:10:08 -0300 | [diff] [blame] | 1291 | 		fe = dvb_attach(stv0299_attach, &cinergy_1200s_config, | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1292 | 				    &budget_av->budget.i2c_adap); | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1293 | 		if (fe) { | 
| Patrick Boettcher | dea7486 | 2006-05-14 05:01:31 -0300 | [diff] [blame] | 1294 | 			fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params; | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1295 | 		} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1296 | 		break; | 
 | 1297 |  | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1298 | 	case SUBID_DVBC_KNC1: | 
 | 1299 | 	case SUBID_DVBC_KNC1_PLUS: | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 1300 | 	case SUBID_DVBC_CINERGY1200: | 
| Thomas Hamm | c01d1e4 | 2006-11-17 07:12:58 -0300 | [diff] [blame] | 1301 | 	case SUBID_DVBC_EASYWATCH: | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 1302 | 		budget_av->reinitialise_demod = 1; | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1303 | 		budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; | 
| Andrew de Quincey | 2bfe031 | 2006-08-08 09:10:08 -0300 | [diff] [blame] | 1304 | 		fe = dvb_attach(tda10021_attach, &philips_cu1216_config, | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1305 | 				     &budget_av->budget.i2c_adap, | 
 | 1306 | 				     read_pwm(budget_av)); | 
| Andrew de Quincey | 61cebe9 | 2006-11-19 14:10:59 -0300 | [diff] [blame] | 1307 | 		if (fe == NULL) | 
 | 1308 | 			fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress, | 
 | 1309 | 					     &budget_av->budget.i2c_adap, | 
 | 1310 | 					     read_pwm(budget_av)); | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1311 | 		if (fe) { | 
| Patrick Boettcher | dea7486 | 2006-05-14 05:01:31 -0300 | [diff] [blame] | 1312 | 			fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; | 
| Andrew de Quincey | e87d41c | 2006-04-18 17:47:11 -0300 | [diff] [blame] | 1313 | 		} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1314 | 		break; | 
 | 1315 |  | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1316 | 	case SUBID_DVBC_EASYWATCH_MK3: | 
 | 1317 | 	case SUBID_DVBC_CINERGY1200_MK3: | 
 | 1318 | 	case SUBID_DVBC_KNC1_MK3: | 
 | 1319 | 	case SUBID_DVBC_KNC1_PLUS_MK3: | 
 | 1320 | 		budget_av->reinitialise_demod = 1; | 
 | 1321 | 		budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; | 
| Antti Palosaari | 4388c3b | 2008-05-17 22:58:04 -0300 | [diff] [blame] | 1322 | 		fe = dvb_attach(tda10023_attach, | 
 | 1323 | 			&philips_cu1216_tda10023_config, | 
 | 1324 | 			&budget_av->budget.i2c_adap, | 
 | 1325 | 			read_pwm(budget_av)); | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1326 | 		if (fe) { | 
 | 1327 | 			fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params; | 
 | 1328 | 		} | 
 | 1329 | 		break; | 
 | 1330 |  | 
| Kim Sandberg | 251130b | 2008-01-30 00:42:01 -0300 | [diff] [blame] | 1331 | 	case SUBID_DVBT_EASYWATCH: | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1332 | 	case SUBID_DVBT_KNC1: | 
 | 1333 | 	case SUBID_DVBT_KNC1_PLUS: | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1334 | 	case SUBID_DVBT_CINERGY1200: | 
| Andrew de Quincey | 5c1208b | 2006-05-22 10:32:02 -0300 | [diff] [blame] | 1335 | 		budget_av->reinitialise_demod = 1; | 
| Andrew de Quincey | 2bfe031 | 2006-08-08 09:10:08 -0300 | [diff] [blame] | 1336 | 		fe = dvb_attach(tda10046_attach, &philips_tu1216_config, | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1337 | 				     &budget_av->budget.i2c_adap); | 
| Andrew de Quincey | 6b3ccab | 2006-04-20 12:01:47 -0300 | [diff] [blame] | 1338 | 		if (fe) { | 
| Patrick Boettcher | dea7486 | 2006-05-14 05:01:31 -0300 | [diff] [blame] | 1339 | 			fe->ops.tuner_ops.init = philips_tu1216_tuner_init; | 
 | 1340 | 			fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params; | 
| Andrew de Quincey | 6b3ccab | 2006-04-20 12:01:47 -0300 | [diff] [blame] | 1341 | 		} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1342 | 		break; | 
 | 1343 | 	} | 
 | 1344 |  | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1345 | 	if (fe == NULL) { | 
 | 1346 | 		printk(KERN_ERR "budget-av: A frontend driver was not found " | 
| Bjorn Helgaas | 29e66a6 | 2008-09-04 17:24:51 -0300 | [diff] [blame] | 1347 | 				"for device [%04x:%04x] subsystem [%04x:%04x]\n", | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1348 | 		       saa->pci->vendor, | 
 | 1349 | 		       saa->pci->device, | 
 | 1350 | 		       saa->pci->subsystem_vendor, | 
 | 1351 | 		       saa->pci->subsystem_device); | 
 | 1352 | 		return; | 
 | 1353 | 	} | 
 | 1354 |  | 
 | 1355 | 	budget_av->budget.dvb_frontend = fe; | 
 | 1356 |  | 
 | 1357 | 	if (dvb_register_frontend(&budget_av->budget.dvb_adapter, | 
 | 1358 | 				  budget_av->budget.dvb_frontend)) { | 
 | 1359 | 		printk(KERN_ERR "budget-av: Frontend registration failed!\n"); | 
| Andrew de Quincey | f52a838 | 2006-08-08 09:10:09 -0300 | [diff] [blame] | 1360 | 		dvb_frontend_detach(budget_av->budget.dvb_frontend); | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1361 | 		budget_av->budget.dvb_frontend = NULL; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1362 | 	} | 
 | 1363 | } | 
 | 1364 |  | 
 | 1365 |  | 
 | 1366 | static void budget_av_irq(struct saa7146_dev *dev, u32 * isr) | 
 | 1367 | { | 
 | 1368 | 	struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; | 
 | 1369 |  | 
 | 1370 | 	dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av); | 
 | 1371 |  | 
 | 1372 | 	if (*isr & MASK_10) | 
 | 1373 | 		ttpci_budget_irq10_handler(dev, isr); | 
 | 1374 | } | 
 | 1375 |  | 
 | 1376 | static int budget_av_detach(struct saa7146_dev *dev) | 
 | 1377 | { | 
 | 1378 | 	struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; | 
 | 1379 | 	int err; | 
 | 1380 |  | 
 | 1381 | 	dprintk(2, "dev: %p\n", dev); | 
 | 1382 |  | 
 | 1383 | 	if (1 == budget_av->has_saa7113) { | 
 | 1384 | 		saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); | 
 | 1385 |  | 
 | 1386 | 		msleep(200); | 
 | 1387 |  | 
 | 1388 | 		saa7146_unregister_device(&budget_av->vd, dev); | 
| Marco Schluessler | 716a4e3 | 2007-02-03 14:47:14 -0300 | [diff] [blame] | 1389 |  | 
 | 1390 | 		saa7146_vv_release(dev); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1391 | 	} | 
 | 1392 |  | 
 | 1393 | 	if (budget_av->budget.ci_present) | 
 | 1394 | 		ciintf_deinit(budget_av); | 
 | 1395 |  | 
| Andrew de Quincey | 2bfe031 | 2006-08-08 09:10:08 -0300 | [diff] [blame] | 1396 | 	if (budget_av->budget.dvb_frontend != NULL) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1397 | 		dvb_unregister_frontend(budget_av->budget.dvb_frontend); | 
| Andrew de Quincey | f52a838 | 2006-08-08 09:10:09 -0300 | [diff] [blame] | 1398 | 		dvb_frontend_detach(budget_av->budget.dvb_frontend); | 
| Andrew de Quincey | 2bfe031 | 2006-08-08 09:10:08 -0300 | [diff] [blame] | 1399 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1400 | 	err = ttpci_budget_deinit(&budget_av->budget); | 
 | 1401 |  | 
 | 1402 | 	kfree(budget_av); | 
 | 1403 |  | 
 | 1404 | 	return err; | 
 | 1405 | } | 
 | 1406 |  | 
 | 1407 | static struct saa7146_ext_vv vv_data; | 
 | 1408 |  | 
 | 1409 | static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) | 
 | 1410 | { | 
 | 1411 | 	struct budget_av *budget_av; | 
 | 1412 | 	u8 *mac; | 
 | 1413 | 	int err; | 
 | 1414 |  | 
 | 1415 | 	dprintk(2, "dev: %p\n", dev); | 
 | 1416 |  | 
| Panagiotis Issaris | 7408187 | 2006-01-11 19:40:56 -0200 | [diff] [blame] | 1417 | 	if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL))) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1418 | 		return -ENOMEM; | 
 | 1419 |  | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1420 | 	budget_av->has_saa7113 = 0; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1421 | 	budget_av->budget.ci_present = 0; | 
 | 1422 |  | 
 | 1423 | 	dev->ext_priv = budget_av; | 
 | 1424 |  | 
| Janne Grunau | 26dc4d0 | 2008-09-21 20:50:11 -0300 | [diff] [blame] | 1425 | 	err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE, | 
 | 1426 | 				adapter_nr); | 
 | 1427 | 	if (err) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1428 | 		kfree(budget_av); | 
 | 1429 | 		return err; | 
 | 1430 | 	} | 
 | 1431 |  | 
 | 1432 | 	/* knc1 initialization */ | 
 | 1433 | 	saa7146_write(dev, DD1_STREAM_B, 0x04000000); | 
 | 1434 | 	saa7146_write(dev, DD1_INIT, 0x07000600); | 
 | 1435 | 	saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26); | 
 | 1436 |  | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1437 | 	if (saa7113_init(budget_av) == 0) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1438 | 		budget_av->has_saa7113 = 1; | 
 | 1439 |  | 
 | 1440 | 		if (0 != saa7146_vv_init(dev, &vv_data)) { | 
 | 1441 | 			/* fixme: proper cleanup here */ | 
 | 1442 | 			ERR(("cannot init vv subsystem.\n")); | 
 | 1443 | 			return err; | 
 | 1444 | 		} | 
 | 1445 |  | 
 | 1446 | 		if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { | 
 | 1447 | 			/* fixme: proper cleanup here */ | 
 | 1448 | 			ERR(("cannot register capture v4l2 device.\n")); | 
| Marco Schluessler | 716a4e3 | 2007-02-03 14:47:14 -0300 | [diff] [blame] | 1449 | 			saa7146_vv_release(dev); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1450 | 			return err; | 
 | 1451 | 		} | 
 | 1452 |  | 
 | 1453 | 		/* beware: this modifies dev->vv ... */ | 
 | 1454 | 		saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A, | 
 | 1455 | 						SAA7146_HPS_SYNC_PORT_A); | 
 | 1456 |  | 
 | 1457 | 		saa7113_setinput(budget_av, 0); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1458 | 	} | 
 | 1459 |  | 
 | 1460 | 	/* fixme: find some sane values here... */ | 
 | 1461 | 	saa7146_write(dev, PCI_BT_V1, 0x1c00101f); | 
 | 1462 |  | 
| Johannes Stezenbach | fdc53a6 | 2005-05-16 21:54:39 -0700 | [diff] [blame] | 1463 | 	mac = budget_av->budget.dvb_adapter.proposed_mac; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1464 | 	if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) { | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1465 | 		printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n", | 
| Johannes Stezenbach | fdc53a6 | 2005-05-16 21:54:39 -0700 | [diff] [blame] | 1466 | 		       budget_av->budget.dvb_adapter.num); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1467 | 		memset(mac, 0, 6); | 
 | 1468 | 	} else { | 
| Johannes Stezenbach | b82a96a | 2005-05-16 21:54:49 -0700 | [diff] [blame] | 1469 | 		printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", | 
| Johannes Stezenbach | fdc53a6 | 2005-05-16 21:54:39 -0700 | [diff] [blame] | 1470 | 		       budget_av->budget.dvb_adapter.num, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1471 | 		       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | 
 | 1472 | 	} | 
 | 1473 |  | 
| Johannes Stezenbach | fdc53a6 | 2005-05-16 21:54:39 -0700 | [diff] [blame] | 1474 | 	budget_av->budget.dvb_adapter.priv = budget_av; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1475 | 	frontend_init(budget_av); | 
| Andrew de Quincey | c5e768a | 2006-06-29 13:16:11 -0300 | [diff] [blame] | 1476 | 	ciintf_init(budget_av); | 
| Oliver Endriss | 32e4c3a | 2006-07-18 22:55:23 -0300 | [diff] [blame] | 1477 |  | 
 | 1478 | 	ttpci_budget_init_hooks(&budget_av->budget); | 
 | 1479 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1480 | 	return 0; | 
 | 1481 | } | 
 | 1482 |  | 
 | 1483 | #define KNC1_INPUTS 2 | 
 | 1484 | static struct v4l2_input knc1_inputs[KNC1_INPUTS] = { | 
 | 1485 | 	{0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0}, | 
 | 1486 | 	{1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0}, | 
 | 1487 | }; | 
 | 1488 |  | 
 | 1489 | static struct saa7146_extension_ioctls ioctls[] = { | 
 | 1490 | 	{VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE}, | 
 | 1491 | 	{VIDIOC_G_INPUT, SAA7146_EXCLUSIVE}, | 
 | 1492 | 	{VIDIOC_S_INPUT, SAA7146_EXCLUSIVE}, | 
 | 1493 | 	{0, 0} | 
 | 1494 | }; | 
 | 1495 |  | 
| Hans Verkuil | 069b747 | 2008-12-30 07:04:34 -0300 | [diff] [blame] | 1496 | static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1497 | { | 
 | 1498 | 	struct saa7146_dev *dev = fh->dev; | 
 | 1499 | 	struct budget_av *budget_av = (struct budget_av *) dev->ext_priv; | 
 | 1500 |  | 
 | 1501 | 	switch (cmd) { | 
 | 1502 | 	case VIDIOC_ENUMINPUT:{ | 
 | 1503 | 		struct v4l2_input *i = arg; | 
 | 1504 |  | 
 | 1505 | 		dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index); | 
 | 1506 | 		if (i->index < 0 || i->index >= KNC1_INPUTS) { | 
 | 1507 | 			return -EINVAL; | 
 | 1508 | 		} | 
 | 1509 | 		memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); | 
 | 1510 | 		return 0; | 
 | 1511 | 	} | 
 | 1512 | 	case VIDIOC_G_INPUT:{ | 
 | 1513 | 		int *input = (int *) arg; | 
 | 1514 |  | 
 | 1515 | 		*input = budget_av->cur_input; | 
 | 1516 |  | 
 | 1517 | 		dprintk(1, "VIDIOC_G_INPUT %d.\n", *input); | 
 | 1518 | 		return 0; | 
 | 1519 | 	} | 
 | 1520 | 	case VIDIOC_S_INPUT:{ | 
 | 1521 | 		int input = *(int *) arg; | 
 | 1522 | 		dprintk(1, "VIDIOC_S_INPUT %d.\n", input); | 
 | 1523 | 		return saa7113_setinput(budget_av, input); | 
 | 1524 | 	} | 
 | 1525 | 	default: | 
 | 1526 | 		return -ENOIOCTLCMD; | 
 | 1527 | 	} | 
 | 1528 | 	return 0; | 
 | 1529 | } | 
 | 1530 |  | 
 | 1531 | static struct saa7146_standard standard[] = { | 
 | 1532 | 	{.name = "PAL",.id = V4L2_STD_PAL, | 
 | 1533 | 	 .v_offset = 0x17,.v_field = 288, | 
 | 1534 | 	 .h_offset = 0x14,.h_pixels = 680, | 
 | 1535 | 	 .v_max_out = 576,.h_max_out = 768 }, | 
 | 1536 |  | 
 | 1537 | 	{.name = "NTSC",.id = V4L2_STD_NTSC, | 
 | 1538 | 	 .v_offset = 0x16,.v_field = 240, | 
 | 1539 | 	 .h_offset = 0x06,.h_pixels = 708, | 
 | 1540 | 	 .v_max_out = 480,.h_max_out = 640, }, | 
 | 1541 | }; | 
 | 1542 |  | 
 | 1543 | static struct saa7146_ext_vv vv_data = { | 
 | 1544 | 	.inputs = 2, | 
 | 1545 | 	.capabilities = 0,	// perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113 | 
 | 1546 | 	.flags = 0, | 
 | 1547 | 	.stds = &standard[0], | 
| Andi Drebes | af520a3 | 2007-07-30 11:48:10 -0300 | [diff] [blame] | 1548 | 	.num_stds = ARRAY_SIZE(standard), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1549 | 	.ioctls = &ioctls[0], | 
 | 1550 | 	.ioctl = av_ioctl, | 
 | 1551 | }; | 
 | 1552 |  | 
 | 1553 | static struct saa7146_extension budget_extension; | 
 | 1554 |  | 
 | 1555 | MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1556 | MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2); | 
| Arvo Jarve | 5dc1611 | 2007-10-25 13:25:23 -0300 | [diff] [blame] | 1557 | MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1558 | MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); | 
 | 1559 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 1560 | MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR); | 
| Thilo Berger | 36f4f33 | 2006-02-27 00:09:08 -0300 | [diff] [blame] | 1561 | MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR); | 
| Lothar Englisch | 60110ce | 2006-06-06 16:13:46 -0300 | [diff] [blame] | 1562 | MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S); | 
| Oliver Endriss | f72ce64 | 2007-05-13 23:25:57 -0300 | [diff] [blame] | 1563 | MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S); | 
| Thomas Hamm | c01d1e4 | 2006-11-17 07:12:58 -0300 | [diff] [blame] | 1564 | MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP); | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1565 | MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3); | 
| Kim Sandberg | 251130b | 2008-01-30 00:42:01 -0300 | [diff] [blame] | 1566 | MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T); | 
| Johannes Stezenbach | 2d4f2c2 | 2005-05-16 21:54:23 -0700 | [diff] [blame] | 1567 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); | 
| Oliver Endriss | 03aa73c | 2008-01-29 23:56:51 -0300 | [diff] [blame] | 1568 | MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP); | 
| Johannes Stezenbach | 2d4f2c2 | 2005-05-16 21:54:23 -0700 | [diff] [blame] | 1569 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1570 | MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3); | 
 | 1571 | MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3); | 
| Johannes Stezenbach | 2d4f2c2 | 2005-05-16 21:54:23 -0700 | [diff] [blame] | 1572 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1573 | MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 1574 | MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1575 | MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1576 | MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1577 | MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); | 
 | 1578 |  | 
 | 1579 | static struct pci_device_id pci_tbl[] = { | 
 | 1580 | 	MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), | 
| Johannes Stezenbach | 2d4f2c2 | 2005-05-16 21:54:23 -0700 | [diff] [blame] | 1581 | 	MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), | 
| Andrew de Quincey | effa791 | 2006-01-09 15:25:09 -0200 | [diff] [blame] | 1582 | 	MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010), | 
| Johannes Stezenbach | 2d4f2c2 | 2005-05-16 21:54:23 -0700 | [diff] [blame] | 1583 | 	MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), | 
| Christoph Pfister | 4e318be | 2006-08-12 09:13:35 -0300 | [diff] [blame] | 1584 | 	MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011), | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 1585 | 	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014), | 
| Oliver Endriss | 03aa73c | 2008-01-29 23:56:51 -0300 | [diff] [blame] | 1586 | 	MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015), | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 1587 | 	MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016), | 
| Manu Abraham | 41e1151 | 2007-09-22 21:28:11 -0300 | [diff] [blame] | 1588 | 	MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018), | 
 | 1589 | 	MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019), | 
| Arvo Jarve | 5dc1611 | 2007-10-25 13:25:23 -0300 | [diff] [blame] | 1590 | 	MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d), | 
| Thilo Berger | 36f4f33 | 2006-02-27 00:09:08 -0300 | [diff] [blame] | 1591 | 	MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e), | 
| Lothar Englisch | 60110ce | 2006-06-06 16:13:46 -0300 | [diff] [blame] | 1592 | 	MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a), | 
| Oliver Endriss | f72ce64 | 2007-05-13 23:25:57 -0300 | [diff] [blame] | 1593 | 	MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b), | 
| Thomas Hamm | c01d1e4 | 2006-11-17 07:12:58 -0300 | [diff] [blame] | 1594 | 	MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a), | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1595 | 	MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c), | 
| Kim Sandberg | 251130b | 2008-01-30 00:42:01 -0300 | [diff] [blame] | 1596 | 	MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1597 | 	MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | 
| Johannes Stezenbach | 2d4f2c2 | 2005-05-16 21:54:23 -0700 | [diff] [blame] | 1598 | 	MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1599 | 	MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022), | 
 | 1600 | 	MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1601 | 	MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), | 
| Johannes Stezenbach | 2d4f2c2 | 2005-05-16 21:54:23 -0700 | [diff] [blame] | 1602 | 	MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1603 | 	MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154), | 
| Regis Prevot | f8bf134 | 2006-01-11 23:31:53 -0200 | [diff] [blame] | 1604 | 	MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1605 | 	MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156), | 
| Hartmut Birr | aa323ac | 2007-04-21 19:37:17 -0300 | [diff] [blame] | 1606 | 	MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176), | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1607 | 	MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157), | 
 | 1608 | 	{ | 
 | 1609 | 	 .vendor = 0, | 
 | 1610 | 	} | 
 | 1611 | }; | 
 | 1612 |  | 
 | 1613 | MODULE_DEVICE_TABLE(pci, pci_tbl); | 
 | 1614 |  | 
 | 1615 | static struct saa7146_extension budget_extension = { | 
| Julian Scheel | 27b05fd | 2005-07-12 13:58:39 -0700 | [diff] [blame] | 1616 | 	.name = "budget_av", | 
| Oliver Endriss | 00c4cc6 | 2006-11-01 13:09:51 -0300 | [diff] [blame] | 1617 | 	.flags = SAA7146_USE_I2C_IRQ, | 
| Oliver Endriss | 69459f3 | 2005-12-01 00:51:48 -0800 | [diff] [blame] | 1618 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1619 | 	.pci_tbl = pci_tbl, | 
 | 1620 |  | 
 | 1621 | 	.module = THIS_MODULE, | 
 | 1622 | 	.attach = budget_av_attach, | 
 | 1623 | 	.detach = budget_av_detach, | 
 | 1624 |  | 
 | 1625 | 	.irq_mask = MASK_10, | 
 | 1626 | 	.irq_func = budget_av_irq, | 
 | 1627 | }; | 
 | 1628 |  | 
 | 1629 | static int __init budget_av_init(void) | 
 | 1630 | { | 
 | 1631 | 	return saa7146_register_extension(&budget_extension); | 
 | 1632 | } | 
 | 1633 |  | 
 | 1634 | static void __exit budget_av_exit(void) | 
 | 1635 | { | 
 | 1636 | 	saa7146_unregister_extension(&budget_extension); | 
 | 1637 | } | 
 | 1638 |  | 
 | 1639 | module_init(budget_av_init); | 
 | 1640 | module_exit(budget_av_exit); | 
 | 1641 |  | 
 | 1642 | MODULE_LICENSE("GPL"); | 
 | 1643 | MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); | 
 | 1644 | MODULE_DESCRIPTION("driver for the SAA7146 based so-called " | 
 | 1645 | 		   "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)"); |