1 /* TODO: clean up/fix CC code */
3 #ifdef HAVE_XORG_CONFIG_H
4 #include <xorg-config.h>
16 /* Changing the following settings (especially VCROP) may */
17 /* require modifying code that calls this driver. */
18 #define HCROP 0 /* amount to crop from the left and right edges */
19 #define VCROP 0 /* amount to crop from the top and bottom edges */
21 #define BTVERSION (bt->id>>4)
23 #define H(X) ( ((X)>>8) & 0xFF )
24 #define L(X) ( (X) & 0xFF )
26 #define LIMIT(X,A,B) (((X)<(A)) ? (A) : ((X)>(B)) ? (B) : (X) )
28 /* Bt829 family chip ID's */
36 #define STATUS 0x00 /* Device Status */
37 #define IFORM 0x01 /* Input Format */
38 #define TDEC 0x02 /* Temporal Decimation */
39 #define CROP 0x03 /* MSB Cropping */
40 #define VDELAY_LO 0x04 /* Vertical Delay */
41 #define VACTIVE_LO 0x05 /* Vertical Active */
42 #define HDELAY_LO 0x06 /* Horizontal Delay */
43 #define HACTIVE_LO 0x07 /* Horizontal Active */
44 #define HSCALE_HI 0x08 /* Horizontal Scaling */
45 #define HSCALE_LO 0x09 /* Horizontal Scaling */
46 #define BRIGHT 0x0A /* Brightness Control */
47 #define CONTROL 0x0B /* Miscellaneous Control */
48 #define CONTRAST_LO 0x0C /* Luma Gain (Contrast) */
49 #define SAT_U_LO 0x0D /* Chroma (U) Gain (Saturation) */
50 #define SAT_V_LO 0x0E /* Chroma (V) Gain (Saturation) */
51 #define HUE 0x0F /* Hue Control */
52 #define SCLOOP 0x10 /* SC Loop Control */
53 #define WC_UP 0x11 /* White Crush Up Count */
54 #define OFORM 0x12 /* Output Format */
55 #define VSCALE_HI 0x13 /* Vertical Scaling */
56 #define VSCALE_LO 0x14 /* Vertical Scaling */
57 #define TEST 0x15 /* Test Control */
58 #define VPOLE 0x16 /* Video Timing Polarity */
59 #define IDCODE 0x17 /* ID Code */
60 #define ADELAY 0x18 /* AGC Delay */
61 #define BDELAY 0x19 /* Burst Gate Delay */
62 #define ADC 0x1A /* ADC Interface */
63 #define VTC 0x1B /* Video Timing Control */
64 #define CC_STATUS 0x1C /* Extended Data Services/Closed Capt Status */
65 #define CC_DATA 0x1D /* Extended Data Services/Closed Capt Data */
66 #define WC_DN 0x1E /* White Crush Down Count */
67 #define SRESET 0x1F /* Software Reset */
68 #define P_IO 0x3F /* Programmable I/O */
70 static CARD8
btread(BT829Ptr bt
, CARD8 reg
)
74 I2C_WriteRead(&(bt
->d
), ®
, 1, &v
, 1);
79 static void btwrite(BT829Ptr bt
, CARD8 reg
, CARD8 val
)
85 I2C_WriteRead(&(bt
->d
), data
, 2, NULL
, 0);
91 static void btwrite_status(BT829Ptr bt
) /* STATUS */
93 btwrite(bt
, STATUS
, 0x00); /* clear */
96 static void btwrite_iform(BT829Ptr bt
) /* IFORM */
100 switch (bt
->format
) {
102 case BT829_NTSC_JAPAN
:
104 case BT829_PAL_N_COMB
: /* gatos says xtsel = 2 */
112 default: /* shouldn't get here */
113 xtsel
= 3; /* hardware default */
117 btwrite(bt
, IFORM
, (bt
->mux
<<5) | (xtsel
<<3) | bt
->format
);
120 static void btwrite_tdec(BT829Ptr bt
) /* TDEC */
125 static void btwrite_crop(BT829Ptr bt
) /* CROP */
127 btwrite(bt
, CROP
, (H(bt
->vdelay
)<<6) | (H(bt
->vactive
)<<4) |
128 (H(bt
->hdelay
)<<2) | H(bt
->width
));
131 static void btwrite_vdelay_lo(BT829Ptr bt
) /* VDELAY_LO */
133 btwrite(bt
, VDELAY_LO
, L(bt
->vdelay
));
136 static void btwrite_vactive_lo(BT829Ptr bt
) /* VACTIVE_LO */
138 btwrite(bt
, VACTIVE_LO
, L(bt
->vactive
));
141 static void btwrite_hdelay_lo(BT829Ptr bt
) /* HDELAY_LO */
143 btwrite(bt
, HDELAY_LO
, L(bt
->hdelay
));
146 static void btwrite_hactive_lo(BT829Ptr bt
) /* HACTIVE_LO */
148 btwrite(bt
, HACTIVE_LO
, L(bt
->width
));
151 static void btwrite_hscale_hi(BT829Ptr bt
) /* HSCALE_HI */
153 btwrite(bt
, HSCALE_HI
, H(bt
->hscale
));
156 static void btwrite_hscale_lo(BT829Ptr bt
) /* HSCALE_LO */
158 btwrite(bt
, HSCALE_LO
, L(bt
->hscale
));
161 static void btwrite_bright(BT829Ptr bt
) /* BRIGHT */
163 btwrite(bt
, BRIGHT
, bt
->brightness
);
166 static void btwrite_control(BT829Ptr bt
) /* CONTROL */
170 /* The data sheet says ldec should always be 0 for SECAM */
171 /* but the picture quality is better with ldec = 1 */
172 ldec
= (bt
->width
> 360); /* gatos says 384 */
175 ((bt
->mux
==bt
->svideo_mux
) ? 0xC0:0x00) | /* LNOTCH and COMP */
176 (ldec
<<5) | (H(bt
->contrast
)<<2) | (H(bt
->sat_u
)<<1) | H(bt
->sat_v
));
179 static void btwrite_contrast_lo(BT829Ptr bt
) /* CONTRAST_LO */
181 btwrite(bt
, CONTRAST_LO
, L(bt
->contrast
));
184 static void btwrite_sat_u_lo(BT829Ptr bt
) /* SAT_U_LO */
186 btwrite(bt
, SAT_U_LO
, L(bt
->sat_u
));
189 static void btwrite_sat_v_lo(BT829Ptr bt
) /* SAT_V_LO */
191 btwrite(bt
, SAT_V_LO
, L(bt
->sat_v
));
194 static void btwrite_hue(BT829Ptr bt
) /* HUE */
196 btwrite(bt
, HUE
, bt
->hue
);
199 static void btwrite_scloop(BT829Ptr bt
) /* SCLOOP */
201 if (BTVERSION
>= BT827
) {
203 (bt
->format
==BT829_SECAM
) ? 0x10:0x00 /* QCIF or AUTO */
208 static void btwrite_wc_up(BT829Ptr bt
) /* WC_UP */
210 if (BTVERSION
>= BT827
) {
215 static void btwrite_oform(BT829Ptr bt
) /* OFORM */
217 btwrite(bt
, OFORM
, (bt
->code
<<3) | (bt
->len
<<2) |
218 0x02 /* RANGE = 0, CORE = 0, VBI_FRAME = 0, OES = 2 (default) */
222 static void btwrite_vscale_hi(BT829Ptr bt
) /* VSCALE_HI */
224 btwrite(bt
, VSCALE_HI
, H(bt
->vscale
) |
225 0x60 /* YCOMB = 0, COMB = 1, INT = 1 (default) */
229 static void btwrite_vscale_lo(BT829Ptr bt
) /* VSCALE_LO */
231 btwrite(bt
, VSCALE_LO
, L(bt
->vscale
));
234 /* TEST should not be written to */
236 static void btwrite_vpole(BT829Ptr bt
) /* VPOLE */
238 btwrite(bt
, VPOLE
, (bt
->out_en
<<7));
241 /* IDCODE is read only */
243 static void btwrite_adelay(BT829Ptr bt
) /* ADELAY */
245 switch (bt
->format
) {
247 case BT829_NTSC_JAPAN
:
249 btwrite(bt
, ADELAY
, 104);
254 case BT829_PAL_N_COMB
:
255 btwrite(bt
, ADELAY
, 127);
257 default: /* shouldn't get here */
258 btwrite(bt
, ADELAY
, 104); /* hardware default */
263 static void btwrite_bdelay(BT829Ptr bt
) /* BDELAY */
265 switch (bt
->format
) {
267 case BT829_NTSC_JAPAN
:
269 btwrite(bt
, BDELAY
, 93);
273 case BT829_PAL_N_COMB
:
274 btwrite(bt
, BDELAY
, 114);
277 btwrite(bt
, BDELAY
, 160);
279 default: /* shouldn't get here */
280 btwrite(bt
, BDELAY
, 93); /* hardware default */
285 static void btwrite_adc(BT829Ptr bt
) /* ADC */
287 btwrite(bt
, ADC
, bt
->mux
==bt
->svideo_mux
? 0x80:0x82); /* CSLEEP = 0 or 1 */
290 static void btwrite_vtc(BT829Ptr bt
) /* VTC */
292 int vfilt
= 0; /* hardware default */
294 if (BTVERSION
> BT827
) { /* gatos says >= BT827 */
295 switch (bt
->format
) {
297 case BT829_NTSC_JAPAN
:
299 case BT829_PAL_N_COMB
: /* gatos groups with BT829_PAL */
300 if (bt
->width
<= 360) vfilt
= 1; /* gatos says <= 240 */
301 if (bt
->width
<= 180) vfilt
= 2; /* gatos says <= 120 */
302 if (bt
->width
<= 90) vfilt
= 3; /* gatos says <= 60 */
307 if (bt
->width
<= 384) vfilt
= 1;
308 if (bt
->width
<= 192) vfilt
= 2;
309 if (bt
->width
<= 96) vfilt
= 3;
311 default: /* shouldn't get here */
312 break; /* use hardware default */
314 btwrite(bt
, VTC
, (bt
->vbien
<<4) | (bt
->vbifmt
<<3) | vfilt
);
318 static void btwrite_cc_status(BT829Ptr bt
) /* CC_STATUS */
319 { /* FIXME: ATI specific */
320 if (BTVERSION
>= BT827
) {
321 if (bt
->ccmode
== 0) btwrite(bt
, CC_STATUS
, 0x00);
322 /* 0x40 is activate to set the CCVALID line. Not required yet */
323 else btwrite(bt
, CC_STATUS
, (bt
->ccmode
<<4) | 0x40);
327 /* CC_DATA is read only */
329 static void btwrite_wc_dn(BT829Ptr bt
) /* WC_DN */
331 if (BTVERSION
>= BT827
) {
336 static void bt_reset(BT829Ptr bt
) { /* SRESET */
337 btwrite(bt
, SRESET
, 0x0); /* Reset all registers */
340 static void btwrite_p_io(BT829Ptr bt
) /* P_IO */
342 if (BTVERSION
>= BT827
) {
343 btwrite(bt
, P_IO
, bt
->p_io
);
348 * Deal with dependencies
350 static void propagate_changes(BT829Ptr bt
)
352 CARD16 hdelay
, unscaled_hdelay
, vdelay
, hscale
, vscale
;
355 switch (bt
->format
) {
357 case BT829_NTSC_JAPAN
:
362 unscaled_hdelay
= 135;
366 vdelay
= (bt
->tunertype
==5) ? 34 : 22;
369 unscaled_hdelay
= 186;
375 unscaled_hdelay
= 186;
377 case BT829_PAL_N_COMB
:
378 vdelay
= (bt
->tunertype
==5) ? 34 : 22; /* windows says 22 */
379 htotal
= 754; /* gatos and windows say 922 */
381 unscaled_hdelay
= 135; /* gatos and windows say 186 */
383 default: /* shouldn't get here */
384 vdelay
= 22; /* hardware default */
386 vactive
= 480; /* hardware default */
387 unscaled_hdelay
= 135;
391 bt
->htotal
= htotal
; /* Used for error checking in bt829_SetCaptSize */
393 hscale
= 4096 * htotal
/ (bt
->width
+ 2 * HCROP
)-4096;
395 HCROP
+ (bt
->width
+ 2 * HCROP
) * unscaled_hdelay
/ htotal
398 vactive
= vactive
- 2 * VCROP
;
399 vdelay
= vdelay
+ VCROP
;
400 vscale
= (0x10000 - (512*vactive
/bt
->height
-512)) & 0x1FFF;
402 if ((hdelay
!= bt
->hdelay
) || (vdelay
!= bt
->vdelay
) ||
403 (vactive
!= bt
->vactive
) || (hscale
!= bt
->hscale
) ||
404 (vscale
!= bt
->vscale
)) {
407 bt
->vactive
= vactive
;
411 btwrite_vdelay_lo(bt
);
412 btwrite_vactive_lo(bt
);
413 btwrite_hdelay_lo(bt
);
414 btwrite_hscale_hi(bt
);
415 btwrite_hscale_lo(bt
);
417 btwrite_vscale_hi(bt
);
418 btwrite_vscale_lo(bt
);
422 static void write_all(BT829Ptr bt
)
425 propagate_changes(bt
); /* ensure consistency */
429 btwrite_vdelay_lo(bt
);
430 btwrite_vactive_lo(bt
);
431 btwrite_hdelay_lo(bt
);
432 btwrite_hactive_lo(bt
);
433 btwrite_hscale_hi(bt
);
434 btwrite_hscale_lo(bt
);
437 btwrite_contrast_lo(bt
);
438 btwrite_sat_u_lo(bt
);
439 btwrite_sat_v_lo(bt
);
444 btwrite_vscale_hi(bt
);
445 btwrite_vscale_lo(bt
);
451 /* btwrite_cc_status(bt); */ /* FIXME: CC code needs cleaning */
459 BT829Ptr
bt829_Detect(I2CBusPtr b
, I2CSlaveAddr addr
)
464 bt
= xcalloc(1, sizeof(BT829Rec
));
465 if(bt
== NULL
) return NULL
;
466 bt
->d
.DevName
= strdup("BT829 video decoder");
467 bt
->d
.SlaveAddr
= addr
;
469 bt
->d
.NextDev
= NULL
;
470 bt
->d
.StartTimeout
= b
->StartTimeout
;
471 bt
->d
.BitTimeout
= b
->BitTimeout
;
472 bt
->d
.AcknTimeout
= b
->AcknTimeout
;
473 bt
->d
.ByteTimeout
= b
->ByteTimeout
;
476 if(!I2C_WriteRead(&(bt
->d
), NULL
, 0, &a
, 1))
482 bt
->id
= btread(bt
,IDCODE
);
485 bt
->d
.DevName
= xcalloc(200, sizeof(char));
488 sprintf(bt
->d
.DevName
, "bt815a video decoder, revision %d",bt
->id
& 0xf);
491 sprintf(bt
->d
.DevName
, "bt817a video decoder, revision %d",bt
->id
& 0xf);
494 sprintf(bt
->d
.DevName
, "bt819a video decoder, revision %d",bt
->id
& 0xf);
497 sprintf(bt
->d
.DevName
, "bt827a/b video decoder, revision %d",bt
->id
& 0xf);
500 sprintf(bt
->d
.DevName
, "bt829a/b video decoder, revision %d",bt
->id
& 0xf);
503 sprintf(bt
->d
.DevName
, "bt8xx/unknown video decoder version %d, revision %d",bt
->id
>> 4,bt
->id
& 0xf);
507 /* set default parameters */
508 if(!I2CDevInit(&(bt
->d
)))
516 bt
->brightness
= 0; /* hardware default */
518 bt
->code
= 0; /* hardware default */
519 bt
->contrast
= 216; /* hardware default */
520 bt
->format
= BT829_NTSC
;
521 bt
->height
= 480; /* hardware default for vactive */
522 bt
->hue
= 0; /* hardware default */
523 bt
->len
= 1; /* hardware default */
524 bt
->mux
= BT829_MUX0
; /* hardware default */
525 bt
->out_en
= 0; /* hardware default */
526 bt
->p_io
= 0; /* hardware default */
527 bt
->sat_u
= 254; /* hardware default */
528 bt
->sat_v
= 180; /* hardware default */
529 bt
->vbien
= 0; /* hardware default */
530 bt
->vbifmt
= 0; /* hardware default */
531 bt
->width
= 640; /* hardware default for hactive */
533 bt
->hdelay
= 120; /* hardware default */
534 bt
->hscale
= 684; /* hardware default */
535 bt
->vactive
= 480; /* hardware default */
536 bt
->vdelay
= 22; /* hardware default */
537 bt
->vscale
= 0; /* hardware default */
539 bt
->htotal
= 754; /* NTSC */
540 bt
->svideo_mux
= 0; /* no s-video */
545 int bt829_ATIInit(BT829Ptr bt
)
551 bt
->svideo_mux
= BT829_MUX1
;
558 int bt829_SetFormat(BT829Ptr bt
, CARD8 format
)
560 if ((format
< 1) || (format
> 7)) return -1;
561 if ((BTVERSION
<= BT819
) &&
562 (format
!= BT829_NTSC
) && (format
!= BT829_PAL
)) return -1;
563 if (format
== bt
->format
) return 0;
565 propagate_changes(bt
);
574 int bt829_SetMux(BT829Ptr bt
, CARD8 mux
)
576 if ((mux
< 1) || (mux
> 3)) return -1;
577 if (mux
== bt
->mux
) return 0;
579 /* propagate_changes(bt); */ /* no dependencies */
586 void bt829_SetBrightness(BT829Ptr bt
, int brightness
)
588 brightness
= LIMIT(brightness
,-1000,999); /* ensure -128 <= brightness <= 127 below */
589 brightness
= (128*brightness
)/1000;
590 if (brightness
== bt
->brightness
) return;
591 bt
->brightness
= brightness
;
592 /* propagate_changes(bt); */ /* no dependencies */
596 void bt829_SetContrast(BT829Ptr bt
, int contrast
)
598 contrast
= LIMIT(contrast
,-1000,1000);
599 contrast
= (216*(contrast
+1000))/1000;
600 if (contrast
== bt
->contrast
) return;
601 bt
->contrast
= contrast
;
602 /* propagate_changes(bt); */ /* no dependencies */
604 btwrite_contrast_lo(bt
);
607 void bt829_SetSaturation(BT829Ptr bt
, int saturation
)
611 saturation
= LIMIT(saturation
,-1000,1000);
612 sat_u
= (254*(saturation
+1000))/1000;
613 sat_v
= (180*(saturation
+1000))/1000;
614 if ((sat_u
== bt
->sat_u
) && (sat_v
== bt
->sat_v
)) return;
617 /* propagate_changes(bt); */ /* no dependencies */
619 btwrite_sat_u_lo(bt
);
620 btwrite_sat_v_lo(bt
);
623 void bt829_SetTint(BT829Ptr bt
, int hue
)
625 hue
= LIMIT(hue
,-1000,999); /* ensure -128 <= hue <= 127 below */
626 hue
= (128*hue
)/1000;
627 if (hue
== bt
->hue
) return;
629 /* propagate_changes(bt); */ /* no dependencies */
633 int bt829_SetCaptSize(BT829Ptr bt
, int width
, int height
)
635 if ((width
> bt
->htotal
- 2 * HCROP
) ||
636 (16 * width
< bt
->htotal
- 32 * HCROP
)) return -1;
637 if ((height
> bt
->vactive
) || (16 * height
< bt
->vactive
)) return -1;
638 if ((width
== bt
->width
) && (height
== bt
->height
)) return 0;
641 propagate_changes(bt
);
643 btwrite_hactive_lo(bt
);
649 int bt829_SetCC(BT829Ptr bt
) /* FIXME: should take ccmode as a parameter */
651 if (BTVERSION
< BT827
) return -1; /* can't do it */
652 /* propagate_changes(bt); */ /* no dependencies */
653 btwrite_cc_status(bt
);
654 /* we write to STATUS to reset the CCVALID flag */
655 if (bt
->ccmode
!= 0) btwrite_status(bt
);
659 void bt829_SetOUT_EN(BT829Ptr bt
, BOOL out_en
)
661 out_en
= (out_en
!= 0);
662 if (out_en
== bt
->out_en
) return;
664 /* propagate_changes(bt); */ /* no dependencies */
668 void bt829_SetP_IO(BT829Ptr bt
, CARD8 p_io
)
670 if (p_io
== bt
->p_io
) return;
672 /* propagate_changes(bt); */ /* no dependencies */
676 #define BTREAD(R) btread(bt,(R))
680 void bt829_getCCdata(BT829Ptr bt
,struct CCdata
*data
)
684 /* wait for buffer to be half full (means 8/16 bytes)
685 * either 4 (one of CC/EDS) or 2 (both CC/EDS) frames */
686 if(!(BTREAD(STATUS
)&0x04)) return; /* could comment this line */
687 for(;data
->num_valid
<CC_FIFO_SIZE
;data
->num_valid
++) {
688 status
=BTREAD(CC_STATUS
);
689 if(!(status
&0x04)) break;
690 data
->data
[data
->num_valid
]= BTREAD(CC_DATA
)&0x7f;
691 /* stripped high bit (parity) */
692 data
->status
[data
->num_valid
]= (CCS_EDS
*((status
&0x02)>>1)) |
693 (CCS_HIGH
*(status
&0x01)) |
694 (CCS_OVER
*((status
&0x08)>>3)) |
695 (CCS_PAR
*((status
&0x80)>>7)) ; }
696 btwrite(bt
,STATUS
,0x00); /* Reset CCVALID status bit */
702 /* ------------------------------------------------------------------------ */
703 /* Debug and report routines */
705 #define DUMPREG(REG) \
706 xf86DrvMsg(bt->d.pI2CBus->scrnIndex,X_INFO," %-12s (0x%02X) = 0x%02X\n", \
707 #REG,REG,BTREAD(REG))
709 /*static void bt829_dumpregs(BT829Ptr bt)
723 DUMPREG(CONTRAST_LO);
727 if (BTVERSION >= BT827) {
739 if (BTVERSION >= BT827) {