0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/delay.h>
0018 #include <linux/kernel.h>
0019 #include <linux/module.h>
0020 #include <linux/platform_device.h>
0021 #include <linux/errno.h>
0022 #include <linux/i2c.h>
0023 #include <linux/slab.h>
0024
0025 #include <asm/mach-au1x00/au1000.h>
0026 #include <asm/mach-au1x00/au1xxx_psc.h>
0027
0028 #define PSC_SEL 0x00
0029 #define PSC_CTRL 0x04
0030 #define PSC_SMBCFG 0x08
0031 #define PSC_SMBMSK 0x0C
0032 #define PSC_SMBPCR 0x10
0033 #define PSC_SMBSTAT 0x14
0034 #define PSC_SMBEVNT 0x18
0035 #define PSC_SMBTXRX 0x1C
0036 #define PSC_SMBTMR 0x20
0037
0038 struct i2c_au1550_data {
0039 void __iomem *psc_base;
0040 int xfer_timeout;
0041 struct i2c_adapter adap;
0042 };
0043
0044 static inline void WR(struct i2c_au1550_data *a, int r, unsigned long v)
0045 {
0046 __raw_writel(v, a->psc_base + r);
0047 wmb();
0048 }
0049
0050 static inline unsigned long RD(struct i2c_au1550_data *a, int r)
0051 {
0052 return __raw_readl(a->psc_base + r);
0053 }
0054
0055 static int wait_xfer_done(struct i2c_au1550_data *adap)
0056 {
0057 int i;
0058
0059
0060 for (i = 0; i < adap->xfer_timeout; i++) {
0061 if (RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_TE)
0062 return 0;
0063
0064 udelay(1);
0065 }
0066
0067 return -ETIMEDOUT;
0068 }
0069
0070 static int wait_ack(struct i2c_au1550_data *adap)
0071 {
0072 unsigned long stat;
0073
0074 if (wait_xfer_done(adap))
0075 return -ETIMEDOUT;
0076
0077 stat = RD(adap, PSC_SMBEVNT);
0078 if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0)
0079 return -ETIMEDOUT;
0080
0081 return 0;
0082 }
0083
0084 static int wait_master_done(struct i2c_au1550_data *adap)
0085 {
0086 int i;
0087
0088
0089 for (i = 0; i < 2 * adap->xfer_timeout; i++) {
0090 if ((RD(adap, PSC_SMBEVNT) & PSC_SMBEVNT_MD) != 0)
0091 return 0;
0092 udelay(1);
0093 }
0094
0095 return -ETIMEDOUT;
0096 }
0097
0098 static int
0099 do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q)
0100 {
0101 unsigned long stat;
0102
0103
0104 stat = RD(adap, PSC_SMBSTAT);
0105 WR(adap, PSC_SMBEVNT, PSC_SMBEVNT_ALLCLR);
0106
0107 if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) {
0108 WR(adap, PSC_SMBPCR, PSC_SMBPCR_DC);
0109 while ((RD(adap, PSC_SMBPCR) & PSC_SMBPCR_DC) != 0)
0110 cpu_relax();
0111 udelay(50);
0112 }
0113
0114
0115 addr <<= 1;
0116 if (rd)
0117 addr |= 1;
0118
0119
0120 if (q)
0121 addr |= PSC_SMBTXRX_STP;
0122
0123
0124 WR(adap, PSC_SMBTXRX, addr);
0125 WR(adap, PSC_SMBPCR, PSC_SMBPCR_MS);
0126 if (wait_ack(adap))
0127 return -EIO;
0128 return (q) ? wait_master_done(adap) : 0;
0129 }
0130
0131 static int wait_for_rx_byte(struct i2c_au1550_data *adap, unsigned char *out)
0132 {
0133 int j;
0134
0135 if (wait_xfer_done(adap))
0136 return -EIO;
0137
0138 j = adap->xfer_timeout * 100;
0139 do {
0140 j--;
0141 if (j <= 0)
0142 return -EIO;
0143
0144 if ((RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_RE) == 0)
0145 j = 0;
0146 else
0147 udelay(1);
0148 } while (j > 0);
0149
0150 *out = RD(adap, PSC_SMBTXRX);
0151
0152 return 0;
0153 }
0154
0155 static int i2c_read(struct i2c_au1550_data *adap, unsigned char *buf,
0156 unsigned int len)
0157 {
0158 int i;
0159
0160 if (len == 0)
0161 return 0;
0162
0163
0164
0165
0166
0167 i = 0;
0168 while (i < (len - 1)) {
0169 WR(adap, PSC_SMBTXRX, 0);
0170 if (wait_for_rx_byte(adap, &buf[i]))
0171 return -EIO;
0172
0173 i++;
0174 }
0175
0176
0177 WR(adap, PSC_SMBTXRX, PSC_SMBTXRX_STP);
0178 if (wait_master_done(adap))
0179 return -EIO;
0180
0181 buf[i] = (unsigned char)(RD(adap, PSC_SMBTXRX) & 0xff);
0182 return 0;
0183 }
0184
0185 static int i2c_write(struct i2c_au1550_data *adap, unsigned char *buf,
0186 unsigned int len)
0187 {
0188 int i;
0189 unsigned long data;
0190
0191 if (len == 0)
0192 return 0;
0193
0194 i = 0;
0195 while (i < (len-1)) {
0196 data = buf[i];
0197 WR(adap, PSC_SMBTXRX, data);
0198 if (wait_ack(adap))
0199 return -EIO;
0200 i++;
0201 }
0202
0203
0204 data = buf[i];
0205 data |= PSC_SMBTXRX_STP;
0206 WR(adap, PSC_SMBTXRX, data);
0207 if (wait_master_done(adap))
0208 return -EIO;
0209 return 0;
0210 }
0211
0212 static int
0213 au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
0214 {
0215 struct i2c_au1550_data *adap = i2c_adap->algo_data;
0216 struct i2c_msg *p;
0217 int i, err = 0;
0218
0219 WR(adap, PSC_CTRL, PSC_CTRL_ENABLE);
0220
0221 for (i = 0; !err && i < num; i++) {
0222 p = &msgs[i];
0223 err = do_address(adap, p->addr, p->flags & I2C_M_RD,
0224 (p->len == 0));
0225 if (err || !p->len)
0226 continue;
0227 if (p->flags & I2C_M_RD)
0228 err = i2c_read(adap, p->buf, p->len);
0229 else
0230 err = i2c_write(adap, p->buf, p->len);
0231 }
0232
0233
0234
0235 if (err == 0)
0236 err = num;
0237
0238 WR(adap, PSC_CTRL, PSC_CTRL_SUSPEND);
0239
0240 return err;
0241 }
0242
0243 static u32 au1550_func(struct i2c_adapter *adap)
0244 {
0245 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
0246 }
0247
0248 static const struct i2c_algorithm au1550_algo = {
0249 .master_xfer = au1550_xfer,
0250 .functionality = au1550_func,
0251 };
0252
0253 static void i2c_au1550_setup(struct i2c_au1550_data *priv)
0254 {
0255 unsigned long cfg;
0256
0257 WR(priv, PSC_CTRL, PSC_CTRL_DISABLE);
0258 WR(priv, PSC_SEL, PSC_SEL_PS_SMBUSMODE);
0259 WR(priv, PSC_SMBCFG, 0);
0260 WR(priv, PSC_CTRL, PSC_CTRL_ENABLE);
0261 while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0)
0262 cpu_relax();
0263
0264 cfg = PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | PSC_SMBCFG_DD_DISABLE;
0265 WR(priv, PSC_SMBCFG, cfg);
0266
0267
0268
0269
0270 cfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8);
0271 WR(priv, PSC_SMBCFG, cfg);
0272 WR(priv, PSC_SMBMSK, PSC_SMBMSK_ALLMASK);
0273
0274
0275
0276
0277 WR(priv, PSC_SMBTMR, PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(20) | \
0278 PSC_SMBTMR_SET_PU(20) | PSC_SMBTMR_SET_SH(20) | \
0279 PSC_SMBTMR_SET_SU(20) | PSC_SMBTMR_SET_CL(20) | \
0280 PSC_SMBTMR_SET_CH(20));
0281
0282 cfg |= PSC_SMBCFG_DE_ENABLE;
0283 WR(priv, PSC_SMBCFG, cfg);
0284 while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0)
0285 cpu_relax();
0286
0287 WR(priv, PSC_CTRL, PSC_CTRL_SUSPEND);
0288 }
0289
0290 static void i2c_au1550_disable(struct i2c_au1550_data *priv)
0291 {
0292 WR(priv, PSC_SMBCFG, 0);
0293 WR(priv, PSC_CTRL, PSC_CTRL_DISABLE);
0294 }
0295
0296
0297
0298
0299
0300
0301 static int
0302 i2c_au1550_probe(struct platform_device *pdev)
0303 {
0304 struct i2c_au1550_data *priv;
0305 struct resource *r;
0306 int ret;
0307
0308 priv = devm_kzalloc(&pdev->dev, sizeof(struct i2c_au1550_data),
0309 GFP_KERNEL);
0310 if (!priv)
0311 return -ENOMEM;
0312
0313 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0314 priv->psc_base = devm_ioremap_resource(&pdev->dev, r);
0315 if (IS_ERR(priv->psc_base))
0316 return PTR_ERR(priv->psc_base);
0317
0318 priv->xfer_timeout = 200;
0319
0320 priv->adap.nr = pdev->id;
0321 priv->adap.algo = &au1550_algo;
0322 priv->adap.algo_data = priv;
0323 priv->adap.dev.parent = &pdev->dev;
0324 strscpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name));
0325
0326
0327 i2c_au1550_setup(priv);
0328
0329 ret = i2c_add_numbered_adapter(&priv->adap);
0330 if (ret) {
0331 i2c_au1550_disable(priv);
0332 return ret;
0333 }
0334
0335 platform_set_drvdata(pdev, priv);
0336 return 0;
0337 }
0338
0339 static int i2c_au1550_remove(struct platform_device *pdev)
0340 {
0341 struct i2c_au1550_data *priv = platform_get_drvdata(pdev);
0342
0343 i2c_del_adapter(&priv->adap);
0344 i2c_au1550_disable(priv);
0345 return 0;
0346 }
0347
0348 #ifdef CONFIG_PM
0349 static int i2c_au1550_suspend(struct device *dev)
0350 {
0351 struct i2c_au1550_data *priv = dev_get_drvdata(dev);
0352
0353 i2c_au1550_disable(priv);
0354
0355 return 0;
0356 }
0357
0358 static int i2c_au1550_resume(struct device *dev)
0359 {
0360 struct i2c_au1550_data *priv = dev_get_drvdata(dev);
0361
0362 i2c_au1550_setup(priv);
0363
0364 return 0;
0365 }
0366
0367 static const struct dev_pm_ops i2c_au1550_pmops = {
0368 .suspend = i2c_au1550_suspend,
0369 .resume = i2c_au1550_resume,
0370 };
0371
0372 #define AU1XPSC_SMBUS_PMOPS (&i2c_au1550_pmops)
0373
0374 #else
0375 #define AU1XPSC_SMBUS_PMOPS NULL
0376 #endif
0377
0378 static struct platform_driver au1xpsc_smbus_driver = {
0379 .driver = {
0380 .name = "au1xpsc_smbus",
0381 .pm = AU1XPSC_SMBUS_PMOPS,
0382 },
0383 .probe = i2c_au1550_probe,
0384 .remove = i2c_au1550_remove,
0385 };
0386
0387 module_platform_driver(au1xpsc_smbus_driver);
0388
0389 MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
0390 MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550");
0391 MODULE_LICENSE("GPL");
0392 MODULE_ALIAS("platform:au1xpsc_smbus");