Attribute VB_Name = "modAcerEC"
' ----------------------------------------------------------------------------
'  Copyright (C) 2009 Noda (Yohan Lasorsa) - http://nodadev.wordpress.com
' ----------------------------------------------------------------------------
'  This software Is provided 'as-is', without any express or implied
'  warranty. In no event will the author be held liable for any damages
'  arising from the use of this software.
'
'  Permission is granted to anyone to use this software for any purpose,
'  including commercial applications, and to alter it and redistribute it
'  freely, subject to the following restrictions:
'
'  1. The origin of this software must not be misrepresented; you must not
'     claim that you wrote the original software. If you use this software
'     in a product, an acknowledgment in the product documentation would be
'     appreciated but is not required.
'  2. Altered source versions must be plainly marked as such, and must not be
'     misrepresented as being the original software.
'  3. This notice may not be removed or altered from any source distribution.
' ----------------------------------------------------------------------------
' Alternate ACPIEC access using DLL by Daniel from http://www.flashsystems.de
' ----------------------------------------------------------------------------
Option Explicit

Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)

Declare Function GetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByRef PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function SetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByVal PortVal As Long, ByVal bSize As Byte) As Boolean
Declare Function InitializeWinIo Lib "WinIo.dll" () As Boolean
Declare Function ShutdownWinIo Lib "WinIo.dll" () As Boolean

Declare Function ECReadByte Lib "acpiec.dll" (ByVal Register As Byte, ByRef Data As Byte) As Long
Declare Function ECWriteByte Lib "acpiec.dll" (ByVal Register As Byte, ByVal Data As Byte) As Long

Public Enum FanMode
    Stopped
    SlowMode
    AutoMode
    Unknown
End Enum

Public fanStatus As FanMode

' ----------------------------------------------------------------------------
' IO ports access (using WinIO by Yariv Kaplan, http://www.internals.com)
' ----------------------------------------------------------------------------

Function InitIO() As Boolean
    InitIO = InitializeWinIo
End Function

Sub CloseIO()
    Call ShutdownWinIo
End Sub

Function GetPortValByte(ByVal iPort As Integer, ByRef iVal As Byte) As Boolean
    Dim val As Long
    GetPortValByte = GetPortVal(iPort, val, 1)
    iVal = CByte(val And &HFF)
End Function

Function SetPortValByte(ByVal iPort As Integer, ByRef iVal As Byte) As Boolean
    SetPortValByte = SetPortVal(iPort, CLng(iVal), 1)
End Function

' ----------------------------------------------------------------------------
' Acer embedded controller functions
' ----------------------------------------------------------------------------
' based on the Acer ACPI project developped by Michael Kurz, Petr Tomasek
' and Carlos Corbacho : http://aceracpi.googlecode.com
' ----------------------------------------------------------------------------

Private Function InB(iPort As Integer) As Byte
    Dim val As Byte
    InB = IIf(GetPortValByte(iPort, val), val, -1)
End Function

Private Function OutB(bValue As Byte, iPort As Integer) As Byte
    OutB = IIf(SetPortValByte(iPort, bValue), 0, -1)
End Function

Private Function WaitEC(iPort As Integer, bVal As Byte) As Boolean
    Dim i As Integer
    i = 0
    While (CBool(InB(iPort) And bVal) And (i < 100))
        Sleep 1
        i = i + 1
    Wend
    WaitEC = Not (i = 100)
End Function

Private Function WaitWriteEC() As Boolean
    WaitWriteEC = WaitEC(&H66, &H2)
End Function

Private Function WaitReadEC() As Boolean
    WaitReadEC = WaitEC(&H66, &H1)
End Function

Private Function WriteEC(bValue As Byte, iPort As Byte) As Byte
    If (settings.useAltDriver) Then
        Call ECWriteByte(iPort, bValue)
        WriteEC = 0
    Else
        If (WaitWriteEC()) Then Call OutB(&H81, &H66)
        If (WaitWriteEC()) Then Call OutB(iPort, &H62)
        If (WaitWriteEC()) Then WriteEC = OutB(bValue, &H62)
    End If
End Function

Private Function ReadEC(iPort As Byte) As Byte
    Dim val As Byte
    If (settings.useAltDriver) Then
        Call ECReadByte(iPort, val)
        ReadEC = val
    Else
        If (WaitWriteEC()) Then Call OutB(&H80, &H66)
        If (WaitWriteEC()) Then Call OutB(iPort, &H62)
        If (WaitReadEC()) Then ReadEC = InB(&H62)
    End If
End Function

' ----------------------------------------------------------------------------
' Aspire One specific functions
' ----------------------------------------------------------------------------

Function GetCpuTemp() As Byte
    GetCpuTemp = ReadEC(&H58)
End Function

Sub StartFanSlow()
    If (settings.customFanVal) Then
        Call WriteEC(settings.fanValSlow, &H55)
    Else
        If (settings.bios = BiosVersion.v3114) Then
            Call WriteEC(&H20, &H55)
        Else
            Call WriteEC(&H10, &H55)
        End If
    End If
    fanStatus = SlowMode
End Sub

Sub StopFan()
    If (settings.customFanVal) Then
        Call WriteEC(settings.fanValOff, &H55)
    Else
        If (settings.bios = BiosVersion.v3114) Then
            Call WriteEC(&H1F, &H55)
        ElseIf (settings.bios = BiosVersion.v3304) Then
            Call WriteEC(&H20, &H55)
        Else
            Call WriteEC(&HAF, &H55)
        End If
    End If
    fanStatus = Stopped
End Sub

Sub StartFanAuto()
    If (settings.customFanVal) Then
        Call WriteEC(settings.fanValAuto, &H55)
    Else
        Call WriteEC(0, &H55)
    End If
    fanStatus = AutoMode
End Sub

