/* * 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); } }