sdk-hwV1.3/lichee/brandy-2.0/u-boot-2018/drivers/sunxi_power/pmu.c

159 lines
3.8 KiB
C

/*
* Copyright (C) 2019 Allwinner.
* weidonghui <weidonghui@allwinnertech.com>
*
* SUNXI AXP Driver
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <sunxi_power/axp.h>
#include <asm/arch/pmic_bus.h>
#ifdef AXP_DEBUG
#define axp_err(fmt...) tick_printf("[axp][err]: " fmt)
#else
#define axp_err(fmt...)
#endif
__attribute__((section(".data"))) static struct sunxi_pmu_dev_t *sunxi_pmu_dev =
NULL;
/* traverse the u-boot segment to find the pmu offset*/
static struct sunxi_pmu_dev_t *pmu_get_axp_dev_t(void)
{
struct sunxi_pmu_dev_t *sunxi_pmu_dev_temp;
struct sunxi_pmu_dev_t *sunxi_pmu_dev_start =
ll_entry_start(struct sunxi_pmu_dev_t, pmu);
int max = ll_entry_count(struct sunxi_pmu_dev_t, pmu);
for (sunxi_pmu_dev_temp = sunxi_pmu_dev_start;
sunxi_pmu_dev_temp != sunxi_pmu_dev_start + max;
sunxi_pmu_dev_temp++) {
if (!strncmp("pmu", sunxi_pmu_dev_temp->pmu_name, 3)) {
if (!sunxi_pmu_dev_temp->probe()) {
pr_msg("PMU: %s found\n",
sunxi_pmu_dev_temp->pmu_name);
return sunxi_pmu_dev_temp;
}
}
}
pr_msg("PMU: no found\n");
return NULL;
}
/* matches chipid*/
int pmu_probe(void)
{
sunxi_pmu_dev = pmu_get_axp_dev_t();
if (sunxi_pmu_dev == NULL)
return -1;
return 0;
}
/*get axp info*/
int pmu_get_info(char *name, unsigned char *chipid)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->get_info))
return sunxi_pmu_dev->get_info(name, chipid);
axp_err("not imple:%s\n", __func__);
*name = 0;
*chipid = 0;
return -1;
}
/*Set a certain power, voltage value. */
int pmu_set_voltage(char *name, uint vol_value, uint onoff)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->set_voltage))
return sunxi_pmu_dev->set_voltage(name, vol_value, onoff);
axp_err("not imple:%s\n", __func__);
return -1;
}
/*Read a certain power, voltage value */
int pmu_get_voltage(char *name)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->get_voltage))
return sunxi_pmu_dev->get_voltage(name);
axp_err("not imple:%s\n", __func__);
return -1;
}
/*Set shutdown*/
int pmu_set_power_off(void)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->set_power_off))
return sunxi_pmu_dev->set_power_off();
axp_err("not imple:%s\n", __func__);
return -1;
}
/*Sets the state of the next mode */
int pmu_set_sys_mode(int status)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->set_sys_mode))
return sunxi_pmu_dev->set_sys_mode(status);
axp_err("not imple:%s\n", __func__);
return -1;
}
/*Force DCDC in pwm mode or not */
int pmu_set_dcdc_mode(const char *name, int mode)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->set_dcdc_mode))
return sunxi_pmu_dev->set_dcdc_mode(name, mode);
axp_err("not imple:%s\n", __func__);
return -1;
}
/*Get the current mode*/
int pmu_get_sys_mode(void)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->get_sys_mode))
return sunxi_pmu_dev->get_sys_mode();
axp_err("not imple:%s\n", __func__);
return -1;
}
/*Get the button length interrupt*/
int pmu_get_key_irq(void)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->get_key_irq))
return sunxi_pmu_dev->get_key_irq();
axp_err("not imple:%s\n", __func__);
return -1;
}
/*Set limit total voltage*/
int pmu_set_bus_vol_limit(int vol_value)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->set_bus_vol_limit))
return sunxi_pmu_dev->set_bus_vol_limit(vol_value);
axp_err("not imple:%s\n", __func__);
return -1;
}
/*get register value*/
unsigned char pmu_get_reg_value(unsigned char reg_addr)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->get_reg_value))
return sunxi_pmu_dev->get_reg_value(reg_addr);
axp_err("not imple:%s\n", __func__);
return -1;
}
/*set register value*/
unsigned char pmu_set_reg_value(unsigned char reg_addr, unsigned char reg_value)
{
if ((sunxi_pmu_dev) && (sunxi_pmu_dev->set_reg_value))
return sunxi_pmu_dev->set_reg_value(reg_addr, reg_value);
axp_err("not imple:%s\n", __func__);
return -1;
}