blob: f6a7a52c09f762f97dce9b918160f300c27de4aa [file] [log] [blame]
/*
* Copyright (C) 2015 Nest Labs
*
* This program 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 version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/cpufreq.h>
#ifdef CONFIG_MACH_DIAMOND3_HIGH_CPU_CLK
#define D3_MAX_CPU_CORE_CLK 792000
#else
#define D3_MAX_CPU_CORE_CLK 396000
#endif
extern void (*pm_halt_system)(void);
extern void snvs_poweroff(void);
static void reset_mcu(void)
{
int mcu_reset_gpio = -1;
struct device_node *np;
np = of_find_node_by_name(NULL, "sensor-mcu-gpios");
if(np != NULL)
{
mcu_reset_gpio = of_get_named_gpio(np, "output-gpios", 0);
}
if(gpio_is_valid(mcu_reset_gpio))
{
/* Drop down reset pin and wait for it to discharge first */
gpio_direction_output(mcu_reset_gpio, 0);
msleep(5000);
/* Toggle reset pin to reset MCU */
gpio_direction_output(mcu_reset_gpio, 1);
msleep(20);
gpio_direction_output(mcu_reset_gpio, 0);
}
}
static void diamond_halt(void)
{
/* Reset MCU first so MCU can hold down VCC main*/
/* do NOT perform pmic shut down, we'll rely on MCU to kill VCC main*/
reset_mcu();
}
static void diamond_register_pm_halt(void)
{
pm_halt_system = diamond_halt;
}
static void diamond_set_max_core_clk(void)
{
struct cpufreq_policy *policy = cpufreq_cpu_get(0);
if(policy != NULL)
{
policy->user_policy.max = D3_MAX_CPU_CORE_CLK;
cpufreq_update_policy(0);
}
}
void diamond_late_init(void)
{
diamond_register_pm_halt();
diamond_set_max_core_clk();
}
EXPORT_SYMBOL(diamond_register_pm_halt);