mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 09:11:26 +03:00
mfd: add max77851 pmic MFD driver
Adding MAX77851 MFD driver provided by Maxim. - fix android warning/error for uninitialized variable return Bug 200749982 Change-Id: I6ef82a6c06fe7bbd4df2c71991ec6c5c15e28474 Signed-off-by: Shubhi Garg <shgarg@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-5.10/+/2591158 Signed-off-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2938653 GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
cdc64f43fa
commit
1ab8a495fc
258
Documentation/devicetree/bindings/mfd/max77851.yaml
Normal file
258
Documentation/devicetree/bindings/mfd/max77851.yaml
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
# 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/mfd/max77851.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Joan Na<Joan.na@maximintegrated.com>
|
||||||
|
- Shubhi Garg <shgarg@nvidia.com>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
MAX77851 Power management IC from Maxim Semiconductor.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: "maxim,max77851-pmic"
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
description:
|
||||||
|
I2C device address.
|
||||||
|
|
||||||
|
interrupts:
|
||||||
|
maxItems: 1
|
||||||
|
description:
|
||||||
|
The interrupt on the parent the controller is connected to.
|
||||||
|
|
||||||
|
interrupt-controller:
|
||||||
|
description:
|
||||||
|
Marks the device node as an interrupt controller.
|
||||||
|
|
||||||
|
"#interrupt-cells":
|
||||||
|
const: 2
|
||||||
|
description:
|
||||||
|
is <2> and their usage is compliant to the 2 cells
|
||||||
|
variant of <../interrupt-controller/interrupts.txt>
|
||||||
|
IRQ numbers for different interrupt source of MAX77851
|
||||||
|
are defined at dt-bindings/mfd/max77620.h.
|
||||||
|
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
|
||||||
|
additionalProperties:
|
||||||
|
- interrupts
|
||||||
|
- interrupt-controller
|
||||||
|
- #interrupt-cells
|
||||||
|
|
||||||
|
Optional subnodes and their properties:
|
||||||
|
|
||||||
|
Flexible power sequence configurations:
|
||||||
|
The Flexible Power Sequencer (FPS) allows each regulator to power up under
|
||||||
|
hardware or software control.
|
||||||
|
|
||||||
|
- maxim,power-down-slot-period-us: Inter Master Power-Down Slot Period
|
||||||
|
- maxim,power-up-slot-period-us: Inter Master Power-Up Slot Period
|
||||||
|
- maxim,sleep-entry-slot-period-us: Inter Master Sleep Entry Slot Period
|
||||||
|
- maxim,sleep-exit-slot-period-us: Inter Master Sleep Exit Slot Period
|
||||||
|
|
||||||
|
- maxim,power-down-time-period-us: Master 0/1/2/3 Power-Down Slot Period
|
||||||
|
- maxim,power-up-time-period-us: Master 0/1/2/3 Power-Up Slot Period
|
||||||
|
- maxim,sleep-entry-time-period-us: Master 0/1/2/3 Sleep Entry Slot Period
|
||||||
|
- maxim,sleep-exit-time-period-us: Master 0/1/2/3 Sleep Exit Slot Period
|
||||||
|
|
||||||
|
Valid values for slot period are:
|
||||||
|
FPS_PERIOD_32KHZ_30US
|
||||||
|
FPS_PERIOD_32KHZ_61US
|
||||||
|
FPS_PERIOD_32KHZ_122US
|
||||||
|
FPS_PERIOD_32KHZ_244US
|
||||||
|
FPS_PERIOD_32KHZ_488US
|
||||||
|
FPS_PERIOD_32KHZ_762US
|
||||||
|
FPS_PERIOD_32KHZ_1007US
|
||||||
|
FPS_PERIOD_32KHZ_1251US
|
||||||
|
FPS_PERIOD_32KHZ_1495US
|
||||||
|
FPS_PERIOD_32KHZ_1739US
|
||||||
|
FPS_PERIOD_32KHZ_2014US
|
||||||
|
FPS_PERIOD_32KHZ_2990US
|
||||||
|
FPS_PERIOD_32KHZ_3997US
|
||||||
|
FPS_PERIOD_32KHZ_5004US
|
||||||
|
FPS_PERIOD_32KHZ_6011US
|
||||||
|
FPS_PERIOD_32KHZ_7995US
|
||||||
|
|
||||||
|
FPS_PERIOD_4KHZ_025US
|
||||||
|
FPS_PERIOD_4KHZ_050US
|
||||||
|
FPS_PERIOD_4KHZ_1US
|
||||||
|
FPS_PERIOD_4KHZ_2US
|
||||||
|
FPS_PERIOD_4KHZ_4US
|
||||||
|
FPS_PERIOD_4KHZ_8US
|
||||||
|
FPS_PERIOD_4KHZ_16US
|
||||||
|
FPS_PERIOD_4KHZ_25US
|
||||||
|
FPS_PERIOD_4KHZ_50US
|
||||||
|
FPS_PERIOD_4KHZ_100US
|
||||||
|
FPS_PERIOD_4KHZ_250US
|
||||||
|
FPS_PERIOD_4KHZ_500US
|
||||||
|
FPS_PERIOD_4KHZ_1000US
|
||||||
|
FPS_PERIOD_4KHZ_2000US
|
||||||
|
FPS_PERIOD_4KHZ_3000US
|
||||||
|
|
||||||
|
- maxim,fps-enable: FPS Enable
|
||||||
|
|
||||||
|
Valid values for FPS enable are:
|
||||||
|
MAX77851_FPS_DISABLE
|
||||||
|
MAX77851_FPS_ENABLE
|
||||||
|
|
||||||
|
- maxim,abort-enable: FPS Abort Enable
|
||||||
|
|
||||||
|
Valid values for FPS enable are:
|
||||||
|
MAX77851_FPS_ABORT_DISABLE
|
||||||
|
MAX77851_FPS_ABORT_ENABLE
|
||||||
|
|
||||||
|
- maxim,sleep-enable: FPS Sleep Enable
|
||||||
|
|
||||||
|
Valid values for FPS sleep enable are:
|
||||||
|
MAX77851_FPS_SLEEP_DISABLE
|
||||||
|
MAX77851_FPS_SLEEP_ENABLE
|
||||||
|
MAX77851_FPS_SLEEP_LPM
|
||||||
|
MAX77851_FPS_SLEEP_ULPM
|
||||||
|
|
||||||
|
- maxim,abort-mode: FPS Abort Mode
|
||||||
|
|
||||||
|
Valid values for FPS sleep abort mode are:
|
||||||
|
MAX77851_FPS_ABORT_NEXT_SLOT
|
||||||
|
MAX77851_FPS_ABORT_NEXT_MASTER_SLOT
|
||||||
|
|
||||||
|
|
||||||
|
- maxim,pd-max-slot: Master 0/1/2/3 Power-Down Max Used Slots
|
||||||
|
- maxim,pu-max-slot: Master 0/1/2/3 Power-Up Max Used Slots
|
||||||
|
|
||||||
|
- maxim,slpy-max-slot: Master 0/1/2/3 Sleep Entry Max Used Slots
|
||||||
|
- maxim,slpx-max-slot: Master 0/1/2/3 Sleep Exit Max Used Slots
|
||||||
|
Valid values for FPS Max Used Slots are:
|
||||||
|
MAX77851_FPS_SLOT_0
|
||||||
|
MAX77851_FPS_SLOT_1
|
||||||
|
MAX77851_FPS_SLOT_2
|
||||||
|
MAX77851_FPS_SLOT_3
|
||||||
|
MAX77851_FPS_SLOT_4
|
||||||
|
MAX77851_FPS_SLOT_5
|
||||||
|
MAX77851_FPS_SLOT_6
|
||||||
|
MAX77851_FPS_SLOT_7
|
||||||
|
MAX77851_FPS_SLOT_8
|
||||||
|
MAX77851_FPS_SLOT_9
|
||||||
|
MAX77851_FPS_SLOT_A
|
||||||
|
MAX77851_FPS_SLOT_B
|
||||||
|
MAX77851_FPS_SLOT_C
|
||||||
|
MAX77851_FPS_SLOT_D
|
||||||
|
MAX77851_FPS_SLOT_E
|
||||||
|
MAX77851_FPS_SLOT_F
|
||||||
|
|
||||||
|
- maxim,sleep-on-suspend: Enter SLEEP state when system is suspended.
|
||||||
|
Bool property. Add this property if required to
|
||||||
|
enter SLEEP state during system suspend.
|
||||||
|
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/mfd/max77620.h>
|
||||||
|
|
||||||
|
max77851: max77851@3c {
|
||||||
|
compatible = "maxim,max77851-pmic";
|
||||||
|
reg = <0x3c>;
|
||||||
|
|
||||||
|
interrupt-parent = <&gpio>;
|
||||||
|
interrupt-names = "max77851_irq";
|
||||||
|
interrupts = <17 IRQ_TYPE_LEVEL_LOW>;
|
||||||
|
#thermal-sensor-cells = <0>;
|
||||||
|
|
||||||
|
system-power-controller;
|
||||||
|
|
||||||
|
#interrupt-cells = <2>;
|
||||||
|
interrupt-controller;
|
||||||
|
|
||||||
|
#gpio-cells = <2>;
|
||||||
|
gpio-controller;
|
||||||
|
|
||||||
|
fps {
|
||||||
|
maxim,power-down-slot-period-us = <FPS_PERIOD_4KHZ_050US>;
|
||||||
|
maxim,power-up-slot-period-us = <FPS_PERIOD_32KHZ_122US>;
|
||||||
|
maxim,sleep-entry-slot-period-us = <FPS_PERIOD_4KHZ_050US>;
|
||||||
|
maxim,sleep-exit-slot-period-us = <FPS_PERIOD_32KHZ_122US>;
|
||||||
|
fps0 {
|
||||||
|
maxim,pd-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
maxim,pu-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
|
||||||
|
maxim,power-down-time-period-us = <FPS_PERIOD_4KHZ_100US>;
|
||||||
|
maxim,power-up-time-period-us = <FPS_PERIOD_32KHZ_244US>;
|
||||||
|
|
||||||
|
maxim,fps-enable = <MAX77851_FPS_ENABLE>;
|
||||||
|
maxim,abort-enable = <MAX77851_FPS_ABORT_ENABLE>;
|
||||||
|
|
||||||
|
maxim,sleep-enable = <MAX77851_FPS_SLEEP_DISABLE>;
|
||||||
|
maxim,abort-mode = <MAX77851_FPS_ABORT_NEXT_MASTER_SLOT>;
|
||||||
|
|
||||||
|
maxim,pd-max-slot = <MAX77851_FPS_12_SLOTS>;
|
||||||
|
maxim,pu-max-slot = <MAX77851_FPS_10_SLOTS>;
|
||||||
|
};
|
||||||
|
fps1 {
|
||||||
|
maxim,pd-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
maxim,pu-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
maxim,slpy-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
maxim,slpx-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
|
||||||
|
maxim,power-down-time-period-us = <FPS_PERIOD_4KHZ_100US>;
|
||||||
|
maxim,power-up-time-period-us = <FPS_PERIOD_32KHZ_244US>;
|
||||||
|
maxim,sleep-entry-time-period-us = <FPS_PERIOD_4KHZ_100US>;
|
||||||
|
maxim,sleep-exit-time-period-us = <FPS_PERIOD_32KHZ_244US>;
|
||||||
|
|
||||||
|
maxim,fps-enable = <MAX77851_FPS_ENABLE>;
|
||||||
|
maxim,abort-enable = <MAX77851_FPS_ABORT_ENABLE>;
|
||||||
|
|
||||||
|
maxim,sleep-enable = <MAX77851_FPS_SLEEP_ENABLE>;
|
||||||
|
maxim,abort-mode = <MAX77851_FPS_ABORT_NEXT_MASTER_SLOT>;
|
||||||
|
|
||||||
|
maxim,pd-max-slot = <MAX77851_FPS_12_SLOTS>;
|
||||||
|
maxim,pu-max-slot = <MAX77851_FPS_10_SLOTS>;
|
||||||
|
|
||||||
|
maxim,slpy-max-slot = <MAX77851_FPS_08_SLOTS>;
|
||||||
|
maxim,slpx-max-slot = <MAX77851_FPS_08_SLOTS>;
|
||||||
|
|
||||||
|
#maxim,fps-event-source = <MAX77851_FPS_EVENT_SRC_EN0>;
|
||||||
|
};
|
||||||
|
fps2 {
|
||||||
|
maxim,pd-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
maxim,pu-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
|
||||||
|
maxim,power-down-time-period-us = <FPS_PERIOD_4KHZ_100US>;
|
||||||
|
maxim,power-up-time-period-us = <FPS_PERIOD_32KHZ_244US>;
|
||||||
|
|
||||||
|
maxim,fps-enable = <MAX77851_FPS_ENABLE>;
|
||||||
|
maxim,abort-enable = <MAX77851_FPS_ABORT_ENABLE>;
|
||||||
|
|
||||||
|
maxim,sleep-enable = <MAX77851_FPS_SLEEP_LPM>;
|
||||||
|
maxim,abort-mode = <MAX77851_FPS_ABORT_NEXT_MASTER_SLOT>;
|
||||||
|
|
||||||
|
maxim,pd-max-slot = <MAX77851_FPS_12_SLOTS>;
|
||||||
|
maxim,pu-max-slot = <MAX77851_FPS_10_SLOTS>;
|
||||||
|
};
|
||||||
|
fps3 {
|
||||||
|
maxim,pd-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
maxim,pu-fps-master-slot = <MAX77851_FPS_MX_MASTER_SLOT_0>;
|
||||||
|
|
||||||
|
maxim,power-down-time-period-us = <FPS_PERIOD_4KHZ_100US>;
|
||||||
|
maxim,power-up-time-period-us = <FPS_PERIOD_32KHZ_244US>;
|
||||||
|
|
||||||
|
maxim,fps-enable = <MAX77851_FPS_ENABLE>;
|
||||||
|
maxim,abort-enable = <MAX77851_FPS_ABORT_ENABLE>;
|
||||||
|
|
||||||
|
maxim,sleep-enable = <MAX77851_FPS_SLEEP_ENABLE>;
|
||||||
|
maxim,abort-mode = <MAX77851_FPS_ABORT_NEXT_MASTER_SLOT>;
|
||||||
|
|
||||||
|
maxim,pd-max-slot = <MAX77851_FPS_12_SLOTS>;
|
||||||
|
maxim,pu-max-slot = <MAX77851_FPS_10_SLOTS>;
|
||||||
|
|
||||||
|
#maxim,fps-event-source = <MAX77851_FPS_EVENT_SRC_EN0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
# SPDX-License-Identifier: GPL-2.0
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
|
||||||
obj-m += nvidia-vrs-pseq.o
|
obj-m += nvidia-vrs-pseq.o
|
||||||
|
obj-m += max77851.o
|
||||||
|
|||||||
663
drivers/mfd/max77851.c
Normal file
663
drivers/mfd/max77851.c
Normal file
@@ -0,0 +1,663 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
// SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||||
|
/*
|
||||||
|
* Maxim MAX77851 MFD Driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/mfd/core.h>
|
||||||
|
#include <linux/mfd/max77851.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
|
||||||
|
#define IS_MX_MASTER23(fps) ((fps == MX_FPS_MASTER2) || (fps == MX_FPS_MASTER3))
|
||||||
|
#define IS_MX_MASTER01(fps) ((fps == MX_FPS_MASTER0) || (fps == MX_FPS_MASTER1))
|
||||||
|
|
||||||
|
#define MAX77851_FPS_CNFG_LENGTH 5
|
||||||
|
|
||||||
|
struct max77851_chip *max77851_chip;
|
||||||
|
|
||||||
|
static const struct resource gpio_resources[] = {
|
||||||
|
DEFINE_RES_IRQ(MAX77851_IRQ_TOP_GPIO),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct resource power_resources[] = {
|
||||||
|
DEFINE_RES_IRQ(MAX77851_IRQ_TOP_LB),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct resource rtc_resources[] = {
|
||||||
|
DEFINE_RES_IRQ(MAX77851_IRQ_TOP_RTC),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct resource thermal_resources[] = {
|
||||||
|
DEFINE_RES_IRQ(MAX77851_IRQ_TOP_TJ_SHDN),
|
||||||
|
DEFINE_RES_IRQ(MAX77851_IRQ_TOP_TJ_ALM1),
|
||||||
|
DEFINE_RES_IRQ(MAX77851_IRQ_TOP_TJ_ALM2),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_irq max77851_top_irqs[] = {
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_BUCK, 0, TOP_INT0_BUCK_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_EN, 0, TOP_INT0_EN_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_FPS, 0, TOP_INT0_FPS_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_GPIO, 0, TOP_INT0_GPIO_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_IO, 0, TOP_INT0_IO_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_LDO, 0, TOP_INT0_LDO_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_RLOGIC, 0, TOP_INT0_RLOGIC_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_RTC, 0, TOP_INT0_RTC_I),
|
||||||
|
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_UVLO, 1, TOP_INT1_UVLO_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_LB, 1, TOP_INT1_LB_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_LDO, 1, TOP_INT1_LB_ALM_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_OVLO, 1, TOP_INT1_OVLO_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_TJ_SHDN, 1, TOP_INT1_TJ_SHDN_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_TJ_ALM1, 1, TOP_INT1_TJ_ALM1_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_TJ_ALM2, 1, TOP_INT1_TJ_ALM2_I),
|
||||||
|
REGMAP_IRQ_REG(MAX77851_IRQ_TOP_TJ_SMPL, 1, TOP_INT1_SMPL_I)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct mfd_cell max77851_children[] = {
|
||||||
|
{ .name = "max77851-pinctrl", },
|
||||||
|
{ .name = "max77851-clock", },
|
||||||
|
{ .name = "max77851-regulator", },
|
||||||
|
{ .name = "max77851-watchdog", },
|
||||||
|
{
|
||||||
|
.name = "max77851-gpio",
|
||||||
|
.resources = gpio_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(gpio_resources),
|
||||||
|
}, {
|
||||||
|
.name = "max77851-rtc",
|
||||||
|
.resources = rtc_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||||
|
}, {
|
||||||
|
.name = "max77851-power",
|
||||||
|
.resources = power_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(power_resources),
|
||||||
|
}, {
|
||||||
|
.name = "max77851-thermal",
|
||||||
|
.resources = thermal_resources,
|
||||||
|
.num_resources = ARRAY_SIZE(thermal_resources),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_range max77851_readable_ranges[] = {
|
||||||
|
regmap_reg_range(TOP_ID_REG, BUCK4_CFG7_REG),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_access_table max77851_readable_table = {
|
||||||
|
.yes_ranges = max77851_readable_ranges,
|
||||||
|
.n_yes_ranges = ARRAY_SIZE(max77851_readable_ranges),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_range max77851_writable_ranges[] = {
|
||||||
|
regmap_reg_range(TOP_ID_REG, BUCK4_CFG7_REG),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_access_table max77851_writable_table = {
|
||||||
|
.yes_ranges = max77851_writable_ranges,
|
||||||
|
.n_yes_ranges = ARRAY_SIZE(max77851_writable_ranges),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct regmap_config max77851_regmap_config = {
|
||||||
|
.name = "max77851-pmic",
|
||||||
|
.reg_bits = 8,
|
||||||
|
.val_bits = 8,
|
||||||
|
.max_register = BUCK4_CFG7_REG + 1,
|
||||||
|
.rd_table = &max77851_readable_table,
|
||||||
|
.wr_table = &max77851_writable_table,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct regmap_irq_chip max77851_top_irq_chip = {
|
||||||
|
.name = "max77851-top",
|
||||||
|
.irqs = max77851_top_irqs,
|
||||||
|
.num_irqs = ARRAY_SIZE(max77851_top_irqs),
|
||||||
|
.num_regs = 2,
|
||||||
|
.status_base = TOP_INT0_REG,
|
||||||
|
.mask_base = TOP_MSK0_REG,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 0 : Mater 0 + Mater 1
|
||||||
|
* 1 : Mater 2 + Mater 3
|
||||||
|
*/
|
||||||
|
static int max77851_master_register_rw_set(struct regmap *rmap, u8 select)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned int val;
|
||||||
|
|
||||||
|
if (IS_MX_MASTER01(select))
|
||||||
|
val = BIT_IS_ZERO;
|
||||||
|
else
|
||||||
|
val = FPS_CFG_MX_RW;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(rmap, FPS_CFG_REG, FPS_CFG_MX_RW, val);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u8 max77851_get_fps_register_addr(unsigned int fps)
|
||||||
|
{
|
||||||
|
u8 ret;
|
||||||
|
|
||||||
|
switch (fps) {
|
||||||
|
case MX_FPS_MASTER0:
|
||||||
|
ret = FPS_M02_CFG0_REG;
|
||||||
|
break;
|
||||||
|
case MX_FPS_MASTER1:
|
||||||
|
ret = FPS_M13_CFG0_REG;
|
||||||
|
break;
|
||||||
|
case MX_FPS_MASTER2:
|
||||||
|
ret = FPS_M02_CFG0_REG;
|
||||||
|
break;
|
||||||
|
case MX_FPS_MASTER3:
|
||||||
|
ret = FPS_M13_CFG0_REG;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = FPS_M02_CFG0_REG;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_config_master_fps(struct max77851_chip *chip)
|
||||||
|
{
|
||||||
|
struct device *dev = chip->dev;
|
||||||
|
struct device_node *np;
|
||||||
|
u32 pval;
|
||||||
|
u32 cnfg0, cnfg1;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
np = of_get_child_by_name(dev->of_node, "fps");
|
||||||
|
if (!np) {
|
||||||
|
dev_err(dev, "FPS master node is not valid: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "maxim,power-down-slot-period-us", &pval);
|
||||||
|
chip->fps_master_pd_slot_period = (!ret) ? pval : FPS_PERIOD_4KHZ_050US;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "maxim,power-up-slot-period-us", &pval);
|
||||||
|
chip->fps_master_pu_slot_period = (!ret) ? pval : FPS_PERIOD_32KHZ_122US;
|
||||||
|
|
||||||
|
cnfg0 = BITS_REAL_VALUE(chip->fps_master_pd_slot_period, MAX77851_FPS_PD_SLOT_MASK) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_pu_slot_period, MAX77851_FPS_PU_SLOT_MASK);
|
||||||
|
|
||||||
|
ret = regmap_write(chip->rmap, FPS_IM_CFG0_REG, (u8)cnfg0);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x write failed, %d\n", FPS_IM_CFG0_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "maxim,sleep-exit-slot-period-us", &pval);
|
||||||
|
chip->fps_master_slpx_slot_period = (!ret) ? pval : FPS_PERIOD_4KHZ_050US;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np, "maxim,sleep-entry-slot-period-us", &pval);
|
||||||
|
chip->fps_master_slpy_slot_period = (!ret) ? pval : FPS_PERIOD_32KHZ_122US;
|
||||||
|
|
||||||
|
cnfg1 = BITS_REAL_VALUE(chip->fps_master_slpy_slot_period, MAX77851_FPS_SLPY_SLOT_MASK) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_slpx_slot_period, MAX77851_FPS_SLPX_SLOT_MASK);
|
||||||
|
|
||||||
|
ret = regmap_write(chip->rmap, FPS_IM_CFG1_REG, (u8)cnfg1);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x write failed, %d\n", FPS_IM_CFG1_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_config_fps(struct max77851_chip *chip,
|
||||||
|
struct device_node *fps_np)
|
||||||
|
{
|
||||||
|
struct device *dev = chip->dev;
|
||||||
|
//unsigned int mask = 0, config = 0;
|
||||||
|
u32 fps_max_period;
|
||||||
|
u32 pval;
|
||||||
|
unsigned int rval;
|
||||||
|
int fps_id;
|
||||||
|
int ret;
|
||||||
|
char fps_name[10];
|
||||||
|
u8 reg_addr;
|
||||||
|
|
||||||
|
fps_max_period = MAX77851_FPS_PERIOD_MAX_US;
|
||||||
|
|
||||||
|
for (fps_id = 0; fps_id < MX_FPS_MASTER_NUM; fps_id++) {
|
||||||
|
sprintf(fps_name, "fps%d", fps_id);
|
||||||
|
if (!strcmp(fps_np->name, fps_name))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fps_id == MX_FPS_MASTER_NUM) {
|
||||||
|
dev_err(dev, "FPS node name fps[%s] is not valid\n", fps_np->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
max77851_master_register_rw_set(chip->rmap, fps_id);
|
||||||
|
|
||||||
|
reg_addr = max77851_get_fps_register_addr(fps_id);
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,fps-enable", &pval);
|
||||||
|
chip->fps_master_data[fps_id].enable = (!ret) ? pval : MAX77851_FPS_DEFAULT;
|
||||||
|
|
||||||
|
if (chip->fps_master_data[fps_id].enable == MAX77851_FPS_DEFAULT) {
|
||||||
|
dev_info(dev, "fps master[%d]: using default setting\n", fps_id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,pd-fps-master-slot", &pval);
|
||||||
|
chip->fps_master_data[fps_id].pd_slot = (!ret) ? pval : FPS_MX_MASTER_SLOT_0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,pu-fps-master-slot", &pval);
|
||||||
|
chip->fps_master_data[fps_id].pu_slot = (!ret) ? pval : FPS_MX_MASTER_SLOT_0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,slpy-fps-master-slot", &pval);
|
||||||
|
chip->fps_master_data[fps_id].slpy_slot = (!ret) ? pval : FPS_MX_MASTER_SLOT_0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,slpx-fps-master-slot", &pval);
|
||||||
|
chip->fps_master_data[fps_id].slpx_slot = (!ret) ? pval : FPS_MX_MASTER_SLOT_0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,power-down-time-period-us", &pval);
|
||||||
|
chip->fps_master_data[fps_id].pd_period = (!ret) ? pval : FPS_PERIOD_4KHZ_100US;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,power-up-time-period-us", &pval);
|
||||||
|
chip->fps_master_data[fps_id].pu_period = (!ret) ? pval : FPS_PERIOD_32KHZ_244US;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,sleep-entry-time-period-us", &pval);
|
||||||
|
chip->fps_master_data[fps_id].slpy_period = (!ret) ? pval : FPS_PERIOD_32KHZ_244US;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,sleep-exit-time-period-us", &pval);
|
||||||
|
chip->fps_master_data[fps_id].slpx_period = (!ret) ? pval : FPS_PERIOD_4KHZ_100US;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,abort-enable", &pval);
|
||||||
|
chip->fps_master_data[fps_id].abort_enable = (!ret) ? pval : MAX77851_FPS_ABORT_DISABLE;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,sleep-enable", &pval);
|
||||||
|
chip->fps_master_data[fps_id].sleep_mode = (!ret) ? pval : MAX77851_FPS_SLEEP_DISABLE;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,abort-mode", &pval);
|
||||||
|
chip->fps_master_data[fps_id].abort_mode = (!ret) ? pval : MAX77851_FPS_ABORT_NEXT_SLOT;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,pd-max-slot", &pval);
|
||||||
|
chip->fps_master_data[fps_id].pd_max_slot = (!ret) ? pval : MAX77851_FPS_16_SLOTS;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,pu-max-slot", &pval);
|
||||||
|
chip->fps_master_data[fps_id].pu_max_slot = (!ret) ? pval : MAX77851_FPS_16_SLOTS;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,slpy-max-slot", &pval);
|
||||||
|
chip->fps_master_data[fps_id].slpy_max_slot = (!ret) ? pval : MAX77851_FPS_16_SLOTS;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(fps_np, "maxim,slpx-max-slot", &pval);
|
||||||
|
chip->fps_master_data[fps_id].slpx_max_slot = (!ret) ? pval : MAX77851_FPS_16_SLOTS;
|
||||||
|
|
||||||
|
rval = BITS_REAL_VALUE(chip->fps_master_data[fps_id].pd_slot, FPS_CFG0_PD) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].pu_slot, FPS_CFG0_PU) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].enable, FPS_CFG0_EN) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].abort_enable, FPS_CFG0_ABT_EN);
|
||||||
|
|
||||||
|
ret = regmap_write(chip->rmap, reg_addr, rval);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x write failed, %d\n", FPS_M02_CFG0_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
rval = BITS_REAL_VALUE(chip->fps_master_data[fps_id].slpy_slot, FPS_CFG1_SLPY) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].slpx_slot, FPS_CFG1_SLPX) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].sleep_mode, FPS_CFG1_SLP_EN) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].abort_mode, FPS_CFG1_ABT);
|
||||||
|
|
||||||
|
ret = regmap_write(chip->rmap, (reg_addr + 1), rval);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x write failed, %d\n", FPS_M02_CFG1_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
rval = BITS_REAL_VALUE(chip->fps_master_data[fps_id].pd_period, FPS_CFG2_PD_T) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].pu_period, FPS_CFG2_PU_T);
|
||||||
|
|
||||||
|
ret = regmap_write(chip->rmap, (reg_addr + 2), rval);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x write failed, %d\n", FPS_M02_CFG2_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
rval = BITS_REAL_VALUE(chip->fps_master_data[fps_id].slpy_period, FPS_CFG3_SLPY_T) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].slpx_period, FPS_CFG3_SLPX_T);
|
||||||
|
|
||||||
|
ret = regmap_write(chip->rmap, (reg_addr + 3), rval);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x write failed, %d\n", FPS_M02_CFG3_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
rval = BITS_REAL_VALUE(chip->fps_master_data[fps_id].pd_max_slot, FPS_CFG4_PD_MAX) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].slpy_max_slot, FPS_CFG4_SLPY_MAX) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].pu_max_slot, FPS_CFG4_PU_MAX) |
|
||||||
|
BITS_REAL_VALUE(chip->fps_master_data[fps_id].slpx_max_slot, FPS_CFG4_SLPX_MAX);
|
||||||
|
|
||||||
|
ret = regmap_write(chip->rmap, (reg_addr + 4), rval);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x write failed, %d\n", FPS_M02_CFG4_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_initialise_fps(struct max77851_chip *chip)
|
||||||
|
{
|
||||||
|
struct device *dev = chip->dev;
|
||||||
|
struct device_node *fps_np, *fps_child;
|
||||||
|
unsigned int val_buf[5];
|
||||||
|
unsigned int val;
|
||||||
|
unsigned int *pval;
|
||||||
|
int fps_num;
|
||||||
|
int ret;
|
||||||
|
u8 reg_addr;
|
||||||
|
|
||||||
|
ret = regmap_read(chip->rmap, FPS_IM_CFG0_REG, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(chip->dev, "Failed to read %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
chip->fps_master_pd_slot_period = BITS_VALUE(val, FPS_IM_CFG0_PD_T);
|
||||||
|
chip->fps_master_pu_slot_period = BITS_VALUE(val, FPS_IM_CFG0_PU_T);
|
||||||
|
|
||||||
|
ret = regmap_read(chip->rmap, FPS_IM_CFG1_REG, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(chip->dev, "Failed to read %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
chip->fps_master_slpy_slot_period = BITS_VALUE(val, FPS_IM_CFG1_SLPY_T);
|
||||||
|
chip->fps_master_slpx_slot_period = BITS_VALUE(val, FPS_IM_CFG1_SLPX_T);
|
||||||
|
|
||||||
|
/* Master 0/1/2/3 Configiuration */
|
||||||
|
|
||||||
|
for (fps_num = 0 ; fps_num < MX_FPS_MASTER_NUM; fps_num++) {
|
||||||
|
max77851_master_register_rw_set(chip->rmap, fps_num);
|
||||||
|
|
||||||
|
reg_addr = max77851_get_fps_register_addr(fps_num);
|
||||||
|
|
||||||
|
ret = regmap_raw_read(chip->rmap, reg_addr, val_buf, MAX77851_FPS_CNFG_LENGTH);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(chip->dev, "Failed to read %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pval = val_buf;
|
||||||
|
|
||||||
|
chip->fps_master_data[fps_num].pd_slot = BITS_VALUE(val_buf[0], FPS_CFG0_PD_MASK);
|
||||||
|
chip->fps_master_data[fps_num].enable = BITS_VALUE(val_buf[0], FPS_CFG0_EN_MASK);
|
||||||
|
chip->fps_master_data[fps_num].pu_slot = BITS_VALUE(val_buf[0], FPS_CFG0_PU_MASK);
|
||||||
|
chip->fps_master_data[fps_num].abort_enable = BITS_VALUE(val_buf[0], FPS_CFG0_ABT_EN_MASK);
|
||||||
|
|
||||||
|
chip->fps_master_data[fps_num].slpx_slot = BITS_VALUE(val_buf[1], FPS_CFG1_SLPX_MASK);
|
||||||
|
chip->fps_master_data[fps_num].slpy_slot = BITS_VALUE(val_buf[1], FPS_CFG1_SLPY_MASK);
|
||||||
|
chip->fps_master_data[fps_num].sleep_mode = BITS_VALUE(val_buf[1], FPS_CFG1_SLP_EN_MASK);
|
||||||
|
chip->fps_master_data[fps_num].abort_mode = BITS_VALUE(val_buf[1], FPS_CFG1_ABT_MASK);
|
||||||
|
|
||||||
|
chip->fps_master_data[fps_num].pd_period = BITS_VALUE(val_buf[2], FPS_CFG2_PD_T_MASK);
|
||||||
|
chip->fps_master_data[fps_num].pu_period = BITS_VALUE(val_buf[2], FPS_CFG2_PU_T_MASK);
|
||||||
|
|
||||||
|
chip->fps_master_data[fps_num].slpx_period = BITS_VALUE(val_buf[3], FPS_CFG3_SLPX_T_MASK);
|
||||||
|
chip->fps_master_data[fps_num].slpy_period = BITS_VALUE(val_buf[3], FPS_CFG3_SLPY_T_MASK);
|
||||||
|
|
||||||
|
chip->fps_master_data[fps_num].pd_max_slot = BITS_VALUE(val_buf[4], FPS_CFG4_PD_MAX_MASK);
|
||||||
|
chip->fps_master_data[fps_num].pu_max_slot = BITS_VALUE(val_buf[4], FPS_CFG4_PU_MAX_MASK);
|
||||||
|
chip->fps_master_data[fps_num].slpy_max_slot = BITS_VALUE(val_buf[4], FPS_CFG4_SLPY_MAX_MASK);
|
||||||
|
chip->fps_master_data[fps_num].slpx_max_slot = BITS_VALUE(val_buf[4], FPS_CFG4_SLPX_MAX_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FPS Master */
|
||||||
|
max77851_config_master_fps(chip);
|
||||||
|
|
||||||
|
fps_np = of_get_child_by_name(dev->of_node, "fps");
|
||||||
|
if (!fps_np)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for_each_child_of_node(fps_np, fps_child) {
|
||||||
|
ret = max77851_config_fps(chip, fps_child);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_init_low_battery_monitor(struct max77851_chip *chip)
|
||||||
|
{
|
||||||
|
struct device *dev = chip->dev;
|
||||||
|
struct device_node *np;
|
||||||
|
u32 pval;
|
||||||
|
u8 mask = 0;
|
||||||
|
u8 val = 0;
|
||||||
|
|
||||||
|
int low_bat_en = 0;
|
||||||
|
int low_bat_alm_en = 0;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
np = of_get_child_by_name(dev->of_node, "low-battery-monitor");
|
||||||
|
if (!np)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np,
|
||||||
|
"maxim,low-battery-enable", &pval);
|
||||||
|
low_bat_en = (!ret) ? pval : MAX77851_LOW_BAT_ENABLE;
|
||||||
|
|
||||||
|
ret = of_property_read_u32(np,
|
||||||
|
"maxim,low-battery-alarm-enable", &pval);
|
||||||
|
low_bat_alm_en = (!ret) ? pval : MAX77851_LOW_BAT_ALARM_ENABLE;
|
||||||
|
|
||||||
|
val = BITS_REAL_VALUE(low_bat_en, TOP_CFG0_LB_EN) |
|
||||||
|
BITS_REAL_VALUE(low_bat_alm_en, TOP_CFG0_LB_ALM_EN);
|
||||||
|
|
||||||
|
mask = TOP_CFG0_LB_EN | TOP_CFG0_LB_ALM_EN;
|
||||||
|
|
||||||
|
ret = regmap_update_bits(chip->rmap, TOP_CFG0_REG, mask, val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x update failed, %d\n", TOP_CFG0_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_read_version(struct max77851_chip *chip)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
u8 cid_val[3];
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for (i = TOP_ID_REG; i <= TOP_OTP_REV_REG; i++) {
|
||||||
|
ret = regmap_read(chip->rmap, i, &val);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(chip->dev, "Failed to read CID: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
cid_val[i] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(chip->dev, "PMIC(0x%X) OTP Revision:0x%X, Device Revision:0x%X\n",
|
||||||
|
cid_val[0], cid_val[2], cid_val[1]);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void max77851_pm_power_off(void)
|
||||||
|
{
|
||||||
|
struct max77851_chip *chip = max77851_chip;
|
||||||
|
|
||||||
|
regmap_update_bits(chip->rmap, FPS_SW_REG,
|
||||||
|
FPS_SW_COLD_RST, FPS_SW_COLD_RST);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
|
||||||
|
static int max77851_probe(struct i2c_client *client)
|
||||||
|
#else
|
||||||
|
static int max77851_probe(struct i2c_client *client,
|
||||||
|
const struct i2c_device_id *id)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
const struct regmap_config *rmap_config;
|
||||||
|
struct max77851_chip *chip;
|
||||||
|
const struct mfd_cell *mfd_cells;
|
||||||
|
int n_mfd_cells;
|
||||||
|
bool pm_off;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||||
|
if (!chip)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
i2c_set_clientdata(client, chip);
|
||||||
|
chip->dev = &client->dev;
|
||||||
|
chip->irq_base = -1;
|
||||||
|
chip->chip_irq = client->irq;
|
||||||
|
|
||||||
|
mfd_cells = max77851_children;
|
||||||
|
n_mfd_cells = ARRAY_SIZE(max77851_children);
|
||||||
|
rmap_config = &max77851_regmap_config;
|
||||||
|
|
||||||
|
|
||||||
|
chip->rmap = devm_regmap_init_i2c(client, rmap_config);
|
||||||
|
if (IS_ERR(chip->rmap)) {
|
||||||
|
ret = PTR_ERR(chip->rmap);
|
||||||
|
dev_err(chip->dev, "Failed to initialise regmap: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = max77851_read_version(chip);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
max77851_top_irq_chip.irq_drv_data = chip;
|
||||||
|
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
|
||||||
|
IRQF_ONESHOT | IRQF_SHARED,
|
||||||
|
chip->irq_base, &max77851_top_irq_chip,
|
||||||
|
&chip->top_irq_data);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = max77851_initialise_fps(chip);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = max77851_init_low_battery_monitor(chip);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = devm_mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE,
|
||||||
|
mfd_cells, n_mfd_cells, NULL, 0,
|
||||||
|
regmap_irq_get_domain(chip->top_irq_data));
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(chip->dev, "Failed to add MFD children: %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pm_off = of_device_is_system_power_controller(client->dev.of_node);
|
||||||
|
|
||||||
|
//if (pm_off && !pm_power_off) {
|
||||||
|
if (pm_off) {
|
||||||
|
max77851_chip = chip;
|
||||||
|
pm_power_off = max77851_pm_power_off;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
|
||||||
|
static int max77851_i2c_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct max77851_chip *chip = dev_get_drvdata(dev);
|
||||||
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* FPS on -> sleep */
|
||||||
|
ret = regmap_write(chip->rmap, FPS_SW_REG, FPS_SW_SLP);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x write failed, %d\n", FPS_SW_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
disable_irq(client->irq);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int max77851_i2c_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct max77851_chip *chip = dev_get_drvdata(dev);
|
||||||
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* FPS sleep -> on */
|
||||||
|
ret = regmap_write(chip->rmap, FPS_SW_REG, FPS_SW_ON);
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(dev, "Reg 0x%02x write failed, %d\n", FPS_SW_REG, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_irq(client->irq);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct i2c_device_id max77851_id[] = {
|
||||||
|
{"maxim,max77851-pmic", 0},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, max77851_id);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static const struct of_device_id max77851_of_match[] = {
|
||||||
|
{.compatible = "maxim,max77851-pmic",},
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, max77851_of_match);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct dev_pm_ops max77851_pm_ops = {
|
||||||
|
SET_SYSTEM_SLEEP_PM_OPS(max77851_i2c_suspend, max77851_i2c_resume)
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_driver max77851_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "maxim,max77851-pmic",
|
||||||
|
.of_match_table = of_match_ptr(max77851_of_match),
|
||||||
|
.pm = &max77851_pm_ops,
|
||||||
|
},
|
||||||
|
.probe = max77851_probe,
|
||||||
|
.id_table = max77851_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int __init max77851_init(void)
|
||||||
|
{
|
||||||
|
return i2c_add_driver(&max77851_driver);
|
||||||
|
}
|
||||||
|
module_init(max77851_init);
|
||||||
|
|
||||||
|
static void __exit max77851_exit(void)
|
||||||
|
{
|
||||||
|
i2c_del_driver(&max77851_driver);
|
||||||
|
}
|
||||||
|
module_exit(max77851_exit);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
module_i2c_driver(max77851_driver);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("MAX77851 Multi Function Device Core Driver");
|
||||||
|
MODULE_AUTHOR("Shubhi Garg<shgarg@nvidia.com>");
|
||||||
|
MODULE_AUTHOR("Joan Na<Joan.na@maximintegrated.com>");
|
||||||
|
MODULE_ALIAS("i2c:max77851");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
||||||
147
include/dt-bindings/mfd/max77851.h
Normal file
147
include/dt-bindings/mfd/max77851.h
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
/* SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
|
||||||
|
/*
|
||||||
|
* This header provides macros for MAXIM MAX77851 device bindings.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DT_BINDINGS_MFD_MAX77851_H
|
||||||
|
#define _DT_BINDINGS_MFD_MAX77851_H
|
||||||
|
|
||||||
|
/* MAX77851 interrupts */
|
||||||
|
#define MAX77851_IRQ_TOP_GLBL 0 /* Low-Battery */
|
||||||
|
#define MAX77851_IRQ_TOP_SD 1 /* SD power fail */
|
||||||
|
#define MAX77851_IRQ_TOP_LDO 2 /* LDO power fail */
|
||||||
|
#define MAX77851_IRQ_TOP_GPIO 3 /* GPIO internal int to MAX77851 */
|
||||||
|
#define MAX77851_IRQ_TOP_RTC 4 /* RTC */
|
||||||
|
#define MAX77851_IRQ_TOP_32K 5 /* 32kHz oscillator */
|
||||||
|
#define MAX77851_IRQ_TOP_ONOFF 6 /* ON/OFF oscillator */
|
||||||
|
#define MAX77851_IRQ_LBT_MBATLOW 7 /* Thermal alarm status, > 120C */
|
||||||
|
#define MAX77851_IRQ_LBT_TJALRM1 8 /* Thermal alarm status, > 120C */
|
||||||
|
#define MAX77851_IRQ_LBT_TJALRM2 9 /* Thermal alarm status, > 140C */
|
||||||
|
|
||||||
|
/* FPS event source */
|
||||||
|
#define MAX77851_FPS_EVENT_SRC_EN0 0
|
||||||
|
#define MAX77851_FPS_EVENT_SRC_EN1 1
|
||||||
|
#define MAX77851_FPS_EVENT_SRC_SW 2
|
||||||
|
|
||||||
|
/* Device state when FPS event LOW */
|
||||||
|
#define MAX77851_FPS_INACTIVE_STATE_SLEEP 0
|
||||||
|
#define MAX77851_FPS_INACTIVE_STATE_LOW_POWER 1
|
||||||
|
|
||||||
|
/* FPS source */
|
||||||
|
#define MAX77851_FPS_SRC_0 0
|
||||||
|
#define MAX77851_FPS_SRC_1 1
|
||||||
|
#define MAX77851_FPS_SRC_2 2
|
||||||
|
|
||||||
|
#define MAX77851_FPS_SRC_NONE 3
|
||||||
|
#define MAX77851_FPS_SRC_DEF 4
|
||||||
|
|
||||||
|
/* FPS Period */
|
||||||
|
#define FPS_PERIOD_32KHZ_30US 0x00
|
||||||
|
#define FPS_PERIOD_32KHZ_61US 0x01
|
||||||
|
#define FPS_PERIOD_32KHZ_122US 0x02
|
||||||
|
#define FPS_PERIOD_32KHZ_244US 0x03
|
||||||
|
#define FPS_PERIOD_32KHZ_488US 0x04
|
||||||
|
#define FPS_PERIOD_32KHZ_762US 0x05
|
||||||
|
#define FPS_PERIOD_32KHZ_1007US 0x06
|
||||||
|
#define FPS_PERIOD_32KHZ_1251US 0x07
|
||||||
|
#define FPS_PERIOD_32KHZ_1495US 0x08
|
||||||
|
#define FPS_PERIOD_32KHZ_1739US 0x09
|
||||||
|
#define FPS_PERIOD_32KHZ_2014US 0x0A
|
||||||
|
#define FPS_PERIOD_32KHZ_2990US 0x0B
|
||||||
|
#define FPS_PERIOD_32KHZ_3997US 0x0C
|
||||||
|
#define FPS_PERIOD_32KHZ_5004US 0x0D
|
||||||
|
#define FPS_PERIOD_32KHZ_6011US 0x0E
|
||||||
|
#define FPS_PERIOD_32KHZ_7995US 0x0F
|
||||||
|
|
||||||
|
#define FPS_PERIOD_4KHZ_025US 0x00
|
||||||
|
#define FPS_PERIOD_4KHZ_050US 0x01
|
||||||
|
#define FPS_PERIOD_4KHZ_1US 0x02
|
||||||
|
#define FPS_PERIOD_4KHZ_2US 0x03
|
||||||
|
#define FPS_PERIOD_4KHZ_4US 0x04
|
||||||
|
#define FPS_PERIOD_4KHZ_8US 0x05
|
||||||
|
#define FPS_PERIOD_4KHZ_16US 0x06
|
||||||
|
#define FPS_PERIOD_4KHZ_25US 0x07
|
||||||
|
#define FPS_PERIOD_4KHZ_50US 0x08
|
||||||
|
#define FPS_PERIOD_4KHZ_100US 0x09
|
||||||
|
#define FPS_PERIOD_4KHZ_250US 0x0A
|
||||||
|
#define FPS_PERIOD_4KHZ_500US 0x0B
|
||||||
|
#define FPS_PERIOD_4KHZ_1000US 0x0C
|
||||||
|
#define FPS_PERIOD_4KHZ_2000US 0x0D
|
||||||
|
#define FPS_PERIOD_4KHZ_3000US 0x0E
|
||||||
|
#define FPS_PERIOD_4KHZ_4000US 0x0F
|
||||||
|
|
||||||
|
/* INPUT DEBOUNCE FILTER */
|
||||||
|
#define MAX77851_NO_RESYNC_NO_DEB 0x00
|
||||||
|
#define MAX77851_RESYNC_NO_DEB 0x01
|
||||||
|
#define MAX77851_RESYNC_100US_DEB 0x02
|
||||||
|
#define MAX77851_RESYNC_1MS_DEB 0x03
|
||||||
|
#define MAX77851_RESYNC_4MS_DEB 0x04
|
||||||
|
#define MAX77851_RESYNC_8MS_DEB 0x05
|
||||||
|
#define MAX77851_RESYNC_16MS_DEB 0x06
|
||||||
|
#define MAX77851_RESYNC_32MS_DEB 0x07
|
||||||
|
|
||||||
|
#define MAX77851_FPS_DISABLE 0x00
|
||||||
|
#define MAX77851_FPS_ENABLE 0x01
|
||||||
|
#define MAX77851_FPS_DEFAULT 0x02
|
||||||
|
|
||||||
|
#define MAX77851_FPS_ABORT_DISABLE 0x00
|
||||||
|
#define MAX77851_FPS_ABORT_ENABLE 0x01
|
||||||
|
|
||||||
|
#define MAX77851_FPS_SLEEP_DISABLE 0x00
|
||||||
|
#define MAX77851_FPS_SLEEP_ENABLE 0x01
|
||||||
|
#define MAX77851_FPS_SLEEP_LPM 0x02
|
||||||
|
#define MAX77851_FPS_SLEEP_ULPM 0x03
|
||||||
|
|
||||||
|
#define MAX77851_FPS_ABORT_NEXT_SLOT 0x00
|
||||||
|
#define MAX77851_FPS_ABORT_NEXT_MASTER_SLOT 0x01
|
||||||
|
|
||||||
|
#define MAX77851_FPS_16_SLOTS 0x00
|
||||||
|
#define MAX77851_FPS_12_SLOTS 0x01
|
||||||
|
#define MAX77851_FPS_10_SLOTS 0x02
|
||||||
|
#define MAX77851_FPS_08_SLOTS 0x03
|
||||||
|
|
||||||
|
#define MAX77851_FPS_MASTER_SLOT_0 0x1
|
||||||
|
#define MAX77851_FPS_MASTER_SLOT_1 0x2
|
||||||
|
#define MAX77851_FPS_MASTER_SLOT_2 0x4
|
||||||
|
#define MAX77851_FPS_MASTER_SLOT_3 0x8
|
||||||
|
|
||||||
|
#define MAX77851_FPS_MX_MASTER_SLOT_0 0x0
|
||||||
|
#define MAX77851_FPS_MX_MASTER_SLOT_1 0x1
|
||||||
|
#define MAX77851_FPS_MX_MASTER_SLOT_2 0x2
|
||||||
|
#define MAX77851_FPS_MX_MASTER_SLOT_3 0x3
|
||||||
|
|
||||||
|
#define MAX77851_FPS_SLOT_0 0x0
|
||||||
|
#define MAX77851_FPS_SLOT_1 0x1
|
||||||
|
#define MAX77851_FPS_SLOT_2 0x2
|
||||||
|
#define MAX77851_FPS_SLOT_3 0x3
|
||||||
|
#define MAX77851_FPS_SLOT_4 0x4
|
||||||
|
#define MAX77851_FPS_SLOT_5 0x5
|
||||||
|
#define MAX77851_FPS_SLOT_6 0x6
|
||||||
|
#define MAX77851_FPS_SLOT_7 0x7
|
||||||
|
#define MAX77851_FPS_SLOT_8 0x8
|
||||||
|
#define MAX77851_FPS_SLOT_9 0x9
|
||||||
|
#define MAX77851_FPS_SLOT_A 0xA
|
||||||
|
#define MAX77851_FPS_SLOT_B 0xB
|
||||||
|
#define MAX77851_FPS_SLOT_C 0xC
|
||||||
|
#define MAX77851_FPS_SLOT_D 0xD
|
||||||
|
#define MAX77851_FPS_SLOT_E 0xE
|
||||||
|
#define MAX77851_FPS_SLOT_F 0xF
|
||||||
|
|
||||||
|
#define MAX77851_LOW_BAT_ENABLE 0x01
|
||||||
|
#define MAX77851_LOW_BAT_DISABLE 0x00
|
||||||
|
|
||||||
|
#define MAX77851_LOW_BAT_ALARM_ENABLE 0x01
|
||||||
|
#define MAX77851_LOW_BAT_ALARM_AUTO_MODE 0x00
|
||||||
|
|
||||||
|
#define MAX77851_PIN_ACTIVE_HIGH 0x00
|
||||||
|
#define MAX77851_PIN_ACTIVE_LOW 0x01
|
||||||
|
|
||||||
|
#define MAX77851_INPUT_VDD 0x00
|
||||||
|
#define MAX77851_INPUT_VIO 0x01
|
||||||
|
#define MAX77851_INPUT_BAT 0x01
|
||||||
|
|
||||||
|
#define MAX77851_VOUT_RNG_LOW 0x0
|
||||||
|
#define MAX77851_VOUT_RNG_MID 0x1
|
||||||
|
#define MAX77851_VOUT_RNG_HIGH 0x2
|
||||||
|
#endif
|
||||||
1719
include/linux/mfd/max77851.h
Normal file
1719
include/linux/mfd/max77851.h
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user