Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/agpgart
[sfrench/cifs-2.6.git] / drivers / media / dvb / ttpci / budget-patch.c
1 /*
2  * budget-patch.c: driver for Budget Patch,
3  * hardware modification of DVB-S cards enabling full TS
4  *
5  * Written by Emard <emard@softhome.net>
6  *
7  * Original idea by Roberto Deza <rdeza@unav.es>
8  *
9  * Special thanks to Holger Waechtler, Michael Hunold, Marian Durkovic
10  * and Metzlerbros
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
28  *
29  *
30  * the project's page is at http://www.linuxtv.org/dvb/
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 #define budget_patch budget
41
42 static struct saa7146_extension budget_extension;
43
44 MAKE_BUDGET_INFO(ttbp, "TT-Budget/Patch DVB-S 1.x PCI", BUDGET_PATCH);
45 //MAKE_BUDGET_INFO(satel,"TT-Budget/Patch SATELCO PCI", BUDGET_TT_HW_DISEQC);
46
47 static struct pci_device_id pci_tbl[] = {
48         MAKE_EXTENSION_PCI(ttbp,0x13c2, 0x0000),
49 //        MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013),
50         {
51                 .vendor    = 0,
52         }
53 };
54
55 /* those lines are for budget-patch to be tried
56 ** on a true budget card and observe the
57 ** behaviour of VSYNC generated by rps1.
58 ** this code was shamelessly copy/pasted from budget.c
59 */
60 static void gpio_Set22K (struct budget *budget, int state)
61 {
62         struct saa7146_dev *dev=budget->dev;
63         dprintk(2, "budget: %p\n", budget);
64         saa7146_setgpio(dev, 3, (state ? SAA7146_GPIO_OUTHI : SAA7146_GPIO_OUTLO));
65 }
66
67 /* Diseqc functions only for TT Budget card */
68 /* taken from the Skyvision DVB driver by
69    Ralph Metzler <rjkm@metzlerbros.de> */
70
71 static void DiseqcSendBit (struct budget *budget, int data)
72 {
73         struct saa7146_dev *dev=budget->dev;
74         dprintk(2, "budget: %p\n", budget);
75
76         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
77         udelay(data ? 500 : 1000);
78         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
79         udelay(data ? 1000 : 500);
80 }
81
82 static void DiseqcSendByte (struct budget *budget, int data)
83 {
84         int i, par=1, d;
85
86         dprintk(2, "budget: %p\n", budget);
87
88         for (i=7; i>=0; i--) {
89                 d = (data>>i)&1;
90                 par ^= d;
91                 DiseqcSendBit(budget, d);
92         }
93
94         DiseqcSendBit(budget, par);
95 }
96
97 static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long burst)
98 {
99         struct saa7146_dev *dev=budget->dev;
100         int i;
101
102         dprintk(2, "budget: %p\n", budget);
103
104         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
105         mdelay(16);
106
107         for (i=0; i<len; i++)
108                 DiseqcSendByte(budget, msg[i]);
109
110         mdelay(16);
111
112         if (burst!=-1) {
113                 if (burst)
114                         DiseqcSendByte(budget, 0xff);
115                 else {
116                         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
117                         udelay(12500);
118                         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
119                 }
120                 msleep(20);
121         }
122
123         return 0;
124 }
125
126 /* shamelessly copy/pasted from budget.c
127 */
128 static int budget_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
129 {
130         struct budget* budget = (struct budget*) fe->dvb->priv;
131
132         switch (tone) {
133         case SEC_TONE_ON:
134                 gpio_Set22K (budget, 1);
135                 break;
136
137         case SEC_TONE_OFF:
138                 gpio_Set22K (budget, 0);
139                 break;
140
141         default:
142                 return -EINVAL;
143         }
144
145         return 0;
146 }
147
148 static int budget_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
149 {
150         struct budget* budget = (struct budget*) fe->dvb->priv;
151
152         SendDiSEqCMsg (budget, cmd->msg_len, cmd->msg, 0);
153
154         return 0;
155 }
156
157 static int budget_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
158 {
159         struct budget* budget = (struct budget*) fe->dvb->priv;
160
161         SendDiSEqCMsg (budget, 0, NULL, minicmd);
162
163         return 0;
164 }
165
166 static int budget_av7110_send_fw_cmd(struct budget_patch *budget, u16* buf, int length)
167 {
168         int i;
169
170         dprintk(2, "budget: %p\n", budget);
171
172         for (i = 2; i < length; i++)
173         {
174                   ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2*i, 2, (u32) buf[i], 0,0);
175                   msleep(5);
176         }
177         if (length)
178                   ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, (u32) buf[1], 0,0);
179         else
180                   ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND + 2, 2, 0, 0,0);
181         msleep(5);
182         ttpci_budget_debiwrite(budget, DEBINOSWAP, COMMAND, 2, (u32) buf[0], 0,0);
183         msleep(5);
184         return 0;
185 }
186
187 static void av7110_set22k(struct budget_patch *budget, int state)
188 {
189         u16 buf[2] = {( COMTYPE_AUDIODAC << 8) | (state ? ON22K : OFF22K), 0};
190
191         dprintk(2, "budget: %p\n", budget);
192         budget_av7110_send_fw_cmd(budget, buf, 2);
193 }
194
195 static int av7110_send_diseqc_msg(struct budget_patch *budget, int len, u8 *msg, int burst)
196 {
197         int i;
198         u16 buf[18] = { ((COMTYPE_AUDIODAC << 8) | SendDiSEqC),
199                 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
200
201         dprintk(2, "budget: %p\n", budget);
202
203         if (len>10)
204                 len=10;
205
206         buf[1] = len+2;
207         buf[2] = len;
208
209         if (burst != -1)
210                 buf[3]=burst ? 0x01 : 0x00;
211         else
212                 buf[3]=0xffff;
213
214         for (i=0; i<len; i++)
215                 buf[i+4]=msg[i];
216
217         budget_av7110_send_fw_cmd(budget, buf, 18);
218         return 0;
219 }
220
221 static int budget_patch_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
222 {
223         struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
224
225         switch (tone) {
226         case SEC_TONE_ON:
227                 av7110_set22k (budget, 1);
228                 break;
229
230         case SEC_TONE_OFF:
231                 av7110_set22k (budget, 0);
232                 break;
233
234         default:
235                 return -EINVAL;
236         }
237
238         return 0;
239 }
240
241 static int budget_patch_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd)
242 {
243         struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
244
245         av7110_send_diseqc_msg (budget, cmd->msg_len, cmd->msg, 0);
246
247         return 0;
248 }
249
250 static int budget_patch_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
251 {
252         struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
253
254         av7110_send_diseqc_msg (budget, 0, NULL, minicmd);
255
256         return 0;
257 }
258
259 static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
260 {
261         struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
262         u8 pwr = 0;
263         u8 buf[4];
264         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
265         u32 div = (params->frequency + 479500) / 125;
266
267         if (params->frequency > 2000000) pwr = 3;
268         else if (params->frequency > 1800000) pwr = 2;
269         else if (params->frequency > 1600000) pwr = 1;
270         else if (params->frequency > 1200000) pwr = 0;
271         else if (params->frequency >= 1100000) pwr = 1;
272         else pwr = 2;
273
274         buf[0] = (div >> 8) & 0x7f;
275         buf[1] = div & 0xff;
276         buf[2] = ((div & 0x18000) >> 10) | 0x95;
277         buf[3] = (pwr << 6) | 0x30;
278
279         // NOTE: since we're using a prescaler of 2, we set the
280         // divisor frequency to 62.5kHz and divide by 125 above
281
282         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
283         return 0;
284 }
285
286 static struct ves1x93_config alps_bsrv2_config = {
287         .demod_address = 0x08,
288         .xin = 90100000UL,
289         .invert_pwm = 0,
290         .pll_set = alps_bsrv2_pll_set,
291 };
292
293 static u8 alps_bsru6_inittab[] = {
294         0x01, 0x15,
295         0x02, 0x00,
296         0x03, 0x00,
297         0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
298         0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
299         0x06, 0x40,   /* DAC not used, set to high impendance mode */
300         0x07, 0x00,   /* DAC LSB */
301         0x08, 0x40,   /* DiSEqC off, LNB power on OP2/LOCK pin on */
302         0x09, 0x00,   /* FIFO */
303         0x0c, 0x51,   /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
304         0x0d, 0x82,   /* DC offset compensation = ON, beta_agc1 = 2 */
305         0x0e, 0x23,   /* alpha_tmg = 2, beta_tmg = 3 */
306         0x10, 0x3f,   // AGC2  0x3d
307         0x11, 0x84,
308         0x12, 0xb9,
309         0x15, 0xc9,   // lock detector threshold
310         0x16, 0x00,
311         0x17, 0x00,
312         0x18, 0x00,
313         0x19, 0x00,
314         0x1a, 0x00,
315         0x1f, 0x50,
316         0x20, 0x00,
317         0x21, 0x00,
318         0x22, 0x00,
319         0x23, 0x00,
320         0x28, 0x00,  // out imp: normal  out type: parallel FEC mode:0
321         0x29, 0x1e,  // 1/2 threshold
322         0x2a, 0x14,  // 2/3 threshold
323         0x2b, 0x0f,  // 3/4 threshold
324         0x2c, 0x09,  // 5/6 threshold
325         0x2d, 0x05,  // 7/8 threshold
326         0x2e, 0x01,
327         0x31, 0x1f,  // test all FECs
328         0x32, 0x19,  // viterbi and synchro search
329         0x33, 0xfc,  // rs control
330         0x34, 0x93,  // error control
331         0x0f, 0x52,
332         0xff, 0xff
333 };
334
335 static int alps_bsru6_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio)
336 {
337         u8 aclk = 0;
338         u8 bclk = 0;
339
340         if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; }
341         else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; }
342         else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; }
343         else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; }
344         else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; }
345         else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; }
346
347         stv0299_writereg (fe, 0x13, aclk);
348         stv0299_writereg (fe, 0x14, bclk);
349         stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff);
350         stv0299_writereg (fe, 0x20, (ratio >>  8) & 0xff);
351         stv0299_writereg (fe, 0x21, (ratio      ) & 0xf0);
352
353         return 0;
354 }
355
356 static int alps_bsru6_pll_set(struct dvb_frontend* fe, struct i2c_adapter *i2c, struct dvb_frontend_parameters* params)
357 {
358         u8 data[4];
359         u32 div;
360         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
361
362         if ((params->frequency < 950000) || (params->frequency > 2150000)) return -EINVAL;
363
364         div = (params->frequency + (125 - 1)) / 125; // round correctly
365         data[0] = (div >> 8) & 0x7f;
366         data[1] = div & 0xff;
367         data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
368         data[3] = 0xC4;
369
370         if (params->frequency > 1530000) data[3] = 0xc0;
371
372         if (i2c_transfer(i2c, &msg, 1) != 1) return -EIO;
373         return 0;
374 }
375
376 static struct stv0299_config alps_bsru6_config = {
377
378         .demod_address = 0x68,
379         .inittab = alps_bsru6_inittab,
380         .mclk = 88000000UL,
381         .invert = 1,
382         .skip_reinit = 0,
383         .lock_output = STV0229_LOCKOUTPUT_1,
384         .volt13_op0_op1 = STV0299_VOLT13_OP1,
385         .min_delay_ms = 100,
386         .set_symbol_rate = alps_bsru6_set_symbol_rate,
387         .pll_set = alps_bsru6_pll_set,
388 };
389
390 static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
391 {
392         struct budget_patch* budget = (struct budget_patch*) fe->dvb->priv;
393         u32 div;
394         u8 data[4];
395         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
396
397         div = params->frequency / 125;
398         data[0] = (div >> 8) & 0x7f;
399         data[1] = div & 0xff;
400         data[2] = 0x8e;
401         data[3] = 0x00;
402
403         if (i2c_transfer (&budget->i2c_adap, &msg, 1) != 1) return -EIO;
404         return 0;
405 }
406
407 static struct tda8083_config grundig_29504_451_config = {
408         .demod_address = 0x68,
409         .pll_set = grundig_29504_451_pll_set,
410 };
411
412 static void frontend_init(struct budget_patch* budget)
413 {
414         switch(budget->dev->pci->subsystem_device) {
415         case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
416         case 0x1013: // SATELCO Multimedia PCI
417
418                 // try the ALPS BSRV2 first of all
419                 budget->dvb_frontend = ves1x93_attach(&alps_bsrv2_config, &budget->i2c_adap);
420                 if (budget->dvb_frontend) {
421                         budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_patch_diseqc_send_master_cmd;
422                         budget->dvb_frontend->ops->diseqc_send_burst = budget_patch_diseqc_send_burst;
423                         budget->dvb_frontend->ops->set_tone = budget_patch_set_tone;
424                         break;
425                 }
426
427                 // try the ALPS BSRU6 now
428                 budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap);
429                 if (budget->dvb_frontend) {
430                         budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
431                         budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
432                         budget->dvb_frontend->ops->set_tone = budget_set_tone;
433                         break;
434                 }
435
436                 // Try the grundig 29504-451
437                 budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap);
438                 if (budget->dvb_frontend) {
439                         budget->dvb_frontend->ops->diseqc_send_master_cmd = budget_diseqc_send_master_cmd;
440                         budget->dvb_frontend->ops->diseqc_send_burst = budget_diseqc_send_burst;
441                         budget->dvb_frontend->ops->set_tone = budget_set_tone;
442                         break;
443                 }
444                 break;
445         }
446
447         if (budget->dvb_frontend == NULL) {
448                 printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
449                        budget->dev->pci->vendor,
450                        budget->dev->pci->device,
451                        budget->dev->pci->subsystem_vendor,
452                        budget->dev->pci->subsystem_device);
453         } else {
454                 if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) {
455                         printk("budget-av: Frontend registration failed!\n");
456                         if (budget->dvb_frontend->ops->release)
457                                 budget->dvb_frontend->ops->release(budget->dvb_frontend);
458                         budget->dvb_frontend = NULL;
459                 }
460         }
461 }
462
463 /* written by Emard */
464 static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_data *info)
465 {
466         struct budget_patch *budget;
467         int err;
468         int count = 0;
469         int detected = 0;
470
471 #define PATCH_RESET 0
472 #define RPS_IRQ 0
473 #define HPS_SETUP 0
474 #if PATCH_RESET
475         saa7146_write(dev, MC1, MASK_31);
476         msleep(40);
477 #endif
478 #if HPS_SETUP
479         // initialize registers. Better to have it like this
480         // than leaving something unconfigured
481         saa7146_write(dev, DD1_STREAM_B, 0);
482         // port B VSYNC at rising edge
483         saa7146_write(dev, DD1_INIT, 0x00000200);  // have this in budget-core too!
484         saa7146_write(dev, BRS_CTRL, 0x00000000);  // VBI
485
486         // debi config
487         // saa7146_write(dev, DEBI_CONFIG, MASK_30|MASK_28|MASK_18);
488
489         // zero all HPS registers
490         saa7146_write(dev, HPS_H_PRESCALE, 0);                  // r68
491         saa7146_write(dev, HPS_H_SCALE, 0);                     // r6c
492         saa7146_write(dev, BCS_CTRL, 0);                        // r70
493         saa7146_write(dev, HPS_V_SCALE, 0);                     // r60
494         saa7146_write(dev, HPS_V_GAIN, 0);                      // r64
495         saa7146_write(dev, CHROMA_KEY_RANGE, 0);                // r74
496         saa7146_write(dev, CLIP_FORMAT_CTRL, 0);                // r78
497         // Set HPS prescaler for port B input
498         saa7146_write(dev, HPS_CTRL, (1<<30) | (0<<29) | (1<<28) | (0<<12) );
499         saa7146_write(dev, MC2,
500           0 * (MASK_08 | MASK_24)  |   // BRS control
501           0 * (MASK_09 | MASK_25)  |   // a
502           0 * (MASK_10 | MASK_26)  |   // b
503           1 * (MASK_06 | MASK_22)  |   // HPS_CTRL1
504           1 * (MASK_05 | MASK_21)  |   // HPS_CTRL2
505           0 * (MASK_01 | MASK_15)      // DEBI
506            );
507 #endif
508         // Disable RPS1 and RPS0
509         saa7146_write(dev, MC1, ( MASK_29 | MASK_28));
510         // RPS1 timeout disable
511         saa7146_write(dev, RPS_TOV1, 0);
512
513         // code for autodetection
514         // will wait for VBI_B event (vertical blank at port B)
515         // and will reset GPIO3 after VBI_B is detected.
516         // (GPIO3 should be raised high by CPU to
517         // test if GPIO3 will generate vertical blank signal
518         // in budget patch GPIO3 is connected to VSYNC_B
519         count = 0;
520 #if 0
521         WRITE_RPS1(cpu_to_le32(CMD_UPLOAD |
522           MASK_10 | MASK_09 | MASK_08 | MASK_06 | MASK_05 | MASK_04 | MASK_03 | MASK_02 ));
523 #endif
524         WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_VBI_B));
525         WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
526         WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
527         WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
528 #if RPS_IRQ
529         // issue RPS1 interrupt to increment counter
530         WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
531         // at least a NOP is neede between two interrupts
532         WRITE_RPS1(cpu_to_le32(CMD_NOP));
533         // interrupt again
534         WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
535 #endif
536         WRITE_RPS1(cpu_to_le32(CMD_STOP));
537
538 #if RPS_IRQ
539         // set event counter 1 source as RPS1 interrupt (0x03)          (rE4 p53)
540         // use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled
541         // use 0x15 to track VPE  interrupts - increase by 1 every vpeirq() is called
542         saa7146_write(dev, EC1SSR, (0x03<<2) | 3 );
543         // set event counter 1 treshold to maximum allowed value        (rEC p55)
544         saa7146_write(dev, ECT1R,  0x3fff );
545 #endif
546         // Fix VSYNC level
547         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
548         // Set RPS1 Address register to point to RPS code               (r108 p42)
549         saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
550         // Enable RPS1,                                                 (rFC p33)
551         saa7146_write(dev, MC1, (MASK_13 | MASK_29 ));
552
553
554         mdelay(50);
555         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI);
556         mdelay(150);
557
558
559         if( (saa7146_read(dev, GPIO_CTRL) & 0x10000000) == 0)
560                 detected = 1;
561
562 #if RPS_IRQ
563         printk("Event Counter 1 0x%04x\n", saa7146_read(dev, EC1R) & 0x3fff );
564 #endif
565         // Disable RPS1
566         saa7146_write(dev, MC1, ( MASK_29 ));
567
568         if(detected == 0)
569                 printk("budget-patch not detected or saa7146 in non-default state.\n"
570                        "try enabling ressetting of 7146 with MASK_31 in MC1 register\n");
571
572         else
573                 printk("BUDGET-PATCH DETECTED.\n");
574
575
576 /*      OLD (Original design by Roberto Deza):
577 **      This code will setup the SAA7146_RPS1 to generate a square
578 **      wave on GPIO3, changing when a field (TS_HEIGHT/2 "lines" of
579 **      TS_WIDTH packets) has been acquired on SAA7146_D1B video port;
580 **      then, this GPIO3 output which is connected to the D1B_VSYNC
581 **      input, will trigger the acquisition of the alternate field
582 **      and so on.
583 **      Currently, the TT_budget / WinTV_Nova cards have two ICs
584 **      (74HCT4040, LVC74) for the generation of this VSYNC signal,
585 **      which seems that can be done perfectly without this :-)).
586 */
587
588 /*      New design (By Emard)
589 **      this rps1 code will copy internal HS event to GPIO3 pin.
590 **      GPIO3 is in budget-patch hardware connectd to port B VSYNC
591
592 **      HS is an internal event of 7146, accessible with RPS
593 **      and temporarily raised high every n lines
594 **      (n in defined in the RPS_THRESH1 counter threshold)
595 **      I think HS is raised high on the beginning of the n-th line
596 **      and remains high until this n-th line that triggered
597 **      it is completely received. When the receiption of n-th line
598 **      ends, HS is lowered.
599
600 **      To transmit data over DMA, 7146 needs changing state at
601 **      port B VSYNC pin. Any changing of port B VSYNC will
602 **      cause some DMA data transfer, with more or less packets loss.
603 **      It depends on the phase and frequency of VSYNC and
604 **      the way of 7146 is instructed to trigger on port B (defined
605 **      in DD1_INIT register, 3rd nibble from the right valid
606 **      numbers are 0-7, see datasheet)
607 **
608 **      The correct triggering can minimize packet loss,
609 **      dvbtraffic should give this stable bandwidths:
610 **        22k transponder = 33814 kbit/s
611 **      27.5k transponder = 38045 kbit/s
612 **      by experiment it is found that the best results
613 **      (stable bandwidths and almost no packet loss)
614 **      are obtained using DD1_INIT triggering number 2
615 **      (Va at rising edge of VS Fa = HS x VS-failing forced toggle)
616 **      and a VSYNC phase that occurs in the middle of DMA transfer
617 **      (about byte 188*512=96256 in the DMA window).
618 **
619 **      Phase of HS is still not clear to me how to control,
620 **      It just happens to be so. It can be seen if one enables
621 **      RPS_IRQ and print Event Counter 1 in vpeirq(). Every
622 **      time RPS_INTERRUPT is called, the Event Counter 1 will
623 **      increment. That's how the 7146 is programmed to do event
624 **      counting in this budget-patch.c
625 **      I *think* HPS setting has something to do with the phase
626 **      of HS but I cant be 100% sure in that.
627
628 **      hardware debug note: a working budget card (including budget patch)
629 **      with vpeirq() interrupt setup in mode "0x90" (every 64K) will
630 **      generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes
631 **      and that means 3*25=75 Hz of interrupt freqency, as seen by
632 **      watch cat /proc/interrupts
633 **
634 **      If this frequency is 3x lower (and data received in the DMA
635 **      buffer don't start with 0x47, but in the middle of packets,
636 **      whose lengths appear to be like 188 292 188 104 etc.
637 **      this means VSYNC line is not connected in the hardware.
638 **      (check soldering pcb and pins)
639 **      The same behaviour of missing VSYNC can be duplicated on budget
640 **      cards, by seting DD1_INIT trigger mode 7 in 3rd nibble.
641 */
642
643         // Setup RPS1 "program" (p35)
644         count = 0;
645
646
647         // Wait Source Line Counter Threshold                           (p36)
648         WRITE_RPS1(cpu_to_le32(CMD_PAUSE | EVT_HS));
649         // Set GPIO3=1                                                  (p42)
650         WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
651         WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
652         WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTHI<<24));
653 #if RPS_IRQ
654         // issue RPS1 interrupt
655         WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
656 #endif
657         // Wait reset Source Line Counter Threshold                     (p36)
658         WRITE_RPS1(cpu_to_le32(CMD_PAUSE | RPS_INV | EVT_HS));
659         // Set GPIO3=0                                                  (p42)
660         WRITE_RPS1(cpu_to_le32(CMD_WR_REG_MASK | (GPIO_CTRL>>2)));
661         WRITE_RPS1(cpu_to_le32(GPIO3_MSK));
662         WRITE_RPS1(cpu_to_le32(SAA7146_GPIO_OUTLO<<24));
663 #if RPS_IRQ
664         // issue RPS1 interrupt
665         WRITE_RPS1(cpu_to_le32(CMD_INTERRUPT));
666 #endif
667         // Jump to begin of RPS program                                 (p37)
668         WRITE_RPS1(cpu_to_le32(CMD_JUMP));
669         WRITE_RPS1(cpu_to_le32(dev->d_rps1.dma_handle));
670
671         // Fix VSYNC level
672         saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
673         // Set RPS1 Address register to point to RPS code               (r108 p42)
674         saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
675         // Set Source Line Counter Threshold, using BRS                 (rCC p43)
676         // It generates HS event every TS_HEIGHT lines
677         // this is related to TS_WIDTH set in register
678         // NUM_LINE_BYTE3 in budget-core.c. If NUM_LINE_BYTE
679         // low 16 bits are set to TS_WIDTH bytes (TS_WIDTH=2*188
680         //,then RPS_THRESH1
681         // should be set to trigger every TS_HEIGHT (512) lines.
682         //
683         saa7146_write(dev, RPS_THRESH1, (TS_HEIGHT*1) | MASK_12 );
684
685         // saa7146_write(dev, RPS_THRESH0, ((TS_HEIGHT/2)<<16) |MASK_28| (TS_HEIGHT/2) |MASK_12 );
686         // Enable RPS1                                                  (rFC p33)
687         saa7146_write(dev, MC1, (MASK_13 | MASK_29));
688
689
690         if (!(budget = kmalloc (sizeof(struct budget_patch), GFP_KERNEL)))
691                 return -ENOMEM;
692
693         dprintk(2, "budget: %p\n", budget);
694
695         if ((err = ttpci_budget_init (budget, dev, info, THIS_MODULE))) {
696                 kfree (budget);
697                 return err;
698         }
699
700
701         dev->ext_priv = budget;
702
703         budget->dvb_adapter.priv = budget;
704         frontend_init(budget);
705
706         return 0;
707 }
708
709 static int budget_patch_detach (struct saa7146_dev* dev)
710 {
711         struct budget_patch *budget = (struct budget_patch*) dev->ext_priv;
712         int err;
713
714         if (budget->dvb_frontend) dvb_unregister_frontend(budget->dvb_frontend);
715
716         err = ttpci_budget_deinit (budget);
717
718         kfree (budget);
719
720         return err;
721 }
722
723 static int __init budget_patch_init(void)
724 {
725         return saa7146_register_extension(&budget_extension);
726 }
727
728 static void __exit budget_patch_exit(void)
729 {
730         saa7146_unregister_extension(&budget_extension);
731 }
732
733 static struct saa7146_extension budget_extension = {
734         .name           = "budget_patch dvb\0",
735         .flags          = 0,
736
737         .module         = THIS_MODULE,
738         .pci_tbl        = pci_tbl,
739         .attach         = budget_patch_attach,
740         .detach         = budget_patch_detach,
741
742         .irq_mask       = MASK_10,
743         .irq_func       = ttpci_budget_irq10_handler,
744 };
745
746 module_init(budget_patch_init);
747 module_exit(budget_patch_exit);
748
749 MODULE_LICENSE("GPL");
750 MODULE_AUTHOR("Emard, Roberto Deza, Holger Waechtler, Michael Hunold, others");
751 MODULE_DESCRIPTION("Driver for full TS modified DVB-S SAA7146+AV7110 "
752                    "based so-called Budget Patch cards");