0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "cobalt-driver.h"
0012 #include "cobalt-i2c.h"
0013
0014 struct cobalt_i2c_regs {
0015
0016 u8 prerlo;
0017 u8 dummy0[3];
0018
0019 u8 prerhi;
0020 u8 dummy1[3];
0021
0022 u8 ctr;
0023 u8 dummy2[3];
0024
0025 u8 txr_rxr;
0026 u8 dummy3[3];
0027
0028 u8 cr_sr;
0029 u8 dummy4[3];
0030 };
0031
0032
0033
0034
0035 #define M00018_CTR_BITMAP_EN_MSK (1 << 7)
0036
0037
0038 #define M00018_CTR_BITMAP_IEN_MSK (1 << 6)
0039
0040
0041
0042
0043 #define M00018_CR_BITMAP_STA_MSK (1 << 7)
0044
0045
0046 #define M00018_CR_BITMAP_STO_MSK (1 << 6)
0047
0048
0049 #define M00018_CR_BITMAP_RD_MSK (1 << 5)
0050
0051
0052 #define M00018_CR_BITMAP_WR_MSK (1 << 4)
0053
0054
0055 #define M00018_CR_BITMAP_ACK_MSK (1 << 3)
0056
0057
0058 #define M00018_CR_BITMAP_IACK_MSK (1 << 0)
0059
0060
0061
0062
0063 #define M00018_SR_BITMAP_RXACK_MSK (1 << 7)
0064
0065
0066 #define M00018_SR_BITMAP_BUSY_MSK (1 << 6)
0067
0068
0069 #define M00018_SR_BITMAP_AL_MSK (1 << 5)
0070
0071
0072 #define M00018_SR_BITMAP_TIP_MSK (1 << 1)
0073
0074
0075 #define M00018_SR_BITMAP_IF_MSK (1 << 0)
0076
0077
0078 #define I2C_FREQUENCY 400000
0079 #define ALT_CPU_FREQ 83333333
0080
0081 static struct cobalt_i2c_regs __iomem *
0082 cobalt_i2c_regs(struct cobalt *cobalt, unsigned idx)
0083 {
0084 switch (idx) {
0085 case 0:
0086 default:
0087 return (struct cobalt_i2c_regs __iomem *)
0088 (cobalt->bar1 + COBALT_I2C_0_BASE);
0089 case 1:
0090 return (struct cobalt_i2c_regs __iomem *)
0091 (cobalt->bar1 + COBALT_I2C_1_BASE);
0092 case 2:
0093 return (struct cobalt_i2c_regs __iomem *)
0094 (cobalt->bar1 + COBALT_I2C_2_BASE);
0095 case 3:
0096 return (struct cobalt_i2c_regs __iomem *)
0097 (cobalt->bar1 + COBALT_I2C_3_BASE);
0098 case 4:
0099 return (struct cobalt_i2c_regs __iomem *)
0100 (cobalt->bar1 + COBALT_I2C_HSMA_BASE);
0101 }
0102 }
0103
0104
0105
0106
0107 static int cobalt_tx_bytes(struct cobalt_i2c_regs __iomem *regs,
0108 struct i2c_adapter *adap, bool start, bool stop,
0109 u8 *data, u16 len)
0110 {
0111 unsigned long start_time;
0112 int status;
0113 int cmd;
0114 int i;
0115
0116 for (i = 0; i < len; i++) {
0117
0118 iowrite8(data[i], ®s->txr_rxr);
0119
0120
0121 if (i == 0 && start) {
0122
0123 cmd = M00018_CR_BITMAP_WR_MSK |
0124 M00018_CR_BITMAP_STA_MSK;
0125 } else if (i == len - 1 && stop) {
0126
0127 cmd = M00018_CR_BITMAP_WR_MSK |
0128 M00018_CR_BITMAP_STO_MSK;
0129 } else {
0130
0131 cmd = M00018_CR_BITMAP_WR_MSK;
0132 }
0133
0134
0135 iowrite8(cmd, ®s->cr_sr);
0136
0137
0138 start_time = jiffies;
0139 status = ioread8(®s->cr_sr);
0140 while (status & M00018_SR_BITMAP_TIP_MSK) {
0141 if (time_after(jiffies, start_time + adap->timeout))
0142 return -ETIMEDOUT;
0143 cond_resched();
0144 status = ioread8(®s->cr_sr);
0145 }
0146
0147
0148 if (status & M00018_SR_BITMAP_RXACK_MSK) {
0149
0150 return -EIO;
0151 }
0152
0153
0154 if (status & M00018_SR_BITMAP_AL_MSK) {
0155
0156 return -EIO;
0157 }
0158 }
0159 return 0;
0160 }
0161
0162
0163
0164
0165 static int cobalt_rx_bytes(struct cobalt_i2c_regs __iomem *regs,
0166 struct i2c_adapter *adap, bool start, bool stop,
0167 u8 *data, u16 len)
0168 {
0169 unsigned long start_time;
0170 int status;
0171 int cmd;
0172 int i;
0173
0174 for (i = 0; i < len; i++) {
0175
0176 if (i == 0 && start) {
0177
0178 cmd = M00018_CR_BITMAP_RD_MSK |
0179 M00018_CR_BITMAP_STA_MSK;
0180 } else if (i == len - 1 && stop) {
0181
0182 cmd = M00018_CR_BITMAP_RD_MSK |
0183 M00018_CR_BITMAP_STO_MSK;
0184 } else {
0185
0186 cmd = M00018_CR_BITMAP_RD_MSK;
0187 }
0188
0189
0190 if (i == len - 1)
0191 cmd |= M00018_CR_BITMAP_ACK_MSK;
0192
0193
0194 iowrite8(cmd, ®s->cr_sr);
0195
0196
0197 start_time = jiffies;
0198 status = ioread8(®s->cr_sr);
0199 while (status & M00018_SR_BITMAP_TIP_MSK) {
0200 if (time_after(jiffies, start_time + adap->timeout))
0201 return -ETIMEDOUT;
0202 cond_resched();
0203 status = ioread8(®s->cr_sr);
0204 }
0205
0206
0207 if (status & M00018_SR_BITMAP_AL_MSK) {
0208
0209 return -EIO;
0210 }
0211
0212
0213 data[i] = ioread8(®s->txr_rxr);
0214 }
0215 return 0;
0216 }
0217
0218
0219
0220
0221
0222 static int cobalt_stop(struct cobalt_i2c_regs __iomem *regs,
0223 struct i2c_adapter *adap)
0224 {
0225 u8 data = 0;
0226
0227 return cobalt_tx_bytes(regs, adap, true, true, &data, 1);
0228 }
0229
0230 static int cobalt_xfer(struct i2c_adapter *adap,
0231 struct i2c_msg msgs[], int num)
0232 {
0233 struct cobalt_i2c_data *data = adap->algo_data;
0234 struct cobalt_i2c_regs __iomem *regs = data->regs;
0235 struct i2c_msg *pmsg;
0236 unsigned short flags;
0237 int ret = 0;
0238 int i, j;
0239
0240 for (i = 0; i < num; i++) {
0241 int stop = (i == num - 1);
0242
0243 pmsg = &msgs[i];
0244 flags = pmsg->flags;
0245
0246 if (!(pmsg->flags & I2C_M_NOSTART)) {
0247 u8 addr = pmsg->addr << 1;
0248
0249 if (flags & I2C_M_RD)
0250 addr |= 1;
0251 if (flags & I2C_M_REV_DIR_ADDR)
0252 addr ^= 1;
0253 for (j = 0; j < adap->retries; j++) {
0254 ret = cobalt_tx_bytes(regs, adap, true, false,
0255 &addr, 1);
0256 if (!ret)
0257 break;
0258 cobalt_stop(regs, adap);
0259 }
0260 if (ret < 0)
0261 return ret;
0262 ret = 0;
0263 }
0264 if (pmsg->flags & I2C_M_RD) {
0265
0266 ret = cobalt_rx_bytes(regs, adap, false, stop,
0267 pmsg->buf, pmsg->len);
0268 if (ret < 0)
0269 goto bailout;
0270 } else {
0271
0272 ret = cobalt_tx_bytes(regs, adap, false, stop,
0273 pmsg->buf, pmsg->len);
0274 if (ret < 0)
0275 goto bailout;
0276 }
0277 }
0278 ret = i;
0279
0280 bailout:
0281 if (ret < 0)
0282 cobalt_stop(regs, adap);
0283 return ret;
0284 }
0285
0286 static u32 cobalt_func(struct i2c_adapter *adap)
0287 {
0288 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
0289 }
0290
0291
0292 static const struct i2c_adapter cobalt_i2c_adap_template = {
0293 .name = "cobalt i2c driver",
0294 .algo = NULL,
0295 .algo_data = NULL,
0296 .owner = THIS_MODULE,
0297 };
0298
0299 static const struct i2c_algorithm cobalt_algo = {
0300 .master_xfer = cobalt_xfer,
0301 .functionality = cobalt_func,
0302 };
0303
0304
0305 int cobalt_i2c_init(struct cobalt *cobalt)
0306 {
0307 int i, err;
0308 int status;
0309 int prescale;
0310 unsigned long start_time;
0311
0312 cobalt_dbg(1, "i2c init\n");
0313
0314
0315 prescale = ((ALT_CPU_FREQ) / (5 * I2C_FREQUENCY)) - 1;
0316
0317 for (i = 0; i < COBALT_NUM_ADAPTERS; i++) {
0318 struct cobalt_i2c_regs __iomem *regs =
0319 cobalt_i2c_regs(cobalt, i);
0320 struct i2c_adapter *adap = &cobalt->i2c_adap[i];
0321
0322
0323 iowrite8(M00018_CTR_BITMAP_EN_MSK, ®s->cr_sr);
0324 iowrite8(0, ®s->ctr);
0325 iowrite8(0, ®s->cr_sr);
0326
0327 start_time = jiffies;
0328 do {
0329 if (time_after(jiffies, start_time + HZ)) {
0330 if (cobalt_ignore_err) {
0331 adap->dev.parent = NULL;
0332 return 0;
0333 }
0334 return -ETIMEDOUT;
0335 }
0336 status = ioread8(®s->cr_sr);
0337 } while (status & M00018_SR_BITMAP_TIP_MSK);
0338
0339
0340 iowrite8(0, ®s->ctr);
0341 iowrite8(0, ®s->cr_sr);
0342
0343
0344 iowrite8(prescale & 0xff, ®s->prerlo);
0345 iowrite8((prescale >> 8) & 0xff, ®s->prerhi);
0346
0347 iowrite8(M00018_CTR_BITMAP_EN_MSK, ®s->ctr);
0348
0349 cobalt->i2c_data[i].cobalt = cobalt;
0350 cobalt->i2c_data[i].regs = regs;
0351 *adap = cobalt_i2c_adap_template;
0352 adap->algo = &cobalt_algo;
0353 adap->algo_data = &cobalt->i2c_data[i];
0354 adap->retries = 3;
0355 sprintf(adap->name + strlen(adap->name),
0356 " #%d-%d", cobalt->instance, i);
0357 i2c_set_adapdata(adap, &cobalt->v4l2_dev);
0358 adap->dev.parent = &cobalt->pci_dev->dev;
0359 err = i2c_add_adapter(adap);
0360 if (err) {
0361 if (cobalt_ignore_err) {
0362 adap->dev.parent = NULL;
0363 return 0;
0364 }
0365 while (i--)
0366 i2c_del_adapter(&cobalt->i2c_adap[i]);
0367 return err;
0368 }
0369 cobalt_info("registered bus %s\n", adap->name);
0370 }
0371 return 0;
0372 }
0373
0374 void cobalt_i2c_exit(struct cobalt *cobalt)
0375 {
0376 int i;
0377
0378 cobalt_dbg(1, "i2c exit\n");
0379
0380 for (i = 0; i < COBALT_NUM_ADAPTERS; i++) {
0381 cobalt_err("unregistered bus %s\n", cobalt->i2c_adap[i].name);
0382 i2c_del_adapter(&cobalt->i2c_adap[i]);
0383 }
0384 }