1 /* 2 Mantis PCI bridge driver 3 4 Copyright (C) Manu Abraham (abraham.manu@gmail.com) 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) 47 | MANTIS_I2C_RATE_3 48 | MANTIS_I2C_STOP 49 | MANTIS_I2C_PGMODE; 50 51 if (i == (msg->len - 1)) 52 rxd &= ~MANTIS_I2C_STOP; 53 54 mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); 55 mmwrite(rxd, MANTIS_I2CDATA_CTL); 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 75 rxd = mmread(MANTIS_I2CDATA_CTL); 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) 95 | MANTIS_I2C_RATE_3 96 | MANTIS_I2C_STOP 97 | MANTIS_I2C_PGMODE; 98 99 if (i == (msg->len - 1)) 100 txd &= ~MANTIS_I2C_STOP; 101 102 mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT); 103 mmwrite(txd, MANTIS_I2CDATA_CTL); 104 105 /* wait for xfer completion */ 106 for (trials = 0; trials < TRIALS; trials++) { 107 stat = mmread(MANTIS_INT_STAT); 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++) { 116 stat = mmread(MANTIS_INT_STAT); 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) 156 | MANTIS_I2C_RATE_3; 157 158 mmwrite(txd, MANTIS_I2CDATA_CTL); 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 const struct i2c_algorithm mantis_algo = { 216 .master_xfer = mantis_i2c_xfer, 217 .functionality = mantis_i2c_func, 218 }; 219 220 int mantis_i2c_init(struct mantis_pci *mantis) 221 { 222 u32 intstat; 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 mmread(MANTIS_INT_MASK); 246 mmwrite(intstat, MANTIS_INT_STAT); 247 dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); 248 mantis_mask_ints(mantis, MANTIS_INT_I2CDONE); 249 250 return 0; 251 } 252 EXPORT_SYMBOL_GPL(mantis_i2c_init); 253 254 int mantis_i2c_exit(struct mantis_pci *mantis) 255 { 256 dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt"); 257 mantis_mask_ints(mantis, MANTIS_INT_I2CDONE); 258 259 dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter"); 260 i2c_del_adapter(&mantis->adapter); 261 262 return 0; 263 } 264 EXPORT_SYMBOL_GPL(mantis_i2c_exit); 265