···66 * Copyright (c) 2003, 2004 Zultys Technologies.77 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>88 *99- * Based on original work by 99+ * Based on original work by1010 * Ian DaSilva <idasilva@mvista.com>1111 * Armin Kuster <akuster@mvista.com>1212 * Matt Porter <mporter@mvista.com>···8686 KERN_DEBUG " sts = 0x%02x, extsts = 0x%02x\n"8787 KERN_DEBUG " clkdiv = 0x%02x, xfrcnt = 0x%02x\n"8888 KERN_DEBUG " xtcntlss = 0x%02x, directcntl = 0x%02x\n",8989- in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts), 9090- in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt), 8989+ in_8(&iic->cntl), in_8(&iic->mdcntl), in_8(&iic->sts),9090+ in_8(&iic->extsts), in_8(&iic->clkdiv), in_8(&iic->xfrcnt),9191 in_8(&iic->xtcntlss), in_8(&iic->directcntl));9292}9393# define DUMP_REGS(h,dev) dump_iic_regs((h),(dev))···125125{126126 out_8(&dev->vaddr->intmsk, enable ? INTRMSK_EIMTC : 0);127127}128128-128128+129129/*130130 * Initialize IIC interface.131131 */···134134 volatile struct iic_regs __iomem *iic = dev->vaddr;135135136136 DBG("%d: init\n", dev->idx);137137-137137+138138 /* Clear master address */139139 out_8(&iic->lmadr, 0);140140 out_8(&iic->hmadr, 0);···160160161161 /* Clear control register */162162 out_8(&iic->cntl, 0);163163-163163+164164 /* Enable interrupts if possible */165165 iic_interrupt_mode(dev, dev->irq >= 0);166166···171171 DUMP_REGS("iic_init", dev);172172}173173174174-/* 174174+/*175175 * Reset IIC interface176176 */177177static void iic_dev_reset(struct ibm_iic_private* dev)···179179 volatile struct iic_regs __iomem *iic = dev->vaddr;180180 int i;181181 u8 dc;182182-182182+183183 DBG("%d: soft reset\n", dev->idx);184184 DUMP_REGS("reset", dev);185185-185185+186186 /* Place chip in the reset state */187187 out_8(&iic->xtcntlss, XTCNTLSS_SRST);188188-188188+189189 /* Check if bus is free */190190- dc = in_8(&iic->directcntl); 190190+ dc = in_8(&iic->directcntl);191191 if (!DIRCTNL_FREE(dc)){192192 DBG("%d: trying to regain bus control\n", dev->idx);193193-193193+194194 /* Try to set bus free state */195195- out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC); 196196-195195+ out_8(&iic->directcntl, DIRCNTL_SDAC | DIRCNTL_SCC);196196+197197 /* Wait until we regain bus control */198198 for (i = 0; i < 100; ++i){199199 dc = in_8(&iic->directcntl);200200 if (DIRCTNL_FREE(dc))201201 break;202202-202202+203203 /* Toggle SCL line */204204 dc ^= DIRCNTL_SCC;205205 out_8(&iic->directcntl, dc);206206 udelay(10);207207 dc ^= DIRCNTL_SCC;208208 out_8(&iic->directcntl, dc);209209-209209+210210 /* be nice */211211 cond_resched();212212 }213213 }214214-214214+215215 /* Remove reset */216216 out_8(&iic->xtcntlss, 0);217217-217217+218218 /* Reinitialize interface */219219 iic_dev_init(dev);220220}···324324{325325 struct ibm_iic_private* dev = (struct ibm_iic_private*)dev_id;326326 volatile struct iic_regs __iomem *iic = dev->vaddr;327327-328328- DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n", 327327+328328+ DBG2("%d: irq handler, STS = 0x%02x, EXTSTS = 0x%02x\n",329329 dev->idx, in_8(&iic->sts), in_8(&iic->extsts));330330-330330+331331 /* Acknowledge IRQ and wakeup iic_wait_for_tc */332332 out_8(&iic->sts, STS_IRQA | STS_SCMP);333333 wake_up_interruptible(&dev->wq);334334-334334+335335 return IRQ_HANDLED;336336}337337···341341 */342342static int iic_xfer_result(struct ibm_iic_private* dev)343343{344344- volatile struct iic_regs __iomem *iic = dev->vaddr; 345345-344344+ volatile struct iic_regs __iomem *iic = dev->vaddr;345345+346346 if (unlikely(in_8(&iic->sts) & STS_ERR)){347347- DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx, 347347+ DBG("%d: xfer error, EXTSTS = 0x%02x\n", dev->idx,348348 in_8(&iic->extsts));349349-349349+350350 /* Clear errors and possible pending IRQs */351351- out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD | 351351+ out_8(&iic->extsts, EXTSTS_IRQP | EXTSTS_IRQD |352352 EXTSTS_LA | EXTSTS_ICT | EXTSTS_XFRA);353353-353353+354354 /* Flush master data buffer */355355 out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);356356-356356+357357 /* Is bus free?358358 * If error happened during combined xfer359359 * IIC interface is usually stuck in some strange···376376{377377 volatile struct iic_regs __iomem *iic = dev->vaddr;378378 unsigned long x;379379-379379+380380 DBG("%d: iic_abort_xfer\n", dev->idx);381381-381381+382382 out_8(&iic->cntl, CNTL_HMT);383383-383383+384384 /*385385 * Wait for the abort command to complete.386386 * It's not worth to be optimized, just poll (timeout >= 1 tick)···405405 * Returns the number of transferred bytes or error (<0)406406 */407407static int iic_wait_for_tc(struct ibm_iic_private* dev){408408-408408+409409 volatile struct iic_regs __iomem *iic = dev->vaddr;410410 int ret = 0;411411-411411+412412 if (dev->irq >= 0){413413 /* Interrupt mode */414414- ret = wait_event_interruptible_timeout(dev->wq, 414414+ ret = wait_event_interruptible_timeout(dev->wq,415415 !(in_8(&iic->sts) & STS_PT), dev->adap.timeout * HZ);416416417417 if (unlikely(ret < 0))···424424 else {425425 /* Polling mode */426426 unsigned long x = jiffies + dev->adap.timeout * HZ;427427-427427+428428 while (in_8(&iic->sts) & STS_PT){429429 if (unlikely(time_after(jiffies, x))){430430 DBG("%d: poll timeout\n", dev->idx);431431 ret = -ETIMEDOUT;432432 break;433433 }434434-434434+435435 if (unlikely(signal_pending(current))){436436 DBG("%d: poll interrupted\n", dev->idx);437437 ret = -ERESTARTSYS;438438 break;439439 }440440 schedule();441441- } 441441+ }442442 }443443-443443+444444 if (unlikely(ret < 0))445445 iic_abort_xfer(dev);446446 else447447 ret = iic_xfer_result(dev);448448-448448+449449 DBG2("%d: iic_wait_for_tc -> %d\n", dev->idx, ret);450450-450450+451451 return ret;452452}453453454454/*455455 * Low level master transfer routine456456 */457457-static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm, 457457+static int iic_xfer_bytes(struct ibm_iic_private* dev, struct i2c_msg* pm,458458 int combined_xfer)459459{460460 volatile struct iic_regs __iomem *iic = dev->vaddr;···465465 u8 cntl = (in_8(&iic->cntl) & CNTL_AMD) | CNTL_PT;466466 if (pm->flags & I2C_M_RD)467467 cntl |= CNTL_RW;468468-468468+469469 loops = (len + 3) / 4;470470 for (i = 0; i < loops; ++i, len -= 4){471471 int count = len > 4 ? 4 : len;472472 u8 cmd = cntl | ((count - 1) << CNTL_TCT_SHIFT);473473-473473+474474 if (!(cntl & CNTL_RW))475475 for (j = 0; j < count; ++j)476476 out_8((void __iomem *)&iic->mdbuf, *buf++);477477-477477+478478 if (i < loops - 1)479479 cmd |= CNTL_CHT;480480 else if (combined_xfer)481481 cmd |= CNTL_RPST;482482-482482+483483 DBG2("%d: xfer_bytes, %d, CNTL = 0x%02x\n", dev->idx, count, cmd);484484-484484+485485 /* Start transfer */486486 out_8(&iic->cntl, cmd);487487-487487+488488 /* Wait for completion */489489 ret = iic_wait_for_tc(dev);490490491491 if (unlikely(ret < 0))492492 break;493493 else if (unlikely(ret != count)){494494- DBG("%d: xfer_bytes, requested %d, transfered %d\n", 494494+ DBG("%d: xfer_bytes, requested %d, transfered %d\n",495495 dev->idx, count, ret);496496-496496+497497 /* If it's not a last part of xfer, abort it */498498 if (combined_xfer || (i < loops - 1))499499 iic_abort_xfer(dev);500500-500500+501501 ret = -EREMOTEIO;502502- break; 502502+ break;503503 }504504-504504+505505 if (cntl & CNTL_RW)506506 for (j = 0; j < count; ++j)507507 *buf++ = in_8((void __iomem *)&iic->mdbuf);508508 }509509-509509+510510 return ret > 0 ? 0 : ret;511511}512512···517517{518518 volatile struct iic_regs __iomem *iic = dev->vaddr;519519 u16 addr = msg->addr;520520-521521- DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx, 520520+521521+ DBG2("%d: iic_address, 0x%03x (%d-bit)\n", dev->idx,522522 addr, msg->flags & I2C_M_TEN ? 10 : 7);523523-523523+524524 if (msg->flags & I2C_M_TEN){525525 out_8(&iic->cntl, CNTL_AMD);526526 out_8(&iic->lmadr, addr);···537537 return (p->addr > 0x3ff) || (!(p->flags & I2C_M_TEN) && (p->addr > 0x7f));538538}539539540540-static inline int iic_address_neq(const struct i2c_msg* p1, 540540+static inline int iic_address_neq(const struct i2c_msg* p1,541541 const struct i2c_msg* p2)542542{543543- return (p1->addr != p2->addr) 543543+ return (p1->addr != p2->addr)544544 || ((p1->flags & I2C_M_TEN) != (p2->flags & I2C_M_TEN));545545-} 545545+}546546547547/*548548- * Generic master transfer entrypoint. 548548+ * Generic master transfer entrypoint.549549 * Returns the number of processed messages or error (<0)550550 */551551static int iic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)···553553 struct ibm_iic_private* dev = (struct ibm_iic_private*)(i2c_get_adapdata(adap));554554 volatile struct iic_regs __iomem *iic = dev->vaddr;555555 int i, ret = 0;556556-556556+557557 DBG2("%d: iic_xfer, %d msg(s)\n", dev->idx, num);558558-558558+559559 if (!num)560560 return 0;561561-561561+562562 /* Check the sanity of the passed messages.563563 * Uhh, generic i2c layer is more suitable place for such code...564564 */565565 if (unlikely(iic_invalid_address(&msgs[0]))){566566- DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx, 566566+ DBG("%d: invalid address 0x%03x (%d-bit)\n", dev->idx,567567 msgs[0].addr, msgs[0].flags & I2C_M_TEN ? 10 : 7);568568 return -EINVAL;569569- } 569569+ }570570 for (i = 0; i < num; ++i){571571 if (unlikely(msgs[i].len <= 0)){572572 if (num == 1 && !msgs[0].len){···576576 */577577 return iic_smbus_quick(dev, &msgs[0]);578578 }579579- DBG("%d: invalid len %d in msg[%d]\n", dev->idx, 579579+ DBG("%d: invalid len %d in msg[%d]\n", dev->idx,580580 msgs[i].len, i);581581 return -EINVAL;582582 }···585585 return -EINVAL;586586 }587587 }588588-588588+589589 /* Check bus state */590590 if (unlikely((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE)){591591 DBG("%d: iic_xfer, bus is not free\n", dev->idx);592592-592592+593593 /* Usually it means something serious has happend.594594 * We *cannot* have unfinished previous transfer595595 * so it doesn't make any sense to try to stop it.596596- * Probably we were not able to recover from the 596596+ * Probably we were not able to recover from the597597 * previous error.598598 * The only *reasonable* thing I can think of here599599 * is soft reset. --ebs600600 */601601 iic_dev_reset(dev);602602-602602+603603 if ((in_8(&iic->extsts) & EXTSTS_BCS_MASK) != EXTSTS_BCS_FREE){604604 DBG("%d: iic_xfer, bus is still not free\n", dev->idx);605605 return -EREMOTEIO;606606 }607607- } 607607+ }608608 else {609609 /* Flush master data buffer (just in case) */610610 out_8(&iic->mdcntl, in_8(&iic->mdcntl) | MDCNTL_FMDB);611611 }612612-612612+613613 /* Load slave address */614614 iic_address(dev, &msgs[0]);615615-615615+616616 /* Do real transfer */617617 for (i = 0; i < num && !ret; ++i)618618 ret = iic_xfer_bytes(dev, &msgs[i], i < num - 1);···648648649649 /* Convert to MHz */650650 opb /= 1000000;651651-651651+652652 if (opb < 20 || opb > 150){653653 printk(KERN_CRIT "ibm-iic: invalid OPB clock frequency %u MHz\n",654654 opb);···666666 struct i2c_adapter* adap;667667 struct ocp_func_iic_data* iic_data = ocp->def->additions;668668 int ret;669669-669669+670670 if (!iic_data)671671 printk(KERN_WARNING"ibm-iic%d: missing additional data!\n",672672 ocp->def->index);···679679680680 dev->idx = ocp->def->index;681681 ocp_set_drvdata(ocp, dev);682682-682682+683683 if (!request_mem_region(ocp->def->paddr, sizeof(struct iic_regs),684684 "ibm_iic")) {685685 ret = -EBUSY;···692692 ret = -ENXIO;693693 goto fail2;694694 }695695-695695+696696 init_waitqueue_head(&dev->wq);697697698698 dev->irq = iic_force_poll ? -1 : ocp->def->irq;···702702 */703703 iic_interrupt_mode(dev, 0);704704 if (request_irq(dev->irq, iic_handler, 0, "IBM IIC", dev)){705705- printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n", 705705+ printk(KERN_ERR "ibm-iic%d: request_irq %d failed\n",706706 dev->idx, dev->irq);707707- /* Fallback to the polling mode */ 707707+ /* Fallback to the polling mode */708708 dev->irq = -1;709709 }710710 }711711-711711+712712 if (dev->irq < 0)713713- printk(KERN_WARNING "ibm-iic%d: using polling mode\n", 713713+ printk(KERN_WARNING "ibm-iic%d: using polling mode\n",714714 dev->idx);715715-715715+716716 /* Board specific settings */717717 dev->fast_mode = iic_force_fast ? 1 : (iic_data ? iic_data->fast_mode : 0);718718-719719- /* clckdiv is the same for *all* IIC interfaces, 718718+719719+ /* clckdiv is the same for *all* IIC interfaces,720720 * but I'd rather make a copy than introduce another global. --ebs721721 */722722 dev->clckdiv = iic_clckdiv(ocp_sys_info.opb_bus_freq);723723 DBG("%d: clckdiv = %d\n", dev->idx, dev->clckdiv);724724-724724+725725 /* Initialize IIC interface */726726 iic_dev_init(dev);727727-727727+728728 /* Register it with i2c layer */729729 adap = &dev->adap;730730 adap->dev.parent = &ocp->dev;···750750 dev->idx);751751 goto fail;752752 }753753-753753+754754 printk(KERN_INFO "ibm-iic%d: using %s mode\n", dev->idx,755755 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");756756757757 return 0;758758759759-fail: 759759+fail:760760 if (dev->irq >= 0){761761 iic_interrupt_mode(dev, 0);762762 free_irq(dev->irq, dev);763763- } 763763+ }764764765765 iounmap(dev->vaddr);766766-fail2: 766766+fail2:767767 release_mem_region(ocp->def->paddr, sizeof(struct iic_regs));768768fail1:769769 ocp_set_drvdata(ocp, NULL);770770- kfree(dev); 770770+ kfree(dev);771771 return ret;772772}773773···783783 dev->idx);784784 /* That's *very* bad, just shutdown IRQ ... */785785 if (dev->irq >= 0){786786- iic_interrupt_mode(dev, 0); 786786+ iic_interrupt_mode(dev, 0);787787 free_irq(dev->irq, dev);788788 dev->irq = -1;789789 }790790 } else {791791 if (dev->irq >= 0){792792- iic_interrupt_mode(dev, 0); 792792+ iic_interrupt_mode(dev, 0);793793 free_irq(dev->irq, dev);794794 }795795 iounmap(dev->vaddr);···798798 }799799}800800801801-static struct ocp_device_id ibm_iic_ids[] __devinitdata = 801801+static struct ocp_device_id ibm_iic_ids[] __devinitdata =802802{803803 { .vendor = OCP_VENDOR_IBM, .function = OCP_FUNC_IIC },804804 { .vendor = OCP_VENDOR_INVALID }
+4-4
drivers/i2c/busses/i2c-ibm_iic.h
···22 * drivers/i2c/busses/i2c-ibm_iic.h33 *44 * Support for the IIC peripheral on IBM PPC 4xx55- * 55+ *66 * Copyright (c) 2003 Zultys Technologies.77 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>88 *99- * Based on original work by 99+ * Based on original work by1010 * Ian DaSilva <idasilva@mvista.com>1111 * Armin Kuster <akuster@mvista.com>1212 * Matt Porter <mporter@mvista.com>···2222#ifndef __I2C_IBM_IIC_H_2323#define __I2C_IBM_IIC_H_24242525-#include <linux/i2c.h> 2525+#include <linux/i2c.h>26262727struct iic_regs {2828 u16 mdbuf;···5858#define CNTL_TCT_MASK 0x305959#define CNTL_TCT_SHIFT 46060#define CNTL_RPST 0x086161-#define CNTL_CHT 0x04 6161+#define CNTL_CHT 0x046262#define CNTL_RW 0x026363#define CNTL_PT 0x016464