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