/* USRP E310 TP54478 driver
* 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 .
*/
#include "mcu_settings.h"
#include "io.h"
#include "tps54478.h"
#include
#include
#include
static io_pin_t CORE_PWR_EN = IO_PA(3);
static io_pin_t CORE_PGOOD = IO_PB(0);
/* per spec we should wait 3 ms here,
* but 10 is better to give external PSU some time
* to settle down*/
static const uint8_t TPS54478_START_DELAY = 10;
/* we'll use this to check for events in the event handler */
static volatile bool tps54478_event = false;
bool tps54478_get_power_good(void)
{
return io_test_pin(CORE_PGOOD);
}
static int8_t tps54478_set_regulator(pmu_regulator_t *pmu_reg, bool on)
{
(void) pmu_reg;
if (on) {
io_input_pin(CORE_PWR_EN);
_delay_ms(TPS54478_START_DELAY);
} else {
io_output_pin(CORE_PWR_EN);
/* no delay here as we can't detect this state anyway */
return 0;
}
/* return zero on success ... */
return !(on == tps54478_get_power_good());
}
void tps54478_init(bool enable)
{
/* enable pull-up for open drain */
io_input_pin(CORE_PGOOD);
io_set_pin(CORE_PGOOD);
tps54478_set_regulator(NULL, enable);
io_clear_pin(CORE_PWR_EN);
}
int8_t tps54478_check_events(pmu_regulator_t *reg)
{
bool power_good;
bool event;
event = false;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
if (tps54478_event) {
tps54478_event = false;
event = true;
}
}
if (event) {
power_good = tps54478_get_power_good();
if (!power_good)
return -1;
}
return 0;
}
const pmu_regulator_ops_t tps54478_ops = {
.set_voltage = NULL,
.set_regulator = tps54478_set_regulator,
.check_events = tps54478_check_events,
};
irqreturn_t tps54478_irq_handler(void)
{
bool power_good;
power_good = tps54478_get_power_good();
/* check if the device indicates power is good,
* if it is probably we're not the source of the IRQ,
* if it is *not* set the event flag to deal with it later */
if (power_good) {
return IRQ_NONE;
} else {
tps54478_event = true;
return IRQ_HANDLED;
}
return IRQ_HANDLED;
}