1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include "av7110.h"
34#include "av7110_hw.h"
35#include "budget.h"
36#include "stv0299.h"
37#include "ves1x93.h"
38#include "tda8083.h"
39
40#include "bsru6.h"
41
42DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
43
44#define budget_patch budget
45
46static struct saa7146_extension budget_extension;
47
48MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
49
50
51static struct pci_device_id pci_tbl[] = {
52 MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
53
54 {
55 .vendor = 0,
56 }
57};
58
59
60
61
62
63
64static void gpio_Set22K (struct budget *budget, int state)
65{
66 struct saa7146_dev *dev=budget->dev;
67 dprintk(2, "budget: %p\n", budget);
68 saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
69}
70
71
72
73
74
75static void DiseqcSendBit (struct budget *budget, int data)
76{
77 struct saa7146_dev *dev=budget->dev;
78 dprintk(2, "budget: %p\n", budget);
79
80 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
81 udelay(data ? 500 : 1000);
82 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
83 udelay(data ? 1000 : 500);
84}
85
86static void DiseqcSendByte (struct budget *budget, int data)
87{
88 int i, par=1, d;
89
90 dprintk(2, "budget: %p\n", budget);
91
92 for (i=7; i>=0; i--) {
93 d = (data>>i)&1;
94 par ^= d;
95 DiseqcSendBit(budget, d);
96 }
97
98 DiseqcSendBit(budget, par);
99}
100
101static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
102{
103 struct saa7146_dev *dev=budget->dev;
104 int i;
105
106 dprintk(2, "budget: %p\n", budget);
107
108 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
109 mdelay(16);
110
111 for (i=0; i<len; i++)
112 DiseqcSendByte(budget, msg[i]);
113
114 mdelay(16);
115
116 if (burst!=-1) {
117 if (burst)
118 DiseqcSendByte(budget, 0xff);
119 else {
120 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
121 mdelay(12);
122 udelay(500);
123 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
124 }
125 msleep(20);
126 }
127
128 return 0;
129}
130
131
132
133static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
134{
135 struct budget* budget = (struct budget*) fe->dvb->priv;
136
137 switch (tone) {
138 case SEC_TONE_ON:
139 gpio_Set22K (budget, 1);
140 break;
141
142 case SEC_TONE_OFF:
143 gpio_Set22K (budget, 0);
144 break;
145
146 default:
147 return -EINVAL;
148 }
149
150 return 0;
151}
152
153static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
154{
155 struct budget* budget = (struct budget*) fe->dvb->priv;
156
157 SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
158
159 return 0;
160}
161
162static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
163{
164 struct budget* budget = (struct budget*) fe->dvb->priv;
165
166 SendDiSEqCMsg (budget, 0, NULL, minicmd);
167
168 return 0;
169}
170
171static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
172{
173 int i;
174
175 dprintk(2, "budget: %p\n", budget);
176
177 for (i = 2; i < length; i++)
178 {
179 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
180 msleep(5);
181 }
182 if (length)
183 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
184 else
185 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
186 msleep(5);
187 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
188 msleep(5);
189 return 0;
190}
191
192static void av7110_set22k(struct budget_patch *budget, int state)
193{
194 u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
195
196 dprintk(2, "budget: %p\n", budget);
197 budget_av7110_send_fw_cmd(budget, buf, 2);
198}
199
200static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
201{
202 int i;
203 u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
204 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
205
206 dprintk(2, "budget: %p\n", budget);
207
208 if (len>10)
209 len=10;
210
211 buf[1] = len+2;
212 buf[2] = len;
213
214 if (burst != -1)
215 buf[3]=burst ? 0x01 : 0x00;
216 else
217 buf[3]=0xffff;
218
219 for (i=0; i<len; i++)
220 buf[i+4]=msg[i];
221
222 budget_av7110_send_fw_cmd(budget, buf, 18);
223 return 0;
224}
225
226static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
227{
228 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
229
230 switch (tone) {
231 case SEC_TONE_ON:
232 av7110_set22k (budget, 1);
233 break;
234
235 case SEC_TONE_OFF:
236 av7110_set22k (budget, 0);
237 break;
238
239 default:
240 return -EINVAL;
241 }
242
243 return 0;
244}
245
246static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
247{
248 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
249
250 av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
251
252 return 0;
253}
254
255static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
256{
257 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
258
259 av7110_send_diseqc_msg (budget, 0, NULL, minicmd);
260
261 return 0;
262}
263
264static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
265{
266 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
267 u8 pwr = 0;
268 u8 buf[4];
269 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
270 u32 div = (params->frequency + 479500) / 125;
271
272 if (params->frequency > 2000000) pwr = 3;
273 else if (params->frequency > 1800000) pwr = 2;
274 else if (params->frequency > 1600000) pwr = 1;
275 else if (params->frequency > 1200000) pwr = 0;
276 else if (params->frequency >= 1100000) pwr = 1;
277 else pwr = 2;
278
279 buf[0] = (div >> 8) & 0x7f;
280 buf[1] = div & 0xff;
281 buf[2] = ((div & 0x18000) >> 10) | 0x95;
282 buf[3] = (pwr << 6) | 0x30;
283
284
285
286
287 if (fe->ops.i2c_gate_ctrl)
288 fe->ops.i2c_gate_ctrl(fe, 1);
289 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
290 return -EIO;
291 return 0;
292}
293
294static struct ves1x93_config alps_bsrv2_config = {
295 .demod_address = 0x08,
296 .xin = 90100000UL,
297 .invert_pwm = 0,
298};
299
300static int grundig_29504_451_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
301{
302 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
303 u32 div;
304 u8 data[4];
305 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
306
307 div = params->frequency / 125;
308 data[0] = (div >> 8) & 0x7f;
309 data[1] = div & 0xff;
310 data[2] = 0x8e;
311 data[3] = 0x00;
312
313 if (fe->ops.i2c_gate_ctrl)
314 fe->ops.i2c_gate_ctrl(fe, 1);
315 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
316 return -EIO;
317 return 0;
318}
319
320static struct tda8083_config grundig_29504_451_config = {
321 .demod_address = 0x68,
322};
323
324static void frontend_init(struct budget_patch* budget)
325{
326 switch(budget->dev->pci->subsystem_device) {
327 case 0x0000:
328 case 0x1013:
329
330
331 budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
332 if (budget->dvb_frontend) {
333 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
334 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
335 budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst;
336 budget->dvb_frontend->ops.set_tone = budget_patch_set_tone;
337 break;
338 }
339
340
341 budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
342 if (budget->dvb_frontend) {
343 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
344 budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
345
346 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
347 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
348 budget->dvb_frontend->ops.set_tone = budget_set_tone;
349 break;
350 }
351
352
353 budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
354 if (budget->dvb_frontend) {
355 budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
356 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
357 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
358 budget->dvb_frontend->ops.set_tone = budget_set_tone;
359 break;
360 }
361 break;
362 }
363
364 if (budget->dvb_frontend == NULL) {
365 printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
366 budget->dev->pci->vendor,
367 budget->dev->pci->device,
368 budget->dev->pci->subsystem_vendor,
369 budget->dev->pci->subsystem_device);
370 } else {
371 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
372 printk("budget-av: Frontend registration failed!\n");
373 dvb_frontend_detach(budget->dvb_frontend);
374 budget->dvb_frontend = NULL;
375 }
376 }
377}
378
379
380static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
381{
382 struct budget_patch *budget;
383 int err;
384 int count = 0;
385 int detected = 0;
386
387#define PATCH_RESET 0
388#define RPS_IRQ 0
389#define HPS_SETUP 0
390#if PATCH_RESET
391 saa7146_write(dev, MC1, MASK_31);
392 msleep(40);
393#endif
394#if HPS_SETUP
395
396
397 saa7146_write(dev, DD1_STREAM_B, 0);
398
399 saa7146_write(dev, DD1_INIT, 0x00000200);
400 saa7146_write(dev, BRS_CTRL, 0x00000000);
401
402
403
404
405
406 saa7146_write(dev, HPS_H_PRESCALE, 0);
407 saa7146_write(dev, HPS_H_SCALE, 0);
408 saa7146_write(dev, BCS_CTRL, 0);
409 saa7146_write(dev, HPS_V_SCALE, 0);
410 saa7146_write(dev, HPS_V_GAIN, 0);
411 saa7146_write(dev, CHROMA_KEY_RANGE, 0);
412 saa7146_write(dev, CLIP_FORMAT_CTRL, 0);
413
414 saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
415 saa7146_write(dev, MC2,
416 0 * (MASK_08 | MASK_24) |
417 0 * (MASK_09 | MASK_25) |
418 0 * (MASK_10 | MASK_26) |
419 1 * (MASK_06 | MASK_22) |
420 1 * (MASK_05 | MASK_21) |
421 0 * (MASK_01 | MASK_15)
422 );
423#endif
424
425 saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
426
427 saa7146_write(dev, RPS_TOV1, 0);
428
429
430
431
432
433
434
435 count = 0;
436#if 0
437 WRITE_RPS1(CMD_UPLOAD |
438 MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 );
439#endif
440 WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
441 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
442 WRITE_RPS1(GPIO3_MSK);
443 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
444#if RPS_IRQ
445
446 WRITE_RPS1(CMD_INTERRUPT);
447
448 WRITE_RPS1(CMD_NOP);
449
450 WRITE_RPS1(CMD_INTERRUPT);
451#endif
452 WRITE_RPS1(CMD_STOP);
453
454#if RPS_IRQ
455
456
457
458 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
459
460 saa7146_write(dev, ECT1R, 0x3fff );
461#endif
462
463 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
464
465 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
466
467 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
468
469
470 mdelay(50);
471 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
472 mdelay(150);
473
474
475 if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
476 detected = 1;
477
478#if RPS_IRQ
479 printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
480#endif
481
482 saa7146_write(dev, MC1, ( MASK_29 ));
483
484 if(detected == 0)
485 printk("budget-patch not detected or saa7146 in non-default state.\n"
486 "try enabling ressetting of 7146 with MASK_31 in MC1 register\n");
487
488 else
489 printk("BUDGET-PATCH DETECTED.\n");
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560 count = 0;
561
562
563
564 WRITE_RPS1(CMD_PAUSE | EVT_HS);
565
566 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
567 WRITE_RPS1(GPIO3_MSK);
568 WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
569#if RPS_IRQ
570
571 WRITE_RPS1(CMD_INTERRUPT);
572#endif
573
574 WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
575
576 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
577 WRITE_RPS1(GPIO3_MSK);
578 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
579#if RPS_IRQ
580
581 WRITE_RPS1(CMD_INTERRUPT);
582#endif
583
584 WRITE_RPS1(CMD_JUMP);
585 WRITE_RPS1(dev->d_rps1.dma_handle);
586
587
588 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
589
590 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
591
592 if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
593 return -ENOMEM;
594
595 dprintk(2, "budget: %p\n", budget);
596
597 err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
598 if (err) {
599 kfree(budget);
600 return err;
601 }
602
603
604
605
606
607
608
609
610
611 saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 );
612
613
614
615 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
616
617
618 dev->ext_priv = budget;
619
620 budget->dvb_adapter.priv = budget;
621 frontend_init(budget);
622
623 ttpci_budget_init_hooks(budget);
624
625 return 0;
626}
627
628static int budget_patch_detach (struct saa7146_dev* dev)
629{
630 struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
631 int err;
632
633 if (budget->dvb_frontend) {
634 dvb_unregister_frontend(budget->dvb_frontend);
635 dvb_frontend_detach(budget->dvb_frontend);
636 }
637 err = ttpci_budget_deinit (budget);
638
639 kfree (budget);
640
641 return err;
642}
643
644static int __init budget_patch_init(void)
645{
646 return saa7146_register_extension(&budget_extension);
647}
648
649static void __exit budget_patch_exit(void)
650{
651 saa7146_unregister_extension(&budget_extension);
652}
653
654static struct saa7146_extension budget_extension = {
655 .name = "budget_patch dvb",
656 .flags = 0,
657
658 .module = THIS_MODULE,
659 .pci_tbl = pci_tbl,
660 .attach = budget_patch_attach,
661 .detach = budget_patch_detach,
662
663 .irq_mask = MASK_10,
664 .irq_func = ttpci_budget_irq10_handler,
665};
666
667module_init(budget_patch_init);
668module_exit(budget_patch_exit);
669
670MODULE_LICENSE("GPL");
671MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
672MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 "
673 "based so-called Budget Patch cards");
674