7592e8bd9c
Adds a new src/ec subdir for embedded controllers (mostly found in laptops) and converts Getac P470 and Roda RK886EX to use the new ACPI EC instead of having their own copies of those functions. Signed-off-by: Sven Schnelle <svens@stackframe.org> Acked-by: Peter Stuge <peter@stuge.se> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6304 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
203 lines
4.7 KiB
C
203 lines
4.7 KiB
C
/*
|
|
* This file is part of the coreboot project.
|
|
*
|
|
* Copyright (C) 2008-2009 coresystems GmbH
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License as
|
|
* published by the Free Software Foundation; version 2 of
|
|
* the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
|
|
* MA 02110-1301 USA
|
|
*/
|
|
|
|
#include <arch/io.h>
|
|
#include <arch/romcc_io.h>
|
|
#include <console/console.h>
|
|
#include <cpu/x86/smm.h>
|
|
#include "southbridge/intel/i82801gx/i82801gx.h"
|
|
#include "southbridge/intel/i82801gx/nvs.h"
|
|
#include <ec/acpi/ec.h>
|
|
#include "ec_oem.c"
|
|
|
|
#define MAX_LCD_BRIGHTNESS 0xd8
|
|
|
|
/* The southbridge SMI handler checks whether gnvs has a
|
|
* valid pointer before calling the trap handler
|
|
*/
|
|
extern global_nvs_t *gnvs;
|
|
|
|
int mainboard_io_trap_handler(int smif)
|
|
{
|
|
u8 reg8;
|
|
u32 reg32;
|
|
|
|
switch (smif) {
|
|
case 0x2b:
|
|
printk(BIOS_DEBUG, "CPU power state switch\n");
|
|
// TODO, move to CPU handler?
|
|
break;
|
|
case 0x3d:
|
|
printk(BIOS_DEBUG, "Enable C-State SMM coordination\n");
|
|
// TODO, move to CPU handler?
|
|
break;
|
|
case 0x46:
|
|
printk(BIOS_DEBUG, "S3 DTS SMI (completely re-enable DTS)\n");
|
|
// TODO, move to CPU handler?
|
|
break;
|
|
case 0x47:
|
|
printk(BIOS_DEBUG, "S4 DTS SMI (Update NVS DTS temperature)\n");
|
|
// TODO, move to CPU handler?
|
|
break;
|
|
case 0xc0:
|
|
printk(BIOS_DEBUG, "Disable RF\n");
|
|
// TODO
|
|
break;
|
|
case 0xd0:
|
|
printk(BIOS_DEBUG, "ACBS LAN Power on\n");
|
|
// TODO
|
|
break;
|
|
case 0xd1:
|
|
printk(BIOS_DEBUG, "ACBS LAN Power off\n");
|
|
// TODO
|
|
break;
|
|
case 0xd2:
|
|
printk(BIOS_DEBUG, "Check AC status\n");
|
|
// TODO
|
|
break;
|
|
case 0xd3:
|
|
printk(BIOS_DEBUG, "Enable Bluetooth\n");
|
|
// TODO
|
|
break;
|
|
case 0xd4:
|
|
printk(BIOS_DEBUG, "Disable Bluetooth\n");
|
|
// TODO
|
|
break;
|
|
case 0xd5:
|
|
printk(BIOS_DEBUG, "Set Brightness\n");
|
|
reg8 = gnvs->brtl;
|
|
printk(BIOS_DEBUG, "brtl: %x\n", reg8);
|
|
ec_write(0x17, reg8);
|
|
break;
|
|
case 0xd6:
|
|
printk(BIOS_DEBUG, "Get Brightness\n");
|
|
reg8 = ec_read(0x17);
|
|
printk(BIOS_DEBUG, "brtl: %x\n", reg8);
|
|
gnvs->brtl = reg8;
|
|
break;
|
|
case 0xd7:
|
|
printk(BIOS_DEBUG, "Get ECO mode status\n");
|
|
// TODO
|
|
break;
|
|
case 0xd8:
|
|
printk(BIOS_DEBUG, "Get sunlight readable status\n");
|
|
// TODO
|
|
break;
|
|
case 0xd9:
|
|
printk(BIOS_DEBUG, "Get docking connection\n");
|
|
// TODO
|
|
break;
|
|
case 0xda:
|
|
printk(BIOS_DEBUG, "Power off docking\n");
|
|
// TODO
|
|
break;
|
|
case 0xdc:
|
|
printk(BIOS_DEBUG, "EC: Turn on LED on ECO enable\n");
|
|
// TODO
|
|
break;
|
|
case 0xdd:
|
|
printk(BIOS_DEBUG, "EC: Turn off LED on ECO disable\n");
|
|
// TODO
|
|
break;
|
|
case 0xde:
|
|
printk(BIOS_DEBUG, "LAN power off\n");
|
|
reg32 = inl(DEFAULT_GPIOBASE + GP_LVL);
|
|
reg32 |= (1 << 24); // Disable LAN Power
|
|
outl(reg32, DEFAULT_GPIOBASE + GP_LVL);
|
|
break;
|
|
case 0xdf:
|
|
printk(BIOS_DEBUG, "RF enable\n");
|
|
// TODO
|
|
break;
|
|
case 0xe0:
|
|
printk(BIOS_DEBUG, "Get RTC wake flag\n");
|
|
// TODO
|
|
break;
|
|
case 0xe1:
|
|
printk(BIOS_DEBUG, "Hotkey function\n");
|
|
// TODO
|
|
break;
|
|
case 0xe3:
|
|
printk(BIOS_DEBUG, "ECO disable\n");
|
|
// TODO
|
|
break;
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
/* gnvs->smif:
|
|
* On success, the IO Trap Handler returns 0
|
|
* On failure, the IO Trap Handler returns a value != 0
|
|
*/
|
|
gnvs->smif = 0;
|
|
return 1;
|
|
}
|
|
|
|
static void mainboard_smi_hotkey(u8 hotkey)
|
|
{
|
|
u8 reg8;
|
|
|
|
switch (hotkey) {
|
|
case 0x3b: break; // Fn+F1
|
|
case 0x3c: break; // Fn+F2
|
|
case 0x3d: break; // Fn+F3
|
|
case 0x3e: break; // Fn+F4
|
|
case 0x3f: break; // Fn+F5
|
|
case 0x40: // Fn+F6 (Decrease Display Brightness)
|
|
reg8 = ec_read(0x17);
|
|
reg8 = (reg8 > 8) ? (reg8 - 8) : 0;
|
|
ec_write(0x17, reg8);
|
|
return;
|
|
case 0x41: // Fn+F7 (Increase Display Brightness)
|
|
reg8 = ec_read(0x17);
|
|
reg8 += 8;
|
|
reg8 = (reg8 >= MAX_LCD_BRIGHTNESS) ? MAX_LCD_BRIGHTNESS : reg8;
|
|
ec_write(0x17, reg8);
|
|
return;
|
|
case 0x42: break; // Fn+F8
|
|
case 0x43: break; // Fn+F9
|
|
case 0x44: break; // Fn+F10
|
|
case 0x57: break; // Fn+F11
|
|
case 0x58: break; // Fn+F12
|
|
}
|
|
printk(BIOS_DEBUG, "EC hotkey: %02x\n", hotkey);
|
|
}
|
|
|
|
void mainboard_smi_gpi(u16 gpi_sts)
|
|
{
|
|
u8 source, hotkey;
|
|
send_ec_oem_command(0x5c);
|
|
source = recv_ec_oem_data();
|
|
|
|
switch (source) {
|
|
case 0:
|
|
// Some kind of ACK?
|
|
break;
|
|
case 1:
|
|
send_ec_oem_command(0x59);
|
|
hotkey = recv_ec_oem_data();
|
|
mainboard_smi_hotkey(hotkey);
|
|
break;
|
|
default:
|
|
printk(BIOS_DEBUG, "EC SMI source: %02x\n", source);
|
|
}
|
|
}
|
|
|