00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <arch/arm.h>
00045 #include <dev/irqreg.h>
00046
00047 #ifndef NUT_IRQPRI_SPI0
00048 #define NUT_IRQPRI_SPI0 4
00049 #endif
00050
00051 static int SerialPeripheral0IrqCtl(int cmd, void *param);
00052
00053 IRQ_HANDLER sig_SPI0 = {
00054 #ifdef NUT_PERFMON
00055 0,
00056 #endif
00057 NULL,
00058 NULL,
00059 SerialPeripheral0IrqCtl
00060 };
00061
00065 static void SerialPeripheral0IrqEntry(void) __attribute__ ((naked));
00066 void SerialPeripheral0IrqEntry(void)
00067 {
00068 IRQ_ENTRY();
00069 #ifdef NUT_PERFMON
00070 sig_SPI0.ir_count++;
00071 #endif
00072 if (sig_SPI0.ir_handler) {
00073 (sig_SPI0.ir_handler) (sig_SPI0.ir_arg);
00074 }
00075 IRQ_EXIT();
00076 }
00077
00095 static int SerialPeripheral0IrqCtl(int cmd, void *param)
00096 {
00097 int rc = 0;
00098 u_int *ival = (u_int *) param;
00099 int enabled = inr(AIC_IMR) & _BV(SPI0_ID);
00100
00101
00102 if (enabled) {
00103 outr(AIC_IDCR, _BV(SPI0_ID));
00104 }
00105
00106 switch (cmd) {
00107 case NUT_IRQCTL_INIT:
00108
00109 outr(AIC_SVR(SPI0_ID), (unsigned int) SerialPeripheral0IrqEntry);
00110
00111 outr(AIC_SMR(SPI0_ID), AIC_SRCTYPE_INT_EDGE_TRIGGERED | NUT_IRQPRI_SPI0);
00112
00113 outr(AIC_ICCR, _BV(SPI0_ID));
00114 break;
00115 case NUT_IRQCTL_STATUS:
00116 if (enabled) {
00117 *ival |= 1;
00118 } else {
00119 *ival &= ~1;
00120 }
00121 break;
00122 case NUT_IRQCTL_ENABLE:
00123 enabled = 1;
00124 break;
00125 case NUT_IRQCTL_DISABLE:
00126 enabled = 0;
00127 break;
00128 case NUT_IRQCTL_GETMODE:
00129 {
00130 u_int val = inr(AIC_SMR(SPI0_ID)) & AIC_SRCTYPE;
00131 if (val == AIC_SRCTYPE_INT_LEVEL_SENSITIVE || val == AIC_SRCTYPE_EXT_HIGH_LEVEL) {
00132 *ival = NUT_IRQMODE_LEVEL;
00133 } else {
00134 *ival = NUT_IRQMODE_EDGE;
00135 }
00136 }
00137 break;
00138 case NUT_IRQCTL_SETMODE:
00139 if (*ival == NUT_IRQMODE_LEVEL) {
00140 outr(AIC_SMR(SPI0_ID), (inr(AIC_SMR(SPI0_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_INT_LEVEL_SENSITIVE);
00141 } else if (*ival == NUT_IRQMODE_EDGE) {
00142 outr(AIC_SMR(SPI0_ID), (inr(AIC_SMR(SPI0_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_INT_EDGE_TRIGGERED);
00143 } else {
00144 rc = -1;
00145 }
00146 break;
00147 case NUT_IRQCTL_GETPRIO:
00148 *ival = inr(AIC_SMR(SPI0_ID)) & AIC_PRIOR;
00149 break;
00150 case NUT_IRQCTL_SETPRIO:
00151 outr(AIC_SMR(SPI0_ID), (inr(AIC_SMR(SPI0_ID)) & ~AIC_PRIOR) | *ival);
00152 break;
00153 #ifdef NUT_PERFMON
00154 case NUT_IRQCTL_GETCOUNT:
00155 *ival = (u_int) sig_SPI0.ir_count;
00156 sig_SPI0.ir_count = 0;
00157 break;
00158 #endif
00159 default:
00160 rc = -1;
00161 break;
00162 }
00163
00164
00165 if (enabled) {
00166 outr(AIC_IECR, _BV(SPI0_ID));
00167 }
00168 return rc;
00169 }