Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mips/loongson/lemote-2f/ec_kb3310b.c
10818 views
1
/*
2
* Basic KB3310B Embedded Controller support for the YeeLoong 2F netbook
3
*
4
* Copyright (C) 2008 Lemote Inc.
5
* Author: liujl <[email protected]>, 2008-04-20
6
*
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
11
*/
12
13
#include <linux/module.h>
14
#include <linux/spinlock.h>
15
#include <linux/delay.h>
16
17
#include "ec_kb3310b.h"
18
19
static DEFINE_SPINLOCK(index_access_lock);
20
static DEFINE_SPINLOCK(port_access_lock);
21
22
unsigned char ec_read(unsigned short addr)
23
{
24
unsigned char value;
25
unsigned long flags;
26
27
spin_lock_irqsave(&index_access_lock, flags);
28
outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
29
outb((addr & 0x00ff), EC_IO_PORT_LOW);
30
value = inb(EC_IO_PORT_DATA);
31
spin_unlock_irqrestore(&index_access_lock, flags);
32
33
return value;
34
}
35
EXPORT_SYMBOL_GPL(ec_read);
36
37
void ec_write(unsigned short addr, unsigned char val)
38
{
39
unsigned long flags;
40
41
spin_lock_irqsave(&index_access_lock, flags);
42
outb((addr & 0xff00) >> 8, EC_IO_PORT_HIGH);
43
outb((addr & 0x00ff), EC_IO_PORT_LOW);
44
outb(val, EC_IO_PORT_DATA);
45
/* flush the write action */
46
inb(EC_IO_PORT_DATA);
47
spin_unlock_irqrestore(&index_access_lock, flags);
48
49
return;
50
}
51
EXPORT_SYMBOL_GPL(ec_write);
52
53
/*
54
* This function is used for EC command writes and corresponding status queries.
55
*/
56
int ec_query_seq(unsigned char cmd)
57
{
58
int timeout;
59
unsigned char status;
60
unsigned long flags;
61
int ret = 0;
62
63
spin_lock_irqsave(&port_access_lock, flags);
64
65
/* make chip goto reset mode */
66
udelay(EC_REG_DELAY);
67
outb(cmd, EC_CMD_PORT);
68
udelay(EC_REG_DELAY);
69
70
/* check if the command is received by ec */
71
timeout = EC_CMD_TIMEOUT;
72
status = inb(EC_STS_PORT);
73
while (timeout-- && (status & (1 << 1))) {
74
status = inb(EC_STS_PORT);
75
udelay(EC_REG_DELAY);
76
}
77
78
spin_unlock_irqrestore(&port_access_lock, flags);
79
80
if (timeout <= 0) {
81
printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
82
ret = -EINVAL;
83
} else
84
printk(KERN_INFO
85
"(%x/%d)ec issued command %d status : 0x%x\n",
86
timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
87
88
return ret;
89
}
90
EXPORT_SYMBOL_GPL(ec_query_seq);
91
92
/*
93
* Send query command to EC to get the proper event number
94
*/
95
int ec_query_event_num(void)
96
{
97
return ec_query_seq(CMD_GET_EVENT_NUM);
98
}
99
EXPORT_SYMBOL(ec_query_event_num);
100
101
/*
102
* Get event number from EC
103
*
104
* NOTE: This routine must follow the query_event_num function in the
105
* interrupt.
106
*/
107
int ec_get_event_num(void)
108
{
109
int timeout = 100;
110
unsigned char value;
111
unsigned char status;
112
113
udelay(EC_REG_DELAY);
114
status = inb(EC_STS_PORT);
115
udelay(EC_REG_DELAY);
116
while (timeout-- && !(status & (1 << 0))) {
117
status = inb(EC_STS_PORT);
118
udelay(EC_REG_DELAY);
119
}
120
if (timeout <= 0) {
121
pr_info("%s: get event number timeout.\n", __func__);
122
123
return -EINVAL;
124
}
125
value = inb(EC_DAT_PORT);
126
udelay(EC_REG_DELAY);
127
128
return value;
129
}
130
EXPORT_SYMBOL(ec_get_event_num);
131
132