1 /* 2 * i2c-au1550.c: SMBus (i2c) adapter for Alchemy PSC interface 3 * Copyright (C) 2004 Embedded Edge, LLC <dan@embeddededge.com> 4 * 5 * 2.6 port by Matt Porter <mporter@kernel.crashing.org> 6 * 7 * The documentation describes this as an SMBus controller, but it doesn't 8 * understand any of the SMBus protocol in hardware. It's really an I2C 9 * controller that could emulate most of the SMBus in software. 10 * 11 * This is just a skeleton adapter to use with the Au1550 PSC 12 * algorithm. It was developed for the Pb1550, but will work with 13 * any Au1550 board that has a similar PSC configuration. 14 * 15 * This program is free software; you can redistribute it and/or 16 * modify it under the terms of the GNU General Public License 17 * as published by the Free Software Foundation; either version 2 18 * of the License, or (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU General Public License for more details. 24 */ 25 26 #include <linux/delay.h> 27 #include <linux/kernel.h> 28 #include <linux/module.h> 29 #include <linux/platform_device.h> 30 #include <linux/errno.h> 31 #include <linux/i2c.h> 32 #include <linux/slab.h> 33 34 #include <asm/mach-au1x00/au1000.h> 35 #include <asm/mach-au1x00/au1xxx_psc.h> 36 37 #define PSC_SEL 0x00 38 #define PSC_CTRL 0x04 39 #define PSC_SMBCFG 0x08 40 #define PSC_SMBMSK 0x0C 41 #define PSC_SMBPCR 0x10 42 #define PSC_SMBSTAT 0x14 43 #define PSC_SMBEVNT 0x18 44 #define PSC_SMBTXRX 0x1C 45 #define PSC_SMBTMR 0x20 46 47 struct i2c_au1550_data { 48 void __iomem *psc_base; 49 int xfer_timeout; 50 struct i2c_adapter adap; 51 }; 52 53 static inline void WR(struct i2c_au1550_data *a, int r, unsigned long v) 54 { 55 __raw_writel(v, a->psc_base + r); 56 wmb(); 57 } 58 59 static inline unsigned long RD(struct i2c_au1550_data *a, int r) 60 { 61 return __raw_readl(a->psc_base + r); 62 } 63 64 static int wait_xfer_done(struct i2c_au1550_data *adap) 65 { 66 int i; 67 68 /* Wait for Tx Buffer Empty */ 69 for (i = 0; i < adap->xfer_timeout; i++) { 70 if (RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_TE) 71 return 0; 72 73 udelay(1); 74 } 75 76 return -ETIMEDOUT; 77 } 78 79 static int wait_ack(struct i2c_au1550_data *adap) 80 { 81 unsigned long stat; 82 83 if (wait_xfer_done(adap)) 84 return -ETIMEDOUT; 85 86 stat = RD(adap, PSC_SMBEVNT); 87 if ((stat & (PSC_SMBEVNT_DN | PSC_SMBEVNT_AN | PSC_SMBEVNT_AL)) != 0) 88 return -ETIMEDOUT; 89 90 return 0; 91 } 92 93 static int wait_master_done(struct i2c_au1550_data *adap) 94 { 95 int i; 96 97 /* Wait for Master Done. */ 98 for (i = 0; i < 2 * adap->xfer_timeout; i++) { 99 if ((RD(adap, PSC_SMBEVNT) & PSC_SMBEVNT_MD) != 0) 100 return 0; 101 udelay(1); 102 } 103 104 return -ETIMEDOUT; 105 } 106 107 static int 108 do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd, int q) 109 { 110 unsigned long stat; 111 112 /* Reset the FIFOs, clear events. */ 113 stat = RD(adap, PSC_SMBSTAT); 114 WR(adap, PSC_SMBEVNT, PSC_SMBEVNT_ALLCLR); 115 116 if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) { 117 WR(adap, PSC_SMBPCR, PSC_SMBPCR_DC); 118 while ((RD(adap, PSC_SMBPCR) & PSC_SMBPCR_DC) != 0) 119 cpu_relax(); 120 udelay(50); 121 } 122 123 /* Write out the i2c chip address and specify operation */ 124 addr <<= 1; 125 if (rd) 126 addr |= 1; 127 128 /* zero-byte xfers stop immediately */ 129 if (q) 130 addr |= PSC_SMBTXRX_STP; 131 132 /* Put byte into fifo, start up master. */ 133 WR(adap, PSC_SMBTXRX, addr); 134 WR(adap, PSC_SMBPCR, PSC_SMBPCR_MS); 135 if (wait_ack(adap)) 136 return -EIO; 137 return (q) ? wait_master_done(adap) : 0; 138 } 139 140 static int wait_for_rx_byte(struct i2c_au1550_data *adap, unsigned char *out) 141 { 142 int j; 143 144 if (wait_xfer_done(adap)) 145 return -EIO; 146 147 j = adap->xfer_timeout * 100; 148 do { 149 j--; 150 if (j <= 0) 151 return -EIO; 152 153 if ((RD(adap, PSC_SMBSTAT) & PSC_SMBSTAT_RE) == 0) 154 j = 0; 155 else 156 udelay(1); 157 } while (j > 0); 158 159 *out = RD(adap, PSC_SMBTXRX); 160 161 return 0; 162 } 163 164 static int i2c_read(struct i2c_au1550_data *adap, unsigned char *buf, 165 unsigned int len) 166 { 167 int i; 168 169 if (len == 0) 170 return 0; 171 172 /* A read is performed by stuffing the transmit fifo with 173 * zero bytes for timing, waiting for bytes to appear in the 174 * receive fifo, then reading the bytes. 175 */ 176 i = 0; 177 while (i < (len - 1)) { 178 WR(adap, PSC_SMBTXRX, 0); 179 if (wait_for_rx_byte(adap, &buf[i])) 180 return -EIO; 181 182 i++; 183 } 184 185 /* The last byte has to indicate transfer done. */ 186 WR(adap, PSC_SMBTXRX, PSC_SMBTXRX_STP); 187 if (wait_master_done(adap)) 188 return -EIO; 189 190 buf[i] = (unsigned char)(RD(adap, PSC_SMBTXRX) & 0xff); 191 return 0; 192 } 193 194 static int i2c_write(struct i2c_au1550_data *adap, unsigned char *buf, 195 unsigned int len) 196 { 197 int i; 198 unsigned long data; 199 200 if (len == 0) 201 return 0; 202 203 i = 0; 204 while (i < (len-1)) { 205 data = buf[i]; 206 WR(adap, PSC_SMBTXRX, data); 207 if (wait_ack(adap)) 208 return -EIO; 209 i++; 210 } 211 212 /* The last byte has to indicate transfer done. */ 213 data = buf[i]; 214 data |= PSC_SMBTXRX_STP; 215 WR(adap, PSC_SMBTXRX, data); 216 if (wait_master_done(adap)) 217 return -EIO; 218 return 0; 219 } 220 221 static int 222 au1550_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 223 { 224 struct i2c_au1550_data *adap = i2c_adap->algo_data; 225 struct i2c_msg *p; 226 int i, err = 0; 227 228 WR(adap, PSC_CTRL, PSC_CTRL_ENABLE); 229 230 for (i = 0; !err && i < num; i++) { 231 p = &msgs[i]; 232 err = do_address(adap, p->addr, p->flags & I2C_M_RD, 233 (p->len == 0)); 234 if (err || !p->len) 235 continue; 236 if (p->flags & I2C_M_RD) 237 err = i2c_read(adap, p->buf, p->len); 238 else 239 err = i2c_write(adap, p->buf, p->len); 240 } 241 242 /* Return the number of messages processed, or the error code. 243 */ 244 if (err == 0) 245 err = num; 246 247 WR(adap, PSC_CTRL, PSC_CTRL_SUSPEND); 248 249 return err; 250 } 251 252 static u32 au1550_func(struct i2c_adapter *adap) 253 { 254 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 255 } 256 257 static const struct i2c_algorithm au1550_algo = { 258 .master_xfer = au1550_xfer, 259 .functionality = au1550_func, 260 }; 261 262 static void i2c_au1550_setup(struct i2c_au1550_data *priv) 263 { 264 unsigned long cfg; 265 266 WR(priv, PSC_CTRL, PSC_CTRL_DISABLE); 267 WR(priv, PSC_SEL, PSC_SEL_PS_SMBUSMODE); 268 WR(priv, PSC_SMBCFG, 0); 269 WR(priv, PSC_CTRL, PSC_CTRL_ENABLE); 270 while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0) 271 cpu_relax(); 272 273 cfg = PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 | PSC_SMBCFG_DD_DISABLE; 274 WR(priv, PSC_SMBCFG, cfg); 275 276 /* Divide by 8 to get a 6.25 MHz clock. The later protocol 277 * timings are based on this clock. 278 */ 279 cfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8); 280 WR(priv, PSC_SMBCFG, cfg); 281 WR(priv, PSC_SMBMSK, PSC_SMBMSK_ALLMASK); 282 283 /* Set the protocol timer values. See Table 71 in the 284 * Au1550 Data Book for standard timing values. 285 */ 286 WR(priv, PSC_SMBTMR, PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(20) | \ 287 PSC_SMBTMR_SET_PU(20) | PSC_SMBTMR_SET_SH(20) | \ 288 PSC_SMBTMR_SET_SU(20) | PSC_SMBTMR_SET_CL(20) | \ 289 PSC_SMBTMR_SET_CH(20)); 290 291 cfg |= PSC_SMBCFG_DE_ENABLE; 292 WR(priv, PSC_SMBCFG, cfg); 293 while ((RD(priv, PSC_SMBSTAT) & PSC_SMBSTAT_SR) == 0) 294 cpu_relax(); 295 296 WR(priv, PSC_CTRL, PSC_CTRL_SUSPEND); 297 } 298 299 static void i2c_au1550_disable(struct i2c_au1550_data *priv) 300 { 301 WR(priv, PSC_SMBCFG, 0); 302 WR(priv, PSC_CTRL, PSC_CTRL_DISABLE); 303 } 304 305 /* 306 * registering functions to load algorithms at runtime 307 * Prior to calling us, the 50MHz clock frequency and routing 308 * must have been set up for the PSC indicated by the adapter. 309 */ 310 static int 311 i2c_au1550_probe(struct platform_device *pdev) 312 { 313 struct i2c_au1550_data *priv; 314 struct resource *r; 315 int ret; 316 317 priv = devm_kzalloc(&pdev->dev, sizeof(struct i2c_au1550_data), 318 GFP_KERNEL); 319 if (!priv) 320 return -ENOMEM; 321 322 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 323 priv->psc_base = devm_ioremap_resource(&pdev->dev, r); 324 if (IS_ERR(priv->psc_base)) 325 return PTR_ERR(priv->psc_base); 326 327 priv->xfer_timeout = 200; 328 329 priv->adap.nr = pdev->id; 330 priv->adap.algo = &au1550_algo; 331 priv->adap.algo_data = priv; 332 priv->adap.dev.parent = &pdev->dev; 333 strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name)); 334 335 /* Now, set up the PSC for SMBus PIO mode. */ 336 i2c_au1550_setup(priv); 337 338 ret = i2c_add_numbered_adapter(&priv->adap); 339 if (ret) { 340 i2c_au1550_disable(priv); 341 return ret; 342 } 343 344 platform_set_drvdata(pdev, priv); 345 return 0; 346 } 347 348 static int i2c_au1550_remove(struct platform_device *pdev) 349 { 350 struct i2c_au1550_data *priv = platform_get_drvdata(pdev); 351 352 i2c_del_adapter(&priv->adap); 353 i2c_au1550_disable(priv); 354 return 0; 355 } 356 357 #ifdef CONFIG_PM 358 static int i2c_au1550_suspend(struct device *dev) 359 { 360 struct i2c_au1550_data *priv = dev_get_drvdata(dev); 361 362 i2c_au1550_disable(priv); 363 364 return 0; 365 } 366 367 static int i2c_au1550_resume(struct device *dev) 368 { 369 struct i2c_au1550_data *priv = dev_get_drvdata(dev); 370 371 i2c_au1550_setup(priv); 372 373 return 0; 374 } 375 376 static const struct dev_pm_ops i2c_au1550_pmops = { 377 .suspend = i2c_au1550_suspend, 378 .resume = i2c_au1550_resume, 379 }; 380 381 #define AU1XPSC_SMBUS_PMOPS (&i2c_au1550_pmops) 382 383 #else 384 #define AU1XPSC_SMBUS_PMOPS NULL 385 #endif 386 387 static struct platform_driver au1xpsc_smbus_driver = { 388 .driver = { 389 .name = "au1xpsc_smbus", 390 .pm = AU1XPSC_SMBUS_PMOPS, 391 }, 392 .probe = i2c_au1550_probe, 393 .remove = i2c_au1550_remove, 394 }; 395 396 module_platform_driver(au1xpsc_smbus_driver); 397 398 MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC."); 399 MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550"); 400 MODULE_LICENSE("GPL"); 401 MODULE_ALIAS("platform:au1xpsc_smbus"); 402