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