0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include "av7110.h"
0017 #include "av7110_hw.h"
0018 #include "budget.h"
0019 #include "stv0299.h"
0020 #include "ves1x93.h"
0021 #include "tda8083.h"
0022
0023 #include "bsru6.h"
0024
0025 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
0026
0027 #define budget_patch budget
0028
0029 static struct saa7146_extension budget_extension;
0030
0031 MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
0032
0033
0034 static const struct pci_device_id pci_tbl[] = {
0035 MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
0036
0037 {
0038 .vendor = 0,
0039 }
0040 };
0041
0042
0043
0044
0045
0046
0047 static void gpio_Set22K (struct budget *budget, int state)
0048 {
0049 struct saa7146_dev *dev=budget->dev;
0050 dprintk(2, "budget: %p\n", budget);
0051 saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
0052 }
0053
0054
0055
0056
0057
0058 static void DiseqcSendBit (struct budget *budget, int data)
0059 {
0060 struct saa7146_dev *dev=budget->dev;
0061 dprintk(2, "budget: %p\n", budget);
0062
0063 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
0064 udelay(data ? 500 : 1000);
0065 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
0066 udelay(data ? 1000 : 500);
0067 }
0068
0069 static void DiseqcSendByte (struct budget *budget, int data)
0070 {
0071 int i, par=1, d;
0072
0073 dprintk(2, "budget: %p\n", budget);
0074
0075 for (i=7; i>=0; i--) {
0076 d = (data>>i)&1;
0077 par ^= d;
0078 DiseqcSendBit(budget, d);
0079 }
0080
0081 DiseqcSendBit(budget, par);
0082 }
0083
0084 static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
0085 {
0086 struct saa7146_dev *dev=budget->dev;
0087 int i;
0088
0089 dprintk(2, "budget: %p\n", budget);
0090
0091 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
0092 mdelay(16);
0093
0094 for (i=0; i<len; i++)
0095 DiseqcSendByte(budget, msg[i]);
0096
0097 mdelay(16);
0098
0099 if (burst!=-1) {
0100 if (burst)
0101 DiseqcSendByte(budget, 0xff);
0102 else {
0103 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
0104 mdelay(12);
0105 udelay(500);
0106 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
0107 }
0108 msleep(20);
0109 }
0110
0111 return 0;
0112 }
0113
0114
0115 static int budget_set_tone(struct dvb_frontend *fe,
0116 enum fe_sec_tone_mode tone)
0117 {
0118 struct budget* budget = (struct budget*) fe->dvb->priv;
0119
0120 switch (tone) {
0121 case SEC_TONE_ON:
0122 gpio_Set22K (budget, 1);
0123 break;
0124
0125 case SEC_TONE_OFF:
0126 gpio_Set22K (budget, 0);
0127 break;
0128
0129 default:
0130 return -EINVAL;
0131 }
0132
0133 return 0;
0134 }
0135
0136 static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
0137 {
0138 struct budget* budget = (struct budget*) fe->dvb->priv;
0139
0140 SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
0141
0142 return 0;
0143 }
0144
0145 static int budget_diseqc_send_burst(struct dvb_frontend *fe,
0146 enum fe_sec_mini_cmd minicmd)
0147 {
0148 struct budget* budget = (struct budget*) fe->dvb->priv;
0149
0150 SendDiSEqCMsg (budget, 0, NULL, minicmd);
0151
0152 return 0;
0153 }
0154
0155 static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
0156 {
0157 int i;
0158
0159 dprintk(2, "budget: %p\n", budget);
0160
0161 for (i = 2; i < length; i++)
0162 {
0163 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
0164 msleep(5);
0165 }
0166 if (length)
0167 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
0168 else
0169 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
0170 msleep(5);
0171 ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
0172 msleep(5);
0173 return 0;
0174 }
0175
0176 static void av7110_set22k(struct budget_patch *budget, int state)
0177 {
0178 u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
0179
0180 dprintk(2, "budget: %p\n", budget);
0181 budget_av7110_send_fw_cmd(budget, buf, 2);
0182 }
0183
0184 static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
0185 {
0186 int i;
0187 u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
0188 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
0189
0190 dprintk(2, "budget: %p\n", budget);
0191
0192 if (len>10)
0193 len=10;
0194
0195 buf[1] = len+2;
0196 buf[2] = len;
0197
0198 if (burst != -1)
0199 buf[3]=burst ? 0x01 : 0x00;
0200 else
0201 buf[3]=0xffff;
0202
0203 for (i=0; i<len; i++)
0204 buf[i+4]=msg[i];
0205
0206 budget_av7110_send_fw_cmd(budget, buf, 18);
0207 return 0;
0208 }
0209
0210 static int budget_patch_set_tone(struct dvb_frontend *fe,
0211 enum fe_sec_tone_mode tone)
0212 {
0213 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
0214
0215 switch (tone) {
0216 case SEC_TONE_ON:
0217 av7110_set22k (budget, 1);
0218 break;
0219
0220 case SEC_TONE_OFF:
0221 av7110_set22k (budget, 0);
0222 break;
0223
0224 default:
0225 return -EINVAL;
0226 }
0227
0228 return 0;
0229 }
0230
0231 static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
0232 {
0233 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
0234
0235 av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
0236
0237 return 0;
0238 }
0239
0240 static int budget_patch_diseqc_send_burst(struct dvb_frontend *fe,
0241 enum fe_sec_mini_cmd minicmd)
0242 {
0243 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
0244
0245 av7110_send_diseqc_msg (budget, 0, NULL, minicmd);
0246
0247 return 0;
0248 }
0249
0250 static int alps_bsrv2_tuner_set_params(struct dvb_frontend *fe)
0251 {
0252 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0253 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
0254 u8 pwr = 0;
0255 u8 buf[4];
0256 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
0257 u32 div = (p->frequency + 479500) / 125;
0258
0259 if (p->frequency > 2000000)
0260 pwr = 3;
0261 else if (p->frequency > 1800000)
0262 pwr = 2;
0263 else if (p->frequency > 1600000)
0264 pwr = 1;
0265 else if (p->frequency > 1200000)
0266 pwr = 0;
0267 else if (p->frequency >= 1100000)
0268 pwr = 1;
0269 else pwr = 2;
0270
0271 buf[0] = (div >> 8) & 0x7f;
0272 buf[1] = div & 0xff;
0273 buf[2] = ((div & 0x18000) >> 10) | 0x95;
0274 buf[3] = (pwr << 6) | 0x30;
0275
0276
0277
0278
0279 if (fe->ops.i2c_gate_ctrl)
0280 fe->ops.i2c_gate_ctrl(fe, 1);
0281 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
0282 return -EIO;
0283 return 0;
0284 }
0285
0286 static struct ves1x93_config alps_bsrv2_config = {
0287 .demod_address = 0x08,
0288 .xin = 90100000UL,
0289 .invert_pwm = 0,
0290 };
0291
0292 static int grundig_29504_451_tuner_set_params(struct dvb_frontend *fe)
0293 {
0294 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0295 struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
0296 u32 div;
0297 u8 data[4];
0298 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
0299
0300 div = p->frequency / 125;
0301 data[0] = (div >> 8) & 0x7f;
0302 data[1] = div & 0xff;
0303 data[2] = 0x8e;
0304 data[3] = 0x00;
0305
0306 if (fe->ops.i2c_gate_ctrl)
0307 fe->ops.i2c_gate_ctrl(fe, 1);
0308 if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1)
0309 return -EIO;
0310 return 0;
0311 }
0312
0313 static struct tda8083_config grundig_29504_451_config = {
0314 .demod_address = 0x68,
0315 };
0316
0317 static void frontend_init(struct budget_patch* budget)
0318 {
0319 switch(budget->dev->pci->subsystem_device) {
0320 case 0x0000:
0321 case 0x1013:
0322
0323
0324 budget->dvb_frontend = dvb_attach(ves1x93_attach, &alps_bsrv2_config, &budget->i2c_adap);
0325 if (budget->dvb_frontend) {
0326 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsrv2_tuner_set_params;
0327 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
0328 budget->dvb_frontend->ops.diseqc_send_burst = budget_patch_diseqc_send_burst;
0329 budget->dvb_frontend->ops.set_tone = budget_patch_set_tone;
0330 break;
0331 }
0332
0333
0334 budget->dvb_frontend = dvb_attach(stv0299_attach, &alps_bsru6_config, &budget->i2c_adap);
0335 if (budget->dvb_frontend) {
0336 budget->dvb_frontend->ops.tuner_ops.set_params = alps_bsru6_tuner_set_params;
0337 budget->dvb_frontend->tuner_priv = &budget->i2c_adap;
0338
0339 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
0340 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
0341 budget->dvb_frontend->ops.set_tone = budget_set_tone;
0342 break;
0343 }
0344
0345
0346 budget->dvb_frontend = dvb_attach(tda8083_attach, &grundig_29504_451_config, &budget->i2c_adap);
0347 if (budget->dvb_frontend) {
0348 budget->dvb_frontend->ops.tuner_ops.set_params = grundig_29504_451_tuner_set_params;
0349 budget->dvb_frontend->ops.diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
0350 budget->dvb_frontend->ops.diseqc_send_burst = budget_diseqc_send_burst;
0351 budget->dvb_frontend->ops.set_tone = budget_set_tone;
0352 break;
0353 }
0354 break;
0355 }
0356
0357 if (budget->dvb_frontend == NULL) {
0358 printk("dvb-ttpci: A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
0359 budget->dev->pci->vendor,
0360 budget->dev->pci->device,
0361 budget->dev->pci->subsystem_vendor,
0362 budget->dev->pci->subsystem_device);
0363 } else {
0364 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
0365 printk("budget-av: Frontend registration failed!\n");
0366 dvb_frontend_detach(budget->dvb_frontend);
0367 budget->dvb_frontend = NULL;
0368 }
0369 }
0370 }
0371
0372
0373 static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
0374 {
0375 struct budget_patch *budget;
0376 int err;
0377 int count = 0;
0378 int detected = 0;
0379
0380 #define PATCH_RESET 0
0381 #define RPS_IRQ 0
0382 #define HPS_SETUP 0
0383 #if PATCH_RESET
0384 saa7146_write(dev, MC1, MASK_31);
0385 msleep(40);
0386 #endif
0387 #if HPS_SETUP
0388
0389
0390 saa7146_write(dev, DD1_STREAM_B, 0);
0391
0392 saa7146_write(dev, DD1_INIT, 0x00000200);
0393 saa7146_write(dev, BRS_CTRL, 0x00000000);
0394
0395
0396
0397
0398
0399 saa7146_write(dev, HPS_H_PRESCALE, 0);
0400 saa7146_write(dev, HPS_H_SCALE, 0);
0401 saa7146_write(dev, BCS_CTRL, 0);
0402 saa7146_write(dev, HPS_V_SCALE, 0);
0403 saa7146_write(dev, HPS_V_GAIN, 0);
0404 saa7146_write(dev, CHROMA_KEY_RANGE, 0);
0405 saa7146_write(dev, CLIP_FORMAT_CTRL, 0);
0406
0407 saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
0408 saa7146_write(dev, MC2,
0409 0 * (MASK_08 | MASK_24) |
0410 0 * (MASK_09 | MASK_25) |
0411 0 * (MASK_10 | MASK_26) |
0412 1 * (MASK_06 | MASK_22) |
0413 1 * (MASK_05 | MASK_21) |
0414 0 * (MASK_01 | MASK_15)
0415 );
0416 #endif
0417
0418 saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
0419
0420 saa7146_write(dev, RPS_TOV1, 0);
0421
0422
0423
0424
0425
0426
0427
0428 count = 0;
0429 #if 0
0430 WRITE_RPS1(CMD_UPLOAD |
0431 MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 );
0432 #endif
0433 WRITE_RPS1(CMD_PAUSE | EVT_VBI_B);
0434 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
0435 WRITE_RPS1(GPIO3_MSK);
0436 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
0437 #if RPS_IRQ
0438
0439 WRITE_RPS1(CMD_INTERRUPT);
0440
0441 WRITE_RPS1(CMD_NOP);
0442
0443 WRITE_RPS1(CMD_INTERRUPT);
0444 #endif
0445 WRITE_RPS1(CMD_STOP);
0446
0447 #if RPS_IRQ
0448
0449
0450
0451 saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
0452
0453 saa7146_write(dev, ECT1R, 0x3fff );
0454 #endif
0455
0456 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
0457
0458 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
0459
0460 saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
0461
0462
0463 mdelay(50);
0464 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
0465 mdelay(150);
0466
0467
0468 if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
0469 detected = 1;
0470
0471 #if RPS_IRQ
0472 printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
0473 #endif
0474
0475 saa7146_write(dev, MC1, ( MASK_29 ));
0476
0477 if(detected == 0)
0478 printk("budget-patch not detected or saa7146 in non-default state.\n"
0479 "try enabling resetting of 7146 with MASK_31 in MC1 register\n");
0480
0481 else
0482 printk("BUDGET-PATCH DETECTED.\n");
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553 count = 0;
0554
0555
0556
0557 WRITE_RPS1(CMD_PAUSE | EVT_HS);
0558
0559 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
0560 WRITE_RPS1(GPIO3_MSK);
0561 WRITE_RPS1(SAA7146_GPIO_OUTHI<<24);
0562 #if RPS_IRQ
0563
0564 WRITE_RPS1(CMD_INTERRUPT);
0565 #endif
0566
0567 WRITE_RPS1(CMD_PAUSE | RPS_INV | EVT_HS);
0568
0569 WRITE_RPS1(CMD_WR_REG_MASK | (GPIO_CTRL>>2));
0570 WRITE_RPS1(GPIO3_MSK);
0571 WRITE_RPS1(SAA7146_GPIO_OUTLO<<24);
0572 #if RPS_IRQ
0573
0574 WRITE_RPS1(CMD_INTERRUPT);
0575 #endif
0576
0577 WRITE_RPS1(CMD_JUMP);
0578 WRITE_RPS1(dev->d_rps1.dma_handle);
0579
0580
0581 saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
0582
0583 saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
0584
0585 if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
0586 return -ENOMEM;
0587
0588 dprintk(2, "budget: %p\n", budget);
0589
0590 err = ttpci_budget_init(budget, dev, info, THIS_MODULE, adapter_nr);
0591 if (err) {
0592 kfree(budget);
0593 return err;
0594 }
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604 saa7146_write(dev, RPS_THRESH1, budget->buffer_height | MASK_12 );
0605
0606
0607
0608 saa7146_write(dev, MC1, (MASK_13 | MASK_29));
0609
0610
0611 dev->ext_priv = budget;
0612
0613 budget->dvb_adapter.priv = budget;
0614 frontend_init(budget);
0615
0616 ttpci_budget_init_hooks(budget);
0617
0618 return 0;
0619 }
0620
0621 static int budget_patch_detach (struct saa7146_dev* dev)
0622 {
0623 struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
0624 int err;
0625
0626 if (budget->dvb_frontend) {
0627 dvb_unregister_frontend(budget->dvb_frontend);
0628 dvb_frontend_detach(budget->dvb_frontend);
0629 }
0630 err = ttpci_budget_deinit (budget);
0631
0632 kfree (budget);
0633
0634 return err;
0635 }
0636
0637 static int __init budget_patch_init(void)
0638 {
0639 return saa7146_register_extension(&budget_extension);
0640 }
0641
0642 static void __exit budget_patch_exit(void)
0643 {
0644 saa7146_unregister_extension(&budget_extension);
0645 }
0646
0647 static struct saa7146_extension budget_extension = {
0648 .name = "budget_patch dvb",
0649 .flags = 0,
0650
0651 .module = THIS_MODULE,
0652 .pci_tbl = pci_tbl,
0653 .attach = budget_patch_attach,
0654 .detach = budget_patch_detach,
0655
0656 .irq_mask = MASK_10,
0657 .irq_func = ttpci_budget_irq10_handler,
0658 };
0659
0660 module_init(budget_patch_init);
0661 module_exit(budget_patch_exit);
0662
0663 MODULE_LICENSE("GPL");
0664 MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
0665 MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 based so-called Budget Patch cards");