0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/io.h>
0010 #include <linux/export.h>
0011 #include <linux/spinlock.h>
0012 #include <linux/delay.h>
0013
0014 #include "ec_kb3310b.h"
0015
0016 static DEFINE_SPINLOCK(index_access_lock);
0017 static DEFINE_SPINLOCK(port_access_lock);
0018
0019 unsigned char ec_read(unsigned short addr)
0020 {
0021 unsigned char value;
0022 unsigned long flags;
0023
0024 spin_lock_irqsave(&index_access_lock, flags);
0025 outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
0026 outb((addr & 0x00ff), EC_IO_PORT_LOW);
0027 value = inb(EC_IO_PORT_DATA);
0028 spin_unlock_irqrestore(&index_access_lock, flags);
0029
0030 return value;
0031 }
0032 EXPORT_SYMBOL_GPL(ec_read);
0033
0034 void ec_write(unsigned short addr, unsigned char val)
0035 {
0036 unsigned long flags;
0037
0038 spin_lock_irqsave(&index_access_lock, flags);
0039 outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
0040 outb((addr & 0x00ff), EC_IO_PORT_LOW);
0041 outb(val, EC_IO_PORT_DATA);
0042
0043 inb(EC_IO_PORT_DATA);
0044 spin_unlock_irqrestore(&index_access_lock, flags);
0045 }
0046 EXPORT_SYMBOL_GPL(ec_write);
0047
0048
0049
0050
0051 int ec_query_seq(unsigned char cmd)
0052 {
0053 int timeout;
0054 unsigned char status;
0055 unsigned long flags;
0056 int ret = 0;
0057
0058 spin_lock_irqsave(&port_access_lock, flags);
0059
0060
0061 udelay(EC_REG_DELAY);
0062 outb(cmd, EC_CMD_PORT);
0063 udelay(EC_REG_DELAY);
0064
0065
0066 timeout = EC_CMD_TIMEOUT;
0067 status = inb(EC_STS_PORT);
0068 while (timeout-- && (status & (1 << 1))) {
0069 status = inb(EC_STS_PORT);
0070 udelay(EC_REG_DELAY);
0071 }
0072
0073 spin_unlock_irqrestore(&port_access_lock, flags);
0074
0075 if (timeout <= 0) {
0076 printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
0077 ret = -EINVAL;
0078 } else
0079 printk(KERN_INFO
0080 "(%x/%d)ec issued command %d status : 0x%x\n",
0081 timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
0082
0083 return ret;
0084 }
0085 EXPORT_SYMBOL_GPL(ec_query_seq);
0086
0087
0088
0089
0090 int ec_query_event_num(void)
0091 {
0092 return ec_query_seq(CMD_GET_EVENT_NUM);
0093 }
0094 EXPORT_SYMBOL(ec_query_event_num);
0095
0096
0097
0098
0099
0100
0101
0102 int ec_get_event_num(void)
0103 {
0104 int timeout = 100;
0105 unsigned char value;
0106 unsigned char status;
0107
0108 udelay(EC_REG_DELAY);
0109 status = inb(EC_STS_PORT);
0110 udelay(EC_REG_DELAY);
0111 while (timeout-- && !(status & (1 << 0))) {
0112 status = inb(EC_STS_PORT);
0113 udelay(EC_REG_DELAY);
0114 }
0115 if (timeout <= 0) {
0116 pr_info("%s: get event number timeout.\n", __func__);
0117
0118 return -EINVAL;
0119 }
0120 value = inb(EC_DAT_PORT);
0121 udelay(EC_REG_DELAY);
0122
0123 return value;
0124 }
0125 EXPORT_SYMBOL(ec_get_event_num);