All pastes #992150 Raw Edit

Stuff

public text v1 · immutable
#992150 ·published 2008-04-21 17:13 UTC
rendered paste body
#ifdef USE_IMX31_I2C_DRIVER
        #define LOGF_ENABLE
        #define IADR            (I2C_BASE_ADDR | 0x00)
        #define IFDR            (I2C_BASE_ADDR | 0x04)
        #define I2CR            (I2C_BASE_ADDR | 0x08)
        #define I2SR            (I2C_BASE_ADDR | 0x0c)
        #define I2DR            (I2C_BASE_ADDR | 0x10)

        #define I2CR_IEN        (1 << 7)
        #define I2CR_IIEN       (1 << 6)
        #define I2CR_MSTA       (1 << 5)
        #define I2CR_MTX        (1 << 4)
        #define I2CR_TX_NO_AK   (1 << 3)
        #define I2CR_RSTA       (1 << 2)

        #define I2SR_ICF        (1 << 7)
        #define I2SR_IBB        (1 << 5)
        #define I2SR_IIF        (1 << 1)
        #define I2SR_RX_NO_AK   (1 << 0)

        static unsigned short div[] = { 30, 32, 36, 42, 48, 52, 60, 72, 80, 88, 104, 128, 144,
                                        160, 192, 240, 288, 320, 384, 480, 576, 640, 768, 960,
                                        1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840};

        static unsigned long mx31_decode_pll(int unsigned long reg, int unsigned long infreq)
        {
                int unsigned long mfi = (reg >> 10) & 0xf;
                int unsigned long mfn =  reg & 0x3f;
                int unsigned long mfd = (reg >> 16) & 0x3f;
                int unsigned long pd =  (reg >> 26) & 0xf;

                mfi = mfi <= 5 ? 5 : mfi;
                mfd += 1;
                pd += 1;

                return ((2 * (infreq >> 10) * (mfi * mfd + mfn)) /
                        (mfd * pd)) << 10;
        }

        static int mx31_get_mpl_dpdgck_clk(void)
        {
                int unsigned long infreq;

                /*if ((__REG(CLKCTL_CCMR) & CCMR_PRCS_MASK) == CCMR_FPM)
                        infreq = CONFIG_MX31_CLK32 * 1024;
                else*/
                        infreq = CONFIG_MX31_HCLK_FREQ;

                return mx31_decode_pll(__REG32(CCM_MPCTL), infreq);
        }

        static int mx31_get_mcu_main_clk(void)
        {
                /* For now we assume mpl_dpdgck_clk == mcu_main_clk
                * which should be correct for most boards
                */
                return mx31_get_mpl_dpdgck_clk();
        }

        static int mx31_get_ipg_clk(void)
        {
                int unsigned long freq = mx31_get_mcu_main_clk();
                int unsigned long pdr0 = __REG32(CCM_PDR0);

                freq /= ((pdr0 >> 3) & 0x7) + 1;
                freq /= ((pdr0 >> 6) & 0x3) + 1;

                return freq;
        }
        void i2c_init(int speed)
        {
                 int freq = mx31_get_ipg_clk();
                 int i;

                 for (i = 0; i < 0x1f; i++)
                        if (freq / div[i] <= speed)
                                break;

                __REG16(I2CR) = 0; /* Reset module */
                __REG16(IFDR) = i;
                __REG16(I2CR) = I2CR_IEN;
                __REG16(I2SR) = 0;
        }

#else

        #if 0
        static int i2c_getack(void)
        {
            return 0;
        }

        static int i2c_start(void)
        {
            return 0;
        }

        static void i2c_stop(void)
        {
        }

        static int i2c_outb(unsigned char byte)
        {
            (void)byte;
            return 0;
        }
        #endif

        void i2c_write(int addr, const unsigned char *buf, int count)
        {
            (void)addr;
            (void)buf;
            (void)count;
        }

        void i2c_init(void)
        {
        }
#endif