/* IO interface mux allocator for ETRAX100LX.
* Copyright 2004-2007, Axis Communications AB
*/
/* C.f. ETRAX100LX Designer's Reference chapter 19.9 */
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/init.h>
#include <arch/svinto.h>
#include <asm/io.h>
#include <arch/io_interface_mux.h>
#define DBG(s)
/* Macro to access ETRAX 100 registers */
#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
IO_STATE_(reg##_, field##_, _##val)
enum io_if_group {
group_a = (1<<0),
group_b = (1<<1),
group_c = (1<<2),
group_d = (1<<3),
group_e = (1<<4),
group_f = (1<<5)
};
struct watcher
{
void (*notify)(const unsigned int gpio_in_available,
const unsigned int gpio_out_available,
const unsigned char pa_available,
const unsigned char pb_available);
struct watcher *next;
};
struct if_group
{
enum io_if_group group;
/* name - the name of the group 'A' to 'F' */
char *name;
/* used - a bit mask of all pins in the group in the order listed
* in the tables in 19.9.1 to 19.9.6. Note that no
* distinction is made between in, out and in/out pins. */
unsigned int used;
};
struct interface
{
enum cris_io_interface ioif;
/* name - the name of the interface */
char *name;
/* groups - OR'ed together io_if_group flags describing what pin groups
* the interface uses pins in. */
unsigned char groups;
/* used - set when the interface is allocated. */
unsigned char used;
char *owner;
/* group_a through group_f - bit masks describing what pins in the
* pin groups the interface uses. */
unsigned int group_a;
unsigned int group_b;
unsigned int group_c;
unsigned int group_d;
unsigned int group_e;
unsigned int group_f;
/* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
* GPIO ports the interface uses. This could be reconstucted using
* the group_X masks and a table of what pins the GPIO ports use,
* but that would be messy. */
unsigned int gpio_g_in;
unsigned int gpio_g_out;
unsigned char gpio_b;
};
static struct if_group if_groups[6] = {
{
.group = group_a,
.name = "A",
.used = 0,
},
{
.group = group_b,
.name = "B",
.used = 0,
},
{
.group = group_c,
.name = "C",
.used = 0,
},
{
.group = group_d,
.name = "D",
.used = 0,
},
{
.group = group_e,
.name = "E",
.used = 0,
},
{
.group = group_f,
.name = "F",
.used = 0,
}
};
/* The order in the array must match the order of enum
* cris_io_interface in io_interface_mux.h */
static struct interface interfaces[] = {
/* Begin Non-multiplexed interfaces */
{
.ioif = if_eth,
.name = "ethernet",
.groups = 0,
.group_a = 0,
.group_b = 0,
.group_c = 0,
.group_d = 0,