unplugged-kernel/drivers/misc/mediatek/pmic/common/upmu_regulator.c

814 lines
21 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#include <generated/autoconf.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/debugfs.h>
#include <linux/syscalls.h>
#include <linux/writeback.h>
#include <linux/seq_file.h>
#include <linux/suspend.h>
#include <linux/uaccess.h>
#include <mt-plat/upmu_common.h>
#include "include/pmic_regulator.h"
#include "include/regulator_codegen.h"
/*****************************************************************************
* Global variable
******************************************************************************/
/*****************************************************************************
* PMIC BUCK/LDO info for EM
******************************************************************************/
static ssize_t show_buck_ldo_info(struct device *dev,
struct device_attribute *attr,
char *buf)
{
unsigned short i;
unsigned int len = 0;
pr_info("[%s]\n", __func__);
for (i = 0; i < mt_bucks_size; i++)
len += snprintf(buf + len, PAGE_SIZE, "%s,0/1=off/on\n"
, mt_bucks[i].en_att.attr.name);
len += snprintf(buf + len, PAGE_SIZE, "SEP\n");
for (i = 0; i < mt_ldos_size; i++)
len += snprintf(buf + len, PAGE_SIZE, "%s,0/1=off/on\n"
, mt_ldos[i].en_att.attr.name);
len += snprintf(buf + len, PAGE_SIZE, "SEP\n");
for (i = 0; i < mt_bucks_size; i++)
len += snprintf(buf + len, PAGE_SIZE, "%s,mv\n"
, mt_bucks[i].voltage_att.attr.name);
len += snprintf(buf + len, PAGE_SIZE, "SEP\n");
for (i = 0; i < mt_ldos_size; i++)
len += snprintf(buf + len, PAGE_SIZE, "%s,mv\n"
, mt_ldos[i].voltage_att.attr.name);
return len;
}
/* 444 no write permission */
static DEVICE_ATTR(buck_ldo_info, 0444, show_buck_ldo_info, NULL);
/*****************************************************************************
* PMIC6355 linux reguplator driver
******************************************************************************/
#ifdef REGULATOR_TEST
unsigned int g_buck_uV;
static ssize_t show_buck_api(struct device *dev,
struct device_attribute *attr,
char *buf)
{
pr_info("[%s] 0x%x\n", __func__, g_buck_uV);
return sprintf(buf, "%u\n", g_buck_uV);
}
static ssize_t store_buck_api(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t size)
{
/*PMICLOG("[EM] Not Support Write Function\n");*/
int ret = 0;
char *pvalue = NULL, *addr = NULL, *val = NULL;
unsigned int buck_uV = 0;
unsigned int buck_type = 0;
pr_info("[%s]\n", __func__);
if (buf != NULL && size != 0) {
pr_info("[%s] buf is %s\n", __func__, buf);
/*buck_type = simple_strtoul(buf, &pvalue, 16);*/
pvalue = (char *)buf;
if (size > 5) {
addr = strsep(&pvalue, " ");
if (addr)
ret = kstrtou32(addr, 10,
(unsigned int *)&buck_type);
} else
ret = kstrtou32(pvalue, 10, (unsigned int *)&buck_type);
if (buck_type == 9999) {
pr_info("[%s] regulator_test!\n", __func__);
pmic_regulator_en_test();
#if 0
pmic_regulator_vol_test();
#endif
} else {
if (size > 5) {
val = strsep(&pvalue, " ");
if (val)
ret = kstrtou32(val, 10,
(unsigned int *)&buck_uV);
pr_info("[%s] write buck_type[%d] with voltgae %d !\n"
, __func__, buck_type, buck_uV);
/* only for regulator test*/
/* ret=buck_set_voltage(buck_type, buck_uV); */
} else {
pr_info("[%s] use \"cat pmic_access\" to get value(decimal)\r\n"
, __func__);
}
}
}
return size;
}
/*664*/
static DEVICE_ATTR(buck_api, 0664, show_buck_api, store_buck_api);
#endif /*--REGULATOR_TEST--*/
/*****************************************************************************
* PMIC extern variable
******************************************************************************/
struct platform_device mt_pmic_device = {
.name = "pmic_regulator",
.id = -1,
};
static const struct platform_device_id pmic_regulator_id[] = {
{"pmic_regulator", 0},
{},
};
static int pmic_regulator_cust_dts_parser(struct platform_device *pdev,
struct device_node *regulators)
{
struct device_node *child = NULL;
int ret = 0;
unsigned int i = 0, default_on = 0;
if (!regulators) {
PMICLOG("[PMIC]%s regulators node not found\n", __func__);
return -ENODEV;
}
for_each_child_of_node(regulators, child) {
for (i = 0; i < pmic_regulator_ldo_matches_size; i++) {
/* compare dt name & ldos name */
if (!of_node_cmp(child->name,
pmic_regulator_ldo_matches[i].name)) {
PMICLOG("[PMIC]%s regulator_matches %s\n"
, child->name
, (char *)of_get_property(child,
"regulator-name", NULL));
break;
}
}
if (i == pmic_regulator_ldo_matches_size)
continue;
/* check regualtors and set it */
if (!of_property_read_u32(child, "regulator-default-on"
, &default_on)) {
switch (default_on) {
case 0:
/* skip */
PMICLOG("[PMIC]%s regulator_skip %s\n"
, child->name
, pmic_regulator_ldo_matches[i].name);
break;
case 1:
/* turn ldo off */
(mt_ldos[i].en_cb)(0);
PMICLOG("[PMIC]%s default is off\n"
, (char *)of_get_property(child,
"regulator-name", NULL));
break;
case 2:
/* turn ldo on */
(mt_ldos[i].en_cb)(1);
PMICLOG("[PMIC]%s default is on\n"
, (char *)of_get_property(child,
"regulator-name", NULL));
break;
default:
break;
}
}
}
PMICLOG("[PMIC]%s done\n", __func__);
return ret;
}
static int pmic_regulator_buck_dts_parser(struct platform_device *pdev,
struct device_node *np)
{
struct device_node *buck_regulators = NULL;
struct regulator_config config = {};
struct regulator_dev *rdev = NULL;
struct regulation_constraints *c = NULL;
int matched, i = 0, ret = 0;
#ifdef REGULATOR_TEST
int isEn;
#endif /*--REGULATOR_TEST--*/
buck_regulators = of_get_child_by_name(np, "buck_regulators");
if (!buck_regulators) {
pr_info("[PMIC]regulators node not found\n");
return -EINVAL;
}
matched = of_regulator_match(&pdev->dev, buck_regulators,
pmic_regulator_buck_matches,
pmic_regulator_buck_matches_size);
if ((matched < 0) || (matched != mt_bucks_size)) {
pr_info("[PMIC]Error parsing regulator init data: %d %d\n",
matched, mt_bucks_size);
ret = -matched;
goto out;
}
for (i = 0; i < pmic_regulator_buck_matches_size; i++) {
if (mt_bucks[i].isUsedable != 1)
continue;
#if 1
config.dev = &(pdev->dev);
config.init_data = pmic_regulator_buck_matches[i].init_data;
config.of_node = pmic_regulator_buck_matches[i].of_node;
config.driver_data = &(mt_bucks[i]);
mt_bucks[i].desc.owner = THIS_MODULE;
rdev = regulator_register(&mt_bucks[i].desc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
pr_notice("[regulator_register] failed to register %s (%d)\n"
, mt_bucks[i].desc.name, ret);
continue;
} else
PMICLOG("[regulator_register] pass %s\n"
, mt_bucks[i].desc.name);
c = rdev->constraints;
c->valid_ops_mask |= mt_bucks[i].constraints.valid_ops_mask;
c->valid_modes_mask |= mt_bucks[i].constraints.valid_modes_mask;
#else
mt_bucks[i].config.dev = &(pdev->dev);
mt_bucks[i].config.init_data =
pmic_regulator_buck_matches[i].init_data;
mt_bucks[i].config.of_node =
pmic_regulator_buck_matches[i].of_node;
mt_bucks[i].config.driver_data =
pmic_regulator_buck_matches[i].driver_data;
mt_bucks[i].desc.owner = THIS_MODULE;
mt_bucks[i].rdev =
regulator_register(&mt_bucks[i].desc,
&mt_bucks[i].config);
if (IS_ERR(mt_bucks[i].rdev)) {
ret = PTR_ERR(mt_bucks[i].rdev);
pr_notice("[regulator_register] failed to register %s (%d)\n"
, mt_bucks[i].desc.name, ret);
continue;
} else
PMICLOG("[regulator_register] pass %s\n"
, mt_bucks[i].desc.name);
#endif
#ifdef REGULATOR_TEST
mt_bucks[i].reg = regulator_get(&(pdev->dev)
, mt_bucks[i].desc.name);
isEn = regulator_is_enabled(mt_bucks[i].reg);
if (isEn != 0)
PMICLOG("[regulator] %s is default on\n"
, mt_bucks[i].desc.name);
#endif /*--REGULATOR_TEST--*/
}
out:
of_node_put(buck_regulators);
return ret;
}
static int pmic_regulator_ldo_dts_parser(struct platform_device *pdev,
struct device_node *np)
{
struct device_node *ldo_regulators = NULL;
struct regulator_config config = {};
struct regulator_dev *rdev = NULL;
int matched, i = 0, ret = 0;
#ifdef REGULATOR_TEST
int isEn;
#endif /*--REGULATOR_TEST--*/
ldo_regulators = of_get_child_by_name(np, "ldo_regulators");
if (!ldo_regulators) {
pr_info("[PMIC]regulators node not found\n");
return -EINVAL;
}
matched = of_regulator_match(&pdev->dev, ldo_regulators,
pmic_regulator_ldo_matches,
pmic_regulator_ldo_matches_size);
if ((matched < 0) || (matched != mt_ldos_size)) {
pr_info("[PMIC]Error parsing regulator init data: %d %d\n",
matched, mt_ldos_size);
ret = -matched;
goto out;
}
for (i = 0; i < pmic_regulator_ldo_matches_size; i++) {
if (mt_ldos[i].isUsedable != 1)
continue;
#if 1
config.dev = &(pdev->dev);
config.init_data = pmic_regulator_ldo_matches[i].init_data;
config.of_node = pmic_regulator_ldo_matches[i].of_node;
config.driver_data = pmic_regulator_ldo_matches[i].driver_data;
mt_ldos[i].desc.owner = THIS_MODULE;
rdev = regulator_register(&mt_ldos[i].desc, &config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
pr_notice("[regulator_register] failed to register %s (%d)\n"
, mt_ldos[i].desc.name, ret);
continue;
} else {
PMICLOG("[regulator_register] pass %s\n"
, mt_ldos[i].desc.name);
}
#else
mt_ldos[i].config.dev = &(pdev->dev);
mt_ldos[i].config.init_data =
pmic_regulator_ldo_matches[i].init_data;
mt_ldos[i].config.of_node =
pmic_regulator_ldo_matches[i].of_node;
mt_ldos[i].config.driver_data =
pmic_regulator_ldo_matches[i].driver_data;
mt_ldos[i].desc.owner = THIS_MODULE;
mt_ldos[i].rdev =
regulator_register(&mt_ldos[i].desc,
&mt_ldos[i].config);
if (IS_ERR(mt_ldos[i].rdev)) {
ret = PTR_ERR(mt_ldos[i].rdev);
pr_notice("[regulator_register] failed to register %s (%d)\n"
, mt_ldos[i].desc.name, ret);
continue;
} else {
PMICLOG("[regulator_register] pass %s\n"
, mt_ldos[i].desc.name);
}
#endif
#ifdef REGULATOR_TEST
mt_ldos[i].reg = regulator_get(&(pdev->dev),
mt_ldos[i].desc.name);
isEn = regulator_is_enabled(mt_ldos[i].reg);
if (isEn != 0)
PMICLOG("[regulator] %s is default on\n"
, mt_ldos[i].desc.name);
#endif /*--REGULATOR_TEST--*/
/* To initialize varriables which were used to record status, */
/* if ldo regulator have been modified by user. */
/* mt_ldos[i].vosel.ldo_user = mt_ldos[i].rdev->use_count; */
if (mt_ldos[i].da_vol_cb != NULL)
mt_ldos[i].vosel.def_sel = (mt_ldos[i].da_vol_cb)();
mt_ldos[i].vosel.cur_sel = mt_ldos[i].vosel.def_sel;
}
/*--for ldo customization--*/
ret = pmic_regulator_cust_dts_parser(pdev, ldo_regulators);
if (ret) {
pr_info("pmic_regulator_cust_dts_parser fail\n");
ret = -EINVAL;
goto out;
}
out:
of_node_put(ldo_regulators);
return ret;
}
static int pmic_regulator_init(struct platform_device *pdev)
{
struct device_node *np;
int ret = 0;
np = pdev->dev.of_node;
if (!np) {
pr_info("%s np = NULL\n", __func__);
return -EINVAL;
}
ret = pmic_regulator_buck_dts_parser(pdev, np);
if (ret) {
pr_info("pmic_regulator_buck_dts_parser fail\n");
ret = -EINVAL;
goto out;
}
ret = pmic_regulator_ldo_dts_parser(pdev, np);
if (ret) {
pr_info("pmic_regulator_ldo_dts_parser fail\n");
ret = -EINVAL;
goto out;
}
out:
of_node_put(np);
return ret;
}
void pmic_regulator_suspend(void)
{
int i;
for (i = 0; i < mt_ldos_size; i++) {
if (mt_ldos[i].isUsedable == 1) {
if (mt_ldos[i].da_vol_cb != NULL) {
mt_ldos[i].vosel.cur_sel =
(mt_ldos[i].da_vol_cb)();
if (mt_ldos[i].vosel.cur_sel !=
mt_ldos[i].vosel.def_sel) {
mt_ldos[i].vosel.restore = true;
pr_info("%s(name=%s id=%d default_sel=%d current_sel=%d)\n"
, __func__
, mt_ldos[i].rdev->desc->name
, mt_ldos[i].rdev->desc->id
, mt_ldos[i].vosel.def_sel
, mt_ldos[i].vosel.cur_sel);
} else
mt_ldos[i].vosel.restore = false;
}
}
}
}
void pmic_regulator_resume(void)
{
int i, selector;
for (i = 0; i < mt_ldos_size; i++) {
if (mt_ldos[i].isUsedable == 1) {
if (mt_ldos[i].vol_cb != NULL) {
if (mt_ldos[i].vosel.restore == true) {
/*-- regulator voltage changed? --*/
selector = mt_ldos[i].vosel.cur_sel;
(mt_ldos[i].vol_cb)(selector);
pr_info("%s(name=%s id=%d default_sel=%d current_sel=%d)\n"
, __func__
, mt_ldos[i].rdev->desc->name
, mt_ldos[i].rdev->desc->id
, mt_ldos[i].vosel.def_sel
, mt_ldos[i].vosel.cur_sel);
}
}
}
}
}
static int pmic_regulator_pm_event(struct notifier_block *notifier,
unsigned long pm_event,
void *unused)
{
switch (pm_event) {
case PM_HIBERNATION_PREPARE: /* Going to hibernate */
pr_info("[%s] pm_event %lu (IPOH)\n", __func__, pm_event);
return NOTIFY_DONE;
case PM_POST_HIBERNATION: /* Hibernation finished */
pr_info("[%s] pm_event %lu\n", __func__, pm_event);
pmic_regulator_resume();
return NOTIFY_DONE;
}
return NOTIFY_OK;
}
static struct notifier_block pmic_regulator_pm_notifier_block = {
.notifier_call = pmic_regulator_pm_event,
.priority = 0,
};
int mtk_regulator_init(struct platform_device *dev)
{
int ret = 0;
#ifdef CONFIG_OF
pmic_regulator_init(dev);
#endif
ret = register_pm_notifier(&pmic_regulator_pm_notifier_block);
if (ret) {
PMICLOG("****failed to register PM notifier %d\n", ret);
return ret;
}
return ret;
}
#ifdef REGULATOR_TEST
void pmic_regulator_en_test(void)
{
int i = 0;
int ret1 = 0, ret2 = 0;
struct regulator *reg = NULL;
/*for (i = 0; i < ARRAY_SIZE(mt_ldos); i++) {*/
for (i = 0; i < mt_ldos_size; i++) {
if (mt_ldos[i].isUsedable != 1)
continue;
/*---VIO18 should not be off---*/
if (strcmp("va09", mt_ldos[i].desc.name) != 0)
continue;
reg = mt_ldos[i].reg;
pr_info("[regulator enable test] %s\n", mt_ldos[i].desc.name);
ret1 = regulator_enable(reg);
ret2 = regulator_is_enabled(reg);
if (ret2 == (mt_ldos[i].da_en_cb()))
pr_info("[enable test pass]\n");
else
pr_info("[enable test fail]\n");
ret1 = regulator_disable(reg);
ret2 = regulator_is_enabled(reg);
if (ret2 == (mt_ldos[i].da_en_cb()))
pr_info("[disable test pass]\n");
else
pr_info("[disable test fail]\n");
}
}
void pmic_regulator_vol_test(void)
{
int i = 0, j = 0;
struct regulator *reg = NULL;
const int *pVoltage = NULL;
const int *idxs = NULL;
int rvoltage = 0;
for (i = 0; i < mt_ldos_size; i++) {
reg = mt_ldos[i].reg;
if (mt_ldos[i].isUsedable != 1)
continue;
pr_info("[regulator voltage test] %s n_voltages:%d\n",
mt_ldos[i].desc.name, mt_ldos[i].desc.n_voltages);
if (mt_ldos[i].pvoltages == NULL)
continue;
pVoltage = mt_ldos[i].pvoltages;
idxs = mt_ldos[i].idxs;
for (j = 0; j < mt_ldos[i].desc.n_voltages; j++) {
regulator_set_voltage(reg, pVoltage[j], pVoltage[j]);
rvoltage = regulator_get_voltage(reg);
if (idxs[j] == mt_ldos[i].da_vol_cb() &&
(pVoltage[j] == rvoltage)) {
pr_info("[%d]:pass set_voltage:%d rvoltage:%d\n"
, idxs[j]
, pVoltage[j]
, rvoltage);
} else {
pr_info("[%d:%d]:fail set_voltage:%d rvoltage:%d\n"
, idxs[j]
, mt_ldos[i].da_vol_cb()
, pVoltage[j]
, rvoltage);
}
}
}
}
#endif /*--REGULATOR_TEST--*/
/*****************************************************************************
* Dump all LDO status
******************************************************************************/
void dump_ldo_status_read_debug(void)
{
int i = 0, j = 0;
int en = 0, ret = 0;
int voltage_reg = 0;
int voltage = 0;
const int *pVoltage = NULL, *pVoltidx = NULL;
pr_debug("********** BUCK/LDO status dump [1:ON,0:OFF]**********\n");
/*for (i = 0; i < ARRAY_SIZE(mtk_bucks); i++) {*/
for (i = 0; i < mt_bucks_size; i++) {
if (mt_bucks[i].da_en_cb != NULL)
en = (mt_bucks[i].da_en_cb)();
else
en = -1;
if (mt_bucks[i].da_vol_cb != NULL) {
voltage_reg = (mt_bucks[i].da_vol_cb)();
voltage = mt_bucks[i].desc.min_uV +
mt_bucks[i].desc.uV_step * voltage_reg;
} else {
voltage_reg = -1;
voltage = -1;
}
pr_info("%s status:%d voltage:%duv voltage_reg:%d\n",
mt_bucks[i].desc.name, en, voltage, voltage_reg);
}
/*for (i = 0; i < ARRAY_SIZE(mt_ldos); i++) {*/
for (i = 0; i < mt_ldos_size; i++) {
if (mt_ldos[i].da_en_cb != NULL)
en = (mt_ldos[i].da_en_cb)();
else
en = -1;
if (mt_ldos[i].desc.n_voltages != 1) {
if (mt_ldos[i].da_vol_cb != NULL) {
voltage_reg = (mt_ldos[i].da_vol_cb)();
if (mt_ldos[i].pvoltages != NULL) {
pVoltage = (const int *)
mt_ldos[i].pvoltages;
pVoltidx = (const int *)
mt_ldos[i].idxs;
/*HW LDO sequence issue, we need to change it */
for (j = 0;
j < mt_ldos[i].desc.n_voltages;
j++) {
if (pVoltidx[j] == voltage_reg) {
ret = j;
break;
}
}
voltage = pVoltage[ret];
} else {
voltage =
mt_ldos[i].desc.min_uV +
mt_ldos[i].desc.uV_step *
voltage_reg;
}
} else {
voltage_reg = -1;
voltage = -1;
}
} else
voltage = mt_ldos[i].desc.fixed_uV;
pr_info("%s status:%d voltage:%duv voltage_reg:%d\n",
mt_ldos[i].desc.name, en, voltage, voltage_reg);
}
}
static int proc_utilization_show(struct seq_file *m, void *v)
{
int i = 0, j = 0;
int en = 0, ret = 0;
int voltage_reg = 0;
int voltage = 0;
const int *pVoltage = NULL, *pVoltidx = NULL;
seq_puts(m, "********** BUCK/LDO status dump [1:ON,0:OFF]**********\n");
/*for (i = 0; i < ARRAY_SIZE(mtk_bucks); i++) {*/
for (i = 0; i < mt_bucks_size; i++) {
if (mt_bucks[i].da_en_cb != NULL)
en = (mt_bucks[i].da_en_cb)();
else
en = -1;
if (mt_bucks[i].da_vol_cb != NULL) {
voltage_reg = (mt_bucks[i].da_vol_cb)();
voltage = mt_bucks[i].desc.min_uV +
mt_bucks[i].desc.uV_step *
voltage_reg;
} else {
voltage_reg = -1;
voltage = -1;
}
seq_printf(m, "%s status:%d voltage:%duv voltage_reg:%d\n"
, mt_bucks[i].desc.name
, en, voltage, voltage_reg);
}
/*for (i = 0; i < ARRAY_SIZE(mt_ldos); i++) {*/
for (i = 0; i < mt_ldos_size; i++) {
if (mt_ldos[i].da_en_cb != NULL)
en = (mt_ldos[i].da_en_cb)();
else
en = -1;
if (mt_ldos[i].desc.n_voltages != 1) {
if (mt_ldos[i].da_vol_cb != NULL) {
voltage_reg = (mt_ldos[i].da_vol_cb)();
if (mt_ldos[i].pvoltages != NULL) {
pVoltage = (const int *)
mt_ldos[i].pvoltages;
pVoltidx = (const int *)
mt_ldos[i].idxs;
/*HW LDO sequence issue, we need to change it */
for (j = 0;
j < mt_ldos[i].desc.n_voltages; j++) {
if (pVoltidx[j] == voltage_reg) {
ret = j;
break;
}
}
voltage = pVoltage[ret];
} else {
voltage =
mt_ldos[i].desc.min_uV +
mt_ldos[i].desc.uV_step *
voltage_reg;
}
} else {
voltage_reg = -1;
voltage = -1;
}
} else {
voltage = mt_ldos[i].desc.fixed_uV;
voltage_reg = -1;
}
seq_printf(m, "%s status:%d voltage:%duv voltage_reg:%d\n"
, mt_ldos[i].desc.name, en, voltage, voltage_reg);
}
return 0;
}
static int proc_utilization_open(struct inode *inode, struct file *file)
{
return single_open(file, proc_utilization_show, NULL);
}
static const struct file_operations pmic_debug_proc_fops = {
.open = proc_utilization_open,
.read = seq_read,
};
void pmic_regulator_debug_init(struct platform_device *dev,
struct dentry *debug_dir)
{
/* /sys/class/regulator/.../ */
int ret_device_file = 0, i;
struct dentry *mt_pmic_dir = debug_dir;
#ifdef REGULATOR_TEST
ret_device_file = device_create_file(&(dev->dev), &dev_attr_buck_api);
#endif /*--REGULATOR_TEST--*/
/* /sys/class/regulator/.../ */
/*EM BUCK voltage & Status*/
for (i = 0; i < mt_bucks_size; i++) {
/*PMICLOG("[PMIC] register buck id=%d\n",i);*/
if (*(int *)(&mt_bucks[i].en_att)) {
PMICLOG("[PMIC] register ldo en_att\n");
ret_device_file = device_create_file(&(dev->dev),
&(mt_bucks[i].en_att));
}
if (*(int *)(&mt_bucks[i].voltage_att)) {
PMICLOG("[PMIC] register ldo voltage_att\n");
ret_device_file = device_create_file(&(dev->dev),
&(mt_bucks[i].voltage_att));
}
}
/*ret_device_file = device_create_file(&(dev->dev),
*&mtk_bucks_class[i].voltage_att);
*/
/*EM ldo voltage & Status*/
for (i = 0; i < mt_ldos_size; i++) {
/*PMICLOG("[PMIC] register ldo id=%d\n",i);*/
if (*(int *)(&mt_ldos[i].en_att)) {
PMICLOG("[PMIC] register ldo en_att\n");
ret_device_file = device_create_file(&(dev->dev),
&mt_ldos[i].en_att);
}
if (*(int *)(&mt_ldos[i].voltage_att)) {
PMICLOG("[PMIC] register ldo voltage_att\n");
ret_device_file = device_create_file(&(dev->dev),
&mt_ldos[i].voltage_att);
}
}
ret_device_file = device_create_file(&(dev->dev),
&dev_attr_buck_ldo_info);
debugfs_create_file("dump_ldo_status", 0644,
mt_pmic_dir, NULL, &pmic_debug_proc_fops);
PMICLOG("proc_create pmic_debug_proc_fops\n");
}
MODULE_AUTHOR("Jimmy-YJ Huang");
MODULE_DESCRIPTION("MT PMIC REGULATOR Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0.0_M");