1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
/* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file pmu.h
* \brief Power Management Unit (PMU) functionality
*/
#ifndef PMU_H
#define PMU_H
#include <stdbool.h>
#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 */
|