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