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