1 /* 2 * i2c-ocores.c: I2C bus driver for OpenCores I2C controller 3 * (http://www.opencores.org/projects.cgi/web/i2c/overview). 4 * 5 * Peter Korsgaard <jacmet@sunsite.dk> 6 * 7 * This file is licensed under the terms of the GNU General Public License 8 * version 2. This program is licensed "as is" without any warranty of any 9 * kind, whether express or implied. 10 */ 11 12 /* 13 * Device tree configuration: 14 * 15 * Required properties: 16 * - compatible : "opencores,i2c-ocores" 17 * - reg : bus address start and address range size of device 18 * - interrupts : interrupt number 19 * - regstep : size of device registers in bytes 20 * - clock-frequency : frequency of bus clock in Hz 21 * 22 * Example: 23 * 24 * i2c0: ocores@a0000000 { 25 * compatible = "opencores,i2c-ocores"; 26 * reg = <0xa0000000 0x8>; 27 * interrupts = <10>; 28 * 29 * regstep = <1>; 30 * clock-frequency = <20000000>; 31 * 32 * -- Devices connected on this I2C bus get 33 * -- defined here; address- and size-cells 34 * -- apply to these child devices 35 * 36 * #address-cells = <1>; 37 * #size-cells = <0>; 38 * 39 * dummy@60 { 40 * compatible = "dummy"; 41 * reg = <60>; 42 * }; 43 * }; 44 * 45 */ 46 47 #include <linux/kernel.h> 48 #include <linux/module.h> 49 #include <linux/init.h> 50 #include <linux/errno.h> 51 #include <linux/platform_device.h> 52 #include <linux/i2c.h> 53 #include <linux/interrupt.h> 54 #include <linux/wait.h> 55 #include <linux/i2c-ocores.h> 56 #include <linux/slab.h> 57 #include <linux/io.h> 58 59 struct ocores_i2c { 60 void __iomem *base; 61 int regstep; 62 wait_queue_head_t wait; 63 struct i2c_adapter adap; 64 struct i2c_msg *msg; 65 int pos; 66 int nmsgs; 67 int state; /* see STATE_ */ 68 int clock_khz; 69 }; 70 71 /* registers */ 72 #define OCI2C_PRELOW 0 73 #define OCI2C_PREHIGH 1 74 #define OCI2C_CONTROL 2 75 #define OCI2C_DATA 3 76 #define OCI2C_CMD 4 /* write only */ 77 #define OCI2C_STATUS 4 /* read only, same address as OCI2C_CMD */ 78 79 #define OCI2C_CTRL_IEN 0x40 80 #define OCI2C_CTRL_EN 0x80 81 82 #define OCI2C_CMD_START 0x91 83 #define OCI2C_CMD_STOP 0x41 84 #define OCI2C_CMD_READ 0x21 85 #define OCI2C_CMD_WRITE 0x11 86 #define OCI2C_CMD_READ_ACK 0x21 87 #define OCI2C_CMD_READ_NACK 0x29 88 #define OCI2C_CMD_IACK 0x01 89 90 #define OCI2C_STAT_IF 0x01 91 #define OCI2C_STAT_TIP 0x02 92 #define OCI2C_STAT_ARBLOST 0x20 93 #define OCI2C_STAT_BUSY 0x40 94 #define OCI2C_STAT_NACK 0x80 95 96 #define STATE_DONE 0 97 #define STATE_START 1 98 #define STATE_WRITE 2 99 #define STATE_READ 3 100 #define STATE_ERROR 4 101 102 static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) 103 { 104 iowrite8(value, i2c->base + reg * i2c->regstep); 105 } 106 107 static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) 108 { 109 return ioread8(i2c->base + reg * i2c->regstep); 110 } 111 112 static void ocores_process(struct ocores_i2c *i2c) 113 { 114 struct i2c_msg *msg = i2c->msg; 115 u8 stat = oc_getreg(i2c, OCI2C_STATUS); 116 117 if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) { 118 /* stop has been sent */ 119 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); 120 wake_up(&i2c->wait); 121 return; 122 } 123 124 /* error? */ 125 if (stat & OCI2C_STAT_ARBLOST) { 126 i2c->state = STATE_ERROR; 127 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); 128 return; 129 } 130 131 if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) { 132 i2c->state = 133 (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE; 134 135 if (stat & OCI2C_STAT_NACK) { 136 i2c->state = STATE_ERROR; 137 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); 138 return; 139 } 140 } else 141 msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA); 142 143 /* end of msg? */ 144 if (i2c->pos == msg->len) { 145 i2c->nmsgs--; 146 i2c->msg++; 147 i2c->pos = 0; 148 msg = i2c->msg; 149 150 if (i2c->nmsgs) { /* end? */ 151 /* send start? */ 152 if (!(msg->flags & I2C_M_NOSTART)) { 153 u8 addr = (msg->addr << 1); 154 155 if (msg->flags & I2C_M_RD) 156 addr |= 1; 157 158 i2c->state = STATE_START; 159 160 oc_setreg(i2c, OCI2C_DATA, addr); 161 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); 162 return; 163 } else 164 i2c->state = (msg->flags & I2C_M_RD) 165 ? STATE_READ : STATE_WRITE; 166 } else { 167 i2c->state = STATE_DONE; 168 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP); 169 return; 170 } 171 } 172 173 if (i2c->state == STATE_READ) { 174 oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ? 175 OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK); 176 } else { 177 oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]); 178 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE); 179 } 180 } 181 182 static irqreturn_t ocores_isr(int irq, void *dev_id) 183 { 184 struct ocores_i2c *i2c = dev_id; 185 186 ocores_process(i2c); 187 188 return IRQ_HANDLED; 189 } 190 191 static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 192 { 193 struct ocores_i2c *i2c = i2c_get_adapdata(adap); 194 195 i2c->msg = msgs; 196 i2c->pos = 0; 197 i2c->nmsgs = num; 198 i2c->state = STATE_START; 199 200 oc_setreg(i2c, OCI2C_DATA, 201 (i2c->msg->addr << 1) | 202 ((i2c->msg->flags & I2C_M_RD) ? 1:0)); 203 204 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START); 205 206 if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) || 207 (i2c->state == STATE_DONE), HZ)) 208 return (i2c->state == STATE_DONE) ? num : -EIO; 209 else 210 return -ETIMEDOUT; 211 } 212 213 static void ocores_init(struct ocores_i2c *i2c) 214 { 215 int prescale; 216 u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); 217 218 /* make sure the device is disabled */ 219 oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); 220 221 prescale = (i2c->clock_khz / (5*100)) - 1; 222 oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff); 223 oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8); 224 225 /* Init the device */ 226 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK); 227 oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN); 228 } 229 230 231 static u32 ocores_func(struct i2c_adapter *adap) 232 { 233 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 234 } 235 236 static const struct i2c_algorithm ocores_algorithm = { 237 .master_xfer = ocores_xfer, 238 .functionality = ocores_func, 239 }; 240 241 static struct i2c_adapter ocores_adapter = { 242 .owner = THIS_MODULE, 243 .name = "i2c-ocores", 244 .class = I2C_CLASS_HWMON | I2C_CLASS_SPD, 245 .algo = &ocores_algorithm, 246 }; 247 248 #ifdef CONFIG_OF 249 static int ocores_i2c_of_probe(struct platform_device* pdev, 250 struct ocores_i2c* i2c) 251 { 252 const __be32* val; 253 254 val = of_get_property(pdev->dev.of_node, "regstep", NULL); 255 if (!val) { 256 dev_err(&pdev->dev, "Missing required parameter 'regstep'"); 257 return -ENODEV; 258 } 259 i2c->regstep = be32_to_cpup(val); 260 261 val = of_get_property(pdev->dev.of_node, "clock-frequency", NULL); 262 if (!val) { 263 dev_err(&pdev->dev, 264 "Missing required parameter 'clock-frequency'"); 265 return -ENODEV; 266 } 267 i2c->clock_khz = be32_to_cpup(val) / 1000; 268 269 return 0; 270 } 271 #else 272 #define ocores_i2c_of_probe(pdev,i2c) -ENODEV 273 #endif 274 275 static int __devinit ocores_i2c_probe(struct platform_device *pdev) 276 { 277 struct ocores_i2c *i2c; 278 struct ocores_i2c_platform_data *pdata; 279 struct resource *res, *res2; 280 int ret; 281 int i; 282 283 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 284 if (!res) 285 return -ENODEV; 286 287 res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 288 if (!res2) 289 return -ENODEV; 290 291 i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); 292 if (!i2c) 293 return -ENOMEM; 294 295 if (!devm_request_mem_region(&pdev->dev, res->start, 296 resource_size(res), pdev->name)) { 297 dev_err(&pdev->dev, "Memory region busy\n"); 298 return -EBUSY; 299 } 300 301 i2c->base = devm_ioremap_nocache(&pdev->dev, res->start, 302 resource_size(res)); 303 if (!i2c->base) { 304 dev_err(&pdev->dev, "Unable to map registers\n"); 305 return -EIO; 306 } 307 308 pdata = pdev->dev.platform_data; 309 if (pdata) { 310 i2c->regstep = pdata->regstep; 311 i2c->clock_khz = pdata->clock_khz; 312 } else { 313 ret = ocores_i2c_of_probe(pdev, i2c); 314 if (ret) 315 return ret; 316 } 317 318 ocores_init(i2c); 319 320 init_waitqueue_head(&i2c->wait); 321 ret = devm_request_irq(&pdev->dev, res2->start, ocores_isr, 0, 322 pdev->name, i2c); 323 if (ret) { 324 dev_err(&pdev->dev, "Cannot claim IRQ\n"); 325 return ret; 326 } 327 328 /* hook up driver to tree */ 329 platform_set_drvdata(pdev, i2c); 330 i2c->adap = ocores_adapter; 331 i2c_set_adapdata(&i2c->adap, i2c); 332 i2c->adap.dev.parent = &pdev->dev; 333 i2c->adap.dev.of_node = pdev->dev.of_node; 334 335 /* add i2c adapter to i2c tree */ 336 ret = i2c_add_adapter(&i2c->adap); 337 if (ret) { 338 dev_err(&pdev->dev, "Failed to add adapter\n"); 339 return ret; 340 } 341 342 /* add in known devices to the bus */ 343 if (pdata) { 344 for (i = 0; i < pdata->num_devices; i++) 345 i2c_new_device(&i2c->adap, pdata->devices + i); 346 } 347 348 return 0; 349 } 350 351 static int __devexit ocores_i2c_remove(struct platform_device* pdev) 352 { 353 struct ocores_i2c *i2c = platform_get_drvdata(pdev); 354 355 /* disable i2c logic */ 356 oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL) 357 & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); 358 359 /* remove adapter & data */ 360 i2c_del_adapter(&i2c->adap); 361 platform_set_drvdata(pdev, NULL); 362 363 return 0; 364 } 365 366 #ifdef CONFIG_PM 367 static int ocores_i2c_suspend(struct platform_device *pdev, pm_message_t state) 368 { 369 struct ocores_i2c *i2c = platform_get_drvdata(pdev); 370 u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL); 371 372 /* make sure the device is disabled */ 373 oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN)); 374 375 return 0; 376 } 377 378 static int ocores_i2c_resume(struct platform_device *pdev) 379 { 380 struct ocores_i2c *i2c = platform_get_drvdata(pdev); 381 382 ocores_init(i2c); 383 384 return 0; 385 } 386 #else 387 #define ocores_i2c_suspend NULL 388 #define ocores_i2c_resume NULL 389 #endif 390 391 static struct of_device_id ocores_i2c_match[] = { 392 { .compatible = "opencores,i2c-ocores", }, 393 {}, 394 }; 395 MODULE_DEVICE_TABLE(of, ocores_i2c_match); 396 397 static struct platform_driver ocores_i2c_driver = { 398 .probe = ocores_i2c_probe, 399 .remove = __devexit_p(ocores_i2c_remove), 400 .suspend = ocores_i2c_suspend, 401 .resume = ocores_i2c_resume, 402 .driver = { 403 .owner = THIS_MODULE, 404 .name = "ocores-i2c", 405 .of_match_table = ocores_i2c_match, 406 }, 407 }; 408 409 module_platform_driver(ocores_i2c_driver); 410 411 MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>"); 412 MODULE_DESCRIPTION("OpenCores I2C bus driver"); 413 MODULE_LICENSE("GPL"); 414 MODULE_ALIAS("platform:ocores-i2c"); 415