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