Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7693868
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: C/C++

2010-12-18 15:50:02

/* soft-sccb.c
 * Implement the SCCB master side protocol.
 */


#include <linux/module.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/semaphore.h>
#include <mach/regs-gpio.h>
#include <linux/gpio.h>

#include "sccb.h"

static DECLARE_MUTEX(bus_lock);

static void __inline__ sccb_start(void)
{
    CFG_WRITE(SIO_D);

    Low(SIO_D);
    WAIT_STABLE();
}

static void __inline__ sccb_write_byte(u8 data)
{
    int i;

    CFG_WRITE(SIO_D);
    WAIT_STABLE();

    /* write 8-bits octet. */
    for (i=0;i<8;i++)
    {
        Low(SIO_C);
        WAIT_STABLE();

        if (data & 0x80)
        {
            High(SIO_D);
        }
        else
        {
            Low(SIO_D);
        }
        data = data<<1;
        WAIT_CYCLE();
        
        High(SIO_C);
        WAIT_CYCLE();
    }
    
    /* write byte done, wait the Don't care bit now. */
    {
        Low(SIO_C);
        High(SIO_D);
        CFG_READ(SIO_D);
        WAIT_CYCLE();
        
        High(SIO_C);
        WAIT_CYCLE();
    }
}

static u8 __inline__ sccb_read_byte(void)
{
    int i;
    u8 data;

    CFG_READ(SIO_D);
    WAIT_STABLE();
    
    Low(SIO_C);
    WAIT_CYCLE();

    data = 0;
    for (i=0;i<8;i++)
    {
        High(SIO_C);
        WAIT_STABLE();
        
        data = data<<1;
        data |= State(SIO_D)?1:0;
        WAIT_CYCLE();
        
        Low(SIO_C);
        WAIT_CYCLE();
    }
    
    /* read byte down, write the NA bit now.*/
    {
        CFG_WRITE(SIO_D);
        High(SIO_D);
        WAIT_CYCLE();
        
        High(SIO_C);
        WAIT_CYCLE();
    }
    
    return data;
}

static void __inline__ sccb_stop(void)
{
    Low(SIO_C);
    WAIT_STABLE();
    
    CFG_WRITE(SIO_D);
    Low(SIO_D);
    WAIT_CYCLE();
    
    High(SIO_C);
    WAIT_STABLE();
    
    High(SIO_D);
    WAIT_CYCLE();
    
    CFG_READ(SIO_D);
}

void sccb_write(u8 IdAddr, u8 SubAddr, u8 data)
{
    down(&bus_lock);
    sccb_start();
    sccb_write_byte(IdAddr);
    sccb_write_byte(SubAddr);
    sccb_write_byte(data);
    sccb_stop();
    up (&bus_lock);
}

u8 sccb_read(u8 IdAddr, u8 SubAddr)
{
    u8 data;

    down(&bus_lock);
    sccb_start();
    sccb_write_byte(IdAddr);
    sccb_write_byte(SubAddr);
    sccb_stop();

    sccb_start();
    sccb_write_byte(IdAddr|0x01);
    data = sccb_read_byte();
    sccb_stop();
    up(&bus_lock);
    
    return data;
}

int sccb_init(void)
{
    CFG_WRITE(SIO_C);
    CFG_WRITE(SIO_D);

    High(SIO_C);
    High(SIO_D);
    WAIT_STABLE();

    return 0;
}

void sccb_cleanup(void)
{
    CFG_READ(SIO_C);
    CFG_READ(SIO_D);
}


阅读(1697) | 评论(0) | 转发(3) |
0

上一篇:s3c2440_camif.h

下一篇:sccb.h

给主人留下些什么吧!~~