summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c668
1 files changed, 0 insertions, 668 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c b/c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c
deleted file mode 100644
index b4c3d477f7..0000000000
--- a/c/src/lib/libcpu/powerpc/mpc83xx/i2c/mpc83xx_i2cdrv.c
+++ /dev/null
@@ -1,668 +0,0 @@
-/*===============================================================*\
-| Project: RTEMS support for MPC83xx |
-+-----------------------------------------------------------------+
-| Copyright (c) 2007 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| |
-| http://www.rtems.org/license/LICENSE. |
-| |
-+-----------------------------------------------------------------+
-| this file contains the MPC83xx I2C driver |
-\*===============================================================*/
-#include <stdlib.h>
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <mpc83xx/mpc83xx_i2cdrv.h>
-#include <rtems/error.h>
-#include <rtems/bspIo.h>
-#include <errno.h>
-#include <rtems/libi2c.h>
-
-#undef DEBUG
-
-#if defined(LIBBSP_POWERPC_GEN83XX_BSP_H)
- #define I2CCR_MEN (1 << 7) /* module enable */
-#elif defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
- #define I2CCR_MDIS (1 << 7) /* module disable */
-#endif
-#define I2CCR_MIEN (1 << 6) /* module interrupt enable */
-#define I2CCR_MSTA (1 << 5) /* 0->1 generates a start condiiton, 1->0 a stop */
-#define I2CCR_MTX (1 << 4) /* 0 = receive mode, 1 = transmit mode */
-#define I2CCR_TXAK (1 << 3) /* 0 = send ack 1 = send nak during receive */
-#define I2CCR_RSTA (1 << 2) /* 1 = send repeated start condition */
-#define I2CCR_BCST (1 << 0) /* 0 = disable 1 = enable broadcast accept */
-
-#define I2CSR_MCF (1 << 7) /* data transfer (0=transfer in progres) */
-#define I2CSR_MAAS (1 << 6) /* addessed as slave */
-#define I2CSR_MBB (1 << 5) /* bus busy */
-#define I2CSR_MAL (1 << 4) /* arbitration lost */
-#define I2CSR_BCSTM (1 << 3) /* broadcast match */
-#define I2CSR_SRW (1 << 2) /* slave read/write */
-#define I2CSR_MIF (1 << 1) /* module interrupt */
-#define I2CSR_RXAK (1 << 0) /* receive acknowledge */
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code mpc83xx_i2c_find_clock_divider
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| determine proper divider value |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- uint8_t *result, /* result value */
- int divider /* requested divider */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- int i;
- int fdr_val;
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- struct {
- int divider;
- int fdr_val;
- } dividers[] ={
-#if defined(LIBBSP_POWERPC_GEN83XX_BSP_H)
- { 256,0x20 }, { 288,0x21 }, { 320,0x22 }, { 352,0x23 },
- { 384,0x00 }, { 416,0x01 }, { 448,0x25 }, { 480,0x02 },
- { 512,0x26 }, { 576,0x03 }, { 640,0x04 }, { 704,0x05 },
- { 768,0x29 }, { 832,0x06 }, { 896,0x2a }, { 1024,0x07 },
- { 1152,0x08 }, { 1280,0x09 }, { 1536,0x0A }, { 1792,0x2E },
- { 1920,0x0B }, { 2048,0x2F }, { 2304,0x0C }, { 2560,0x0D },
- { 3072,0x0E }, { 3584,0x32 }, { 3840,0x0F }, { 4096,0x33 },
- { 4608,0x10 }, { 5120,0x11 }, { 6144,0x12 }, { 7168,0x36 },
- { 7680,0x13 }, { 8192,0x37 }, { 9216,0x14 }, {10240,0x15 },
- {12288,0x16 }, {14336,0x3A }, {15360,0x17 }, {16384,0x3B },
- {18432,0x18 }, {20480,0x19 }, {24576,0x1A }, {28672,0x3E },
- {30720,0x1B }, {32768,0x3F }, {36864,0x1C }, {40960,0x1D },
- {49152,0x1E }, {61440,0x1F }
-#elif defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
- { 768, 0x31 }
-#endif
- };
-
- if (divider <= 0) {
- sc = RTEMS_INVALID_NUMBER;
- }
-
- if (sc == RTEMS_SUCCESSFUL) {
- sc = RTEMS_INVALID_NUMBER;
- for (i = 0, fdr_val = -1; i < sizeof(dividers)/sizeof(dividers[0]); i++) {
- fdr_val = dividers[i].fdr_val;
- if (dividers[i].divider >= divider)
- {
- sc = RTEMS_SUCCESSFUL;
- *result = fdr_val;
- break;
- }
- }
- }
- return sc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static int mpc83xx_i2c_wait
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| wait for i2c to become idle |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- mpc83xx_i2c_softc_t *softc_ptr, /* handle */
- uint8_t desired_status, /* desired status word */
- uint8_t status_mask /* status word mask */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- uint8_t act_status;
- rtems_status_code rc;
- uint32_t tout;
-
-#if defined(DEBUG)
- printk("mpc83xx_i2c_wait called... ");
-#endif
-
- if (softc_ptr->initialized) {
- /*
- * enable interrupt mask
- */
- softc_ptr->reg_ptr->i2ccr |= I2CCR_MIEN;
- rc = rtems_semaphore_obtain(softc_ptr->irq_sema_id,RTEMS_WAIT,100);
- if (rc != RTEMS_SUCCESSFUL) {
- return rc;
- }
- }
- else {
- tout = 0;
- do {
- if (tout++ > 1000000) {
-#if defined(DEBUG)
- printk("... exit with RTEMS_TIMEOUT\r\n");
-#endif
- return RTEMS_TIMEOUT;
- }
- } while (!(softc_ptr->reg_ptr->i2csr & I2CSR_MIF));
- }
- softc_ptr->reg_ptr->i2ccr &= ~I2CCR_MIEN;
-
- act_status = softc_ptr->reg_ptr->i2csr;
- if ((act_status & status_mask) != desired_status) {
-#if defined(DEBUG)
- printk("... exit with RTEMS_IO_ERROR\r\n");
-#endif
- return RTEMS_IO_ERROR;
- }
-#if defined(DEBUG)
- printk("... exit OK\r\n");
-#endif
- return RTEMS_SUCCESSFUL;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static void mpc83xx_i2c_irq_handler
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| handle interrupts |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_irq_hdl_param handle /* handle, is softc_ptr structure */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| <none> |
-\*=========================================================================*/
-{
- mpc83xx_i2c_softc_t *softc_ptr = (mpc83xx_i2c_softc_t *)handle;
-
- /*
- * clear IRQ flag
- */
- #if defined(LIBBSP_POWERPC_GEN83XX_BSP_H)
- softc_ptr->reg_ptr->i2csr &= ~I2CSR_MIF;
- #elif defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
- softc_ptr->reg_ptr->i2csr = I2CSR_MIF;
- #endif
-
- /*
- * disable interrupt mask
- */
- softc_ptr->reg_ptr->i2ccr &= ~I2CCR_MIEN;
- if (softc_ptr->initialized) {
- rtems_semaphore_release(softc_ptr->irq_sema_id);
- }
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static void mpc83xx_i2c_irq_on_off
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| enable/disable interrupts (void, handled at different position) |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- const
- rtems_irq_connect_data *irq_conn_data /* irq connect data */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| <none> |
-\*=========================================================================*/
-{
-}
-
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static int mpc83xx_i2c_irq_isOn
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| check state of interrupts, void, done differently |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- const
- rtems_irq_connect_data *irq_conn_data /* irq connect data */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| TRUE, if enabled |
-\*=========================================================================*/
-{
- return (TRUE);
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static void mpc83xx_i2c_install_irq_handler
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| (un-)install the interrupt handler |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- mpc83xx_i2c_softc_t *softc_ptr, /* ptr to control structure */
- int install /* TRUE: install, FALSE: remove */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| <none> |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
-
- rtems_irq_connect_data irq_conn_data = {
- softc_ptr->irq_number,
- mpc83xx_i2c_irq_handler, /* rtems_irq_hdl */
- (rtems_irq_hdl_param)softc_ptr, /* (rtems_irq_hdl_param) */
- mpc83xx_i2c_irq_on_off, /* (rtems_irq_enable) */
- mpc83xx_i2c_irq_on_off, /* (rtems_irq_disable) */
- mpc83xx_i2c_irq_isOn /* (rtems_irq_is_enabled) */
- };
-
- /*
- * (un-)install handler for I2C device
- */
- if (install) {
- /*
- * create semaphore for IRQ synchronization
- */
- rc = rtems_semaphore_create(rtems_build_name('i','2','c','s'),
- 0,
- RTEMS_FIFO
- | RTEMS_SIMPLE_BINARY_SEMAPHORE,
- 0,
- &softc_ptr->irq_sema_id);
- if (rc != RTEMS_SUCCESSFUL) {
- rtems_panic("I2C: cannot create semaphore");
- }
- if (!BSP_install_rtems_irq_handler (&irq_conn_data)) {
- rtems_panic("I2C: cannot install IRQ handler");
- }
- }
- else {
- if (!BSP_remove_rtems_irq_handler (&irq_conn_data)) {
- rtems_panic("I2C: cannot uninstall IRQ handler");
- }
- /*
- * delete sync semaphore
- */
- if (softc_ptr->irq_sema_id != 0) {
- rc = rtems_semaphore_delete(softc_ptr->irq_sema_id);
- if (rc != RTEMS_SUCCESSFUL) {
- rtems_panic("I2C: cannot delete semaphore");
- }
- }
- }
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code mpc83xx_i2c_init
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| initialize the driver |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_libi2c_bus_t *bh /* bus specifier structure */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
- uint8_t fdr_val;
- int errval;
-#if defined(DEBUG)
- printk("mpc83xx_i2c_init called... ");
-#endif
- /*
- * init HW registers
- */
- /*
- * init frequency divider to 100kHz
- */
- errval = mpc83xx_i2c_find_clock_divider(&fdr_val,
- softc_ptr->base_frq/100000);
- if (errval != 0) {
- return errval;
- }
- softc_ptr->reg_ptr->i2cfdr = fdr_val;
- /*
- * init digital filter sampling rate
- */
- softc_ptr->reg_ptr->i2cdfsrr = 0x10 ; /* no special filtering needed */
- /*
- * set own slave address to broadcast (0x00)
- */
- softc_ptr->reg_ptr->i2cadr = 0x00 ;
-
- /*
- * set control register to module enable
- */
- #if defined(LIBBSP_POWERPC_GEN83XX_BSP_H)
- softc_ptr->reg_ptr->i2ccr = I2CCR_MEN;
- #elif defined(LIBBSP_POWERPC_MPC55XXEVB_BSP_H)
- softc_ptr->reg_ptr->i2ccr = 0;
- #endif
-
- /*
- * init interrupt stuff
- */
- mpc83xx_i2c_install_irq_handler(softc_ptr,TRUE);
-
- /*
- * mark, that we have initialized
- */
- softc_ptr->initialized = TRUE;
-#if defined(DEBUG)
- printk("... exit OK\r\n");
-#endif
- return RTEMS_SUCCESSFUL;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code mpc83xx_i2c_send_start
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| send a start condition to bus |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_libi2c_bus_t *bh /* bus specifier structure */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
-
-#if defined(DEBUG)
- printk("mpc83xx_i2c_send_start called... ");
-#endif
- if (0 != (softc_ptr->reg_ptr->i2ccr & I2CCR_MSTA)) {
- /*
- * already started, so send a "repeated start"
- */
- softc_ptr->reg_ptr->i2ccr |= I2CCR_RSTA;
- }
- else {
- softc_ptr->reg_ptr->i2ccr |= I2CCR_MSTA;
- }
-
-#if defined(DEBUG)
- printk("... exit OK\r\n");
-#endif
- return 0;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code mpc83xx_i2c_send_stop
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| send a stop condition to bus |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_libi2c_bus_t *bh /* bus specifier structure */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
-
-#if defined(DEBUG)
- printk("mpc83xx_i2c_send_stop called... ");
-#endif
- softc_ptr->reg_ptr->i2ccr &= ~I2CCR_MSTA;
- /*
- * wait, 'til stop has been executed
- */
- while (0 != (softc_ptr->reg_ptr->i2csr & I2CSR_MBB)) {
- rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
- }
-#if defined(DEBUG)
- printk("... exit OK\r\n");
-#endif
- return 0;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code mpc83xx_i2c_send_addr
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| address a slave device on the bus |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_libi2c_bus_t *bh, /* bus specifier structure */
- uint32_t addr, /* address to send on bus */
- int rw /* 0=write,1=read */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
- uint8_t addr_byte;
- rtems_status_code rc;
-
-#if defined(DEBUG)
- printk("mpc83xx_i2c_send_addr called... ");
-#endif
- softc_ptr->reg_ptr->i2ccr |= I2CCR_MTX;
- /*
- * determine, whether short or long address is needed, determine rd/wr
- */
- if (addr > 0x7f) {
- addr_byte = (0xf0
- | ((addr >> 7) & 0x06)
- | ((rw) ? 1 : 0));
- /*
- * send first byte
- */
- softc_ptr->reg_ptr->i2cdr = addr_byte;
- /*
- * wait for successful transfer
- */
- rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF | I2CSR_RXAK);
- if (rc != RTEMS_SUCCESSFUL) {
-#if defined(DEBUG)
- printk("... exit rc=%d\r\n",rc);
-#endif
- return rc;
- }
- }
- /*
- * send (final) byte
- */
- addr_byte = ((addr << 1)
- | ((rw) ? 1 : 0));
-
- softc_ptr->reg_ptr->i2cdr = addr_byte;
- /*
- * wait for successful transfer
- */
- rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF | I2CSR_RXAK);
-
-#if defined(DEBUG)
- printk("... exit rc=%d\r\n",rc);
-#endif
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static int mpc83xx_i2c_read_bytes
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| receive some bytes from I2C device |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_libi2c_bus_t *bh, /* bus specifier structure */
- unsigned char *buf, /* buffer to store bytes */
- int len /* number of bytes to receive */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| number of bytes received or (negative) error code |
-\*=========================================================================*/
-{
- mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
- rtems_status_code rc;
- unsigned char *p = buf;
-
-#if defined(DEBUG)
- printk("mpc83xx_i2c_read_bytes called... ");
-#endif
- softc_ptr->reg_ptr->i2ccr &= ~I2CCR_MTX;
- softc_ptr->reg_ptr->i2ccr &= ~I2CCR_TXAK;
- /*
- * FIXME: do we need to deactivate TXAK from the start,
- * when only one byte is to be received?
- */
- /*
- * we need a dummy transfer here to start the first read
- */
- softc_ptr->reg_ptr->i2cdr;
-
- while (len-- > 0) {
- if (len == 0) {
- /*
- * last byte is not acknowledged
- */
- softc_ptr->reg_ptr->i2ccr |= I2CCR_TXAK;
- }
- /*
- * wait 'til end of transfer
- */
- rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF);
- if (rc != RTEMS_SUCCESSFUL) {
-#if defined(DEBUG)
- printk("... exit rc=%d\r\n",-rc);
-#endif
- return -rc;
- }
- *p++ = softc_ptr->reg_ptr->i2cdr;
-
- }
-
- /*
- * wait 'til end of last transfer
- */
- rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF);
-
-#if defined(DEBUG)
- printk("... exit OK, rc=%d\r\n",p-buf);
-#endif
- return p - buf;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static int mpc83xx_i2c_write_bytes
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| send some bytes to I2C device |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_libi2c_bus_t *bh, /* bus specifier structure */
- unsigned char *buf, /* buffer to send */
- int len /* number of bytes to send */
-
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| number of bytes sent or (negative) error code |
-\*=========================================================================*/
-{
- mpc83xx_i2c_softc_t *softc_ptr = &(((mpc83xx_i2c_desc_t *)(bh))->softc);
- rtems_status_code rc;
- unsigned char *p = buf;
-
-#if defined(DEBUG)
- printk("mpc83xx_i2c_write_bytes called... ");
-#endif
- softc_ptr->reg_ptr->i2ccr =
- (softc_ptr->reg_ptr->i2ccr & ~I2CCR_TXAK) | I2CCR_MTX;
- while (len-- > 0) {
- int rxack = len != 0 ? I2CSR_RXAK : 0;
-
- softc_ptr->reg_ptr->i2cdr = *p++;
- /*
- * wait 'til end of transfer
- */
- rc = mpc83xx_i2c_wait(softc_ptr, I2CSR_MCF, I2CSR_MCF | rxack);
- if (rc != RTEMS_SUCCESSFUL) {
-#if defined(DEBUG)
- printk("... exit rc=%d\r\n",-rc);
-#endif
- return -rc;
- }
- }
-#if defined(DEBUG)
- printk("... exit OK, rc=%d\r\n",p-buf);
-#endif
- return p - buf;
-}
-
-rtems_libi2c_bus_ops_t mpc83xx_i2c_ops = {
- .init = mpc83xx_i2c_init,
- .send_start = mpc83xx_i2c_send_start,
- .send_stop = mpc83xx_i2c_send_stop,
- .send_addr = mpc83xx_i2c_send_addr,
- .read_bytes = mpc83xx_i2c_read_bytes,
- .write_bytes = mpc83xx_i2c_write_bytes,
-};
-