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