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#include "av7110.h"
31#include "av7110_hw.h"
32#include "budget.h"
33#include "stv0299.h"
34#include "ves1x93.h"
35#include "tda8083.h"
36
37#include "bsru6.h"
38
39DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
40
41#define budget_patch budget
42
43static struct saa7146_extension budget_extension;
44
45MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
46
47
48static struct pci_device_id pci_tbl[] = {
49 MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
50
51 {
52 .vendor = 0,
53 }
54};
55
56
57
58
59
60
61static void gpio_Set22K (struct budget *budget, int state)
62{
63 struct saa7146_dev *dev=budget->dev;
64 dprintk(2, "budget: %p\n", budget);
65 saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
66}
67
68
69
70
71
72static void DiseqcSendBit (struct budget *budget, int data)
73{
74 struct saa7146_dev *dev=budget->dev;
75 dprintk(2, "budget: %p\n", budget);
76
77 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
78 udelay(data ? 500 : 1000);
79 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
80 udelay(data ? 1000 : 500);
81}
82
83static void DiseqcSendByte (struct budget *budget, int data)
84{
85 int i, par=1, d;
86
87 dprintk(2, "budget: %p\n", budget);
88
89 for (i=7; i>=0; i--) {
90 d = (data>>i)&1;
91 par ^= d;
92 DiseqcSendBit(budget, d);
93 }
94
95 DiseqcSendBit(budget, par);
96}
97
98static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
99{
100 struct saa7146_dev *dev=budget->dev;
101 int i;
102
103 dprintk(2, "budget: %p\n", budget);
104
105 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
106 mdelay(16);
107
108 for (i=0; i<len; i++)
109 DiseqcSendByte(budget, msg[i]);
110
111 mdelay(16);
112
113 if (burst!=-1) {
114 if (burst)
115 DiseqcSendByte(budget, 0xff);
116 else {
117 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
118 mdelay(12);
119 udelay(500);
120 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
121 }
122 msleep(20);
123 }
124
125 return 0;
126}
127
128
129static int budget_set_tone(struct dvb_frontend *fe,
130 enum fe_sec_tone_mode tone)
131{
132 struct budget* budget = (struct budget*) fe->dvb->priv;
133
134 switch (tone) {
135 case SEC_TONE_ON:
136 gpio_Set22K (budget, 1);
137 break;
138
139 case SEC_TONE_OFF:
140 gpio_Set22K (budget, 0);
141 break;
142
143 default:
144 return -EINVAL;
145 }
146
147 return 0;
148}
149
150static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
151{
152 struct budget* budget = (struct budget*) fe->dvb->priv;
153
154 SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
155
156 return 0;
157}
158
159static int budget_diseqc_send_burst(struct dvb_frontend *fe,
160 enum fe_sec_mini_cmd minicmd)
161{
162 struct budget* budget = (struct budget*) fe->dvb->priv;
163
164 SendDiSEqCMsg (budget, 0, NULL, minicmd);
165
166 return 0;
167}
168
169static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
170{
171 int i;
172
173 dprintk(2, "budget: %p\n", budget);
174
175 for (i = 2; i < length; i++)
176 {
177 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
178 msleep(5);
179 }
180 if (length)
181 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
182 else
183 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
184 msleep(5);
185 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
186 msleep(5);
187 return 0;
188}
189
190static void av7110_set22k(struct budget_patch *budget, int state)
191{
192 u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
193
194 dprintk(2, "budget: %p\n", budget);
195 budget_av7110_send_fw_cmd(budget, buf, 2);
196}
197
198static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
199{
200 int i;
201 u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
202 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
203
204 dprintk(2, "budget: %p\n", budget);
205
206 if (len>10)
207 len=10;
208
209 buf[1] = len+2;
210 buf[2] = len;
211
212 if (burst != -1)
213 buf[3]=burst ? 0x01 : 0x00;
214 else
215 buf[3]=0xffff;
216
217 for (i=0; i<len; i++)
218 buf[i+4]=msg[i];
219
220 budget_av7110_send_fw_cmd(budget, buf, 18);
221 return 0;
222}
223
224static int budget_patch_set_tone(struct dvb_frontend *fe,
225 enum fe_sec_tone_mode tone)
226{
227 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
228
229 switch (tone) {
230 case SEC_TONE_ON:
231 av7110_set22k (budget, 1);
232 break;
233
234 case SEC_TONE_OFF:
235 av7110_set22k (budget, 0);
236 break;
237
238 default:
239 return -EINVAL;
240 }
241
242 return 0;
243}
244
245static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
246{
247 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
248
249 av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
250
251 return 0;
252}
253
254static int budget_patch_diseqc_send_burst(struct dvb_frontend *fe,
255 enum fe_sec_mini_cmd 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 resetting 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 based so-called Budget Patch cards");
680