1/* TODO: clean up/fix CC code */
2
3#ifdef HAVE_XORG_CONFIG_H
4#include <xorg-config.h>
5#endif
6
7#include <stdlib.h>
8#include <string.h>
9#include <stdio.h>
10
11#include "xf86.h"
12#include "xf86i2c.h"
13#include "bt829.h"
14#include "i2c_def.h"
15
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 */
20
21#define BTVERSION	(bt->id>>4)
22
23#define H(X)		( ((X)>>8) & 0xFF )
24#define L(X)		( (X) & 0xFF )
25
26#define LIMIT(X,A,B)	(((X)<(A)) ? (A) : ((X)>(B)) ? (B) : (X) )
27
28/* Bt829 family chip ID's */
29#define BT815	0x02
30#define BT817	0x06
31#define BT819	0x07
32#define BT827	0x0C
33#define BT829	0x0E
34
35/* Bt829 registers */
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 */
69
70static CARD8 btread(BT829Ptr bt, CARD8 reg)
71{
72  CARD8 v;
73
74  I2C_WriteRead(&(bt->d), &reg, 1, &v, 1);
75
76  return v;
77}
78
79static void btwrite(BT829Ptr bt, CARD8 reg, CARD8 val)
80{
81  CARD8 data[2];
82
83  data[0] = reg;
84  data[1] = val;
85  I2C_WriteRead(&(bt->d), data, 2, NULL, 0);
86}
87
88/*
89 * Register access
90 */
91static void btwrite_status(BT829Ptr bt) /* STATUS */
92{
93  btwrite(bt, STATUS, 0x00); /* clear */
94}
95
96static void btwrite_iform(BT829Ptr bt) /* IFORM */
97{
98  int xtsel;
99
100  switch (bt->format) {
101    case BT829_NTSC:
102    case BT829_NTSC_JAPAN:
103    case BT829_PAL_M:
104    case BT829_PAL_N_COMB: /* gatos says xtsel = 2 */
105      xtsel = 1;
106      break;
107    case BT829_PAL:
108    case BT829_PAL_N:
109    case BT829_SECAM:
110      xtsel = 2;
111      break;
112    default: /* shouldn't get here */
113      xtsel = 3; /* hardware default */
114      break;
115  }
116
117  btwrite(bt, IFORM, (bt->mux<<5) | (xtsel<<3) | bt->format);
118}
119
120static void btwrite_tdec(BT829Ptr bt) /* TDEC */
121{
122  /* use default */
123}
124
125static void btwrite_crop(BT829Ptr bt) /* CROP */
126{
127  btwrite(bt, CROP, (H(bt->vdelay)<<6) | (H(bt->vactive)<<4) |
128    (H(bt->hdelay)<<2) | H(bt->width));
129}
130
131static void btwrite_vdelay_lo(BT829Ptr bt) /* VDELAY_LO */
132{
133  btwrite(bt, VDELAY_LO, L(bt->vdelay));
134}
135
136static void btwrite_vactive_lo(BT829Ptr bt) /* VACTIVE_LO */
137{
138  btwrite(bt, VACTIVE_LO, L(bt->vactive));
139}
140
141static void btwrite_hdelay_lo(BT829Ptr bt) /* HDELAY_LO */
142{
143  btwrite(bt, HDELAY_LO, L(bt->hdelay));
144}
145
146static void btwrite_hactive_lo(BT829Ptr bt) /* HACTIVE_LO */
147{
148  btwrite(bt, HACTIVE_LO, L(bt->width));
149}
150
151static void btwrite_hscale_hi(BT829Ptr bt) /* HSCALE_HI */
152{
153  btwrite(bt, HSCALE_HI, H(bt->hscale));
154}
155
156static void btwrite_hscale_lo(BT829Ptr bt) /* HSCALE_LO */
157{
158  btwrite(bt, HSCALE_LO, L(bt->hscale));
159}
160
161static void btwrite_bright(BT829Ptr bt) /* BRIGHT */
162{
163  btwrite(bt, BRIGHT, bt->brightness);
164}
165
166static void btwrite_control(BT829Ptr bt) /* CONTROL */
167{
168  int ldec;
169
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 */
173
174  btwrite(bt, CONTROL,
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));
177}
178
179static void btwrite_contrast_lo(BT829Ptr bt) /* CONTRAST_LO */
180{
181  btwrite(bt, CONTRAST_LO, L(bt->contrast));
182}
183
184static void btwrite_sat_u_lo(BT829Ptr bt) /* SAT_U_LO */
185{
186  btwrite(bt, SAT_U_LO, L(bt->sat_u));
187}
188
189static void btwrite_sat_v_lo(BT829Ptr bt) /* SAT_V_LO */
190{
191  btwrite(bt, SAT_V_LO, L(bt->sat_v));
192}
193
194static void btwrite_hue(BT829Ptr bt) /* HUE */
195{
196  btwrite(bt, HUE, bt->hue);
197}
198
199static void btwrite_scloop(BT829Ptr bt) /* SCLOOP */
200{
201  if (BTVERSION >= BT827) {
202    btwrite(bt, SCLOOP,
203      (bt->format==BT829_SECAM) ? 0x10:0x00 /* QCIF or AUTO */
204    );
205  }
206}
207
208static void btwrite_wc_up(BT829Ptr bt) /* WC_UP */
209{
210  if (BTVERSION >= BT827) {
211    /* use default */
212  }
213}
214
215static void btwrite_oform(BT829Ptr bt) /* OFORM */
216{
217  btwrite(bt, OFORM, (bt->code<<3) | (bt->len<<2) |
218    0x02 /* RANGE = 0, CORE = 0, VBI_FRAME = 0, OES = 2 (default) */
219  );
220}
221
222static void btwrite_vscale_hi(BT829Ptr bt) /* VSCALE_HI */
223{
224  btwrite(bt, VSCALE_HI, H(bt->vscale) |
225    0x60 /* YCOMB = 0, COMB = 1, INT = 1 (default) */
226  );
227}
228
229static void btwrite_vscale_lo(BT829Ptr bt) /* VSCALE_LO */
230{
231  btwrite(bt, VSCALE_LO, L(bt->vscale));
232}
233
234/* TEST should not be written to */
235
236static void btwrite_vpole(BT829Ptr bt) /* VPOLE */
237{
238  btwrite(bt, VPOLE, (bt->out_en<<7));
239}
240
241/* IDCODE is read only */
242
243static void btwrite_adelay(BT829Ptr bt) /* ADELAY */
244{
245  switch (bt->format) {
246    case BT829_NTSC:
247    case BT829_NTSC_JAPAN:
248    case BT829_PAL_M:
249      btwrite(bt, ADELAY, 104);
250      break;
251    case BT829_PAL:
252    case BT829_PAL_N:
253    case BT829_SECAM:
254    case BT829_PAL_N_COMB:
255      btwrite(bt, ADELAY, 127);
256      break;
257    default: /* shouldn't get here */
258      btwrite(bt, ADELAY, 104); /* hardware default */
259      break;
260  }
261}
262
263static void btwrite_bdelay(BT829Ptr bt) /* BDELAY */
264{
265  switch (bt->format) {
266    case BT829_NTSC:
267    case BT829_NTSC_JAPAN:
268    case BT829_PAL_M:
269      btwrite(bt, BDELAY, 93);
270      break;
271    case BT829_PAL:
272    case BT829_PAL_N:
273    case BT829_PAL_N_COMB:
274      btwrite(bt, BDELAY, 114);
275      break;
276    case BT829_SECAM:
277      btwrite(bt, BDELAY, 160);
278      break;
279    default: /* shouldn't get here */
280      btwrite(bt, BDELAY, 93); /* hardware default */
281      break;
282  }
283}
284
285static void btwrite_adc(BT829Ptr bt) /* ADC */
286{
287  btwrite(bt, ADC, bt->mux==bt->svideo_mux ? 0x80:0x82); /* CSLEEP = 0 or 1 */
288}
289
290static void btwrite_vtc(BT829Ptr bt) /* VTC */
291{
292  int vfilt = 0; /* hardware default */
293
294  if (BTVERSION > BT827) { /* gatos says >= BT827 */
295    switch (bt->format) {
296      case BT829_NTSC:
297      case BT829_NTSC_JAPAN:
298      case BT829_PAL_M:
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 */
303        break;
304      case BT829_PAL:
305      case BT829_PAL_N:
306      case BT829_SECAM:
307        if (bt->width <= 384) vfilt = 1;
308        if (bt->width <= 192) vfilt = 2;
309        if (bt->width<=  96) vfilt = 3;
310        break;
311      default: /* shouldn't get here */
312        break; /* use hardware default */
313    }
314    btwrite(bt, VTC, (bt->vbien<<4) | (bt->vbifmt<<3) | vfilt);
315  }
316}
317
318static 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);
324  }
325}
326
327/* CC_DATA is read only */
328
329static void btwrite_wc_dn(BT829Ptr bt) /* WC_DN */
330{
331  if (BTVERSION >= BT827) {
332    /* use default */
333  }
334}
335
336static void bt_reset(BT829Ptr bt) { /* SRESET */
337  btwrite(bt, SRESET, 0x0); /* Reset all registers */
338}
339
340static void btwrite_p_io(BT829Ptr bt) /* P_IO */
341{
342  if (BTVERSION >= BT827) {
343    btwrite(bt, P_IO, bt->p_io);
344  }
345}
346
347/*
348 * Deal with dependencies
349 */
350static void propagate_changes(BT829Ptr bt)
351{
352  CARD16 hdelay, unscaled_hdelay, vdelay, hscale, vscale;
353  int htotal, vactive;
354
355  switch (bt->format) {
356    case BT829_NTSC:
357    case BT829_NTSC_JAPAN:
358    case BT829_PAL_M:
359      vdelay = 22;
360      htotal = 754;
361      vactive = 480;
362      unscaled_hdelay = 135;
363      break;
364    case BT829_PAL:
365    case BT829_PAL_N:
366      vdelay = (bt->tunertype==5) ? 34 : 22;
367      htotal = 922;
368      vactive = 576;
369      unscaled_hdelay = 186;
370      break;
371    case BT829_SECAM:
372      vdelay = 34;
373      htotal = 922;
374      vactive = 576;
375      unscaled_hdelay = 186;
376      break;
377    case BT829_PAL_N_COMB:
378      vdelay = (bt->tunertype==5) ? 34 : 22; /* windows says 22 */
379      htotal = 754; /* gatos and windows say 922 */
380      vactive = 576;
381      unscaled_hdelay = 135; /* gatos and windows say 186 */
382      break;
383    default: /* shouldn't get here */
384      vdelay = 22; /* hardware default */
385      htotal = 754;
386      vactive = 480; /* hardware default */
387      unscaled_hdelay = 135;
388      break;
389  }
390
391  bt->htotal = htotal; /* Used for error checking in bt829_SetCaptSize */
392
393  hscale = 4096 * htotal / (bt->width + 2 * HCROP)-4096;
394  hdelay = (
395    HCROP + (bt->width + 2 * HCROP) * unscaled_hdelay / htotal
396  ) & 0x3FE;
397
398  vactive = vactive - 2 * VCROP;
399  vdelay = vdelay + VCROP;
400  vscale = (0x10000 - (512*vactive/bt->height-512)) & 0x1FFF;
401
402  if ((hdelay  != bt->hdelay)  || (vdelay != bt->vdelay) ||
403      (vactive != bt->vactive) || (hscale != bt->hscale) ||
404      (vscale  != bt->vscale)) {
405    bt->hdelay = hdelay;
406    bt->vdelay = vdelay;
407    bt->vactive = vactive;
408    bt->hscale = hscale;
409    bt->vscale = vscale;
410    btwrite_crop(bt);
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);
416    btwrite_control(bt);
417    btwrite_vscale_hi(bt);
418    btwrite_vscale_lo(bt);
419  }
420}
421
422static void write_all(BT829Ptr bt)
423{
424  bt_reset(bt);
425  propagate_changes(bt); /* ensure consistency */
426  btwrite_iform(bt);
427  btwrite_tdec(bt);
428  btwrite_crop(bt);
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);
435  btwrite_bright(bt);
436  btwrite_control(bt);
437  btwrite_contrast_lo(bt);
438  btwrite_sat_u_lo(bt);
439  btwrite_sat_v_lo(bt);
440  btwrite_hue(bt);
441  btwrite_scloop(bt);
442  btwrite_wc_up(bt);
443  btwrite_oform(bt);
444  btwrite_vscale_hi(bt);
445  btwrite_vscale_lo(bt);
446  btwrite_vpole(bt);
447  btwrite_adelay(bt);
448  btwrite_bdelay(bt);
449  btwrite_adc(bt);
450  btwrite_vtc(bt);
451/*  btwrite_cc_status(bt); */ /* FIXME: CC code needs cleaning */
452  btwrite_wc_dn(bt);
453  btwrite_p_io(bt);
454}
455
456/*
457 * Public functions
458 */
459BT829Ptr bt829_Detect(I2CBusPtr b, I2CSlaveAddr addr)
460{
461  BT829Ptr bt;
462  I2CByte a;
463
464  bt = calloc(1, sizeof(BT829Rec));
465  if(bt == NULL) return NULL;
466  bt->d.DevName = strdup("BT829 video decoder");
467  bt->d.SlaveAddr = addr;
468  bt->d.pI2CBus = b;
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;
474
475
476  if(!I2C_WriteRead(&(bt->d), NULL, 0, &a, 1))
477  {
478     free(bt);
479     return NULL;
480  }
481
482  bt->id = btread(bt,IDCODE);
483
484  free(bt->d.DevName);
485  bt->d.DevName = calloc(200, sizeof(char));
486  switch(BTVERSION){
487  	case BT815:
488		sprintf(bt->d.DevName, "bt815a video decoder, revision %d",bt->id & 0xf);
489		break;
490	case BT817:
491		sprintf(bt->d.DevName, "bt817a video decoder, revision %d",bt->id & 0xf);
492  		break;
493	case BT819:
494		sprintf(bt->d.DevName, "bt819a video decoder, revision %d",bt->id & 0xf);
495  		break;
496	case BT827:
497		sprintf(bt->d.DevName, "bt827a/b video decoder, revision %d",bt->id & 0xf);
498  		break;
499	case BT829:
500		sprintf(bt->d.DevName, "bt829a/b video decoder, revision %d",bt->id & 0xf);
501  		break;
502	default:
503		sprintf(bt->d.DevName, "bt8xx/unknown video decoder version %d, revision %d",bt->id >> 4,bt->id & 0xf);
504  		break;
505	}
506
507  /* set default parameters */
508  if(!I2CDevInit(&(bt->d)))
509  {
510     free(bt);
511     return NULL;
512  }
513
514  bt->tunertype = 1;
515
516  bt->brightness = 0; /* hardware default */
517  bt->ccmode = 0;
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 */
532
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 */
538
539  bt->htotal = 754; /* NTSC */
540  bt->svideo_mux = 0; /* no s-video */
541
542  return bt;
543}
544
545int bt829_ATIInit(BT829Ptr bt)
546{
547  bt->code = 1;
548  bt->len = 0;
549  bt->vbien = 1;
550  bt->vbifmt = 1;
551  bt->svideo_mux = BT829_MUX1;
552
553  write_all (bt);
554
555  return 0;
556}
557
558int bt829_SetFormat(BT829Ptr bt, CARD8 format)
559{
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;
564  bt->format = format;
565  propagate_changes(bt);
566  btwrite_iform(bt);
567  btwrite_scloop(bt);
568  btwrite_adelay(bt);
569  btwrite_bdelay(bt);
570  btwrite_vtc(bt);
571  return 0;
572}
573
574int bt829_SetMux(BT829Ptr bt, CARD8 mux)
575{
576  if ((mux < 1) || (mux > 3)) return -1;
577  if (mux == bt->mux) return 0;
578  bt->mux = mux;
579  /* propagate_changes(bt); */ /* no dependencies */
580  btwrite_iform(bt);
581  btwrite_control(bt);
582  btwrite_adc(bt);
583  return 0;
584}
585
586void bt829_SetBrightness(BT829Ptr bt, int brightness)
587{
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 */
593  btwrite_bright(bt);
594}
595
596void bt829_SetContrast(BT829Ptr bt, int contrast)
597{
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 */
603  btwrite_control(bt);
604  btwrite_contrast_lo(bt);
605}
606
607void bt829_SetSaturation(BT829Ptr bt, int saturation)
608{
609  CARD16 sat_u, sat_v;
610
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;
615  bt->sat_u = sat_u;
616  bt->sat_v = sat_v;
617  /* propagate_changes(bt); */ /* no dependencies */
618  btwrite_control(bt);
619  btwrite_sat_u_lo(bt);
620  btwrite_sat_v_lo(bt);
621}
622
623void bt829_SetTint(BT829Ptr bt, int hue)
624{
625  hue = LIMIT(hue,-1000,999); /* ensure -128 <= hue <= 127 below */
626  hue = (128*hue)/1000;
627  if (hue == bt->hue) return;
628  bt->hue = hue;
629  /* propagate_changes(bt); */ /* no dependencies */
630  btwrite_hue(bt);
631}
632
633int bt829_SetCaptSize(BT829Ptr bt, int width, int height)
634{
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;
639  bt->width = width;
640  bt->height = height;
641  propagate_changes(bt);
642  btwrite_crop(bt);
643  btwrite_hactive_lo(bt);
644  btwrite_control(bt);
645  btwrite_vtc(bt);
646  return 0;
647}
648
649int bt829_SetCC(BT829Ptr bt) /* FIXME: should take ccmode as a parameter */
650{
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);
656  return 0;
657}
658
659void bt829_SetOUT_EN(BT829Ptr bt, BOOL out_en)
660{
661  out_en = (out_en != 0);
662  if (out_en == bt->out_en) return;
663  bt->out_en = out_en;
664  /* propagate_changes(bt); */ /* no dependencies */
665  btwrite_vpole(bt);
666}
667
668void bt829_SetP_IO(BT829Ptr bt, CARD8 p_io)
669{
670  if (p_io == bt->p_io) return;
671  bt->p_io = p_io;
672  /* propagate_changes(bt); */ /* no dependencies */
673  btwrite_p_io(bt);
674}
675
676#define BTREAD(R)	btread(bt,(R))
677
678#if 0
679
680void bt829_getCCdata(BT829Ptr bt,struct CCdata *data)
681{
682  CARD8 status;
683  data->num_valid=0;
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 */
697  return;
698}
699
700#endif
701
702/* ------------------------------------------------------------------------ */
703/* Debug and report routines */
704
705#define DUMPREG(REG)   \
706  xf86DrvMsg(bt->d.pI2CBus->scrnIndex,X_INFO," %-12s (0x%02X) = 0x%02X\n", \
707              #REG,REG,BTREAD(REG))
708
709/*static void bt829_dumpregs(BT829Ptr bt)
710{
711  DUMPREG(STATUS);
712  DUMPREG(IFORM);
713  DUMPREG(TDEC);
714  DUMPREG(CROP);
715  DUMPREG(VDELAY_LO);
716  DUMPREG(VACTIVE_LO);
717  DUMPREG(HDELAY_LO);
718  DUMPREG(HACTIVE_LO);
719  DUMPREG(HSCALE_HI);
720  DUMPREG(HSCALE_LO);
721  DUMPREG(BRIGHT);
722  DUMPREG(CONTROL);
723  DUMPREG(CONTRAST_LO);
724  DUMPREG(SAT_U_LO);
725  DUMPREG(SAT_V_LO);
726  DUMPREG(HUE);
727  if (BTVERSION >= BT827) {
728    DUMPREG(SCLOOP);
729    DUMPREG(WC_UP) ; }
730  DUMPREG(OFORM);
731  DUMPREG(VSCALE_HI);
732  DUMPREG(VSCALE_LO);
733  DUMPREG(TEST);
734  DUMPREG(VPOLE);
735  DUMPREG(IDCODE);
736  DUMPREG(ADELAY);
737  DUMPREG(BDELAY);
738  DUMPREG(ADC);
739  if (BTVERSION >= BT827) {
740    DUMPREG(VTC);
741    DUMPREG(CC_STATUS);
742    DUMPREG(CC_DATA);
743    DUMPREG(WC_DN);
744    DUMPREG(P_IO) ; }
745}*/
746