2  * i2c-ocores.c: I2C bus driver for OpenCores I2C controller
 
   3  * (http://www.opencores.org/projects.cgi/web/i2c/overview).
 
   5  * Peter Korsgaard <jacmet@sunsite.dk>
 
   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.
 
  12 #include <linux/kernel.h>
 
  13 #include <linux/module.h>
 
  14 #include <linux/init.h>
 
  15 #include <linux/errno.h>
 
  16 #include <linux/platform_device.h>
 
  17 #include <linux/i2c.h>
 
  18 #include <linux/interrupt.h>
 
  19 #include <linux/wait.h>
 
  20 #include <linux/i2c-ocores.h>
 
  26         wait_queue_head_t wait;
 
  27         struct i2c_adapter adap;
 
  31         int state; /* see STATE_ */
 
  35 #define OCI2C_PRELOW            0
 
  36 #define OCI2C_PREHIGH           1
 
  37 #define OCI2C_CONTROL           2
 
  39 #define OCI2C_CMD               4 /* write only */
 
  40 #define OCI2C_STATUS            4 /* read only, same address as OCI2C_CMD */
 
  42 #define OCI2C_CTRL_IEN          0x40
 
  43 #define OCI2C_CTRL_EN           0x80
 
  45 #define OCI2C_CMD_START         0x91
 
  46 #define OCI2C_CMD_STOP          0x41
 
  47 #define OCI2C_CMD_READ          0x21
 
  48 #define OCI2C_CMD_WRITE         0x11
 
  49 #define OCI2C_CMD_READ_ACK      0x21
 
  50 #define OCI2C_CMD_READ_NACK     0x29
 
  51 #define OCI2C_CMD_IACK          0x01
 
  53 #define OCI2C_STAT_IF           0x01
 
  54 #define OCI2C_STAT_TIP          0x02
 
  55 #define OCI2C_STAT_ARBLOST      0x20
 
  56 #define OCI2C_STAT_BUSY         0x40
 
  57 #define OCI2C_STAT_NACK         0x80
 
  65 static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
 
  67         iowrite8(value, i2c->base + reg * i2c->regstep);
 
  70 static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg)
 
  72         return ioread8(i2c->base + reg * i2c->regstep);
 
  75 static void ocores_process(struct ocores_i2c *i2c)
 
  77         struct i2c_msg *msg = i2c->msg;
 
  78         u8 stat = oc_getreg(i2c, OCI2C_STATUS);
 
  80         if ((i2c->state == STATE_DONE) || (i2c->state == STATE_ERROR)) {
 
  81                 /* stop has been sent */
 
  82                 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
 
  88         if (stat & OCI2C_STAT_ARBLOST) {
 
  89                 i2c->state = STATE_ERROR;
 
  90                 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
 
  94         if ((i2c->state == STATE_START) || (i2c->state == STATE_WRITE)) {
 
  96                         (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
 
  98                 if (stat & OCI2C_STAT_NACK) {
 
  99                         i2c->state = STATE_ERROR;
 
 100                         oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
 
 104                 msg->buf[i2c->pos++] = oc_getreg(i2c, OCI2C_DATA);
 
 107         if (i2c->pos == msg->len) {
 
 113                 if (i2c->nmsgs) {       /* end? */
 
 115                         if (!(msg->flags & I2C_M_NOSTART)) {
 
 116                                 u8 addr = (msg->addr << 1);
 
 118                                 if (msg->flags & I2C_M_RD)
 
 121                                 i2c->state = STATE_START;
 
 123                                 oc_setreg(i2c, OCI2C_DATA, addr);
 
 124                                 oc_setreg(i2c, OCI2C_CMD,  OCI2C_CMD_START);
 
 127                                 i2c->state = (msg->flags & I2C_M_RD)
 
 128                                         ? STATE_READ : STATE_WRITE;
 
 130                         i2c->state = STATE_DONE;
 
 131                         oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_STOP);
 
 136         if (i2c->state == STATE_READ) {
 
 137                 oc_setreg(i2c, OCI2C_CMD, i2c->pos == (msg->len-1) ?
 
 138                           OCI2C_CMD_READ_NACK : OCI2C_CMD_READ_ACK);
 
 140                 oc_setreg(i2c, OCI2C_DATA, msg->buf[i2c->pos++]);
 
 141                 oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_WRITE);
 
 145 static irqreturn_t ocores_isr(int irq, void *dev_id)
 
 147         struct ocores_i2c *i2c = dev_id;
 
 154 static int ocores_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 
 156         struct ocores_i2c *i2c = i2c_get_adapdata(adap);
 
 161         i2c->state = STATE_START;
 
 163         oc_setreg(i2c, OCI2C_DATA,
 
 164                         (i2c->msg->addr << 1) |
 
 165                         ((i2c->msg->flags & I2C_M_RD) ? 1:0));
 
 167         oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_START);
 
 169         if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
 
 170                                (i2c->state == STATE_DONE), HZ))
 
 171                 return (i2c->state == STATE_DONE) ? num : -EIO;
 
 176 static void ocores_init(struct ocores_i2c *i2c,
 
 177                         struct ocores_i2c_platform_data *pdata)
 
 180         u8 ctrl = oc_getreg(i2c, OCI2C_CONTROL);
 
 182         /* make sure the device is disabled */
 
 183         oc_setreg(i2c, OCI2C_CONTROL, ctrl & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
 
 185         prescale = (pdata->clock_khz / (5*100)) - 1;
 
 186         oc_setreg(i2c, OCI2C_PRELOW, prescale & 0xff);
 
 187         oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8);
 
 189         /* Init the device */
 
 190         oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
 
 191         oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_IEN | OCI2C_CTRL_EN);
 
 195 static u32 ocores_func(struct i2c_adapter *adap)
 
 197         return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 
 200 static const struct i2c_algorithm ocores_algorithm = {
 
 201         .master_xfer    = ocores_xfer,
 
 202         .functionality  = ocores_func,
 
 205 static struct i2c_adapter ocores_adapter = {
 
 206         .owner          = THIS_MODULE,
 
 207         .name           = "i2c-ocores",
 
 208         .class          = I2C_CLASS_HWMON,
 
 209         .algo           = &ocores_algorithm,
 
 213 static int __devinit ocores_i2c_probe(struct platform_device *pdev)
 
 215         struct ocores_i2c *i2c;
 
 216         struct ocores_i2c_platform_data *pdata;
 
 217         struct resource *res, *res2;
 
 220         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 224         res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
 228         pdata = (struct ocores_i2c_platform_data*) pdev->dev.platform_data;
 
 232         i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
 
 236         if (!request_mem_region(res->start, res->end - res->start + 1,
 
 238                 dev_err(&pdev->dev, "Memory region busy\n");
 
 240                 goto request_mem_failed;
 
 243         i2c->base = ioremap(res->start, res->end - res->start + 1);
 
 245                 dev_err(&pdev->dev, "Unable to map registers\n");
 
 250         i2c->regstep = pdata->regstep;
 
 251         ocores_init(i2c, pdata);
 
 253         init_waitqueue_head(&i2c->wait);
 
 254         ret = request_irq(res2->start, ocores_isr, 0, pdev->name, i2c);
 
 256                 dev_err(&pdev->dev, "Cannot claim IRQ\n");
 
 257                 goto request_irq_failed;
 
 260         /* hook up driver to tree */
 
 261         platform_set_drvdata(pdev, i2c);
 
 262         i2c->adap = ocores_adapter;
 
 263         i2c_set_adapdata(&i2c->adap, i2c);
 
 264         i2c->adap.dev.parent = &pdev->dev;
 
 266         /* add i2c adapter to i2c tree */
 
 267         ret = i2c_add_adapter(&i2c->adap);
 
 269                 dev_err(&pdev->dev, "Failed to add adapter\n");
 
 270                 goto add_adapter_failed;
 
 276         free_irq(res2->start, i2c);
 
 280         release_mem_region(res->start, res->end - res->start + 1);
 
 287 static int __devexit ocores_i2c_remove(struct platform_device* pdev)
 
 289         struct ocores_i2c *i2c = platform_get_drvdata(pdev);
 
 290         struct resource *res;
 
 292         /* disable i2c logic */
 
 293         oc_setreg(i2c, OCI2C_CONTROL, oc_getreg(i2c, OCI2C_CONTROL)
 
 294                   & ~(OCI2C_CTRL_EN|OCI2C_CTRL_IEN));
 
 296         /* remove adapter & data */
 
 297         i2c_del_adapter(&i2c->adap);
 
 298         platform_set_drvdata(pdev, NULL);
 
 300         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
 302                 free_irq(res->start, i2c);
 
 306         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 308                 release_mem_region(res->start, res->end - res->start + 1);
 
 315 static struct platform_driver ocores_i2c_driver = {
 
 316         .probe  = ocores_i2c_probe,
 
 317         .remove = __devexit_p(ocores_i2c_remove),
 
 319                 .owner = THIS_MODULE,
 
 320                 .name = "ocores-i2c",
 
 324 static int __init ocores_i2c_init(void)
 
 326         return platform_driver_register(&ocores_i2c_driver);
 
 329 static void __exit ocores_i2c_exit(void)
 
 331         platform_driver_unregister(&ocores_i2c_driver);
 
 334 module_init(ocores_i2c_init);
 
 335 module_exit(ocores_i2c_exit);
 
 337 MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
 
 338 MODULE_DESCRIPTION("OpenCores I2C bus driver");
 
 339 MODULE_LICENSE("GPL");