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
00049 #include <dev/npl.h>
00050
00051 #if 0
00052
00053 #define NUTDEBUG
00054 #include <stdio.h>
00055 #endif
00056
00061
00062 static int npl_registered;
00063
00064
00065
00066
00067 static void NplInterrupt(void *arg)
00068 {
00069 u_short slr;
00070
00071
00072 slr = inw(NPL_SLR) & inw(NPL_IMR);
00073
00074
00075 if (slr & NPL_RSCTS) {
00076 if (sig_RSCTS.ir_handler) {
00077 (sig_RSCTS.ir_handler) (sig_RSCTS.ir_arg);
00078 }
00079 }
00080
00081 if (slr & NPL_RSDSR) {
00082 if (sig_RSDSR.ir_handler) {
00083 (sig_RSDSR.ir_handler) (sig_RSDSR.ir_arg);
00084 }
00085 }
00086
00087 if (slr & NPL_RSDCD) {
00088 if (sig_RSDCD.ir_handler) {
00089 (sig_RSDCD.ir_handler) (sig_RSDCD.ir_arg);
00090 }
00091 }
00092
00093 if (slr & NPL_RSRI) {
00094 if (sig_RSRI.ir_handler) {
00095 (sig_RSRI.ir_handler) (sig_RSRI.ir_arg);
00096 }
00097 }
00098
00099 if (slr & NPL_RTCALARM) {
00100 if (sig_RTCALARM.ir_handler) {
00101 (sig_RTCALARM.ir_handler) (sig_RTCALARM.ir_arg);
00102 }
00103 }
00104
00105 if (slr & NPL_LANWAKEUP) {
00106 if (sig_LANWAKEUP.ir_handler) {
00107 (sig_LANWAKEUP.ir_handler) (sig_LANWAKEUP.ir_arg);
00108 }
00109 }
00110
00111 if (slr & NPL_FMBUSY) {
00112 if (sig_FMBUSY.ir_handler) {
00113 (sig_FMBUSY.ir_handler) (sig_FMBUSY.ir_arg);
00114 }
00115 }
00116
00117 if (slr & NPL_RSINVAL) {
00118 if (sig_RSINVAL.ir_handler) {
00119 (sig_RSINVAL.ir_handler) (sig_RSINVAL.ir_arg);
00120 }
00121 }
00122
00123 if (slr & NPL_NRSINVAL) {
00124 if (sig_NRSINVAL.ir_handler) {
00125 (sig_NRSINVAL.ir_handler) (sig_NRSINVAL.ir_arg);
00126 }
00127 }
00128
00129 if (slr & NPL_MMCD) {
00130 if (sig_MMCD.ir_handler) {
00131 (sig_MMCD.ir_handler) (sig_MMCD.ir_arg);
00132 }
00133 }
00134
00135 if (slr & NPL_NMMCD) {
00136 if (sig_NMMCD.ir_handler) {
00137 (sig_NMMCD.ir_handler) (sig_NMMCD.ir_arg);
00138 }
00139 }
00140 outw(NPL_SCR, slr);
00141 }
00142
00143 static int NplIrqCtl(int cmd, void *param, IRQ_HANDLER * irq, u_int mask)
00144 {
00145 int rc = 0;
00146 u_int *ival = (u_int *) param;
00147 u_short enabled = inw(NPL_IMR) & mask;
00148
00149
00150 if (enabled) {
00151 outw(NPL_IMR, enabled & ~mask);
00152 }
00153 switch (cmd) {
00154 case NUT_IRQCTL_INIT:
00155
00156 outw(NPL_SCR, mask);
00157 break;
00158 case NUT_IRQCTL_STATUS:
00159 if (enabled) {
00160 *ival |= 1;
00161 } else {
00162 *ival &= ~1;
00163 }
00164 break;
00165 case NUT_IRQCTL_ENABLE:
00166 enabled = 1;
00167 break;
00168 case NUT_IRQCTL_DISABLE:
00169 enabled = 0;
00170 break;
00171 #ifdef NUT_PERFMON
00172 case NUT_IRQCTL_GETCOUNT:
00173 *ival = (u_int) irq->ir_count;
00174 irq->ir_count = 0;
00175 break;
00176 #endif
00177 default:
00178 rc = -1;
00179 break;
00180 }
00181
00182
00183 if (enabled) {
00184 outw(NPL_IMR, inw(NPL_IMR) | mask);
00185 }
00186 return rc;
00187 }
00188
00189
00190 static int NplRsCtsCtl(int cmd, void *param)
00191 {
00192 return NplIrqCtl(cmd, param, &sig_RSCTS, NPL_RSCTS);
00193 }
00194
00195 static int NplRsDsrCtl(int cmd, void *param)
00196 {
00197 return NplIrqCtl(cmd, param, &sig_RSDSR, NPL_RSDSR);
00198 }
00199
00200 static int NplRsDcdCtl(int cmd, void *param)
00201 {
00202 return NplIrqCtl(cmd, param, &sig_RSDCD, NPL_RSDCD);
00203 }
00204
00205 static int NplRsRiCtl(int cmd, void *param)
00206 {
00207 return NplIrqCtl(cmd, param, &sig_RSRI, NPL_RSRI);
00208 }
00209
00210 static int NplRtcAlarmCtl(int cmd, void *param)
00211 {
00212 return NplIrqCtl(cmd, param, &sig_RTCALARM, NPL_RTCALARM);
00213 }
00214
00215 static int NplLanWakeupCtl(int cmd, void *param)
00216 {
00217 return NplIrqCtl(cmd, param, &sig_LANWAKEUP, NPL_LANWAKEUP);
00218 }
00219
00220 static int NplFmBusyCtl(int cmd, void *param)
00221 {
00222 return NplIrqCtl(cmd, param, &sig_FMBUSY, NPL_FMBUSY);
00223 }
00224
00225 static int NplRsInvalCtl(int cmd, void *param)
00226 {
00227 return NplIrqCtl(cmd, param, &sig_RSINVAL, NPL_RSINVAL);
00228 }
00229
00230 static int NplRsValidCtl(int cmd, void *param)
00231 {
00232 return NplIrqCtl(cmd, param, &sig_NRSINVAL, NPL_NRSINVAL);
00233 }
00234
00235 static int NplMmcInsertCtl(int cmd, void *param)
00236 {
00237 return NplIrqCtl(cmd, param, &sig_MMCD, NPL_MMCD);
00238 }
00239
00240 static int NplMmcRemoveCtl(int cmd, void *param)
00241 {
00242 return NplIrqCtl(cmd, param, &sig_NMMCD, NPL_NMMCD);
00243 }
00244
00245
00260 int NplRegisterIrqHandler(IRQ_HANDLER * irq, void (*handler) (void *), void *arg)
00261 {
00262 int rc;
00263
00264
00265 rc = (irq->ir_ctl) (NUT_IRQCTL_INIT, NULL);
00266
00267 if (rc == 0) {
00268
00269 irq->ir_arg = arg;
00270 irq->ir_handler = handler;
00271
00272 if (!npl_registered) {
00273 npl_registered = 1;
00274 #if defined(ETHERNUT3)
00275 outr(PIO_PDR, _BV(9));
00276 #endif
00277 if ((rc = NutRegisterIrqHandler(&sig_INTERRUPT0, NplInterrupt, NULL)) == 0) {
00278 NutIrqSetMode(&sig_INTERRUPT0, NUT_IRQMODE_LOWLEVEL);
00279 NutIrqEnable(&sig_INTERRUPT0);
00280 }
00281 }
00282 }
00283 return rc;
00284 }
00285
00293 int NplIrqEnable(IRQ_HANDLER * irq)
00294 {
00295 return (irq->ir_ctl) (NUT_IRQCTL_ENABLE, NULL);
00296 }
00297
00305 int NplIrqDisable(IRQ_HANDLER * irq)
00306 {
00307 return (irq->ir_ctl) (NUT_IRQCTL_DISABLE, NULL);
00308 }
00309
00313 IRQ_HANDLER sig_RSCTS = {
00314 #ifdef NUT_PERFMON
00315 0,
00316 #endif
00317 NULL,
00318 NULL,
00319 NplRsCtsCtl
00320 };
00321
00325 IRQ_HANDLER sig_RSDSR = {
00326 #ifdef NUT_PERFMON
00327 0,
00328 #endif
00329 NULL,
00330 NULL,
00331 NplRsDsrCtl
00332 };
00333
00337 IRQ_HANDLER sig_RSDCD = {
00338 #ifdef NUT_PERFMON
00339 0,
00340 #endif
00341 NULL,
00342 NULL,
00343 NplRsDcdCtl
00344 };
00345
00349 IRQ_HANDLER sig_RSRI = {
00350 #ifdef NUT_PERFMON
00351 0,
00352 #endif
00353 NULL,
00354 NULL,
00355 NplRsRiCtl
00356 };
00357
00361 IRQ_HANDLER sig_RTCALARM = {
00362 #ifdef NUT_PERFMON
00363 0,
00364 #endif
00365 NULL,
00366 NULL,
00367 NplRtcAlarmCtl
00368 };
00369
00373 IRQ_HANDLER sig_LANWAKEUP = {
00374 #ifdef NUT_PERFMON
00375 0,
00376 #endif
00377 NULL,
00378 NULL,
00379 NplLanWakeupCtl
00380 };
00381
00385 IRQ_HANDLER sig_FMBUSY = {
00386 #ifdef NUT_PERFMON
00387 0,
00388 #endif
00389 NULL,
00390 NULL,
00391 NplFmBusyCtl
00392 };
00393
00397 IRQ_HANDLER sig_RSINVAL = {
00398 #ifdef NUT_PERFMON
00399 0,
00400 #endif
00401 NULL,
00402 NULL,
00403 NplRsInvalCtl
00404 };
00405
00409 IRQ_HANDLER sig_NRSINVAL = {
00410 #ifdef NUT_PERFMON
00411 0,
00412 #endif
00413 NULL,
00414 NULL,
00415 NplRsValidCtl
00416 };
00417
00421 IRQ_HANDLER sig_MMCD = {
00422 #ifdef NUT_PERFMON
00423 0,
00424 #endif
00425 NULL,
00426 NULL,
00427 NplMmcInsertCtl
00428 };
00429
00433 IRQ_HANDLER sig_NMMCD = {
00434 #ifdef NUT_PERFMON
00435 0,
00436 #endif
00437 NULL,
00438 NULL,
00439 NplMmcRemoveCtl
00440 };
00441