* [PATCH v4 4/7] mfd: mt6397: Add support for MT6392 pmic
2019-06-19 14:20 [PATCH v4 0/7] mt6392: Add support for MediaTek MT6392 PMIC Fabien Parent
` (2 preceding siblings ...)
2019-06-19 14:20 ` [PATCH v4 3/7] dt-bindings: input: mtk-pmic-keys: add MT6392 binding definition Fabien Parent
@ 2019-06-19 14:20 ` Fabien Parent
2019-06-19 14:20 ` [PATCH v4 5/7] regulator: mt6392: Add support for MT6392 regulator Fabien Parent
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Fabien Parent @ 2019-06-19 14:20 UTC (permalink / raw)
To: robh+dt, mark.rutland, matthias.bgg, lee.jones, lgirdwood, broonie
Cc: devicetree, dmitry.torokhov, linux-kernel, Fabien Parent,
linux-mediatek, linux-input, linux-arm-kernel
Update the MT6397 MFD driver to support the MT6392 PMIC.
Signed-off-by: Fabien Parent <fparent@baylibre.com>
---
V4:
* Use DEFINE_RES_* macro to define RTC ressources.
* Use PLATFORM_DEVID_NONE instead of -1 value when registering devices.
V3:
* No change
V2:
* Pass IRQ comain to fix invalid MFD devices IRQs.
* Remove resources and mfd cells for device we don't support.
* Rename IRQ names to follow what's done for MT6397.
---
drivers/mfd/mt6397-core.c | 47 +++
include/linux/mfd/mt6392/core.h | 42 +++
include/linux/mfd/mt6392/registers.h | 487 +++++++++++++++++++++++++++
3 files changed, 576 insertions(+)
create mode 100644 include/linux/mfd/mt6392/core.h
create mode 100644 include/linux/mfd/mt6392/registers.h
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 1e315712870b..fd14d1fc0eeb 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -10,17 +10,27 @@
#include <linux/of_irq.h>
#include <linux/regmap.h>
#include <linux/mfd/core.h>
+#include <linux/mfd/mt6392/core.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/core.h>
+#include <linux/mfd/mt6392/registers.h>
#include <linux/mfd/mt6397/registers.h>
#include <linux/mfd/mt6323/registers.h>
+#define MT6392_RTC_BASE 0x8000
+#define MT6392_RTC_SIZE 0x3e
#define MT6397_RTC_BASE 0xe000
#define MT6397_RTC_SIZE 0x3e
#define MT6323_CID_CODE 0x23
#define MT6391_CID_CODE 0x91
#define MT6397_CID_CODE 0x97
+#define MT6392_CID_CODE 0x92
+
+static const struct resource mt6392_rtc_resources[] = {
+ DEFINE_RES_MEM(MT6392_RTC_BASE, MT6392_RTC_SIZE),
+ DEFINE_RES_IRQ(MT6392_IRQ_RTC),
+};
static const struct resource mt6397_rtc_resources[] = {
DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
@@ -32,11 +42,33 @@ static const struct resource mt6323_keys_resources[] = {
DEFINE_RES_IRQ(MT6323_IRQ_STATUS_FCHRKEY),
};
+static const struct resource mt6392_keys_resources[] = {
+ DEFINE_RES_IRQ(MT6392_IRQ_PWRKEY),
+ DEFINE_RES_IRQ(MT6392_IRQ_FCHRKEY),
+};
+
static const struct resource mt6397_keys_resources[] = {
DEFINE_RES_IRQ(MT6397_IRQ_PWRKEY),
DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY),
};
+static const struct mfd_cell mt6392_devs[] = {
+ {
+ .name = "mt6392-regulator",
+ .of_compatible = "mediatek,mt6392-regulator",
+ }, {
+ .name = "mt6397-rtc",
+ .num_resources = ARRAY_SIZE(mt6392_rtc_resources),
+ .resources = mt6392_rtc_resources,
+ .of_compatible = "mediatek,mt6392-rtc",
+ }, {
+ .name = "mtk-pmic-keys",
+ .num_resources = ARRAY_SIZE(mt6392_keys_resources),
+ .resources = mt6392_keys_resources,
+ .of_compatible = "mediatek,mt6392-keys"
+ },
+};
+
static const struct mfd_cell mt6323_devs[] = {
{
.name = "mt6323-regulator",
@@ -311,6 +343,20 @@ static int mt6397_probe(struct platform_device *pdev)
NULL, 0, pmic->irq_domain);
break;
+ case MT6392_CID_CODE:
+ pmic->int_con[0] = MT6392_INT_CON0;
+ pmic->int_con[1] = MT6392_INT_CON1;
+ pmic->int_status[0] = MT6392_INT_STATUS0;
+ pmic->int_status[1] = MT6392_INT_STATUS1;
+ ret = mt6397_irq_init(pmic);
+ if (ret)
+ return ret;
+
+ ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
+ mt6392_devs, ARRAY_SIZE(mt6392_devs),
+ NULL, 0, pmic->irq_domain);
+ break;
+
default:
dev_err(&pdev->dev, "unsupported chip: %d\n", id);
return -ENODEV;
@@ -327,6 +373,7 @@ static int mt6397_probe(struct platform_device *pdev)
static const struct of_device_id mt6397_of_match[] = {
{ .compatible = "mediatek,mt6397" },
{ .compatible = "mediatek,mt6323" },
+ { .compatible = "mediatek,mt6392" },
{ }
};
MODULE_DEVICE_TABLE(of, mt6397_of_match);
diff --git a/include/linux/mfd/mt6392/core.h b/include/linux/mfd/mt6392/core.h
new file mode 100644
index 000000000000..7575a79ea052
--- /dev/null
+++ b/include/linux/mfd/mt6392/core.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ */
+
+#ifndef __MFD_MT6392_CORE_H__
+#define __MFD_MT6392_CORE_H__
+
+enum MT6392_IRQ_numbers {
+ MT6392_IRQ_SPKL_AB = 0,
+ MT6392_IRQ_SPKL,
+ MT6392_IRQ_BAT_L,
+ MT6392_IRQ_BAT_H,
+ MT6392_IRQ_WATCHDOG,
+ MT6392_IRQ_PWRKEY,
+ MT6392_IRQ_THR_L,
+ MT6392_IRQ_THR_H,
+ MT6392_IRQ_VBATON_UNDET,
+ MT6392_IRQ_BVALID_DET,
+ MT6392_IRQ_CHRDET,
+ MT6392_IRQ_OV,
+ MT6392_IRQ_LDO = 16,
+ MT6392_IRQ_FCHRKEY,
+ MT6392_IRQ_RELEASE_PWRKEY,
+ MT6392_IRQ_RELEASE_FCHRKEY,
+ MT6392_IRQ_RTC,
+ MT6392_IRQ_VPROC,
+ MT6392_IRQ_VSYS,
+ MT6392_IRQ_VCORE,
+ MT6392_IRQ_TYPE_C_CC,
+ MT6392_IRQ_TYPEC_H_MAX,
+ MT6392_IRQ_TYPEC_H_MIN,
+ MT6392_IRQ_TYPEC_L_MAX,
+ MT6392_IRQ_TYPEC_L_MIN,
+ MT6392_IRQ_THR_MAX,
+ MT6392_IRQ_THR_MIN,
+ MT6392_IRQ_NAG_C_DLTV,
+ MT6392_IRQ_NR,
+};
+
+#endif /* __MFD_MT6392_CORE_H__ */
diff --git a/include/linux/mfd/mt6392/registers.h b/include/linux/mfd/mt6392/registers.h
new file mode 100644
index 000000000000..f02b478fc418
--- /dev/null
+++ b/include/linux/mfd/mt6392/registers.h
@@ -0,0 +1,487 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ */
+
+#ifndef __MFD_MT6392_REGISTERS_H__
+#define __MFD_MT6392_REGISTERS_H__
+
+/* PMIC Registers */
+#define MT6392_CHR_CON0 0x0000
+#define MT6392_CHR_CON1 0x0002
+#define MT6392_CHR_CON2 0x0004
+#define MT6392_CHR_CON3 0x0006
+#define MT6392_CHR_CON4 0x0008
+#define MT6392_CHR_CON5 0x000A
+#define MT6392_CHR_CON6 0x000C
+#define MT6392_CHR_CON7 0x000E
+#define MT6392_CHR_CON8 0x0010
+#define MT6392_CHR_CON9 0x0012
+#define MT6392_CHR_CON10 0x0014
+#define MT6392_CHR_CON11 0x0016
+#define MT6392_CHR_CON12 0x0018
+#define MT6392_CHR_CON13 0x001A
+#define MT6392_CHR_CON14 0x001C
+#define MT6392_CHR_CON15 0x001E
+#define MT6392_CHR_CON16 0x0020
+#define MT6392_CHR_CON17 0x0022
+#define MT6392_CHR_CON18 0x0024
+#define MT6392_CHR_CON19 0x0026
+#define MT6392_CHR_CON20 0x0028
+#define MT6392_CHR_CON21 0x002A
+#define MT6392_CHR_CON22 0x002C
+#define MT6392_CHR_CON23 0x002E
+#define MT6392_CHR_CON24 0x0030
+#define MT6392_CHR_CON25 0x0032
+#define MT6392_CHR_CON26 0x0034
+#define MT6392_CHR_CON27 0x0036
+#define MT6392_CHR_CON28 0x0038
+#define MT6392_CHR_CON29 0x003A
+#define MT6392_STRUP_CON0 0x003C
+#define MT6392_STRUP_CON2 0x003E
+#define MT6392_STRUP_CON3 0x0040
+#define MT6392_STRUP_CON4 0x0042
+#define MT6392_STRUP_CON5 0x0044
+#define MT6392_STRUP_CON6 0x0046
+#define MT6392_STRUP_CON7 0x0048
+#define MT6392_STRUP_CON8 0x004A
+#define MT6392_STRUP_CON9 0x004C
+#define MT6392_STRUP_CON10 0x004E
+#define MT6392_STRUP_CON11 0x0050
+#define MT6392_SPK_CON0 0x0052
+#define MT6392_SPK_CON1 0x0054
+#define MT6392_SPK_CON2 0x0056
+#define MT6392_SPK_CON6 0x005E
+#define MT6392_SPK_CON7 0x0060
+#define MT6392_SPK_CON8 0x0062
+#define MT6392_SPK_CON9 0x0064
+#define MT6392_SPK_CON10 0x0066
+#define MT6392_SPK_CON11 0x0068
+#define MT6392_SPK_CON12 0x006A
+#define MT6392_STRUP_CON12 0x006E
+#define MT6392_STRUP_CON13 0x0070
+#define MT6392_STRUP_CON14 0x0072
+#define MT6392_STRUP_CON15 0x0074
+#define MT6392_STRUP_CON16 0x0076
+#define MT6392_STRUP_CON17 0x0078
+#define MT6392_STRUP_CON18 0x007A
+#define MT6392_STRUP_CON19 0x007C
+#define MT6392_STRUP_CON20 0x007E
+#define MT6392_CID 0x0100
+#define MT6392_TOP_CKPDN0 0x0102
+#define MT6392_TOP_CKPDN0_SET 0x0104
+#define MT6392_TOP_CKPDN0_CLR 0x0106
+#define MT6392_TOP_CKPDN1 0x0108
+#define MT6392_TOP_CKPDN1_SET 0x010A
+#define MT6392_TOP_CKPDN1_CLR 0x010C
+#define MT6392_TOP_CKPDN2 0x010E
+#define MT6392_TOP_CKPDN2_SET 0x0110
+#define MT6392_TOP_CKPDN2_CLR 0x0112
+#define MT6392_TOP_RST_CON 0x0114
+#define MT6392_TOP_RST_CON_SET 0x0116
+#define MT6392_TOP_RST_CON_CLR 0x0118
+#define MT6392_TOP_RST_MISC 0x011A
+#define MT6392_TOP_RST_MISC_SET 0x011C
+#define MT6392_TOP_RST_MISC_CLR 0x011E
+#define MT6392_TOP_CKCON0 0x0120
+#define MT6392_TOP_CKCON0_SET 0x0122
+#define MT6392_TOP_CKCON0_CLR 0x0124
+#define MT6392_TOP_CKCON1 0x0126
+#define MT6392_TOP_CKCON1_SET 0x0128
+#define MT6392_TOP_CKCON1_CLR 0x012A
+#define MT6392_TOP_CKTST0 0x012C
+#define MT6392_TOP_CKTST1 0x012E
+#define MT6392_TOP_CKTST2 0x0130
+#define MT6392_TEST_OUT 0x0132
+#define MT6392_TEST_CON0 0x0134
+#define MT6392_TEST_CON1 0x0136
+#define MT6392_EN_STATUS0 0x0138
+#define MT6392_EN_STATUS1 0x013A
+#define MT6392_OCSTATUS0 0x013C
+#define MT6392_OCSTATUS1 0x013E
+#define MT6392_PGSTATUS 0x0140
+#define MT6392_CHRSTATUS 0x0142
+#define MT6392_TDSEL_CON 0x0144
+#define MT6392_RDSEL_CON 0x0146
+#define MT6392_SMT_CON0 0x0148
+#define MT6392_SMT_CON1 0x014A
+#define MT6392_DRV_CON0 0x0152
+#define MT6392_DRV_CON1 0x0154
+#define MT6392_INT_CON0 0x0160
+#define MT6392_INT_CON0_SET 0x0162
+#define MT6392_INT_CON0_CLR 0x0164
+#define MT6392_INT_CON1 0x0166
+#define MT6392_INT_CON1_SET 0x0168
+#define MT6392_INT_CON1_CLR 0x016A
+#define MT6392_INT_MISC_CON 0x016C
+#define MT6392_INT_MISC_CON_SET 0x016E
+#define MT6392_INT_MISC_CON_CLR 0x0170
+#define MT6392_INT_STATUS0 0x0172
+#define MT6392_INT_STATUS1 0x0174
+#define MT6392_OC_GEAR_0 0x0176
+#define MT6392_OC_GEAR_1 0x0178
+#define MT6392_OC_GEAR_2 0x017A
+#define MT6392_OC_CTL_VPROC 0x017C
+#define MT6392_OC_CTL_VSYS 0x017E
+#define MT6392_OC_CTL_VCORE 0x0180
+#define MT6392_FQMTR_CON0 0x0182
+#define MT6392_FQMTR_CON1 0x0184
+#define MT6392_FQMTR_CON2 0x0186
+#define MT6392_RG_SPI_CON 0x0188
+#define MT6392_DEW_DIO_EN 0x018A
+#define MT6392_DEW_READ_TEST 0x018C
+#define MT6392_DEW_WRITE_TEST 0x018E
+#define MT6392_DEW_CRC_SWRST 0x0190
+#define MT6392_DEW_CRC_EN 0x0192
+#define MT6392_DEW_CRC_VAL 0x0194
+#define MT6392_DEW_DBG_MON_SEL 0x0196
+#define MT6392_DEW_CIPHER_KEY_SEL 0x0198
+#define MT6392_DEW_CIPHER_IV_SEL 0x019A
+#define MT6392_DEW_CIPHER_EN 0x019C
+#define MT6392_DEW_CIPHER_RDY 0x019E
+#define MT6392_DEW_CIPHER_MODE 0x01A0
+#define MT6392_DEW_CIPHER_SWRST 0x01A2
+#define MT6392_DEW_RDDMY_NO 0x01A4
+#define MT6392_DEW_RDATA_DLY_SEL 0x01A6
+#define MT6392_CLK_TRIM_CON0 0x01A8
+#define MT6392_BUCK_CON0 0x0200
+#define MT6392_BUCK_CON1 0x0202
+#define MT6392_BUCK_CON2 0x0204
+#define MT6392_BUCK_CON3 0x0206
+#define MT6392_BUCK_CON4 0x0208
+#define MT6392_BUCK_CON5 0x020A
+#define MT6392_VPROC_CON0 0x020C
+#define MT6392_VPROC_CON1 0x020E
+#define MT6392_VPROC_CON2 0x0210
+#define MT6392_VPROC_CON3 0x0212
+#define MT6392_VPROC_CON4 0x0214
+#define MT6392_VPROC_CON5 0x0216
+#define MT6392_VPROC_CON7 0x021A
+#define MT6392_VPROC_CON8 0x021C
+#define MT6392_VPROC_CON9 0x021E
+#define MT6392_VPROC_CON10 0x0220
+#define MT6392_VPROC_CON11 0x0222
+#define MT6392_VPROC_CON12 0x0224
+#define MT6392_VPROC_CON13 0x0226
+#define MT6392_VPROC_CON14 0x0228
+#define MT6392_VPROC_CON15 0x022A
+#define MT6392_VPROC_CON18 0x0230
+#define MT6392_VSYS_CON0 0x0232
+#define MT6392_VSYS_CON1 0x0234
+#define MT6392_VSYS_CON2 0x0236
+#define MT6392_VSYS_CON3 0x0238
+#define MT6392_VSYS_CON4 0x023A
+#define MT6392_VSYS_CON5 0x023C
+#define MT6392_VSYS_CON7 0x0240
+#define MT6392_VSYS_CON8 0x0242
+#define MT6392_VSYS_CON9 0x0244
+#define MT6392_VSYS_CON10 0x0246
+#define MT6392_VSYS_CON11 0x0248
+#define MT6392_VSYS_CON12 0x024A
+#define MT6392_VSYS_CON13 0x024C
+#define MT6392_VSYS_CON14 0x024E
+#define MT6392_VSYS_CON15 0x0250
+#define MT6392_VSYS_CON18 0x0256
+#define MT6392_BUCK_OC_CON0 0x0258
+#define MT6392_BUCK_OC_CON1 0x025A
+#define MT6392_BUCK_OC_CON2 0x025C
+#define MT6392_BUCK_OC_CON3 0x025E
+#define MT6392_BUCK_OC_CON4 0x0260
+#define MT6392_BUCK_OC_VPROC_CON0 0x0262
+#define MT6392_BUCK_OC_VCORE_CON0 0x0264
+#define MT6392_BUCK_OC_VSYS_CON0 0x0266
+#define MT6392_BUCK_ANA_MON_CON0 0x0268
+#define MT6392_BUCK_EFUSE_OC_CON0 0x026A
+#define MT6392_VCORE_CON0 0x0300
+#define MT6392_VCORE_CON1 0x0302
+#define MT6392_VCORE_CON2 0x0304
+#define MT6392_VCORE_CON3 0x0306
+#define MT6392_VCORE_CON4 0x0308
+#define MT6392_VCORE_CON5 0x030A
+#define MT6392_VCORE_CON7 0x030E
+#define MT6392_VCORE_CON8 0x0310
+#define MT6392_VCORE_CON9 0x0312
+#define MT6392_VCORE_CON10 0x0314
+#define MT6392_VCORE_CON11 0x0316
+#define MT6392_VCORE_CON12 0x0318
+#define MT6392_VCORE_CON13 0x031A
+#define MT6392_VCORE_CON14 0x031C
+#define MT6392_VCORE_CON15 0x031E
+#define MT6392_VCORE_CON18 0x0324
+#define MT6392_BUCK_K_CON0 0x032A
+#define MT6392_BUCK_K_CON1 0x032C
+#define MT6392_BUCK_K_CON2 0x032E
+#define MT6392_ANALDO_CON0 0x0400
+#define MT6392_ANALDO_CON1 0x0402
+#define MT6392_ANALDO_CON2 0x0404
+#define MT6392_ANALDO_CON3 0x0406
+#define MT6392_ANALDO_CON4 0x0408
+#define MT6392_ANALDO_CON6 0x040C
+#define MT6392_ANALDO_CON7 0x040E
+#define MT6392_ANALDO_CON8 0x0410
+#define MT6392_ANALDO_CON10 0x0412
+#define MT6392_ANALDO_CON15 0x0414
+#define MT6392_ANALDO_CON16 0x0416
+#define MT6392_ANALDO_CON17 0x0418
+#define MT6392_ANALDO_CON21 0x0420
+#define MT6392_ANALDO_CON22 0x0422
+#define MT6392_ANALDO_CON23 0x0424
+#define MT6392_ANALDO_CON24 0x0426
+#define MT6392_ANALDO_CON25 0x0428
+#define MT6392_ANALDO_CON26 0x042A
+#define MT6392_ANALDO_CON27 0x042C
+#define MT6392_ANALDO_CON28 0x042E
+#define MT6392_ANALDO_CON29 0x0430
+#define MT6392_DIGLDO_CON0 0x0500
+#define MT6392_DIGLDO_CON2 0x0502
+#define MT6392_DIGLDO_CON3 0x0504
+#define MT6392_DIGLDO_CON5 0x0506
+#define MT6392_DIGLDO_CON6 0x0508
+#define MT6392_DIGLDO_CON7 0x050A
+#define MT6392_DIGLDO_CON8 0x050C
+#define MT6392_DIGLDO_CON10 0x0510
+#define MT6392_DIGLDO_CON11 0x0512
+#define MT6392_DIGLDO_CON12 0x0514
+#define MT6392_DIGLDO_CON15 0x051A
+#define MT6392_DIGLDO_CON20 0x0524
+#define MT6392_DIGLDO_CON21 0x0526
+#define MT6392_DIGLDO_CON23 0x0528
+#define MT6392_DIGLDO_CON24 0x052A
+#define MT6392_DIGLDO_CON26 0x052C
+#define MT6392_DIGLDO_CON27 0x052E
+#define MT6392_DIGLDO_CON28 0x0530
+#define MT6392_DIGLDO_CON29 0x0532
+#define MT6392_DIGLDO_CON30 0x0534
+#define MT6392_DIGLDO_CON31 0x0536
+#define MT6392_DIGLDO_CON32 0x0538
+#define MT6392_DIGLDO_CON33 0x053A
+#define MT6392_DIGLDO_CON36 0x0540
+#define MT6392_DIGLDO_CON41 0x0546
+#define MT6392_DIGLDO_CON44 0x054C
+#define MT6392_DIGLDO_CON47 0x0552
+#define MT6392_DIGLDO_CON48 0x0554
+#define MT6392_DIGLDO_CON49 0x0556
+#define MT6392_DIGLDO_CON50 0x0558
+#define MT6392_DIGLDO_CON51 0x055A
+#define MT6392_DIGLDO_CON52 0x055C
+#define MT6392_DIGLDO_CON53 0x055E
+#define MT6392_DIGLDO_CON54 0x0560
+#define MT6392_DIGLDO_CON55 0x0562
+#define MT6392_DIGLDO_CON56 0x0564
+#define MT6392_DIGLDO_CON57 0x0566
+#define MT6392_DIGLDO_CON58 0x0568
+#define MT6392_DIGLDO_CON59 0x056A
+#define MT6392_DIGLDO_CON60 0x056C
+#define MT6392_DIGLDO_CON61 0x056E
+#define MT6392_DIGLDO_CON62 0x0570
+#define MT6392_DIGLDO_CON63 0x0572
+#define MT6392_EFUSE_CON0 0x0600
+#define MT6392_EFUSE_CON1 0x0602
+#define MT6392_EFUSE_CON2 0x0604
+#define MT6392_EFUSE_CON3 0x0606
+#define MT6392_EFUSE_CON4 0x0608
+#define MT6392_EFUSE_CON5 0x060A
+#define MT6392_EFUSE_CON6 0x060C
+#define MT6392_EFUSE_VAL_0_15 0x060E
+#define MT6392_EFUSE_VAL_16_31 0x0610
+#define MT6392_EFUSE_VAL_32_47 0x0612
+#define MT6392_EFUSE_VAL_48_63 0x0614
+#define MT6392_EFUSE_VAL_64_79 0x0616
+#define MT6392_EFUSE_VAL_80_95 0x0618
+#define MT6392_EFUSE_VAL_96_111 0x061A
+#define MT6392_EFUSE_VAL_112_127 0x061C
+#define MT6392_EFUSE_VAL_128_143 0x061E
+#define MT6392_EFUSE_VAL_144_159 0x0620
+#define MT6392_EFUSE_VAL_160_175 0x0622
+#define MT6392_EFUSE_VAL_176_191 0x0624
+#define MT6392_EFUSE_VAL_192_207 0x0626
+#define MT6392_EFUSE_VAL_208_223 0x0628
+#define MT6392_EFUSE_VAL_224_239 0x062A
+#define MT6392_EFUSE_VAL_240_255 0x062C
+#define MT6392_EFUSE_VAL_256_271 0x062E
+#define MT6392_EFUSE_VAL_272_287 0x0630
+#define MT6392_EFUSE_VAL_288_303 0x0632
+#define MT6392_EFUSE_VAL_304_319 0x0634
+#define MT6392_EFUSE_VAL_320_335 0x0636
+#define MT6392_EFUSE_VAL_336_351 0x0638
+#define MT6392_EFUSE_VAL_352_367 0x063A
+#define MT6392_EFUSE_VAL_368_383 0x063C
+#define MT6392_EFUSE_VAL_384_399 0x063E
+#define MT6392_EFUSE_VAL_400_415 0x0640
+#define MT6392_EFUSE_VAL_416_431 0x0642
+#define MT6392_RTC_MIX_CON0 0x0644
+#define MT6392_RTC_MIX_CON1 0x0646
+#define MT6392_EFUSE_VAL_432_447 0x0648
+#define MT6392_EFUSE_VAL_448_463 0x064A
+#define MT6392_EFUSE_VAL_464_479 0x064C
+#define MT6392_EFUSE_VAL_480_495 0x064E
+#define MT6392_EFUSE_VAL_496_511 0x0650
+#define MT6392_EFUSE_DOUT_0_15 0x0652
+#define MT6392_EFUSE_DOUT_16_31 0x0654
+#define MT6392_EFUSE_DOUT_32_47 0x0656
+#define MT6392_EFUSE_DOUT_48_63 0x0658
+#define MT6392_EFUSE_DOUT_64_79 0x065A
+#define MT6392_EFUSE_DOUT_80_95 0x065C
+#define MT6392_EFUSE_DOUT_96_111 0x065E
+#define MT6392_EFUSE_DOUT_112_127 0x0660
+#define MT6392_EFUSE_DOUT_128_143 0x0662
+#define MT6392_EFUSE_DOUT_144_159 0x0664
+#define MT6392_EFUSE_DOUT_160_175 0x0666
+#define MT6392_EFUSE_DOUT_176_191 0x0668
+#define MT6392_EFUSE_DOUT_192_207 0x066A
+#define MT6392_EFUSE_DOUT_208_223 0x066C
+#define MT6392_EFUSE_DOUT_224_239 0x066E
+#define MT6392_EFUSE_DOUT_240_255 0x0670
+#define MT6392_EFUSE_DOUT_256_271 0x0672
+#define MT6392_EFUSE_DOUT_272_287 0x0674
+#define MT6392_EFUSE_DOUT_288_303 0x0676
+#define MT6392_EFUSE_DOUT_304_319 0x0678
+#define MT6392_EFUSE_DOUT_320_335 0x067A
+#define MT6392_EFUSE_DOUT_336_351 0x067C
+#define MT6392_EFUSE_DOUT_352_367 0x067E
+#define MT6392_EFUSE_DOUT_368_383 0x0680
+#define MT6392_EFUSE_DOUT_384_399 0x0682
+#define MT6392_EFUSE_DOUT_400_415 0x0684
+#define MT6392_EFUSE_DOUT_416_431 0x0686
+#define MT6392_EFUSE_DOUT_432_447 0x0688
+#define MT6392_EFUSE_DOUT_448_463 0x068A
+#define MT6392_EFUSE_DOUT_464_479 0x068C
+#define MT6392_EFUSE_DOUT_480_495 0x068E
+#define MT6392_EFUSE_DOUT_496_511 0x0690
+#define MT6392_EFUSE_CON7 0x0692
+#define MT6392_EFUSE_CON8 0x0694
+#define MT6392_EFUSE_CON9 0x0696
+#define MT6392_AUXADC_ADC0 0x0700
+#define MT6392_AUXADC_ADC1 0x0702
+#define MT6392_AUXADC_ADC2 0x0704
+#define MT6392_AUXADC_ADC3 0x0706
+#define MT6392_AUXADC_ADC4 0x0708
+#define MT6392_AUXADC_ADC5 0x070A
+#define MT6392_AUXADC_ADC6 0x070C
+#define MT6392_AUXADC_ADC7 0x070E
+#define MT6392_AUXADC_ADC8 0x0710
+#define MT6392_AUXADC_ADC9 0x0712
+#define MT6392_AUXADC_ADC10 0x0714
+#define MT6392_AUXADC_ADC11 0x0716
+#define MT6392_AUXADC_ADC12 0x0718
+#define MT6392_AUXADC_ADC13 0x071A
+#define MT6392_AUXADC_ADC14 0x071C
+#define MT6392_AUXADC_ADC15 0x071E
+#define MT6392_AUXADC_ADC16 0x0720
+#define MT6392_AUXADC_ADC17 0x0722
+#define MT6392_AUXADC_ADC18 0x0724
+#define MT6392_AUXADC_ADC19 0x0726
+#define MT6392_AUXADC_ADC20 0x0728
+#define MT6392_AUXADC_ADC21 0x072A
+#define MT6392_AUXADC_ADC22 0x072C
+#define MT6392_AUXADC_STA0 0x072E
+#define MT6392_AUXADC_STA1 0x0730
+#define MT6392_AUXADC_RQST0 0x0732
+#define MT6392_AUXADC_RQST0_SET 0x0734
+#define MT6392_AUXADC_RQST0_CLR 0x0736
+#define MT6392_AUXADC_CON0 0x0738
+#define MT6392_AUXADC_CON0_SET 0x073A
+#define MT6392_AUXADC_CON0_CLR 0x073C
+#define MT6392_AUXADC_CON1 0x073E
+#define MT6392_AUXADC_CON2 0x0740
+#define MT6392_AUXADC_CON3 0x0742
+#define MT6392_AUXADC_CON4 0x0744
+#define MT6392_AUXADC_CON5 0x0746
+#define MT6392_AUXADC_CON6 0x0748
+#define MT6392_AUXADC_CON7 0x074A
+#define MT6392_AUXADC_CON8 0x074C
+#define MT6392_AUXADC_CON9 0x074E
+#define MT6392_AUXADC_CON10 0x0750
+#define MT6392_AUXADC_CON11 0x0752
+#define MT6392_AUXADC_CON12 0x0754
+#define MT6392_AUXADC_CON13 0x0756
+#define MT6392_AUXADC_CON14 0x0758
+#define MT6392_AUXADC_CON15 0x075A
+#define MT6392_AUXADC_CON16 0x075C
+#define MT6392_AUXADC_AUTORPT0 0x075E
+#define MT6392_AUXADC_LBAT0 0x0760
+#define MT6392_AUXADC_LBAT1 0x0762
+#define MT6392_AUXADC_LBAT2 0x0764
+#define MT6392_AUXADC_LBAT3 0x0766
+#define MT6392_AUXADC_LBAT4 0x0768
+#define MT6392_AUXADC_LBAT5 0x076A
+#define MT6392_AUXADC_LBAT6 0x076C
+#define MT6392_AUXADC_THR0 0x076E
+#define MT6392_AUXADC_THR1 0x0770
+#define MT6392_AUXADC_THR2 0x0772
+#define MT6392_AUXADC_THR3 0x0774
+#define MT6392_AUXADC_THR4 0x0776
+#define MT6392_AUXADC_THR5 0x0778
+#define MT6392_AUXADC_THR6 0x077A
+#define MT6392_AUXADC_EFUSE0 0x077C
+#define MT6392_AUXADC_EFUSE1 0x077E
+#define MT6392_AUXADC_EFUSE2 0x0780
+#define MT6392_AUXADC_EFUSE3 0x0782
+#define MT6392_AUXADC_EFUSE4 0x0784
+#define MT6392_AUXADC_EFUSE5 0x0786
+#define MT6392_AUXADC_NAG_0 0x0788
+#define MT6392_AUXADC_NAG_1 0x078A
+#define MT6392_AUXADC_NAG_2 0x078C
+#define MT6392_AUXADC_NAG_3 0x078E
+#define MT6392_AUXADC_NAG_4 0x0790
+#define MT6392_AUXADC_NAG_5 0x0792
+#define MT6392_AUXADC_NAG_6 0x0794
+#define MT6392_AUXADC_NAG_7 0x0796
+#define MT6392_AUXADC_NAG_8 0x0798
+#define MT6392_AUXADC_TYPEC_H_1 0x079A
+#define MT6392_AUXADC_TYPEC_H_2 0x079C
+#define MT6392_AUXADC_TYPEC_H_3 0x079E
+#define MT6392_AUXADC_TYPEC_H_4 0x07A0
+#define MT6392_AUXADC_TYPEC_H_5 0x07A2
+#define MT6392_AUXADC_TYPEC_H_6 0x07A4
+#define MT6392_AUXADC_TYPEC_H_7 0x07A6
+#define MT6392_AUXADC_TYPEC_L_1 0x07A8
+#define MT6392_AUXADC_TYPEC_L_2 0x07AA
+#define MT6392_AUXADC_TYPEC_L_3 0x07AC
+#define MT6392_AUXADC_TYPEC_L_4 0x07AE
+#define MT6392_AUXADC_TYPEC_L_5 0x07B0
+#define MT6392_AUXADC_TYPEC_L_6 0x07B2
+#define MT6392_AUXADC_TYPEC_L_7 0x07B4
+#define MT6392_AUXADC_NAG_9 0x07B6
+#define MT6392_TYPE_C_PHY_RG_0 0x0800
+#define MT6392_TYPE_C_PHY_RG_CC_RESERVE_CSR 0x0802
+#define MT6392_TYPE_C_VCMP_CTRL 0x0804
+#define MT6392_TYPE_C_CTRL 0x0806
+#define MT6392_TYPE_C_CC_SW_CTRL 0x080a
+#define MT6392_TYPE_C_CC_VOL_PERIODIC_MEAS_VAL 0x080c
+#define MT6392_TYPE_C_CC_VOL_DEBOUCE_CNT_VAL 0x080e
+#define MT6392_TYPE_C_DRP_SRC_CNT_VAL_0 0x0810
+#define MT6392_TYPE_C_DRP_SNK_CNT_VAL_0 0x0814
+#define MT6392_TYPE_C_DRP_TRY_CNT_VAL_0 0x0818
+#define MT6392_TYPE_C_CC_SRC_DEFAULT_DAC_VAL 0x0820
+#define MT6392_TYPE_C_CC_SRC_15_DAC_VAL 0x0822
+#define MT6392_TYPE_C_CC_SRC_30_DAC_VAL 0x0824
+#define MT6392_TYPE_C_CC_SNK_DAC_VAL_0 0x0828
+#define MT6392_TYPE_C_CC_SNK_DAC_VAL_1 0x082a
+#define MT6392_TYPE_C_INTR_EN_0 0x0830
+#define MT6392_TYPE_C_INTR_EN_2 0x0834
+#define MT6392_TYPE_C_INTR_0 0x0838
+#define MT6392_TYPE_C_INTR_2 0x083C
+#define MT6392_TYPE_C_CC_STATUS 0x0840
+#define MT6392_TYPE_C_PWR_STATUS 0x0842
+#define MT6392_TYPE_C_PHY_RG_CC1_RESISTENCE_0 0x0844
+#define MT6392_TYPE_C_PHY_RG_CC1_RESISTENCE_1 0x0846
+#define MT6392_TYPE_C_PHY_RG_CC2_RESISTENCE_0 0x0848
+#define MT6392_TYPE_C_PHY_RG_CC2_RESISTENCE_1 0x084a
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_ENABLE_0 0x0860
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_VAL_0 0x0864
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_VAL_1 0x0866
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_ENABLE_1 0x0868
+#define MT6392_TYPE_C_CC_SW_FORCE_MODE_VAL_2 0x086c
+#define MT6392_TYPE_C_CC_DAC_CALI_CTRL 0x0870
+#define MT6392_TYPE_C_CC_DAC_CALI_RESULT 0x0872
+#define MT6392_TYPE_C_DEBUG_PORT_SELECT_0 0x0880
+#define MT6392_TYPE_C_DEBUG_PORT_SELECT_1 0x0882
+#define MT6392_TYPE_C_DEBUG_MODE_SELECT 0x0884
+#define MT6392_TYPE_C_DEBUG_OUT_READ_0 0x0888
+#define MT6392_TYPE_C_DEBUG_OUT_READ_1 0x088a
+#define MT6392_TYPE_C_SW_DEBUG_PORT_0 0x088c
+#define MT6392_TYPE_C_SW_DEBUG_PORT_1 0x088e
+
+#endif /* __MFD_MT6392_REGISTERS_H__ */
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 5/7] regulator: mt6392: Add support for MT6392 regulator
2019-06-19 14:20 [PATCH v4 0/7] mt6392: Add support for MediaTek MT6392 PMIC Fabien Parent
` (3 preceding siblings ...)
2019-06-19 14:20 ` [PATCH v4 4/7] mfd: mt6397: Add support for MT6392 pmic Fabien Parent
@ 2019-06-19 14:20 ` Fabien Parent
2019-06-19 14:20 ` [PATCH v4 6/7] input: keyboard: mtk-pmic-keys: add MT6392 support Fabien Parent
2019-06-19 14:20 ` [PATCH v4 7/7] arm64: dts: mt6392: Add PMIC mt6392 dtsi Fabien Parent
6 siblings, 0 replies; 8+ messages in thread
From: Fabien Parent @ 2019-06-19 14:20 UTC (permalink / raw)
To: robh+dt, mark.rutland, matthias.bgg, lee.jones, lgirdwood, broonie
Cc: devicetree, dmitry.torokhov, linux-kernel, Fabien Parent,
linux-mediatek, linux-input, linux-arm-kernel
The MT6392 is a regulator found on boards based on the MediaTek
MT8167, MT8516, and probably other SoCs. It is a so called PMIC and
connectcts as a slave to a SoC using SPI, wrapped inside PWRAP.
Signed-off-by: Fabien Parent <fparent@baylibre.com>
---
V4:
* No change
V3:
* fix regulator's of_match following the renaming of the of nodes.
V2:
* no changes
---
drivers/regulator/Kconfig | 9 +
drivers/regulator/Makefile | 1 +
drivers/regulator/mt6392-regulator.c | 490 +++++++++++++++++++++
include/linux/regulator/mt6392-regulator.h | 40 ++
4 files changed, 540 insertions(+)
create mode 100644 drivers/regulator/mt6392-regulator.c
create mode 100644 include/linux/regulator/mt6392-regulator.h
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 8553bdf87c1d..6f6865b95c36 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -626,6 +626,15 @@ config REGULATOR_MT6380
This driver supports the control of different power rails of device
through regulator interface.
+config REGULATOR_MT6392
+ tristate "MediaTek MT6392 PMIC"
+ depends on MFD_MT6397
+ help
+ Say y here to select this option to enable the power regulator of
+ MediaTek MT6392 PMIC.
+ This driver supports the control of different power rails of device
+ through regulator interface.
+
config REGULATOR_MT6397
tristate "MediaTek MT6397 PMIC"
depends on MFD_MT6397
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 93f53840e8f1..fc67a215479d 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -80,6 +80,7 @@ obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
+obj-$(CONFIG_REGULATOR_MT6392) += mt6392-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPMH) += qcom-rpmh-regulator.o
diff --git a/drivers/regulator/mt6392-regulator.c b/drivers/regulator/mt6392-regulator.c
new file mode 100644
index 000000000000..2b7dcf3c72e8
--- /dev/null
+++ b/drivers/regulator/mt6392-regulator.c
@@ -0,0 +1,490 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/mfd/mt6392/registers.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/mt6392-regulator.h>
+#include <linux/regulator/of_regulator.h>
+
+#define MT6392_BUCK_MODE_AUTO 0
+#define MT6392_BUCK_MODE_FORCE_PWM 1
+#define MT6392_LDO_MODE_NORMAL 0
+#define MT6392_LDO_MODE_LP 1
+
+/*
+ * MT6392 regulators' information
+ *
+ * @desc: standard fields of regulator description.
+ * @qi: Mask for query enable signal status of regulators
+ * @vselon_reg: Register sections for hardware control mode of bucks
+ * @vselctrl_reg: Register for controlling the buck control mode.
+ * @vselctrl_mask: Mask for query buck's voltage control mode.
+ */
+struct mt6392_regulator_info {
+ struct regulator_desc desc;
+ u32 qi;
+ u32 vselon_reg;
+ u32 vselctrl_reg;
+ u32 vselctrl_mask;
+ u32 modeset_reg;
+ u32 modeset_mask;
+};
+
+#define MT6392_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \
+ vosel, vosel_mask, voselon, vosel_ctrl, \
+ _modeset_reg, _modeset_mask) \
+[MT6392_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6392_volt_range_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6392_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = (max - min)/step + 1, \
+ .linear_ranges = volt_ranges, \
+ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
+ .vsel_reg = vosel, \
+ .vsel_mask = vosel_mask, \
+ .enable_reg = enreg, \
+ .enable_mask = BIT(0), \
+ }, \
+ .qi = BIT(13), \
+ .vselon_reg = voselon, \
+ .vselctrl_reg = vosel_ctrl, \
+ .vselctrl_mask = BIT(1), \
+ .modeset_reg = _modeset_reg, \
+ .modeset_mask = _modeset_mask, \
+}
+
+#define MT6392_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \
+ vosel_mask, _modeset_reg, _modeset_mask) \
+[MT6392_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6392_volt_table_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6392_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ARRAY_SIZE(ldo_volt_table), \
+ .volt_table = ldo_volt_table, \
+ .vsel_reg = vosel, \
+ .vsel_mask = vosel_mask, \
+ .enable_reg = enreg, \
+ .enable_mask = BIT(enbit), \
+ }, \
+ .qi = BIT(15), \
+ .modeset_reg = _modeset_reg, \
+ .modeset_mask = _modeset_mask, \
+}
+
+#define MT6392_REG_FIXED(match, vreg, enreg, enbit, volt, \
+ _modeset_reg, _modeset_mask) \
+[MT6392_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6392_volt_fixed_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6392_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = 1, \
+ .enable_reg = enreg, \
+ .enable_mask = BIT(enbit), \
+ .min_uV = volt, \
+ }, \
+ .qi = BIT(15), \
+ .modeset_reg = _modeset_reg, \
+ .modeset_mask = _modeset_mask, \
+}
+
+static const struct regulator_linear_range buck_volt_range1[] = {
+ REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250),
+};
+
+static const struct regulator_linear_range buck_volt_range2[] = {
+ REGULATOR_LINEAR_RANGE(1400000, 0, 0x7f, 12500),
+};
+
+static const u32 ldo_volt_table1[] = {
+ 1800000, 1900000, 2000000, 2200000,
+};
+
+static const u32 ldo_volt_table2[] = {
+ 3300000, 3400000, 3500000, 3600000,
+};
+
+static const u32 ldo_volt_table3[] = {
+ 1800000, 3300000,
+};
+
+static const u32 ldo_volt_table4[] = {
+ 3000000, 3300000,
+};
+
+static const u32 ldo_volt_table5[] = {
+ 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, 3300000,
+};
+
+static const u32 ldo_volt_table6[] = {
+ 1240000, 1390000,
+};
+
+static const u32 ldo_volt_table7[] = {
+ 1200000, 1300000, 1500000, 1800000,
+};
+
+static const u32 ldo_volt_table8[] = {
+ 1800000, 2000000,
+};
+
+static int mt6392_get_status(struct regulator_dev *rdev)
+{
+ int ret;
+ u32 regval;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+ ret = regmap_read(rdev->regmap, info->desc.enable_reg, ®val);
+ if (ret != 0) {
+ dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret);
+ return ret;
+ }
+
+ return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
+}
+
+static int mt6392_buck_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+ int ret, val = 0;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+ u32 reg_value;
+
+ if (!info->modeset_mask) {
+ dev_err(&rdev->dev, "regulator %s doesn't support set_mode\n",
+ info->desc.name);
+ return -EINVAL;
+ }
+
+ switch (mode) {
+ case REGULATOR_MODE_FAST:
+ val = MT6392_BUCK_MODE_FORCE_PWM;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ val = MT6392_BUCK_MODE_AUTO;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val <<= ffs(info->modeset_mask) - 1;
+
+ ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
+ info->modeset_mask, val);
+
+ if (regmap_read(rdev->regmap, info->modeset_reg, ®_value) < 0) {
+ dev_err(&rdev->dev, "Failed to read register value\n");
+ return -EIO;
+ }
+
+ return ret;
+}
+
+static unsigned int mt6392_buck_get_mode(struct regulator_dev *rdev)
+{
+ unsigned int val;
+ unsigned int mode;
+ int ret;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+ if (!info->modeset_mask) {
+ dev_err(&rdev->dev, "regulator %s doesn't support get_mode\n",
+ info->desc.name);
+ return -EINVAL;
+ }
+
+ ret = regmap_read(rdev->regmap, info->modeset_reg, &val);
+ if (ret < 0)
+ return ret;
+
+ val &= info->modeset_mask;
+ val >>= ffs(info->modeset_mask) - 1;
+
+ if (val & 0x1)
+ mode = REGULATOR_MODE_FAST;
+ else
+ mode = REGULATOR_MODE_NORMAL;
+
+ return mode;
+}
+
+static int mt6392_ldo_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+ int ret, val = 0;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+ if (!info->modeset_mask) {
+ dev_err(&rdev->dev, "regulator %s doesn't support set_mode\n",
+ info->desc.name);
+ return -EINVAL;
+ }
+
+ switch (mode) {
+ case REGULATOR_MODE_STANDBY:
+ val = MT6392_LDO_MODE_LP;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ val = MT6392_LDO_MODE_NORMAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val <<= ffs(info->modeset_mask) - 1;
+
+ ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
+ info->modeset_mask, val);
+
+ return ret;
+}
+
+static unsigned int mt6392_ldo_get_mode(struct regulator_dev *rdev)
+{
+ unsigned int val;
+ unsigned int mode;
+ int ret;
+ struct mt6392_regulator_info *info = rdev_get_drvdata(rdev);
+
+ if (!info->modeset_mask) {
+ dev_err(&rdev->dev, "regulator %s doesn't support get_mode\n",
+ info->desc.name);
+ return -EINVAL;
+ }
+
+ ret = regmap_read(rdev->regmap, info->modeset_reg, &val);
+ if (ret < 0)
+ return ret;
+
+ val &= info->modeset_mask;
+ val >>= ffs(info->modeset_mask) - 1;
+
+ if (val & 0x1)
+ mode = REGULATOR_MODE_STANDBY;
+ else
+ mode = REGULATOR_MODE_NORMAL;
+
+ return mode;
+}
+
+static const struct regulator_ops mt6392_volt_range_ops = {
+ .list_voltage = regulator_list_voltage_linear_range,
+ .map_voltage = regulator_map_voltage_linear_range,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_status = mt6392_get_status,
+ .set_mode = mt6392_buck_set_mode,
+ .get_mode = mt6392_buck_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_table_ops = {
+ .list_voltage = regulator_list_voltage_table,
+ .map_voltage = regulator_map_voltage_iterate,
+ .set_voltage_sel = regulator_set_voltage_sel_regmap,
+ .get_voltage_sel = regulator_get_voltage_sel_regmap,
+ .set_voltage_time_sel = regulator_set_voltage_time_sel,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_status = mt6392_get_status,
+ .set_mode = mt6392_ldo_set_mode,
+ .get_mode = mt6392_ldo_get_mode,
+};
+
+static const struct regulator_ops mt6392_volt_fixed_ops = {
+ .list_voltage = regulator_list_voltage_linear,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
+ .get_status = mt6392_get_status,
+ .set_mode = mt6392_ldo_set_mode,
+ .get_mode = mt6392_ldo_get_mode,
+};
+
+/* The array is indexed by id(MT6392_ID_XXX) */
+static struct mt6392_regulator_info mt6392_regulators[] = {
+ MT6392_BUCK("buck-vproc", VPROC, 700000, 1493750, 6250,
+ buck_volt_range1, MT6392_VPROC_CON7, MT6392_VPROC_CON9, 0x7f,
+ MT6392_VPROC_CON10, MT6392_VPROC_CON5, MT6392_VPROC_CON2,
+ 0x100),
+ MT6392_BUCK("buck-vsys", VSYS, 1400000, 2987500, 12500,
+ buck_volt_range2, MT6392_VSYS_CON7, MT6392_VSYS_CON9, 0x7f,
+ MT6392_VSYS_CON10, MT6392_VSYS_CON5, MT6392_VSYS_CON2, 0x100),
+ MT6392_BUCK("buck-vcore", VCORE, 700000, 1493750, 6250,
+ buck_volt_range1, MT6392_VCORE_CON7, MT6392_VCORE_CON9, 0x7f,
+ MT6392_VCORE_CON10, MT6392_VCORE_CON5, MT6392_VCORE_CON2,
+ 0x100),
+ MT6392_REG_FIXED("ldo-vxo22", VXO22, MT6392_ANALDO_CON1, 10, 2200000,
+ MT6392_ANALDO_CON1, 0x2),
+ MT6392_LDO("ldo-vaud22", VAUD22, ldo_volt_table1,
+ MT6392_ANALDO_CON2, 14, MT6392_ANALDO_CON8, 0x60,
+ MT6392_ANALDO_CON2, 0x2),
+ MT6392_REG_FIXED("ldo-vcama", VCAMA, MT6392_ANALDO_CON4, 15, 2800000,
+ -1, 0),
+ MT6392_REG_FIXED("ldo-vaud28", VAUD28, MT6392_ANALDO_CON23, 14, 2800000,
+ MT6392_ANALDO_CON23, 0x2),
+ MT6392_REG_FIXED("ldo-vadc18", VADC18, MT6392_ANALDO_CON25, 14, 1800000,
+ MT6392_ANALDO_CON25, 0x2),
+ MT6392_LDO("ldo-vcn35", VCN35, ldo_volt_table2,
+ MT6392_ANALDO_CON21, 12, MT6392_ANALDO_CON16, 0xC,
+ MT6392_ANALDO_CON21, 0x2),
+ MT6392_REG_FIXED("ldo-vio28", VIO28, MT6392_DIGLDO_CON0, 14, 2800000,
+ MT6392_DIGLDO_CON0, 0x2),
+ MT6392_REG_FIXED("ldo-vusb", VUSB, MT6392_DIGLDO_CON2, 14, 3300000,
+ MT6392_DIGLDO_CON2, 0x2),
+ MT6392_LDO("ldo-vmc", VMC, ldo_volt_table3,
+ MT6392_DIGLDO_CON3, 12, MT6392_DIGLDO_CON24, 0x10,
+ MT6392_DIGLDO_CON3, 0x2),
+ MT6392_LDO("ldo-vmch", VMCH, ldo_volt_table4,
+ MT6392_DIGLDO_CON5, 14, MT6392_DIGLDO_CON26, 0x80,
+ MT6392_DIGLDO_CON5, 0x2),
+ MT6392_LDO("ldo-vemc3v3", VEMC3V3, ldo_volt_table4,
+ MT6392_DIGLDO_CON6, 14, MT6392_DIGLDO_CON27, 0x80,
+ MT6392_DIGLDO_CON6, 0x2),
+ MT6392_LDO("ldo-vgp1", VGP1, ldo_volt_table5,
+ MT6392_DIGLDO_CON7, 15, MT6392_DIGLDO_CON28, 0xE0,
+ MT6392_DIGLDO_CON7, 0x2),
+ MT6392_LDO("ldo-vgp2", VGP2, ldo_volt_table5,
+ MT6392_DIGLDO_CON8, 15, MT6392_DIGLDO_CON29, 0xE0,
+ MT6392_DIGLDO_CON8, 0x2),
+ MT6392_REG_FIXED("ldo-vcn18", VCN18, MT6392_DIGLDO_CON11, 14, 1800000,
+ MT6392_DIGLDO_CON11, 0x2),
+ MT6392_LDO("ldo-vcamaf", VCAMAF, ldo_volt_table5,
+ MT6392_DIGLDO_CON31, 15, MT6392_DIGLDO_CON32, 0xE0,
+ MT6392_DIGLDO_CON31, 0x2),
+ MT6392_LDO("ldo-vm", VM, ldo_volt_table6,
+ MT6392_DIGLDO_CON47, 14, MT6392_DIGLDO_CON48, 0x30,
+ MT6392_DIGLDO_CON47, 0x2),
+ MT6392_REG_FIXED("ldo-vio18", VIO18, MT6392_DIGLDO_CON49, 14, 1800000,
+ MT6392_DIGLDO_CON49, 0x2),
+ MT6392_LDO("ldo-vcamd", VCAMD, ldo_volt_table7,
+ MT6392_DIGLDO_CON51, 14, MT6392_DIGLDO_CON52, 0x60,
+ MT6392_DIGLDO_CON51, 0x2),
+ MT6392_REG_FIXED("ldo-vcamio", VCAMIO, MT6392_DIGLDO_CON53, 14, 1800000,
+ MT6392_DIGLDO_CON53, 0x2),
+ MT6392_REG_FIXED("ldo-vm25", VM25, MT6392_DIGLDO_CON55, 14, 2500000,
+ MT6392_DIGLDO_CON55, 0x2),
+ MT6392_LDO("ldo-vefuse", VEFUSE, ldo_volt_table8,
+ MT6392_DIGLDO_CON57, 14, MT6392_DIGLDO_CON58, 0x10,
+ MT6392_DIGLDO_CON57, 0x2),
+};
+
+static int mt6392_set_buck_vosel_reg(struct platform_device *pdev)
+{
+ struct mt6397_chip *mt6392 = dev_get_drvdata(pdev->dev.parent);
+ int i;
+ u32 regval;
+
+ for (i = 0; i < MT6392_MAX_REGULATOR; i++) {
+ if (mt6392_regulators[i].vselctrl_reg) {
+ if (regmap_read(mt6392->regmap,
+ mt6392_regulators[i].vselctrl_reg,
+ ®val) < 0) {
+ dev_err(&pdev->dev,
+ "Failed to read buck ctrl\n");
+ return -EIO;
+ }
+
+ if (regval & mt6392_regulators[i].vselctrl_mask) {
+ mt6392_regulators[i].desc.vsel_reg =
+ mt6392_regulators[i].vselon_reg;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int mt6392_regulator_probe(struct platform_device *pdev)
+{
+ struct mt6397_chip *mt6392 = dev_get_drvdata(pdev->dev.parent);
+ struct regulator_config config = {};
+ struct regulator_dev *rdev;
+ struct regulation_constraints *c;
+ int i;
+ u32 reg_value;
+
+ /* Query buck controller to select activated voltage register part */
+ if (mt6392_set_buck_vosel_reg(pdev))
+ return -EIO;
+
+ /* Read PMIC chip revision to update constraints and voltage table */
+ if (regmap_read(mt6392->regmap, MT6392_CID, ®_value) < 0) {
+ dev_err(&pdev->dev, "Failed to read Chip ID\n");
+ return -EIO;
+ }
+
+ dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value);
+
+ for (i = 0; i < MT6392_MAX_REGULATOR; i++) {
+ config.dev = &pdev->dev;
+ config.driver_data = &mt6392_regulators[i];
+ config.regmap = mt6392->regmap;
+ rdev = devm_regulator_register(&pdev->dev,
+ &mt6392_regulators[i].desc, &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ mt6392_regulators[i].desc.name);
+ return PTR_ERR(rdev);
+ }
+
+ /* Constrain board-specific capabilities according to what
+ * this driver and the chip itself can actually do.
+ */
+ c = rdev->constraints;
+ c->valid_modes_mask |= REGULATOR_MODE_NORMAL|
+ REGULATOR_MODE_STANDBY | REGULATOR_MODE_FAST;
+ c->valid_ops_mask |= REGULATOR_CHANGE_MODE;
+
+ }
+ return 0;
+}
+
+static const struct platform_device_id mt6392_platform_ids[] = {
+ {"mt6392-regulator", 0},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, mt6392_platform_ids);
+
+static const struct of_device_id mt6392_of_match[] = {
+ { .compatible = "mediatek,mt6392-regulator", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mt6392_of_match);
+
+static struct platform_driver mt6392_regulator_driver = {
+ .driver = {
+ .name = "mt6392-regulator",
+ .of_match_table = of_match_ptr(mt6392_of_match),
+ },
+ .probe = mt6392_regulator_probe,
+ .id_table = mt6392_platform_ids,
+};
+
+module_platform_driver(mt6392_regulator_driver);
+
+MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6392 PMIC");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/regulator/mt6392-regulator.h b/include/linux/regulator/mt6392-regulator.h
new file mode 100644
index 000000000000..dfcbcacb5ad4
--- /dev/null
+++ b/include/linux/regulator/mt6392-regulator.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Chen Zhong <chen.zhong@mediatek.com>
+ */
+
+#ifndef __LINUX_REGULATOR_MT6392_H
+#define __LINUX_REGULATOR_MT6392_H
+
+enum {
+ MT6392_ID_VPROC = 0,
+ MT6392_ID_VSYS,
+ MT6392_ID_VCORE,
+ MT6392_ID_VXO22,
+ MT6392_ID_VAUD22,
+ MT6392_ID_VCAMA,
+ MT6392_ID_VAUD28,
+ MT6392_ID_VADC18,
+ MT6392_ID_VCN35,
+ MT6392_ID_VIO28,
+ MT6392_ID_VUSB = 10,
+ MT6392_ID_VMC,
+ MT6392_ID_VMCH,
+ MT6392_ID_VEMC3V3,
+ MT6392_ID_VGP1,
+ MT6392_ID_VGP2,
+ MT6392_ID_VCN18,
+ MT6392_ID_VCAMAF,
+ MT6392_ID_VM,
+ MT6392_ID_VIO18,
+ MT6392_ID_VCAMD,
+ MT6392_ID_VCAMIO,
+ MT6392_ID_VM25,
+ MT6392_ID_VEFUSE,
+ MT6392_ID_RG_MAX,
+};
+
+#define MT6392_MAX_REGULATOR MT6392_ID_RG_MAX
+
+#endif /* __LINUX_REGULATOR_MT6392_H */
--
2.20.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 8+ messages in thread