]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/media/dvb/ttpci/budget-av.c
V4L/DVB (8554): media/video/Kconfig: cosmetic changes and convert select into depends on
[mirror_ubuntu-hirsute-kernel.git] / drivers / media / dvb / ttpci / budget-av.c
CommitLineData
1da177e4
LT
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"
aa323ac8 38#include "tda1002x.h"
1da177e4 39#include "tda1004x.h"
1c72cfdc 40#include "tua6100.h"
f8bf134d 41#include "dvb-pll.h"
1da177e4
LT
42#include <media/saa7146_vv.h>
43#include <linux/module.h>
44#include <linux/errno.h>
45#include <linux/slab.h>
46#include <linux/interrupt.h>
47#include <linux/input.h>
48#include <linux/spinlock.h>
49
50#include "dvb_ca_en50221.h"
51
52#define DEBICICAM 0x02420000
53
5c1208ba
AQ
54#define SLOTSTATUS_NONE 1
55#define SLOTSTATUS_PRESENT 2
56#define SLOTSTATUS_RESET 4
57#define SLOTSTATUS_READY 8
58#define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
59
1da177e4
LT
60struct budget_av {
61 struct budget budget;
62 struct video_device *vd;
63 int cur_input;
64 int has_saa7113;
65 struct tasklet_struct ciintf_irq_tasklet;
66 int slot_status;
67 struct dvb_ca_en50221 ca;
5c1208ba 68 u8 reinitialise_demod:1;
1da177e4
LT
69};
70
5c1208ba
AQ
71static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
72
73
86f40cc3
AQ
74/* GPIO Connections:
75 * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
76 * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
77 * 2 - CI Card Enable (Active Low)
78 * 3 - CI Card Detect
b82a96a7 79 */
1da177e4
LT
80
81/****************************************************************************
82 * INITIALIZATION
83 ****************************************************************************/
84
85static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
86{
87 u8 mm1[] = { 0x00 };
88 u8 mm2[] = { 0x00 };
89 struct i2c_msg msgs[2];
90
91 msgs[0].flags = 0;
92 msgs[1].flags = I2C_M_RD;
93 msgs[0].addr = msgs[1].addr = id / 2;
94 mm1[0] = reg;
95 msgs[0].len = 1;
96 msgs[1].len = 1;
97 msgs[0].buf = mm1;
98 msgs[1].buf = mm2;
99
100 i2c_transfer(i2c, msgs, 2);
101
102 return mm2[0];
103}
104
105static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
106{
107 u8 mm1[] = { reg };
108 struct i2c_msg msgs[2] = {
109 {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
110 {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
111 };
112
113 if (i2c_transfer(i2c, msgs, 2) != 2)
114 return -EIO;
115
116 return 0;
117}
118
119static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
120{
121 u8 msg[2] = { reg, val };
122 struct i2c_msg msgs;
123
124 msgs.flags = 0;
125 msgs.addr = id / 2;
126 msgs.len = 2;
127 msgs.buf = msg;
128 return i2c_transfer(i2c, &msgs, 1);
129}
130
131static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
132{
133 struct budget_av *budget_av = (struct budget_av *) ca->data;
134 int result;
135
136 if (slot != 0)
137 return -EINVAL;
138
139 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
140 udelay(1);
141
2d0235df 142 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
5c1208ba
AQ
143 if (result == -ETIMEDOUT) {
144 ciintf_slot_shutdown(ca, slot);
145 printk(KERN_INFO "budget-av: cam ejected 1\n");
146 }
1da177e4
LT
147 return result;
148}
149
150static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
151{
152 struct budget_av *budget_av = (struct budget_av *) ca->data;
153 int result;
154
155 if (slot != 0)
156 return -EINVAL;
157
158 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
159 udelay(1);
160
2d0235df 161 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
5c1208ba
AQ
162 if (result == -ETIMEDOUT) {
163 ciintf_slot_shutdown(ca, slot);
164 printk(KERN_INFO "budget-av: cam ejected 2\n");
165 }
1da177e4
LT
166 return result;
167}
168
169static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
170{
171 struct budget_av *budget_av = (struct budget_av *) ca->data;
172 int result;
173
174 if (slot != 0)
175 return -EINVAL;
176
177 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
178 udelay(1);
179
180 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
8727073b 181 if (result == -ETIMEDOUT) {
5c1208ba
AQ
182 ciintf_slot_shutdown(ca, slot);
183 printk(KERN_INFO "budget-av: cam ejected 3\n");
184 return -ETIMEDOUT;
185 }
1da177e4
LT
186 return result;
187}
188
189static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
190{
191 struct budget_av *budget_av = (struct budget_av *) ca->data;
192 int result;
193
194 if (slot != 0)
195 return -EINVAL;
196
197 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
198 udelay(1);
199
200 result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
5c1208ba
AQ
201 if (result == -ETIMEDOUT) {
202 ciintf_slot_shutdown(ca, slot);
203 printk(KERN_INFO "budget-av: cam ejected 5\n");
204 }
1da177e4
LT
205 return result;
206}
207
208static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
209{
210 struct budget_av *budget_av = (struct budget_av *) ca->data;
211 struct saa7146_dev *saa = budget_av->budget.dev;
1da177e4
LT
212
213 if (slot != 0)
214 return -EINVAL;
215
216 dprintk(1, "ciintf_slot_reset\n");
5c1208ba 217 budget_av->slot_status = SLOTSTATUS_RESET;
1da177e4 218
b82a96a7 219 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
1da177e4 220
b82a96a7
JS
221 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
222 msleep(2);
223 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
224 msleep(20); /* 20 ms Vcc settling time */
225
226 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
5c1208ba
AQ
227 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
228 msleep(20);
b82a96a7 229
5c1208ba
AQ
230 /* reinitialise the frontend if necessary */
231 if (budget_av->reinitialise_demod)
232 dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
86f40cc3 233
1da177e4
LT
234 return 0;
235}
236
237static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
238{
239 struct budget_av *budget_av = (struct budget_av *) ca->data;
240 struct saa7146_dev *saa = budget_av->budget.dev;
241
242 if (slot != 0)
243 return -EINVAL;
244
245 dprintk(1, "ciintf_slot_shutdown\n");
246
247 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
5c1208ba
AQ
248 budget_av->slot_status = SLOTSTATUS_NONE;
249
1da177e4
LT
250 return 0;
251}
252
253static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
254{
255 struct budget_av *budget_av = (struct budget_av *) ca->data;
256 struct saa7146_dev *saa = budget_av->budget.dev;
257
258 if (slot != 0)
259 return -EINVAL;
260
261 dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
262
263 ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
5c1208ba 264
1da177e4
LT
265 return 0;
266}
267
268static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
269{
270 struct budget_av *budget_av = (struct budget_av *) ca->data;
271 struct saa7146_dev *saa = budget_av->budget.dev;
5c1208ba 272 int result;
1da177e4
LT
273
274 if (slot != 0)
275 return -EINVAL;
276
5c1208ba
AQ
277 /* test the card detect line - needs to be done carefully
278 * since it never goes high for some CAMs on this interface (e.g. topuptv) */
279 if (budget_av->slot_status == SLOTSTATUS_NONE) {
1da177e4
LT
280 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
281 udelay(1);
5c1208ba
AQ
282 if (saa7146_read(saa, PSR) & MASK_06) {
283 if (budget_av->slot_status == SLOTSTATUS_NONE) {
284 budget_av->slot_status = SLOTSTATUS_PRESENT;
285 printk(KERN_INFO "budget-av: cam inserted A\n");
286 }
2d0235df
AQ
287 }
288 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
5c1208ba 289 }
2d0235df 290
5c1208ba
AQ
291 /* We also try and read from IO memory to work round the above detection bug. If
292 * there is no CAM, we will get a timeout. Only done if there is no cam
293 * present, since this test actually breaks some cams :(
294 *
295 * if the CI interface is not open, we also do the above test since we
296 * don't care if the cam has problems - we'll be resetting it on open() anyway */
297 if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
298 saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
299 result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
300 if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
301 budget_av->slot_status = SLOTSTATUS_PRESENT;
302 printk(KERN_INFO "budget-av: cam inserted B\n");
303 } else if (result < 0) {
304 if (budget_av->slot_status != SLOTSTATUS_NONE) {
305 ciintf_slot_shutdown(ca, slot);
306 printk(KERN_INFO "budget-av: cam ejected 5\n");
307 return 0;
2d0235df
AQ
308 }
309 }
5c1208ba 310 }
2d0235df 311
5c1208ba
AQ
312 /* read from attribute memory in reset/ready state to know when the CAM is ready */
313 if (budget_av->slot_status == SLOTSTATUS_RESET) {
314 result = ciintf_read_attribute_mem(ca, slot, 0);
315 if (result == 0x1d) {
316 budget_av->slot_status = SLOTSTATUS_READY;
b82a96a7 317 }
1da177e4
LT
318 }
319
5c1208ba
AQ
320 /* work out correct return code */
321 if (budget_av->slot_status != SLOTSTATUS_NONE) {
322 if (budget_av->slot_status & SLOTSTATUS_READY) {
323 return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
324 }
325 return DVB_CA_EN50221_POLL_CAM_PRESENT;
326 }
1da177e4
LT
327 return 0;
328}
329
330static int ciintf_init(struct budget_av *budget_av)
331{
332 struct saa7146_dev *saa = budget_av->budget.dev;
333 int result;
334
335 memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
336
b82a96a7
JS
337 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
338 saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
1da177e4
LT
339 saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO);
340 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO);
341
1da177e4 342 /* Enable DEBI pins */
2a893dea 343 saa7146_write(saa, MC1, MASK_27 | MASK_11);
1da177e4
LT
344
345 /* register CI interface */
346 budget_av->ca.owner = THIS_MODULE;
347 budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
348 budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
349 budget_av->ca.read_cam_control = ciintf_read_cam_control;
350 budget_av->ca.write_cam_control = ciintf_write_cam_control;
351 budget_av->ca.slot_reset = ciintf_slot_reset;
352 budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
353 budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
354 budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
355 budget_av->ca.data = budget_av;
5c1208ba
AQ
356 budget_av->budget.ci_present = 1;
357 budget_av->slot_status = SLOTSTATUS_NONE;
b82a96a7 358
fdc53a6d 359 if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
1da177e4 360 &budget_av->ca, 0, 1)) != 0) {
b82a96a7 361 printk(KERN_ERR "budget-av: ci initialisation failed.\n");
1da177e4
LT
362 goto error;
363 }
b82a96a7
JS
364
365 printk(KERN_INFO "budget-av: ci interface initialised.\n");
1da177e4
LT
366 return 0;
367
368error:
2a893dea 369 saa7146_write(saa, MC1, MASK_27);
1da177e4
LT
370 return result;
371}
372
373static void ciintf_deinit(struct budget_av *budget_av)
374{
375 struct saa7146_dev *saa = budget_av->budget.dev;
376
377 saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
378 saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
379 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
380 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
381
382 /* release the CA device */
383 dvb_ca_en50221_release(&budget_av->ca);
384
385 /* disable DEBI pins */
2a893dea 386 saa7146_write(saa, MC1, MASK_27);
1da177e4
LT
387}
388
389
390static const u8 saa7113_tab[] = {
391 0x01, 0x08,
392 0x02, 0xc0,
393 0x03, 0x33,
394 0x04, 0x00,
395 0x05, 0x00,
396 0x06, 0xeb,
397 0x07, 0xe0,
398 0x08, 0x28,
399 0x09, 0x00,
400 0x0a, 0x80,
401 0x0b, 0x47,
402 0x0c, 0x40,
403 0x0d, 0x00,
404 0x0e, 0x01,
405 0x0f, 0x44,
406
407 0x10, 0x08,
408 0x11, 0x0c,
409 0x12, 0x7b,
410 0x13, 0x00,
411 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
412
413 0x57, 0xff,
414 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
415 0x5b, 0x83, 0x5e, 0x00,
416 0xff
417};
418
419static int saa7113_init(struct budget_av *budget_av)
420{
421 struct budget *budget = &budget_av->budget;
b82a96a7 422 struct saa7146_dev *saa = budget->dev;
1da177e4
LT
423 const u8 *data = saa7113_tab;
424
b82a96a7
JS
425 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI);
426 msleep(200);
427
1da177e4
LT
428 if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
429 dprintk(1, "saa7113 not found on KNC card\n");
430 return -ENODEV;
431 }
432
433 dprintk(1, "saa7113 detected and initializing\n");
434
435 while (*data != 0xff) {
436 i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
437 data += 2;
438 }
439
440 dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
441
442 return 0;
443}
444
445static int saa7113_setinput(struct budget_av *budget_av, int input)
446{
447 struct budget *budget = &budget_av->budget;
448
449 if (1 != budget_av->has_saa7113)
450 return -ENODEV;
451
452 if (input == 1) {
453 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
454 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
455 } else if (input == 0) {
456 i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
457 i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
458 } else
459 return -EINVAL;
460
461 budget_av->cur_input = input;
462 return 0;
463}
464
465
466static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
467{
468 u8 aclk = 0;
469 u8 bclk = 0;
470 u8 m1;
471
472 aclk = 0xb5;
473 if (srate < 2000000)
474 bclk = 0x86;
475 else if (srate < 5000000)
476 bclk = 0x89;
477 else if (srate < 15000000)
478 bclk = 0x8f;
479 else if (srate < 45000000)
480 bclk = 0x95;
481
482 m1 = 0x14;
483 if (srate < 4000000)
484 m1 = 0x10;
485
486 stv0299_writereg(fe, 0x13, aclk);
487 stv0299_writereg(fe, 0x14, bclk);
488 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
489 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
490 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
491 stv0299_writereg(fe, 0x0f, 0x80 | m1);
492
493 return 0;
494}
495
e87d41c4
AQ
496static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe,
497 struct dvb_frontend_parameters *params)
1da177e4 498{
1da177e4
LT
499 u32 div;
500 u8 buf[4];
e87d41c4 501 struct budget *budget = (struct budget *) fe->dvb->priv;
1da177e4
LT
502 struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
503
504 if ((params->frequency < 950000) || (params->frequency > 2150000))
505 return -EINVAL;
506
507 div = (params->frequency + (125 - 1)) / 125; // round correctly
508 buf[0] = (div >> 8) & 0x7f;
509 buf[1] = div & 0xff;
510 buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
511 buf[3] = 0x20;
512
513 if (params->u.qpsk.symbol_rate < 4000000)
514 buf[3] |= 1;
515
516 if (params->frequency < 1250000)
517 buf[3] |= 0;
518 else if (params->frequency < 1550000)
519 buf[3] |= 0x40;
520 else if (params->frequency < 2050000)
521 buf[3] |= 0x80;
522 else if (params->frequency < 2150000)
523 buf[3] |= 0xC0;
524
dea74869
PB
525 if (fe->ops.i2c_gate_ctrl)
526 fe->ops.i2c_gate_ctrl(fe, 1);
e87d41c4 527 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
1da177e4
LT
528 return -EIO;
529 return 0;
530}
531
532static u8 typhoon_cinergy1200s_inittab[] = {
533 0x01, 0x15,
534 0x02, 0x30,
535 0x03, 0x00,
536 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
537 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
538 0x06, 0x40, /* DAC not used, set to high impendance mode */
539 0x07, 0x00, /* DAC LSB */
540 0x08, 0x40, /* DiSEqC off */
541 0x09, 0x00, /* FIFO */
542 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
543 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
544 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
545 0x10, 0x3f, // AGC2 0x3d
546 0x11, 0x84,
ff29d06a 547 0x12, 0xb9,
1da177e4
LT
548 0x15, 0xc9, // lock detector threshold
549 0x16, 0x00,
550 0x17, 0x00,
551 0x18, 0x00,
552 0x19, 0x00,
553 0x1a, 0x00,
554 0x1f, 0x50,
555 0x20, 0x00,
556 0x21, 0x00,
557 0x22, 0x00,
558 0x23, 0x00,
559 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
560 0x29, 0x1e, // 1/2 threshold
561 0x2a, 0x14, // 2/3 threshold
562 0x2b, 0x0f, // 3/4 threshold
563 0x2c, 0x09, // 5/6 threshold
564 0x2d, 0x05, // 7/8 threshold
565 0x2e, 0x01,
566 0x31, 0x1f, // test all FECs
567 0x32, 0x19, // viterbi and synchro search
568 0x33, 0xfc, // rs control
569 0x34, 0x93, // error control
570 0x0f, 0x92,
571 0xff, 0xff
572};
573
574static struct stv0299_config typhoon_config = {
575 .demod_address = 0x68,
576 .inittab = typhoon_cinergy1200s_inittab,
577 .mclk = 88000000UL,
578 .invert = 0,
1da177e4 579 .skip_reinit = 0,
da2c7f66 580 .lock_output = STV0299_LOCKOUTPUT_1,
1da177e4
LT
581 .volt13_op0_op1 = STV0299_VOLT13_OP0,
582 .min_delay_ms = 100,
583 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
1da177e4
LT
584};
585
586
587static struct stv0299_config cinergy_1200s_config = {
588 .demod_address = 0x68,
589 .inittab = typhoon_cinergy1200s_inittab,
590 .mclk = 88000000UL,
591 .invert = 0,
1da177e4 592 .skip_reinit = 0,
da2c7f66 593 .lock_output = STV0299_LOCKOUTPUT_0,
1da177e4
LT
594 .volt13_op0_op1 = STV0299_VOLT13_OP0,
595 .min_delay_ms = 100,
596 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
1da177e4
LT
597};
598
effa791c
AQ
599static struct stv0299_config cinergy_1200s_1894_0010_config = {
600 .demod_address = 0x68,
601 .inittab = typhoon_cinergy1200s_inittab,
602 .mclk = 88000000UL,
603 .invert = 1,
604 .skip_reinit = 0,
da2c7f66 605 .lock_output = STV0299_LOCKOUTPUT_1,
effa791c
AQ
606 .volt13_op0_op1 = STV0299_VOLT13_OP0,
607 .min_delay_ms = 100,
608 .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
effa791c 609};
1da177e4 610
e87d41c4 611static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1da177e4
LT
612{
613 struct budget *budget = (struct budget *) fe->dvb->priv;
aa323ac8 614 u8 buf[6];
1da177e4 615 struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
aa323ac8 616 int i;
1da177e4 617
aa323ac8 618#define CU1216_IF 36125000
1da177e4
LT
619#define TUNER_MUL 62500
620
aa323ac8 621 u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
1da177e4
LT
622
623 buf[0] = (div >> 8) & 0x7f;
624 buf[1] = div & 0xff;
aa323ac8 625 buf[2] = 0xce;
eef5764d
JS
626 buf[3] = (params->frequency < 150000000 ? 0x01 :
627 params->frequency < 445000000 ? 0x02 : 0x04);
aa323ac8
HB
628 buf[4] = 0xde;
629 buf[5] = 0x20;
1da177e4 630
dea74869
PB
631 if (fe->ops.i2c_gate_ctrl)
632 fe->ops.i2c_gate_ctrl(fe, 1);
1da177e4
LT
633 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
634 return -EIO;
aa323ac8
HB
635
636 /* wait for the pll lock */
637 msg.flags = I2C_M_RD;
638 msg.len = 1;
639 for (i = 0; i < 20; i++) {
640 if (fe->ops.i2c_gate_ctrl)
641 fe->ops.i2c_gate_ctrl(fe, 1);
642 if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
643 break;
644 msleep(10);
645 }
646
647 /* switch the charge pump to the lower current */
648 msg.flags = 0;
649 msg.len = 2;
650 msg.buf = &buf[2];
651 buf[2] &= ~0x40;
652 if (fe->ops.i2c_gate_ctrl)
653 fe->ops.i2c_gate_ctrl(fe, 1);
654 if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
655 return -EIO;
656
1da177e4
LT
657 return 0;
658}
659
aa323ac8 660static struct tda1002x_config philips_cu1216_config = {
1da177e4 661 .demod_address = 0x0c,
dc120b07 662 .invert = 1,
1da177e4
LT
663};
664
aa323ac8 665static struct tda1002x_config philips_cu1216_config_altaddress = {
61cebe9d 666 .demod_address = 0x0d,
dc120b07 667 .invert = 0,
61cebe9d
AQ
668};
669
4388c3b4
AP
670static struct tda10023_config philips_cu1216_tda10023_config = {
671 .demod_address = 0x0c,
672 .invert = 1,
673};
674
e87d41c4 675static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
1da177e4
LT
676{
677 struct budget *budget = (struct budget *) fe->dvb->priv;
678 static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
679 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
680
681 // setup PLL configuration
dea74869
PB
682 if (fe->ops.i2c_gate_ctrl)
683 fe->ops.i2c_gate_ctrl(fe, 1);
1da177e4
LT
684 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
685 return -EIO;
686 msleep(1);
687
688 return 0;
689}
690
e87d41c4 691static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
1da177e4
LT
692{
693 struct budget *budget = (struct budget *) fe->dvb->priv;
694 u8 tuner_buf[4];
695 struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
696 sizeof(tuner_buf) };
697 int tuner_frequency = 0;
698 u8 band, cp, filter;
699
700 // determine charge pump
701 tuner_frequency = params->frequency + 36166000;
702 if (tuner_frequency < 87000000)
703 return -EINVAL;
704 else if (tuner_frequency < 130000000)
705 cp = 3;
706 else if (tuner_frequency < 160000000)
707 cp = 5;
708 else if (tuner_frequency < 200000000)
709 cp = 6;
710 else if (tuner_frequency < 290000000)
711 cp = 3;
712 else if (tuner_frequency < 420000000)
713 cp = 5;
714 else if (tuner_frequency < 480000000)
715 cp = 6;
716 else if (tuner_frequency < 620000000)
717 cp = 3;
718 else if (tuner_frequency < 830000000)
719 cp = 5;
720 else if (tuner_frequency < 895000000)
721 cp = 7;
722 else
723 return -EINVAL;
724
725 // determine band
726 if (params->frequency < 49000000)
727 return -EINVAL;
728 else if (params->frequency < 161000000)
729 band = 1;
730 else if (params->frequency < 444000000)
731 band = 2;
732 else if (params->frequency < 861000000)
733 band = 4;
734 else
735 return -EINVAL;
736
737 // setup PLL filter
738 switch (params->u.ofdm.bandwidth) {
739 case BANDWIDTH_6_MHZ:
740 filter = 0;
741 break;
742
743 case BANDWIDTH_7_MHZ:
744 filter = 0;
745 break;
746
747 case BANDWIDTH_8_MHZ:
748 filter = 1;
749 break;
750
751 default:
752 return -EINVAL;
753 }
754
755 // calculate divisor
756 // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
757 tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
758
759 // setup tuner buffer
760 tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
761 tuner_buf[1] = tuner_frequency & 0xff;
762 tuner_buf[2] = 0xca;
763 tuner_buf[3] = (cp << 5) | (filter << 3) | band;
764
dea74869
PB
765 if (fe->ops.i2c_gate_ctrl)
766 fe->ops.i2c_gate_ctrl(fe, 1);
1da177e4
LT
767 if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
768 return -EIO;
769
770 msleep(1);
771 return 0;
772}
773
774static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
775 const struct firmware **fw, char *name)
776{
777 struct budget *budget = (struct budget *) fe->dvb->priv;
778
779 return request_firmware(fw, name, &budget->dev->pci->dev);
780}
781
782static struct tda1004x_config philips_tu1216_config = {
783
784 .demod_address = 0x8,
785 .invert = 1,
786 .invert_oclk = 1,
ecb60deb
HH
787 .xtal_freq = TDA10046_XTAL_4M,
788 .agc_config = TDA10046_AGC_DEFAULT,
789 .if_freq = TDA10046_FREQ_3617,
1da177e4
LT
790 .request_firmware = philips_tu1216_request_firmware,
791};
792
f8bf134d
RP
793static u8 philips_sd1878_inittab[] = {
794 0x01, 0x15,
795 0x02, 0x30,
796 0x03, 0x00,
797 0x04, 0x7d,
798 0x05, 0x35,
799 0x06, 0x40,
800 0x07, 0x00,
801 0x08, 0x43,
802 0x09, 0x02,
803 0x0C, 0x51,
804 0x0D, 0x82,
805 0x0E, 0x23,
806 0x10, 0x3f,
807 0x11, 0x84,
808 0x12, 0xb9,
809 0x15, 0xc9,
810 0x16, 0x19,
811 0x17, 0x8c,
812 0x18, 0x59,
813 0x19, 0xf8,
814 0x1a, 0xfe,
815 0x1c, 0x7f,
816 0x1d, 0x00,
817 0x1e, 0x00,
818 0x1f, 0x50,
819 0x20, 0x00,
820 0x21, 0x00,
821 0x22, 0x00,
822 0x23, 0x00,
823 0x28, 0x00,
824 0x29, 0x28,
825 0x2a, 0x14,
826 0x2b, 0x0f,
827 0x2c, 0x09,
828 0x2d, 0x09,
829 0x31, 0x1f,
830 0x32, 0x19,
831 0x33, 0xfc,
832 0x34, 0x93,
833 0xff, 0xff
834};
835
f8bf134d
RP
836static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
837 u32 srate, u32 ratio)
838{
839 u8 aclk = 0;
840 u8 bclk = 0;
841 u8 m1;
842
843 aclk = 0xb5;
844 if (srate < 2000000)
845 bclk = 0x86;
846 else if (srate < 5000000)
847 bclk = 0x89;
848 else if (srate < 15000000)
849 bclk = 0x8f;
850 else if (srate < 45000000)
851 bclk = 0x95;
852
853 m1 = 0x14;
854 if (srate < 4000000)
855 m1 = 0x10;
856
857 stv0299_writereg(fe, 0x0e, 0x23);
858 stv0299_writereg(fe, 0x0f, 0x94);
859 stv0299_writereg(fe, 0x10, 0x39);
860 stv0299_writereg(fe, 0x13, aclk);
861 stv0299_writereg(fe, 0x14, bclk);
862 stv0299_writereg(fe, 0x15, 0xc9);
863 stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
864 stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
865 stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
866 stv0299_writereg(fe, 0x0f, 0x80 | m1);
867
868 return 0;
869}
870
871static struct stv0299_config philips_sd1878_config = {
872 .demod_address = 0x68,
5c1208ba 873 .inittab = philips_sd1878_inittab,
f8bf134d
RP
874 .mclk = 88000000UL,
875 .invert = 0,
876 .skip_reinit = 0,
da2c7f66 877 .lock_output = STV0299_LOCKOUTPUT_1,
f8bf134d
RP
878 .volt13_op0_op1 = STV0299_VOLT13_OP0,
879 .min_delay_ms = 100,
880 .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
f8bf134d 881};
1da177e4
LT
882
883static u8 read_pwm(struct budget_av *budget_av)
884{
885 u8 b = 0xff;
886 u8 pwm;
887 struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
888 {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
889 };
890
891 if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
892 || (pwm == 0xff))
893 pwm = 0x48;
894
895 return pwm;
896}
897
aa323ac8
HB
898#define SUBID_DVBS_KNC1 0x0010
899#define SUBID_DVBS_KNC1_PLUS 0x0011
900#define SUBID_DVBS_TYPHOON 0x4f56
901#define SUBID_DVBS_CINERGY1200 0x1154
902#define SUBID_DVBS_CYNERGY1200N 0x1155
903#define SUBID_DVBS_TV_STAR 0x0014
03aa73c5 904#define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
aa323ac8
HB
905#define SUBID_DVBS_TV_STAR_CI 0x0016
906#define SUBID_DVBS_EASYWATCH_1 0x001a
f72ce644 907#define SUBID_DVBS_EASYWATCH_2 0x001b
aa323ac8
HB
908#define SUBID_DVBS_EASYWATCH 0x001e
909
910#define SUBID_DVBC_EASYWATCH 0x002a
911#define SUBID_DVBC_EASYWATCH_MK3 0x002c
912#define SUBID_DVBC_KNC1 0x0020
913#define SUBID_DVBC_KNC1_PLUS 0x0021
914#define SUBID_DVBC_KNC1_MK3 0x0022
915#define SUBID_DVBC_KNC1_PLUS_MK3 0x0023
916#define SUBID_DVBC_CINERGY1200 0x1156
917#define SUBID_DVBC_CINERGY1200_MK3 0x1176
918
251130bf 919#define SUBID_DVBT_EASYWATCH 0x003a
aa323ac8
HB
920#define SUBID_DVBT_KNC1_PLUS 0x0031
921#define SUBID_DVBT_KNC1 0x0030
922#define SUBID_DVBT_CINERGY1200 0x1157
1da177e4
LT
923
924static void frontend_init(struct budget_av *budget_av)
925{
b82a96a7
JS
926 struct saa7146_dev * saa = budget_av->budget.dev;
927 struct dvb_frontend * fe = NULL;
928
473f5427
AQ
929 /* Enable / PowerON Frontend */
930 saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO);
931
740cf9e1
HB
932 /* Wait for PowerON */
933 msleep(100);
934
473f5427 935 /* additional setup necessary for the PLUS cards */
b82a96a7
JS
936 switch (saa->pci->subsystem_device) {
937 case SUBID_DVBS_KNC1_PLUS:
938 case SUBID_DVBC_KNC1_PLUS:
939 case SUBID_DVBT_KNC1_PLUS:
c01d1e48 940 case SUBID_DVBC_EASYWATCH:
aa323ac8 941 case SUBID_DVBC_KNC1_PLUS_MK3:
b82a96a7 942 saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI);
1da177e4 943 break;
b82a96a7
JS
944 }
945
946 switch (saa->pci->subsystem_device) {
947
948 case SUBID_DVBS_KNC1:
c4e3bcb6
CP
949 /*
950 * maybe that setting is needed for other dvb-s cards as well,
951 * but so far it has been only confirmed for this type
952 */
953 budget_av->reinitialise_demod = 1;
954 /* fall through */
4e318bef 955 case SUBID_DVBS_KNC1_PLUS:
60110ce2 956 case SUBID_DVBS_EASYWATCH_1:
effa791c 957 if (saa->pci->subsystem_vendor == 0x1894) {
2bfe031d 958 fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
effa791c 959 &budget_av->budget.i2c_adap);
e87d41c4 960 if (fe) {
1c72cfdc 961 dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
e87d41c4 962 }
effa791c 963 } else {
2bfe031d 964 fe = dvb_attach(stv0299_attach, &typhoon_config,
effa791c 965 &budget_av->budget.i2c_adap);
e87d41c4 966 if (fe) {
dea74869 967 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
e87d41c4 968 }
effa791c
AQ
969 }
970 break;
971
f8bf134d 972 case SUBID_DVBS_TV_STAR:
03aa73c5 973 case SUBID_DVBS_TV_STAR_PLUS_X4:
f8bf134d
RP
974 case SUBID_DVBS_TV_STAR_CI:
975 case SUBID_DVBS_CYNERGY1200N:
36f4f334 976 case SUBID_DVBS_EASYWATCH:
f72ce644 977 case SUBID_DVBS_EASYWATCH_2:
2bfe031d 978 fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
f8bf134d 979 &budget_av->budget.i2c_adap);
e87d41c4 980 if (fe) {
9b98fd28
MK
981 dvb_attach(dvb_pll_attach, fe, 0x60,
982 &budget_av->budget.i2c_adap,
47a9991e 983 DVB_PLL_PHILIPS_SD1878_TDA8261);
e87d41c4 984 }
f8bf134d
RP
985 break;
986
b82a96a7 987 case SUBID_DVBS_TYPHOON:
2bfe031d 988 fe = dvb_attach(stv0299_attach, &typhoon_config,
b82a96a7 989 &budget_av->budget.i2c_adap);
e87d41c4 990 if (fe) {
dea74869 991 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
e87d41c4 992 }
1da177e4
LT
993 break;
994
b82a96a7 995 case SUBID_DVBS_CINERGY1200:
2bfe031d 996 fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
b82a96a7 997 &budget_av->budget.i2c_adap);
e87d41c4 998 if (fe) {
dea74869 999 fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
e87d41c4 1000 }
1da177e4
LT
1001 break;
1002
b82a96a7
JS
1003 case SUBID_DVBC_KNC1:
1004 case SUBID_DVBC_KNC1_PLUS:
5c1208ba 1005 case SUBID_DVBC_CINERGY1200:
c01d1e48 1006 case SUBID_DVBC_EASYWATCH:
5c1208ba 1007 budget_av->reinitialise_demod = 1;
aa323ac8 1008 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
2bfe031d 1009 fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
b82a96a7
JS
1010 &budget_av->budget.i2c_adap,
1011 read_pwm(budget_av));
61cebe9d
AQ
1012 if (fe == NULL)
1013 fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
1014 &budget_av->budget.i2c_adap,
1015 read_pwm(budget_av));
e87d41c4 1016 if (fe) {
dea74869 1017 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
e87d41c4 1018 }
1da177e4
LT
1019 break;
1020
aa323ac8
HB
1021 case SUBID_DVBC_EASYWATCH_MK3:
1022 case SUBID_DVBC_CINERGY1200_MK3:
1023 case SUBID_DVBC_KNC1_MK3:
1024 case SUBID_DVBC_KNC1_PLUS_MK3:
1025 budget_av->reinitialise_demod = 1;
1026 budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
4388c3b4
AP
1027 fe = dvb_attach(tda10023_attach,
1028 &philips_cu1216_tda10023_config,
1029 &budget_av->budget.i2c_adap,
1030 read_pwm(budget_av));
aa323ac8
HB
1031 if (fe) {
1032 fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1033 }
1034 break;
1035
251130bf 1036 case SUBID_DVBT_EASYWATCH:
b82a96a7
JS
1037 case SUBID_DVBT_KNC1:
1038 case SUBID_DVBT_KNC1_PLUS:
b82a96a7 1039 case SUBID_DVBT_CINERGY1200:
5c1208ba 1040 budget_av->reinitialise_demod = 1;
2bfe031d 1041 fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
b82a96a7 1042 &budget_av->budget.i2c_adap);
6b3ccab7 1043 if (fe) {
dea74869
PB
1044 fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1045 fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
6b3ccab7 1046 }
1da177e4
LT
1047 break;
1048 }
1049
b82a96a7
JS
1050 if (fe == NULL) {
1051 printk(KERN_ERR "budget-av: A frontend driver was not found "
1052 "for device %04x/%04x subsystem %04x/%04x\n",
1053 saa->pci->vendor,
1054 saa->pci->device,
1055 saa->pci->subsystem_vendor,
1056 saa->pci->subsystem_device);
1057 return;
1058 }
1059
1060 budget_av->budget.dvb_frontend = fe;
1061
1062 if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1063 budget_av->budget.dvb_frontend)) {
1064 printk(KERN_ERR "budget-av: Frontend registration failed!\n");
f52a838b 1065 dvb_frontend_detach(budget_av->budget.dvb_frontend);
b82a96a7 1066 budget_av->budget.dvb_frontend = NULL;
1da177e4
LT
1067 }
1068}
1069
1070
1071static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1072{
1073 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1074
1075 dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1076
1077 if (*isr & MASK_10)
1078 ttpci_budget_irq10_handler(dev, isr);
1079}
1080
1081static int budget_av_detach(struct saa7146_dev *dev)
1082{
1083 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1084 int err;
1085
1086 dprintk(2, "dev: %p\n", dev);
1087
1088 if (1 == budget_av->has_saa7113) {
1089 saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
1090
1091 msleep(200);
1092
1093 saa7146_unregister_device(&budget_av->vd, dev);
716a4e33
MS
1094
1095 saa7146_vv_release(dev);
1da177e4
LT
1096 }
1097
1098 if (budget_av->budget.ci_present)
1099 ciintf_deinit(budget_av);
1100
2bfe031d 1101 if (budget_av->budget.dvb_frontend != NULL) {
1da177e4 1102 dvb_unregister_frontend(budget_av->budget.dvb_frontend);
f52a838b 1103 dvb_frontend_detach(budget_av->budget.dvb_frontend);
2bfe031d 1104 }
1da177e4
LT
1105 err = ttpci_budget_deinit(&budget_av->budget);
1106
1107 kfree(budget_av);
1108
1109 return err;
1110}
1111
1112static struct saa7146_ext_vv vv_data;
1113
1114static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1115{
1116 struct budget_av *budget_av;
1117 u8 *mac;
1118 int err;
1119
1120 dprintk(2, "dev: %p\n", dev);
1121
7408187d 1122 if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
1da177e4
LT
1123 return -ENOMEM;
1124
b82a96a7 1125 budget_av->has_saa7113 = 0;
1da177e4
LT
1126 budget_av->budget.ci_present = 0;
1127
1128 dev->ext_priv = budget_av;
1129
1130 if ((err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE))) {
1131 kfree(budget_av);
1132 return err;
1133 }
1134
1135 /* knc1 initialization */
1136 saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1137 saa7146_write(dev, DD1_INIT, 0x07000600);
1138 saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26);
1139
b82a96a7 1140 if (saa7113_init(budget_av) == 0) {
1da177e4
LT
1141 budget_av->has_saa7113 = 1;
1142
1143 if (0 != saa7146_vv_init(dev, &vv_data)) {
1144 /* fixme: proper cleanup here */
1145 ERR(("cannot init vv subsystem.\n"));
1146 return err;
1147 }
1148
1149 if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1150 /* fixme: proper cleanup here */
1151 ERR(("cannot register capture v4l2 device.\n"));
716a4e33 1152 saa7146_vv_release(dev);
1da177e4
LT
1153 return err;
1154 }
1155
1156 /* beware: this modifies dev->vv ... */
1157 saa7146_set_hps_source_and_sync(dev, SAA7146_HPS_SOURCE_PORT_A,
1158 SAA7146_HPS_SYNC_PORT_A);
1159
1160 saa7113_setinput(budget_av, 0);
1da177e4
LT
1161 }
1162
1163 /* fixme: find some sane values here... */
1164 saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1165
fdc53a6d 1166 mac = budget_av->budget.dvb_adapter.proposed_mac;
1da177e4 1167 if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
b82a96a7 1168 printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n",
fdc53a6d 1169 budget_av->budget.dvb_adapter.num);
1da177e4
LT
1170 memset(mac, 0, 6);
1171 } else {
b82a96a7 1172 printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
fdc53a6d 1173 budget_av->budget.dvb_adapter.num,
1da177e4
LT
1174 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
1175 }
1176
fdc53a6d 1177 budget_av->budget.dvb_adapter.priv = budget_av;
1da177e4 1178 frontend_init(budget_av);
c5e768a1 1179 ciintf_init(budget_av);
32e4c3a5
OE
1180
1181 ttpci_budget_init_hooks(&budget_av->budget);
1182
1da177e4
LT
1183 return 0;
1184}
1185
1186#define KNC1_INPUTS 2
1187static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1188 {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1189 {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
1190};
1191
1192static struct saa7146_extension_ioctls ioctls[] = {
1193 {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
1194 {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
1195 {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
1196 {0, 0}
1197};
1198
1199static int av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
1200{
1201 struct saa7146_dev *dev = fh->dev;
1202 struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1203
1204 switch (cmd) {
1205 case VIDIOC_ENUMINPUT:{
1206 struct v4l2_input *i = arg;
1207
1208 dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
1209 if (i->index < 0 || i->index >= KNC1_INPUTS) {
1210 return -EINVAL;
1211 }
1212 memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1213 return 0;
1214 }
1215 case VIDIOC_G_INPUT:{
1216 int *input = (int *) arg;
1217
1218 *input = budget_av->cur_input;
1219
1220 dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
1221 return 0;
1222 }
1223 case VIDIOC_S_INPUT:{
1224 int input = *(int *) arg;
1225 dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
1226 return saa7113_setinput(budget_av, input);
1227 }
1228 default:
1229 return -ENOIOCTLCMD;
1230 }
1231 return 0;
1232}
1233
1234static struct saa7146_standard standard[] = {
1235 {.name = "PAL",.id = V4L2_STD_PAL,
1236 .v_offset = 0x17,.v_field = 288,
1237 .h_offset = 0x14,.h_pixels = 680,
1238 .v_max_out = 576,.h_max_out = 768 },
1239
1240 {.name = "NTSC",.id = V4L2_STD_NTSC,
1241 .v_offset = 0x16,.v_field = 240,
1242 .h_offset = 0x06,.h_pixels = 708,
1243 .v_max_out = 480,.h_max_out = 640, },
1244};
1245
1246static struct saa7146_ext_vv vv_data = {
1247 .inputs = 2,
1248 .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1249 .flags = 0,
1250 .stds = &standard[0],
af520a34 1251 .num_stds = ARRAY_SIZE(standard),
1da177e4
LT
1252 .ioctls = &ioctls[0],
1253 .ioctl = av_ioctl,
1254};
1255
1256static struct saa7146_extension budget_extension;
1257
1258MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1259MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1260MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
f8bf134d 1261MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
36f4f334 1262MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
60110ce2 1263MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
f72ce644 1264MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
c01d1e48 1265MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
aa323ac8 1266MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
251130bf 1267MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
2d4f2c2e 1268MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
03aa73c5 1269MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
2d4f2c2e 1270MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
aa323ac8
HB
1271MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1272MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
2d4f2c2e 1273MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1da177e4 1274MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
f8bf134d 1275MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1da177e4 1276MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
aa323ac8 1277MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
1da177e4
LT
1278MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1279
1280static struct pci_device_id pci_tbl[] = {
1281 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
2d4f2c2e 1282 MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
effa791c 1283 MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
2d4f2c2e 1284 MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
4e318bef 1285 MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
f8bf134d 1286 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
03aa73c5 1287 MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
f8bf134d 1288 MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
36f4f334 1289 MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
60110ce2 1290 MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
f72ce644 1291 MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
c01d1e48 1292 MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
aa323ac8 1293 MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
251130bf 1294 MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
1da177e4 1295 MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
2d4f2c2e 1296 MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
aa323ac8
HB
1297 MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1298 MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
1da177e4 1299 MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
2d4f2c2e 1300 MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1da177e4 1301 MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
f8bf134d 1302 MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1da177e4 1303 MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
aa323ac8 1304 MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
1da177e4
LT
1305 MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1306 {
1307 .vendor = 0,
1308 }
1309};
1310
1311MODULE_DEVICE_TABLE(pci, pci_tbl);
1312
1313static struct saa7146_extension budget_extension = {
27b05fd2 1314 .name = "budget_av",
00c4cc67 1315 .flags = SAA7146_USE_I2C_IRQ,
69459f3d 1316
1da177e4
LT
1317 .pci_tbl = pci_tbl,
1318
1319 .module = THIS_MODULE,
1320 .attach = budget_av_attach,
1321 .detach = budget_av_detach,
1322
1323 .irq_mask = MASK_10,
1324 .irq_func = budget_av_irq,
1325};
1326
1327static int __init budget_av_init(void)
1328{
1329 return saa7146_register_extension(&budget_extension);
1330}
1331
1332static void __exit budget_av_exit(void)
1333{
1334 saa7146_unregister_extension(&budget_extension);
1335}
1336
1337module_init(budget_av_init);
1338module_exit(budget_av_exit);
1339
1340MODULE_LICENSE("GPL");
1341MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1342MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1343 "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");