135db13eaSAxel Dörfler/*
235db13eaSAxel Dörfler	Haiku S3 Virge driver adapted from the X.org Virge driver.
335db13eaSAxel Dörfler
435db13eaSAxel Dörfler	Copyright (C) 1994-1999 The XFree86 Project, Inc.  All Rights Reserved.
535db13eaSAxel Dörfler
635db13eaSAxel Dörfler	Copyright 2007-2008 Haiku, Inc.  All rights reserved.
735db13eaSAxel Dörfler	Distributed under the terms of the MIT license.
835db13eaSAxel Dörfler
935db13eaSAxel Dörfler	Authors:
1035db13eaSAxel Dörfler	Gerald Zajac 2007-2008
1135db13eaSAxel Dörfler*/
1235db13eaSAxel Dörfler
1335db13eaSAxel Dörfler
1435db13eaSAxel Dörfler#include "accel.h"
1535db13eaSAxel Dörfler#include "virge.h"
1635db13eaSAxel Dörfler
1735db13eaSAxel Dörfler
1835db13eaSAxel Dörfler
1935db13eaSAxel Dörfleruint32
2035db13eaSAxel DörflerVirge_DPMSCapabilities(void)
2135db13eaSAxel Dörfler{
2235db13eaSAxel Dörfler	// Return DPMS modes supported by this device.
2335db13eaSAxel Dörfler
2435db13eaSAxel Dörfler	return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF;
2535db13eaSAxel Dörfler}
2635db13eaSAxel Dörfler
2735db13eaSAxel Dörfler
2835db13eaSAxel Dörfleruint32
29c1379d35SAxel DörflerVirge_GetDPMSMode(void)
3035db13eaSAxel Dörfler{
3135db13eaSAxel Dörfler	// Return the current DPMS mode.
3235db13eaSAxel Dörfler
3335db13eaSAxel Dörfler	// Note:  I do not know whether the following code is correctly reading
3435db13eaSAxel Dörfler	// the current DPMS mode.  I'm assuming that reading back the bits that
3535db13eaSAxel Dörfler	// were set by function Virge_SetDPMSMode will give the current DPMS mode.
3635db13eaSAxel Dörfler
3735db13eaSAxel Dörfler	uint32 mode = B_DPMS_ON;
3835db13eaSAxel Dörfler
3935db13eaSAxel Dörfler	switch (ReadSeqReg(0x0d) & 0x70) {
4035db13eaSAxel Dörfler		case 0:
4135db13eaSAxel Dörfler			mode = B_DPMS_ON;
4235db13eaSAxel Dörfler			break;
4335db13eaSAxel Dörfler		case 0x10:
4435db13eaSAxel Dörfler			mode = B_DPMS_STAND_BY;
4535db13eaSAxel Dörfler			break;
4635db13eaSAxel Dörfler		case 0x40:
4735db13eaSAxel Dörfler			mode = B_DPMS_SUSPEND;
4835db13eaSAxel Dörfler			break;
4935db13eaSAxel Dörfler		case 0x50:
5035db13eaSAxel Dörfler			mode = B_DPMS_OFF;
5135db13eaSAxel Dörfler			break;
5235db13eaSAxel Dörfler		default:
5335db13eaSAxel Dörfler			TRACE("Unknown DPMS mode, reg sr0D: 0x%X\n", ReadSeqReg(0x0d));
5435db13eaSAxel Dörfler	}
5535db13eaSAxel Dörfler
56c1379d35SAxel Dörfler	TRACE("Virge_GetDPMSMode() mode: %d\n", mode);
5735db13eaSAxel Dörfler	return mode;
5835db13eaSAxel Dörfler}
5935db13eaSAxel Dörfler
6035db13eaSAxel Dörfler
6135db13eaSAxel Dörflerstatus_t
6235db13eaSAxel DörflerVirge_SetDPMSMode(uint32 dpmsMode)
6335db13eaSAxel Dörfler{
6435db13eaSAxel Dörfler	// Set the display into one of the Display Power Management modes,
6535db13eaSAxel Dörfler	// and return B_OK if successful, else return B_ERROR.
6635db13eaSAxel Dörfler
6735db13eaSAxel Dörfler	TRACE("Virge_SetDPMSMode() mode: %d\n", dpmsMode);
6835db13eaSAxel Dörfler
6935db13eaSAxel Dörfler	WriteSeqReg(0x08, 0x06);		// unlock extended sequencer regs
7035db13eaSAxel Dörfler
7135db13eaSAxel Dörfler	uint8 sr0D = ReadSeqReg(0x0d) & 0x03;
7235db13eaSAxel Dörfler
7335db13eaSAxel Dörfler	switch (dpmsMode) {
7435db13eaSAxel Dörfler		case B_DPMS_ON:
7535db13eaSAxel Dörfler			break;
7635db13eaSAxel Dörfler		case B_DPMS_STAND_BY:
7735db13eaSAxel Dörfler			sr0D |= 0x10;
7835db13eaSAxel Dörfler			break;
7935db13eaSAxel Dörfler		case B_DPMS_SUSPEND:
8035db13eaSAxel Dörfler			sr0D |= 0x40;
8135db13eaSAxel Dörfler			break;
8235db13eaSAxel Dörfler		case B_DPMS_OFF:
8335db13eaSAxel Dörfler			sr0D |= 0x50;
8435db13eaSAxel Dörfler			break;
8535db13eaSAxel Dörfler		default:
8635db13eaSAxel Dörfler			TRACE("Invalid DPMS mode %d\n", dpmsMode);
8735db13eaSAxel Dörfler			return B_ERROR;
8835db13eaSAxel Dörfler	}
8935db13eaSAxel Dörfler
9035db13eaSAxel Dörfler	WriteSeqReg(0x0d, sr0D);
9135db13eaSAxel Dörfler
9235db13eaSAxel Dörfler	return B_OK;
9335db13eaSAxel Dörfler}