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
132static int budget_set_tone(struct dvb_frontend *fe,
133 enum fe_sec_tone_mode 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,
163 enum fe_sec_mini_cmd minicmd)
164{
165 struct budget* budget = (struct budget*) fe->dvb->priv;
166
167 SendDiSEqCMsg (budget, 0, NULL, minicmd);
168
169 return 0;
170}
171
172static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
173{
174 int i;
175
176 dprintk(2, "budget: %p\n", budget);
177
178 for (i = 2; i < length; i++)
179 {
180 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
181 msleep(5);
182 }
183 if (length)
184 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
185 else
186 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
187 msleep(5);
188 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
189 msleep(5);
190 return 0;
191}
192
193static void av7110_set22k(struct budget_patch *budget, int state)
194{
195 u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
196
197 dprintk(2, "budget: %p\n", budget);
198 budget_av7110_send_fw_cmd(budget, buf, 2);
199}
200
201static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
202{
203 int i;
204 u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
205 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
206
207 dprintk(2, "budget: %p\n", budget);
208
209 if (len>10)
210 len=10;
211
212 buf[1] = len+2;
213 buf[2] = len;
214
215 if (burst != -1)
216 buf[3]=burst ? 0x01 : 0x00;
217 else
218 buf[3]=0xffff;
219
220 for (i=0; i<len; i++)
221 buf[i+4]=msg[i];
222
223 budget_av7110_send_fw_cmd(budget, buf, 18);
224 return 0;
225}
226
227static int budget_patch_set_tone(struct dvb_frontend *fe,
228 enum fe_sec_tone_mode tone)
229{
230 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
231
232 switch (tone) {
233 case SEC_TONE_ON:
234 av7110_set22k (budget, 1);
235 break;
236
237 case SEC_TONE_OFF:
238 av7110_set22k (budget, 0);
239 break;
240
241 default:
242 return -EINVAL;
243 }
244
245 return 0;
246}
247
248static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
249{
250 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
251
252 av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
253
254 return 0;
255}
256
257static int budget_patch_diseqc_send_burst(struct dvb_frontend *fe,
258 enum fe_sec_mini_cmd minicmd)
259{
260 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
261
262 av7110_send_diseqc_msg (budget, 0, NULL, minicmd);
263
264 return 0;
265}
266
267static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
268{
269 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
270 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
271 u8 pwr = 0;
272 u8 buf[4];
273 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
274 u32 div = (p->frequency + 479500) / 125;
275
276 if (p->frequency > 2000000)
277 pwr = 3;
278 else if (p->frequency > 1800000)
279 pwr = 2;
280 else if (p->frequency > 1600000)
281 pwr = 1;
282 else if (p->frequency > 1200000)
283 pwr = 0;
284 else if (p->frequency >= 1100000)
285 pwr = 1;
286 else pwr = 2;
287
288 buf[0] = (div >> 8) & 0x7f;
289 buf[1] = div & 0xff;
290 buf[2] = ((div & 0x18000) >> 10) | 0x95;
291 buf[3] = (pwr << 6) | 0x30;
292
293
294
295
296 if (fe->ops.i2c_gate_ctrl)
297 fe->ops.i2c_gate_ctrl(fe, 1);
298 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
299 return -EIO;
300 return 0;
301}
302
303static struct ves1x93_config alps_bsrv2_config = {
304 .demod_address = 0x08,
305 .xin = 90100000UL,
306 .invert_pwm = 0,
307};
308
309static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
310{
311 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
312 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
313 u32 div;
314 u8 data[4];
315 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
316
317 div = p->frequency / 125;
318 data[0] = (div >> 8) & 0x7f;
319 data[1] = div & 0xff;
320 data[2] = 0x8e;
321 data[3] = 0x00;
322
323 if (fe->ops.i2c_gate_ctrl)
324 fe->ops.i2c_gate_ctrl(fe, 1);
325 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
326 return -EIO;
327 return 0;
328}
329
330static struct tda8083_config grundig_29504_451_config = {
331 .demod_address = 0x68,
332};
333
334static void frontend_init(struct budget_patch* budget)
335{
336 switch(budget->dev->pci->subsystem_device) {
337 case 0x0000:
338 case 0x1013:
339
340
341 budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
342 if (budget->dvb_frontend) {
343 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
344 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
345 budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst;
346 budget->dvb_frontend->ops.set_tone = budget_patch_set_tone;
347 break;
348 }
349
350
351 budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
352 if (budget->dvb_frontend) {
353 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
354 budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
355
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
362
363 budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
364 if (budget->dvb_frontend) {
365 budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
366 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
367 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
368 budget->dvb_frontend->ops.set_tone = budget_set_tone;
369 break;
370 }
371 break;
372 }
373
374 if (budget->dvb_frontend == NULL) {
375 printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
376 budget->dev->pci->vendor,
377 budget->dev->pci->device,
378 budget->dev->pci->subsystem_vendor,
379 budget->dev->pci->subsystem_device);
380 } else {
381 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
382 printk("budget-av: Frontend registration failed!\n");
383 dvb_frontend_detach(budget->dvb_frontend);
384 budget->dvb_frontend = NULL;
385 }
386 }
387}
388
389
390static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
391{
392 struct budget_patch *budget;
393 int err;
394 int count = 0;
395 int detected = 0;
396
397#define PATCH_RESET 0
398#define RPS_IRQ 0
399#define HPS_SETUP 0
400#if PATCH_RESET
401 saa7146_write(dev, MC1, MASK_31);
402 msleep(40);
403#endif
404#if HPS_SETUP
405
406
407 saa7146_write(dev, DD1_STREAM_B, 0);
408
409 saa7146_write(dev, DD1_INIT, 0x00000200);
410 saa7146_write(dev, BRS_CTRL, 0x00000000);
411
412
413
414
415
416 saa7146_write(dev, HPS_H_PRESCALE, 0);
417 saa7146_write(dev, HPS_H_SCALE, 0);
418 saa7146_write(dev, BCS_CTRL, 0);
419 saa7146_write(dev, HPS_V_SCALE, 0);
420 saa7146_write(dev, HPS_V_GAIN, 0);
421 saa7146_write(dev, CHROMA_KEY_RANGE, 0);
422 saa7146_write(dev, CLIP_FORMAT_CTRL, 0);
423
424 saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
425 saa7146_write(dev, MC2,
426 0 * (MASK_08 | MASK_24) |
427 0 * (MASK_09 | MASK_25) |
428 0 * (MASK_10 | MASK_26) |
429 1 * (MASK_06 | MASK_22) |
430 1 * (MASK_05 | MASK_21) |
431 0 * (MASK_01 | MASK_15)
432 );
433#endif
434
435 saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
436
437 saa7146_write(dev, RPS_TOV1, 0);
438
439
440
441
442
443
444
445 count = 0;
446#if 0
447 WRITE_RPS1(CMD_UPLOAD |
448 MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 );
449#endif
450 WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
451 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
452 WRITE_RPS1(GPIO3_MSK);
453 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
454#if RPS_IRQ
455
456 WRITE_RPS1(CMD_INTERRUPT);
457
458 WRITE_RPS1(CMD_NOP);
459
460 WRITE_RPS1(CMD_INTERRUPT);
461#endif
462 WRITE_RPS1(CMD_STOP);
463
464#if RPS_IRQ
465
466
467
468 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
469
470 saa7146_write(dev, ECT1R, 0x3fff );
471#endif
472
473 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
474
475 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
476
477 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
478
479
480 mdelay(50);
481 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
482 mdelay(150);
483
484
485 if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
486 detected = 1;
487
488#if RPS_IRQ
489 printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
490#endif
491
492 saa7146_write(dev, MC1, ( MASK_29 ));
493
494 if(detected == 0)
495 printk("budget-patch not detected or saa7146 in non-default state.\n"
496 "try enabling resetting of 7146 with MASK_31 in MC1 register\n");
497
498 else
499 printk("BUDGET-PATCH DETECTED.\n");
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
561
562
563
564
565
566
567
568
569
570 count = 0;
571
572
573
574 WRITE_RPS1(CMD_PAUSE | EVT_HS);
575
576 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
577 WRITE_RPS1(GPIO3_MSK);
578 WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
579#if RPS_IRQ
580
581 WRITE_RPS1(CMD_INTERRUPT);
582#endif
583
584 WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
585
586 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
587 WRITE_RPS1(GPIO3_MSK);
588 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
589#if RPS_IRQ
590
591 WRITE_RPS1(CMD_INTERRUPT);
592#endif
593
594 WRITE_RPS1(CMD_JUMP);
595 WRITE_RPS1(dev->d_rps1.dma_handle);
596
597
598 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
599
600 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
601
602 if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
603 return -ENOMEM;
604
605 dprintk(2, "budget: %p\n", budget);
606
607 err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
608 if (err) {
609 kfree(budget);
610 return err;
611 }
612
613
614
615
616
617
618
619
620
621 saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 );
622
623
624
625 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
626
627
628 dev->ext_priv = budget;
629
630 budget->dvb_adapter.priv = budget;
631 frontend_init(budget);
632
633 ttpci_budget_init_hooks(budget);
634
635 return 0;
636}
637
638static int budget_patch_detach (struct saa7146_dev* dev)
639{
640 struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
641 int err;
642
643 if (budget->dvb_frontend) {
644 dvb_unregister_frontend(budget->dvb_frontend);
645 dvb_frontend_detach(budget->dvb_frontend);
646 }
647 err = ttpci_budget_deinit (budget);
648
649 kfree (budget);
650
651 return err;
652}
653
654static int __init budget_patch_init(void)
655{
656 return saa7146_register_extension(&budget_extension);
657}
658
659static void __exit budget_patch_exit(void)
660{
661 saa7146_unregister_extension(&budget_extension);
662}
663
664static struct saa7146_extension budget_extension = {
665 .name = "budget_patch dvb",
666 .flags = 0,
667
668 .module = THIS_MODULE,
669 .pci_tbl = pci_tbl,
670 .attach = budget_patch_attach,
671 .detach = budget_patch_detach,
672
673 .irq_mask = MASK_10,
674 .irq_func = ttpci_budget_irq10_handler,
675};
676
677module_init(budget_patch_init);
678module_exit(budget_patch_exit);
679
680MODULE_LICENSE("GPL");
681MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
682MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 "
683 "based so-called Budget Patch cards");
684