Path: blob/master/arch/mips/loongson2ef/lemote-2f/ec_kb3310b.c
26490 views
// SPDX-License-Identifier: GPL-2.0-or-later1/*2* Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook3*4* Copyright (C) 2008 Lemote Inc.5* Author: liujl <[email protected]>, 2008-04-206*/78#include <linux/io.h>9#include <linux/export.h>10#include <linux/spinlock.h>11#include <linux/delay.h>1213#include "ec_kb3310b.h"1415static DEFINE_SPINLOCK(index_access_lock);16static DEFINE_SPINLOCK(port_access_lock);1718unsigned char ec_read(unsigned short addr)19{20unsigned char value;21unsigned long flags;2223spin_lock_irqsave(&index_access_lock, flags);24outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);25outb((addr & 0x00ff), EC_IO_PORT_LOW);26value = inb(EC_IO_PORT_DATA);27spin_unlock_irqrestore(&index_access_lock, flags);2829return value;30}31EXPORT_SYMBOL_GPL(ec_read);3233void ec_write(unsigned short addr, unsigned char val)34{35unsigned long flags;3637spin_lock_irqsave(&index_access_lock, flags);38outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);39outb((addr & 0x00ff), EC_IO_PORT_LOW);40outb(val, EC_IO_PORT_DATA);41/* flush the write action */42inb(EC_IO_PORT_DATA);43spin_unlock_irqrestore(&index_access_lock, flags);44}45EXPORT_SYMBOL_GPL(ec_write);4647/*48* This function is used for EC command writes and corresponding status queries.49*/50int ec_query_seq(unsigned char cmd)51{52int timeout;53unsigned char status;54unsigned long flags;55int ret = 0;5657spin_lock_irqsave(&port_access_lock, flags);5859/* make chip goto reset mode */60udelay(EC_REG_DELAY);61outb(cmd, EC_CMD_PORT);62udelay(EC_REG_DELAY);6364/* check if the command is received by ec */65timeout = EC_CMD_TIMEOUT;66status = inb(EC_STS_PORT);67while (timeout-- && (status & (1 << 1))) {68status = inb(EC_STS_PORT);69udelay(EC_REG_DELAY);70}7172spin_unlock_irqrestore(&port_access_lock, flags);7374if (timeout <= 0) {75printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);76ret = -EINVAL;77} else78printk(KERN_INFO79"(%x/%d)ec issued command %d status : 0x%x\n",80timeout, EC_CMD_TIMEOUT - timeout, cmd, status);8182return ret;83}84EXPORT_SYMBOL_GPL(ec_query_seq);8586/*87* Send query command to EC to get the proper event number88*/89int ec_query_event_num(void)90{91return ec_query_seq(CMD_GET_EVENT_NUM);92}93EXPORT_SYMBOL(ec_query_event_num);9495/*96* Get event number from EC97*98* NOTE: This routine must follow the query_event_num function in the99* interrupt.100*/101int ec_get_event_num(void)102{103int timeout = 100;104unsigned char value;105unsigned char status;106107udelay(EC_REG_DELAY);108status = inb(EC_STS_PORT);109udelay(EC_REG_DELAY);110while (timeout-- && !(status & (1 << 0))) {111status = inb(EC_STS_PORT);112udelay(EC_REG_DELAY);113}114if (timeout <= 0) {115pr_info("%s: get event number timeout.\n", __func__);116117return -EINVAL;118}119value = inb(EC_DAT_PORT);120udelay(EC_REG_DELAY);121122return value;123}124EXPORT_SYMBOL(ec_get_event_num);125126127