Mercurial > mplayer.hg
annotate vidix/sis_vid.c @ 25284:e60a367eb80e
suppress silly messages when checktree is not called from the root of the tree
but nevertheless has no specific arguments to work with. it will traverse
the tree from there, but obviously cannot find our externals.
author | ivo |
---|---|
date | Wed, 05 Dec 2007 23:44:31 +0000 |
parents | 427075ffb413 |
children | 0d255d03016f |
rev | line source |
---|---|
23046
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
1 /* |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
2 * VIDIX driver for SiS chipsets. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
3 * Copyright (C) 2003 Jake Page, Sugar Media. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
4 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
5 * This file is part of MPlayer. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
6 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
7 * MPlayer is free software; you can redistribute it and/or modify |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
8 * it under the terms of the GNU General Public License as published by |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
9 * the Free Software Foundation; either version 2 of the License, or |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
10 * (at your option) any later version. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
11 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
12 * MPlayer is distributed in the hope that it will be useful, |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
15 * GNU General Public License for more details. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
16 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
17 * You should have received a copy of the GNU General Public License |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
18 * along with MPlayer; if not, write to the Free Software |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
20 * |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
21 * Based on SiS Xv driver |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
22 * Copyright 2002-2003 by Thomas Winischhofer, Vienna, Austria. |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
23 * 2003/10/08 integrated into mplayer/vidix architecture -- Alex Beregszaszi |
82216ef041e0
updated vidix files headers whenever it's possible to have a clear GPL statement
ben
parents:
22905
diff
changeset
|
24 */ |
22850 | 25 |
26 #include <errno.h> | |
27 #include <stdio.h> | |
28 #include <stdlib.h> | |
29 #include <string.h> | |
30 #include <inttypes.h> | |
31 #include <unistd.h> | |
32 | |
33 #include "vidix.h" | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
34 #include "vidixlib.h" |
22850 | 35 #include "fourcc.h" |
22901 | 36 #include "dha.h" |
22900
a9e111b88c4a
merged libdha and libvidix, moved all files from libdha to vidix directory
ben
parents:
22867
diff
changeset
|
37 #include "pci_ids.h" |
a9e111b88c4a
merged libdha and libvidix, moved all files from libdha to vidix directory
ben
parents:
22867
diff
changeset
|
38 #include "pci_names.h" |
22905 | 39 #include "config.h" |
22850 | 40 |
41 #include "sis_regs.h" | |
42 #include "sis_defs.h" | |
43 | |
44 | |
45 /** Random defines **/ | |
46 | |
47 #define WATCHDOG_DELAY 500000 /* Watchdog counter for retrace waiting */ | |
48 #define IMAGE_MIN_WIDTH 32 /* Min and max source image sizes */ | |
49 #define IMAGE_MIN_HEIGHT 24 | |
50 #define IMAGE_MAX_WIDTH 720 | |
51 #define IMAGE_MAX_HEIGHT 576 | |
52 #define IMAGE_MAX_WIDTH_M650 1920 | |
53 #define IMAGE_MAX_HEIGHT_M650 1080 | |
54 | |
55 #define OVERLAY_MIN_WIDTH 32 /* Minimum overlay sizes */ | |
56 #define OVERLAY_MIN_HEIGHT 24 | |
57 | |
58 #define DISPMODE_SINGLE1 0x1 /* TW: CRT1 only */ | |
59 #define DISPMODE_SINGLE2 0x2 /* TW: CRT2 only */ | |
60 #define DISPMODE_MIRROR 0x4 /* TW: CRT1 + CRT2 MIRROR */ | |
61 | |
62 #define VMODE_INTERLACED 0x1 | |
63 #define VMODE_DOUBLESCAN 0x2 | |
64 | |
65 typedef struct { | |
66 short x1, y1, x2, y2; | |
67 } BoxRec; | |
68 | |
69 typedef struct { | |
70 int pixelFormat; | |
71 | |
72 uint16_t pitch; | |
73 uint16_t origPitch; | |
74 | |
75 uint8_t keyOP; | |
76 uint16_t HUSF; | |
77 uint16_t VUSF; | |
78 uint8_t IntBit; | |
79 uint8_t wHPre; | |
80 | |
81 uint16_t srcW; | |
82 uint16_t srcH; | |
83 | |
84 BoxRec dstBox; | |
85 | |
86 uint32_t PSY; | |
87 uint32_t PSV; | |
88 uint32_t PSU; | |
89 uint8_t bobEnable; | |
90 | |
91 uint8_t contrastCtrl; | |
92 uint8_t contrastFactor; | |
93 | |
94 uint8_t lineBufSize; | |
95 | |
96 uint8_t(*VBlankActiveFunc) (); | |
97 | |
98 uint16_t SCREENheight; | |
99 | |
100 } SISOverlayRec, *SISOverlayPtr; | |
101 | |
102 | |
103 /** static variable definitions **/ | |
104 static int sis_probed = 0; | |
105 static pciinfo_t pci_info; | |
106 unsigned int sis_verbose = 0; | |
107 | |
108 static void *sis_mem_base; | |
109 /* static void *sis_reg_base; */ | |
110 unsigned short sis_iobase; | |
111 | |
112 unsigned int sis_vga_engine = UNKNOWN_VGA; | |
113 static unsigned int sis_displaymode = DISPMODE_SINGLE1; | |
114 static unsigned int sis_has_two_overlays = 0; | |
115 static unsigned int sis_bridge_is_slave = 0; | |
116 static unsigned int sis_shift_value = 1; | |
117 static unsigned int sis_vmode = 0; | |
118 unsigned int sis_vbflags = DISPTYPE_DISP1; | |
119 unsigned int sis_overlay_on_crt1 = 1; | |
22867 | 120 int sis_crt1_off = -1; |
22850 | 121 unsigned int sis_detected_crt2_devices; |
122 unsigned int sis_force_crt2_type = CRT2_DEFAULT; | |
22867 | 123 int sis_device_id = -1; |
22850 | 124 |
125 static int sis_format; | |
126 static int sis_Yoff = 0; | |
127 static int sis_Voff = 0; | |
128 static int sis_Uoff = 0; | |
129 static int sis_screen_width = 640; | |
130 static int sis_screen_height = 480; | |
131 | |
132 static int sis_frames[VID_PLAY_MAXFRAMES]; | |
133 | |
134 static vidix_grkey_t sis_grkey; | |
135 | |
136 static vidix_capability_t sis_cap = { | |
137 "SiS 300/310/325 Video Driver", | |
138 "Jake Page", | |
139 TYPE_OUTPUT, | |
140 {0, 0, 0, 0}, | |
141 2048, | |
142 2048, | |
143 4, | |
144 4, | |
145 -1, | |
146 FLAG_UPSCALER | FLAG_DOWNSCALER | FLAG_EQUALIZER, | |
147 VENDOR_SIS, | |
148 -1, | |
149 {0, 0, 0, 0} | |
150 }; | |
151 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
152 static vidix_video_eq_t sis_equal = { |
22850 | 153 VEQ_CAP_BRIGHTNESS | VEQ_CAP_CONTRAST, |
154 200, 0, 0, 0, 0, 0, 0, 0 | |
155 }; | |
156 | |
157 static unsigned short sis_card_ids[] = { | |
158 DEVICE_SIS_300, | |
159 DEVICE_SIS_315H, | |
160 DEVICE_SIS_315, | |
161 DEVICE_SIS_315PRO, | |
162 DEVICE_SIS_330, | |
163 DEVICE_SIS_540_VGA, | |
164 DEVICE_SIS_550_VGA, | |
165 DEVICE_SIS_630_VGA, | |
166 DEVICE_SIS_650_VGA | |
167 }; | |
168 | |
169 /** function declarations **/ | |
170 | |
171 extern void sis_init_video_bridge(void); | |
172 | |
173 | |
174 static void set_overlay(SISOverlayPtr pOverlay, int index); | |
175 static void close_overlay(void); | |
176 static void calc_scale_factor(SISOverlayPtr pOverlay, | |
177 int index, int iscrt2); | |
178 static void set_line_buf_size(SISOverlayPtr pOverlay); | |
179 static void merge_line_buf(int enable); | |
180 static void set_format(SISOverlayPtr pOverlay); | |
181 static void set_colorkey(void); | |
182 | |
183 static void set_brightness(uint8_t brightness); | |
184 static void set_contrast(uint8_t contrast); | |
185 static void set_saturation(char saturation); | |
186 static void set_hue(uint8_t hue); | |
187 | |
188 /* IO Port access functions */ | |
189 static uint8_t getvideoreg(uint8_t reg) | |
190 { | |
191 uint8_t ret; | |
192 inSISIDXREG(SISVID, reg, ret); | |
193 return (ret); | |
194 } | |
195 | |
196 static void setvideoreg(uint8_t reg, uint8_t data) | |
197 { | |
198 outSISIDXREG(SISVID, reg, data); | |
199 } | |
200 | |
201 static void setvideoregmask(uint8_t reg, uint8_t data, uint8_t mask) | |
202 { | |
203 uint8_t old; | |
204 | |
205 inSISIDXREG(SISVID, reg, old); | |
206 data = (data & mask) | (old & (~mask)); | |
207 outSISIDXREG(SISVID, reg, data); | |
208 } | |
209 | |
210 static void setsrregmask(uint8_t reg, uint8_t data, uint8_t mask) | |
211 { | |
212 uint8_t old; | |
213 | |
214 inSISIDXREG(SISSR, reg, old); | |
215 data = (data & mask) | (old & (~mask)); | |
216 outSISIDXREG(SISSR, reg, data); | |
217 } | |
218 | |
219 /* vblank checking*/ | |
220 static uint8_t vblank_active_CRT1(void) | |
221 { | |
222 /* this may be too simplistic? */ | |
223 return (inSISREG(SISINPSTAT) & 0x08); | |
224 } | |
225 | |
226 static uint8_t vblank_active_CRT2(void) | |
227 { | |
228 uint8_t ret; | |
229 if (sis_vga_engine == SIS_315_VGA) { | |
230 inSISIDXREG(SISPART1, Index_310_CRT2_FC_VR, ret); | |
231 } else { | |
232 inSISIDXREG(SISPART1, Index_CRT2_FC_VR, ret); | |
233 } | |
234 return ((ret & 0x02) ^ 0x02); | |
235 } | |
236 | |
237 static int find_chip(unsigned chip_id) | |
238 { | |
239 unsigned i; | |
240 for (i = 0; i < sizeof(sis_card_ids) / sizeof(unsigned short); i++) { | |
241 if (chip_id == sis_card_ids[i]) | |
242 return i; | |
243 } | |
244 return -1; | |
245 } | |
246 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
247 static int sis_probe(int verbose, int force) |
22850 | 248 { |
249 pciinfo_t lst[MAX_PCI_DEVICES]; | |
250 unsigned i, num_pci; | |
251 int err; | |
252 | |
253 sis_verbose = verbose; | |
254 force = force; | |
255 err = pci_scan(lst, &num_pci); | |
256 if (err) { | |
257 printf("[SiS] Error occurred during pci scan: %s\n", strerror(err)); | |
258 return err; | |
259 } else { | |
260 err = ENXIO; | |
261 for (i = 0; i < num_pci; i++) { | |
262 if (lst[i].vendor == VENDOR_SIS) { | |
263 int idx; | |
264 const char *dname; | |
265 idx = find_chip(lst[i].device); | |
266 if (idx == -1) | |
267 continue; | |
268 dname = pci_device_name(VENDOR_SIS, lst[i].device); | |
269 dname = dname ? dname : "Unknown chip"; | |
270 if (sis_verbose > 0) | |
271 printf("[SiS] Found chip: %s (0x%X)\n", | |
272 dname, lst[i].device); | |
273 sis_device_id = sis_cap.device_id = lst[i].device; | |
274 err = 0; | |
275 memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); | |
276 | |
277 sis_has_two_overlays = 0; | |
278 switch (sis_cap.device_id) { | |
279 case DEVICE_SIS_300: | |
280 case DEVICE_SIS_630_VGA: | |
281 sis_has_two_overlays = 1; | |
282 case DEVICE_SIS_540_VGA: | |
283 sis_vga_engine = SIS_300_VGA; | |
284 break; | |
285 case DEVICE_SIS_330: | |
286 case DEVICE_SIS_550_VGA: | |
287 sis_has_two_overlays = 1; | |
288 case DEVICE_SIS_315H: | |
289 case DEVICE_SIS_315: | |
290 case DEVICE_SIS_315PRO: | |
291 case DEVICE_SIS_650_VGA: | |
292 /* M650 & 651 have 2 overlays */ | |
293 /* JCP: I think this works, but not really tested yet */ | |
23260
427075ffb413
allow sis vidix driver to access registers and avoid segfaulting (patch by Andrew Calkin)
ben
parents:
23048
diff
changeset
|
294 if (enable_app_io() == 0 ) |
22850 | 295 { |
296 unsigned char CR5F; | |
297 unsigned char tempreg1, tempreg2; | |
298 | |
299 inSISIDXREG(SISCR, 0x5F, CR5F); | |
300 CR5F &= 0xf0; | |
301 andSISIDXREG(SISCR, 0x5c, 0x07); | |
302 inSISIDXREG(SISCR, 0x5c, tempreg1); | |
303 tempreg1 &= 0xf8; | |
304 setSISIDXREG(SISCR, 0x5c, 0x07, 0xf8); | |
305 inSISIDXREG(SISCR, 0x5c, tempreg2); | |
306 tempreg2 &= 0xf8; | |
307 if ((!tempreg1) || (tempreg2)) { | |
308 if (CR5F & 0x80) { | |
309 sis_has_two_overlays = 1; | |
310 } | |
311 } else { | |
312 sis_has_two_overlays = 1; /* ? */ | |
313 } | |
314 if (sis_has_two_overlays) { | |
315 if (sis_verbose > 0) | |
316 printf | |
317 ("[SiS] detected M650/651 with 2 overlays\n"); | |
318 } | |
23260
427075ffb413
allow sis vidix driver to access registers and avoid segfaulting (patch by Andrew Calkin)
ben
parents:
23048
diff
changeset
|
319 disable_app_io(); |
22850 | 320 } |
321 sis_vga_engine = SIS_315_VGA; | |
322 break; | |
323 default: | |
324 /* should never get here */ | |
325 sis_vga_engine = UNKNOWN_VGA; | |
326 break; | |
327 } | |
328 } | |
329 } | |
330 } | |
331 if (err && sis_verbose) { | |
332 printf("[SiS] Can't find chip\n"); | |
333 } else { | |
334 sis_probed = 1; | |
335 } | |
336 | |
337 return err; | |
338 } | |
339 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
340 static int sis_init(void) |
22850 | 341 { |
342 uint8_t sr_data, cr_data, cr_data2; | |
343 char *env_overlay_crt; | |
344 | |
345 if (!sis_probed) { | |
346 printf("[SiS] driver was not probed but is being initialized\n"); | |
347 return (EINTR); | |
348 } | |
349 | |
23260
427075ffb413
allow sis vidix driver to access registers and avoid segfaulting (patch by Andrew Calkin)
ben
parents:
23048
diff
changeset
|
350 if (enable_app_io() != 0) |
427075ffb413
allow sis vidix driver to access registers and avoid segfaulting (patch by Andrew Calkin)
ben
parents:
23048
diff
changeset
|
351 { |
427075ffb413
allow sis vidix driver to access registers and avoid segfaulting (patch by Andrew Calkin)
ben
parents:
23048
diff
changeset
|
352 printf("[SiS] can't enable register I/O\n"); |
427075ffb413
allow sis vidix driver to access registers and avoid segfaulting (patch by Andrew Calkin)
ben
parents:
23048
diff
changeset
|
353 return(EINTR); |
427075ffb413
allow sis vidix driver to access registers and avoid segfaulting (patch by Andrew Calkin)
ben
parents:
23048
diff
changeset
|
354 } |
427075ffb413
allow sis vidix driver to access registers and avoid segfaulting (patch by Andrew Calkin)
ben
parents:
23048
diff
changeset
|
355 |
22850 | 356 /* JCP: this is WRONG. Need to coordinate w/ sisfb to use correct mem */ |
357 /* map 16MB scary hack for now. */ | |
358 sis_mem_base = map_phys_mem(pci_info.base0, 0x1000000); | |
359 /* sis_reg_base = map_phys_mem(pci_info.base1, 0x20000); */ | |
360 sis_iobase = pci_info.base2 & 0xFFFC; | |
361 | |
362 /* would like to use fb ioctl - or some other method - here to get | |
363 current resolution. */ | |
364 inSISIDXREG(SISCR, 0x12, cr_data); | |
365 inSISIDXREG(SISCR, 0x07, cr_data2); | |
366 sis_screen_height = | |
367 ((cr_data & 0xff) | ((uint16_t) (cr_data2 & 0x02) << 7) | | |
368 ((uint16_t) (cr_data2 & 0x40) << 3) | ((uint16_t) (cr_data & 0x02) | |
369 << 9)) + 1; | |
370 | |
371 inSISIDXREG(SISSR, 0x0b, sr_data); | |
372 inSISIDXREG(SISCR, 0x01, cr_data); | |
373 sis_screen_width = (((cr_data & 0xff) | | |
374 ((uint16_t) (sr_data & 0x0C) << 6)) + 1) * 8; | |
375 | |
376 inSISIDXREG(SISSR, Index_SR_Graphic_Mode, sr_data); | |
377 if (sr_data & 0x20) /* interlaced mode */ | |
378 sis_vmode |= VMODE_INTERLACED; | |
379 | |
380 /* JCP: eventually I'd like to replace this with a call to sisfb | |
381 SISFB_GET_INFO ioctl to get video bridge info. Not for now, | |
382 since it requires a very new and not widely distributed version. */ | |
383 sis_init_video_bridge(); | |
384 | |
385 env_overlay_crt = getenv("VIDIX_CRT"); | |
386 if (env_overlay_crt) { | |
387 int crt = atoi(env_overlay_crt); | |
388 if (crt == 1 || crt == 2) { | |
389 sis_overlay_on_crt1 = (crt == 1); | |
390 if (sis_verbose > 0) { | |
391 printf | |
392 ("[SiS] override: using overlay on CRT%d from VIDIX_CRT\n", | |
393 crt); | |
394 } | |
395 } | |
396 } | |
397 | |
398 return 0; | |
399 } | |
400 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
401 static void sis_destroy(void) |
22850 | 402 { |
403 /* unmap_phys_mem(sis_reg_base, 0x20000); */ | |
404 /* JCP: see above, hence also a hack. */ | |
405 unmap_phys_mem(sis_mem_base, 0x1000000); | |
23260
427075ffb413
allow sis vidix driver to access registers and avoid segfaulting (patch by Andrew Calkin)
ben
parents:
23048
diff
changeset
|
406 disable_app_io(); |
22850 | 407 } |
408 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
409 static int sis_get_caps(vidix_capability_t * to) |
22850 | 410 { |
411 memcpy(to, &sis_cap, sizeof(vidix_capability_t)); | |
412 return 0; | |
413 } | |
414 | |
415 static int is_supported_fourcc(uint32_t fourcc) | |
416 { | |
417 switch (fourcc) { | |
418 case IMGFMT_YV12: | |
419 case IMGFMT_I420: | |
420 case IMGFMT_UYVY: | |
421 case IMGFMT_YUY2: | |
422 case IMGFMT_RGB15: | |
423 case IMGFMT_RGB16: | |
424 return 1; | |
425 default: | |
426 return 0; | |
427 } | |
428 } | |
429 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
430 static int sis_query_fourcc(vidix_fourcc_t * to) |
22850 | 431 { |
432 if (is_supported_fourcc(to->fourcc)) { | |
433 to->depth = VID_DEPTH_8BPP | VID_DEPTH_16BPP | VID_DEPTH_32BPP; | |
434 to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; | |
435 return 0; | |
436 } else | |
437 to->depth = to->flags = 0; | |
438 return ENOSYS; | |
439 } | |
440 | |
441 static int bridge_in_slave_mode(void) | |
442 { | |
443 unsigned char usScratchP1_00; | |
444 | |
445 if (!(sis_vbflags & VB_VIDEOBRIDGE)) | |
446 return 0; | |
447 | |
448 inSISIDXREG(SISPART1, 0x00, usScratchP1_00); | |
449 if (((sis_vga_engine == SIS_300_VGA) | |
450 && (usScratchP1_00 & 0xa0) == 0x20) | |
451 || ((sis_vga_engine == SIS_315_VGA) | |
452 && (usScratchP1_00 & 0x50) == 0x10)) { | |
453 return 1; | |
454 } else { | |
455 return 0; | |
456 } | |
457 } | |
458 | |
459 /* This does not handle X dual head mode, since 1) vidix doesn't support it | |
460 and 2) it doesn't make sense for other gfx drivers */ | |
461 static void set_dispmode(void) | |
462 { | |
463 sis_bridge_is_slave = 0; | |
464 | |
465 if (bridge_in_slave_mode()) | |
466 sis_bridge_is_slave = 1; | |
467 | |
468 if ((sis_vbflags & VB_DISPMODE_MIRROR) || | |
469 (sis_bridge_is_slave && (sis_vbflags & DISPTYPE_DISP2))) { | |
470 if (sis_has_two_overlays) | |
471 sis_displaymode = DISPMODE_MIRROR; /* TW: CRT1+CRT2 (2 overlays) */ | |
472 else if (!sis_overlay_on_crt1) | |
473 sis_displaymode = DISPMODE_SINGLE2; | |
474 else | |
475 sis_displaymode = DISPMODE_SINGLE1; | |
476 } else { | |
477 if (sis_vbflags & DISPTYPE_DISP1) { | |
478 sis_displaymode = DISPMODE_SINGLE1; /* TW: CRT1 only */ | |
479 } else { | |
480 sis_displaymode = DISPMODE_SINGLE2; /* TW: CRT2 only */ | |
481 } | |
482 } | |
483 } | |
484 | |
485 static void set_disptype_regs(void) | |
486 { | |
487 switch (sis_displaymode) { | |
488 case DISPMODE_SINGLE1: /* TW: CRT1 only */ | |
489 if (sis_verbose > 2) { | |
490 printf("[SiS] Setting up overlay on CRT1\n"); | |
491 } | |
492 if (sis_has_two_overlays) { | |
493 setsrregmask(0x06, 0x00, 0xc0); | |
494 setsrregmask(0x32, 0x00, 0xc0); | |
495 } else { | |
496 setsrregmask(0x06, 0x00, 0xc0); | |
497 setsrregmask(0x32, 0x00, 0xc0); | |
498 } | |
499 break; | |
500 case DISPMODE_SINGLE2: /* TW: CRT2 only */ | |
501 if (sis_verbose > 2) { | |
502 printf("[SiS] Setting up overlay on CRT2\n"); | |
503 } | |
504 if (sis_has_two_overlays) { | |
505 setsrregmask(0x06, 0x80, 0xc0); | |
506 setsrregmask(0x32, 0x80, 0xc0); | |
507 } else { | |
508 setsrregmask(0x06, 0x40, 0xc0); | |
509 setsrregmask(0x32, 0x40, 0xc0); | |
510 } | |
511 break; | |
512 case DISPMODE_MIRROR: /* TW: CRT1 + CRT2 */ | |
513 default: | |
514 if (sis_verbose > 2) { | |
515 printf("[SiS] Setting up overlay on CRT1 AND CRT2!\n"); | |
516 } | |
517 setsrregmask(0x06, 0x80, 0xc0); | |
518 setsrregmask(0x32, 0x80, 0xc0); | |
519 break; | |
520 } | |
521 } | |
522 | |
523 static void init_overlay(void) | |
524 { | |
525 /* Initialize first overlay (CRT1) */ | |
526 | |
527 /* Write-enable video registers */ | |
528 setvideoregmask(Index_VI_Control_Misc2, 0x80, 0x81); | |
529 | |
530 /* Disable overlay */ | |
531 setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); | |
532 | |
533 /* Disable bobEnable */ | |
534 setvideoregmask(Index_VI_Control_Misc1, 0x02, 0x02); | |
535 | |
536 /* Reset scale control and contrast */ | |
537 setvideoregmask(Index_VI_Scale_Control, 0x60, 0x60); | |
538 setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); | |
539 | |
540 setvideoreg(Index_VI_Disp_Y_Buf_Preset_Low, 0x00); | |
541 setvideoreg(Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); | |
542 setvideoreg(Index_VI_UV_Buf_Preset_Low, 0x00); | |
543 setvideoreg(Index_VI_UV_Buf_Preset_Middle, 0x00); | |
544 setvideoreg(Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); | |
545 setvideoreg(Index_VI_Play_Threshold_Low, 0x00); | |
546 setvideoreg(Index_VI_Play_Threshold_High, 0x00); | |
547 | |
548 /* may not want to init these here, could already be set to other | |
549 values by app? */ | |
550 setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x01); | |
551 setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); | |
552 setvideoreg(Index_VI_Brightness, 0x20); | |
553 if (sis_vga_engine == SIS_315_VGA) { | |
554 setvideoreg(Index_VI_Hue, 0x00); | |
555 setvideoreg(Index_VI_Saturation, 0x00); | |
556 } | |
557 | |
558 /* Initialize second overlay (CRT2) */ | |
559 if (sis_has_two_overlays) { | |
560 /* Write-enable video registers */ | |
561 setvideoregmask(Index_VI_Control_Misc2, 0x81, 0x81); | |
562 | |
563 /* Disable overlay */ | |
564 setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); | |
565 | |
566 /* Disable bobEnable */ | |
567 setvideoregmask(Index_VI_Control_Misc1, 0x02, 0x02); | |
568 | |
569 /* Reset scale control and contrast */ | |
570 setvideoregmask(Index_VI_Scale_Control, 0x60, 0x60); | |
571 setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); | |
572 | |
573 setvideoreg(Index_VI_Disp_Y_Buf_Preset_Low, 0x00); | |
574 setvideoreg(Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); | |
575 setvideoreg(Index_VI_UV_Buf_Preset_Low, 0x00); | |
576 setvideoreg(Index_VI_UV_Buf_Preset_Middle, 0x00); | |
577 setvideoreg(Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); | |
578 setvideoreg(Index_VI_Play_Threshold_Low, 0x00); | |
579 setvideoreg(Index_VI_Play_Threshold_High, 0x00); | |
580 | |
581 setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x01); | |
582 setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); | |
583 setvideoreg(Index_VI_Brightness, 0x20); | |
584 if (sis_vga_engine == SIS_315_VGA) { | |
585 setvideoreg(Index_VI_Hue, 0x00); | |
586 setvideoreg(Index_VI_Saturation, 0x00); | |
587 } | |
588 } | |
589 } | |
590 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
591 static int sis_set_eq(const vidix_video_eq_t * eq); |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
592 |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
593 static int sis_config_playback(vidix_playback_t * info) |
22850 | 594 { |
595 SISOverlayRec overlay; | |
596 int srcOffsetX = 0, srcOffsetY = 0; | |
597 int sx, sy; | |
598 int index = 0, iscrt2 = 0; | |
599 int total_size; | |
600 | |
601 short src_w, drw_w; | |
602 short src_h, drw_h; | |
603 short src_x, drw_x; | |
604 short src_y, drw_y; | |
605 long dga_offset; | |
606 int pitch; | |
607 unsigned int i; | |
608 | |
609 if (!is_supported_fourcc(info->fourcc)) | |
610 return -1; | |
611 | |
612 /* set chipset/engine.dependent config info */ | |
613 /* which CRT to use, etc.? */ | |
614 switch (sis_vga_engine) { | |
615 case SIS_315_VGA: | |
616 sis_shift_value = 1; | |
617 sis_equal.cap |= VEQ_CAP_SATURATION | VEQ_CAP_HUE; | |
618 break; | |
619 case SIS_300_VGA: | |
620 default: | |
621 sis_shift_value = 2; | |
622 break; | |
623 } | |
624 | |
625 sis_displaymode = DISPMODE_SINGLE1; /* xV driver code in set_dispmode() */ | |
626 set_dispmode(); | |
627 | |
628 set_disptype_regs(); | |
629 | |
630 init_overlay(); | |
631 | |
632 /* get basic dimension info */ | |
633 src_x = info->src.x; | |
634 src_y = info->src.y; | |
635 src_w = info->src.w; | |
636 src_h = info->src.h; | |
637 | |
638 drw_x = info->dest.x; | |
639 drw_y = info->dest.y; | |
640 drw_w = info->dest.w; | |
641 drw_h = info->dest.h; | |
642 | |
643 switch (info->fourcc) { | |
644 case IMGFMT_YV12: | |
645 case IMGFMT_I420: | |
646 pitch = (src_w + 7) & ~7; | |
647 total_size = (pitch * src_h * 3) >> 1; | |
648 break; | |
649 case IMGFMT_YUY2: | |
650 case IMGFMT_UYVY: | |
651 case IMGFMT_RGB15: | |
652 case IMGFMT_RGB16: | |
653 pitch = ((src_w << 1) + 3) & ~3; | |
654 total_size = pitch * src_h; | |
655 break; | |
656 default: | |
657 return -1; | |
658 } | |
659 | |
660 /* "allocate" memory for overlay! */ | |
661 /* start at 8MB = sisfb's "dri reserved space" - | |
662 really shouldn't hardcode though */ | |
663 /* XXX: JCP - this can use the sisfb FBIO_ALLOC ioctl to safely | |
664 allocate "video heap" memory... */ | |
665 dga_offset = 0x800000; | |
666 | |
667 /* use 7MB for now. need to calc/get real info from sisfb? */ | |
668 /* this can result in a LOT of frames - probably not necessary */ | |
669 info->num_frames = 0x700000 / (total_size * 2); | |
670 if (info->num_frames > VID_PLAY_MAXFRAMES) | |
671 info->num_frames = VID_PLAY_MAXFRAMES; | |
672 | |
673 info->dga_addr = sis_mem_base + dga_offset; | |
674 info->dest.pitch.y = 16; | |
675 info->dest.pitch.u = 16; | |
676 info->dest.pitch.v = 16; | |
677 info->offset.y = 0; | |
678 info->offset.u = 0; | |
679 info->offset.v = 0; | |
680 info->frame_size = (total_size * 2); /* why times 2 ? */ | |
681 for (i = 0; i < info->num_frames; i++) { | |
682 info->offsets[i] = info->frame_size * i; | |
683 /* save ptrs to mem buffers */ | |
684 sis_frames[i] = (dga_offset + info->offsets[i]); | |
685 } | |
686 | |
687 memset(&overlay, 0, sizeof(overlay)); | |
688 overlay.pixelFormat = sis_format = info->fourcc; | |
689 overlay.pitch = overlay.origPitch = pitch; | |
690 | |
691 | |
692 overlay.keyOP = (sis_grkey.ckey.op == CKEY_TRUE ? | |
693 VI_ROP_DestKey : VI_ROP_Always); | |
694 | |
695 overlay.bobEnable = 0x00; | |
696 | |
697 overlay.SCREENheight = sis_screen_height; | |
698 | |
699 /* probably will not support X virtual screen > phys very well? */ | |
700 overlay.dstBox.x1 = drw_x; /* - pScrn->frameX0; */ | |
701 overlay.dstBox.x2 = drw_x + drw_w; /* - pScrn->frameX0; ??? */ | |
702 overlay.dstBox.y1 = drw_y; /* - pScrn->frameY0; */ | |
703 overlay.dstBox.y2 = drw_y + drw_h; /* - pScrn->frameY0; ??? */ | |
704 | |
705 if ((overlay.dstBox.x1 > overlay.dstBox.x2) || | |
706 (overlay.dstBox.y1 > overlay.dstBox.y2)) | |
707 return -1; | |
708 | |
709 if ((overlay.dstBox.x2 < 0) || (overlay.dstBox.y2 < 0)) | |
710 return -1; | |
711 | |
712 if (overlay.dstBox.x1 < 0) { | |
713 srcOffsetX = src_w * (-overlay.dstBox.x1) / drw_w; | |
714 overlay.dstBox.x1 = 0; | |
715 } | |
716 if (overlay.dstBox.y1 < 0) { | |
717 srcOffsetY = src_h * (-overlay.dstBox.y1) / drw_h; | |
718 overlay.dstBox.y1 = 0; | |
719 } | |
720 | |
721 switch (info->fourcc) { | |
722 case IMGFMT_YV12: | |
723 info->dest.pitch.y = 16; | |
724 sx = (src_x + srcOffsetX) & ~7; | |
725 sy = (src_y + srcOffsetY) & ~1; | |
726 info->offset.y = sis_Yoff = sx + sy * pitch; | |
727 /* JCP: NOTE reversed u & v here! Not sure why this is needed. | |
728 maybe mplayer & sis define U & V differently?? */ | |
729 info->offset.u = sis_Voff = | |
730 src_h * pitch + ((sx + sy * pitch / 2) >> 1); | |
731 info->offset.v = sis_Uoff = | |
732 src_h * pitch * 5 / 4 + ((sx + sy * pitch / 2) >> 1); | |
733 | |
734 overlay.PSY = (sis_frames[0] + sis_Yoff) >> sis_shift_value; | |
735 overlay.PSV = (sis_frames[0] + sis_Voff) >> sis_shift_value; | |
736 overlay.PSU = (sis_frames[0] + sis_Uoff) >> sis_shift_value; | |
737 break; | |
738 case IMGFMT_I420: | |
739 sx = (src_x + srcOffsetX) & ~7; | |
740 sy = (src_y + srcOffsetY) & ~1; | |
741 info->offset.y = sis_Yoff = sx + sy * pitch; | |
742 /* JCP: see above... */ | |
743 info->offset.u = sis_Voff = | |
744 src_h * pitch * 5 / 4 + ((sx + sy * pitch / 2) >> 1); | |
745 info->offset.v = sis_Uoff = | |
746 src_h * pitch + ((sx + sy * pitch / 2) >> 1); | |
747 | |
748 overlay.PSY = (sis_frames[0] + sis_Yoff) >> sis_shift_value; | |
749 overlay.PSV = (sis_frames[0] + sis_Voff) >> sis_shift_value; | |
750 overlay.PSU = (sis_frames[0] + sis_Uoff) >> sis_shift_value; | |
751 break; | |
752 case IMGFMT_YUY2: | |
753 case IMGFMT_UYVY: | |
754 case IMGFMT_RGB16: | |
755 case IMGFMT_RGB15: | |
756 default: | |
757 sx = (src_x + srcOffsetX) & ~1; | |
758 sy = (src_y + srcOffsetY); | |
759 info->offset.y = sis_Yoff = sx * 2 + sy * pitch; | |
760 | |
761 overlay.PSY = (sis_frames[0] + sis_Yoff) >> sis_shift_value; | |
762 break; | |
763 } | |
764 | |
765 /* FIXME: is it possible that srcW < 0? */ | |
766 overlay.srcW = src_w - (sx - src_x); | |
767 overlay.srcH = src_h - (sy - src_y); | |
768 | |
769 /* set merge line buffer */ | |
770 merge_line_buf(overlay.srcW > 384); | |
771 | |
772 /* calculate line buffer length */ | |
773 set_line_buf_size(&overlay); | |
774 | |
775 if (sis_displaymode == DISPMODE_SINGLE2) { | |
776 if (sis_has_two_overlays) { | |
777 /* TW: On chips with two overlays we use | |
778 * overlay 2 for CRT2 */ | |
779 index = 1; | |
780 iscrt2 = 1; | |
781 } else { | |
782 /* TW: On chips with only one overlay we | |
783 * use that only overlay for CRT2 */ | |
784 index = 0; | |
785 iscrt2 = 1; | |
786 } | |
787 overlay.VBlankActiveFunc = vblank_active_CRT2; | |
788 /* overlay.GetScanLineFunc = get_scanline_CRT2; */ | |
789 } else { | |
790 index = 0; | |
791 iscrt2 = 0; | |
792 overlay.VBlankActiveFunc = vblank_active_CRT1; | |
793 /* overlay.GetScanLineFunc = get_scanline_CRT1; */ | |
794 } | |
795 | |
796 /* calc scale factor (to use below) */ | |
797 calc_scale_factor(&overlay, index, iscrt2); | |
798 | |
799 /* Select video1 (used for CRT1) or video2 (used for CRT2) */ | |
800 setvideoregmask(Index_VI_Control_Misc2, index, 0x01); | |
801 | |
802 set_format(&overlay); | |
803 | |
804 set_colorkey(); | |
805 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
806 sis_set_eq(&sis_equal); |
22850 | 807 |
808 /* set up video overlay registers */ | |
809 set_overlay(&overlay, index); | |
810 | |
811 /* prevent badness if bits are not at default setting */ | |
812 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x01); | |
813 setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x04); | |
814 | |
815 /* JCP: Xv driver implementation loops back over above code to | |
816 setup mirror CRT2 */ | |
817 | |
818 return 0; | |
819 } | |
820 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
821 static int sis_playback_on(void) |
22850 | 822 { |
823 setvideoregmask(Index_VI_Control_Misc0, 0x02, 0x02); | |
824 return 0; | |
825 } | |
826 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
827 static int sis_playback_off(void) |
22850 | 828 { |
829 unsigned char sridx, cridx; | |
830 sridx = inSISREG(SISSR); | |
831 cridx = inSISREG(SISCR); | |
832 close_overlay(); | |
833 outSISREG(SISSR, sridx); | |
834 outSISREG(SISCR, cridx); | |
835 | |
836 return 0; | |
837 } | |
838 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
839 static int sis_frame_select(unsigned int frame) |
22850 | 840 { |
841 uint8_t data; | |
842 int index = 0; | |
843 uint32_t PSY; | |
844 | |
845 if (sis_displaymode == DISPMODE_SINGLE2 && sis_has_two_overlays) { | |
846 index = 1; | |
847 } | |
848 | |
849 PSY = (sis_frames[frame] + sis_Yoff) >> sis_shift_value; | |
850 | |
851 /* Unlock address registers */ | |
852 data = getvideoreg(Index_VI_Control_Misc1); | |
853 setvideoreg(Index_VI_Control_Misc1, data | 0x20); | |
854 /* TEST: Is this required? */ | |
855 setvideoreg(Index_VI_Control_Misc1, data | 0x20); | |
856 /* TEST end */ | |
857 /* TEST: Is this required? */ | |
858 if (sis_vga_engine == SIS_315_VGA) | |
859 setvideoreg(Index_VI_Control_Misc3, 0x00); | |
860 /* TEST end */ | |
861 | |
862 /* set Y start address */ | |
863 setvideoreg(Index_VI_Disp_Y_Buf_Start_Low, (uint8_t) (PSY)); | |
864 setvideoreg(Index_VI_Disp_Y_Buf_Start_Middle, (uint8_t) ((PSY) >> 8)); | |
865 setvideoreg(Index_VI_Disp_Y_Buf_Start_High, (uint8_t) ((PSY) >> 16)); | |
866 /* set 310/325 series overflow bits for Y plane */ | |
867 if (sis_vga_engine == SIS_315_VGA) { | |
868 setvideoreg(Index_VI_Y_Buf_Start_Over, | |
869 ((uint8_t) ((PSY) >> 24) & 0x01)); | |
870 } | |
871 | |
872 /* Set U/V data if using plane formats */ | |
873 if ((sis_format == IMGFMT_YV12) || (sis_format == IMGFMT_I420)) { | |
874 | |
875 uint32_t PSU, PSV; | |
876 | |
877 PSU = (sis_frames[frame] + sis_Uoff) >> sis_shift_value; | |
878 PSV = (sis_frames[frame] + sis_Voff) >> sis_shift_value; | |
879 | |
880 /* set U/V start address */ | |
881 setvideoreg(Index_VI_U_Buf_Start_Low, (uint8_t) PSU); | |
882 setvideoreg(Index_VI_U_Buf_Start_Middle, (uint8_t) (PSU >> 8)); | |
883 setvideoreg(Index_VI_U_Buf_Start_High, (uint8_t) (PSU >> 16)); | |
884 | |
885 setvideoreg(Index_VI_V_Buf_Start_Low, (uint8_t) PSV); | |
886 setvideoreg(Index_VI_V_Buf_Start_Middle, (uint8_t) (PSV >> 8)); | |
887 setvideoreg(Index_VI_V_Buf_Start_High, (uint8_t) (PSV >> 16)); | |
888 | |
889 /* 310/325 series overflow bits */ | |
890 if (sis_vga_engine == SIS_315_VGA) { | |
891 setvideoreg(Index_VI_U_Buf_Start_Over, | |
892 ((uint8_t) (PSU >> 24) & 0x01)); | |
893 setvideoreg(Index_VI_V_Buf_Start_Over, | |
894 ((uint8_t) (PSV >> 24) & 0x01)); | |
895 } | |
896 } | |
897 | |
898 if (sis_vga_engine == SIS_315_VGA) { | |
899 /* Trigger register copy for 310 series */ | |
900 setvideoreg(Index_VI_Control_Misc3, 1 << index); | |
901 } | |
902 | |
903 /* Lock the address registers */ | |
904 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x20); | |
905 | |
906 return 0; | |
907 } | |
908 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
909 static int sis_get_gkeys(vidix_grkey_t * grkey) |
22850 | 910 { |
911 memcpy(grkey, &sis_grkey, sizeof(vidix_grkey_t)); | |
912 return 0; | |
913 } | |
914 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
915 static int sis_set_gkeys(const vidix_grkey_t * grkey) |
22850 | 916 { |
917 memcpy(&sis_grkey, grkey, sizeof(vidix_grkey_t)); | |
918 set_colorkey(); | |
919 return 0; | |
920 } | |
921 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
922 static int sis_get_eq(vidix_video_eq_t * eq) |
22850 | 923 { |
924 memcpy(eq, &sis_equal, sizeof(vidix_video_eq_t)); | |
925 return 0; | |
926 } | |
927 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
928 static int sis_set_eq(const vidix_video_eq_t * eq) |
22850 | 929 { |
930 int br, sat, cr, hue; | |
931 if (eq->cap & VEQ_CAP_BRIGHTNESS) | |
932 sis_equal.brightness = eq->brightness; | |
933 if (eq->cap & VEQ_CAP_CONTRAST) | |
934 sis_equal.contrast = eq->contrast; | |
935 if (eq->cap & VEQ_CAP_SATURATION) | |
936 sis_equal.saturation = eq->saturation; | |
937 if (eq->cap & VEQ_CAP_HUE) | |
938 sis_equal.hue = eq->hue; | |
939 if (eq->cap & VEQ_CAP_RGB_INTENSITY) { | |
940 sis_equal.red_intensity = eq->red_intensity; | |
941 sis_equal.green_intensity = eq->green_intensity; | |
942 sis_equal.blue_intensity = eq->blue_intensity; | |
943 } | |
944 sis_equal.flags = eq->flags; | |
945 | |
946 cr = (sis_equal.contrast + 1000) * 7 / 2000; | |
947 if (cr < 0) | |
948 cr = 0; | |
949 if (cr > 7) | |
950 cr = 7; | |
951 | |
952 br = sis_equal.brightness * 127 / 1000; | |
953 if (br < -128) | |
954 br = -128; | |
955 if (br > 127) | |
956 br = 127; | |
957 | |
958 sat = (sis_equal.saturation * 7) / 1000; | |
959 if (sat < -7) | |
960 sat = -7; | |
961 if (sat > 7) | |
962 sat = 7; | |
963 | |
964 hue = sis_equal.hue * 7 / 1000; | |
965 if (hue < -8) | |
966 hue = -8; | |
967 if (hue > 7) | |
968 hue = 7; | |
969 | |
970 set_brightness(br); | |
971 set_contrast(cr); | |
972 if (sis_vga_engine == SIS_315_VGA) { | |
973 set_saturation(sat); | |
974 set_hue(hue); | |
975 } | |
976 | |
977 return 0; | |
978 } | |
979 | |
980 static void set_overlay(SISOverlayPtr pOverlay, int index) | |
981 { | |
982 uint16_t pitch = 0; | |
983 uint8_t h_over = 0, v_over = 0; | |
984 uint16_t top, bottom, left, right; | |
985 uint16_t screenX = sis_screen_width; | |
986 uint16_t screenY = sis_screen_height; | |
987 uint8_t data; | |
988 uint32_t watchdog; | |
989 | |
990 top = pOverlay->dstBox.y1; | |
991 bottom = pOverlay->dstBox.y2; | |
992 if (bottom > screenY) { | |
993 bottom = screenY; | |
994 } | |
995 | |
996 left = pOverlay->dstBox.x1; | |
997 right = pOverlay->dstBox.x2; | |
998 if (right > screenX) { | |
999 right = screenX; | |
1000 } | |
1001 | |
1002 /* JCP: these aren't really tested... */ | |
1003 /* TW: DoubleScan modes require Y coordinates * 2 */ | |
1004 if (sis_vmode & VMODE_DOUBLESCAN) { | |
1005 top <<= 1; | |
1006 bottom <<= 1; | |
1007 } | |
1008 /* TW: Interlace modes require Y coordinates / 2 */ | |
1009 if (sis_vmode & VMODE_INTERLACED) { | |
1010 top >>= 1; | |
1011 bottom >>= 1; | |
1012 } | |
1013 | |
1014 h_over = (((left >> 8) & 0x0f) | ((right >> 4) & 0xf0)); | |
1015 v_over = (((top >> 8) & 0x0f) | ((bottom >> 4) & 0xf0)); | |
1016 | |
1017 pitch = pOverlay->pitch >> sis_shift_value; | |
1018 | |
1019 /* set line buffer size */ | |
1020 setvideoreg(Index_VI_Line_Buffer_Size, pOverlay->lineBufSize); | |
1021 | |
1022 /* set color key mode */ | |
1023 setvideoregmask(Index_VI_Key_Overlay_OP, pOverlay->keyOP, 0x0F); | |
1024 | |
1025 /* TW: We don't have to wait for vertical retrace in all cases */ | |
1026 /* JCP: be safe for now. */ | |
1027 if (1 /*pPriv->mustwait */ ) { | |
1028 watchdog = WATCHDOG_DELAY; | |
1029 while (pOverlay->VBlankActiveFunc() && --watchdog); | |
1030 watchdog = WATCHDOG_DELAY; | |
1031 while ((!pOverlay->VBlankActiveFunc()) && --watchdog); | |
1032 if (!watchdog && sis_verbose > 0) { | |
1033 printf("[SiS]: timed out waiting for vertical retrace\n"); | |
1034 } | |
1035 } | |
1036 | |
1037 /* Unlock address registers */ | |
1038 data = getvideoreg(Index_VI_Control_Misc1); | |
1039 setvideoreg(Index_VI_Control_Misc1, data | 0x20); | |
1040 /* TEST: Is this required? */ | |
1041 setvideoreg(Index_VI_Control_Misc1, data | 0x20); | |
1042 /* TEST end */ | |
1043 | |
1044 /* TEST: Is this required? */ | |
1045 if (sis_vga_engine == SIS_315_VGA) | |
1046 setvideoreg(Index_VI_Control_Misc3, 0x00); | |
1047 /* TEST end */ | |
1048 | |
1049 /* Set Y buf pitch */ | |
1050 setvideoreg(Index_VI_Disp_Y_Buf_Pitch_Low, (uint8_t) (pitch)); | |
1051 setvideoregmask(Index_VI_Disp_Y_UV_Buf_Pitch_Middle, | |
1052 (uint8_t) (pitch >> 8), 0x0f); | |
1053 | |
1054 /* Set Y start address */ | |
1055 setvideoreg(Index_VI_Disp_Y_Buf_Start_Low, (uint8_t) (pOverlay->PSY)); | |
1056 setvideoreg(Index_VI_Disp_Y_Buf_Start_Middle, | |
1057 (uint8_t) ((pOverlay->PSY) >> 8)); | |
1058 setvideoreg(Index_VI_Disp_Y_Buf_Start_High, | |
1059 (uint8_t) ((pOverlay->PSY) >> 16)); | |
1060 | |
1061 /* set 310/325 series overflow bits for Y plane */ | |
1062 if (sis_vga_engine == SIS_315_VGA) { | |
1063 setvideoreg(Index_VI_Disp_Y_Buf_Pitch_High, | |
1064 (uint8_t) (pitch >> 12)); | |
1065 setvideoreg(Index_VI_Y_Buf_Start_Over, | |
1066 ((uint8_t) ((pOverlay->PSY) >> 24) & 0x01)); | |
1067 } | |
1068 | |
1069 /* Set U/V data if using plane formats */ | |
1070 if ((pOverlay->pixelFormat == IMGFMT_YV12) || | |
1071 (pOverlay->pixelFormat == IMGFMT_I420)) { | |
1072 | |
1073 uint32_t PSU, PSV; | |
1074 | |
1075 PSU = pOverlay->PSU; | |
1076 PSV = pOverlay->PSV; | |
1077 | |
1078 /* Set U/V pitch */ | |
1079 setvideoreg(Index_VI_Disp_UV_Buf_Pitch_Low, | |
1080 (uint8_t) (pitch >> 1)); | |
1081 setvideoregmask(Index_VI_Disp_Y_UV_Buf_Pitch_Middle, | |
1082 (uint8_t) (pitch >> 5), 0xf0); | |
1083 | |
1084 /* set U/V start address */ | |
1085 setvideoreg(Index_VI_U_Buf_Start_Low, (uint8_t) PSU); | |
1086 setvideoreg(Index_VI_U_Buf_Start_Middle, (uint8_t) (PSU >> 8)); | |
1087 setvideoreg(Index_VI_U_Buf_Start_High, (uint8_t) (PSU >> 16)); | |
1088 | |
1089 setvideoreg(Index_VI_V_Buf_Start_Low, (uint8_t) PSV); | |
1090 setvideoreg(Index_VI_V_Buf_Start_Middle, (uint8_t) (PSV >> 8)); | |
1091 setvideoreg(Index_VI_V_Buf_Start_High, (uint8_t) (PSV >> 16)); | |
1092 | |
1093 /* 310/325 series overflow bits */ | |
1094 if (sis_vga_engine == SIS_315_VGA) { | |
1095 setvideoreg(Index_VI_Disp_UV_Buf_Pitch_High, | |
1096 (uint8_t) (pitch >> 13)); | |
1097 setvideoreg(Index_VI_U_Buf_Start_Over, | |
1098 ((uint8_t) (PSU >> 24) & 0x01)); | |
1099 setvideoreg(Index_VI_V_Buf_Start_Over, | |
1100 ((uint8_t) (PSV >> 24) & 0x01)); | |
1101 } | |
1102 } | |
1103 | |
1104 if (sis_vga_engine == SIS_315_VGA) { | |
1105 /* Trigger register copy for 310 series */ | |
1106 setvideoreg(Index_VI_Control_Misc3, 1 << index); | |
1107 } | |
1108 | |
1109 /* set scale factor */ | |
1110 setvideoreg(Index_VI_Hor_Post_Up_Scale_Low, | |
1111 (uint8_t) (pOverlay->HUSF)); | |
1112 setvideoreg(Index_VI_Hor_Post_Up_Scale_High, | |
1113 (uint8_t) ((pOverlay->HUSF) >> 8)); | |
1114 setvideoreg(Index_VI_Ver_Up_Scale_Low, (uint8_t) (pOverlay->VUSF)); | |
1115 setvideoreg(Index_VI_Ver_Up_Scale_High, | |
1116 (uint8_t) ((pOverlay->VUSF) >> 8)); | |
1117 | |
1118 setvideoregmask(Index_VI_Scale_Control, (pOverlay->IntBit << 3) | |
1119 | (pOverlay->wHPre), 0x7f); | |
1120 | |
1121 /* set destination window position */ | |
1122 setvideoreg(Index_VI_Win_Hor_Disp_Start_Low, (uint8_t) left); | |
1123 setvideoreg(Index_VI_Win_Hor_Disp_End_Low, (uint8_t) right); | |
1124 setvideoreg(Index_VI_Win_Hor_Over, (uint8_t) h_over); | |
1125 | |
1126 setvideoreg(Index_VI_Win_Ver_Disp_Start_Low, (uint8_t) top); | |
1127 setvideoreg(Index_VI_Win_Ver_Disp_End_Low, (uint8_t) bottom); | |
1128 setvideoreg(Index_VI_Win_Ver_Over, (uint8_t) v_over); | |
1129 | |
1130 setvideoregmask(Index_VI_Control_Misc1, pOverlay->bobEnable, 0x1a); | |
1131 | |
1132 /* Lock the address registers */ | |
1133 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x20); | |
1134 } | |
1135 | |
1136 | |
1137 /* TW: Overlay MUST NOT be switched off while beam is over it */ | |
1138 static void close_overlay(void) | |
1139 { | |
1140 uint32_t watchdog; | |
1141 | |
1142 if ((sis_displaymode == DISPMODE_SINGLE2) || | |
1143 (sis_displaymode == DISPMODE_MIRROR)) { | |
1144 if (sis_has_two_overlays) { | |
1145 setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x01); | |
1146 watchdog = WATCHDOG_DELAY; | |
1147 while (vblank_active_CRT2() && --watchdog); | |
1148 watchdog = WATCHDOG_DELAY; | |
1149 while ((!vblank_active_CRT2()) && --watchdog); | |
1150 setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); | |
1151 watchdog = WATCHDOG_DELAY; | |
1152 while (vblank_active_CRT2() && --watchdog); | |
1153 watchdog = WATCHDOG_DELAY; | |
1154 while ((!vblank_active_CRT2()) && --watchdog); | |
1155 } else if (sis_displaymode == DISPMODE_SINGLE2) { | |
1156 setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x01); | |
1157 watchdog = WATCHDOG_DELAY; | |
1158 while (vblank_active_CRT1() && --watchdog); | |
1159 watchdog = WATCHDOG_DELAY; | |
1160 while ((!vblank_active_CRT1()) && --watchdog); | |
1161 setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); | |
1162 watchdog = WATCHDOG_DELAY; | |
1163 while (vblank_active_CRT1() && --watchdog); | |
1164 watchdog = WATCHDOG_DELAY; | |
1165 while ((!vblank_active_CRT1()) && --watchdog); | |
1166 } | |
1167 } | |
1168 if ((sis_displaymode == DISPMODE_SINGLE1) || | |
1169 (sis_displaymode == DISPMODE_MIRROR)) { | |
1170 setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x01); | |
1171 watchdog = WATCHDOG_DELAY; | |
1172 while (vblank_active_CRT1() && --watchdog); | |
1173 watchdog = WATCHDOG_DELAY; | |
1174 while ((!vblank_active_CRT1()) && --watchdog); | |
1175 setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); | |
1176 watchdog = WATCHDOG_DELAY; | |
1177 while (vblank_active_CRT1() && --watchdog); | |
1178 watchdog = WATCHDOG_DELAY; | |
1179 while ((!vblank_active_CRT1()) && --watchdog); | |
1180 } | |
1181 } | |
1182 | |
1183 | |
1184 static void | |
1185 calc_scale_factor(SISOverlayPtr pOverlay, int index, int iscrt2) | |
1186 { | |
1187 uint32_t i = 0, mult = 0; | |
1188 int flag = 0; | |
1189 | |
1190 int dstW = pOverlay->dstBox.x2 - pOverlay->dstBox.x1; | |
1191 int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1; | |
1192 int srcW = pOverlay->srcW; | |
1193 int srcH = pOverlay->srcH; | |
1194 /* uint16_t LCDheight = pSiS->LCDheight; */ | |
1195 int srcPitch = pOverlay->origPitch; | |
1196 int origdstH = dstH; | |
1197 | |
1198 /* get rid of warnings for now */ | |
1199 index = index; | |
1200 iscrt2 = iscrt2; | |
1201 | |
1202 /* TW: For double scan modes, we need to double the height | |
1203 * (Perhaps we also need to scale LVDS, but I'm not sure.) | |
1204 * On 310/325 series, we need to double the width as well. | |
1205 * Interlace mode vice versa. | |
1206 */ | |
1207 if (sis_vmode & VMODE_DOUBLESCAN) { | |
1208 dstH = origdstH << 1; | |
1209 flag = 0; | |
1210 if (sis_vga_engine == SIS_315_VGA) { | |
1211 dstW <<= 1; | |
1212 } | |
1213 } | |
1214 if (sis_vmode & VMODE_INTERLACED) { | |
1215 dstH = origdstH >> 1; | |
1216 flag = 0; | |
1217 } | |
1218 | |
1219 if (dstW < OVERLAY_MIN_WIDTH) | |
1220 dstW = OVERLAY_MIN_WIDTH; | |
1221 if (dstW == srcW) { | |
1222 pOverlay->HUSF = 0x00; | |
1223 pOverlay->IntBit = 0x05; | |
1224 pOverlay->wHPre = 0; | |
1225 } else if (dstW > srcW) { | |
1226 dstW += 2; | |
1227 pOverlay->HUSF = (srcW << 16) / dstW; | |
1228 pOverlay->IntBit = 0x04; | |
1229 pOverlay->wHPre = 0; | |
1230 } else { | |
1231 int tmpW = dstW; | |
1232 | |
1233 /* TW: It seems, the hardware can't scale below factor .125 (=1/8) if the | |
1234 pitch isn't a multiple of 256. | |
1235 TODO: Test this on the 310/325 series! | |
1236 */ | |
1237 if ((srcPitch % 256) || (srcPitch < 256)) { | |
1238 if (((dstW * 1000) / srcW) < 125) | |
1239 dstW = tmpW = ((srcW * 125) / 1000) + 1; | |
1240 } | |
1241 | |
1242 i = 0; | |
1243 pOverlay->IntBit = 0x01; | |
1244 while (srcW >= tmpW) { | |
1245 tmpW <<= 1; | |
1246 i++; | |
1247 } | |
1248 pOverlay->wHPre = (uint8_t) (i - 1); | |
1249 dstW <<= (i - 1); | |
1250 if ((srcW % dstW)) | |
1251 pOverlay->HUSF = ((srcW - dstW) << 16) / dstW; | |
1252 else | |
1253 pOverlay->HUSF = 0x00; | |
1254 } | |
1255 | |
1256 if (dstH < OVERLAY_MIN_HEIGHT) | |
1257 dstH = OVERLAY_MIN_HEIGHT; | |
1258 if (dstH == srcH) { | |
1259 pOverlay->VUSF = 0x00; | |
1260 pOverlay->IntBit |= 0x0A; | |
1261 } else if (dstH > srcH) { | |
1262 dstH += 0x02; | |
1263 pOverlay->VUSF = (srcH << 16) / dstH; | |
1264 pOverlay->IntBit |= 0x08; | |
1265 } else { | |
1266 uint32_t realI; | |
1267 | |
1268 i = realI = srcH / dstH; | |
1269 pOverlay->IntBit |= 0x02; | |
1270 | |
1271 if (i < 2) { | |
1272 pOverlay->VUSF = ((srcH - dstH) << 16) / dstH; | |
1273 /* TW: Needed for LCD-scaling modes */ | |
1274 if ((flag) && (mult = (srcH / origdstH)) >= 2) | |
1275 pOverlay->pitch /= mult; | |
1276 } else { | |
1277 if (((srcPitch * i) >> 2) > 0xFFF) { | |
1278 i = (0xFFF * 2 / srcPitch); | |
1279 pOverlay->VUSF = 0xFFFF; | |
1280 } else { | |
1281 dstH = i * dstH; | |
1282 if (srcH % dstH) | |
1283 pOverlay->VUSF = ((srcH - dstH) << 16) / dstH; | |
1284 else | |
1285 pOverlay->VUSF = 0x00; | |
1286 } | |
1287 /* set video frame buffer offset */ | |
1288 pOverlay->pitch = (uint16_t) (srcPitch * i); | |
1289 } | |
1290 } | |
1291 } | |
1292 | |
1293 static void set_line_buf_size(SISOverlayPtr pOverlay) | |
1294 { | |
1295 uint8_t preHIDF; | |
1296 uint32_t i; | |
1297 uint32_t line = pOverlay->srcW; | |
1298 | |
1299 if ((pOverlay->pixelFormat == IMGFMT_YV12) || | |
1300 (pOverlay->pixelFormat == IMGFMT_I420)) { | |
1301 preHIDF = pOverlay->wHPre & 0x07; | |
1302 switch (preHIDF) { | |
1303 case 3: | |
1304 if ((line & 0xffffff00) == line) | |
1305 i = (line >> 8); | |
1306 else | |
1307 i = (line >> 8) + 1; | |
1308 pOverlay->lineBufSize = (uint8_t) (i * 32 - 1); | |
1309 break; | |
1310 case 4: | |
1311 if ((line & 0xfffffe00) == line) | |
1312 i = (line >> 9); | |
1313 else | |
1314 i = (line >> 9) + 1; | |
1315 pOverlay->lineBufSize = (uint8_t) (i * 64 - 1); | |
1316 break; | |
1317 case 5: | |
1318 if ((line & 0xfffffc00) == line) | |
1319 i = (line >> 10); | |
1320 else | |
1321 i = (line >> 10) + 1; | |
1322 pOverlay->lineBufSize = (uint8_t) (i * 128 - 1); | |
1323 break; | |
1324 case 6: | |
1325 if ((line & 0xfffff800) == line) | |
1326 i = (line >> 11); | |
1327 else | |
1328 i = (line >> 11) + 1; | |
1329 pOverlay->lineBufSize = (uint8_t) (i * 256 - 1); | |
1330 break; | |
1331 default: | |
1332 if ((line & 0xffffff80) == line) | |
1333 i = (line >> 7); | |
1334 else | |
1335 i = (line >> 7) + 1; | |
1336 pOverlay->lineBufSize = (uint8_t) (i * 16 - 1); | |
1337 break; | |
1338 } | |
1339 } else { /* YUV2, UYVY */ | |
1340 if ((line & 0xffffff8) == line) | |
1341 i = (line >> 3); | |
1342 else | |
1343 i = (line >> 3) + 1; | |
1344 pOverlay->lineBufSize = (uint8_t) (i - 1); | |
1345 } | |
1346 } | |
1347 | |
1348 static void merge_line_buf(int enable) | |
1349 { | |
1350 if (enable) { | |
1351 switch (sis_displaymode) { | |
1352 case DISPMODE_SINGLE1: | |
1353 if (sis_has_two_overlays) { | |
1354 /* dual line merge */ | |
1355 setvideoregmask(Index_VI_Control_Misc2, 0x10, 0x11); | |
1356 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); | |
1357 } else { | |
1358 setvideoregmask(Index_VI_Control_Misc2, 0x10, 0x11); | |
1359 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); | |
1360 } | |
1361 break; | |
1362 case DISPMODE_SINGLE2: | |
1363 if (sis_has_two_overlays) { | |
1364 /* line merge */ | |
1365 setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11); | |
1366 setvideoregmask(Index_VI_Control_Misc1, 0x04, 0x04); | |
1367 } else { | |
1368 setvideoregmask(Index_VI_Control_Misc2, 0x10, 0x11); | |
1369 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); | |
1370 } | |
1371 break; | |
1372 case DISPMODE_MIRROR: | |
1373 default: | |
1374 /* line merge */ | |
1375 setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11); | |
1376 setvideoregmask(Index_VI_Control_Misc1, 0x04, 0x04); | |
1377 if (sis_has_two_overlays) { | |
1378 /* line merge */ | |
1379 setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11); | |
1380 setvideoregmask(Index_VI_Control_Misc1, 0x04, 0x04); | |
1381 } | |
1382 break; | |
1383 } | |
1384 } else { | |
1385 switch (sis_displaymode) { | |
1386 case DISPMODE_SINGLE1: | |
1387 setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11); | |
1388 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); | |
1389 break; | |
1390 case DISPMODE_SINGLE2: | |
1391 if (sis_has_two_overlays) { | |
1392 setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11); | |
1393 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); | |
1394 } else { | |
1395 setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11); | |
1396 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); | |
1397 } | |
1398 break; | |
1399 case DISPMODE_MIRROR: | |
1400 default: | |
1401 setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11); | |
1402 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); | |
1403 if (sis_has_two_overlays) { | |
1404 setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11); | |
1405 setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); | |
1406 } | |
1407 break; | |
1408 } | |
1409 } | |
1410 } | |
1411 | |
1412 | |
1413 static void set_format(SISOverlayPtr pOverlay) | |
1414 { | |
1415 uint8_t fmt; | |
1416 | |
1417 switch (pOverlay->pixelFormat) { | |
1418 case IMGFMT_YV12: | |
1419 case IMGFMT_I420: | |
1420 fmt = 0x0c; | |
1421 break; | |
1422 case IMGFMT_YUY2: | |
1423 fmt = 0x28; | |
1424 break; | |
1425 case IMGFMT_UYVY: | |
1426 fmt = 0x08; | |
1427 break; | |
1428 case IMGFMT_RGB15: /* D[5:4] : 00 RGB555, 01 RGB 565 */ | |
1429 fmt = 0x00; | |
1430 break; | |
1431 case IMGFMT_RGB16: | |
1432 fmt = 0x10; | |
1433 break; | |
1434 default: | |
1435 fmt = 0x00; | |
1436 break; | |
1437 } | |
1438 setvideoregmask(Index_VI_Control_Misc0, fmt, 0x7c); | |
1439 } | |
1440 | |
1441 static void set_colorkey(void) | |
1442 { | |
1443 uint8_t r, g, b; | |
1444 | |
1445 b = (uint8_t) sis_grkey.ckey.blue; | |
1446 g = (uint8_t) sis_grkey.ckey.green; | |
1447 r = (uint8_t) sis_grkey.ckey.red; | |
1448 | |
1449 /* set color key mode */ | |
1450 setvideoregmask(Index_VI_Key_Overlay_OP, | |
1451 sis_grkey.ckey.op == CKEY_TRUE ? | |
1452 VI_ROP_DestKey : VI_ROP_Always, 0x0F); | |
1453 | |
1454 /* set colorkey values */ | |
1455 setvideoreg(Index_VI_Overlay_ColorKey_Blue_Min, (uint8_t) b); | |
1456 setvideoreg(Index_VI_Overlay_ColorKey_Green_Min, (uint8_t) g); | |
1457 setvideoreg(Index_VI_Overlay_ColorKey_Red_Min, (uint8_t) r); | |
1458 | |
1459 setvideoreg(Index_VI_Overlay_ColorKey_Blue_Max, (uint8_t) b); | |
1460 setvideoreg(Index_VI_Overlay_ColorKey_Green_Max, (uint8_t) g); | |
1461 setvideoreg(Index_VI_Overlay_ColorKey_Red_Max, (uint8_t) r); | |
1462 } | |
1463 | |
1464 static void set_brightness(uint8_t brightness) | |
1465 { | |
1466 setvideoreg(Index_VI_Brightness, brightness); | |
1467 } | |
1468 | |
1469 static void set_contrast(uint8_t contrast) | |
1470 { | |
1471 setvideoregmask(Index_VI_Contrast_Enh_Ctrl, contrast, 0x07); | |
1472 } | |
1473 | |
1474 /* Next 3 functions are 310/325 series only */ | |
1475 | |
1476 static void set_saturation(char saturation) | |
1477 { | |
1478 uint8_t temp = 0; | |
1479 | |
1480 if (saturation < 0) { | |
1481 temp |= 0x88; | |
1482 saturation = -saturation; | |
1483 } | |
1484 temp |= (saturation & 0x07); | |
1485 temp |= ((saturation & 0x07) << 4); | |
1486 | |
1487 setvideoreg(Index_VI_Saturation, temp); | |
1488 } | |
1489 | |
1490 static void set_hue(uint8_t hue) | |
1491 { | |
1492 setvideoreg(Index_VI_Hue, (hue & 0x08) ? (hue ^ 0x07) : hue); | |
1493 } | |
1494 | |
22857
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1495 VDXDriver sis_drv = { |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1496 "sis", |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1497 NULL, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1498 |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1499 .probe = sis_probe, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1500 .get_caps = sis_get_caps, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1501 .query_fourcc = sis_query_fourcc, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1502 .init = sis_init, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1503 .destroy = sis_destroy, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1504 .config_playback = sis_config_playback, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1505 .playback_on = sis_playback_on, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1506 .playback_off = sis_playback_off, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1507 .frame_sel = sis_frame_select, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1508 .get_eq = sis_get_eq, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1509 .set_eq = sis_set_eq, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1510 .get_gkey = sis_get_gkeys, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1511 .set_gkey = sis_set_gkeys, |
77def5093daf
switch to new internal vidix API, no more dlopen/dlsym, libvidix is now a fully static library with all drivers built-in
ben
parents:
22850
diff
changeset
|
1512 }; |