Annotation of XNU/iokit/Drivers/audio/drvPPCDACA/PPCI2CInterface.cpp, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
        !            24:  *
        !            25:  * Implementation of the interface for the keylargo I2C interface
        !            26:  *
        !            27:  * HISTORY
        !            28:  *
        !            29:  */
        !            30: 
        !            31: #include "PPCI2CInterface.h"
        !            32: 
        !            33: // Uncomment the following define if you wish ro see more logging
        !            34: // on the i2c interface:
        !            35: // #define DEBUGMODE 
        !            36: 
        !            37: // Private Methods:
        !            38: // ===============
        !            39: 
        !            40: // FIXME: change the if 0 into if 1 in the following line for final
        !            41: // builds so all the simple private functions can be inlined.
        !            42: #if 1
        !            43: #define INLINE inline
        !            44: #else
        !            45: #define INLINE
        !            46: #endif
        !            47: 
        !            48: // --------------------------------------------------------------------------
        !            49: // Method: dumpI2CRegisters
        !            50: //
        !            51: // Purpose:
        !            52: //        Given the base of the i2c registers inits all the registers
        !            53: INLINE void
        !            54: PPCI2CInterface::dumpI2CRegisters()
        !            55: {
        !            56: #ifdef DEBUGMODE
        !            57:     IOLog("mode    0x%08lx -> 0x%02x\n", (UInt32)mode,*mode);
        !            58:     IOLog("control 0x%08lx -> 0x%02x\n", (UInt32)control,*control);
        !            59:     IOLog("status  0x%08lx -> 0x%02x\n", (UInt32)status,*status);
        !            60:     IOLog("ISR     0x%08lx -> 0x%02x\n", (UInt32)ISR,*ISR);
        !            61:     IOLog("IER     0x%08lx -> 0x%02x\n", (UInt32)IER,*IER);
        !            62:     IOLog("address 0x%08lx -> 0x%02x\n", (UInt32)address,*address);
        !            63:     IOLog("subAddr 0x%08lx -> 0x%02x\n", (UInt32)subAddr,*subAddr);
        !            64:     //IOLog("data    0x%08lx -> 0x%02x\n", (UInt32)data,*data);
        !            65: #endif //DEBUGMODE
        !            66: }
        !            67: 
        !            68: // --------------------------------------------------------------------------
        !            69: // Method: SetI2CBase
        !            70: //
        !            71: // Purpose:
        !            72: //        Given the base of the i2c registers inits all the registers
        !            73: INLINE void
        !            74: PPCI2CInterface::SetI2CBase(UInt8 *baseAddress, UInt8 steps)
        !            75: {
        !            76:     I2CRegister base = (I2CRegister)baseAddress;
        !            77: 
        !            78:     if (base != NULL) {
        !            79:         mode = base;                                                                           // Configure the transmission mode of the i2c cell and the databit rate.
        !            80:         control = mode + steps;                         // Holds the 4 bits used to start the operations on the i2c interface.
        !            81:         status = control + steps;              // Status bits for the i2 cell and the i2c interface.
        !            82:         ISR = status + steps;                                          // Holds the status bits for the interrupt conditions.
        !            83:         IER = ISR + steps;                                               // Eneables the bits that allow the four interrupt status conditions.
        !            84:         address = IER + steps;                   // Holds the 7 bits address and the R/W bit.
        !            85:         subAddr = address + steps; // the 8bit subaddress..
        !            86:         data = subAddr + steps;                        // from where we read and write data
        !            87: 
        !            88:         // Clears interrupt and status register:
        !            89:         *status = 0x00;
        !            90:         *ISR = 0x00;
        !            91: 
        !            92:         // And remembers the current mode:
        !            93:         getMode();
        !            94: 
        !            95: #ifdef DEBUGMODE
        !            96:         IOLog("PPCI2CInterface::SetI2CBase(0x%08lx,0x%02x)\n",(UInt32)baseAddress, steps);
        !            97:         dumpI2CRegisters();
        !            98: #endif // DEBUGMODE
        !            99:     }
        !           100: }
        !           101: 
        !           102: // --------------------------------------------------------------------------
        !           103: // Method: shiftedMask
        !           104: //
        !           105: // Purpose:
        !           106: //        Returns the mask to use with the register:
        !           107: INLINE UInt8
        !           108: PPCI2CInterface::shiftedMask(UInt8 mask, UInt8 shift)
        !           109: {
        !           110:     return (mask << shift);
        !           111: }
        !           112: 
        !           113: // --------------------------------------------------------------------------
        !           114: // Method: shiftedCompMask
        !           115: //
        !           116: // Purpose:
        !           117: //        Returns the complement of the mask
        !           118: INLINE UInt8
        !           119: PPCI2CInterface::shiftedCompMask(UInt8 mask, UInt8 shift)
        !           120: {
        !           121:     return ~shiftedMask(mask, shift);
        !           122: }
        !           123: 
        !           124: // --------------------------------------------------------------------------
        !           125: // Method: writeRegisterField
        !           126: //
        !           127: // Purpose:
        !           128: //        writes a field of a regiter with the given data. The arguments are
        !           129: //        the register, the mask for the field, shift to get to the right bits
        !           130: //        and the new data.
        !           131: INLINE void
        !           132: PPCI2CInterface::writeRegisterField(I2CRegister reg, UInt8 mask, UInt8 shift, UInt8 newData)
        !           133: {
        !           134:     UInt8 registerValue = *reg;
        !           135:     UInt8 data = (newData & mask);
        !           136:     UInt8 nMask = shiftedCompMask(mask, shift);
        !           137: 
        !           138:     *reg = (registerValue & nMask) | (data << shift);
        !           139:     eieio();
        !           140:  
        !           141: #ifdef DEBUGMODE
        !           142: /*    IOLog("PPCI2CInterface::writeRegisterField(0x%08lx, 0x%02x, 0x%02x, 0x%02x)\n",(UInt32)reg, mask, shift, newData);
        !           143:     IOLog("PPCI2CInterface::writeRegisterField() registerValue=0x%02x\n", registerValue);
        !           144:     IOLog("PPCI2CInterface::writeRegisterField() data=0x%02x\n", data);
        !           145:     IOLog("PPCI2CInterface::writeRegisterField() nMask=0x%02x\n", nMask);
        !           146:     IOLog("PPCI2CInterface::writeRegisterField() *reg=0x%02x\n", *reg);*/
        !           147: #endif // DEBUGMODE
        !           148: }
        !           149: 
        !           150: // --------------------------------------------------------------------------
        !           151: // Method: readRegisterField
        !           152: //
        !           153: // Purpose:
        !           154: //        writes a field of a regiter with the given data. The arguments are
        !           155: //        the register, the mask for the field and shift to get to the right
        !           156: //        bits.
        !           157: INLINE UInt8
        !           158: PPCI2CInterface::readRegisterField(I2CRegister reg, UInt8 mask, UInt8 shift)
        !           159: {
        !           160:     UInt8 registerValue = *reg;
        !           161:     UInt8 returnValue = ((registerValue) >> shift) & mask;
        !           162: 
        !           163: #ifdef DEBUGMODE
        !           164: /*    IOLog("PPCI2CInterface::readRegisterField(0x%08lx, 0x%02x, 0x%02x)\n",(UInt32)reg, mask, shift);
        !           165:     IOLog("PPCI2CInterface::readRegisterField() *reg=0x%02x\n", *reg);
        !           166:     IOLog("PPCI2CInterface::readRegisterField() returnValue=0x%02x\n", returnValue);*/
        !           167: #endif // DEBUGMODE
        !           168: 
        !           169:     return returnValue;
        !           170: }
        !           171: 
        !           172: // Intermediate methods to access to each field of all the registers:
        !           173: // ------------------------------------------------------------------
        !           174: 
        !           175: // Mode register
        !           176: INLINE void
        !           177: PPCI2CInterface::setMode(I2CMode newMode)
        !           178: {
        !           179:     // remoeber the last mode:
        !           180:     lastMode = newMode;
        !           181:     writeRegisterField(mode, (UInt8)kModeMask, (UInt8)I2CModeShift, (UInt8)newMode);
        !           182: }
        !           183: 
        !           184: INLINE PPCI2CInterface::I2CMode
        !           185: PPCI2CInterface::getMode()
        !           186: {
        !           187:     lastMode = (I2CMode)readRegisterField(mode, (UInt8)kModeMask, (UInt8)I2CModeShift);
        !           188:     return lastMode;
        !           189: }
        !           190: 
        !           191: INLINE void
        !           192: PPCI2CInterface::setSpeed(I2CSpeed newSpeed)
        !           193: {
        !           194:     writeRegisterField(mode, (UInt8)kSpeedMask, (UInt8)I2CSpeedShift, (UInt8)newSpeed);
        !           195: }
        !           196: 
        !           197: INLINE PPCI2CInterface::I2CSpeed
        !           198: PPCI2CInterface::getSpeed()
        !           199: {
        !           200:     return (I2CSpeed)readRegisterField(mode, (UInt8)kSpeedMask, (UInt8)I2CSpeedShift);
        !           201: }
        !           202: 
        !           203: // Control register
        !           204: INLINE void
        !           205: PPCI2CInterface::setControl(I2CControl newControlValue)
        !           206: {
        !           207:     *control = (UInt8)newControlValue;
        !           208:     eieio();
        !           209: }
        !           210: 
        !           211: INLINE PPCI2CInterface::I2CControl
        !           212: PPCI2CInterface::getControl()
        !           213: {
        !           214:     return (I2CControl)(*control);
        !           215: }
        !           216: 
        !           217: // Status register
        !           218: INLINE void
        !           219: PPCI2CInterface::setStatus(I2CStatus newStatusValue)
        !           220: {
        !           221:     *status = (UInt8)newStatusValue;
        !           222:     eieio();
        !           223: }
        !           224: 
        !           225: INLINE PPCI2CInterface::I2CStatus
        !           226: PPCI2CInterface::getStatus()
        !           227: {
        !           228:     return (I2CStatus)(*status);
        !           229: }
        !           230: 
        !           231: // Interrupt status
        !           232: INLINE void
        !           233: PPCI2CInterface::setInterruptStatus(I2CInterruptStatus newStatusValue)
        !           234: {
        !           235:     *ISR = (UInt8)newStatusValue;
        !           236:     eieio();
        !           237: }
        !           238: 
        !           239: INLINE PPCI2CInterface::I2CInterruptStatus
        !           240: PPCI2CInterface::getInterruptStatus()
        !           241: {
        !           242:     return (I2CInterruptStatus)(*ISR);
        !           243: }
        !           244: 
        !           245: // Interrupt enable
        !           246: INLINE void
        !           247: PPCI2CInterface::setInterruptEnable(I2CInterruptEnable newInterruptEnable)
        !           248: {
        !           249:     *IER = (UInt8)newInterruptEnable;
        !           250:     eieio();
        !           251: }
        !           252: 
        !           253: INLINE PPCI2CInterface::I2CInterruptEnable
        !           254: PPCI2CInterface::setInterruptEnable()
        !           255: {
        !           256:     return (I2CInterruptEnable)(*IER);
        !           257: }
        !           258: 
        !           259: // Address Register:
        !           260: INLINE void
        !           261: PPCI2CInterface::setAddress(UInt8 newAddress)
        !           262: {
        !           263:     writeRegisterField(address, (UInt8)kADDRMask, (UInt8)I2CAddressShift, (UInt8)newAddress);
        !           264:     eieio();
        !           265: }
        !           266: 
        !           267: INLINE void
        !           268: PPCI2CInterface::setAddressRegister(UInt8 newAddress, I2CRWMode readMode)
        !           269: {
        !           270:     newAddress &= kADDRMask;
        !           271:     *address = (newAddress << I2CAddressShift) | readMode;
        !           272:     eieio();
        !           273: }
        !           274: 
        !           275: INLINE UInt8
        !           276: PPCI2CInterface::getAddress()
        !           277: {
        !           278:     return readRegisterField(address, (UInt8)kADDRMask, (UInt8)I2CAddressShift);
        !           279: }
        !           280: 
        !           281: INLINE void
        !           282: PPCI2CInterface::setReadWrite(I2CRWMode readMode)
        !           283: {
        !           284:     writeRegisterField(address, (UInt8)kRWMask, (UInt8)I2CRWShift, (UInt8)readMode);
        !           285:     eieio();
        !           286: }
        !           287: 
        !           288: INLINE PPCI2CInterface::I2CRWMode
        !           289: PPCI2CInterface::getReadWrite()
        !           290: {
        !           291:     return (I2CRWMode)readRegisterField(address, (UInt8)kRWMask, (UInt8)I2CRWShift);
        !           292: }
        !           293: 
        !           294: // SubAddress register
        !           295: INLINE void
        !           296: PPCI2CInterface::setSubAddress(UInt8 newSubAddress)
        !           297: {
        !           298:     *subAddr = newSubAddress;
        !           299:     eieio();
        !           300: }
        !           301: 
        !           302: INLINE UInt8
        !           303: PPCI2CInterface::getSubAddress()
        !           304: {
        !           305:     return (*subAddr);
        !           306: }
        !           307: 
        !           308: // Data register
        !           309: INLINE void
        !           310: PPCI2CInterface::setData(UInt8 newByte)
        !           311: {
        !           312:     *data = newByte;
        !           313:     eieio();
        !           314: }
        !           315: 
        !           316: INLINE UInt8
        !           317: PPCI2CInterface::getData()
        !           318: {
        !           319:     return (*data);
        !           320: }
        !           321: 
        !           322: // --------------------------------------------------------------------------
        !           323: // Method: setAddressAndDirection
        !           324: //
        !           325: // Purpose:
        !           326: //        sets the control register with the correct address and data direction.
        !           327: INLINE bool
        !           328: PPCI2CInterface::setAddressAndDirection()
        !           329: {
        !           330:     // sets the address register:
        !           331:     if (isReading) {
        !           332:         setAddressRegister(currentAddress, kReadADDR);        
        !           333:     }
        !           334:     else {
        !           335:         setAddressRegister(currentAddress, kWriteADDR);       
        !           336:     }
        !           337: 
        !           338:     // sets the subAddress:
        !           339:     setSubAddress(currentSubaddress);
        !           340: 
        !           341:     currentState = ki2cStateWaitingForIADDR;
        !           342:     setControl((I2CControl)(getControl() | kXAddrCNTRL));
        !           343: 
        !           344: #ifdef DEBUGMODE
        !           345:     IOLog("PPCI2CInterface::setAddressAndDirection()\n");
        !           346: #endif // DEBUGMODE
        !           347: 
        !           348:     return(true);
        !           349: }
        !           350: 
        !           351: // --------------------------------------------------------------------------
        !           352: // Method: i2cStandardSubModeInterrupts
        !           353: //
        !           354: // Purpose:
        !           355: //        handles the interrupts and the state machine for the Standard + SubAddress mode:
        !           356: bool
        !           357: PPCI2CInterface::i2cStandardSubModeInterrupts(UInt8 interruptStatus)
        !           358: {
        !           359:     bool success = true;
        !           360: 
        !           361:     switch (currentState) {
        !           362:         case ki2cStateWaitingForIADDR:
        !           363: #ifdef DEBUGMODE            
        !           364:             IOLog("ki2cStateWaitingForIADDR: ");
        !           365: #endif // DEBUGMODE            
        !           366: 
        !           367:             // verify that correct interrupt bit set
        !           368:             if ((interruptStatus & kIAddrISR) == 0) {
        !           369: #ifdef DEBUGMODE            
        !           370:                 IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts (ki2cStateWaitingForIADDR): bad state ");
        !           371: #endif
        !           372:                 success = false;
        !           373:             }
        !           374: 
        !           375:             if (success) {
        !           376:                 if (getStatus() & kLastAakSTATUS) {
        !           377:                         if (isReading) {
        !           378:                             // if multiple bytes are to be read, set AAK bit
        !           379:                             if (nBytes > 1)
        !           380:                                 setControl((I2CControl)(getControl() | kAakCNTRL));
        !           381:                         }
        !           382:                         else {
        !           383:                             // write operation
        !           384:                             setData(*dataBuffer++);
        !           385:                             nBytes--;
        !           386:                         }
        !           387: 
        !           388:                         currentState = ki2cStateWaitingForIDATA;
        !           389:                     }
        !           390:                     else {
        !           391:                         // no slave responded, so wait for STOP (control bit does not need to be set,
        !           392:                         // since NAAK sets the control bit automatically)
        !           393: #ifdef DEBUGMODE            
        !           394:                         IOLog("...no slave...");
        !           395: #endif
        !           396:                         currentState = ki2cStateWaitingForISTOP;
        !           397:                         success = false;
        !           398:                     }
        !           399:                 }
        !           400:                 else {
        !           401:                     // bad state, so abort command
        !           402:                     abortTransfer();
        !           403:                 }
        !           404: 
        !           405:                 // clear IADDR bit and go
        !           406:                 setInterruptStatus(kIAddrISR);
        !           407:             break;
        !           408: 
        !           409:         case ki2cStateWaitingForIDATA:
        !           410: #ifdef DEBUGMODE            
        !           411:             IOLog("ki2cStateWaitingForIDATA: ");
        !           412: #endif
        !           413:             // verify that correct interrupt bit set
        !           414:             if ((interruptStatus & kIDataISR) == 0) {
        !           415: #ifdef DEBUGMODE            
        !           416:                 IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts (ki2cStateWaitingForIDATA): bad state ");
        !           417: #endif
        !           418:                 success = false;
        !           419:             }
        !           420: 
        !           421:                 if (success) {
        !           422:                     if (isReading) {
        !           423:                         *dataBuffer++ = getData();
        !           424:                         nBytes--;
        !           425: 
        !           426:                         if (nBytes == 0)                       // read operation completed
        !           427:                             currentState = ki2cStateWaitingForISTOP;
        !           428:                         else                                   // if next byte is last byte, clear AAK bit, and state remains unchanged
        !           429:                             setControl(kClrCNTRL);
        !           430:                     }
        !           431:                     else {
        !           432:                         // write operation
        !           433:                         if (getStatus() & kLastAakSTATUS) {
        !           434:                             if (nBytes == 0) {
        !           435:                                 // write operation completed
        !           436:                                 currentState = ki2cStateWaitingForISTOP;
        !           437:                                 setControl((I2CControl)(getControl() | kStopCNTRL));
        !           438:                             }
        !           439:                             else {
        !           440:                                 // send an other byte
        !           441:                                 setData(*dataBuffer++);
        !           442:                                 nBytes--;
        !           443:                             }
        !           444:                         }
        !           445:                        else {
        !           446:                            // no slave responded, so wait for STOP (control bit does not need to be set,
        !           447:                            // since NAAK sets the control bit automatically)
        !           448: #ifdef DEBUGMODE            
        !           449:                            IOLog("...no slave...");
        !           450: #endif
        !           451:                            currentState = ki2cStateWaitingForISTOP;
        !           452:                            success = false;
        !           453:                         }
        !           454:                     }
        !           455:                 }
        !           456:                 else {
        !           457:                     // bad state, so abort command
        !           458:                     abortTransfer();
        !           459:                 }
        !           460: 
        !           461:                 // clear IDATA bit and go
        !           462:                 setInterruptStatus(kIDataISR);
        !           463:             break;
        !           464: 
        !           465:         case ki2cStateWaitingForISTOP:
        !           466: #ifdef DEBUGMODE
        !           467:             IOLog("ki2cStateWaitingForISTOP: ");
        !           468: #endif
        !           469:             // verify that correct interrupt bit set
        !           470:             if ((interruptStatus & kIStopISR) == 0) {
        !           471: #ifdef DEBUGMODE
        !           472:                 IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts (ki2cStateWaitingForISTOP): bad state ");
        !           473: #endif
        !           474:                 success = false;
        !           475:             }
        !           476: 
        !           477:             currentState = ki2cStateIdle;
        !           478:             setInterruptStatus(kIStopISR);
        !           479:            break;
        !           480: 
        !           481:         case ki2cStateWaitingForISTART:
        !           482: #ifdef DEBUGMODE
        !           483:             IOLog("ki2cStateWaitingForISTART: is not supposed to happen in this state machine ");
        !           484: #endif
        !           485:             break;
        !           486: 
        !           487:         case ki2cStateIdle:
        !           488: #ifdef DEBUGMODE
        !           489:             IOLog("ki2cStateIdle: ");
        !           490: #endif
        !           491:             break;
        !           492: 
        !           493:         default:
        !           494:              break;
        !           495:     }
        !           496: #ifdef DEBUGMODE
        !           497:     IOLog("\n");
        !           498: #endif
        !           499: 
        !           500:     // tell the system that this interrupt has been serviced
        !           501:     return success;
        !           502: }
        !           503: 
        !           504: // --------------------------------------------------------------------------
        !           505: // Method: abortTransfer
        !           506: //
        !           507: // Purpose:
        !           508: //        ends the data transfer.
        !           509: INLINE bool
        !           510: PPCI2CInterface::abortTransfer()
        !           511: {
        !           512:     currentState = ki2cStateWaitingForISTOP;
        !           513:     setControl((I2CControl)(getControl() | kStopCNTRL));
        !           514:     return false;
        !           515: }
        !           516: 
        !           517: // --------------------------------------------------------------------------
        !           518: // Method: waitForCompletion
        !           519: //
        !           520: // Purpose:
        !           521: //        waits until the last command was executed correctly and when it
        !           522: //        happens it calls the interrupt handler. This is useful for when
        !           523: //        we use this object without an interrupt handler.
        !           524: bool
        !           525: PPCI2CInterface::waitForCompletion()
        !           526: {
        !           527:     UInt16 loop = 50 + nBytes * 10;
        !           528:     UInt8 intStat = getInterruptStatus();
        !           529:     
        !           530:     // First call to the interrupt handler in case the last command
        !           531:     // is already completed
        !           532:     
        !           533:     //IOLog("1] Interrupt Status = 0x%02x\n", intStat);
        !           534:     if (intStat & kISRMask)
        !           535:         handleI2CInterrupt();
        !           536: 
        !           537:     // makes 10 loops for each expected interrupt with 1 millisecond delay for each loop:
        !           538:     while((loop--) && (currentState != ki2cStateIdle)) {
        !           539:         IOSleep(1);
        !           540: 
        !           541:         // If an interrupt occured handle it:
        !           542:         intStat = getInterruptStatus();
        !           543:         
        !           544:         //IOLog("%d] Interrupt Status = 0x%02x\n", intStat);
        !           545:         if (intStat & kISRMask)
        !           546:             handleI2CInterrupt();
        !           547:     }
        !           548: 
        !           549:     if (currentState != ki2cStateIdle) {
        !           550: #ifdef DEBUGMODE
        !           551:         IOLog("PPCI2CInterface::waitForCompletion error loop is incomplete\n");
        !           552: #endif
        !           553:         return false;
        !           554:     }
        !           555:     else {
        !           556: #ifdef DEBUGMODE
        !           557:         IOLog("PPCI2CInterface::waitForCompletion loop is complete\n");
        !           558: #endif
        !           559:         return true;        
        !           560:     }
        !           561: }
        !           562: 
        !           563: // Public Methods:
        !           564: // ===============
        !           565: 
        !           566: // Initialize the address of the registers and the registers themselfs:
        !           567: bool
        !           568: PPCI2CInterface::initI2CBus(UInt8 *baseAddress, UInt8 steps)
        !           569: {
        !           570:     pollingMode = true;
        !           571:     currentState = ki2cStateIdle;
        !           572:     SetI2CBase(baseAddress, steps);
        !           573: 
        !           574:     return true;
        !           575: }
        !           576: 
        !           577: // The default behavior of this class is to work in "polling mode"
        !           578: // where the interrupt handler is called by a polling routine.
        !           579: // However it is always possible to attahc the interrupt handler
        !           580: // to an hardware interrupt and handle the transfer in the proper
        !           581: // way. (the polling mode was created for the sole pourpose to
        !           582: // debug the state machine).
        !           583: void
        !           584: PPCI2CInterface::setPollingMode(bool mode)
        !           585: {
        !           586:     pollingMode = mode; 
        !           587: }
        !           588: 
        !           589: // These are to setup the mode for the I2C bus:
        !           590: void
        !           591: PPCI2CInterface::setDumbMode()
        !           592: {
        !           593:     setMode(kDumbMode);
        !           594: }
        !           595: 
        !           596: void
        !           597: PPCI2CInterface::setStandardMode()
        !           598: {
        !           599:     setMode(kStandardMode);
        !           600: }
        !           601: 
        !           602: void
        !           603: PPCI2CInterface::setStandardSubMode()
        !           604: {
        !           605:     setMode(kStandardSubMode);
        !           606: }
        !           607: 
        !           608: void
        !           609: PPCI2CInterface::setCombinedMode()
        !           610: {
        !           611:     setMode(kCombinedMode);
        !           612: }
        !           613: 
        !           614: // These instead set the speed:
        !           615: bool
        !           616: PPCI2CInterface::setKhzSpeed(UInt speed)
        !           617: {
        !           618:     switch (speed)
        !           619:     {
        !           620:         case 100:
        !           621:             setSpeed(k100KhzMode);
        !           622:             break;
        !           623: 
        !           624:         case 50:
        !           625:             setSpeed(k50KhzMode);
        !           626:             break;
        !           627: 
        !           628:         case 25:
        !           629:             setSpeed(k25KhzMode);
        !           630:             break;
        !           631: 
        !           632:         default:
        !           633: #ifdef DEBUGMODE
        !           634:             IOLog("PPCI2CInterface::setKhzSpeed Can not set bus speed %d is not allowed\n", speed);
        !           635: #endif
        !           636:             return false;
        !           637:             break;
        !           638:     }
        !           639: 
        !           640:     return true;
        !           641: }
        !           642: 
        !           643: // Test to read the values set by the funtions above:
        !           644: bool
        !           645: PPCI2CInterface::isInDumbMode()
        !           646: {
        !           647:     return (getMode() == kDumbMode);
        !           648: }
        !           649: 
        !           650: bool
        !           651: PPCI2CInterface::isInStandardMode()
        !           652: {
        !           653:     return (getMode() == kStandardMode);
        !           654: }
        !           655: 
        !           656: bool
        !           657: PPCI2CInterface::isInStandardSubMode()
        !           658: {
        !           659:     return (getMode() == kStandardSubMode);
        !           660: }
        !           661: 
        !           662: bool
        !           663: PPCI2CInterface::isInCombinedMode()
        !           664: {
        !           665:     return (getMode() == kCombinedMode);
        !           666: }
        !           667: 
        !           668: // These instead returns the speed:
        !           669: UInt
        !           670: PPCI2CInterface::getKhzSpeed()
        !           671: {
        !           672:     switch((int)getSpeed())
        !           673:     {
        !           674:         case k100KhzMode:
        !           675:             return (100);
        !           676:             break;
        !           677: 
        !           678:         case k50KhzMode:
        !           679:             return (50);
        !           680:             break;
        !           681: 
        !           682:         case k25KhzMode:
        !           683:             return (25);
        !           684:             break;
        !           685:     }
        !           686: 
        !           687:     // Returns 0 since the speed was not set to a real value
        !           688:     return (0);
        !           689: }
        !           690: 
        !           691: // Starts the use of the interface:
        !           692: bool
        !           693: PPCI2CInterface::openI2CBus(UInt8 port)
        !           694: {
        !           695:     portSelect = port;
        !           696: 
        !           697:     // Enable all the interrupts:
        !           698:     setInterruptEnable((I2CInterruptEnable)(kEDataIER | kEAddrIER | kEStopIER | kEStartIER));
        !           699: 
        !           700:     return true;
        !           701: }
        !           702: 
        !           703: // Writes a block of data at a given address:
        !           704: bool
        !           705: PPCI2CInterface::writeI2CBus(UInt8 address, UInt8 subAddress, UInt8 *newData, UInt16 len)
        !           706: {
        !           707:     bool success = true;
        !           708: 
        !           709:     // waits for the completion of the previous command
        !           710:     waitForCompletion();
        !           711: 
        !           712:     // pointer to the data to be transfered
        !           713:     dataBuffer = newData;
        !           714: 
        !           715:     // and the number of bytes still to transfer
        !           716:     nBytes = len;
        !           717: 
        !           718:     // the current transfer address:
        !           719:     currentAddress = address;
        !           720: 
        !           721:     // the current transfer subAddress:
        !           722:     currentSubaddress = subAddress;
        !           723: 
        !           724:     // the data direction:
        !           725:     isReading = false;
        !           726: 
        !           727:     if ((success = setAddressAndDirection()) == true ) {
        !           728:         if (pollingMode)
        !           729:             success = waitForCompletion();
        !           730:     }
        !           731: 
        !           732:     return success;
        !           733: }
        !           734: 
        !           735: // Reads a block of data at a given address:
        !           736: bool
        !           737: PPCI2CInterface::readI2CBus(UInt8 address, UInt8 subAddress, UInt8 *newData, UInt16 len)
        !           738: {
        !           739:     bool success = false;
        !           740: 
        !           741:     // waits for the completion of the previous command
        !           742:     waitForCompletion();
        !           743: 
        !           744:     // pointer to the data to be received
        !           745:     dataBuffer = data;
        !           746: 
        !           747:     // and the number of bytes still to receive
        !           748:     nBytes = len;
        !           749: 
        !           750:     // the current transfer address:
        !           751:     currentAddress = address;
        !           752: 
        !           753:     // the current transfer subAddress:
        !           754:     currentSubaddress = subAddress;
        !           755: 
        !           756:     // the data direction:
        !           757:     isReading = true;
        !           758: 
        !           759:     if ((success = setAddressAndDirection()) == true ) {
        !           760:         if (pollingMode)
        !           761:             success = waitForCompletion();
        !           762:     }
        !           763:  
        !           764:     return success;
        !           765: }
        !           766: 
        !           767: // End using the interface:
        !           768: bool
        !           769: PPCI2CInterface::closei2CBus()
        !           770: {
        !           771:     // For now empty, we may add here some deinitialization parameters.
        !           772:     return true;
        !           773: }
        !           774: 
        !           775: // The interrupt handler:
        !           776: // dispatches to the correct interrupt handler according to the current mode set:
        !           777: bool
        !           778: PPCI2CInterface::handleI2CInterrupt()
        !           779: {
        !           780:     switch(lastMode)
        !           781:     {
        !           782:         case kDumbMode:
        !           783: #ifdef DEBUGMODE
        !           784:             IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts kDumbMode is an unsupported mode (for now)\n");
        !           785: #endif
        !           786:             break;
        !           787: 
        !           788:         case kStandardMode:
        !           789: #ifdef DEBUGMODE
        !           790:             IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts kStandardMode is an unsupported mode (for now)\n");
        !           791: #endif
        !           792:             break;
        !           793: 
        !           794:         case kStandardSubMode:
        !           795:             return (i2cStandardSubModeInterrupts(getInterruptStatus()));
        !           796:             break;
        !           797: 
        !           798:         case kCombinedMode:
        !           799: #ifdef DEBUGMODE
        !           800:             IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts kCombinedMode is an unsupported mode (for now)\n");
        !           801: #endif
        !           802:             break;
        !           803:     }
        !           804: 
        !           805:     // By default we fail ...
        !           806:     return false;
        !           807: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.