blob: 13f875c8deae9685b4f6bb3b93e060181e8e4c90 [file] [log] [blame]
/*
* Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <stdint.h>
#include <stdbool.h>
#include <utils/arith.h>
#include <utils/attribute.h>
#include <utils/force.h>
#include <platsupport/io.h>
#include "devcfg.h"
#define XADC_MSTS_CFIFOE BIT(10) // XADC Interafce Command FIFO empty
#define XADCIF_CFG_ENABLE BIT(31) // XADC Interface Configuration Enable
#define XADCIF_MCTL_RESET BIT(4) // XADC Interface Miscellaneous Control Reset
/* Constants/macros for formatting commands for the XADC */
#define XADC_DATA_OFFSET 0
#define XADC_DATA_MASK MASK(16)
#define XADC_ADDRESS_OFFSET 16
#define XADC_ADDRESS_MASK MASK(10)
#define XADC_VALID_ADDRESS_MASK MASK(6)
#define XADC_COMMAND_OFFSET 26
#define XADC_COMMAND_MASK MASK(4)
#define FORMAT_XADC_COMMAND(command, address, data) (\
(((data) & XADC_DATA_MASK) << XADC_DATA_OFFSET) |\
(((address) & XADC_ADDRESS_MASK) << XADC_ADDRESS_OFFSET) |\
(((command) & XADC_COMMAND_MASK) << XADC_COMMAND_OFFSET))
#define XADC_COMMAND_NOOP 0
#define XADC_COMMAND_READ 1
#define XADC_COMMAND_WRITE 2
#define FORMAT_XADC_READ(address) FORMAT_XADC_COMMAND(XADC_COMMAND_READ, address, 0)
#define XADC_NOOP FORMAT_XADC_COMMAND(XADC_COMMAND_NOOP, 0, 0)
static bool initialized = false;
int xadc_init(ps_io_ops_t* ops) {
if (initialized) {
return 0;
}
int error = devcfg_init(ops);
if (error != 0) {
return error;
}
devcfg_regs_t* devcfg_regs = devcfg_get_regs();
if (devcfg_regs == NULL) {
return -1;
}
devcfg_regs->xadcif_cfg |= XADCIF_CFG_ENABLE;
devcfg_regs->xadcif_mctl &= ~XADCIF_MCTL_RESET;
initialized = true;
return 0;
}
uint32_t xadc_read_register(uint32_t address) {
devcfg_regs_t* devcfg_regs = devcfg_get_regs();
// write the command
devcfg_regs->xadcif_cmdfifo = FORMAT_XADC_READ(address & XADC_VALID_ADDRESS_MASK);
// wait for the command to leave the fifo
while (!(devcfg_regs->xadcif_msts & XADC_MSTS_CFIFOE));
// do a dummy read
FORCE_READ(&devcfg_regs->xadcif_rdfifo);
// send a noop to shift the result into rdfifo
devcfg_regs->xadcif_cmdfifo = XADC_NOOP;
// read the result
return devcfg_regs->xadcif_rdfifo;
}