0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/pci.h>
0010 #include <linux/kernel.h>
0011 #include <linux/stddef.h>
0012 #include <linux/sched.h>
0013 #include <linux/i2c.h>
0014 #include <linux/delay.h>
0015 #include <linux/slab.h>
0016 #include <linux/io.h>
0017
0018 #include "i2c-pasemi-core.h"
0019
0020
0021 #define REG_MTXFIFO 0x00
0022 #define REG_MRXFIFO 0x04
0023 #define REG_SMSTA 0x14
0024 #define REG_CTL 0x1c
0025 #define REG_REV 0x28
0026
0027
0028 #define MTXFIFO_READ 0x00000400
0029 #define MTXFIFO_STOP 0x00000200
0030 #define MTXFIFO_START 0x00000100
0031 #define MTXFIFO_DATA_M 0x000000ff
0032
0033 #define MRXFIFO_EMPTY 0x00000100
0034 #define MRXFIFO_DATA_M 0x000000ff
0035
0036 #define SMSTA_XEN 0x08000000
0037 #define SMSTA_MTN 0x00200000
0038
0039 #define CTL_MRR 0x00000400
0040 #define CTL_MTR 0x00000200
0041 #define CTL_EN 0x00000800
0042 #define CTL_CLK_M 0x000000ff
0043
0044 static inline void reg_write(struct pasemi_smbus *smbus, int reg, int val)
0045 {
0046 dev_dbg(smbus->dev, "smbus write reg %x val %08x\n", reg, val);
0047 iowrite32(val, smbus->ioaddr + reg);
0048 }
0049
0050 static inline int reg_read(struct pasemi_smbus *smbus, int reg)
0051 {
0052 int ret;
0053 ret = ioread32(smbus->ioaddr + reg);
0054 dev_dbg(smbus->dev, "smbus read reg %x val %08x\n", reg, ret);
0055 return ret;
0056 }
0057
0058 #define TXFIFO_WR(smbus, reg) reg_write((smbus), REG_MTXFIFO, (reg))
0059 #define RXFIFO_RD(smbus) reg_read((smbus), REG_MRXFIFO)
0060
0061 static void pasemi_reset(struct pasemi_smbus *smbus)
0062 {
0063 u32 val = (CTL_MTR | CTL_MRR | (smbus->clk_div & CTL_CLK_M));
0064
0065 if (smbus->hw_rev >= 6)
0066 val |= CTL_EN;
0067
0068 reg_write(smbus, REG_CTL, val);
0069 }
0070
0071 static void pasemi_smb_clear(struct pasemi_smbus *smbus)
0072 {
0073 unsigned int status;
0074
0075 status = reg_read(smbus, REG_SMSTA);
0076 reg_write(smbus, REG_SMSTA, status);
0077 }
0078
0079 static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
0080 {
0081 int timeout = 10;
0082 unsigned int status;
0083
0084 status = reg_read(smbus, REG_SMSTA);
0085
0086 while (!(status & SMSTA_XEN) && timeout--) {
0087 msleep(1);
0088 status = reg_read(smbus, REG_SMSTA);
0089 }
0090
0091
0092 if (status & SMSTA_MTN)
0093 return -ENXIO;
0094
0095 if (timeout < 0) {
0096 dev_warn(smbus->dev, "Timeout, status 0x%08x\n", status);
0097 reg_write(smbus, REG_SMSTA, status);
0098 return -ETIME;
0099 }
0100
0101
0102 reg_write(smbus, REG_SMSTA, SMSTA_XEN);
0103
0104 return 0;
0105 }
0106
0107 static int pasemi_i2c_xfer_msg(struct i2c_adapter *adapter,
0108 struct i2c_msg *msg, int stop)
0109 {
0110 struct pasemi_smbus *smbus = adapter->algo_data;
0111 int read, i, err;
0112 u32 rd;
0113
0114 read = msg->flags & I2C_M_RD ? 1 : 0;
0115
0116 TXFIFO_WR(smbus, MTXFIFO_START | i2c_8bit_addr_from_msg(msg));
0117
0118 if (read) {
0119 TXFIFO_WR(smbus, msg->len | MTXFIFO_READ |
0120 (stop ? MTXFIFO_STOP : 0));
0121
0122 err = pasemi_smb_waitready(smbus);
0123 if (err)
0124 goto reset_out;
0125
0126 for (i = 0; i < msg->len; i++) {
0127 rd = RXFIFO_RD(smbus);
0128 if (rd & MRXFIFO_EMPTY) {
0129 err = -ENODATA;
0130 goto reset_out;
0131 }
0132 msg->buf[i] = rd & MRXFIFO_DATA_M;
0133 }
0134 } else {
0135 for (i = 0; i < msg->len - 1; i++)
0136 TXFIFO_WR(smbus, msg->buf[i]);
0137
0138 TXFIFO_WR(smbus, msg->buf[msg->len-1] |
0139 (stop ? MTXFIFO_STOP : 0));
0140
0141 if (stop) {
0142 err = pasemi_smb_waitready(smbus);
0143 if (err)
0144 goto reset_out;
0145 }
0146 }
0147
0148 return 0;
0149
0150 reset_out:
0151 pasemi_reset(smbus);
0152 return err;
0153 }
0154
0155 static int pasemi_i2c_xfer(struct i2c_adapter *adapter,
0156 struct i2c_msg *msgs, int num)
0157 {
0158 struct pasemi_smbus *smbus = adapter->algo_data;
0159 int ret, i;
0160
0161 pasemi_smb_clear(smbus);
0162
0163 ret = 0;
0164
0165 for (i = 0; i < num && !ret; i++)
0166 ret = pasemi_i2c_xfer_msg(adapter, &msgs[i], (i == (num - 1)));
0167
0168 return ret ? ret : num;
0169 }
0170
0171 static int pasemi_smb_xfer(struct i2c_adapter *adapter,
0172 u16 addr, unsigned short flags, char read_write, u8 command,
0173 int size, union i2c_smbus_data *data)
0174 {
0175 struct pasemi_smbus *smbus = adapter->algo_data;
0176 unsigned int rd;
0177 int read_flag, err;
0178 int len = 0, i;
0179
0180
0181 addr <<= 1;
0182 read_flag = read_write == I2C_SMBUS_READ;
0183
0184 pasemi_smb_clear(smbus);
0185
0186 switch (size) {
0187 case I2C_SMBUS_QUICK:
0188 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START |
0189 MTXFIFO_STOP);
0190 break;
0191 case I2C_SMBUS_BYTE:
0192 TXFIFO_WR(smbus, addr | read_flag | MTXFIFO_START);
0193 if (read_write)
0194 TXFIFO_WR(smbus, 1 | MTXFIFO_STOP | MTXFIFO_READ);
0195 else
0196 TXFIFO_WR(smbus, MTXFIFO_STOP | command);
0197 break;
0198 case I2C_SMBUS_BYTE_DATA:
0199 TXFIFO_WR(smbus, addr | MTXFIFO_START);
0200 TXFIFO_WR(smbus, command);
0201 if (read_write) {
0202 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
0203 TXFIFO_WR(smbus, 1 | MTXFIFO_READ | MTXFIFO_STOP);
0204 } else {
0205 TXFIFO_WR(smbus, MTXFIFO_STOP | data->byte);
0206 }
0207 break;
0208 case I2C_SMBUS_WORD_DATA:
0209 TXFIFO_WR(smbus, addr | MTXFIFO_START);
0210 TXFIFO_WR(smbus, command);
0211 if (read_write) {
0212 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
0213 TXFIFO_WR(smbus, 2 | MTXFIFO_READ | MTXFIFO_STOP);
0214 } else {
0215 TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M);
0216 TXFIFO_WR(smbus, MTXFIFO_STOP | (data->word >> 8));
0217 }
0218 break;
0219 case I2C_SMBUS_BLOCK_DATA:
0220 TXFIFO_WR(smbus, addr | MTXFIFO_START);
0221 TXFIFO_WR(smbus, command);
0222 if (read_write) {
0223 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
0224 TXFIFO_WR(smbus, 1 | MTXFIFO_READ);
0225 rd = RXFIFO_RD(smbus);
0226 len = min_t(u8, (rd & MRXFIFO_DATA_M),
0227 I2C_SMBUS_BLOCK_MAX);
0228 TXFIFO_WR(smbus, len | MTXFIFO_READ |
0229 MTXFIFO_STOP);
0230 } else {
0231 len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX);
0232 TXFIFO_WR(smbus, len);
0233 for (i = 1; i < len; i++)
0234 TXFIFO_WR(smbus, data->block[i]);
0235 TXFIFO_WR(smbus, data->block[len] | MTXFIFO_STOP);
0236 }
0237 break;
0238 case I2C_SMBUS_PROC_CALL:
0239 read_write = I2C_SMBUS_READ;
0240 TXFIFO_WR(smbus, addr | MTXFIFO_START);
0241 TXFIFO_WR(smbus, command);
0242 TXFIFO_WR(smbus, data->word & MTXFIFO_DATA_M);
0243 TXFIFO_WR(smbus, (data->word >> 8) & MTXFIFO_DATA_M);
0244 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ | MTXFIFO_START);
0245 TXFIFO_WR(smbus, 2 | MTXFIFO_STOP | MTXFIFO_READ);
0246 break;
0247 case I2C_SMBUS_BLOCK_PROC_CALL:
0248 len = min_t(u8, data->block[0], I2C_SMBUS_BLOCK_MAX - 1);
0249 read_write = I2C_SMBUS_READ;
0250 TXFIFO_WR(smbus, addr | MTXFIFO_START);
0251 TXFIFO_WR(smbus, command);
0252 TXFIFO_WR(smbus, len);
0253 for (i = 1; i <= len; i++)
0254 TXFIFO_WR(smbus, data->block[i]);
0255 TXFIFO_WR(smbus, addr | I2C_SMBUS_READ);
0256 TXFIFO_WR(smbus, MTXFIFO_READ | 1);
0257 rd = RXFIFO_RD(smbus);
0258 len = min_t(u8, (rd & MRXFIFO_DATA_M),
0259 I2C_SMBUS_BLOCK_MAX - len);
0260 TXFIFO_WR(smbus, len | MTXFIFO_READ | MTXFIFO_STOP);
0261 break;
0262
0263 default:
0264 dev_warn(&adapter->dev, "Unsupported transaction %d\n", size);
0265 return -EINVAL;
0266 }
0267
0268 err = pasemi_smb_waitready(smbus);
0269 if (err)
0270 goto reset_out;
0271
0272 if (read_write == I2C_SMBUS_WRITE)
0273 return 0;
0274
0275 switch (size) {
0276 case I2C_SMBUS_BYTE:
0277 case I2C_SMBUS_BYTE_DATA:
0278 rd = RXFIFO_RD(smbus);
0279 if (rd & MRXFIFO_EMPTY) {
0280 err = -ENODATA;
0281 goto reset_out;
0282 }
0283 data->byte = rd & MRXFIFO_DATA_M;
0284 break;
0285 case I2C_SMBUS_WORD_DATA:
0286 case I2C_SMBUS_PROC_CALL:
0287 rd = RXFIFO_RD(smbus);
0288 if (rd & MRXFIFO_EMPTY) {
0289 err = -ENODATA;
0290 goto reset_out;
0291 }
0292 data->word = rd & MRXFIFO_DATA_M;
0293 rd = RXFIFO_RD(smbus);
0294 if (rd & MRXFIFO_EMPTY) {
0295 err = -ENODATA;
0296 goto reset_out;
0297 }
0298 data->word |= (rd & MRXFIFO_DATA_M) << 8;
0299 break;
0300 case I2C_SMBUS_BLOCK_DATA:
0301 case I2C_SMBUS_BLOCK_PROC_CALL:
0302 data->block[0] = len;
0303 for (i = 1; i <= len; i ++) {
0304 rd = RXFIFO_RD(smbus);
0305 if (rd & MRXFIFO_EMPTY) {
0306 err = -ENODATA;
0307 goto reset_out;
0308 }
0309 data->block[i] = rd & MRXFIFO_DATA_M;
0310 }
0311 break;
0312 }
0313
0314 return 0;
0315
0316 reset_out:
0317 pasemi_reset(smbus);
0318 return err;
0319 }
0320
0321 static u32 pasemi_smb_func(struct i2c_adapter *adapter)
0322 {
0323 return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
0324 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
0325 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_PROC_CALL |
0326 I2C_FUNC_SMBUS_BLOCK_PROC_CALL | I2C_FUNC_I2C;
0327 }
0328
0329 static const struct i2c_algorithm smbus_algorithm = {
0330 .master_xfer = pasemi_i2c_xfer,
0331 .smbus_xfer = pasemi_smb_xfer,
0332 .functionality = pasemi_smb_func,
0333 };
0334
0335 int pasemi_i2c_common_probe(struct pasemi_smbus *smbus)
0336 {
0337 int error;
0338
0339 smbus->adapter.owner = THIS_MODULE;
0340 snprintf(smbus->adapter.name, sizeof(smbus->adapter.name),
0341 "PA Semi SMBus adapter (%s)", dev_name(smbus->dev));
0342 smbus->adapter.algo = &smbus_algorithm;
0343 smbus->adapter.algo_data = smbus;
0344
0345
0346 smbus->adapter.dev.parent = smbus->dev;
0347
0348 if (smbus->hw_rev != PASEMI_HW_REV_PCI)
0349 smbus->hw_rev = reg_read(smbus, REG_REV);
0350
0351 pasemi_reset(smbus);
0352
0353 error = devm_i2c_add_adapter(smbus->dev, &smbus->adapter);
0354 if (error)
0355 return error;
0356
0357 return 0;
0358 }