20 #include <linux/module.h>
21 #include <linux/pci.h>
22 #include <linux/kernel.h>
23 #include <linux/stddef.h>
24 #include <linux/sched.h>
25 #include <linux/i2c.h>
27 #include <linux/slab.h>
40 #define REG_MTXFIFO 0x00
41 #define REG_MRXFIFO 0x04
42 #define REG_SMSTA 0x14
46 #define MTXFIFO_READ 0x00000400
47 #define MTXFIFO_STOP 0x00000200
48 #define MTXFIFO_START 0x00000100
49 #define MTXFIFO_DATA_M 0x000000ff
51 #define MRXFIFO_EMPTY 0x00000100
52 #define MRXFIFO_DATA_M 0x000000ff
54 #define SMSTA_XEN 0x08000000
55 #define SMSTA_MTN 0x00200000
57 #define CTL_MRR 0x00000400
58 #define CTL_MTR 0x00000200
59 #define CTL_CLK_M 0x000000ff
61 #define CLK_100K_DIV 84
62 #define CLK_400K_DIV 21
66 dev_dbg(&smbus->
dev->dev,
"smbus write reg %lx val %08x\n",
67 smbus->
base + reg, val);
75 dev_dbg(&smbus->
dev->dev,
"smbus read reg %lx val %08x\n",
76 smbus->
base + reg, ret);
80 #define TXFIFO_WR(smbus, reg) reg_write((smbus), REG_MTXFIFO, (reg))
81 #define RXFIFO_RD(smbus) reg_read((smbus), REG_MRXFIFO)
91 static int pasemi_smb_waitready(
struct pasemi_smbus *smbus)
98 while (!(status &
SMSTA_XEN) && timeout--) {
108 dev_warn(&smbus->
dev->dev,
"Timeout, status 0x%08x\n", status);
134 err = pasemi_smb_waitready(smbus);
138 for (i = 0; i < msg->
len; i++) {
147 for (i = 0; i < msg->
len - 1; i++)
162 static int pasemi_i2c_xfer(
struct i2c_adapter *adapter,
168 pasemi_smb_clear(smbus);
172 for (i = 0; i < num && !
ret; i++)
173 ret = pasemi_i2c_xfer_msg(adapter, &msgs[i], (i == (num - 1)));
175 return ret ? ret : num;
178 static int pasemi_smb_xfer(
struct i2c_adapter *adapter,
191 pasemi_smb_clear(smbus);
240 for (i = 1; i < len; i++)
260 for (i = 1; i <= len; i++)
271 dev_warn(&adapter->
dev,
"Unsupported transaction %d\n", size);
275 err = pasemi_smb_waitready(smbus);
295 if (rd & MRXFIFO_EMPTY) {
301 if (rd & MRXFIFO_EMPTY) {
309 data->
block[0] = len;
310 for (i = 1; i <= len; i ++) {
312 if (rd & MRXFIFO_EMPTY) {
338 .master_xfer = pasemi_i2c_xfer,
339 .smbus_xfer = pasemi_smb_xfer,
340 .functionality = pasemi_smb_func,
361 pasemi_smb_driver.name)) {
368 "PA Semi SMBus adapter at 0x%lx", smbus->
base);
370 smbus->
adapter.algo = &smbus_algorithm;
371 smbus->
adapter.algo_data = smbus;
382 goto out_release_region;
384 pci_set_drvdata(dev, smbus);
411 static struct pci_driver pasemi_smb_driver = {
412 .name =
"i2c-pasemi",
413 .id_table = pasemi_smb_ids,
414 .probe = pasemi_smb_probe,