drm/i915: fix mask bits setting
[pandora-kernel.git] / drivers / gpu / drm / i915 / intel_dp_i2c.c
1 /*
2  * Copyright © 2009 Keith Packard
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that copyright
7  * notice and this permission notice appear in supporting documentation, and
8  * that the name of the copyright holders not be used in advertising or
9  * publicity pertaining to distribution of the software without specific,
10  * written prior permission.  The copyright holders make no representations
11  * about the suitability of this software for any purpose.  It is provided "as
12  * is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20  * OF THIS SOFTWARE.
21  */
22
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/delay.h>
26 #include <linux/slab.h>
27 #include <linux/init.h>
28 #include <linux/errno.h>
29 #include <linux/sched.h>
30 #include <linux/i2c.h>
31 #include "intel_dp.h"
32 #include "drmP.h"
33
34 /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
35
36 #define MODE_I2C_START  1
37 #define MODE_I2C_WRITE  2
38 #define MODE_I2C_READ   4
39 #define MODE_I2C_STOP   8
40
41 static int
42 i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
43                             uint8_t write_byte, uint8_t *read_byte)
44 {
45         struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
46         uint16_t address = algo_data->address;
47         uint8_t msg[5];
48         uint8_t reply[2];
49         int msg_bytes;
50         int reply_bytes;
51         int ret;
52
53         /* Set up the command byte */
54         if (mode & MODE_I2C_READ)
55                 msg[0] = AUX_I2C_READ << 4;
56         else
57                 msg[0] = AUX_I2C_WRITE << 4;
58
59         if (!(mode & MODE_I2C_STOP))
60                 msg[0] |= AUX_I2C_MOT << 4;
61
62         msg[1] = address >> 8;
63         msg[2] = address;
64
65         switch (mode) {
66         case MODE_I2C_WRITE:
67                 msg[3] = 0;
68                 msg[4] = write_byte;
69                 msg_bytes = 5;
70                 reply_bytes = 1;
71                 break;
72         case MODE_I2C_READ:
73                 msg[3] = 0;
74                 msg_bytes = 4;
75                 reply_bytes = 2;
76                 break;
77         default:
78                 msg_bytes = 3;
79                 reply_bytes = 1;
80                 break;
81         }
82
83         for (;;) {
84                 ret = (*algo_data->aux_ch)(adapter,
85                                            msg, msg_bytes,
86                                            reply, reply_bytes);
87                 if (ret < 0) {
88                         DRM_DEBUG("aux_ch failed %d\n", ret);
89                         return ret;
90                 }
91                 switch (reply[0] & AUX_I2C_REPLY_MASK) {
92                 case AUX_I2C_REPLY_ACK:
93                         if (mode == MODE_I2C_READ) {
94                                 *read_byte = reply[1];
95                         }
96                         return reply_bytes - 1;
97                 case AUX_I2C_REPLY_NACK:
98                         DRM_DEBUG("aux_ch nack\n");
99                         return -EREMOTEIO;
100                 case AUX_I2C_REPLY_DEFER:
101                         DRM_DEBUG("aux_ch defer\n");
102                         udelay(100);
103                         break;
104                 default:
105                         DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]);
106                         return -EREMOTEIO;
107                 }
108         }
109 }
110
111 /*
112  * I2C over AUX CH
113  */
114
115 /*
116  * Send the address. If the I2C link is running, this 'restarts'
117  * the connection with the new address, this is used for doing
118  * a write followed by a read (as needed for DDC)
119  */
120 static int
121 i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
122 {
123         struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
124         int mode = MODE_I2C_START;
125         int ret;
126
127         if (reading)
128                 mode |= MODE_I2C_READ;
129         else
130                 mode |= MODE_I2C_WRITE;
131         algo_data->address = address;
132         algo_data->running = true;
133         ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
134         return ret;
135 }
136
137 /*
138  * Stop the I2C transaction. This closes out the link, sending
139  * a bare address packet with the MOT bit turned off
140  */
141 static void
142 i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
143 {
144         struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
145         int mode = MODE_I2C_STOP;
146
147         if (reading)
148                 mode |= MODE_I2C_READ;
149         else
150                 mode |= MODE_I2C_WRITE;
151         if (algo_data->running) {
152                 (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
153                 algo_data->running = false;
154         }
155 }
156
157 /*
158  * Write a single byte to the current I2C address, the
159  * the I2C link must be running or this returns -EIO
160  */
161 static int
162 i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
163 {
164         struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
165         int ret;
166
167         if (!algo_data->running)
168                 return -EIO;
169
170         ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
171         return ret;
172 }
173
174 /*
175  * Read a single byte from the current I2C address, the
176  * I2C link must be running or this returns -EIO
177  */
178 static int
179 i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
180 {
181         struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
182         int ret;
183
184         if (!algo_data->running)
185                 return -EIO;
186
187         ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
188         return ret;
189 }
190
191 static int
192 i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
193                      struct i2c_msg *msgs,
194                      int num)
195 {
196         int ret = 0;
197         bool reading = false;
198         int m;
199         int b;
200
201         for (m = 0; m < num; m++) {
202                 u16 len = msgs[m].len;
203                 u8 *buf = msgs[m].buf;
204                 reading = (msgs[m].flags & I2C_M_RD) != 0;
205                 ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
206                 if (ret < 0)
207                         break;
208                 if (reading) {
209                         for (b = 0; b < len; b++) {
210                                 ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
211                                 if (ret < 0)
212                                         break;
213                         }
214                 } else {
215                         for (b = 0; b < len; b++) {
216                                 ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
217                                 if (ret < 0)
218                                         break;
219                         }
220                 }
221                 if (ret < 0)
222                         break;
223         }
224         if (ret >= 0)
225                 ret = num;
226         i2c_algo_dp_aux_stop(adapter, reading);
227         DRM_DEBUG("dp_aux_xfer return %d\n", ret);
228         return ret;
229 }
230
231 static u32
232 i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
233 {
234         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
235                I2C_FUNC_SMBUS_READ_BLOCK_DATA |
236                I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
237                I2C_FUNC_10BIT_ADDR;
238 }
239
240 static const struct i2c_algorithm i2c_dp_aux_algo = {
241         .master_xfer    = i2c_algo_dp_aux_xfer,
242         .functionality  = i2c_algo_dp_aux_functionality,
243 };
244
245 static void
246 i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
247 {
248         (void) i2c_algo_dp_aux_address(adapter, 0, false);
249         (void) i2c_algo_dp_aux_stop(adapter, false);
250                                            
251 }
252
253 static int
254 i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
255 {
256         adapter->algo = &i2c_dp_aux_algo;
257         adapter->retries = 3;
258         i2c_dp_aux_reset_bus(adapter);
259         return 0;
260 }
261
262 int
263 i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
264 {
265         int error;
266         
267         error = i2c_dp_aux_prepare_bus(adapter);
268         if (error)
269                 return error;
270         error = i2c_add_adapter(adapter);
271         return error;
272 }
273 EXPORT_SYMBOL(i2c_dp_aux_add_bus);