Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
bit.c
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Red Hat Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: Ben Skeggs
23  */
24 
25 #include "subdev/i2c.h"
26 
27 #ifdef CONFIG_NOUVEAU_I2C_INTERNAL
28 #define T_TIMEOUT 2200000
29 #define T_RISEFALL 1000
30 #define T_HOLD 5000
31 
32 static inline void
33 i2c_drive_scl(struct nouveau_i2c_port *port, int state)
34 {
35  nouveau_i2c_drive_scl(port, state);
36 }
37 
38 static inline void
39 i2c_drive_sda(struct nouveau_i2c_port *port, int state)
40 {
41  nouveau_i2c_drive_sda(port, state);
42 }
43 
44 static inline int
45 i2c_sense_scl(struct nouveau_i2c_port *port)
46 {
47  return nouveau_i2c_sense_scl(port);
48 }
49 
50 static inline int
51 i2c_sense_sda(struct nouveau_i2c_port *port)
52 {
53  return nouveau_i2c_sense_sda(port);
54 }
55 
56 static void
58 {
59  udelay((nsec + 500) / 1000);
60 }
61 
62 static bool
63 i2c_raise_scl(struct nouveau_i2c_port *port)
64 {
65  u32 timeout = T_TIMEOUT / T_RISEFALL;
66 
67  i2c_drive_scl(port, 1);
68  do {
69  i2c_delay(port, T_RISEFALL);
70  } while (!i2c_sense_scl(port) && --timeout);
71 
72  return timeout != 0;
73 }
74 
75 static int
76 i2c_start(struct nouveau_i2c_port *port)
77 {
78  int ret = 0;
79 
80  port->state = i2c_sense_scl(port);
81  port->state |= i2c_sense_sda(port) << 1;
82  if (port->state != 3) {
83  i2c_drive_scl(port, 0);
84  i2c_drive_sda(port, 1);
85  if (!i2c_raise_scl(port))
86  ret = -EBUSY;
87  }
88 
89  i2c_drive_sda(port, 0);
90  i2c_delay(port, T_HOLD);
91  i2c_drive_scl(port, 0);
92  i2c_delay(port, T_HOLD);
93  return ret;
94 }
95 
96 static void
97 i2c_stop(struct nouveau_i2c_port *port)
98 {
99  i2c_drive_scl(port, 0);
100  i2c_drive_sda(port, 0);
101  i2c_delay(port, T_RISEFALL);
102 
103  i2c_drive_scl(port, 1);
104  i2c_delay(port, T_HOLD);
105  i2c_drive_sda(port, 1);
106  i2c_delay(port, T_HOLD);
107 }
108 
109 static int
110 i2c_bitw(struct nouveau_i2c_port *port, int sda)
111 {
112  i2c_drive_sda(port, sda);
113  i2c_delay(port, T_RISEFALL);
114 
115  if (!i2c_raise_scl(port))
116  return -ETIMEDOUT;
117  i2c_delay(port, T_HOLD);
118 
119  i2c_drive_scl(port, 0);
120  i2c_delay(port, T_HOLD);
121  return 0;
122 }
123 
124 static int
125 i2c_bitr(struct nouveau_i2c_port *port)
126 {
127  int sda;
128 
129  i2c_drive_sda(port, 1);
130  i2c_delay(port, T_RISEFALL);
131 
132  if (!i2c_raise_scl(port))
133  return -ETIMEDOUT;
134  i2c_delay(port, T_HOLD);
135 
136  sda = i2c_sense_sda(port);
137 
138  i2c_drive_scl(port, 0);
139  i2c_delay(port, T_HOLD);
140  return sda;
141 }
142 
143 static int
144 i2c_get_byte(struct nouveau_i2c_port *port, u8 *byte, bool last)
145 {
146  int i, bit;
147 
148  *byte = 0;
149  for (i = 7; i >= 0; i--) {
150  bit = i2c_bitr(port);
151  if (bit < 0)
152  return bit;
153  *byte |= bit << i;
154  }
155 
156  return i2c_bitw(port, last ? 1 : 0);
157 }
158 
159 static int
160 i2c_put_byte(struct nouveau_i2c_port *port, u8 byte)
161 {
162  int i, ret;
163  for (i = 7; i >= 0; i--) {
164  ret = i2c_bitw(port, !!(byte & (1 << i)));
165  if (ret < 0)
166  return ret;
167  }
168 
169  ret = i2c_bitr(port);
170  if (ret == 1) /* nack */
171  ret = -EIO;
172  return ret;
173 }
174 
175 static int
176 i2c_addr(struct nouveau_i2c_port *port, struct i2c_msg *msg)
177 {
178  u32 addr = msg->addr << 1;
179  if (msg->flags & I2C_M_RD)
180  addr |= 1;
181  return i2c_put_byte(port, addr);
182 }
183 
184 static int
185 i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
186 {
187  struct nouveau_i2c_port *port = (struct nouveau_i2c_port *)adap;
188  struct i2c_msg *msg = msgs;
189  int ret = 0, mcnt = num;
190 
191  while (!ret && mcnt--) {
192  u8 remaining = msg->len;
193  u8 *ptr = msg->buf;
194 
195  ret = i2c_start(port);
196  if (ret == 0)
197  ret = i2c_addr(port, msg);
198 
199  if (msg->flags & I2C_M_RD) {
200  while (!ret && remaining--)
201  ret = i2c_get_byte(port, ptr++, !remaining);
202  } else {
203  while (!ret && remaining--)
204  ret = i2c_put_byte(port, *ptr++);
205  }
206 
207  msg++;
208  }
209 
210  i2c_stop(port);
211  return (ret < 0) ? ret : num;
212 }
213 #else
214 static int
215 i2c_bit_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
216 {
217  return -ENODEV;
218 }
219 #endif
220 
221 static u32
222 i2c_bit_func(struct i2c_adapter *adap)
223 {
225 }
226 
228  .master_xfer = i2c_bit_xfer,
229  .functionality = i2c_bit_func
230 };