OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [kernel/] [iic.c] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

Rev 1765 Rev 1782
/*
/*
 * linux/arch/arm/kernel/iic.c
 * linux/arch/arm/kernel/iic.c
 *
 *
 * Copyright (C) 1995, 1996 Russell King
 * Copyright (C) 1995, 1996 Russell King
 *
 *
 * IIC is used to get the current time from the CMOS rtc.
 * IIC is used to get the current time from the CMOS rtc.
 */
 */
 
 
#include <asm/system.h>
#include <asm/system.h>
#include <asm/delay.h>
#include <asm/delay.h>
#include <asm/io.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/hardware.h>
 
 
#define FORCE_ONES      0xdc
#define FORCE_ONES      0xdc
 
 
/*
/*
 * if delay loop has been calibrated then us that,
 * if delay loop has been calibrated then us that,
 * else use IOC timer 1.
 * else use IOC timer 1.
 */
 */
static void iic_delay (void)
static void iic_delay (void)
{
{
        extern unsigned long loops_per_sec;
        extern unsigned long loops_per_sec;
        if (loops_per_sec != (1 << 12)) {
        if (loops_per_sec != (1 << 12)) {
                udelay(10);
                udelay(10);
                return;
                return;
        } else {
        } else {
                unsigned long flags;
                unsigned long flags;
                save_flags_cli(flags);
                save_flags_cli(flags);
 
 
                outb(254,  IOC_T1LTCHL);
                outb(254,  IOC_T1LTCHL);
                outb(255,  IOC_T1LTCHH);
                outb(255,  IOC_T1LTCHH);
                outb(0,    IOC_T1GO);
                outb(0,    IOC_T1GO);
                outb(1<<6, IOC_IRQCLRA);                        /* clear T1 irq */
                outb(1<<6, IOC_IRQCLRA);                        /* clear T1 irq */
                outb(4,    IOC_T1LTCHL);
                outb(4,    IOC_T1LTCHL);
                outb(0,    IOC_T1LTCHH);
                outb(0,    IOC_T1LTCHH);
                outb(0,    IOC_T1GO);
                outb(0,    IOC_T1GO);
                while ((inb(IOC_IRQSTATA) & (1<<6)) == 0);
                while ((inb(IOC_IRQSTATA) & (1<<6)) == 0);
                restore_flags(flags);
                restore_flags(flags);
        }
        }
}
}
 
 
static inline void iic_start (void)
static inline void iic_start (void)
{
{
        unsigned char out;
        unsigned char out;
 
 
        out = inb(IOC_CONTROL) | FORCE_ONES | 0x02;
        out = inb(IOC_CONTROL) | FORCE_ONES | 0x02;
 
 
        outb(out, IOC_CONTROL);
        outb(out, IOC_CONTROL);
        iic_delay();
        iic_delay();
 
 
        outb(out ^ 1, IOC_CONTROL);
        outb(out ^ 1, IOC_CONTROL);
        iic_delay();
        iic_delay();
}
}
 
 
static inline void iic_stop (void)
static inline void iic_stop (void)
{
{
        unsigned char out;
        unsigned char out;
 
 
        out = inb(IOC_CONTROL) | FORCE_ONES | 0x03;
        out = inb(IOC_CONTROL) | FORCE_ONES | 0x03;
 
 
        iic_delay();
        iic_delay();
        outb(out ^ 1, IOC_CONTROL);
        outb(out ^ 1, IOC_CONTROL);
 
 
        iic_delay();
        iic_delay();
        outb(out, IOC_CONTROL);
        outb(out, IOC_CONTROL);
}
}
 
 
static int iic_sendbyte (unsigned char b)
static int iic_sendbyte (unsigned char b)
{
{
        unsigned char out, in;
        unsigned char out, in;
        int i;
        int i;
 
 
        out = (inb(IOC_CONTROL) & 0xfc) | FORCE_ONES;
        out = (inb(IOC_CONTROL) & 0xfc) | FORCE_ONES;
 
 
        outb(out, IOC_CONTROL);
        outb(out, IOC_CONTROL);
        for (i = 7; i >= 0; i--) {
        for (i = 7; i >= 0; i--) {
                unsigned char c;
                unsigned char c;
                c = out | ((b & (1 << i)) ? 1 : 0);
                c = out | ((b & (1 << i)) ? 1 : 0);
 
 
                outb(c, IOC_CONTROL);
                outb(c, IOC_CONTROL);
                iic_delay();
                iic_delay();
 
 
                outb(c | 2, IOC_CONTROL);
                outb(c | 2, IOC_CONTROL);
                iic_delay();
                iic_delay();
 
 
                outb(c, IOC_CONTROL);
                outb(c, IOC_CONTROL);
        }
        }
        outb(out | 1, IOC_CONTROL);
        outb(out | 1, IOC_CONTROL);
        iic_delay();
        iic_delay();
 
 
        outb(out | 3, IOC_CONTROL);
        outb(out | 3, IOC_CONTROL);
        iic_delay();
        iic_delay();
 
 
        in = inb(IOC_CONTROL) & 1;
        in = inb(IOC_CONTROL) & 1;
 
 
        outb(out | 1, IOC_CONTROL);
        outb(out | 1, IOC_CONTROL);
        iic_delay();
        iic_delay();
 
 
        outb(out, IOC_CONTROL);
        outb(out, IOC_CONTROL);
        iic_delay();
        iic_delay();
 
 
        if(in) {
        if(in) {
                printk("No acknowledge from RTC\n");
                printk("No acknowledge from RTC\n");
                return 1;
                return 1;
        } else
        } else
                return 0;
                return 0;
}
}
 
 
static unsigned char iic_recvbyte (void)
static unsigned char iic_recvbyte (void)
{
{
        unsigned char out, in;
        unsigned char out, in;
        int i;
        int i;
 
 
        out = (inb(IOC_CONTROL) & 0xfc) | FORCE_ONES;
        out = (inb(IOC_CONTROL) & 0xfc) | FORCE_ONES;
 
 
        outb(out, IOC_CONTROL);
        outb(out, IOC_CONTROL);
        in = 0;
        in = 0;
        for (i = 7; i >= 0; i--) {
        for (i = 7; i >= 0; i--) {
                outb(out | 1, IOC_CONTROL);
                outb(out | 1, IOC_CONTROL);
                iic_delay();
                iic_delay();
                outb(out | 3, IOC_CONTROL);
                outb(out | 3, IOC_CONTROL);
                iic_delay();
                iic_delay();
                in = (in << 1) | (inb(IOC_CONTROL) & 1);
                in = (in << 1) | (inb(IOC_CONTROL) & 1);
                outb(out | 1, IOC_CONTROL);
                outb(out | 1, IOC_CONTROL);
                iic_delay();
                iic_delay();
        }
        }
        outb(out, IOC_CONTROL);
        outb(out, IOC_CONTROL);
        iic_delay();
        iic_delay();
        outb(out | 2, IOC_CONTROL);
        outb(out | 2, IOC_CONTROL);
        iic_delay();
        iic_delay();
 
 
        return in;
        return in;
}
}
 
 
void iic_control (unsigned char addr, unsigned char loc, unsigned char *buf, int len)
void iic_control (unsigned char addr, unsigned char loc, unsigned char *buf, int len)
{
{
        iic_start();
        iic_start();
 
 
        if (iic_sendbyte(addr & 0xfe))
        if (iic_sendbyte(addr & 0xfe))
                goto error;
                goto error;
 
 
        if (iic_sendbyte(loc))
        if (iic_sendbyte(loc))
                goto error;
                goto error;
 
 
        if (addr & 1) {
        if (addr & 1) {
                int i;
                int i;
 
 
                for (i = 0; i < len; i++)
                for (i = 0; i < len; i++)
                        if (iic_sendbyte (buf[i]))
                        if (iic_sendbyte (buf[i]))
                                break;
                                break;
        } else {
        } else {
                int i;
                int i;
 
 
                iic_stop();
                iic_stop();
                iic_start();
                iic_start();
                iic_sendbyte(addr|1);
                iic_sendbyte(addr|1);
                for (i = 0; i < len; i++)
                for (i = 0; i < len; i++)
                        buf[i] = iic_recvbyte ();
                        buf[i] = iic_recvbyte ();
        }
        }
error:
error:
        iic_stop();
        iic_stop();
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.