1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#include <stdint.h> 14#include <stdbool.h> 15 16#include <utils/arith.h> 17#include <utils/attribute.h> 18#include <utils/force.h> 19#include <platsupport/io.h> 20 21#include "devcfg.h" 22 23#define XADC_MSTS_CFIFOE BIT(10) // XADC Interafce Command FIFO empty 24#define XADCIF_CFG_ENABLE BIT(31) // XADC Interface Configuration Enable 25#define XADCIF_MCTL_RESET BIT(4) // XADC Interface Miscellaneous Control Reset 26 27/* Constants/macros for formatting commands for the XADC */ 28#define XADC_DATA_OFFSET 0 29#define XADC_DATA_MASK MASK(16) 30 31#define XADC_ADDRESS_OFFSET 16 32#define XADC_ADDRESS_MASK MASK(10) 33#define XADC_VALID_ADDRESS_MASK MASK(6) 34 35#define XADC_COMMAND_OFFSET 26 36#define XADC_COMMAND_MASK MASK(4) 37 38#define FORMAT_XADC_COMMAND(command, address, data) (\ 39 (((data) & XADC_DATA_MASK) << XADC_DATA_OFFSET) |\ 40 (((address) & XADC_ADDRESS_MASK) << XADC_ADDRESS_OFFSET) |\ 41 (((command) & XADC_COMMAND_MASK) << XADC_COMMAND_OFFSET)) 42 43#define XADC_COMMAND_NOOP 0 44#define XADC_COMMAND_READ 1 45#define XADC_COMMAND_WRITE 2 46 47#define FORMAT_XADC_READ(address) FORMAT_XADC_COMMAND(XADC_COMMAND_READ, address, 0) 48#define XADC_NOOP FORMAT_XADC_COMMAND(XADC_COMMAND_NOOP, 0, 0) 49 50static bool initialized = false; 51 52int xadc_init(ps_io_ops_t* ops) { 53 if (initialized) { 54 return 0; 55 } 56 57 int error = devcfg_init(ops); 58 if (error != 0) { 59 return error; 60 } 61 62 devcfg_regs_t* devcfg_regs = devcfg_get_regs(); 63 if (devcfg_regs == NULL) { 64 return -1; 65 } 66 67 devcfg_regs->xadcif_cfg |= XADCIF_CFG_ENABLE; 68 devcfg_regs->xadcif_mctl &= ~XADCIF_MCTL_RESET; 69 70 initialized = true; 71 72 return 0; 73} 74 75uint32_t xadc_read_register(uint32_t address) { 76 devcfg_regs_t* devcfg_regs = devcfg_get_regs(); 77 78 // write the command 79 devcfg_regs->xadcif_cmdfifo = FORMAT_XADC_READ(address & XADC_VALID_ADDRESS_MASK); 80 81 // wait for the command to leave the fifo 82 while (!(devcfg_regs->xadcif_msts & XADC_MSTS_CFIFOE)); 83 84 // do a dummy read 85 FORCE_READ(&devcfg_regs->xadcif_rdfifo); 86 87 // send a noop to shift the result into rdfifo 88 devcfg_regs->xadcif_cmdfifo = XADC_NOOP; 89 90 // read the result 91 return devcfg_regs->xadcif_rdfifo; 92} 93