net5501 __JP5__GPIO程序

来源:互联网 发布:提取淘宝买家电话号码 编辑:程序博客网 时间:2024/06/05 03:45
/*  direct GPIO access code for net5501 running linux  Matthew Kaufman 3/24/2009, 4/1/2009  Direct driverless access to PC87366 for GPIO and CS5536 for Error LED  For register details see pgs 480 onward of:    http://www.amd.com/files/connectivitysolutions/geode/geode_lx/33238G_cs5536_db.pdf  And page 129 onward of:    http://www.datasheetcatalog.org/datasheet/nationalsemiconductor/PC87366.pdf  This is example code. A fancier version would make it easier to work with more than one  pin at a time.*/    #include <stdio.h>#include <sys/io.h>#define GPIO_BASE_CS5535   0x6100      /* rather than asking MSR_LBAR_GPIO which is harder to do */#define SIO_INDEX            0x2e      /* index register of PC87366 Super I/O */#define SIO_DATA             0x2f      /* data register of PC87366 Super I/O */#define SIO_REG_SID          0x20      /* Configuration register containing ID */#define SIO_SID_VALUE        0xe9      /* Expected ID value */#define SIO_REG_LDN          0x07      /* Configuration register: logical device number selector */#define SIO_LDN_GPIO         0x07      /* LDN Value to select GPIO configuration */#define SIO_REG_ACTIVATE     0x30      /* (Shared) Device register: Activate */#define SIO_REG_BASE_MSB_0   0x60      /* (Shared) Device register: I/O Port base, descriptor 0, MSB */#define SIO_REG_BASE_LSB_0   0x61      /* (Shared) Device register: I/O Port base, descriptor 0, LSB */#define SIO_GPIO_PIN_SELECT  0xf0      /* GPIO device-specific register: Pin select */#define SIO_GPIO_PIN_CONFIG  0xf1      /* GPIO device-specific register: Pin configuration */int gpio_base = 0;int pin_init(){    int i;    if(iopl(3)) /* allow direct I/O access at 0x2e, 0x6100, 0x6640 and thereabouts. must be root. */        return -1;    outb(SIO_REG_SID, SIO_INDEX);   /* probe PC87366 */    i = inb(SIO_DATA);    if(i != SIO_SID_VALUE)        return -1;    outb(SIO_REG_BASE_MSB_0, SIO_INDEX);    /* get MSB of GPIO I/O */    gpio_base = inb(SIO_DATA) << 8;    outb(SIO_REG_BASE_LSB_0, SIO_INDEX);    /* get LSB of GPIO I/O */    gpio_base |= inb(SIO_DATA);    /* turn on GPIO */    /* Note: the pin configuration calls assume that this logical device select hasn't been overridden */    /* if that's a problem in practice, the next two lines must be added to the _pin_config function   */    outb(SIO_REG_LDN, SIO_INDEX);     /* logical device select */    outb(SIO_LDN_GPIO, SIO_DATA);     /* select GPIO */    outb(SIO_REG_ACTIVATE, SIO_INDEX); /* activation for selected device, which is GPIO */    outb(0x01, SIO_DATA);              /* active */    return 0;}void error_led_set(){    /* error LED is GPIO 6 on the CS5535 */    outl(1 << 6, GPIO_BASE_CS5535); /* using CS5535 atomic set */}void error_led_clear(){    outl(1 << (6+16), GPIO_BASE_CS5535); /* using CS5535 atomic clear */}static int _pin_to_gpio(int pin){    /* mapping table from email by Ralph Becker-Szendy */    switch(pin)    {    case 3: return 16;    case 4: return 17;    case 5: return 18;    case 6: return 19;    case 7: return 20;    case 8: return 21;    case 9: return 22;    case 10: return 23;    case 12: return 4;    case 13: return 5;    case 15: return 11;    case 16: return 10;    default: return -1;    }}int pin_test(int pin){    int gpio = _pin_to_gpio(pin);    int offset;    int i;    if(gpio < 0)        return;    if(gpio >= 16)        offset = 0x09;    else if(gpio >= 8)        offset = 0x05;    else        offset = 0x01;    i = inb(gpio_base + offset);    return(i & (1 << (gpio & 0x07)));}      void pin_set_to(int pin, int set){    int gpio = _pin_to_gpio(pin);    int offset;    int i;    if(gpio_base == 0)        return; /* not initialized */    if(gpio < 0)        return;    if(gpio >= 16)        offset = 0x08;    else if(gpio >= 8)        offset = 0x04;    else        offset = 0x00;    i = inb(gpio_base + offset);    if(set)    {        i |= 1 << (gpio & 0x07);    }    else    {        i &= ~(1 << (gpio & 0x07));    }    outb(i, gpio_base + offset);}void pin_set(int pin){    pin_set_to(pin, 1);}void pin_clear(int pin){    pin_set_to(pin, 0);}static void _pin_config(int pin, int bit, int set){    int gpio = _pin_to_gpio(pin);    int i;    if(gpio_base == 0)        return; /* not initialized */    if(gpio < 0)        return;    /* See note above about how we assume GPIO logical device is already selected */    outb(SIO_GPIO_PIN_SELECT, SIO_INDEX);    outb(((gpio & 0x38) << 1) | (gpio & 0x07), SIO_DATA);    outb( SIO_GPIO_PIN_CONFIG, SIO_INDEX);    i = inb(SIO_DATA);    if(set)    {        i |= 1 << bit;    }    else    {        i &= ~(1 << bit);    }    outb( i, SIO_DATA);}void pin_output_enable(int pin){    _pin_config(pin, 0, 1);}void pin_output_disable(int pin){    _pin_config(pin, 0, 0);}void pin_output_pushpull(int pin){    _pin_config(pin, 1, 1);}void pin_output_opendrain(int pin){    _pin_config(pin, 1, 0);}void pin_output_pullup_enable(int pin){    _pin_config(pin, 2, 1);}void pin_output_pullup_disable(int pin){    _pin_config(pin, 2, 0);}


0 0
原创粉丝点击