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