Blame |
Last modification |
View Log
| RSS feed
//SHARK version by Giacomo Guidi <giacomo@gandalf.sssup.it>
#define __NO_VERSION__ 1
#include <sys/types.h>
#include "drivers/compbttv.h"
#include <asm/bitops.h>
#include "drivers/bt848.h"
#include "drivers/gpio.h"
#define printk cprintf
/*********************/
/* gpio_adapter ctor */
void init_gpio_adapter ( struct gpio_adapter *gpio )
{
//ignore overlapped fields...they are configured elsewhere
gpio->state = 0;
gpio->sync_bits = 0;
gpio->async_mask = ~0; //assign everything to async control
gpio->async_bits = 0;
init_request_queue(&(gpio->request_queue));
init_request_queue(&(gpio->free_queue));
gpio->private_data = NULL;
}
/********************************************************************/
/* async bit methods...restricted to the bits allowed in async mode */
static void gpio_apply_bits ( struct gpio_adapter * );
void gpio_set ( struct gpio_adapter *gpio, __u32 data )
{
//printk("gpio: set called with %08lX\n",(unsigned long)data);
gpio->async_bits = data & gpio->async_mask;
//printk("gpio: set to: %06lX\n",(long)(gpio->async_bits|gpio->sync_bits));
gpio_apply_bits(gpio);
}
void gpio_and ( struct gpio_adapter *gpio, __u32 data )
{
//printk("gpio: and called with &=%08lX\n",(unsigned long)data);
gpio->async_bits &= data; // disallowed bits are already zero...
//printk("gpio: and to: %06lX\n",(long)(gpio->async_bits|gpio->sync_bits));
gpio_apply_bits(gpio);
}
void gpio_or ( struct gpio_adapter *gpio, __u32 data )
{
//printk("gpio: or called with |=%08lX\n",(unsigned long)data);
gpio->async_bits |= data & gpio->async_mask;
//printk("gpio: or to: %06lX\n",(long)(gpio->async_bits|gpio->sync_bits));
gpio_apply_bits(gpio);
}
/* placed here to (hopefully) allow near jumps (smaller/faster) */
static void gpio_apply_bits ( struct gpio_adapter *gpio )
{
if (!test_bit(GPIO_HW_LOCKED,&(gpio->state))) {
__u32 value = gpio->sync_bits|gpio->async_bits;
*(__u32 *)(gpio->bt848_mem+BT848_GPIO_DATA) = value;
//printk("gpio: %06lX\n",(long)value);
//printk("gpio: out_en = %06lX\n",(long)readl(gpio->bt848_mem+BT848_GPIO_OUT_EN));
} else {
// can't update...leave it for task holding hardware lock
set_bit(GPIO_ASYNC_MOD,&(gpio->state));
// yes, that's correct...the sync task must up our async_lock
// this prevents the next async write until this one hits the hardware
}
}
void gpio_andor ( struct gpio_adapter *gpio, __u32 and_data, __u32 or_data )
{
//printk("gpio: andor called with &=%08lX and |=%08lX\n",(unsigned long)and_data,(unsigned long)or_data);
gpio->async_bits &= and_data;
gpio->async_bits |= or_data & gpio->async_mask;
//printk("gpio: aor to: %06lX\n",(long)(gpio->async_bits|gpio->sync_bits));
gpio_apply_bits(gpio);
}
/***********************/
/* synchronous methods */
static inline void gpio_sync_write( struct gpio_adapter *gpio,
__u32 sync_bits,
__u32 *async_bits )
{
if (test_and_clear_bit(GPIO_ASYNC_MOD,&((gpio)->state))) {
*async_bits = (gpio)->async_bits;
}
*(__u32 *)(gpio->bt848_mem+BT848_GPIO_DATA) = (sync_bits)|(*async_bits);
}
static inline void gpio_sync_acquire_hardware( struct gpio_adapter *gpio )
{
if (test_and_set_bit(GPIO_HW_LOCKED,&(gpio->state)))
printk("gpio: acquire\n");;
}
static void gpio_sync_release_hardware ( struct gpio_adapter *gpio )
{
if (test_and_clear_bit(GPIO_ASYNC_MOD,&(gpio->state))) {
//we are responsible for a final update...do it here
*(__u32 *)(gpio->bt848_mem+BT848_GPIO_DATA) = gpio->sync_bits|gpio->async_bits;
}
/* must have the hardware to release it */
if (!test_and_clear_bit(GPIO_HW_LOCKED,&(gpio->state))) {
printk("gpio: release\n");;
}
}
/* request queue access */
void gpio_commit_request( struct gpio_adapter *gpio,
struct gpio_request *request )
{
list_add_tail(&(request->list),&(gpio->request_queue.list));
}
void gpio_commit_transaction( struct gpio_adapter *gpio,
struct list_head *list )
{
list_splice(list,gpio->request_queue.list.prev);
}