i.MX31: Make some style changes to some driver code so that hardware vs. variable access is more obvious to the eye. Change a few data types and qualifiers. No functional differences.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25865 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
13b8e3d66d
commit
affea5fe9e
6 changed files with 130 additions and 287 deletions
|
@ -25,7 +25,23 @@
|
|||
#include "panic.h"
|
||||
#include "debug.h"
|
||||
|
||||
static const char * avic_int_names[64] =
|
||||
#define avic ((unsigned long * const)AVIC_BASE_ADDR)
|
||||
#define INTCNTL (0x000 / sizeof (unsigned long)) /* 000h */
|
||||
#define NIMASK (0x004 / sizeof (unsigned long)) /* 004h */
|
||||
#define INTENNUM (0x008 / sizeof (unsigned long)) /* 008h */
|
||||
#define INTDISNUM (0x00c / sizeof (unsigned long)) /* 00Ch */
|
||||
#define INTENABLE (0x010 / sizeof (unsigned long)) /* 010h H,L */
|
||||
#define INTTYPE (0x018 / sizeof (unsigned long)) /* 018h H,L */
|
||||
#define NIPRIORITY (0x020 / sizeof (unsigned long)) /* 020h 7-0 */
|
||||
#define NIVECSR (0x040 / sizeof (unsigned long)) /* 040h */
|
||||
#define FIVECSR (0x044 / sizeof (unsigned long)) /* 044h */
|
||||
#define INTSRC (0x048 / sizeof (unsigned long)) /* 048h H,L */
|
||||
#define INTFRC (0x050 / sizeof (unsigned long)) /* 050h H,L */
|
||||
#define NIPND (0x058 / sizeof (unsigned long)) /* 058h H,L */
|
||||
#define FIPND (0x060 / sizeof (unsigned long)) /* 060h H,L */
|
||||
#define VECTOR (0x100 / sizeof (unsigned long)) /* 100h */
|
||||
|
||||
static const char * const avic_int_names[64] =
|
||||
{
|
||||
"RESERVED0", "RESERVED1", "RESERVED2", "I2C3",
|
||||
"I2C2", "MPEG4_ENCODER", "RTIC", "FIR",
|
||||
|
@ -47,7 +63,7 @@ static const char * avic_int_names[64] =
|
|||
|
||||
void UIE_VECTOR(void)
|
||||
{
|
||||
int mode;
|
||||
unsigned long mode;
|
||||
int offset;
|
||||
|
||||
asm volatile (
|
||||
|
@ -58,8 +74,7 @@ void UIE_VECTOR(void)
|
|||
: "=&r"(mode)
|
||||
);
|
||||
|
||||
offset = mode == 0x11 ?
|
||||
(int32_t)AVIC_FIVECSR : ((int32_t)AVIC_NIVECSR >> 16);
|
||||
offset = mode == 0x11 ? (long)avic[FIVECSR] : ((long)avic[NIVECSR] >> 16);
|
||||
|
||||
panicf("Unhandled %s %d: %s",
|
||||
mode == 0x11 ? "FIQ" : "IRQ", offset,
|
||||
|
@ -70,7 +85,7 @@ void UIE_VECTOR(void)
|
|||
/* We use the AVIC */
|
||||
void __attribute__((interrupt("IRQ"))) irq_handler(void)
|
||||
{
|
||||
const int offset = (int32_t)AVIC_NIVECSR >> 16;
|
||||
int offset = (long)avic[NIVECSR] >> 16;
|
||||
|
||||
if (offset == -1)
|
||||
{
|
||||
|
@ -103,25 +118,24 @@ void __attribute__((naked)) fiq_handler(void)
|
|||
|
||||
void avic_init(void)
|
||||
{
|
||||
struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
|
||||
int i;
|
||||
|
||||
/* Disable all interrupts and set to unhandled */
|
||||
avic_disable_int(INT_ALL);
|
||||
|
||||
/* Reset AVIC control */
|
||||
avic->intcntl = 0;
|
||||
avic[INTCNTL] = 0;
|
||||
|
||||
/* Init all interrupts to type IRQ */
|
||||
avic_set_int_type(INT_ALL, INT_TYPE_IRQ);
|
||||
|
||||
/* Set all normal to lowest priority */
|
||||
for (i = 0; i < 8; i++)
|
||||
avic->nipriority[i] = 0;
|
||||
avic[NIPRIORITY + i] = 0;
|
||||
|
||||
/* Set NM bit to enable VIC. Mask fast interrupts. Core arbiter rise
|
||||
* for normal interrupts (for lowest latency). */
|
||||
avic->intcntl |= AVIC_INTCNTL_NM | AVIC_INTCNTL_FIDIS |
|
||||
avic[INTCNTL] |= AVIC_INTCNTL_NM | AVIC_INTCNTL_FIDIS |
|
||||
AVIC_INTCNTL_NIAD;
|
||||
|
||||
/* Enable VE bit in CP15 Control reg to enable VIC */
|
||||
|
@ -132,30 +146,28 @@ void avic_init(void)
|
|||
: : : "r0");
|
||||
|
||||
/* Enable normal interrupts at all priorities */
|
||||
avic->nimask = AVIC_NIL_ENABLE;
|
||||
avic[NIMASK] = AVIC_NIL_ENABLE;
|
||||
}
|
||||
|
||||
void avic_set_int_priority(enum IMX31_INT_LIST ints,
|
||||
unsigned long ni_priority)
|
||||
{
|
||||
struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
|
||||
volatile uint32_t *reg = &avic->nipriority[7 - (ints >> 3)];
|
||||
volatile unsigned long * const reg = &avic[NIPRIORITY + 7 - (ints >> 3)];
|
||||
unsigned int shift = (ints & 0x7) << 2;
|
||||
uint32_t mask = 0xful << shift;
|
||||
unsigned long mask = 0xful << shift;
|
||||
*reg = (*reg & ~mask) | ((ni_priority << shift) & mask);
|
||||
}
|
||||
|
||||
void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
|
||||
unsigned long ni_priority, void (*handler)(void))
|
||||
{
|
||||
struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
|
||||
int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS);
|
||||
|
||||
if (ints != INT_ALL) /* No mass-enable allowed */
|
||||
{
|
||||
avic_set_int_type(ints, intstype);
|
||||
avic->vector[ints] = (long)handler;
|
||||
avic->intennum = ints;
|
||||
avic[VECTOR + ints] = (unsigned long)handler;
|
||||
avic[INTENNUM] = ints;
|
||||
avic_set_int_priority(ints, ni_priority);
|
||||
}
|
||||
|
||||
|
@ -164,30 +176,27 @@ void avic_enable_int(enum IMX31_INT_LIST ints, enum INT_TYPE intstype,
|
|||
|
||||
void avic_disable_int(enum IMX31_INT_LIST ints)
|
||||
{
|
||||
struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
|
||||
uint32_t i;
|
||||
|
||||
if (ints == INT_ALL)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
avic->intdisnum = i;
|
||||
avic->vector[i] = (long)UIE_VECTOR;
|
||||
avic[INTDISNUM] = i;
|
||||
avic[VECTOR + i] = (unsigned long)UIE_VECTOR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
avic->intdisnum = ints;
|
||||
avic->vector[ints] = (long)UIE_VECTOR;
|
||||
avic[INTDISNUM] = ints;
|
||||
avic[VECTOR + ints] = (unsigned long)UIE_VECTOR;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_int_type(int i, enum INT_TYPE intstype)
|
||||
{
|
||||
/* INTTYPEH: vectors 63-32, INTTYPEL: vectors 31-0 */
|
||||
struct avic_map * const avic = (struct avic_map *)AVIC_BASE_ADDR;
|
||||
volatile uint32_t *reg = &avic->inttype[1 - (i >> 5)];
|
||||
uint32_t val = 1L << (i & 0x1f);
|
||||
volatile unsigned long * const reg = &avic[INTTYPE + 1 - (i >> 5)];
|
||||
unsigned long val = 1L << (i & 0x1f);
|
||||
|
||||
if (intstype == INT_TYPE_IRQ)
|
||||
val = *reg & ~val;
|
||||
|
@ -222,5 +231,5 @@ void avic_set_ni_level(int level)
|
|||
else if (level > 15)
|
||||
level = 15;
|
||||
|
||||
AVIC_NIMASK = level;
|
||||
avic[NIMASK] = level;
|
||||
}
|
||||
|
|
|
@ -21,157 +21,6 @@
|
|||
#ifndef AVIC_IMX31_H
|
||||
#define AVIC_IMX31_H
|
||||
|
||||
struct avic_map
|
||||
{
|
||||
volatile uint32_t intcntl; /* 00h */
|
||||
volatile uint32_t nimask; /* 04h */
|
||||
volatile uint32_t intennum; /* 08h */
|
||||
volatile uint32_t intdisnum; /* 0Ch */
|
||||
union /* 10h */
|
||||
{
|
||||
struct
|
||||
{
|
||||
volatile uint32_t intenableh; /* 10h */
|
||||
volatile uint32_t intenablel; /* 14h */
|
||||
};
|
||||
volatile uint32_t intenable[2]; /* H,L */
|
||||
};
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
volatile uint32_t inttypeh; /* 18h */
|
||||
volatile uint32_t inttypel; /* 1Ch */
|
||||
};
|
||||
volatile uint32_t inttype[2]; /* H,L */
|
||||
};
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
volatile uint32_t nipriority7; /* 20h */
|
||||
volatile uint32_t nipriority6; /* 24h */
|
||||
volatile uint32_t nipriority5; /* 28h */
|
||||
volatile uint32_t nipriority4; /* 2Ch */
|
||||
volatile uint32_t nipriority3; /* 30h */
|
||||
volatile uint32_t nipriority2; /* 34h */
|
||||
volatile uint32_t nipriority1; /* 38h */
|
||||
volatile uint32_t nipriority0; /* 3Ch */
|
||||
};
|
||||
volatile uint32_t nipriority[8]; /* 7-0 */
|
||||
};
|
||||
volatile uint32_t nivecsr; /* 40h */
|
||||
volatile uint32_t fivecsr; /* 44h */
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
volatile uint32_t intsrch; /* 48h */
|
||||
volatile uint32_t intsrcl; /* 4Ch */
|
||||
};
|
||||
volatile uint32_t intsrc[2]; /* H,L */
|
||||
};
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
volatile uint32_t intfrch; /* 50h */
|
||||
volatile uint32_t intfrcl; /* 54h */
|
||||
};
|
||||
volatile uint32_t intfrc[2]; /* H,L */
|
||||
};
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
volatile uint32_t nipndh; /* 58h */
|
||||
volatile uint32_t nipndl; /* 5Ch */
|
||||
};
|
||||
volatile uint32_t nipnd[2]; /* H,L */
|
||||
};
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
volatile uint32_t fipndh; /* 60h */
|
||||
volatile uint32_t fipndl; /* 64h */
|
||||
};
|
||||
volatile uint32_t fipnd[2]; /* H,L */
|
||||
};
|
||||
volatile uint32_t skip1[0x26]; /* 68h */
|
||||
union /* 100h */
|
||||
{
|
||||
struct
|
||||
{
|
||||
volatile uint32_t reserved0;
|
||||
volatile uint32_t reserved1;
|
||||
volatile uint32_t reserved2;
|
||||
volatile uint32_t i2c3;
|
||||
volatile uint32_t i2c2;
|
||||
volatile uint32_t mpeg4encoder;
|
||||
volatile uint32_t rtic;
|
||||
volatile uint32_t fir;
|
||||
volatile uint32_t mmc_sdhc2;
|
||||
volatile uint32_t mmc_sdhc1;
|
||||
volatile uint32_t i2c1;
|
||||
volatile uint32_t ssi2;
|
||||
volatile uint32_t ssi1;
|
||||
volatile uint32_t cspi2;
|
||||
volatile uint32_t cspi1;
|
||||
volatile uint32_t ata;
|
||||
volatile uint32_t mbx;
|
||||
volatile uint32_t cspi3;
|
||||
volatile uint32_t uart3;
|
||||
volatile uint32_t iim;
|
||||
volatile uint32_t sim1;
|
||||
volatile uint32_t sim2;
|
||||
volatile uint32_t rnga;
|
||||
volatile uint32_t evtmon;
|
||||
volatile uint32_t kpp;
|
||||
volatile uint32_t rtc;
|
||||
volatile uint32_t pwn;
|
||||
volatile uint32_t epit2;
|
||||
volatile uint32_t epit1;
|
||||
volatile uint32_t gpt;
|
||||
volatile uint32_t pwr_fail;
|
||||
volatile uint32_t ccm_dvfs;
|
||||
volatile uint32_t uart2;
|
||||
volatile uint32_t nandfc;
|
||||
volatile uint32_t sdma;
|
||||
volatile uint32_t usb_host1;
|
||||
volatile uint32_t usb_host2;
|
||||
volatile uint32_t usb_otg;
|
||||
volatile uint32_t reserved3;
|
||||
volatile uint32_t mshc1;
|
||||
volatile uint32_t mshc2;
|
||||
volatile uint32_t ipu_err;
|
||||
volatile uint32_t ipu;
|
||||
volatile uint32_t reserved4;
|
||||
volatile uint32_t reserved5;
|
||||
volatile uint32_t uart1;
|
||||
volatile uint32_t uart4;
|
||||
volatile uint32_t uart5;
|
||||
volatile uint32_t etc_irq;
|
||||
volatile uint32_t scc_scm;
|
||||
volatile uint32_t scc_smn;
|
||||
volatile uint32_t gpio2;
|
||||
volatile uint32_t gpio1;
|
||||
volatile uint32_t ccm_clk;
|
||||
volatile uint32_t pcmcia;
|
||||
volatile uint32_t wdog;
|
||||
volatile uint32_t gpio3;
|
||||
volatile uint32_t reserved6;
|
||||
volatile uint32_t ext_pwmg;
|
||||
volatile uint32_t ext_temp;
|
||||
volatile uint32_t ext_sense1;
|
||||
volatile uint32_t ext_sense2;
|
||||
volatile uint32_t ext_wdog;
|
||||
volatile uint32_t ext_tv;
|
||||
};
|
||||
volatile uint32_t vector[0x40]; /* 100h */
|
||||
};
|
||||
};
|
||||
|
||||
/* #define IRQ priorities for different modules (0-15) */
|
||||
#define INT_PRIO_DEFAULT 7
|
||||
#define INT_PRIO_DVFS (INT_PRIO_DEFAULT+1)
|
||||
|
|
|
@ -37,13 +37,16 @@ static __attribute__((interrupt("IRQ"))) void I2C2_HANDLER(void);
|
|||
static __attribute__((interrupt("IRQ"))) void I2C3_HANDLER(void);
|
||||
#endif
|
||||
|
||||
#define IADR (0x00 / sizeof (unsigned short)) /* 00h */
|
||||
#define IFDR (0x04 / sizeof (unsigned short)) /* 04h */
|
||||
#define I2CR (0x08 / sizeof (unsigned short)) /* 08h */
|
||||
#define I2SR (0x0c / sizeof (unsigned short)) /* 0ch */
|
||||
#define I2DR (0x10 / sizeof (unsigned short)) /* 10h */
|
||||
|
||||
static struct i2c_module_descriptor
|
||||
{
|
||||
struct i2c_map *base; /* Module base address */
|
||||
enum IMX31_CG_LIST cg; /* Clock gating index */
|
||||
enum IMX31_INT_LIST ints; /* Module interrupt number */
|
||||
int enable; /* Enable count */
|
||||
void (*handler)(void); /* Module interrupt handler */
|
||||
volatile unsigned short * const base; /* Module base address */
|
||||
void (* const handler)(void); /* Module interrupt handler */
|
||||
struct mutex m; /* Node mutual-exclusion */
|
||||
struct wakeup w; /* I2C done signal */
|
||||
unsigned char *addr_data; /* Additional addressing data */
|
||||
|
@ -51,11 +54,14 @@ static struct i2c_module_descriptor
|
|||
unsigned char *data; /* TX/RX buffer (actual data) */
|
||||
int data_count; /* TX/RX byte count */
|
||||
unsigned char addr; /* Address + r/w bit */
|
||||
uint8_t enable; /* Enable count */
|
||||
const uint8_t cg; /* Clock gating index */
|
||||
const uint8_t ints; /* Module interrupt number */
|
||||
} i2c_descs[I2C_NUM_I2C] =
|
||||
{
|
||||
#if (I2C_MODULE_MASK & USE_I2C1_MODULE)
|
||||
{
|
||||
.base = (struct i2c_map *)I2C1_BASE_ADDR,
|
||||
.base = (unsigned short *)I2C1_BASE_ADDR,
|
||||
.cg = CG_I2C1,
|
||||
.ints = INT_I2C1,
|
||||
.handler = I2C1_HANDLER,
|
||||
|
@ -63,7 +69,7 @@ static struct i2c_module_descriptor
|
|||
#endif
|
||||
#if (I2C_MODULE_MASK & USE_I2C2_MODULE)
|
||||
{
|
||||
.base = (struct i2c_map *)I2C2_BASE_ADDR,
|
||||
.base = (unsigned short *)I2C2_BASE_ADDR,
|
||||
.cg = CG_I2C2,
|
||||
.ints = INT_I2C2,
|
||||
.handler = I2C2_HANDLER,
|
||||
|
@ -71,7 +77,7 @@ static struct i2c_module_descriptor
|
|||
#endif
|
||||
#if (I2C_MODULE_MASK & USE_I2C3_MODULE)
|
||||
{
|
||||
.base = (struct i2c_map *)I2C3_BASE_ADDR,
|
||||
.base = (unsigned short *)I2C3_BASE_ADDR,
|
||||
.cg = CG_I2C3,
|
||||
.ints = INT_I2C3,
|
||||
.handler = I2C3_HANDLER,
|
||||
|
@ -82,10 +88,10 @@ static struct i2c_module_descriptor
|
|||
static void i2c_interrupt(enum i2c_module_number i2c)
|
||||
{
|
||||
struct i2c_module_descriptor * const desc = &i2c_descs[i2c];
|
||||
struct i2c_map * const base = desc->base;
|
||||
uint16_t i2sr = base->i2sr;
|
||||
volatile unsigned short * const base = desc->base;
|
||||
unsigned short i2sr = base[I2SR];
|
||||
|
||||
base->i2sr = 0; /* Clear IIF */
|
||||
base[I2SR] = 0; /* Clear IIF */
|
||||
|
||||
if (desc->addr_count >= 0)
|
||||
{
|
||||
|
@ -100,8 +106,8 @@ static void i2c_interrupt(enum i2c_module_number i2c)
|
|||
/* Switching to data cycle */
|
||||
if (desc->addr & 0x1)
|
||||
{
|
||||
base->i2cr &= ~I2C_I2CR_MTX; /* Switch to RX mode */
|
||||
base->i2dr; /* Dummy read */
|
||||
base[I2CR] &= ~I2C_I2CR_MTX; /* Switch to RX mode */
|
||||
base[I2DR]; /* Dummy read */
|
||||
return;
|
||||
}
|
||||
/* else remaining data is TX - handle below */
|
||||
|
@ -109,12 +115,12 @@ static void i2c_interrupt(enum i2c_module_number i2c)
|
|||
}
|
||||
else
|
||||
{
|
||||
base->i2dr = *desc->addr_data++; /* Send next addressing byte */
|
||||
base[I2DR] = *desc->addr_data++; /* Send next addressing byte */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (base->i2cr & I2C_I2CR_MTX)
|
||||
if (base[I2CR] & I2C_I2CR_MTX)
|
||||
{
|
||||
/* Transmitting data */
|
||||
if ((i2sr & I2C_I2SR_RXAK) == 0)
|
||||
|
@ -123,7 +129,7 @@ i2c_transmit:
|
|||
if (desc->data_count > 0)
|
||||
{
|
||||
/* More bytes to send, got ACK from previous byte */
|
||||
base->i2dr = *desc->data++;
|
||||
base[I2DR] = *desc->data++;
|
||||
desc->data_count--;
|
||||
return;
|
||||
}
|
||||
|
@ -138,24 +144,24 @@ i2c_transmit:
|
|||
if (desc->data_count == 1)
|
||||
{
|
||||
/* 2nd to Last byte - NACK */
|
||||
base->i2cr |= I2C_I2CR_TXAK;
|
||||
base[I2CR] |= I2C_I2CR_TXAK;
|
||||
}
|
||||
|
||||
*desc->data++ = base->i2dr; /* Read data from I2DR and store */
|
||||
*desc->data++ = base[I2DR]; /* Read data from I2DR and store */
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Generate STOP signal before reading data */
|
||||
base->i2cr &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
|
||||
*desc->data++ = base->i2dr; /* Read data from I2DR and store */
|
||||
base[I2CR] &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
|
||||
*desc->data++ = base[I2DR]; /* Read data from I2DR and store */
|
||||
goto i2c_done;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_stop:
|
||||
/* Generate STOP signal */
|
||||
base->i2cr &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
|
||||
base[I2CR] &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
|
||||
i2c_done:
|
||||
/* Signal thread we're done */
|
||||
wakeup_signal(&desc->w);
|
||||
|
@ -183,18 +189,18 @@ static __attribute__((interrupt("IRQ"))) void I2C3_HANDLER(void)
|
|||
static int i2c_transfer(struct i2c_node * const node,
|
||||
struct i2c_module_descriptor *const desc)
|
||||
{
|
||||
struct i2c_map * const base = desc->base;
|
||||
volatile unsigned short * const base = desc->base;
|
||||
int count = desc->data_count;
|
||||
uint16_t i2cr;
|
||||
|
||||
/* Make sure bus is idle. */
|
||||
while (base->i2sr & I2C_I2SR_IBB);
|
||||
while (base[I2SR] & I2C_I2SR_IBB);
|
||||
|
||||
/* Set speed */
|
||||
base->ifdr = node->ifdr;
|
||||
base[IFDR] = node->ifdr;
|
||||
|
||||
/* Enable module */
|
||||
base->i2cr = I2C_I2CR_IEN;
|
||||
base[I2CR] = I2C_I2CR_IEN;
|
||||
|
||||
/* Enable Interrupt, Master */
|
||||
i2cr = I2C_I2CR_IEN | I2C_I2CR_IIEN | I2C_I2CR_MTX;
|
||||
|
@ -206,13 +212,13 @@ static int i2c_transfer(struct i2c_node * const node,
|
|||
}
|
||||
|
||||
/* Set config */
|
||||
base->i2cr = i2cr;
|
||||
base[I2CR] = i2cr;
|
||||
|
||||
/* Generate START */
|
||||
base->i2cr = i2cr | I2C_I2CR_MSTA;
|
||||
base[I2CR] = i2cr | I2C_I2CR_MSTA;
|
||||
|
||||
/* Address slave (first byte sent) and begin session. */
|
||||
base->i2dr = desc->addr;
|
||||
base[I2DR] = desc->addr;
|
||||
|
||||
/* Wait for transfer to complete */
|
||||
if (wakeup_wait(&desc->w, HZ) == OBJ_WAIT_SUCCEEDED)
|
||||
|
@ -222,7 +228,7 @@ static int i2c_transfer(struct i2c_node * const node,
|
|||
else
|
||||
{
|
||||
/* Generate STOP if timeout */
|
||||
base->i2cr &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
|
||||
base[I2CR] &= ~(I2C_I2CR_MSTA | I2C_I2CR_IIEN);
|
||||
count = -1;
|
||||
}
|
||||
|
||||
|
@ -289,7 +295,7 @@ void i2c_init(void)
|
|||
ccm_module_clock_gating(desc->cg, CGM_ON_RUN_WAIT);
|
||||
mutex_init(&desc->m);
|
||||
wakeup_init(&desc->w);
|
||||
desc->base->i2cr = 0;
|
||||
desc->base[I2CR] = 0;
|
||||
ccm_module_clock_gating(desc->cg, CGM_OFF);
|
||||
}
|
||||
}
|
||||
|
@ -315,8 +321,8 @@ void i2c_enable_node(struct i2c_node *node, bool enable)
|
|||
if (desc->enable > 0 && --desc->enable == 0)
|
||||
{
|
||||
/* Last enable */
|
||||
while (desc->base->i2sr & I2C_I2SR_IBB); /* Wait for STOP */
|
||||
desc->base->i2cr &= ~I2C_I2CR_IEN;
|
||||
while (desc->base[I2SR] & I2C_I2SR_IBB); /* Wait for STOP */
|
||||
desc->base[I2CR] &= ~I2C_I2CR_IEN;
|
||||
avic_disable_int(desc->ints);
|
||||
ccm_module_clock_gating(desc->cg, CGM_OFF);
|
||||
}
|
||||
|
|
|
@ -43,20 +43,6 @@ enum i2c_module_number
|
|||
I2C_NUM_I2C,
|
||||
};
|
||||
|
||||
/* Module interface map structure */
|
||||
struct i2c_map
|
||||
{
|
||||
volatile uint16_t iadr; /* 0x00 */
|
||||
volatile uint16_t unused1;
|
||||
volatile uint16_t ifdr; /* 0x04 */
|
||||
volatile uint16_t unused2;
|
||||
volatile uint16_t i2cr; /* 0x08 */
|
||||
volatile uint16_t unused3;
|
||||
volatile uint16_t i2sr; /* 0x0C */
|
||||
volatile uint16_t unused4;
|
||||
volatile uint16_t i2dr; /* 0x10 */
|
||||
};
|
||||
|
||||
struct i2c_node
|
||||
{
|
||||
enum i2c_module_number num; /* Module that this node uses */
|
||||
|
|
|
@ -37,25 +37,34 @@ static __attribute__((interrupt("IRQ"))) void CSPI2_HANDLER(void);
|
|||
static __attribute__((interrupt("IRQ"))) void CSPI3_HANDLER(void);
|
||||
#endif
|
||||
|
||||
#define RXDATA (0x000 / sizeof (unsigned long)) /* 000h */
|
||||
#define TXDATA (0x004 / sizeof (unsigned long)) /* 004h */
|
||||
#define CONREG (0x008 / sizeof (unsigned long)) /* 008h */
|
||||
#define INTREG (0x00c / sizeof (unsigned long)) /* 00Ch */
|
||||
#define DMAREG (0x010 / sizeof (unsigned long)) /* 010h */
|
||||
#define STATREG (0x014 / sizeof (unsigned long)) /* 014h */
|
||||
#define PERIODREG (0x01c / sizeof (unsigned long)) /* 018h */
|
||||
#define TESTREG (0x1c0 / sizeof (unsigned long)) /* 1C0h */
|
||||
|
||||
/* State data associatated with each CSPI module */
|
||||
static struct spi_module_desc
|
||||
{
|
||||
struct cspi_map * const base; /* CSPI module address */
|
||||
volatile unsigned long * const base; /* CSPI module address */
|
||||
struct spi_transfer_desc *head; /* Running job */
|
||||
struct spi_transfer_desc *tail; /* Most recent job added */
|
||||
const struct spi_node *last_node; /* Last node used for module */
|
||||
void (*handler)(void); /* Interrupt handler */
|
||||
void (* const handler)(void); /* Interrupt handler */
|
||||
int rxcount; /* Independent copy of txcount */
|
||||
int8_t enab; /* Enable count */
|
||||
int8_t byte_size; /* Size of transfers in bytes */
|
||||
int8_t cg; /* Clock-gating value */
|
||||
int8_t ints; /* AVIC vector number */
|
||||
const int8_t cg; /* Clock-gating value */
|
||||
const int8_t ints; /* AVIC vector number */
|
||||
} spi_descs[SPI_NUM_CSPI] =
|
||||
/* Init non-zero members */
|
||||
{
|
||||
#if (SPI_MODULE_MASK & USE_CSPI1_MODULE)
|
||||
{
|
||||
.base = (struct cspi_map *)CSPI1_BASE_ADDR,
|
||||
.base = (unsigned long *)CSPI1_BASE_ADDR,
|
||||
.cg = CG_CSPI1,
|
||||
.ints = INT_CSPI1,
|
||||
.handler = CSPI1_HANDLER,
|
||||
|
@ -63,7 +72,7 @@ static struct spi_module_desc
|
|||
#endif
|
||||
#if (SPI_MODULE_MASK & USE_CSPI2_MODULE)
|
||||
{
|
||||
.base = (struct cspi_map *)CSPI2_BASE_ADDR,
|
||||
.base = (unsigned long *)CSPI2_BASE_ADDR,
|
||||
.cg = CG_CSPI2,
|
||||
.ints = INT_CSPI2,
|
||||
.handler = CSPI2_HANDLER,
|
||||
|
@ -71,7 +80,7 @@ static struct spi_module_desc
|
|||
#endif
|
||||
#if (SPI_MODULE_MASK & USE_CSPI3_MODULE)
|
||||
{
|
||||
.base = (struct cspi_map *)CSPI3_BASE_ADDR,
|
||||
.base = (unsigned long *)CSPI3_BASE_ADDR,
|
||||
.cg = CG_CSPI3,
|
||||
.ints = INT_CSPI3,
|
||||
.handler = CSPI3_HANDLER,
|
||||
|
@ -83,8 +92,7 @@ static struct spi_module_desc
|
|||
static void spi_reset(struct spi_module_desc * const desc)
|
||||
{
|
||||
/* Reset by leaving it disabled */
|
||||
struct cspi_map * const base = desc->base;
|
||||
base->conreg &= ~CSPI_CONREG_EN;
|
||||
desc->base[CONREG] &= ~CSPI_CONREG_EN;
|
||||
}
|
||||
|
||||
/* Write the context for the node and remember it to avoid unneeded reconfigure */
|
||||
|
@ -92,7 +100,7 @@ static bool spi_set_context(struct spi_module_desc *desc,
|
|||
struct spi_transfer_desc *xfer)
|
||||
{
|
||||
const struct spi_node * const node = xfer->node;
|
||||
struct cspi_map * const base = desc->base;
|
||||
volatile unsigned long * const base = desc->base;
|
||||
|
||||
if (desc->enab == 0)
|
||||
return false;
|
||||
|
@ -101,17 +109,17 @@ static bool spi_set_context(struct spi_module_desc *desc,
|
|||
return true;
|
||||
|
||||
/* Errata says CSPI should be disabled when writing PERIODREG. */
|
||||
base->conreg &= ~CSPI_CONREG_EN;
|
||||
base[CONREG] &= ~CSPI_CONREG_EN;
|
||||
|
||||
/* Switch the module's node */
|
||||
desc->last_node = node;
|
||||
desc->byte_size = (((node->conreg >> 8) & 0x1f) + 1 + 7) / 8 - 1;
|
||||
|
||||
/* Set the wait-states */
|
||||
base->periodreg = node->periodreg & 0xffff;
|
||||
base[PERIODREG] = node->periodreg & 0xffff;
|
||||
|
||||
/* Keep reserved and start bits cleared. Keep enabled bit. */
|
||||
base->conreg =
|
||||
base[CONREG] =
|
||||
(node->conreg & ~(0xfcc8e000 | CSPI_CONREG_XCH | CSPI_CONREG_SMC));
|
||||
return true;
|
||||
}
|
||||
|
@ -119,13 +127,13 @@ static bool spi_set_context(struct spi_module_desc *desc,
|
|||
|
||||
/* Fill the TX fifo. Returns the number of remaining words. */
|
||||
static int tx_fill_fifo(struct spi_module_desc * const desc,
|
||||
struct cspi_map * const base,
|
||||
volatile unsigned long * const base,
|
||||
struct spi_transfer_desc * const xfer)
|
||||
{
|
||||
int count = xfer->count;
|
||||
int size = desc->byte_size;
|
||||
|
||||
while ((base->statreg & CSPI_STATREG_TF) == 0)
|
||||
while ((base[STATREG] & CSPI_STATREG_TF) == 0)
|
||||
{
|
||||
uint32_t word = 0;
|
||||
|
||||
|
@ -143,7 +151,7 @@ static int tx_fill_fifo(struct spi_module_desc * const desc,
|
|||
|
||||
xfer->txbuf += size + 1; /* Increment buffer */
|
||||
|
||||
base->txdata = word; /* Write to FIFO */
|
||||
base[TXDATA] = word; /* Write to FIFO */
|
||||
|
||||
if (--count == 0)
|
||||
break;
|
||||
|
@ -158,13 +166,13 @@ static int tx_fill_fifo(struct spi_module_desc * const desc,
|
|||
static bool start_transfer(struct spi_module_desc * const desc,
|
||||
struct spi_transfer_desc * const xfer)
|
||||
{
|
||||
struct cspi_map * const base = desc->base;
|
||||
volatile unsigned long * const base = desc->base;
|
||||
unsigned long intreg;
|
||||
|
||||
if (!spi_set_context(desc, xfer))
|
||||
return false;
|
||||
|
||||
base->conreg |= CSPI_CONREG_EN; /* Enable module */
|
||||
base[CONREG] |= CSPI_CONREG_EN; /* Enable module */
|
||||
|
||||
desc->rxcount = xfer->count;
|
||||
|
||||
|
@ -178,9 +186,9 @@ static bool start_transfer(struct spi_module_desc * const desc,
|
|||
|
||||
tx_fill_fifo(desc, base, xfer);
|
||||
|
||||
base->statreg = CSPI_STATREG_TC; /* Ack 'complete' */
|
||||
base->intreg = intreg; /* Enable interrupts */
|
||||
base->conreg |= CSPI_CONREG_XCH; /* Begin transfer */
|
||||
base[STATREG] = CSPI_STATREG_TC; /* Ack 'complete' */
|
||||
base[INTREG] = intreg; /* Enable interrupts */
|
||||
base[CONREG] |= CSPI_CONREG_XCH; /* Begin transfer */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -189,15 +197,15 @@ static bool start_transfer(struct spi_module_desc * const desc,
|
|||
static void spi_interrupt(enum spi_module_number spi)
|
||||
{
|
||||
struct spi_module_desc *desc = &spi_descs[spi];
|
||||
struct cspi_map * const base = desc->base;
|
||||
unsigned long intreg = base->intreg;
|
||||
volatile unsigned long * const base = desc->base;
|
||||
unsigned long intreg = base[INTREG];
|
||||
struct spi_transfer_desc *xfer = desc->head;
|
||||
int inc = desc->byte_size + 1;
|
||||
|
||||
/* Data received - empty out RXFIFO */
|
||||
while ((base->statreg & CSPI_STATREG_RR) != 0)
|
||||
while ((base[STATREG] & CSPI_STATREG_RR) != 0)
|
||||
{
|
||||
uint32_t word = base->rxdata;
|
||||
uint32_t word = base[RXDATA];
|
||||
|
||||
if (desc->rxcount <= 0)
|
||||
continue;
|
||||
|
@ -226,14 +234,14 @@ static void spi_interrupt(enum spi_module_number spi)
|
|||
{
|
||||
/* No more to receive - stop RX interrupts */
|
||||
intreg &= ~(CSPI_INTREG_RHEN | CSPI_INTREG_RREN);
|
||||
base->intreg = intreg;
|
||||
base[INTREG] = intreg;
|
||||
}
|
||||
else if (intreg & CSPI_INTREG_RHEN)
|
||||
{
|
||||
/* < 4 words expected - switch to RX ready */
|
||||
intreg &= ~CSPI_INTREG_RHEN;
|
||||
intreg |= CSPI_INTREG_RREN;
|
||||
base->intreg = intreg;
|
||||
base[INTREG] = intreg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -247,15 +255,15 @@ static void spi_interrupt(enum spi_module_number spi)
|
|||
/* Out of data - stop TX interrupts, enable TC interrupt. */
|
||||
intreg &= ~CSPI_INTREG_THEN;
|
||||
intreg |= CSPI_INTREG_TCEN;
|
||||
base->intreg = intreg;
|
||||
base[INTREG] = intreg;
|
||||
}
|
||||
|
||||
if ((intreg & CSPI_INTREG_TCEN) && (base->statreg & CSPI_STATREG_TC))
|
||||
if ((intreg & CSPI_INTREG_TCEN) && (base[STATREG] & CSPI_STATREG_TC))
|
||||
{
|
||||
/* Outbound transfer is complete. */
|
||||
intreg &= ~CSPI_INTREG_TCEN;
|
||||
base->intreg = intreg;
|
||||
base->statreg = CSPI_STATREG_TC; /* Ack 'complete' */
|
||||
base[INTREG] = intreg;
|
||||
base[STATREG] = CSPI_STATREG_TC; /* Ack 'complete' */
|
||||
}
|
||||
|
||||
if (intreg != 0)
|
||||
|
@ -268,7 +276,7 @@ static void spi_interrupt(enum spi_module_number spi)
|
|||
spi_transfer_cb_fn_type callback = xfer->callback;
|
||||
xfer->next = NULL;
|
||||
|
||||
base->conreg &= ~CSPI_CONREG_EN; /* Disable module */
|
||||
base[CONREG] &= ~CSPI_CONREG_EN; /* Disable module */
|
||||
|
||||
if (next == xfer)
|
||||
{
|
||||
|
@ -361,8 +369,6 @@ void spi_disable_module(const struct spi_node *node)
|
|||
if (desc->enab > 0 && --desc->enab == 0)
|
||||
{
|
||||
/* Last enable for this module */
|
||||
struct cspi_map * const base = desc->base;
|
||||
|
||||
/* Wait for outstanding transactions */
|
||||
while (*(void ** volatile)&desc->head != NULL);
|
||||
|
||||
|
@ -370,7 +376,7 @@ void spi_disable_module(const struct spi_node *node)
|
|||
avic_disable_int(desc->ints);
|
||||
|
||||
/* Disable interface */
|
||||
base->conreg &= ~CSPI_CONREG_EN;
|
||||
desc->base[CONREG] &= ~CSPI_CONREG_EN;
|
||||
|
||||
/* Disable interface clock */
|
||||
ccm_module_clock_gating(desc->cg, CGM_OFF);
|
||||
|
|
|
@ -41,19 +41,6 @@ enum spi_module_number
|
|||
SPI_NUM_CSPI,
|
||||
};
|
||||
|
||||
struct cspi_map
|
||||
{
|
||||
volatile uint32_t rxdata; /* 00h */
|
||||
volatile uint32_t txdata; /* 04h */
|
||||
volatile uint32_t conreg; /* 08h */
|
||||
volatile uint32_t intreg; /* 0Ch */
|
||||
volatile uint32_t dmareg; /* 10h */
|
||||
volatile uint32_t statreg; /* 14h */
|
||||
volatile uint32_t periodreg; /* 18h */
|
||||
volatile uint32_t skip1[0x69]; /* 1Ch */
|
||||
volatile uint32_t testreg; /* 1C0h */
|
||||
};
|
||||
|
||||
struct spi_node
|
||||
{
|
||||
enum spi_module_number num; /* Module number (CSPIx_NUM) */
|
||||
|
|
Loading…
Reference in a new issue