/* USRP E310 Firmware PMU
* Copyright (C) 2014 Ettus Research
* This file is part of the USRP E310 Firmware
* The USRP E310 Firmware is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* The USRP E310 Firmware is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with the USRP E310 Firmware. If not, see .
*/
/**
* \file pmu.h
* \brief Power Management Unit (PMU) functionality
*/
#ifndef PMU_H
#define PMU_H
#include
#include "interrupt.h"
#include "utils.h"
/**
* \brief Initialize the Power Management Unit
* \return 0 on success, negative error code on error
*/
int8_t pmu_init(void);
typedef struct pmu_regulator pmu_regulator_t;
typedef struct pmu_regulator_ops {
int8_t (*set_voltage)(pmu_regulator_t *, uint16_t);
int8_t (*set_regulator)(pmu_regulator_t *, bool);
int8_t (*check_events)(pmu_regulator_t *);
} pmu_regulator_ops_t;
struct pmu_regulator {
const pmu_regulator_ops_t *ops;
const uint16_t voltage;
bool powered;
uint8_t error_code;
};
/**
* \brief Event loop that handles all the various events
*/
void pmu_handle_events(void);
extern irqreturn_t pmu_fpga_irq_handler(void);
extern irqreturn_t pmu_led_timer_comp_a_irq_handler(void);
extern irqreturn_t pmu_led_timer_comp_b_irq_handler(void);
extern irqreturn_t pmu_wdt_handler(void);
/**
* \brief Turn on the regulators and powerup ARM and FPGA
*/
void pmu_power_on(void);
enum pmu_health {
PMU_HEALTH_GOOD,
PMU_HEALTH_UNSPEC_FAIL,
PMU_HEALTH_OVERVOLTAGE,
PMU_HEALTH_OVERHEAT,
PMU_HEALTH_COLD,
PMU_HEALTH_SAFETY_TIMER_EXPIRE,
PMU_HEALTH_UNKNOWN
};
enum pmu_charge_type {
PMU_CHARGE_TYPE_NONE,
PMU_CHARGE_TYPE_TRICKLE,
PMU_CHARGE_TYPE_FAST,
};
enum pmu_status {
PMU_STATUS_NOT_CHARGING,
PMU_STATUS_CHARGING,
PMU_STATUS_FULL,
PMU_STATUS_DISCHARGING
};
typedef struct pmu_charger pmu_charger_t;
enum pmu_charger_event_mask {
PMU_CHARGER_EVENT_NONE = 0x00,
PMU_CHARGER_EVENT_STATUS_CHANGE = BIT(0),
PMU_CHARGER_EVENT_FAULT_CHANGE = BIT(1),
PMU_CHARGER_EVENT_CHARGE_DONE = BIT(2)
};
typedef struct pmu_charger_ops {
int8_t (*set_charger_voltage)(pmu_charger_t *, uint16_t);
int8_t (*set_charger_current)(pmu_charger_t *, uint16_t);
uint8_t (*get_temp_alert)(pmu_charger_t *);
int8_t (*set_temp_alert)(pmu_charger_t *, uint8_t);
enum pmu_charge_type (*get_charge_type)(pmu_charger_t *);
int8_t (*set_charge_type)(pmu_charger_t *, enum pmu_charge_type);
enum pmu_health (*get_charger_health)(pmu_charger_t *);
bool (*get_charger_online)(pmu_charger_t *);
enum pmu_health (*get_battery_health)(pmu_charger_t *);
enum pmu_status (*get_battery_status)(pmu_charger_t *);
bool (*get_battery_online)(pmu_charger_t *);
uint8_t (*check_events)(pmu_charger_t *);
} pmu_charger_ops_t;
struct pmu_charger {
const pmu_charger_ops_t *ops;
};
/**
* \brief Set the PMU's charger to the given one
* \param[in] pmu_charger Pointer to the implementation's pmu_charger
*/
void pmu_register_charger(pmu_charger_t *pmu_charger);
typedef struct pmu_button pmu_button_t;
enum pmu_button_event_mask {
PMU_BUTTON_EVENT_MASK_PRESS = 0x01,
PMU_BUTTON_EVENT_MASK_RELEASE = 0x02,
PMU_BUTTON_EVENT_MASK_POWERDOWN = 0x04,
PMU_BUTTON_EVENT_MASK_WAKEUP = 0x08,
};
typedef struct pmu_button_ops {
uint8_t (*check_events)(pmu_button_t *);
} pmu_button_ops_t;
struct pmu_button {
const pmu_button_ops_t *ops;
};
/**
* \brief Set the PMU's button to the given one
* \param[in] pmu_button Pointer to the implementation's pmu_button
*/
void pmu_register_button(pmu_button_t *pmu_button);
typedef struct pmu_gauge pmu_gauge_t;
enum pmu_gauge_event_mask {
PMU_GAUGE_EVENT_NONE = 0x00,
PMU_GAUGE_CHARGE_HI = 0x01,
PMU_GAUGE_CHARGE_LO = 0x02,
PMU_GAUGE_TEMP_HI = 0x04,
PMU_GAUGE_TEMP_LO = 0x08,
PMU_GAUGE_VOLT_LO = 0x10,
PMU_GAUGE_VOLT_HI = 0x20,
};
typedef struct pmu_gauge_ops {
uint8_t (*check_events)(void);
uint16_t (*get_charge)(void);
void (*set_charge)(uint16_t val);
void (*set_low_threshold)(uint16_t val);
uint16_t (*get_temperature)(void);
uint16_t (*get_voltage)(void);
} pmu_gauge_ops_t;
struct pmu_gauge {
const pmu_gauge_ops_t *ops;
};
/**
* \brief Set the PMU's power gauge to the given one
* \param[in] pmu_gauge Pointer to the implementation's pmu_gauge
*/
void pmu_register_gauge(pmu_gauge_t *pmu_gauge);
#endif /* PMU_H */