Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:57

0001 /*
0002  * Two-Wire Serial Interface (TWSI) support for the GT64260
0003  */
0004 
0005 /*
0006  * Copyright (c) 2004, Brookhaven National Laboratory and
0007  *                 Shuchen Kate Feng <feng1@bnl.gov>
0008  * All rights reserved.
0009  *
0010  * The license and distribution terms for this file may be
0011  * found in the file LICENSE in this distribution.
0012  *
0013  * See section 24:TWSI interface of "the GT-64260B System Controller
0014  * for powerPc Processors Data Sheet".
0015  *
0016  * For full TWSI protocol description look in Philips Semiconductor
0017  * TWSI spec.
0018  *
0019  * We need it to read out I2C devices used for the MVME5500
0020  * (eg. the memory SPD and VPD).
0021  */
0022 
0023 #include <libcpu/spr.h>  /*registers.h included here for rtems_bsp_delay()*/
0024 #include <libcpu/io.h>
0025 #include <rtems/bspIo.h>
0026 
0027 #include "bsp/gtreg.h"
0028 #include "bsp/GT64260TWSI.h"
0029 
0030 #define MAX_LOOP 100
0031 
0032 #define TWSI_DEBUG 0
0033 
0034 static int TWSI_initFlg = 0;  /* TWSI Initialization Flag */
0035 
0036 void GT64260TWSIinit(void)
0037 {
0038   if ( !TWSI_initFlg ) {
0039 #if TWSI_DEBUG
0040    printk("GT64260TWSIinit(");
0041 #endif
0042    outl( 0, TWSI_SFT_RST); /* soft reset */
0043    rtems_bsp_delay(1000);
0044 
0045    /* See 24.2.5 : Assume bus speed is 133MHZ
0046     * Try to be close to the default frequency : 62.5KHZ
0047     * value 0x2c: 69.27 KHz TWSI bus clock
0048     */
0049    outl(0x2c, TWSI_BAUDE_RATE);
0050    rtems_bsp_delay(1000);
0051 
0052    /* Set Acknowledge and enable TWSI in the Control register */
0053    outl(0x44, TWSI_CTRL);
0054    rtems_bsp_delay(4000);
0055    TWSI_initFlg = 1;
0056 #if TWSI_DEBUG
0057    printk(")\n");
0058 #endif
0059   }
0060 }
0061 
0062 /* return the interrupt flag */
0063 static int GT64260TWSIintFlag(void)
0064 {
0065   unsigned int loop;
0066 
0067   for (loop = 0; loop < MAX_LOOP; loop++ ) {
0068     /* Return 1 if the interrupt flag is set */
0069     if (inl(TWSI_CTRL) & TWSI_INTFLG)
0070       return(1);
0071     rtems_bsp_delay(1000);
0072   }
0073   return(0);
0074 }
0075 
0076 int GT64260TWSIstop(void)
0077 {
0078 
0079 #if TWSI_DEBUG
0080   printk("GT64260TWSIstop(");
0081 #endif
0082 
0083   outl((inl(TWSI_CTRL) | TWSI_STOP), TWSI_CTRL);
0084   rtems_bsp_delay(1000);
0085 
0086   /* Check if interrupt flag bit is set*/
0087   if (GT64260TWSIintFlag()) {
0088      outl((inl( TWSI_CTRL) & ~TWSI_INTFLG), TWSI_CTRL);
0089      rtems_bsp_delay(1000);
0090 #if TWSI_DEBUG
0091      printk(")\n");
0092 #endif
0093      return(0);
0094   }
0095 #if TWSI_DEBUG
0096      printk("NoIntFlag\n");
0097 #endif
0098   return(-1);
0099 }
0100 
0101 int GT64260TWSIstart(void)
0102 {
0103   unsigned int loop;
0104   unsigned int status;
0105 
0106 #if TWSI_DEBUG
0107   printk("GT64260TWSIstart(");
0108 #endif
0109   /* Initialize the TWSI interface */
0110   GT64260TWSIinit();
0111 
0112   /* set the start bit */
0113   outl((TWSI_START | TWSI_TWSIEN), TWSI_CTRL);
0114   rtems_bsp_delay(1000);
0115 
0116   if (GT64260TWSIintFlag()) {
0117     /* Check for completion of START sequence */
0118     for (loop = 0; loop<MAX_LOOP; loop++ ) {
0119       /* if (start condition transmitted) ||
0120        *    (repeated start condition transmitted )
0121        */
0122       if (((status= inl( TWSI_STATUS)) == 8) || (status == 0x10)) {
0123 #if TWSI_DEBUG
0124         printk(")");
0125 #endif
0126         return(0);
0127       }
0128       rtems_bsp_delay(1000);
0129     }
0130   }
0131   /* if loop ends or intFlag ==0 */
0132   GT64260TWSIstop();
0133   return(-1);
0134 }
0135 
0136 int GT64260TWSIread(unsigned char * pData, int lastByte)
0137 {
0138   unsigned int loop;
0139 
0140 #if TWSI_DEBUG
0141   printk("GT64260TWSIread(");
0142 #endif
0143   /* Clear INTFLG and set ACK and ENABLE bits */
0144   outl((TWSI_ACK | TWSI_TWSIEN), TWSI_CTRL);
0145   rtems_bsp_delay(1000);
0146 
0147   if (GT64260TWSIintFlag()) {
0148     for (loop = 0; loop< MAX_LOOP; loop++) {
0149       /* if Master received read data, acknowledge transmitted */
0150       if ( (inl( TWSI_STATUS) == 0x50)) {
0151         *pData = (unsigned char) inl( TWSI_DATA);
0152         rtems_bsp_delay(1500);
0153 
0154         /* Clear INTFLAG and set Enable bit only */
0155         if (lastByte)
0156          outl(TWSI_TWSIEN, TWSI_CTRL);
0157         rtems_bsp_delay(1500);
0158 #if TWSI_DEBUG
0159         printk(")\n");
0160 #endif
0161         return(0);
0162       }
0163       rtems_bsp_delay(1000);
0164     } /* end for */
0165   }
0166   /* if loop ends or intFlag ==0 */
0167   GT64260TWSIstop();
0168   return(-1);
0169 }
0170 
0171 /* do a TWSI write cycle on the TWSI bus*/
0172 int GT64260TWSIwrite(unsigned char Data)
0173 {
0174   unsigned int loop;
0175   unsigned int status;
0176 
0177 #if TWSI_DEBUG
0178   printk("GT64260TWSIwrite(");
0179 #endif
0180   /* Write data into the TWSI data register */
0181   outl(((unsigned int) Data), TWSI_DATA);
0182   rtems_bsp_delay(1000);
0183 
0184   /* Clear INTFLG in the control register to drive data onto TWSI bus */
0185   outl(0, TWSI_CTRL);
0186   rtems_bsp_delay(1000);
0187 
0188   if (GT64260TWSIintFlag() ) {
0189     for (loop = 0; loop< MAX_LOOP; loop++) {
0190       rtems_bsp_delay(1000);
0191       /* if address + write bit transmitted, acknowledge not received */
0192       if ( (status = inl( TWSI_STATUS)) == 0x20) {
0193         /* No device responding, generate STOP and return -1 */
0194         printk("no device responding\n");
0195         GT64260TWSIstop();
0196         return(-1);
0197       }
0198       /* if (address + write bit transmitted, acknowledge received)
0199        * (Master transmmitted data byte, acknowledge received)
0200        *    (address + read bit transmitted, acknowledge received)
0201        */
0202       if ((status == 0x18)||(status == 0x28)||(status == 0x40)) {
0203 #if TWSI_DEBUG
0204         printk(")\n");
0205 #endif
0206         return(0);
0207       }
0208       rtems_bsp_delay(1000);
0209     } /* end for */
0210   }
0211   printk("No correct status, timeout\n");
0212   GT64260TWSIstop();
0213   return(-1);
0214 }