141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham/*
241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	Mantis PCI bridge driver
341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
48825a0970cef408fb2f1a44e3cb05d6ba41a18dbManu Abraham	Copyright (C) Manu Abraham (abraham.manu@gmail.com)
541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	This program is free software; you can redistribute it and/or modify
741e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	it under the terms of the GNU General Public License as published by
841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	the Free Software Foundation; either version 2 of the License, or
941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	(at your option) any later version.
1041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
1141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	This program is distributed in the hope that it will be useful,
1241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	but WITHOUT ANY WARRANTY; without even the implied warranty of
1341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	GNU General Public License for more details.
1541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
1641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	You should have received a copy of the GNU General Public License
1741e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	along with this program; if not, write to the Free Software
1841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham*/
2041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
2141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham#include <asm/io.h>
2241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham#include <linux/ioport.h>
23b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include <linux/pci.h>
24b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include <linux/i2c.h>
25b3b961448f702339444036f94252ff2ba7a99febManu Abraham
26b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dmxdev.h"
27b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dvbdev.h"
28b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dvb_demux.h"
29b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dvb_frontend.h"
30b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "dvb_net.h"
31b3b961448f702339444036f94252ff2ba7a99febManu Abraham
3241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham#include "mantis_common.h"
33b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "mantis_reg.h"
34b3b961448f702339444036f94252ff2ba7a99febManu Abraham#include "mantis_i2c.h"
3541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
36bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham#define TRIALS			10000
37bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
3841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abrahamstatic int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
3941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham{
403e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	u32 rxd, i, stat, trials;
4141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
42b3b961448f702339444036f94252ff2ba7a99febManu Abraham	dprintk(MANTIS_INFO, 0, "        %s:  Address=[0x%02x] <R>[ ",
43715d341c59d2563940ae07b12f949555ccbe3efbManu Abraham		__func__, msg->addr);
44715d341c59d2563940ae07b12f949555ccbe3efbManu Abraham
4541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	for (i = 0; i < msg->len; i++) {
4641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		rxd = (msg->addr << 25) | (1 << 24)
4741e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham					| MANTIS_I2C_RATE_3
4841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham					| MANTIS_I2C_STOP
4941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham					| MANTIS_I2C_PGMODE;
5041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
5141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		if (i == (msg->len - 1))
5241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham			rxd &= ~MANTIS_I2C_STOP;
5341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
54df0cca174b4d85ea041509a13e5e68b377758bf1Manu Abraham		mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
5541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		mmwrite(rxd, MANTIS_I2CDATA_CTL);
563e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
573e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham		/* wait for xfer completion */
58bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		for (trials = 0; trials < TRIALS; trials++) {
593e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			stat = mmread(MANTIS_INT_STAT);
603e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			if (stat & MANTIS_INT_I2CDONE)
613e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				break;
6241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		}
633e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
64bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
65bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
66bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		/* wait for xfer completion */
67bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		for (trials = 0; trials < TRIALS; trials++) {
68bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			stat = mmread(MANTIS_INT_STAT);
69bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			if (stat & MANTIS_INT_I2CRACK)
70bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham				break;
71bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		}
72bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
73bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
74bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
7541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		rxd = mmread(MANTIS_I2CDATA_CTL);
7641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
77b3b961448f702339444036f94252ff2ba7a99febManu Abraham		dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
7841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	}
79b3b961448f702339444036f94252ff2ba7a99febManu Abraham	dprintk(MANTIS_INFO, 0, "]\n");
8041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
8141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	return 0;
8241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham}
8341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
8441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abrahamstatic int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
8541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham{
8641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	int i;
873e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	u32 txd = 0, stat, trials;
8841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
89b3b961448f702339444036f94252ff2ba7a99febManu Abraham	dprintk(MANTIS_INFO, 0, "        %s: Address=[0x%02x] <W>[ ",
90715d341c59d2563940ae07b12f949555ccbe3efbManu Abraham		__func__, msg->addr);
91715d341c59d2563940ae07b12f949555ccbe3efbManu Abraham
9241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	for (i = 0; i < msg->len; i++) {
93b3b961448f702339444036f94252ff2ba7a99febManu Abraham		dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
9441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		txd = (msg->addr << 25) | (msg->buf[i] << 8)
9541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham					| MANTIS_I2C_RATE_3
9641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham					| MANTIS_I2C_STOP
9741e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham					| MANTIS_I2C_PGMODE;
9841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
9941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		if (i == (msg->len - 1))
10041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham			txd &= ~MANTIS_I2C_STOP;
10141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
102df0cca174b4d85ea041509a13e5e68b377758bf1Manu Abraham		mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
10341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		mmwrite(txd, MANTIS_I2CDATA_CTL);
1043e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
1053e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham		/* wait for xfer completion */
106bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		for (trials = 0; trials < TRIALS; trials++) {
1073e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			stat = mmread(MANTIS_INT_STAT);
1083e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			if (stat & MANTIS_INT_I2CDONE)
1093e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				break;
11041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		}
111bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
112bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
113bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
114bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		/* wait for xfer completion */
115bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		for (trials = 0; trials < TRIALS; trials++) {
116bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			stat = mmread(MANTIS_INT_STAT);
117bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			if (stat & MANTIS_INT_I2CRACK)
118bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham				break;
119bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		}
120bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham
121bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
12241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	}
123b3b961448f702339444036f94252ff2ba7a99febManu Abraham	dprintk(MANTIS_INFO, 0, "]\n");
12441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
12541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	return 0;
12641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham}
12741e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
12841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abrahamstatic int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
12941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham{
1303e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	int ret = 0, i = 0, trials;
1313e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	u32 stat, data, txd;
13241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	struct mantis_pci *mantis;
1333e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	struct mantis_hwconfig *config;
13441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
13541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	mantis = i2c_get_adapdata(adapter);
1363e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	BUG_ON(!mantis);
1373e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	config = mantis->hwconfig;
1383e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	BUG_ON(!config);
1393e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
1403e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	dprintk(MANTIS_DEBUG, 1, "Messages:%d", num);
141e2f67e4fb931b975058b3bd48eaac43780c92c88Manu Abraham	mutex_lock(&mantis->i2c_lock);
1423e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
1433e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	while (i < num) {
1443e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham		/* Byte MODE */
145bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		if ((config->i2c_mode & MANTIS_BYTE_MODE) &&
146bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		    ((i + 1) < num)			&&
147bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		    (msgs[i].len < 2)			&&
148bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		    (msgs[i + 1].len < 2)		&&
149bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham		    (msgs[i + 1].flags & I2C_M_RD)) {
1503e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
1513e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			dprintk(MANTIS_DEBUG, 0, "        Byte MODE:\n");
1523e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
1533e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			/* Read operation */
1543e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			txd = msgs[i].addr << 25 | (0x1 << 24)
1553e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham						 | (msgs[i].buf[0] << 16)
1563e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham						 | MANTIS_I2C_RATE_3;
1573e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
1583e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			mmwrite(txd, MANTIS_I2CDATA_CTL);
1593e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			/* wait for xfer completion */
160bc832fa2c0310c25ed60204616ccef4f8db088f3Manu Abraham			for (trials = 0; trials < TRIALS; trials++) {
1613e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				stat = mmread(MANTIS_INT_STAT);
1623e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				if (stat & MANTIS_INT_I2CDONE)
1633e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham					break;
1643e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			}
1653e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
1663e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			/* check for xfer completion */
1673e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			if (stat & MANTIS_INT_I2CDONE) {
1683e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				/* check xfer was acknowledged */
1693e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				if (stat & MANTIS_INT_I2CRACK) {
1703e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham					data = mmread(MANTIS_I2CDATA_CTL);
1713e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham					msgs[i + 1].buf[0] = (data >> 8) & 0xff;
1723e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham					dprintk(MANTIS_DEBUG, 0, "        Byte <%d> RXD=0x%02x  [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
1733e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				} else {
1743e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham					/* I/O error */
1753e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham					dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
1763e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham					ret = -EIO;
1773e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham					break;
1783e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				}
1793e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			} else {
1803e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				/* I/O error */
1813e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				dprintk(MANTIS_ERROR, 1, "        I/O error, LINE:%d", __LINE__);
1823e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				ret = -EIO;
1833e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				break;
1843e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			}
1853e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			i += 2; /* Write/Read operation in one go */
1863e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham		}
1873e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
1883e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham		if (i < num) {
1893e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			if (msgs[i].flags & I2C_M_RD)
1903e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				ret = mantis_i2c_read(mantis, &msgs[i]);
1913e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			else
1923e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				ret = mantis_i2c_write(mantis, &msgs[i]);
1933e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
1943e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			i++;
1953e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham			if (ret < 0)
1963e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham				goto bail_out;
1973e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham		}
1983e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
19941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	}
2003e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
201e2f67e4fb931b975058b3bd48eaac43780c92c88Manu Abraham	mutex_unlock(&mantis->i2c_lock);
20241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
20341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	return num;
20499d96e4e9202aa046e3e2be1813ff59c84e67608Manu Abraham
20599d96e4e9202aa046e3e2be1813ff59c84e67608Manu Abrahambail_out:
20699d96e4e9202aa046e3e2be1813ff59c84e67608Manu Abraham	mutex_unlock(&mantis->i2c_lock);
20799d96e4e9202aa046e3e2be1813ff59c84e67608Manu Abraham	return ret;
20841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham}
20941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
21041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abrahamstatic u32 mantis_i2c_func(struct i2c_adapter *adapter)
21141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham{
21241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	return I2C_FUNC_SMBUS_EMUL;
21341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham}
21441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
21541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abrahamstatic struct i2c_algorithm mantis_algo = {
21641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	.master_xfer		= mantis_i2c_xfer,
21741e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	.functionality		= mantis_i2c_func,
21841e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham};
21941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
22041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abrahamint __devinit mantis_i2c_init(struct mantis_pci *mantis)
22141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham{
222df0cca174b4d85ea041509a13e5e68b377758bf1Manu Abraham	u32 intstat, intmask;
2238154bad4c488c1a23fb504a6e751d71a39733b76Manu Abraham	struct i2c_adapter *i2c_adapter = &mantis->adapter;
2248154bad4c488c1a23fb504a6e751d71a39733b76Manu Abraham	struct pci_dev *pdev		= mantis->pdev;
22541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
226b3b961448f702339444036f94252ff2ba7a99febManu Abraham	init_waitqueue_head(&mantis->i2c_wq);
227e2f67e4fb931b975058b3bd48eaac43780c92c88Manu Abraham	mutex_init(&mantis->i2c_lock);
228f5ae4f6f482191c531ea9e50ac91d9bd2ffca171Manu Abraham	strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name));
2298154bad4c488c1a23fb504a6e751d71a39733b76Manu Abraham	i2c_set_adapdata(i2c_adapter, mantis);
2308154bad4c488c1a23fb504a6e751d71a39733b76Manu Abraham
231b3b961448f702339444036f94252ff2ba7a99febManu Abraham	i2c_adapter->owner	= THIS_MODULE;
232b3b961448f702339444036f94252ff2ba7a99febManu Abraham	i2c_adapter->algo	= &mantis_algo;
233b3b961448f702339444036f94252ff2ba7a99febManu Abraham	i2c_adapter->algo_data	= NULL;
234b3b961448f702339444036f94252ff2ba7a99febManu Abraham	i2c_adapter->timeout	= 500;
235b3b961448f702339444036f94252ff2ba7a99febManu Abraham	i2c_adapter->retries	= 3;
236b3b961448f702339444036f94252ff2ba7a99febManu Abraham	i2c_adapter->dev.parent	= &pdev->dev;
237b3b961448f702339444036f94252ff2ba7a99febManu Abraham
2388154bad4c488c1a23fb504a6e751d71a39733b76Manu Abraham	mantis->i2c_rc		= i2c_add_adapter(i2c_adapter);
23941e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	if (mantis->i2c_rc < 0)
24041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham		return mantis->i2c_rc;
24141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
242b3b961448f702339444036f94252ff2ba7a99febManu Abraham	dprintk(MANTIS_DEBUG, 1, "Initializing I2C ..");
24341e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
24441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	intstat = mmread(MANTIS_INT_STAT);
245df0cca174b4d85ea041509a13e5e68b377758bf1Manu Abraham	intmask = mmread(MANTIS_INT_MASK);
24641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	mmwrite(intstat, MANTIS_INT_STAT);
2473e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
2483e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	intmask = mmread(MANTIS_INT_MASK);
2493e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
25041e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
25141e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	return 0;
25241e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham}
253b3b961448f702339444036f94252ff2ba7a99febManu AbrahamEXPORT_SYMBOL_GPL(mantis_i2c_init);
25441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham
2554cf0b3f130a4fe573077e4d0237fd3dd0f67d3f6Mauro Carvalho Chehabint mantis_i2c_exit(struct mantis_pci *mantis)
25641e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham{
2573e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	u32 intmask;
2583e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
2593e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
2603e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	intmask = mmread(MANTIS_INT_MASK);
2613e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham	mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
2623e978a8284080d801d20cda377d9cf7c12fe68b9Manu Abraham
263b3b961448f702339444036f94252ff2ba7a99febManu Abraham	dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
26441e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham	return i2c_del_adapter(&mantis->adapter);
26541e840b13e111ba18b138d055ddd250bd5ad5e39Manu Abraham}
266b3b961448f702339444036f94252ff2ba7a99febManu AbrahamEXPORT_SYMBOL_GPL(mantis_i2c_exit);
267