/*
* 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 read_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_INPUT);
// 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));
// }
i=gpio_read(g, port);
printk("Read %d on gpio %d\n", i, port);
}
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]);
read_port(23, g);
}
static void __exit gpiotoggle_driver_exit(void)
{
}
module_init(gpiotoggle_driver_init);
module_exit(gpiotoggle_driver_exit);