File indexing completed on 2025-05-11 08:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include <bsp.h>
0031 #include <rtems/libio.h>
0032 #include <stdlib.h>
0033 #include <assert.h>
0034 #include <rtems/bspIo.h>
0035 #include <string.h>
0036 #include <stdio.h>
0037
0038 #include <drvmgr/drvmgr.h>
0039 #include <grlib/ambapp_bus.h>
0040 #include <grlib/grgpio.h>
0041 #include <grlib/gpiolib.h>
0042 #include <grlib/ambapp.h>
0043 #include <grlib/grlib.h>
0044 #include <grlib/grlib_impl.h>
0045
0046
0047
0048 #ifdef DEBUG
0049 #define DBG(x...) printk(x)
0050 #define STATIC
0051 #else
0052 #define DBG(x...)
0053 #define STATIC static
0054 #endif
0055
0056 struct grgpio_isr {
0057 drvmgr_isr isr;
0058 void *arg;
0059 };
0060
0061 struct grgpio_priv {
0062 struct drvmgr_dev *dev;
0063 struct grgpio_regs *regs;
0064 int irq;
0065 int minor;
0066
0067
0068 int port_cnt;
0069 unsigned char port_handles[32];
0070 struct grgpio_isr isrs[32];
0071 struct gpiolib_drv gpiolib_desc;
0072 unsigned int bypass;
0073 unsigned int imask;
0074 };
0075
0076
0077
0078 int grgpio_device_init(struct grgpio_priv *priv);
0079
0080 int grgpio_init1(struct drvmgr_dev *dev);
0081 int grgpio_init2(struct drvmgr_dev *dev);
0082
0083 struct drvmgr_drv_ops grgpio_ops =
0084 {
0085 .init = {grgpio_init1, NULL, NULL, NULL},
0086 .remove = NULL,
0087 .info = NULL
0088 };
0089
0090 struct amba_dev_id grgpio_ids[] =
0091 {
0092 {VENDOR_GAISLER, GAISLER_GPIO},
0093 {0, 0}
0094 };
0095
0096 struct amba_drv_info grgpio_drv_info =
0097 {
0098 {
0099 DRVMGR_OBJ_DRV,
0100 NULL,
0101 NULL,
0102 DRIVER_AMBAPP_GAISLER_GRGPIO_ID,
0103 "GRGPIO_DRV",
0104 DRVMGR_BUS_TYPE_AMBAPP,
0105 &grgpio_ops,
0106 NULL,
0107 0,
0108 0,
0109 },
0110 &grgpio_ids[0]
0111 };
0112
0113 void grgpio_register_drv (void)
0114 {
0115 DBG("Registering GRGPIO driver\n");
0116 drvmgr_drv_register(&grgpio_drv_info.general);
0117 }
0118
0119
0120
0121
0122
0123
0124 int grgpio_init1(struct drvmgr_dev *dev)
0125 {
0126 struct grgpio_priv *priv;
0127 int status, port;
0128
0129 DBG("GRGPIO[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0130
0131
0132
0133
0134
0135
0136 status = gpiolib_initialize();
0137 if ( status < 0 )
0138 return DRVMGR_FAIL;
0139
0140 priv = dev->priv = grlib_calloc(1, sizeof(*priv));
0141 if ( !priv )
0142 return DRVMGR_NOMEM;
0143 priv->dev = dev;
0144
0145 if ( grgpio_device_init(priv) ) {
0146 free(dev->priv);
0147 dev->priv = NULL;
0148 return DRVMGR_FAIL;
0149 }
0150
0151
0152
0153
0154 for(port=0; port<priv->port_cnt; port++) {
0155 priv->port_handles[port] = port;
0156 gpiolib_drv_register(&priv->gpiolib_desc,
0157 &priv->port_handles[port]);
0158 }
0159
0160 return DRVMGR_OK;
0161 }
0162
0163
0164
0165
0166 static int grgpio_find_port(void *handle, struct grgpio_priv **priv)
0167 {
0168 unsigned char portnr;
0169
0170 portnr = *(unsigned char *)handle;
0171 if ( portnr > 31 )
0172 return -1;
0173 *priv = (struct grgpio_priv *)
0174 (((unsigned int)handle - portnr*sizeof(unsigned char)) -
0175 offsetof(struct grgpio_priv, port_handles));
0176 return portnr;
0177 }
0178
0179 static int grgpio_gpiolib_open(void *handle)
0180 {
0181 struct grgpio_priv *priv;
0182 int portnr;
0183
0184 portnr = grgpio_find_port(handle, &priv);
0185 if ( portnr < 0 ) {
0186 DBG("GRGPIO: FAILED OPENING HANDLE 0x%08x\n", handle);
0187 return -1;
0188 }
0189 DBG("GRGPIO[0x%08x][%d]: OPENING\n", priv->regs, portnr);
0190
0191
0192
0193 return 0;
0194 }
0195
0196 static int grgpio_grpiolib_config(void *handle, struct gpiolib_config *cfg)
0197 {
0198 struct grgpio_priv *priv;
0199 int portnr;
0200 unsigned int mask;
0201
0202 portnr = grgpio_find_port(handle, &priv);
0203 if ( portnr < 0 ) {
0204 return -1;
0205 }
0206 DBG("GRGPIO[0x%08x][%d]: CONFIG\n", priv->regs, portnr);
0207
0208
0209
0210
0211 mask = (1<<portnr);
0212
0213
0214
0215
0216 if ( ((mask & priv->imask) == 0) && cfg->mask )
0217 return -1;
0218
0219 priv->regs->imask &= ~mask;
0220
0221
0222 priv->regs->ipol = (priv->regs->ipol & ~mask) | (cfg->irq_polarity ? mask : 0);
0223 priv->regs->iedge = (priv->regs->iedge & ~mask) | (cfg->irq_level ? 0 : mask);
0224 priv->regs->imask |= cfg->mask ? mask : 0;
0225
0226 return 0;
0227 }
0228
0229 static int grgpio_grpiolib_get(void *handle, int *inval)
0230 {
0231 struct grgpio_priv *priv;
0232 int portnr;
0233
0234 portnr = grgpio_find_port(handle, &priv);
0235 if ( portnr < 0 ) {
0236 return -1;
0237 }
0238 DBG("GRGPIO[0x%08x][%d]: GET\n", priv->regs, portnr);
0239
0240
0241 if ( inval )
0242 *inval = (priv->regs->data >> portnr) & 0x1;
0243
0244 return 0;
0245 }
0246
0247 static int grgpio_grpiolib_irq_opts(void *handle, unsigned int options)
0248 {
0249 struct grgpio_priv *priv;
0250 int portnr;
0251 drvmgr_isr isr;
0252 void *arg;
0253
0254 portnr = grgpio_find_port(handle, &priv);
0255 if ( portnr < 0 ) {
0256 return -1;
0257 }
0258 DBG("GRGPIO[0x%08x][%d]: IRQ OPTS 0x%x\n", priv->regs, portnr, options);
0259
0260 if ( options & GPIOLIB_IRQ_FORCE )
0261 return -1;
0262
0263 isr = priv->isrs[portnr].isr;
0264 arg = priv->isrs[portnr].arg;
0265
0266 if ( options & GPIOLIB_IRQ_DISABLE ) {
0267
0268 if ( drvmgr_interrupt_unregister(priv->dev, portnr, isr, arg) ) {
0269 return -1;
0270 }
0271 }
0272 if ( options & GPIOLIB_IRQ_CLEAR ) {
0273
0274 if ( drvmgr_interrupt_clear(priv->dev, portnr) ) {
0275 return -1;
0276 }
0277 }
0278 if ( options & GPIOLIB_IRQ_ENABLE ) {
0279
0280 if ( drvmgr_interrupt_register(priv->dev, portnr, "grgpio", isr, arg) ) {
0281 return -1;
0282 }
0283 }
0284 if ( options & GPIOLIB_IRQ_MASK ) {
0285
0286 if ( drvmgr_interrupt_mask(priv->dev, portnr) ) {
0287 return -1;
0288 }
0289 }
0290 if ( options & GPIOLIB_IRQ_UNMASK ) {
0291
0292 if ( drvmgr_interrupt_unmask(priv->dev, portnr) ) {
0293 return -1;
0294 }
0295 }
0296
0297 return 0;
0298 }
0299
0300 static int grgpio_grpiolib_irq_register(void *handle, void *func, void *arg)
0301 {
0302 struct grgpio_priv *priv;
0303 int portnr;
0304
0305 portnr = grgpio_find_port(handle, &priv);
0306 if ( portnr < 0 ) {
0307 DBG("GRGPIO: FAILED OPENING HANDLE 0x%08x\n", handle);
0308 return -1;
0309 }
0310 DBG("GRGPIO: OPENING %d at [0x%08x]\n", portnr, priv->regs);
0311
0312
0313 priv->isrs[portnr].isr = func;
0314 priv->isrs[portnr].arg = arg;
0315
0316 return 0;
0317 }
0318
0319 static int grgpio_grpiolib_set(void *handle, int dir, int outval)
0320 {
0321 struct grgpio_priv *priv;
0322 int portnr;
0323 unsigned int mask;
0324
0325 portnr = grgpio_find_port(handle, &priv);
0326 if ( portnr < 0 ) {
0327 DBG("GRGPIO: FAILED OPENING HANDLE 0x%08x\n", handle);
0328 return -1;
0329 }
0330 DBG("GRGPIO: OPENING %d at [0x%08x]\n", portnr, priv->regs);
0331
0332
0333 mask = 1<<portnr;
0334 priv->regs->dir = (priv->regs->dir & ~mask) | (dir ? mask : 0);
0335 priv->regs->output = (priv->regs->output & ~mask) | (outval ? mask : 0);
0336
0337 return 0;
0338 }
0339
0340 static int grgpio_gpiolib_show(void *handle)
0341 {
0342 struct grgpio_priv *priv;
0343 int portnr, i, regs[7];
0344 volatile unsigned int *reg;
0345
0346 portnr = grgpio_find_port(handle, &priv);
0347 if ( portnr < 0 ) {
0348 DBG("GRGPIO: FAILED SHOWING HANDLE 0x%08x\n", handle);
0349 return -1;
0350 }
0351 for (i=0, reg=&priv->regs->data; i<7; i++, reg++) {
0352 regs[i] = ( *reg >> portnr) & 1;
0353 }
0354 printf("GRGPIO[%p] PORT[%d]: IN/OUT/DIR: [%d,%d,%d], MASK/POL/EDGE: [%d,%d,%d], BYPASS: %d\n",
0355 priv->regs, portnr, regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6]);
0356 return 0;
0357 }
0358
0359 static int grgpio_gpiolib_get_info(void *handle, struct gpiolib_info *pinfo)
0360 {
0361 struct grgpio_priv *priv;
0362 int portnr;
0363 char prefix[48];
0364 struct drvmgr_dev *dev;
0365
0366 if ( !pinfo )
0367 return -1;
0368
0369 portnr = grgpio_find_port(handle, &priv);
0370 if ( portnr < 0 ) {
0371 DBG("GRGPIO: FAILED GET_INFO HANDLE 0x%08x\n", handle);
0372 return -1;
0373 }
0374
0375
0376 dev = priv->dev;
0377 prefix[0] = '\0';
0378 if ( drvmgr_get_dev_prefix(dev, prefix) ) {
0379
0380
0381
0382 snprintf(pinfo->devName, 80, "/dev/grgpio%d/%d", dev->minor_drv, portnr);
0383 } else {
0384
0385
0386
0387 snprintf(pinfo->devName, 80, "/dev/%sgrgpio%d/%d", prefix, dev->minor_bus, portnr);
0388 }
0389
0390 return 0;
0391 }
0392
0393 static struct gpiolib_drv_ops grgpio_gpiolib_ops =
0394 {
0395 .config = grgpio_grpiolib_config,
0396 .get = grgpio_grpiolib_get,
0397 .irq_opts = grgpio_grpiolib_irq_opts,
0398 .irq_register = grgpio_grpiolib_irq_register,
0399 .open = grgpio_gpiolib_open,
0400 .set = grgpio_grpiolib_set,
0401 .show = grgpio_gpiolib_show,
0402 .get_info = grgpio_gpiolib_get_info,
0403 };
0404
0405 int grgpio_device_init(struct grgpio_priv *priv)
0406 {
0407 struct amba_dev_info *ambadev;
0408 struct ambapp_core *pnpinfo;
0409 union drvmgr_key_value *value;
0410 unsigned int mask;
0411 int port_cnt;
0412
0413
0414 ambadev = (struct amba_dev_info *)priv->dev->businfo;
0415 if ( ambadev == NULL ) {
0416 return -1;
0417 }
0418 pnpinfo = &ambadev->info;
0419 priv->irq = pnpinfo->irq;
0420 priv->regs = (struct grgpio_regs *)pnpinfo->apb_slv->start;
0421
0422 DBG("GRGPIO: 0x%08x irq %d\n", (unsigned int)priv->regs, priv->irq);
0423
0424
0425 priv->regs->imask = 0;
0426
0427
0428 priv->regs->ipol = 0xfffffffe;
0429 priv->regs->iedge = 0xfffffffe;
0430
0431
0432 priv->imask = priv->regs->ipol;
0433
0434
0435
0436
0437 value = drvmgr_dev_key_get(priv->dev, "nBits", DRVMGR_KT_INT);
0438 if ( value ) {
0439 priv->port_cnt = value->i;
0440 } else {
0441
0442 priv->regs->dir = 0;
0443 priv->regs->output = 0xffffffff;
0444 mask = priv->regs->output;
0445 priv->regs->output = 0;
0446
0447 for(port_cnt=0; port_cnt<32; port_cnt++)
0448 if ( (mask & (1<<port_cnt)) == 0 )
0449 break;
0450 priv->port_cnt = port_cnt;
0451 }
0452
0453
0454
0455
0456 value = drvmgr_dev_key_get(priv->dev, "bypass", DRVMGR_KT_INT);
0457 if ( value ) {
0458 priv->bypass = value->i;
0459 } else {
0460 priv->bypass = 0;
0461 }
0462 priv->regs->bypass = priv->bypass;
0463
0464
0465 priv->gpiolib_desc.ops = &grgpio_gpiolib_ops;
0466
0467 return 0;
0468 }