Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mantis_i2c.c
Go to the documentation of this file.
1 /*
2  Mantis PCI bridge driver
3 
4  Copyright (C) Manu Abraham ([email protected])
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 
21 #include <asm/io.h>
22 #include <linux/ioport.h>
23 #include <linux/pci.h>
24 #include <linux/i2c.h>
25 
26 #include "dmxdev.h"
27 #include "dvbdev.h"
28 #include "dvb_demux.h"
29 #include "dvb_frontend.h"
30 #include "dvb_net.h"
31 
32 #include "mantis_common.h"
33 #include "mantis_reg.h"
34 #include "mantis_i2c.h"
35 
36 #define TRIALS 10000
37 
38 static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
39 {
40  u32 rxd, i, stat, trials;
41 
42  dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ",
43  __func__, msg->addr);
44 
45  for (i = 0; i < msg->len; i++) {
46  rxd = (msg->addr << 25) | (1 << 24)
50 
51  if (i == (msg->len - 1))
52  rxd &= ~MANTIS_I2C_STOP;
53 
56 
57  /* wait for xfer completion */
58  for (trials = 0; trials < TRIALS; trials++) {
59  stat = mmread(MANTIS_INT_STAT);
60  if (stat & MANTIS_INT_I2CDONE)
61  break;
62  }
63 
64  dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
65 
66  /* wait for xfer completion */
67  for (trials = 0; trials < TRIALS; trials++) {
68  stat = mmread(MANTIS_INT_STAT);
69  if (stat & MANTIS_INT_I2CRACK)
70  break;
71  }
72 
73  dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
74 
76  msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
77  dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
78  }
79  dprintk(MANTIS_INFO, 0, "]\n");
80 
81  return 0;
82 }
83 
84 static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
85 {
86  int i;
87  u32 txd = 0, stat, trials;
88 
89  dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ",
90  __func__, msg->addr);
91 
92  for (i = 0; i < msg->len; i++) {
93  dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
94  txd = (msg->addr << 25) | (msg->buf[i] << 8)
98 
99  if (i == (msg->len - 1))
100  txd &= ~MANTIS_I2C_STOP;
101 
104 
105  /* wait for xfer completion */
106  for (trials = 0; trials < TRIALS; trials++) {
108  if (stat & MANTIS_INT_I2CDONE)
109  break;
110  }
111 
112  dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
113 
114  /* wait for xfer completion */
115  for (trials = 0; trials < TRIALS; trials++) {
117  if (stat & MANTIS_INT_I2CRACK)
118  break;
119  }
120 
121  dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
122  }
123  dprintk(MANTIS_INFO, 0, "]\n");
124 
125  return 0;
126 }
127 
128 static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
129 {
130  int ret = 0, i = 0, trials;
131  u32 stat, data, txd;
132  struct mantis_pci *mantis;
133  struct mantis_hwconfig *config;
134 
135  mantis = i2c_get_adapdata(adapter);
136  BUG_ON(!mantis);
137  config = mantis->hwconfig;
138  BUG_ON(!config);
139 
140  dprintk(MANTIS_DEBUG, 1, "Messages:%d", num);
141  mutex_lock(&mantis->i2c_lock);
142 
143  while (i < num) {
144  /* Byte MODE */
145  if ((config->i2c_mode & MANTIS_BYTE_MODE) &&
146  ((i + 1) < num) &&
147  (msgs[i].len < 2) &&
148  (msgs[i + 1].len < 2) &&
149  (msgs[i + 1].flags & I2C_M_RD)) {
150 
151  dprintk(MANTIS_DEBUG, 0, " Byte MODE:\n");
152 
153  /* Read operation */
154  txd = msgs[i].addr << 25 | (0x1 << 24)
155  | (msgs[i].buf[0] << 16)
157 
159  /* wait for xfer completion */
160  for (trials = 0; trials < TRIALS; trials++) {
161  stat = mmread(MANTIS_INT_STAT);
162  if (stat & MANTIS_INT_I2CDONE)
163  break;
164  }
165 
166  /* check for xfer completion */
167  if (stat & MANTIS_INT_I2CDONE) {
168  /* check xfer was acknowledged */
169  if (stat & MANTIS_INT_I2CRACK) {
170  data = mmread(MANTIS_I2CDATA_CTL);
171  msgs[i + 1].buf[0] = (data >> 8) & 0xff;
172  dprintk(MANTIS_DEBUG, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
173  } else {
174  /* I/O error */
175  dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__);
176  ret = -EIO;
177  break;
178  }
179  } else {
180  /* I/O error */
181  dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__);
182  ret = -EIO;
183  break;
184  }
185  i += 2; /* Write/Read operation in one go */
186  }
187 
188  if (i < num) {
189  if (msgs[i].flags & I2C_M_RD)
190  ret = mantis_i2c_read(mantis, &msgs[i]);
191  else
192  ret = mantis_i2c_write(mantis, &msgs[i]);
193 
194  i++;
195  if (ret < 0)
196  goto bail_out;
197  }
198 
199  }
200 
201  mutex_unlock(&mantis->i2c_lock);
202 
203  return num;
204 
205 bail_out:
206  mutex_unlock(&mantis->i2c_lock);
207  return ret;
208 }
209 
210 static u32 mantis_i2c_func(struct i2c_adapter *adapter)
211 {
212  return I2C_FUNC_SMBUS_EMUL;
213 }
214 
215 static struct i2c_algorithm mantis_algo = {
216  .master_xfer = mantis_i2c_xfer,
217  .functionality = mantis_i2c_func,
218 };
219 
221 {
222  u32 intstat, intmask;
223  struct i2c_adapter *i2c_adapter = &mantis->adapter;
224  struct pci_dev *pdev = mantis->pdev;
225 
226  init_waitqueue_head(&mantis->i2c_wq);
227  mutex_init(&mantis->i2c_lock);
228  strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name));
229  i2c_set_adapdata(i2c_adapter, mantis);
230 
231  i2c_adapter->owner = THIS_MODULE;
232  i2c_adapter->algo = &mantis_algo;
233  i2c_adapter->algo_data = NULL;
234  i2c_adapter->timeout = 500;
235  i2c_adapter->retries = 3;
236  i2c_adapter->dev.parent = &pdev->dev;
237 
238  mantis->i2c_rc = i2c_add_adapter(i2c_adapter);
239  if (mantis->i2c_rc < 0)
240  return mantis->i2c_rc;
241 
242  dprintk(MANTIS_DEBUG, 1, "Initializing I2C ..");
243 
244  intstat = mmread(MANTIS_INT_STAT);
245  intmask = mmread(MANTIS_INT_MASK);
246  mmwrite(intstat, MANTIS_INT_STAT);
247  dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
248  intmask = mmread(MANTIS_INT_MASK);
249  mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
250 
251  return 0;
252 }
254 
255 int mantis_i2c_exit(struct mantis_pci *mantis)
256 {
257  u32 intmask;
258 
259  dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
260  intmask = mmread(MANTIS_INT_MASK);
261  mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
262 
263  dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
264  return i2c_del_adapter(&mantis->adapter);
265 }