File indexing completed on 2025-05-11 08:24:07
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
0031
0032 #include <stdio.h>
0033 #include <stdlib.h>
0034 #include <stddef.h>
0035 #include <rtems.h>
0036 #include <rtems/bspIo.h>
0037 #include <drvmgr/drvmgr.h>
0038 #include <grlib/ambapp.h>
0039 #include <grlib/ambapp_bus.h>
0040 #include <bsp.h>
0041 #include <grlib/spwtdp.h>
0042
0043 #include <grlib/grlib_impl.h>
0044
0045
0046 #define STATIC static
0047
0048
0049 #define INLINE inline
0050
0051
0052 #define UNUSED __attribute__((unused))
0053
0054 #define DEBUG 1
0055
0056 #ifdef DEBUG
0057 #define DBG(x...) printf(x)
0058 #else
0059 #define DBG(x...)
0060 #endif
0061
0062
0063 #define REG_WRITE(addr, val) \
0064 (*(volatile unsigned int *)(addr) = (unsigned int)(val))
0065 #define REG_READ(addr) (*(volatile unsigned int *)(addr))
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 #define TSTXCTRL_TSTC (0xff<<TSTXCTRL_TSTC_BIT)
0081 #define ETCTRL_PF (0xffff<<ETCTRL_PF_BIT)
0082
0083 #define TSTXCTRL_TSTC_BIT 24
0084 #define ETCTRL_PF_BIT 0
0085
0086 #define DEVNAME_LEN 11
0087
0088 struct spwtdp_priv {
0089 char devname[DEVNAME_LEN];
0090 struct drvmgr_dev *dev;
0091 struct spwtdp_regs *regs;
0092 int open;
0093 int index;
0094 int initiator;
0095 int target;
0096 int freq;
0097
0098
0099 SPIN_DECLARE(devlock);
0100
0101
0102 rtems_id sem;
0103 spwtdp_isr_t isr;
0104 void * isr_arg;
0105 };
0106 int spwtdp_count = 0;
0107 static struct spwtdp_priv *priv_tab[SPWTDP_MAX];
0108
0109
0110 STATIC void spwtdp_isr(void *data);
0111 STATIC int spwtdp_hw_reset(struct spwtdp_priv *priv);
0112 STATIC int spwtdp_init2(struct drvmgr_dev *dev);
0113
0114 struct drvmgr_drv_ops spwtdp_ops =
0115 {
0116 {NULL, spwtdp_init2, NULL, NULL},
0117 NULL,
0118 NULL
0119 };
0120
0121 struct amba_dev_id spwtdp_ids[] =
0122 {
0123 {VENDOR_GAISLER, GAISLER_SPWTDP},
0124 {0, 0}
0125 };
0126
0127 struct amba_drv_info spwtdp_drv_info =
0128 {
0129 {
0130 DRVMGR_OBJ_DRV,
0131 NULL,
0132 NULL,
0133 DRIVER_AMBAPP_GAISLER_SPWTDP_ID,
0134 "SPWTDP_DRV",
0135 DRVMGR_BUS_TYPE_AMBAPP,
0136 &spwtdp_ops,
0137 NULL,
0138 0,
0139 sizeof(struct spwtdp_priv),
0140 },
0141 &spwtdp_ids[0]
0142 };
0143
0144
0145 void spwtdp_register_drv(void)
0146 {
0147 DBG("Registering SPWTDP driver\n");
0148 drvmgr_drv_register(&spwtdp_drv_info.general);
0149 }
0150
0151 STATIC int spwtdp_init(struct spwtdp_priv *priv)
0152 {
0153 struct amba_dev_info *ainfo = priv->dev->businfo;
0154 struct ambapp_apb_info *apb;
0155
0156
0157 if (ainfo == NULL) {
0158 return -1;
0159 }
0160 apb = ainfo->info.apb_slv;
0161 priv->regs = (struct spwtdp_regs *)apb->start;
0162
0163 spwtdp_hw_reset(priv);
0164
0165 if (REG_READ(&priv->regs->dat_ctrl) != 0x2f00) {
0166 DBG("SPWTDP only supports 56 bit precission counters.\n");
0167 return -1;
0168 }
0169 DBG("SPWTDP driver initialized\n");
0170
0171 return 0;
0172 }
0173
0174
0175 STATIC int spwtdp_init2(struct drvmgr_dev *dev)
0176 {
0177 int status;
0178 struct spwtdp_priv *priv;
0179
0180 DBG("SPWTDP[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0181
0182 if (spwtdp_count >= SPWTDP_MAX)
0183 return DRVMGR_ENORES;
0184
0185 priv = dev->priv;
0186 if (priv == NULL)
0187 return DRVMGR_NOMEM;
0188
0189
0190 priv->dev = dev;
0191 priv->index = spwtdp_count;
0192 priv_tab[priv->index] = priv;
0193 snprintf(priv->devname, DEVNAME_LEN, "spwtdp%01u", priv->index);
0194 spwtdp_count++;
0195
0196
0197 if (rtems_semaphore_create(
0198 rtems_build_name('S', 'T', 'P', '0' + priv->index), 1,
0199 RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | \
0200 RTEMS_NO_INHERIT_PRIORITY | RTEMS_LOCAL | \
0201 RTEMS_NO_PRIORITY_CEILING, 0, &priv->sem) != RTEMS_SUCCESSFUL) {
0202 priv->sem = RTEMS_ID_NONE;
0203 return DRVMGR_FAIL;
0204 }
0205
0206
0207 status = spwtdp_init(priv);
0208 if (status) {
0209 printk("Failed to initialize spwtdp driver %d\n", status);
0210 return -1;
0211 }
0212
0213 return DRVMGR_OK;
0214 }
0215
0216
0217 STATIC int spwtdp_hw_reset(struct spwtdp_priv *priv)
0218 {
0219 int i = 1000;
0220 SPIN_IRQFLAGS(irqflags);
0221
0222 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0223
0224
0225 REG_WRITE(&priv->regs->ists, SPWTDP_IRQ_WCLEAR);
0226
0227
0228 REG_WRITE(&priv->regs->conf[0], CONF0_RS);
0229
0230
0231 while ((REG_READ(&priv->regs->conf[0]) & CONF0_RS) && (i > 0)) {
0232 i--;
0233 }
0234
0235 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0236
0237 return ((i > 0)? SPWTDP_ERR_OK : SPWTDP_ERR_ERROR);
0238 }
0239
0240 int spwtdp_reset(void *spwtdp)
0241 {
0242 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0243
0244
0245 int ret = spwtdp_isr_unregister(spwtdp);
0246 if (ret != SPWTDP_ERR_OK)
0247 return ret;
0248
0249 priv->initiator=0;
0250 priv->target=0;
0251 priv->freq=0;
0252
0253 return spwtdp_hw_reset(priv);
0254 }
0255
0256 void *spwtdp_open(int dev_no)
0257 {
0258 struct spwtdp_priv *priv;
0259
0260 if (dev_no >= spwtdp_count)
0261 return NULL;
0262
0263
0264 priv = priv_tab[dev_no];
0265 if ((priv == NULL)||(priv->open == 1)) {
0266 return NULL;
0267 }
0268
0269
0270 priv->open = 1;
0271
0272 return priv;
0273 }
0274
0275 int spwtdp_close(void *spwtdp)
0276 {
0277 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0278
0279
0280 int ret = spwtdp_reset(spwtdp);
0281 if (ret != SPWTDP_ERR_OK)
0282 return ret;
0283
0284 priv->open = 0;
0285 return SPWTDP_ERR_OK;
0286 }
0287
0288 int spwtdp_freq_setup(void *spwtdp, uint32_t fsinc, uint32_t cv, uint8_t etinc)
0289 {
0290 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0291
0292
0293 if (priv == NULL)
0294 return SPWTDP_ERR_NOINIT;
0295
0296 if (priv->open == 0)
0297 return SPWTDP_ERR_EINVAL;
0298
0299
0300 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0301 != RTEMS_SUCCESSFUL)
0302 return SPWTDP_ERR_ERROR;
0303
0304 REG_WRITE(&priv->regs->conf[1], fsinc & CONF1_FSINC);
0305 REG_WRITE(&priv->regs->conf[2],
0306 ((cv<<CONF2_CV_BIT) & CONF2_CV) |
0307 ((uint32_t)etinc & CONF2_ETINC));
0308
0309 rtems_semaphore_release(priv->sem);
0310 priv->freq = 1;
0311
0312 return SPWTDP_ERR_OK;
0313 }
0314
0315 #define CONF0_INI_MASK (CONF0_EP|CONF0_ET|CONF0_SP|CONF0_SE|CONF0_LE| \
0316 CONF0_TD)
0317 int spwtdp_initiator_conf(void *spwtdp, uint8_t mapping, uint32_t options)
0318 {
0319 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0320
0321
0322 if (priv == NULL)
0323 return SPWTDP_ERR_NOINIT;
0324
0325 if (priv->open == 0)
0326 return SPWTDP_ERR_EINVAL;
0327
0328
0329 if (priv->target == 1)
0330 return SPWTDP_ERR_EINVAL;
0331
0332
0333 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0334 != RTEMS_SUCCESSFUL)
0335 return SPWTDP_ERR_ERROR;
0336
0337 unsigned int conf0 = REG_READ(&priv->regs->conf[0]);
0338 conf0 &= ~(CONF0_INI_MASK|CONF0_MAP);
0339 REG_WRITE(&priv->regs->conf[0],
0340 conf0 | (options & CONF0_INI_MASK) |
0341 (((uint32_t)mapping << CONF0_MAP_BIT) & CONF0_MAP));
0342
0343 priv->initiator = 1;
0344
0345 rtems_semaphore_release(priv->sem);
0346
0347 return SPWTDP_ERR_OK;
0348 }
0349
0350 #define CONF0_TAR_MASK (CONF0_JE|CONF0_ST|CONF0_EP|CONF0_ET|CONF0_SP| \
0351 CONF0_SE|CONF0_LE|CONF0_TD|CONF0_ME)
0352 int spwtdp_target_conf(void *spwtdp, uint8_t mapping, uint32_t options)
0353 {
0354 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0355
0356
0357 if (priv == NULL)
0358 return SPWTDP_ERR_NOINIT;
0359
0360 if (priv->open == 0)
0361 return SPWTDP_ERR_EINVAL;
0362
0363
0364 if (priv->initiator == 1)
0365 return SPWTDP_ERR_EINVAL;
0366
0367
0368 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0369 != RTEMS_SUCCESSFUL)
0370 return SPWTDP_ERR_ERROR;
0371
0372 unsigned int conf0 = REG_READ(&priv->regs->conf[0]);
0373 conf0 &= ~(CONF0_TAR_MASK|CONF0_MAP);
0374 REG_WRITE(&priv->regs->conf[0],
0375 conf0 | (options & CONF0_TAR_MASK) |
0376 (((uint32_t)mapping << CONF0_MAP_BIT) & CONF0_MAP));
0377
0378 priv->initiator = 1;
0379
0380 rtems_semaphore_release(priv->sem);
0381
0382 return SPWTDP_ERR_OK;
0383 }
0384
0385 int spwtdp_initiator_int_conf(void *spwtdp, uint8_t stm, uint8_t inrx,
0386 uint8_t intx)
0387 {
0388 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0389
0390
0391 if (priv == NULL)
0392 return SPWTDP_ERR_NOINIT;
0393
0394 if (priv->open == 0)
0395 return SPWTDP_ERR_EINVAL;
0396
0397
0398 if (priv->initiator != 1)
0399 return SPWTDP_ERR_EINVAL;
0400
0401 REG_WRITE(&priv->regs->conf[3],
0402 (((uint32_t)stm << CONF3_STM_BIT) & CONF3_STM) |
0403 (((uint32_t)inrx << CONF3_INRX_BIT) & CONF3_INRX) |
0404 (((uint32_t)intx << CONF3_INTX_BIT) & CONF3_INTX));
0405
0406 return SPWTDP_ERR_OK;
0407 }
0408
0409 int spwtdp_target_int_conf(void *spwtdp, uint8_t inrx, uint8_t intx,
0410 uint32_t options)
0411 {
0412 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0413
0414
0415 if (priv == NULL) {
0416 return SPWTDP_ERR_NOINIT;
0417 }
0418
0419 if (priv->open == 0)
0420 return SPWTDP_ERR_EINVAL;
0421
0422
0423 if (priv->target != 1)
0424 return SPWTDP_ERR_EINVAL;
0425
0426 REG_WRITE(&priv->regs->conf[3],
0427 (options & CONF3_DI) |
0428 (((uint32_t)inrx << CONF3_INRX_BIT) & CONF3_INRX) |
0429 (((uint32_t)intx << CONF3_INTX_BIT) & CONF3_INTX));
0430
0431 return SPWTDP_ERR_OK;
0432 }
0433
0434 int spwtdp_initiator_enable(void *spwtdp)
0435 {
0436 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0437
0438
0439 if (priv == NULL) {
0440 return SPWTDP_ERR_NOINIT;
0441 }
0442
0443 if (priv->open == 0)
0444 return SPWTDP_ERR_EINVAL;
0445
0446
0447 if (priv->initiator != 1)
0448 return SPWTDP_ERR_EINVAL;
0449
0450
0451 if (priv->freq != 1)
0452 return SPWTDP_ERR_EINVAL;
0453
0454
0455 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0456 != RTEMS_SUCCESSFUL)
0457 return SPWTDP_ERR_ERROR;
0458
0459 unsigned int conf0 = REG_READ(&priv->regs->conf[0]);
0460 REG_WRITE(&priv->regs->conf[0], conf0 | CONF0_TE);
0461
0462 rtems_semaphore_release(priv->sem);
0463
0464 return SPWTDP_ERR_OK;
0465 }
0466
0467 int spwtdp_target_enable(void *spwtdp)
0468 {
0469 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0470
0471
0472 if (priv == NULL)
0473 return SPWTDP_ERR_NOINIT;
0474
0475 if (priv->open == 0)
0476 return SPWTDP_ERR_EINVAL;
0477
0478
0479 if (priv->target != 1)
0480 return SPWTDP_ERR_EINVAL;
0481
0482
0483 if (priv->freq != 1)
0484 return SPWTDP_ERR_EINVAL;
0485
0486
0487 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0488 != RTEMS_SUCCESSFUL)
0489 return SPWTDP_ERR_ERROR;
0490
0491 unsigned int conf0 = REG_READ(&priv->regs->conf[0]);
0492 REG_WRITE(&priv->regs->conf[0], conf0 | CONF0_RE);
0493
0494 rtems_semaphore_release(priv->sem);
0495
0496 return SPWTDP_ERR_OK;
0497 }
0498
0499 int spwtdp_initiator_disable(void *spwtdp)
0500 {
0501 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0502
0503
0504 if (priv == NULL)
0505 return SPWTDP_ERR_NOINIT;
0506
0507 if (priv->open == 0)
0508 return SPWTDP_ERR_EINVAL;
0509
0510
0511 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0512 != RTEMS_SUCCESSFUL)
0513 return SPWTDP_ERR_ERROR;
0514
0515 unsigned int conf0 = REG_READ(&priv->regs->conf[0]);
0516 REG_WRITE(&priv->regs->conf[0], conf0 & ~(CONF0_TE));
0517
0518 rtems_semaphore_release(priv->sem);
0519
0520 return SPWTDP_ERR_OK;
0521 }
0522
0523 int spwtdp_target_disable(void *spwtdp)
0524 {
0525 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0526
0527
0528 if (priv == NULL)
0529 return SPWTDP_ERR_NOINIT;
0530
0531 if (priv->open == 0)
0532 return SPWTDP_ERR_EINVAL;
0533
0534
0535 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0536 != RTEMS_SUCCESSFUL)
0537 return SPWTDP_ERR_ERROR;
0538
0539 unsigned int conf0 = REG_READ(&priv->regs->conf[0]);
0540 REG_WRITE(&priv->regs->conf[0], conf0 & ~(CONF0_RE));
0541
0542 rtems_semaphore_release(priv->sem);
0543
0544 return SPWTDP_ERR_OK;
0545 }
0546
0547
0548 int spwtdp_status(void *spwtdp, uint32_t *sts, uint32_t clrmask)
0549 {
0550 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0551
0552 if (priv == NULL) {
0553
0554 return SPWTDP_ERR_NOINIT;
0555 }
0556
0557 unsigned int status = REG_READ(&priv->regs->stat[0]);
0558 REG_WRITE(&priv->regs->stat[0], status & clrmask);
0559
0560 if (sts != NULL)
0561 *sts = status;
0562
0563 return SPWTDP_ERR_OK;
0564 }
0565
0566
0567 int spwtdp_interrupt_status(void *spwtdp, uint32_t *sts, uint32_t clrmask)
0568 {
0569 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0570 SPIN_IRQFLAGS(irqflags);
0571
0572 if (priv == NULL) {
0573
0574 return SPWTDP_ERR_NOINIT;
0575 }
0576
0577 SPIN_LOCK_IRQ(&priv->devlock, irqflags);
0578 unsigned int status = REG_READ(&priv->regs->ists);
0579 REG_WRITE(&priv->regs->ists, status & clrmask);
0580 SPIN_UNLOCK_IRQ(&priv->devlock, irqflags);
0581
0582 if (sts != NULL)
0583 *sts = status;
0584
0585 return SPWTDP_ERR_OK;
0586 }
0587
0588
0589 int spwtdp_interrupt_unmask(void *spwtdp, uint32_t irqmask)
0590 {
0591 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0592
0593 if (priv == NULL) {
0594
0595 return SPWTDP_ERR_NOINIT;
0596 }
0597
0598 if (priv->open == 0)
0599 return SPWTDP_ERR_EINVAL;
0600
0601 unsigned int ctrl = REG_READ(&priv->regs->ien);
0602 REG_WRITE(&priv->regs->ien, ctrl | irqmask);
0603
0604 return SPWTDP_ERR_OK;
0605 }
0606
0607
0608 int spwtdp_interrupt_mask(void *spwtdp, uint32_t irqmask)
0609 {
0610 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0611
0612 if (priv == NULL) {
0613
0614 return SPWTDP_ERR_NOINIT;
0615 }
0616
0617 if (priv->open == 0)
0618 return SPWTDP_ERR_EINVAL;
0619
0620 unsigned int ctrl = REG_READ(&priv->regs->ien);
0621 REG_WRITE(&priv->regs->ien, ctrl & ~(irqmask));
0622
0623 return SPWTDP_ERR_OK;
0624 }
0625
0626 int spwtdp_isr_register(void *spwtdp, spwtdp_isr_t func, void *data)
0627 {
0628 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0629 SPIN_ISR_IRQFLAGS(irqflags);
0630
0631 if (priv == NULL) {
0632
0633 return SPWTDP_ERR_NOINIT;
0634 }
0635
0636 if (priv->open == 0)
0637 return SPWTDP_ERR_EINVAL;
0638
0639
0640 if (func == NULL) {
0641
0642 return SPWTDP_ERR_EINVAL;
0643 }
0644
0645 priv->isr = func;
0646 priv->isr_arg = data;
0647
0648
0649 drvmgr_interrupt_register(priv->dev, 0, "spwtdp", spwtdp_isr, priv);
0650
0651
0652 SPIN_LOCK(&priv->devlock, irqflags);
0653 unsigned int cfg0 = REG_READ(&priv->regs->conf[0]);
0654 REG_WRITE(&priv->regs->conf[0], cfg0 | CONF0_AE);
0655 SPIN_UNLOCK(&priv->devlock, irqflags);
0656
0657 return SPWTDP_ERR_OK;
0658 }
0659
0660 int spwtdp_isr_unregister(void *spwtdp)
0661 {
0662 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0663 SPIN_ISR_IRQFLAGS(irqflags);
0664
0665
0666 int ret=spwtdp_interrupt_mask(spwtdp, SPWTDP_IRQ_WCLEAR);
0667 if (ret != SPWTDP_ERR_OK)
0668 return ret;
0669
0670
0671 SPIN_LOCK(&priv->devlock, irqflags);
0672 unsigned int cfg0 = REG_READ(&priv->regs->conf[0]);
0673 REG_WRITE(&priv->regs->conf[0], cfg0 & ~(CONF0_AE));
0674 SPIN_UNLOCK(&priv->devlock, irqflags);
0675
0676
0677 drvmgr_interrupt_unregister(priv->dev, 0, spwtdp_isr, priv);
0678
0679
0680 priv->isr = NULL;
0681 priv->isr_arg = NULL;
0682
0683 return SPWTDP_ERR_OK;
0684 }
0685
0686 STATIC void spwtdp_isr(void *arg)
0687 {
0688 struct spwtdp_priv *priv = arg;
0689 unsigned int ists = REG_READ(&priv->regs->ists);
0690 SPIN_ISR_IRQFLAGS(irqflags);
0691
0692
0693 if (ists == 0)
0694 return;
0695
0696 SPIN_LOCK(&priv->devlock, irqflags);
0697 REG_WRITE(&priv->regs->ists, ists);
0698 SPIN_UNLOCK(&priv->devlock, irqflags);
0699
0700
0701 if (priv->isr!=NULL)
0702 priv->isr(ists, priv->isr_arg);
0703
0704 return;
0705 }
0706
0707 int spwtdp_dat_et_get(void * spwtdp, spwtdp_time_t * val)
0708 {
0709 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0710
0711 if (priv == NULL) {
0712
0713 return SPWTDP_ERR_NOINIT;
0714 }
0715
0716 if (priv->open == 0)
0717 return SPWTDP_ERR_EINVAL;
0718
0719
0720 if (val == NULL) {
0721 return SPWTDP_ERR_EINVAL;
0722 }
0723
0724 val->preamble = REG_READ(&priv->regs->dat_ctrl) & ETCTRL_PF;
0725 unsigned int * buffer = (unsigned int *) val->data;
0726 buffer[0] = REG_READ(&priv->regs->dat_et[0]);
0727 buffer[1] = REG_READ(&priv->regs->dat_et[1]);
0728 buffer[2] = REG_READ(&priv->regs->dat_et[2]);
0729 buffer[3] = REG_READ(&priv->regs->dat_et[3]);
0730 buffer[4] = REG_READ(&priv->regs->dat_et[4]);
0731
0732 return SPWTDP_ERR_OK;
0733 }
0734
0735 int spwtdp_tsrx_et_get(void * spwtdp, spwtdp_time_t * val)
0736 {
0737 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0738
0739 if (priv == NULL) {
0740
0741 return SPWTDP_ERR_NOINIT;
0742 }
0743
0744 if (priv->open == 0)
0745 return SPWTDP_ERR_EINVAL;
0746
0747
0748 if (val == NULL) {
0749 return SPWTDP_ERR_EINVAL;
0750 }
0751
0752 val->preamble = REG_READ(&priv->regs->ts_rx_ctrl) & ETCTRL_PF;
0753 unsigned int * buffer = (unsigned int *) val->data;
0754 buffer[0] = REG_READ(&priv->regs->ts_rx_et[0]);
0755 buffer[1] = REG_READ(&priv->regs->ts_rx_et[1]);
0756 buffer[2] = REG_READ(&priv->regs->ts_rx_et[2]);
0757 buffer[3] = REG_READ(&priv->regs->ts_rx_et[3]);
0758 buffer[4] = REG_READ(&priv->regs->ts_rx_et[4]);
0759
0760 return SPWTDP_ERR_OK;
0761 }
0762
0763 int spwtdp_tstx_et_get(void * spwtdp, spwtdp_time_t * val)
0764 {
0765 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0766
0767 if (priv == NULL) {
0768
0769 return SPWTDP_ERR_NOINIT;
0770 }
0771
0772 if (priv->open == 0)
0773 return SPWTDP_ERR_EINVAL;
0774
0775
0776 if (val == NULL) {
0777 return SPWTDP_ERR_EINVAL;
0778 }
0779
0780 val->preamble = REG_READ(&priv->regs->ts_tx_ctrl) & ETCTRL_PF;
0781 unsigned int * buffer = (unsigned int *) val->data;
0782 buffer[0] = REG_READ(&priv->regs->ts_tx_et[0]);
0783 buffer[1] = REG_READ(&priv->regs->ts_tx_et[1]);
0784 buffer[2] = REG_READ(&priv->regs->ts_tx_et[2]);
0785 buffer[3] = REG_READ(&priv->regs->ts_tx_et[3]);
0786 buffer[4] = REG_READ(&priv->regs->ts_tx_et[4]);
0787
0788 return SPWTDP_ERR_OK;
0789 }
0790
0791 int spwtdp_lat_et_get(void * spwtdp, spwtdp_time_t * val)
0792 {
0793 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0794
0795 if (priv == NULL) {
0796
0797 return SPWTDP_ERR_NOINIT;
0798 }
0799
0800 if (priv->open == 0)
0801 return SPWTDP_ERR_EINVAL;
0802
0803
0804 if (val == NULL) {
0805 return SPWTDP_ERR_EINVAL;
0806 }
0807
0808 val->preamble = REG_READ(&priv->regs->lat_ctrl) & ETCTRL_PF;
0809 unsigned int * buffer = (unsigned int *) val->data;
0810 buffer[0] = REG_READ(&priv->regs->lat_et[0]);
0811 buffer[1] = REG_READ(&priv->regs->lat_et[1]);
0812 buffer[2] = REG_READ(&priv->regs->lat_et[2]);
0813 buffer[3] = REG_READ(&priv->regs->lat_et[3]);
0814 buffer[4] = REG_READ(&priv->regs->lat_et[4]);
0815
0816 return SPWTDP_ERR_OK;
0817 }
0818
0819 int spwtdp_cmd_et_get(void * spwtdp, spwtdp_time_t * val)
0820 {
0821 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0822
0823 if (priv == NULL) {
0824
0825 return SPWTDP_ERR_NOINIT;
0826 }
0827
0828 if (priv->open == 0)
0829 return SPWTDP_ERR_EINVAL;
0830
0831
0832 if (val == NULL) {
0833 return SPWTDP_ERR_EINVAL;
0834 }
0835
0836 val->preamble = REG_READ(&priv->regs->cmd_ctrl) & ETCTRL_PF;
0837 unsigned int * buffer = (unsigned int *) val->data;
0838 buffer[0] = REG_READ(&priv->regs->cmd_et[0]);
0839 buffer[1] = REG_READ(&priv->regs->cmd_et[1]);
0840 buffer[2] = REG_READ(&priv->regs->cmd_et[2]);
0841 buffer[3] = REG_READ(&priv->regs->cmd_et[3]);
0842 buffer[4] = REG_READ(&priv->regs->cmd_et[4]);
0843
0844 return SPWTDP_ERR_OK;
0845 }
0846
0847 int spwtdp_initiator_tstx_conf(void * spwtdp, uint8_t tstc)
0848 {
0849 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0850
0851 if (priv == NULL) {
0852
0853 return SPWTDP_ERR_NOINIT;
0854 }
0855
0856 if (priv->open == 0)
0857 return SPWTDP_ERR_EINVAL;
0858
0859
0860 if (priv->initiator != 1)
0861 return SPWTDP_ERR_EINVAL;
0862
0863 REG_WRITE(&priv->regs->ts_tx_ctrl,
0864 (((uint32_t)tstc) << TSTXCTRL_TSTC_BIT) & TSTXCTRL_TSTC);
0865
0866 return SPWTDP_ERR_OK;
0867 }
0868
0869 int spwtdp_initiator_cmd_et_set(void *spwtdp, spwtdp_time_t val)
0870 {
0871 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0872
0873 if (priv == NULL) {
0874
0875 return SPWTDP_ERR_NOINIT;
0876 }
0877
0878 if (priv->open == 0)
0879 return SPWTDP_ERR_EINVAL;
0880
0881
0882 if (priv->initiator != 1)
0883 return SPWTDP_ERR_EINVAL;
0884
0885 unsigned int * buffer = (unsigned int *) val.data;
0886 REG_WRITE(&priv->regs->lat_et[0], buffer[0]);
0887 REG_WRITE(&priv->regs->lat_et[1], buffer[1]);
0888 REG_WRITE(&priv->regs->lat_et[2], buffer[2]);
0889 REG_WRITE(&priv->regs->lat_et[3], buffer[3]);
0890 REG_WRITE(&priv->regs->lat_et[4], buffer[4]);
0891
0892
0893
0894 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0895 != RTEMS_SUCCESSFUL)
0896 return SPWTDP_ERR_ERROR;
0897
0898
0899 unsigned int ctrl = REG_READ(&priv->regs->cmd_ctrl);
0900 REG_WRITE(&priv->regs->cmd_ctrl, ctrl | CTRL_NC);
0901
0902 rtems_semaphore_release(priv->sem);
0903
0904 return SPWTDP_ERR_OK;
0905 }
0906
0907 int spwtdp_initiator_cmd_spwtc_set(void *spwtdp, uint8_t spwtc)
0908 {
0909 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0910
0911 if (priv == NULL) {
0912
0913 return SPWTDP_ERR_NOINIT;
0914 }
0915
0916 if (priv->open == 0)
0917 return SPWTDP_ERR_EINVAL;
0918
0919
0920 if (priv->initiator != 1)
0921 return SPWTDP_ERR_EINVAL;
0922
0923
0924 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0925 != RTEMS_SUCCESSFUL)
0926 return SPWTDP_ERR_ERROR;
0927
0928 unsigned int ctrl = (REG_READ(&priv->regs->cmd_ctrl) &~ CTRL_SPWTC);
0929 REG_WRITE(&priv->regs->cmd_ctrl,
0930 ctrl | (((uint32_t)spwtc << CTRL_SPWTC_BIT) & CTRL_SPWTC));
0931
0932 rtems_semaphore_release(priv->sem);
0933
0934 return SPWTDP_ERR_OK;
0935 }
0936
0937 #define CTRL_TAR_MASK (CTRL_NC|CTRL_IS)
0938 int spwtdp_target_cmd_conf(void *spwtdp, uint8_t spwtc, uint16_t cpf,
0939 uint32_t options)
0940 {
0941 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0942
0943 if (priv == NULL) {
0944
0945 return SPWTDP_ERR_NOINIT;
0946 }
0947
0948 if (priv->open == 0)
0949 return SPWTDP_ERR_EINVAL;
0950
0951
0952 if (priv->target != 1)
0953 return SPWTDP_ERR_EINVAL;
0954
0955
0956 if (rtems_semaphore_obtain(priv->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
0957 != RTEMS_SUCCESSFUL)
0958 return SPWTDP_ERR_ERROR;
0959
0960 REG_WRITE(&priv->regs->cmd_ctrl,
0961 (options & CTRL_TAR_MASK) |
0962 ((cpf << CTRL_CPF_BIT) & CTRL_CPF) |
0963 (((uint32_t)spwtc << CTRL_SPWTC_BIT) & CTRL_SPWTC));
0964
0965 rtems_semaphore_release(priv->sem);
0966
0967 return SPWTDP_ERR_OK;
0968 }
0969
0970 int spwtdp_precision_get(void *spwtdp, uint8_t *fine, uint8_t *coarse)
0971 {
0972 struct spwtdp_priv *priv = (struct spwtdp_priv *)spwtdp;
0973 int coarse_precision, fine_precision;
0974
0975 if (priv == NULL) {
0976
0977 return SPWTDP_ERR_NOINIT;
0978 }
0979
0980 if (priv->open == 0)
0981 return SPWTDP_ERR_EINVAL;
0982
0983 unsigned int preamble = REG_READ(&priv->regs->dat_ctrl);
0984
0985 if (preamble & 0x80) {
0986 DBG("Pfield second extension set: unknown format");
0987 return SPWTDP_ERR_ERROR;
0988 }
0989 if (!((preamble & 0x7000) == 0x2000 || (preamble & 0x7000) == 0x1000)) {
0990 DBG(" PField indicates not unsegmented code: unknown format");
0991 return SPWTDP_ERR_ERROR;
0992 }
0993
0994
0995
0996
0997 coarse_precision = ((preamble >> 10) & 0x3) + 1;
0998 if (preamble & 0x80)
0999 coarse_precision += (preamble >> 5) & 0x3;
1000 fine_precision = (preamble >> 8) & 0x3;
1001 if (preamble & 0x80)
1002 fine_precision += (preamble >> 2) & 0x7;
1003 if (coarse!=NULL)
1004 *coarse = coarse_precision;
1005 if (fine!=NULL)
1006 *fine = fine_precision;
1007
1008 return SPWTDP_ERR_OK;
1009 }
1010