mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
regulator: max77851: add max77851 regulator driver
Bug 200749982 Change-Id: I8bbc914b7aa93058e4ec116fb3eb5b6d3eb74606 Signed-off-by: Shubhi Garg <shgarg@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.10/+/2595372 Signed-off-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2946283 GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
3006e5b42f
commit
0acac0ee77
@@ -0,0 +1,239 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/regulator/regulator-max77851.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: MAX77851 Power management IC Regulator
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Joan Na<Joan.na@maximintegrated.com>
|
||||||
|
- Shubhi Garg <shgarg@nvidia.com>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Regulator DT binding for MAX77851 Power management IC from Maxim Semiconductor.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
maxim,out-voltage-range:
|
||||||
|
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||||
|
description:
|
||||||
|
Output Voltage Range
|
||||||
|
enabled/disabled when system is in active state.
|
||||||
|
Valid values are:
|
||||||
|
- MAX77620_FPS_SRC_0,
|
||||||
|
FPS source is FPS0.
|
||||||
|
- MAX77620_FPS_SRC_1,
|
||||||
|
FPS source is FPS1
|
||||||
|
- MAX77620_FPS_SRC_2 and
|
||||||
|
FPS source is FPS2
|
||||||
|
- MAX77620_FPS_SRC_NONE.
|
||||||
|
Regulator is not controlled
|
||||||
|
by FPS events and it gets
|
||||||
|
enabled/disabled by register
|
||||||
|
access.
|
||||||
|
Absence of this property will leave
|
||||||
|
the FPS configuration register for that
|
||||||
|
regulator to default configuration.
|
||||||
|
|
||||||
|
maxim,fps-user-setting-enable:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
using default setting (OTP/SHADOW)
|
||||||
|
|
||||||
|
maxim,regulator-dvs-mode-enable:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/flag
|
||||||
|
DVS Mode Enable
|
||||||
|
the regulator get disabled when master
|
||||||
|
FPS input event set to LOW.
|
||||||
|
Valid values are 0 to 7.
|
||||||
|
This is applicable if FPS source is
|
||||||
|
selected as FPS0, FPS1 or FPS2.
|
||||||
|
|
||||||
|
maxim,regulator-dvs-voltage:
|
||||||
|
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||||
|
VOUT0/VOUT1 Voltage array
|
||||||
|
|
||||||
|
maxim,pu-slot:
|
||||||
|
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||||
|
FPS Power-Up Slot
|
||||||
|
Valid values are 0 to F.
|
||||||
|
|
||||||
|
maxim,pd-slot:
|
||||||
|
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||||
|
FPS Power-Down Slot
|
||||||
|
Valid values are 0 to F.
|
||||||
|
|
||||||
|
maxim,slpx-slot:
|
||||||
|
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||||
|
FPS Sleep Exit Slot
|
||||||
|
Valid values are 0 to F.
|
||||||
|
|
||||||
|
maxim,slpy-slot:
|
||||||
|
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||||
|
FPS Sleep Enter Slot
|
||||||
|
Valid values are 0 to F.
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/mfd/max77851.h>
|
||||||
|
...
|
||||||
|
max77851: max77851@3c {
|
||||||
|
regulators {
|
||||||
|
|
||||||
|
max77851_ldo0: ldo0 {
|
||||||
|
...
|
||||||
|
|
||||||
|
#maxim,fps-default-enable;
|
||||||
|
maxim,fps-user-setting-enable;
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_1>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_1>;
|
||||||
|
maxim,pu-slot = <MAX77851_FPS_SLOT_5>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_7>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_ldo1: ldo1 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,fps-user-setting-enable;
|
||||||
|
|
||||||
|
maxim,regulator-dvs-mode-enable;
|
||||||
|
/*
|
||||||
|
* 0x38(56h) : 0.75V
|
||||||
|
* 0x30(48h) : 0.70V
|
||||||
|
*/
|
||||||
|
maxim,regulator-dvs-voltage = <0x38>, <0x30>;
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_2>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_2>;
|
||||||
|
maxim,pu-slot = <MAX77851_FPS_SLOT_1>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_ldo2: ldo2 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,fps-user-setting-enable;
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_1>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_1>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_8>;
|
||||||
|
maxim,slpx-slot = <MAX77851_FPS_SLOT_2>;
|
||||||
|
maxim,slpy-slot = <MAX77851_FPS_SLOT_5>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_ldo3: ldo3 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,fps-user-setting-enable;
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_1>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_1>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_8>;
|
||||||
|
maxim,slpx-slot = <MAX77851_FPS_SLOT_2>;
|
||||||
|
maxim,slpy-slot = <MAX77851_FPS_SLOT_5>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_ldo4: ldo4 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_0>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_0>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_8>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_ldo5: ldo5 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_0>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_0>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_8>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_ldo6: ldo6 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_0>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_0>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_8>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_buck0: buck0 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,fps-user-setting-enable;
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_3>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_3>;
|
||||||
|
maxim,pu-slot = <MAX77851_FPS_SLOT_6>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_6>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_buck1: buck1 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,fps-user-setting-enable;
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_3>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_3>;
|
||||||
|
maxim,pu-slot = <MAX77851_FPS_SLOT_6>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_6>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_buck2: buck2 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,fps-user-setting-enable;
|
||||||
|
|
||||||
|
maxim,regulator-dvs-mode-enable;
|
||||||
|
/*
|
||||||
|
* 0x50(80h) : 0.50V
|
||||||
|
* 0x3C(60h) : 0.45V
|
||||||
|
*/
|
||||||
|
maxim,regulator-dvs-voltage = <0x50>, <0x3C>;
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_LOW>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_1>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_1>;
|
||||||
|
maxim,pu-slot = <MAX77851_FPS_SLOT_7>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_7>;
|
||||||
|
|
||||||
|
maxim,slpx-slot = <MAX77851_FPS_SLOT_3>;
|
||||||
|
maxim,slpy-slot = <MAX77851_FPS_SLOT_3>;
|
||||||
|
};
|
||||||
|
|
||||||
|
max77851_buck3: buck3 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,fps-user-setting-enable;
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_MID>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_3>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_3>;
|
||||||
|
maxim,pu-slot = <MAX77851_FPS_SLOT_0>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_2>;
|
||||||
|
};
|
||||||
|
max77851_buck4: buck4 {
|
||||||
|
...
|
||||||
|
|
||||||
|
maxim,fps-user-setting-enable;
|
||||||
|
|
||||||
|
maxim,out-voltage-range = <MAX77851_VOUT_RNG_MID>;
|
||||||
|
maxim,pu-slpx-master-slot = <MAX77851_FPS_MASTER_SLOT_3>;
|
||||||
|
maxim,pd-slpy-master-slot = <MAX77851_FPS_MASTER_SLOT_3>;
|
||||||
|
maxim,pu-slot = <MAX77851_FPS_SLOT_2>;
|
||||||
|
maxim,pd-slot = <MAX77851_FPS_SLOT_3>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
...
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
# Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
|
# SPDX-FileCopyrightText: Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved.
|
||||||
|
|
||||||
LINUXINCLUDE += -I$(srctree.nvidia-oot)/include
|
LINUXINCLUDE += -I$(srctree.nvidia-oot)/include
|
||||||
LINUXINCLUDE += -I$(srctree.nvidia-oot)/drivers/gpu/host1x/hw/
|
LINUXINCLUDE += -I$(srctree.nvidia-oot)/drivers/gpu/host1x/hw/
|
||||||
@@ -52,6 +52,7 @@ obj-m += pinctrl/
|
|||||||
obj-m += platform/tegra/
|
obj-m += platform/tegra/
|
||||||
obj-m += pwm/
|
obj-m += pwm/
|
||||||
obj-m += ras/
|
obj-m += ras/
|
||||||
|
obj-m += regulator/
|
||||||
obj-m += rtc/
|
obj-m += rtc/
|
||||||
obj-m += cpuidle/
|
obj-m += cpuidle/
|
||||||
ifdef CONFIG_SCSI
|
ifdef CONFIG_SCSI
|
||||||
|
|||||||
8
drivers/regulator/Makefile
Normal file
8
drivers/regulator/Makefile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
#
|
||||||
|
# Makefile for regulator drivers.
|
||||||
|
#
|
||||||
|
|
||||||
|
obj-m += max77851-regulator.o
|
||||||
|
|
||||||
842
drivers/regulator/max77851-regulator.c
Normal file
842
drivers/regulator/max77851-regulator.c
Normal file
@@ -0,0 +1,842 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
/*
|
||||||
|
* Maxim MAX77851 Regulator driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/mfd/max77851.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/regulator/driver.h>
|
||||||
|
#include <linux/regulator/machine.h>
|
||||||
|
#include <linux/regulator/of_regulator.h>
|
||||||
|
|
||||||
|
#define max77851_rails(_name) "max77851-"#_name
|
||||||
|
|
||||||
|
#define IS_BUCK(type) (type == MAX77851_REGULATOR_TYPE_BUCK)
|
||||||
|
#define IS_NLDO(type) (type == MAX77851_REGULATOR_TYPE_LDO_N)
|
||||||
|
#define IS_PLDO(type) (type == MAX77851_REGULATOR_TYPE_LDO_P)
|
||||||
|
|
||||||
|
/* Power Mode */
|
||||||
|
#define MAX77851_POWER_MODE_NORMAL BIT_IS_ZERO
|
||||||
|
#define MAX77851_POWER_MODE_LPM BIT(1)
|
||||||
|
|
||||||
|
#define MAX77851_POWER_MODE_MASK BIT(1)
|
||||||
|
|
||||||
|
/* SD Slew Rate */
|
||||||
|
#define MAX77851_SD_SR_13_75 0
|
||||||
|
#define MAX77851_SD_SR_27_5 1
|
||||||
|
#define MAX77851_SD_SR_55 2
|
||||||
|
#define MAX77851_SD_SR_100 3
|
||||||
|
|
||||||
|
/* FPS ENABLE / DISABLE */
|
||||||
|
#define MAX77851_FPS_MODE_DISABLE 0
|
||||||
|
#define MAX77851_FPS_MODE_ENABLE 1
|
||||||
|
|
||||||
|
#define MAX77851_DVS_VOLTAGE_NUM 2
|
||||||
|
|
||||||
|
#define MAX77851_BUCK_RAMP_DELAY 10000 /* uV/us */
|
||||||
|
#define MAX77851_LDO_ENABLE_TIME 100 /* us */
|
||||||
|
#define MAX77851_BUCK_ENABLE_TIME 100 /* us */
|
||||||
|
|
||||||
|
enum max77851_ramp_rate {
|
||||||
|
RAMP_RATE_0P15MV,
|
||||||
|
RAMP_RATE_0P625MV,
|
||||||
|
RAMP_RATE_1P25MV,
|
||||||
|
RAMP_RATE_2P5MV,
|
||||||
|
RAMP_RATE_5MV,
|
||||||
|
RAMP_RATE_10MV,
|
||||||
|
RAMP_RATE_20MV,
|
||||||
|
RAMP_RATE_40MV,
|
||||||
|
RAMP_RATE_NO_CTRL, /* 100mV/us */
|
||||||
|
};
|
||||||
|
|
||||||
|
enum max77851_regulators_ldo {
|
||||||
|
MAX77851_REGULATOR_ID_LDO0,
|
||||||
|
MAX77851_REGULATOR_ID_LDO1,
|
||||||
|
MAX77851_REGULATOR_ID_LDO2,
|
||||||
|
MAX77851_REGULATOR_ID_LDO3,
|
||||||
|
MAX77851_REGULATOR_ID_LDO4,
|
||||||
|
MAX77851_REGULATOR_ID_LDO5,
|
||||||
|
MAX77851_REGULATOR_ID_LDO6,
|
||||||
|
|
||||||
|
MAX77851_REGULATOR_ID_BUCK0,
|
||||||
|
MAX77851_REGULATOR_ID_BUCK1,
|
||||||
|
MAX77851_REGULATOR_ID_BUCK2,
|
||||||
|
MAX77851_REGULATOR_ID_BUCK3,
|
||||||
|
MAX77851_REGULATOR_ID_BUCK4,
|
||||||
|
MAX77851_REGULATOR_ID_NUM,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Regulator types */
|
||||||
|
enum max77851_regulator_type {
|
||||||
|
/* LDO 0-3 */
|
||||||
|
MAX77851_REGULATOR_TYPE_LDO_N,
|
||||||
|
/* LDO 4-6 */
|
||||||
|
MAX77851_REGULATOR_TYPE_LDO_P,
|
||||||
|
/* BUCK */
|
||||||
|
MAX77851_REGULATOR_TYPE_BUCK,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct max77851_regulator_data {
|
||||||
|
u8 type;
|
||||||
|
|
||||||
|
u8 cfg_addr;
|
||||||
|
u8 vout0_addr;
|
||||||
|
u8 vout1_addr;
|
||||||
|
u8 ramp_delay_addr;
|
||||||
|
|
||||||
|
/* Common */
|
||||||
|
unsigned int en;
|
||||||
|
unsigned int lp_mode_en;
|
||||||
|
unsigned int power_mode;
|
||||||
|
|
||||||
|
unsigned int opmode;
|
||||||
|
unsigned int fps_mode_en;
|
||||||
|
|
||||||
|
unsigned int voltage[MAX77851_DVS_VOLTAGE_NUM];
|
||||||
|
|
||||||
|
struct regulator_desc desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Main Regulator Resource */
|
||||||
|
struct max77851_regulator {
|
||||||
|
struct device *dev;
|
||||||
|
struct regmap *rmap;
|
||||||
|
|
||||||
|
unsigned int num_reulator;
|
||||||
|
|
||||||
|
/* FPS */
|
||||||
|
struct max77851_fps_data *fps_data;
|
||||||
|
|
||||||
|
/* Regulator */
|
||||||
|
struct max77851_regulator_data *reg_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int max77851_regulator_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
|
||||||
|
{
|
||||||
|
struct max77851_regulator *pmic = rdev_get_drvdata(rdev);
|
||||||
|
int id = rdev_get_id(rdev);
|
||||||
|
struct max77851_regulator_data *rdata = &pmic->reg_data[id];
|
||||||
|
unsigned int ramp_value;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (ramp_delay) {
|
||||||
|
case 1 ... 150:
|
||||||
|
ramp_value = RAMP_RATE_0P15MV;
|
||||||
|
break;
|
||||||
|
case 151 ... 625:
|
||||||
|
ramp_value = RAMP_RATE_0P625MV;
|
||||||
|
break;
|
||||||
|
case 626 ... 1250:
|
||||||
|
ramp_value = RAMP_RATE_1P25MV;
|
||||||
|
break;
|
||||||
|
case 1251 ... 2500:
|
||||||
|
ramp_value = RAMP_RATE_1P25MV;
|
||||||
|
break;
|
||||||
|
case 2501 ... 5000:
|
||||||
|
ramp_value = RAMP_RATE_5MV;
|
||||||
|
break;
|
||||||
|
case 5001 ... 10000:
|
||||||
|
ramp_value = RAMP_RATE_10MV;
|
||||||
|
break;
|
||||||
|
case 10001 ... 20000:
|
||||||
|
ramp_value = RAMP_RATE_20MV;
|
||||||
|
break;
|
||||||
|
case 20001 ... 40000:
|
||||||
|
ramp_value = RAMP_RATE_40MV;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_warn("%s: ramp_delay: %d not supported\n", rdev->desc->name, ramp_delay);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regmap_update_bits(rdev->regmap, rdata->ramp_delay_addr,
|
||||||
|
BUCK_CFG5_RD_SR, ramp_value << FFS(BUCK_CFG5_RD_SR));
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Reg 0x%02x read failed %d\n", rdata->ramp_delay_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regmap_update_bits(rdev->regmap, rdata->ramp_delay_addr,
|
||||||
|
BUCK_CFG5_RU_SR, ramp_value << FFS(BUCK_CFG5_RU_SR));
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Reg 0x%02x read failed %d\n", rdata->ramp_delay_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_get_enable(struct max77851_regulator *pmic,
|
||||||
|
int id)
|
||||||
|
{
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = regmap_read(pmic->rmap, reg_data->cfg_addr, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d: Reg 0x%02x read failed: %d\n",
|
||||||
|
id, reg_data->cfg_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BITS_VALUE(val, REGULATOR_ENABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_set_enable(struct max77851_regulator *pmic,
|
||||||
|
int id)
|
||||||
|
{
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
val = REGULATOR_ENABLE;
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_data->cfg_addr,
|
||||||
|
REGULATOR_ENABLE_MASK, val);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_set_disable(struct max77851_regulator *pmic,
|
||||||
|
int id)
|
||||||
|
{
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
val = REGULATOR_DISABLE;
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_data->cfg_addr,
|
||||||
|
REGULATOR_ENABLE_MASK, val);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_enable(struct regulator_dev *rdev)
|
||||||
|
{
|
||||||
|
struct max77851_regulator *pmic = rdev_get_drvdata(rdev);
|
||||||
|
int id = rdev_get_id(rdev);
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
|
||||||
|
if (reg_data->fps_mode_en != MAX77851_FPS_MODE_DISABLE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return max77851_regulator_set_enable(pmic, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_disable(struct regulator_dev *rdev)
|
||||||
|
{
|
||||||
|
struct max77851_regulator *pmic = rdev_get_drvdata(rdev);
|
||||||
|
int id = rdev_get_id(rdev);
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
|
||||||
|
if (reg_data->fps_mode_en != MAX77851_FPS_MODE_DISABLE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return max77851_regulator_set_disable(pmic, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_is_enabled(struct regulator_dev *rdev)
|
||||||
|
{
|
||||||
|
struct max77851_regulator *pmic = rdev_get_drvdata(rdev);
|
||||||
|
int id = rdev_get_id(rdev);
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (reg_data->fps_mode_en != MAX77851_FPS_MODE_DISABLE)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
ret = max77851_regulator_get_enable(pmic, id);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (ret & REGULATOR_ENABLE)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_set_power_mode(struct max77851_regulator *pmic,
|
||||||
|
int power_mode, int id)
|
||||||
|
{
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
u8 mask = MAX77851_POWER_MODE_MASK;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_data->cfg_addr, mask, power_mode);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d mode set failed: %d\n",
|
||||||
|
id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_data->power_mode = power_mode;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_get_power_mode(struct max77851_regulator *pmic,
|
||||||
|
int id)
|
||||||
|
{
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = regmap_read(pmic->rmap, reg_data->cfg_addr, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d: Reg 0x%02x read failed: %d\n",
|
||||||
|
id, reg_data->cfg_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (val & MAX77851_POWER_MODE_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int max77851_regulator_get_mode(struct regulator_dev *rdev)
|
||||||
|
{
|
||||||
|
struct max77851_regulator *pmic = rdev_get_drvdata(rdev);
|
||||||
|
int id = rdev_get_id(rdev);
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
int ret;
|
||||||
|
int power_mode, opmode;
|
||||||
|
|
||||||
|
ret = max77851_regulator_get_power_mode(pmic, id);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
power_mode = ret;
|
||||||
|
|
||||||
|
switch (power_mode) {
|
||||||
|
case MAX77851_POWER_MODE_NORMAL:
|
||||||
|
opmode = REGULATOR_MODE_NORMAL;
|
||||||
|
break;
|
||||||
|
case MAX77851_POWER_MODE_LPM:
|
||||||
|
opmode = REGULATOR_MODE_IDLE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_data->opmode = opmode;
|
||||||
|
|
||||||
|
return opmode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_set_mode(struct regulator_dev *rdev, unsigned int mode)
|
||||||
|
{
|
||||||
|
struct max77851_regulator *pmic = rdev_get_drvdata(rdev);
|
||||||
|
int id = rdev_get_id(rdev);
|
||||||
|
unsigned int power_mode = MAX77851_POWER_MODE_NORMAL;
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case REGULATOR_MODE_IDLE:
|
||||||
|
power_mode = MAX77851_POWER_MODE_LPM; /* ON in Low Power Mode */
|
||||||
|
break;
|
||||||
|
case REGULATOR_MODE_NORMAL:
|
||||||
|
power_mode = MAX77851_POWER_MODE_NORMAL; /* ON in Normal Mode */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
|
||||||
|
rdev->desc->name, mode);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
reg_data->power_mode = power_mode;
|
||||||
|
reg_data->opmode = mode;
|
||||||
|
|
||||||
|
return max77851_regulator_set_power_mode(pmic, power_mode, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_intial(struct max77851_regulator *pmic, int id)
|
||||||
|
{
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = regmap_read(pmic->rmap, reg_data->cfg_addr, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Reg 0x%02x read failed %d\n", reg_data->cfg_addr, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_data->en = ret & BIT(0) ? 1 : 0;
|
||||||
|
reg_data->lp_mode_en = ret & BIT(2) ? 1 : 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_set_vout_range(struct max77851_regulator *pmic,
|
||||||
|
u32 val, int id)
|
||||||
|
{
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
u8 reg_addr;
|
||||||
|
int mask, shift;
|
||||||
|
int ret;
|
||||||
|
unsigned int read_val;
|
||||||
|
|
||||||
|
ret = regmap_read(pmic->rmap, reg_data->cfg_addr, &read_val);
|
||||||
|
|
||||||
|
if (IS_BUCK(reg_data->type)) {
|
||||||
|
reg_addr = reg_data->cfg_addr;
|
||||||
|
mask = BUCK_CFG0_VOUT_RNG;
|
||||||
|
shift = FFS(BUCK_CFG0_VOUT_RNG);
|
||||||
|
} else {
|
||||||
|
if (IS_NLDO(reg_data->type)) {
|
||||||
|
reg_addr = reg_data->cfg_addr;
|
||||||
|
mask = LDO_CFG0_VOUT_RNG;
|
||||||
|
shift = FFS(LDO_CFG0_VOUT_RNG);
|
||||||
|
} else {
|
||||||
|
dev_info(pmic->dev, "PMOS is not supported : %d\n", ret);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_addr, mask, BITS_REAL_VALUE(val, mask));
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d range set failed: %d\n",
|
||||||
|
id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regmap_read(pmic->rmap, reg_data->cfg_addr, &read_val);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_set_vout_voltage(struct max77851_regulator *pmic,
|
||||||
|
unsigned int *vout, int id)
|
||||||
|
{
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[id];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (IS_BUCK(reg_data->type)) {
|
||||||
|
ret = regmap_write(pmic->rmap, reg_data->vout0_addr, vout[0]);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d vout set failed: %d\n", id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = regmap_write(pmic->rmap, reg_data->vout1_addr, vout[1]);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d vout set failed: %d\n", id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Register set vout0 */
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_data->cfg_addr, LDO_CFG0_VOUT_RW, BIT_IS_ZERO);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d register set failed: %d\n",
|
||||||
|
id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = regmap_write(pmic->rmap, reg_data->vout0_addr, vout[0]);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d vout set failed: %d\n", id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register set vout1 */
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_data->cfg_addr, LDO_CFG0_VOUT_RW, LDO_CFG0_VOUT_RW);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d register set failed: %d\n",
|
||||||
|
id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ret = regmap_write(pmic->rmap, reg_data->vout1_addr, vout[1]);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "Regulator %d vout set failed: %d\n", id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_set_fps(struct max77851_regulator *pmic, int id)
|
||||||
|
{
|
||||||
|
struct max77851_fps_data *fps_data = &pmic->fps_data[id];
|
||||||
|
unsigned int val;
|
||||||
|
int mask, shift;
|
||||||
|
u8 reg_addr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mask = MAX77851_FPS_PU_SLPX_SLOT_MASK;
|
||||||
|
shift = FFS(MAX77851_FPS_PU_SLPX_SLOT_MASK);
|
||||||
|
val = fps_data->pu_slpx_master_slot;
|
||||||
|
reg_addr = fps_data->fps_cfg0_addr;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_addr, mask, val << shift);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "PY SLPX MASTER SLOT update failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = MAX77851_FPS_PD_SLPY_SLOT_MASK;
|
||||||
|
shift = FFS(MAX77851_FPS_PD_SLPY_SLOT_MASK);
|
||||||
|
|
||||||
|
val = fps_data->pd_slpy_master_slot;
|
||||||
|
reg_addr = fps_data->fps_cfg0_addr;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_addr, mask, val << shift);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "PD SLPY MASTER SLOT update failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = MAX77851_FPS_PU_SLOT_MASK;
|
||||||
|
shift = FFS(MAX77851_FPS_PU_SLOT_MASK);
|
||||||
|
|
||||||
|
val = fps_data->pu_slot;
|
||||||
|
reg_addr = fps_data->fps_cfg1_addr;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_addr, mask, val << shift);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "PU SLOT update failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = MAX77851_FPS_PD_SLOT_MASK;
|
||||||
|
shift = FFS(MAX77851_FPS_PD_SLOT_MASK);
|
||||||
|
|
||||||
|
val = fps_data->pd_slot;
|
||||||
|
reg_addr = fps_data->fps_cfg1_addr;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_addr, mask, val << shift);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "PD SLOT update failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = MAX77851_FPS_SLPX_SLOT_MASK;
|
||||||
|
shift = FFS(MAX77851_FPS_SLPX_SLOT_MASK);
|
||||||
|
|
||||||
|
val = fps_data->slpx_slot;
|
||||||
|
reg_addr = fps_data->fps_cfg2_addr;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_addr, mask, val << shift);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "SLPX SLOT update failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = MAX77851_FPS_SLPY_SLOT_MASK;
|
||||||
|
shift = FFS(MAX77851_FPS_SLPY_SLOT_MASK);
|
||||||
|
|
||||||
|
val = fps_data->slpy_slot;
|
||||||
|
reg_addr = fps_data->fps_cfg2_addr;
|
||||||
|
ret = regmap_update_bits(pmic->rmap, reg_addr, mask, val << shift);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(pmic->dev, "SLPY SLOT update failed: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_of_parse_cb(struct device_node *np,
|
||||||
|
const struct regulator_desc *desc,
|
||||||
|
struct regulator_config *config)
|
||||||
|
{
|
||||||
|
struct max77851_regulator *pmic = config->driver_data;
|
||||||
|
struct max77851_fps_data *fps_data = &pmic->fps_data[desc->id];
|
||||||
|
struct max77851_regulator_data *reg_data = &pmic->reg_data[desc->id];
|
||||||
|
unsigned int voltage[MAX77851_VOUT_NUM];
|
||||||
|
u32 pval;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Use FPS Default Data */
|
||||||
|
if (of_property_read_bool(np, "maxim,fps-default-enable")) {
|
||||||
|
reg_data->fps_mode_en = MAX77851_FPS_MODE_ENABLE;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg_data->fps_mode_en = MAX77851_FPS_MODE_DISABLE;
|
||||||
|
|
||||||
|
/* VOUT Range */
|
||||||
|
ret = of_property_read_u32(np, "maxim,out-voltage-range", &pval);
|
||||||
|
if (ret < 0)
|
||||||
|
pval = MAX77851_VOUT_RNG_LOW;
|
||||||
|
|
||||||
|
max77851_regulator_set_vout_range(pmic, pval, desc->id);
|
||||||
|
|
||||||
|
if (of_property_read_bool(np, "maxim,fps-user-setting-enable")) {
|
||||||
|
ret = of_property_read_u32(np, "maxim,pu-slpx-master-slot", &pval);
|
||||||
|
fps_data->pu_slpx_master_slot = (!ret) ? pval : MAX77851_FPS_MASTER_SLOT_0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "maxim,pd-slpy-master-slot", &pval);
|
||||||
|
fps_data->pd_slpy_master_slot = (!ret) ? pval : MAX77851_FPS_MASTER_SLOT_0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "maxim,pu-slot", &pval);
|
||||||
|
fps_data->pu_slot = (!ret) ? pval : MAX77851_FPS_SLOT_0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "maxim,pd-slot", &pval);
|
||||||
|
fps_data->pd_slot = (!ret) ? pval : MAX77851_FPS_SLOT_0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "maxim,slpy-slot", &pval);
|
||||||
|
fps_data->slpy_slot = (!ret) ? pval : MAX77851_FPS_SLOT_0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "maxim,slpx-slot", &pval);
|
||||||
|
fps_data->slpx_slot = (!ret) ? pval : MAX77851_FPS_SLOT_0;
|
||||||
|
|
||||||
|
reg_data->fps_mode_en = MAX77851_FPS_MODE_ENABLE;
|
||||||
|
|
||||||
|
max77851_regulator_set_fps(pmic, desc->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (of_property_read_bool(np, "maxim,regulator-dvs-mode-enable")) {
|
||||||
|
if (of_property_read_u32_array(np, "maxim,regulator-dvs-voltage",
|
||||||
|
voltage, MAX77851_DVS_VOLTAGE_NUM)) {
|
||||||
|
dev_err(pmic->dev, "dvs voltages not specified\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
max77851_regulator_set_vout_voltage(pmic, voltage, desc->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return max77851_regulator_intial(pmic, desc->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct regulator_ops max77851_regulator_ldo_ops = {
|
||||||
|
.is_enabled = max77851_regulator_is_enabled,
|
||||||
|
.enable = max77851_regulator_enable,
|
||||||
|
.disable = max77851_regulator_disable,
|
||||||
|
.list_voltage = regulator_list_voltage_linear,
|
||||||
|
.map_voltage = regulator_map_voltage_linear,
|
||||||
|
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||||
|
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||||
|
.set_mode = max77851_regulator_set_mode,
|
||||||
|
.get_mode = max77851_regulator_get_mode,
|
||||||
|
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||||
|
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regulator_ops max77851_regulator_buck_ops = {
|
||||||
|
.is_enabled = max77851_regulator_is_enabled,
|
||||||
|
.enable = max77851_regulator_enable,
|
||||||
|
.disable = max77851_regulator_disable,
|
||||||
|
.list_voltage = regulator_list_voltage_linear,
|
||||||
|
.map_voltage = regulator_map_voltage_linear,
|
||||||
|
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||||
|
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||||
|
.set_mode = max77851_regulator_set_mode,
|
||||||
|
.get_mode = max77851_regulator_get_mode,
|
||||||
|
.set_ramp_delay = max77851_regulator_set_ramp_delay,
|
||||||
|
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||||
|
.set_active_discharge = regulator_set_active_discharge_regmap,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define REGULATOR_LDO_DESC(_id, _name, _sname, _type, _min_uV, _max_uV, _step_uV) \
|
||||||
|
[MAX77851_REGULATOR_ID_##_id] = { \
|
||||||
|
.type = MAX77851_REGULATOR_TYPE_LDO_##_type, \
|
||||||
|
.cfg_addr = _id##_CFG0_REG, \
|
||||||
|
.vout0_addr = _id##_CFG1_REG, \
|
||||||
|
.vout1_addr = _id##_CFG1_REG, \
|
||||||
|
.desc = { \
|
||||||
|
.owner = THIS_MODULE, \
|
||||||
|
.name = max77851_rails(_name), \
|
||||||
|
.supply_name = _sname, \
|
||||||
|
.of_match = of_match_ptr(#_name), \
|
||||||
|
.regulators_node = of_match_ptr("regulators"), \
|
||||||
|
.of_parse_cb = max77851_of_parse_cb, \
|
||||||
|
.id = MAX77851_REGULATOR_ID_##_id, \
|
||||||
|
.ops = &max77851_regulator_ldo_ops, \
|
||||||
|
.type = REGULATOR_VOLTAGE, \
|
||||||
|
.min_uV = _min_uV, \
|
||||||
|
.uV_step = _step_uV, \
|
||||||
|
.enable_time = MAX77851_LDO_ENABLE_TIME, \
|
||||||
|
.n_voltages = ((_max_uV - _min_uV) / _step_uV) + 1, \
|
||||||
|
.vsel_reg = _id##_CFG1_REG, \
|
||||||
|
.vsel_mask = LDO_CFG1_VOUT, \
|
||||||
|
.enable_reg = _id##_CFG0_REG, \
|
||||||
|
.enable_mask = LDO_CFG0_EN, \
|
||||||
|
.enable_val = LDO_CFG0_EN, \
|
||||||
|
.disable_val = BIT_IS_ZERO, \
|
||||||
|
.active_discharge_reg = _id##_CFG0_REG, \
|
||||||
|
.active_discharge_mask = LDO_CFG0_ADE, \
|
||||||
|
.active_discharge_on = LDO_CFG0_ADE, \
|
||||||
|
.active_discharge_off = BIT_IS_ZERO, \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define REGULATOR_BUCK_DESC(_id, _name, _sname, _min_uV, _max_uV, _step_uV) \
|
||||||
|
[MAX77851_REGULATOR_ID_##_id] = { \
|
||||||
|
.type = MAX77851_REGULATOR_TYPE_BUCK, \
|
||||||
|
.cfg_addr = _id##_CFG0_REG, \
|
||||||
|
.vout0_addr = _id##_CFG1_REG, \
|
||||||
|
.vout1_addr = _id##_CFG2_REG, \
|
||||||
|
.ramp_delay_addr = _id##_CFG5_REG, \
|
||||||
|
.desc = { \
|
||||||
|
.owner = THIS_MODULE, \
|
||||||
|
.name = max77851_rails(_name), \
|
||||||
|
.supply_name = _sname, \
|
||||||
|
.of_match = of_match_ptr(#_name), \
|
||||||
|
.regulators_node = of_match_ptr("regulators"), \
|
||||||
|
.of_parse_cb = max77851_of_parse_cb, \
|
||||||
|
.id = MAX77851_REGULATOR_ID_##_id, \
|
||||||
|
.ops = &max77851_regulator_buck_ops, \
|
||||||
|
.type = REGULATOR_VOLTAGE, \
|
||||||
|
.min_uV = _min_uV, \
|
||||||
|
.uV_step = _step_uV, \
|
||||||
|
.ramp_delay = MAX77851_BUCK_RAMP_DELAY, \
|
||||||
|
.enable_time = MAX77851_BUCK_ENABLE_TIME, \
|
||||||
|
.n_voltages = ((_max_uV - _min_uV) / _step_uV) + 1, \
|
||||||
|
.vsel_reg = _id##_CFG1_REG, \
|
||||||
|
.vsel_mask = BUCK_CFG1_VOUT0, \
|
||||||
|
.enable_reg = _id##_CFG0_REG, \
|
||||||
|
.enable_mask = BUCK_CFG0_EN, \
|
||||||
|
.enable_val = BUCK_CFG0_EN, \
|
||||||
|
.disable_val = BIT_IS_ZERO, \
|
||||||
|
.active_discharge_reg = _id##_CFG6_REG, \
|
||||||
|
.active_discharge_mask = BUCK_CFG6_ADE, \
|
||||||
|
.active_discharge_on = BUCK_CFG6_ADE, \
|
||||||
|
.active_discharge_off = BIT_IS_ZERO, \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct max77851_regulator_data max77851_regs_data[MAX77851_REGULATOR_ID_NUM] = {
|
||||||
|
REGULATOR_LDO_DESC(LDO0, ldo0, "in-ldo0", N, 400000, 1993750, 6250),
|
||||||
|
REGULATOR_LDO_DESC(LDO1, ldo1, "in-ldo1", N, 400000, 1993750, 6250),
|
||||||
|
REGULATOR_LDO_DESC(LDO2, ldo2, "in-ldo2", N, 400000, 1993750, 6250),
|
||||||
|
REGULATOR_LDO_DESC(LDO3, ldo3, "in-ldo3", N, 400000, 1993750, 6250),
|
||||||
|
REGULATOR_LDO_DESC(LDO4, ldo4, "in-ldo4", P, 400000, 3975000, 25000),
|
||||||
|
REGULATOR_LDO_DESC(LDO5, ldo5, "in-ldo5", P, 400000, 3975000, 25000),
|
||||||
|
REGULATOR_LDO_DESC(LDO6, ldo6, "in-ldo6", P, 400000, 3975000, 25000),
|
||||||
|
|
||||||
|
REGULATOR_BUCK_DESC(BUCK0, buck0, "in-buck0", 300000, 1200000, 2500),
|
||||||
|
REGULATOR_BUCK_DESC(BUCK1, buck1, "in-buck1", 300000, 1200000, 2500),
|
||||||
|
REGULATOR_BUCK_DESC(BUCK2, buck2, "in-buck2", 300000, 1200000, 2500),
|
||||||
|
REGULATOR_BUCK_DESC(BUCK3, buck3, "in-buck3", 1000000, 2400000, 2500),
|
||||||
|
REGULATOR_BUCK_DESC(BUCK4, buck4, "in-buck4", 1000000, 2400000, 2500),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX77851_FPS_REGULATOR_REG(_fps_name) { \
|
||||||
|
.fps_cfg0_addr = _fps_name##_CFG0_REG, \
|
||||||
|
.fps_cfg1_addr = _fps_name##_CFG1_REG, \
|
||||||
|
.fps_cfg2_addr = _fps_name##_CFG2_REG, \
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct max77851_fps_data max77851_fps_data_data[MAX77851_REGULATOR_ID_NUM] = {
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_LDO0),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_LDO1),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_LDO2),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_LDO3),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_LDO4),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_LDO5),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_LDO6),
|
||||||
|
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_BUCK0),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_BUCK1),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_BUCK2),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_BUCK3),
|
||||||
|
MAX77851_FPS_REGULATOR_REG(FPS_BUCK4),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int max77851_regulator_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct max77851_chip *max77851_chip = dev_get_drvdata(pdev->dev.parent);
|
||||||
|
struct max77851_regulator *pmic;
|
||||||
|
struct max77851_fps_data *fps_data;
|
||||||
|
struct max77851_regulator_data *reg_data;
|
||||||
|
struct device *dev = &pdev->dev;
|
||||||
|
struct regulator_config config = { };
|
||||||
|
int ret = 0;
|
||||||
|
int id = 0;
|
||||||
|
|
||||||
|
pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
|
||||||
|
if (!pmic)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, pmic);
|
||||||
|
|
||||||
|
pmic->dev = dev;
|
||||||
|
pmic->rmap = max77851_chip->rmap;
|
||||||
|
pmic->dev->of_node = pdev->dev.parent->of_node;
|
||||||
|
|
||||||
|
fps_data = max77851_fps_data_data;
|
||||||
|
reg_data = max77851_regs_data;
|
||||||
|
|
||||||
|
pmic->reg_data = max77851_regs_data;
|
||||||
|
pmic->fps_data = max77851_fps_data_data;
|
||||||
|
|
||||||
|
config.regmap = pmic->rmap;
|
||||||
|
config.dev = dev;
|
||||||
|
config.driver_data = pmic;
|
||||||
|
|
||||||
|
for (id = 0; id < MAX77851_REGULATOR_ID_NUM; id++) {
|
||||||
|
struct regulator_dev *rdev;
|
||||||
|
struct regulator_desc *rdesc;
|
||||||
|
|
||||||
|
rdesc = ®_data[id].desc;
|
||||||
|
|
||||||
|
pmic->reg_data[id].power_mode = MAX77851_POWER_MODE_NORMAL;
|
||||||
|
|
||||||
|
pmic->fps_data[id].pd_slot = -1;
|
||||||
|
pmic->fps_data[id].pu_slot = -1;
|
||||||
|
pmic->fps_data[id].slpx_slot = -1;
|
||||||
|
pmic->fps_data[id].slpy_slot = -1;
|
||||||
|
pmic->fps_data[id].pu_slpx_master_slot = -1;
|
||||||
|
pmic->fps_data[id].pd_slpy_master_slot = -1;
|
||||||
|
|
||||||
|
rdev = devm_regulator_register(dev, rdesc, &config);
|
||||||
|
if (IS_ERR(rdev)) {
|
||||||
|
ret = PTR_ERR(rdev);
|
||||||
|
dev_err(dev, "Regulator registration %s failed: %d\n",
|
||||||
|
rdesc->name, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
static int max77851_regulator_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_regulator_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct dev_pm_ops max77851_regulator_pm_ops = {
|
||||||
|
SET_SYSTEM_SLEEP_PM_OPS(max77851_regulator_suspend,
|
||||||
|
max77851_regulator_resume)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct platform_device_id max77851_regulator_devtype[] = {
|
||||||
|
{ .name = "max77851-regulator", },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(platform, max77851_regulator_devtype);
|
||||||
|
|
||||||
|
static struct platform_driver max77851_regulator_driver = {
|
||||||
|
.probe = max77851_regulator_probe,
|
||||||
|
.id_table = max77851_regulator_devtype,
|
||||||
|
.driver = {
|
||||||
|
.name = "max77851-regulator",
|
||||||
|
.pm = &max77851_regulator_pm_ops,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init max77851_regulator_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&max77851_regulator_driver);
|
||||||
|
}
|
||||||
|
subsys_initcall(max77851_regulator_init);
|
||||||
|
|
||||||
|
static void __exit max77851_reg_exit(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&max77851_regulator_driver);
|
||||||
|
}
|
||||||
|
module_exit(max77851_reg_exit);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("MAX77851 regulator driver");
|
||||||
|
MODULE_AUTHOR("Shubhi Garg<shgarg@nvidia.com>");
|
||||||
|
MODULE_AUTHOR("Joan Na<Joan.na@maximintegrated.com>");
|
||||||
|
MODULE_ALIAS("platform:max77851-regulator");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
Reference in New Issue
Block a user