Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ec_kb3310b.c
Go to the documentation of this file.
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 }
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 */
47  spin_unlock_irqrestore(&index_access_lock, flags);
48 }
50 
51 /*
52  * This function is used for EC command writes and corresponding status queries.
53  */
54 int ec_query_seq(unsigned char cmd)
55 {
56  int timeout;
57  unsigned char status;
58  unsigned long flags;
59  int ret = 0;
60 
61  spin_lock_irqsave(&port_access_lock, flags);
62 
63  /* make chip goto reset mode */
65  outb(cmd, EC_CMD_PORT);
67 
68  /* check if the command is received by ec */
69  timeout = EC_CMD_TIMEOUT;
70  status = inb(EC_STS_PORT);
71  while (timeout-- && (status & (1 << 1))) {
72  status = inb(EC_STS_PORT);
74  }
75 
76  spin_unlock_irqrestore(&port_access_lock, flags);
77 
78  if (timeout <= 0) {
79  printk(KERN_ERR "%s: deadable error : timeout...\n", __func__);
80  ret = -EINVAL;
81  } else
83  "(%x/%d)ec issued command %d status : 0x%x\n",
84  timeout, EC_CMD_TIMEOUT - timeout, cmd, status);
85 
86  return ret;
87 }
89 
90 /*
91  * Send query command to EC to get the proper event number
92  */
94 {
96 }
98 
99 /*
100  * Get event number from EC
101  *
102  * NOTE: This routine must follow the query_event_num function in the
103  * interrupt.
104  */
106 {
107  int timeout = 100;
108  unsigned char value;
109  unsigned char status;
110 
112  status = inb(EC_STS_PORT);
114  while (timeout-- && !(status & (1 << 0))) {
115  status = inb(EC_STS_PORT);
117  }
118  if (timeout <= 0) {
119  pr_info("%s: get event number timeout.\n", __func__);
120 
121  return -EINVAL;
122  }
123  value = inb(EC_DAT_PORT);
125 
126  return value;
127 }