/*
 * Copyright (c) Guylhem Aznar, 2005 - GPL
 *
 * Please check http://externe.net/zaurus/simpad-bluetooth reference design first.
 */

#include <linux/module.h>
#include <linux/mm.h>
#include <linux/init.h>

#include <asm/hardware.h>
#include <asm/uaccess.h>
#include <asm/io.h>

#define MAP_START 0x90040000
#define MAP_SIZE  0x00001000
#define GPIO_OFF  0

#define GPIO_DIR_INPUT 0
#define GPIO_DIR_OUTPUT 1

#define MY_GPLR 0
#define MY_GPDR 1
#define MY_GPSR 2
#define MY_GPCR 3
#define MY_GRER 4
#define MY_GFER 5
#define MY_GEDR 6
#define MY_GAFR 7

typedef unsigned long u32_t;
typedef unsigned short u16_t;
typedef unsigned char u8_t;
typedef struct gpio_s gpio_t;
struct gpio_s {
    volatile u32_t *base;
};

MODULE_AUTHOR("Guylhem Aznar <mmc-driver @externe.net>");
MODULE_DESCRIPTION("Pseudo driver to toggle GPIO 23");
MODULE_SUPPORTED_DEVICE("SA1100");
MODULE_LICENSE("GPL");

gpio_t *gpio_open(void)
{
    static gpio_t tmp;
    tmp.base = (void *) io_p2v(MAP_START);
    return (&tmp);
}

void gpio_setdir(gpio_t * g, int num, int dir)
{
    if (dir == 1) {
	g->base[MY_GPDR] |= (1 << num);
    } else {
	g->base[MY_GPDR] &= ~(1 << num);

    }
}

void gpio_setalt(gpio_t * g, int num, int alt)
{
    if (alt == 1) {
	g->base[MY_GAFR] |= (1 << num);
    } else {
	g->base[MY_GAFR] &= ~(1 << num);

    }
}

int gpio_getdir(gpio_t * g, int num)
{
    return ((g->base[MY_GPDR] & (1 << num)) ? 1 : 0);
}

int gpio_getalt(gpio_t * g, int num)
{
    return ((g->base[MY_GAFR] & (1 << num)) ? 1 : 0);
}

void gpio_write(gpio_t * g, int num, int val)
{
    if (val == 1) {
	g->base[MY_GPSR] = 1 << num;
    } else {
	g->base[MY_GPCR] = 1 << num;
    }
}

int gpio_read(gpio_t * g, int num)
{
    return ((g->base[MY_GPLR] & (1 << num)) ? 1 : 0);
}


void toggle_port(int port, gpio_t * g)
{
//    int i;

//  printk("Printing gpio info: \n");
//    for (i = 0; i < 27; i++) {
//    printk("Pin %u: Alternate=%u, Direction=%u\n", i, gpio_getalt(g, i), gpio_getdir(g, i));
//    }
//  printk("gpio open OK\n");
    gpio_setalt(g, port, 0);
//  printk ("gpio setalt OK\n");
    gpio_setdir(g, port, GPIO_DIR_OUTPUT);
//  printk("gpio setdir OK\n");
//  printk("Printing gpio info: \n");
//  for (i = 0; i < 27; i++) {
//    printk("Pin %u: Alternate=%u, Direction=%u\n", i, gpio_getalt(g, i), gpio_getdir(g, i));
//  }

    if (gpio_read(g, port) == 1) {
	printk("Going from 1 to 0 \n");
	gpio_write(g, port, 0);
    } else {
	printk("Going from 0 to 1 \n");
	gpio_write(g, port, 1);
    }
}

static int __init gpiotoggle_driver_init(void)
{
    gpio_t *g;
//    int i;

    printk("U32 : %u\n", sizeof(u32_t));
    g = gpio_open();
    if (g == NULL) {
	printk("Error at gpio_open\n");
    }
    printk("%x\n", (int) g->base[0]);
    toggle_port(23, g);
}

static void __exit gpiotoggle_driver_exit(void)
{
}

module_init(gpiotoggle_driver_init);
module_exit(gpiotoggle_driver_exit);
This page was last modified 13:56, 21 June 2006. | This page has been accessed 1,009 times. | About OpenSIMpad.org
Designed by Anna Boheim | Powerd by mediawiki