コード例 #1
0
ファイル: i2c.c プロジェクト: Harry-Wu/C51
unsigned char * i2c_read(u8 *val, u32 n, u16 addr) {
	if (!i2c_free())
		return NULL;

	i2c_start();
	i2c_sendbyte(ST24C512_ADDR & 0xfe);
	i2c_waitack();

	i2c_sendbyte(addr >> 8);
	i2c_waitack();
	i2c_sendbyte(addr & 0xff);
	i2c_waitack();
	
	i2c_start();
	i2c_sendbyte(ST24C512_ADDR | 1);
	i2c_waitack();

	n--;
	while (n--) {
		*val = i2c_recvbyte();
		i2c_sendack();
		val++;
	}

	*val = i2c_recvbyte();
	i2c_sendnack();

	i2c_stop();

	return val;
}
コード例 #2
0
ファイル: i2c.c プロジェクト: Blackburn29/PsycoKernel
unsigned char
i2c_readreg(unsigned char theSlave, unsigned char theReg)
{
	unsigned char b = 0;
	int error, cntr = 3;
	unsigned long flags;

	spin_lock_irqsave(&i2c_lock, flags);

	do {
		error = 0;
		i2c_start();

		i2c_outbyte((theSlave & 0xfe));
		if(!i2c_getack())
			error = 1;
		i2c_dir_out();
		i2c_outbyte(theReg);
		if(!i2c_getack())
			error |= 2;
		i2c_delay(CLOCK_LOW_TIME);
		i2c_start();
		i2c_outbyte(theSlave | 0x01);
		if(!i2c_getack())
			error |= 4;
		b = i2c_inbyte();
		i2c_sendnack();
		i2c_stop();

	} while(error && cntr--);

	spin_unlock_irqrestore(&i2c_lock, flags);

	return b;
}
コード例 #3
0
ファイル: i2c.c プロジェクト: Blackburn29/PsycoKernel
int
i2c_read(unsigned char theSlave, void *data, size_t nbytes)
{
	unsigned char b = 0;
	unsigned char bytes_read = 0;
	int error, cntr = 3;
	unsigned long flags;

	spin_lock_irqsave(&i2c_lock, flags);

	do {
		error = 0;
		memset(data, 0, nbytes);
		i2c_start();
		i2c_outbyte((theSlave | 0x01));
		if (!i2c_getack())
			error = 1;
		for (bytes_read = 0; bytes_read < nbytes; bytes_read++) {
			b = i2c_inbyte();
			memcpy(data + bytes_read, &b, sizeof b);

			if (bytes_read < (nbytes - 1))
				i2c_sendack();
		}
		i2c_sendnack();
		i2c_stop();
	} while (error && cntr--);

	spin_unlock_irqrestore(&i2c_lock, flags);

	return -error;
}
コード例 #4
0
ファイル: i2c.c プロジェクト: BinVul/linux2.6.32
/*#---------------------------------------------------------------------------
*#
*# FUNCTION NAME: i2c_read
*#
*# DESCRIPTION  : Reads a value from an I2C device
*#
*#--------------------------------------------------------------------------*/
int
i2c_read(unsigned char theSlave, void *data, size_t nbytes)
{
	unsigned char b = 0;
	unsigned char bytes_read = 0;
	int error, cntr = 3;
	unsigned long flags;

	spin_lock_irqsave(&i2c_lock, flags);

	do {
		error = 0;
		memset(data, 0, nbytes);
		/*
		 * generate start condition
		 */
		i2c_start();
		/*
		 * send slave address
		 */
		i2c_outbyte((theSlave | 0x01));
		/*
		 * wait for ack
		 */
		if (!i2c_getack())
			error = 1;
		/*
		 * fetch data
		 */
		for (bytes_read = 0; bytes_read < nbytes; bytes_read++) {
			b = i2c_inbyte();
			memcpy(data + bytes_read, &b, sizeof b);

			if (bytes_read < (nbytes - 1))
				i2c_sendack();
		}
		/*
		 * last received byte needs to be nacked
		 * instead of acked
		 */
		i2c_sendnack();
		/*
		 * end sequence
		 */
		i2c_stop();
	} while (error && cntr--);

	spin_unlock_irqrestore(&i2c_lock, flags);

	return -error;
}
コード例 #5
0
unsigned char
i2c_readreg(unsigned char theSlave, unsigned char theReg)
{
    unsigned char b = 0;
    int error, cntr = 3;
    unsigned long flags;

    spin_lock(&i2c_lock);

    do {
        error = 0;
        /*
         * we don't like to be interrupted
         */
        local_irq_save(flags);
        /*
         * generate start condition
         */
        i2c_start();

        /*
         * send slave address
         */
        i2c_outbyte((theSlave & 0xfe));
        /*
         * wait for ack
         */
        if(!i2c_getack())
            error = 1;
        /*
         * now select register
         */
        i2c_dir_out();
        i2c_outbyte(theReg);
        /*
         * now it's time to wait for ack
         */
        if(!i2c_getack())
            error = 1;
        /*
         * repeat start condition
         */
        i2c_delay(CLOCK_LOW_TIME);
        i2c_start();
        /*
         * send slave address
         */
        i2c_outbyte(theSlave | 0x01);
        /*
         * wait for ack
         */
        if(!i2c_getack())
            error = 1;
        /*
         * fetch register
         */
        b = i2c_inbyte();
        /*
         * last received byte needs to be nacked
         * instead of acked
         */
        i2c_sendnack();
        /*
         * end sequence
         */
        i2c_stop();
        /*
         * enable interrupt again
         */
        local_irq_restore(flags);

    } while(error && cntr--);

    spin_unlock(&i2c_lock);

    return b;
}
コード例 #6
0
ファイル: i2c_gvc.c プロジェクト: 7LK/McWRT
/*#---------------------------------------------------------------------------
 *#
 *# FUNCTION NAME: i2c_command
 *#
 *# DESCRIPTION  : general routine to read/write bytes from an I2C device
 *#
 *#                'i2c_command()' sends wlen bytes to the I2c bus and receives
 *#                rlen bytes from the I2c bus.
 *#                The data to be send must be placed in wbuf[ 0 ] upto wbuf[ wlen - 1 ).
 *#                The data to be received is assembled in rbuf[ 0 ] upto rbuf[ rlen - 1 ].
 *#
 *#                If no data is to be sent or received, put appropriate buffer parameter
 *#                to "NULL" and appropriate length parameter to "0".
 *#
 *# PARAMETERS   : slave = slave address of the I2C device
 *#                wbuf  = address of first element of write buffer (wbuf)
 *#                wlen  = number of bytes to be written to slave
 *#                rbuf  = address of first element of read buffer (rbuf)
 *#                rlen  = number of bytes to be read from slave
 *#
 *# RETURN       :
 *#    EI2CNOERRORS: I2C communication went fine
 *#    EI2CBUSNFREE: I2C bus is not free
 *#    EI2CWADDRESS: I2C write address failed
 *#    EI2CRADDRESS: I2C read address failed
 *#    EI2CSENDDATA: I2C send data failed
 *#    EI2CRECVDATA: I2C receive data failed
 *#    EI2CSTRTCOND: I2C start condition failed
 *#    EI2CRSTACOND: I2C repeated start condition failed
 *#    EI2CSTOPCOND: I2C stop condition failed
 *#    EI2CNOSNDBYT: I2C no bytes to be sent
 *#    EI2CNOSNDBUF: I2C no send buffer defined
 *#    EI2CNORCVBYT: I2C no bytes to be received
 *#    EI2CNORCVBUF: I2C no receive buffer defined
 *#    EI2CNOACKNLD: I2C no acknowledge received
 *#
 *# REMARK       :
 *#   First, the send part is completed.
 *#   In the send routine, there is no stop generated.  This is because maybe
 *#   a repeated start condition must be generated.
 *#   This happens when we want to receive some data from the I2c bus.  If not,
 *#   at the end of the general I2c loop the stopcondition is generated.
 *#   If, on the contrary, there are a number of bytes to be received, a new
 *#   startcondition is generated in the 'if' part of the main I2c routine,
 *#   which controls the receiving part.
 *#   Only when the receiving of data is finished, a final stopcondition is
 *#   generated.
 *#
 *#---------------------------------------------------------------------------
 */
static int i2c_command( unsigned char  slave
                      , unsigned char* wbuf
                      , unsigned char  wlen
                      , unsigned char* rbuf
                      , unsigned char  rlen
                      )
{
    /* Check arguments and report error if relevant... */
    if ( ( wlen > 0 ) && ( wbuf == NULL ) )
    {
        printk( KERN_DEBUG "I2C: EI2CNOSNDBUF\n" );
        return ( EI2CNOSNDBUF );
    }
    else if ( ( wlen == 0 ) && ( wbuf != NULL ) )
    {
        printk( KERN_DEBUG "I2C: EI2CNOSNDBYT\n" );
        return ( EI2CNOSNDBYT );
    }
    else if ( ( rlen > 0 ) && ( rbuf == NULL ) )
    {
        printk( KERN_DEBUG "I2C: EI2CNORCVBUF\n" );
        return ( EI2CNORCVBUF );
    }
    else if ( ( rlen == 0 ) && ( rbuf != NULL ) )
    {
        printk( KERN_DEBUG "I2C: EI2CNORCVBYT\n" );
        return ( EI2CNORCVBYT );
    }
    else if ( EI2CBUSNFREE == i2c_bus_free_check( MAXBUSFREERETRIES ) )
    {
        /* There's no need to try more, since we weren't even
         * able to start the I2C communication.
         * So, no IRQ flags are stored yet, no changes to any other
         * stuff like START, STOP, SENDBYTES...
         * Result, simply write down the error and return the correct error code.
         */
        printk( KERN_DEBUG "I2C: EI2CBUSNFREE\n" );
        return ( EI2CBUSNFREE );
    }
    else
    {
        /* Finally... We made it... */
        unsigned long irqflags = 0;

        /* we don't like to be interrupted */
        local_irq_save( irqflags );

        /* Check if there are bytes to be send,
         * or if you immediately want to receive data.
         */
        if ( 0 < wlen )
        {
            /* start I2C communication */
            if ( EI2CNOERRORS != i2c_start() )
            {
                return ( i2c_finalise( "I2C: EI2CSTRTCOND\n", irqflags  )
                       , EI2CSTRTCOND
                       );
            }

            /* send slave address: xxxxxxx0B (last bit must be zero) */
            if ( EI2CNOERRORS != i2c_outbyte( slave & WRITEADDRESS_MASK ) )
            {
                return ( i2c_finalise( "I2C: EI2CWADDRESS\n", irqflags  )
                       , EI2CWADDRESS
                       );
            }

            while ( wlen-- )
            {
                /* send register data */
                if ( EI2CNOERRORS != i2c_outbyte( *wbuf ) && wlen )
                {
                    return ( i2c_finalise( "I2C: EI2CSENDDATA\n", irqflags  )
                           , EI2CSENDDATA
                           );
                }

                wbuf++;
            };

            i2c_delay( TLOW );
        }

        /*
         * Receiving data from I2c_bus
         * If there are bytes to be received, a new start condition is
         * generated => Repeated Startcondition.
         * A final stopcondition is generated at the end of the main I2c
         * routine.
         */
        if ( 0 < rlen )
        {
            /*
             * Generate start condition if wlen == 0
             * or repeated start condition if wlen != 0...
             */
            if ( EI2CNOERRORS != i2c_start() )
            {
                return ( i2c_finalise( ( ( 0 < wlen )
                                       ? "I2C: EI2CRSTACOND\n"
                                       : "I2C: EI2CSTRTCOND\n"
                                       )
                                     , irqflags
                                     )
                       , ( ( 0 < wlen ) ? EI2CRSTACOND : EI2CSTRTCOND )
                       );
            }

            /* Send ReadAddress: xxxxxxx1B (last bit must be one) */
            if ( EI2CNOERRORS != i2c_outbyte( slave | READADDRESS_MASK ) )
            {
                return ( i2c_finalise( "I2C: EI2CRADDRESS\n", irqflags )
                       , EI2CRADDRESS
                       );
            }

            while ( rlen-- )
            {
                /* fetch register */
                *rbuf = i2c_inbyte();
                rbuf++;

                /* last received byte needs to be NACK-ed instead of ACK-ed */
                if ( rlen )
                {
                    i2c_sendack();
                }
                else
                {
                    i2c_sendnack();
                }
            };
        }

        /* Generate final stop condition */
        if ( EI2CNOERRORS != i2c_stop() )
        {
            return ( i2c_finalise( "I2C CMD: EI2CSTOPCOND\n", irqflags )
                   , EI2CSTOPCOND
                   );
        }

        /* enable interrupt again */
        local_irq_restore( irqflags );
    }

    return ( EI2CNOERRORS );
} /*  i2c_command */
コード例 #7
0
ファイル: i2c_gvc.c プロジェクト: 7LK/McWRT
/*#---------------------------------------------------------------------------
 *#
 *# FUNCTION NAME: i2c_readreg
 *#
 *# DESCRIPTION  : reads the value from a certain register of an I2C device.
 *#                Function first writes the register that it wants to read
 *#                later on.
 *#
 *# PARAMETERS   : theSlave = slave address of the I2C device
 *#                theReg   = register of the I2C device that needs to be written
 *#
 *# RETURN       : returns OR-ed result of the write action:
 *#                  0 = Ok
 *#                  1 = Slave_NoAck
 *#                  2 = Reg_NoAck
 *#                  4 = Val_NoAck
 *#
 *#---------------------------------------------------------------------------
 */
unsigned char i2c_readreg( unsigned char theSlave
                         , unsigned char theReg
                         )
{
    unsigned char b = 0;
    int error, cntr = 3;
    unsigned long flags;

    spin_lock( &i2c_lock );

    do
    {
        error = 0;

        /* we don't like to be interrupted */
        local_irq_save( flags );

        /* generate start condition */
        i2c_start();

        /* send slave address */
        if ( EI2CNOACKNLD == i2c_outbyte( theSlave & 0xfe ) )
        {
            error = 1;
        }

        /* now select register */
        i2c_sda_dir_out();

        if ( EI2CNOACKNLD == i2c_outbyte( theReg ) )
        {
            error |= 2;
        }

        /* repeat start condition */
        i2c_delay( TLOW );
        i2c_start();

        /* send slave address */
        if ( EI2CNOACKNLD == i2c_outbyte( theSlave | 0x01 ) )
        {
            error |= 1;
        }

        /* fetch register */
        b = i2c_inbyte();
        /*
         * last received byte needs to be nacked
         * instead of acked
         */
        i2c_sendnack();

        /* end sequence */
        i2c_stop();

        /* enable interrupt again */
        local_irq_restore( flags );

    } while ( error && cntr-- );

    spin_unlock( &i2c_lock );

    return ( b );
}   /* i2c_readreg */