Add max77620-rtc driver & disable alarm on shut off

This commit is contained in:
Kostas Missos 2019-02-12 00:45:27 +02:00
parent b3f8961e45
commit b677d6cad3
4 changed files with 162 additions and 0 deletions

View file

@ -53,6 +53,7 @@ OBJS = $(addprefix $(BUILD)/$(TARGET)/, \
ini.o \ ini.o \
ianos.o \ ianos.o \
smmu.o \ smmu.o \
max77620-rtc.o \
) )
OBJS += $(addprefix $(BUILD)/$(TARGET)/, \ OBJS += $(addprefix $(BUILD)/$(TARGET)/, \

View file

@ -31,6 +31,7 @@
#include "mem/heap.h" #include "mem/heap.h"
#include "mem/sdram.h" #include "mem/sdram.h"
#include "power/max77620.h" #include "power/max77620.h"
#include "rtc/max77620-rtc.h"
#include "soc/hw_init.h" #include "soc/hw_init.h"
#include "soc/i2c.h" #include "soc/i2c.h"
#include "soc/pmc.h" #include "soc/pmc.h"
@ -229,6 +230,10 @@ void reboot_rcm()
void power_off() void power_off()
{ {
sd_unmount(); sd_unmount();
// Stop the alarm, in case we injected and powered off too fast.
max77620_rtc_stop_alarm();
#ifdef MENU_LOGO_ENABLE #ifdef MENU_LOGO_ENABLE
free(Kc_MENU_LOGO); free(Kc_MENU_LOGO);
#endif //MENU_LOGO_ENABLE #endif //MENU_LOGO_ENABLE
@ -243,6 +248,10 @@ void check_power_off_from_hos()
if (hosWakeup & MAX77620_IRQ_TOP_RTC_MASK) if (hosWakeup & MAX77620_IRQ_TOP_RTC_MASK)
{ {
sd_unmount(); sd_unmount();
// Stop the alarm, in case we injected too fast.
max77620_rtc_stop_alarm();
if (h_cfg.autohosoff == 1) if (h_cfg.autohosoff == 1)
{ {
gfx_clear_grey(&gfx_ctxt, 0x1B); gfx_clear_grey(&gfx_ctxt, 0x1B);

View file

@ -0,0 +1,77 @@
/*
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
*
* Copyright (c) 2018 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "max77620-rtc.h"
#include "../soc/i2c.h"
#include "../utils/util.h"
void max77620_rtc_get_time(rtc_time_t *time)
{
u8 val = 0;
// Update RTC regs from RTC clock.
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
// Get control reg config.
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_CONTROL_REG);
// TODO: Check for binary format also?
// Get time.
time->sec = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_SEC_REG) & 0x7F;
time->min = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MIN_REG) & 0x7F;
time->hour = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_HOUR_REG) & 0x1F;
if (!(val & MAX77620_RTC_24H) && time->hour & MAX77620_RTC_HOUR_PM_MASK)
time->hour = (time->hour & 0xF) + 12;
// Get day of week. 1: Monday to 7: Sunday.
time->weekday = 0;
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_WEEKDAY_REG);
for (int i = 0; i < 8; i++)
{
time->weekday++;
if (val & 1)
break;
val >>= 1;
}
// Get date.
time->date = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_DATE_REG) & 0x1f;
time->month = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_MONTH_REG) & 0xF) - 1;
time->year = (i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_YEAR_REG) & 0x7F) + 2000;
}
void max77620_rtc_stop_alarm()
{
u8 val = 0;
// Update RTC regs from RTC clock.
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_READ_UPDATE);
// Stop alarm for both ALARM1 and ALARM2. Horizon uses ALARM2.
for (int i = 0; i < (MAX77620_RTC_NR_TIME_REGS * 2); i++)
{
val = i2c_recv_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_SEC_REG + i);
val &= ~MAX77620_RTC_ALARM_EN_MASK;
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_ALARM1_SEC_REG + i, val);
}
// Update RTC clock from RTC regs.
i2c_send_byte(I2C_5, MAX77620_RTC_I2C_ADDR, MAX77620_RTC_UPDATE0_REG, MAX77620_RTC_WRITE_UPDATE);
}

View file

@ -0,0 +1,75 @@
/*
* PMIC Real Time Clock driver for Nintendo Switch's MAX77620-RTC
*
* Copyright (c) 2018 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MFD_MAX77620_RTC_H_
#define _MFD_MAX77620_RTC_H_
#include "../utils/types.h"
#define MAX77620_RTC_I2C_ADDR 0x68
#define MAX77620_RTC_NR_TIME_REGS 7
#define MAX77620_RTC_CONTROLM_REG 0x02
#define MAX77620_RTC_CONTROL_REG 0x03
#define MAX77620_RTC_BIN_FORMAT (1 << 0)
#define MAX77620_RTC_24H (1 << 1)
#define MAX77620_RTC_UPDATE0_REG 0x04
#define MAX77620_RTC_WRITE_UPDATE (1 << 0)
#define MAX77620_RTC_READ_UPDATE (1 << 4)
#define MAX77620_RTC_SEC_REG 0x07
#define MAX77620_RTC_MIN_REG 0x08
#define MAX77620_RTC_HOUR_REG 0x09
#define MAX77620_RTC_HOUR_PM_MASK (1 << 6)
#define MAX77620_RTC_WEEKDAY_REG 0x0A
#define MAX77620_RTC_MONTH_REG 0x0B
#define MAX77620_RTC_YEAR_REG 0x0C
#define MAX77620_RTC_DATE_REG 0x0D
#define MAX77620_ALARM1_SEC_REG 0x0E
#define MAX77620_ALARM1_MIN_REG 0x0F
#define MAX77620_ALARM1_HOUR_REG 0x10
#define MAX77620_ALARM1_WEEKDAY_REG 0x11
#define MAX77620_ALARM1_MONTH_REG 0x12
#define MAX77620_ALARM1_YEAR_REG 0x13
#define MAX77620_ALARM1_DATE_REG 0x14
#define MAX77620_ALARM2_SEC_REG 0x15
#define MAX77620_ALARM2_MIN_REG 0x16
#define MAX77620_ALARM2_HOUR_REG 0x17
#define MAX77620_ALARM2_WEEKDAY_REG 0x18
#define MAX77620_ALARM2_MONTH_REG 0x19
#define MAX77620_ALARM2_YEAR_REG 0x1A
#define MAX77620_ALARM2_DATE_REG 0x1B
#define MAX77620_RTC_ALARM_EN_MASK (1 << 7)
typedef struct _rtc_time_t {
u8 weekday;
u8 sec;
u8 min;
u8 hour;
u8 date;
u8 month;
u16 year;
} rtc_time_t;
void max77620_rtc_get_time(rtc_time_t *time);
void max77620_rtc_stop_alarm();
#endif /* _MFD_MAX77620_RTC_H_ */