oleavr-rgl-a500-mini-linux-.../drivers/power/axp_power/axpdummy/axpdummy.c
Ole André Vadla Ravnås 169c65d57e Initial commit
2022-05-07 01:01:45 +02:00

201 lines
4.3 KiB
C

#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/of_irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/mfd/core.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/err.h>
#include <linux/power/aw_pm.h>
#include "../axp-core.h"
static struct axp_dev *axpdummy_pm_power;
struct axp_config_info axpdummy_config;
static int axpdummy_pmu_num;
static struct mfd_cell axpdummy_cells[] = {
{
.name = "axpdummy-regulator",
},
};
void axpdummy_power_off(void)
{
return;
}
static s32 axpdummy_usb_det(void)
{
return 0;
}
static s32 axpdummy_usb_vbus_output(int high)
{
return 0;
}
static int axpdummy_cfg_pmux_para(int num, struct aw_pm_info *api, int *pmu_id)
{
char name[8];
struct device_node *np;
sprintf(name, "pmu%d", num);
np = of_find_node_by_type(NULL, name);
if (NULL == np) {
pr_err("can not find device_type for %s\n", name);
return -1;
}
if (!of_device_is_available(np)) {
pr_err("can not find node for %s\n", name);
return -1;
}
api->pmu_arg.twi_port = 0;
api->pmu_arg.dev_addr = 0x34;
*pmu_id = axpdummy_config.pmu_id;
return 0;
}
static const char *axpdummy_get_pmu_name(void)
{
return axp_name[axpdummy_pmu_num];
}
static struct axp_dev *axpdummy_get_pmu_dev(void)
{
return axpdummy_pm_power;
}
struct axp_platform_ops axpdummy_platform_ops = {
.usb_det = axpdummy_usb_det,
.usb_vbus_output = axpdummy_usb_vbus_output,
.cfg_pmux_para = axpdummy_cfg_pmux_para,
.get_pmu_name = axpdummy_get_pmu_name,
.get_pmu_dev = axpdummy_get_pmu_dev,
.regulator_name = {"axpdummy-regulator"},
};
static const struct of_device_id axpdummy_dt_ids[] = {
{ .compatible = "axpdummy", },
{},
};
MODULE_DEVICE_TABLE(of, axpdummy_dt_ids);
static int axpdummy_probe(struct platform_device *pdev)
{
int ret;
struct axp_dev *axpdummy;
struct device_node *node = pdev->dev.of_node;
axpdummy_pmu_num = axp_get_pmu_num(axpdummy_dt_ids,
ARRAY_SIZE(axpdummy_dt_ids));
if (axpdummy_pmu_num < 0) {
pr_err("%s get pmu num failed\n", __func__);
return axpdummy_pmu_num;
}
if (node) {
/* get dt and sysconfig */
if (!of_device_is_available(node)) {
axpdummy_config.pmu_used = 0;
pr_err("%s: pmu_used = %u\n", __func__,
axpdummy_config.pmu_used);
return -EPERM;
} else {
axpdummy_config.pmu_used = 1;
ret = axp_dt_parse(node, axpdummy_pmu_num,
&axpdummy_config);
if (ret) {
pr_err("%s parse device tree err\n", __func__);
return -EINVAL;
}
}
} else {
pr_err("AXPDUMMY device tree err!\n");
return -EBUSY;
}
axpdummy = devm_kzalloc(&pdev->dev, sizeof(*axpdummy), GFP_KERNEL);
if (!axpdummy)
return -ENOMEM;
axpdummy->dev = &pdev->dev;
axpdummy->nr_cells = ARRAY_SIZE(axpdummy_cells);
axpdummy->cells = axpdummy_cells;
axpdummy->pmu_num = axpdummy_pmu_num;
ret = axp_mfd_cell_name_init(&axpdummy_platform_ops,
ARRAY_SIZE(axpdummy_dt_ids), axpdummy->pmu_num,
axpdummy->nr_cells, axpdummy->cells);
if (ret)
return ret;
platform_set_drvdata(pdev, axpdummy);
ret = axp_mfd_add_devices(axpdummy);
if (ret)
goto fail_init;
axpdummy->is_dummy = true;
axpdummy_pm_power = axpdummy;
if (!pm_power_off)
pm_power_off = axpdummy_power_off;
axp_platform_ops_set(axpdummy->pmu_num, &axpdummy_platform_ops);
return 0;
fail_init:
dev_err(axpdummy->dev, "failed to add MFD devices: %d\n", ret);
return ret;
}
static int axpdummy_remove(struct platform_device *pdev)
{
struct axp_dev *axpdummy = platform_get_drvdata(pdev);
if (axpdummy == axpdummy_pm_power) {
axpdummy_pm_power = NULL;
pm_power_off = NULL;
}
axp_mfd_remove_devices(axpdummy);
return 0;
}
static struct platform_driver axpdummy_driver = {
.driver = {
.name = "axpdummy",
.owner = THIS_MODULE,
.of_match_table = axpdummy_dt_ids,
},
.probe = axpdummy_probe,
.remove = axpdummy_remove,
};
static int __init axpdummy_init(void)
{
int ret;
ret = platform_driver_register(&axpdummy_driver);
if (ret != 0)
pr_err("Failed to register axpdummy driver: %d\n", ret);
return ret;
}
subsys_initcall(axpdummy_init);
static void __exit axpdummy_exit(void)
{
platform_driver_unregister(&axpdummy_driver);
}
module_exit(axpdummy_exit);
MODULE_DESCRIPTION("PMIC Driver for AXPDUMMY");
MODULE_AUTHOR("<pannan@allwinnertech.com>");
MODULE_LICENSE("GPL");