This patchset including refactoring interrupt add support to MT6358 PMIC.
MT6358 is the primary PMIC for MT8183 platform.
changes since v1:
- refine for better code quality.
- remove of_match_table in the MT6358 regulator driver.
- some minor bug fix of mfd driver, like getting pmic id flow.
- add support for the MediaTek MT6358 RTC.
Hsin-Hsiung Wang (7):
mfd: mt6397: clean up code
mfd: mt6397: extract irq related code from core driver
dt-bindings: mfd: Add compatible for the MediaTek MT6358 PMIC
regulator: Add document for MT6358 regulator
mfd: Add support for the MediaTek MT6358 PMIC
regulator: mt6358: Add support for MT6358 regulator
arm64: dts: mt6358: add PMIC MT6358 related nodes
Ran Bi (2):
rtc: mt6397: fix alarm register overwrite
rtc: Add support for the MediaTek MT6358 RTC
Documentation/devicetree/bindings/mfd/mt6397.txt | 11 +-
.../bindings/regulator/mt6358-regulator.txt | 318 ++++
arch/arm64/boot/dts/mediatek/mt6358.dtsi | 318 ++++
drivers/mfd/Makefile | 2 +-
drivers/mfd/mt6358-irq.c | 236 +++
drivers/mfd/mt6397-core.c | 289 +--
drivers/mfd/mt6397-irq.c | 214 +++
drivers/regulator/Kconfig | 9 +
drivers/regulator/Makefile | 1 +
drivers/regulator/mt6358-regulator.c | 600 ++++++
drivers/rtc/rtc-mt6397.c | 63 +-
include/linux/mfd/mt6358/core.h | 158 ++
include/linux/mfd/mt6358/registers.h | 1926 ++++++++++++++++++++
include/linux/mfd/mt6397/core.h | 15 +
include/linux/regulator/mt6358-regulator.h | 56 +
15 files changed, 4000 insertions(+), 216 deletions(-)
create mode 100644 Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
create mode 100644 arch/arm64/boot/dts/mediatek/mt6358.dtsi
create mode 100644 drivers/mfd/mt6358-irq.c
create mode 100644 drivers/mfd/mt6397-irq.c
create mode 100644 drivers/regulator/mt6358-regulator.c
create mode 100644 include/linux/mfd/mt6358/core.h
create mode 100644 include/linux/mfd/mt6358/registers.h
create mode 100644 include/linux/regulator/mt6358-regulator.h
--
1.9.1
From: Ran Bi <[email protected]>
Alarm registers high byte was reserved for other functions.
This add mask in alarm registers operation functions.
This also fix error condition in interrupt handler.
Fixes: fc2979118f3f ("rtc: mediatek: Add MT6397 RTC driver")
Signed-off-by: Ran Bi <[email protected]>
---
drivers/rtc/rtc-mt6397.c | 47 +++++++++++++++++++++++++++++++++--------------
1 file changed, 33 insertions(+), 14 deletions(-)
diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
index e9a25ec..f85f1fc 100644
--- a/drivers/rtc/rtc-mt6397.c
+++ b/drivers/rtc/rtc-mt6397.c
@@ -55,6 +55,14 @@
#define RTC_AL_SEC 0x0018
+#define RTC_AL_SEC_MASK 0x003f
+#define RTC_AL_MIN_MASK 0x003f
+#define RTC_AL_HOU_MASK 0x001f
+#define RTC_AL_DOM_MASK 0x001f
+#define RTC_AL_DOW_MASK 0x0007
+#define RTC_AL_MTH_MASK 0x000f
+#define RTC_AL_YEA_MASK 0x007f
+
#define RTC_PDN2 0x002e
#define RTC_PDN2_PWRON_ALARM BIT(4)
@@ -111,7 +119,7 @@ static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data)
irqen = irqsta & ~RTC_IRQ_EN_AL;
mutex_lock(&rtc->lock);
if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN,
- irqen) < 0)
+ irqen) == 0)
mtk_rtc_write_trigger(rtc);
mutex_unlock(&rtc->lock);
@@ -233,12 +241,12 @@ static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM);
mutex_unlock(&rtc->lock);
- tm->tm_sec = data[RTC_OFFSET_SEC];
- tm->tm_min = data[RTC_OFFSET_MIN];
- tm->tm_hour = data[RTC_OFFSET_HOUR];
- tm->tm_mday = data[RTC_OFFSET_DOM];
- tm->tm_mon = data[RTC_OFFSET_MTH];
- tm->tm_year = data[RTC_OFFSET_YEAR];
+ tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK;
+ tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK;
+ tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK;
+ tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK;
+ tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK;
+ tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK;
tm->tm_year += RTC_MIN_YEAR_OFFSET;
tm->tm_mon--;
@@ -259,14 +267,25 @@ static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
tm->tm_year -= RTC_MIN_YEAR_OFFSET;
tm->tm_mon++;
- data[RTC_OFFSET_SEC] = tm->tm_sec;
- data[RTC_OFFSET_MIN] = tm->tm_min;
- data[RTC_OFFSET_HOUR] = tm->tm_hour;
- data[RTC_OFFSET_DOM] = tm->tm_mday;
- data[RTC_OFFSET_MTH] = tm->tm_mon;
- data[RTC_OFFSET_YEAR] = tm->tm_year;
-
mutex_lock(&rtc->lock);
+ ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC,
+ data, RTC_OFFSET_COUNT);
+ if (ret < 0)
+ goto exit;
+
+ data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) |
+ (tm->tm_sec & RTC_AL_SEC_MASK));
+ data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) |
+ (tm->tm_min & RTC_AL_MIN_MASK));
+ data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) |
+ (tm->tm_hour & RTC_AL_HOU_MASK));
+ data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) |
+ (tm->tm_mday & RTC_AL_DOM_MASK));
+ data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) |
+ (tm->tm_mon & RTC_AL_MTH_MASK));
+ data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) |
+ (tm->tm_year & RTC_AL_YEA_MASK));
+
if (alm->enabled) {
ret = regmap_bulk_write(rtc->regmap,
rtc->addr_base + RTC_AL_SEC,
--
1.9.1
clean up code
Signed-off-by: Hsin-Hsiung Wang <[email protected]>
---
drivers/mfd/mt6397-core.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 77b64bd..acb9812 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -18,17 +18,17 @@
#include <linux/of_irq.h>
#include <linux/regmap.h>
#include <linux/mfd/core.h>
-#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/core.h>
-#include <linux/mfd/mt6397/registers.h>
+#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/registers.h>
+#include <linux/mfd/mt6397/registers.h>
#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 MT6323_CHIP_ID 0x23
+#define MT6391_CHIP_ID 0x91
+#define MT6397_CHIP_ID 0x97
static const struct resource mt6397_rtc_resources[] = {
{
@@ -298,7 +298,7 @@ static int mt6397_probe(struct platform_device *pdev)
return pmic->irq;
switch (id & 0xff) {
- case MT6323_CID_CODE:
+ case MT6323_CHIP_ID:
pmic->int_con[0] = MT6323_INT_CON0;
pmic->int_con[1] = MT6323_INT_CON1;
pmic->int_status[0] = MT6323_INT_STATUS0;
@@ -312,8 +312,8 @@ static int mt6397_probe(struct platform_device *pdev)
0, pmic->irq_domain);
break;
- case MT6397_CID_CODE:
- case MT6391_CID_CODE:
+ case MT6391_CHIP_ID:
+ case MT6397_CHIP_ID:
pmic->int_con[0] = MT6397_INT_CON0;
pmic->int_con[1] = MT6397_INT_CON1;
pmic->int_status[0] = MT6397_INT_STATUS0;
--
1.9.1
The MT6358 is a regulator found on boards based on MediaTek MT8183 and
probably other SoCs. It is a so called pmic and connects as a slave to
SoC using SPI, wrapped inside the pmic-wrapper.
Signed-off-by: Hsin-Hsiung Wang <[email protected]>
---
drivers/regulator/Kconfig | 9 +
drivers/regulator/Makefile | 1 +
drivers/regulator/mt6358-regulator.c | 600 +++++++++++++++++++++++++++++
include/linux/regulator/mt6358-regulator.h | 56 +++
4 files changed, 666 insertions(+)
create mode 100644 drivers/regulator/mt6358-regulator.c
create mode 100644 include/linux/regulator/mt6358-regulator.h
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index ee60a22..5a6006e 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -596,6 +596,15 @@ config REGULATOR_MT6323
This driver supports the control of different power rails of device
through regulator interface.
+config REGULATOR_MT6358
+ tristate "MediaTek MT6358 PMIC"
+ depends on MFD_MT6397
+ help
+ Say y here to select this option to enable the power regulator of
+ MediaTek MT6358 PMIC.
+ This driver supports the control of different power rails of device
+ through regulator interface.
+
config REGULATOR_MT6380
tristate "MediaTek MT6380 PMIC"
depends on MTK_PMIC_WRAP
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index b12e1c9..4681425 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -77,6 +77,7 @@ obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
+obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c
new file mode 100644
index 0000000..6815778
--- /dev/null
+++ b/drivers/regulator/mt6358-regulator.c
@@ -0,0 +1,600 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2019 MediaTek Inc.
+
+#include <linux/mfd/mt6358/registers.h>
+#include <linux/mfd/mt6397/core.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/mt6358-regulator.h>
+#include <linux/regulator/of_regulator.h>
+
+#define MT6358_BUCK_MODE_AUTO 0
+#define MT6358_BUCK_MODE_FORCE_PWM 1
+
+/*
+ * MT6358 regulators' information
+ *
+ * @desc: standard fields of regulator description.
+ * @qi: Mask for query enable signal status of regulators
+ */
+struct mt6358_regulator_info {
+ struct regulator_desc desc;
+ u32 status_reg;
+ u32 qi;
+ const u32 *index_table;
+ unsigned int n_table;
+ u32 vsel_shift;
+ u32 da_vsel_reg;
+ u32 da_vsel_mask;
+ u32 da_vsel_shift;
+ u32 modeset_reg;
+ u32 modeset_mask;
+ u32 modeset_shift;
+};
+
+#define MT6358_BUCK(match, vreg, min, max, step, \
+ volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask, \
+ _da_vsel_shift, _modeset_reg, _modeset_shift) \
+[MT6358_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6358_volt_range_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6358_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = ((max) - (min)) / (step) + 1, \
+ .linear_ranges = volt_ranges, \
+ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \
+ .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \
+ .vsel_mask = vosel_mask, \
+ .enable_reg = MT6358_BUCK_##vreg##_CON0, \
+ .enable_mask = BIT(0), \
+ .of_map_mode = mt6358_map_mode, \
+ }, \
+ .status_reg = MT6358_BUCK_##vreg##_DBG1, \
+ .qi = BIT(0), \
+ .da_vsel_reg = _da_vsel_reg, \
+ .da_vsel_mask = _da_vsel_mask, \
+ .da_vsel_shift = _da_vsel_shift, \
+ .modeset_reg = _modeset_reg, \
+ .modeset_mask = BIT(_modeset_shift), \
+ .modeset_shift = _modeset_shift \
+}
+
+#define MT6358_LDO(match, vreg, ldo_volt_table, \
+ ldo_index_table, enreg, enbit, vosel, \
+ vosel_mask, vosel_shift) \
+[MT6358_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6358_volt_table_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6358_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), \
+ }, \
+ .status_reg = MT6358_LDO_##vreg##_CON1, \
+ .qi = BIT(15), \
+ .index_table = ldo_index_table, \
+ .n_table = ARRAY_SIZE(ldo_index_table), \
+ .vsel_shift = vosel_shift, \
+}
+
+#define MT6358_LDO1(match, vreg, min, max, step, \
+ volt_ranges, _da_vsel_reg, _da_vsel_mask, \
+ _da_vsel_shift, vosel, vosel_mask) \
+[MT6358_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6358_volt_range_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6358_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 = MT6358_LDO_##vreg##_CON0, \
+ .enable_mask = BIT(0), \
+ }, \
+ .da_vsel_reg = _da_vsel_reg, \
+ .da_vsel_mask = _da_vsel_mask, \
+ .da_vsel_shift = _da_vsel_shift, \
+ .status_reg = MT6358_LDO_##vreg##_DBG1, \
+ .qi = BIT(0), \
+}
+
+#define MT6358_REG_FIXED(match, vreg, \
+ enreg, enbit, volt) \
+[MT6358_ID_##vreg] = { \
+ .desc = { \
+ .name = #vreg, \
+ .of_match = of_match_ptr(match), \
+ .ops = &mt6358_volt_fixed_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = MT6358_ID_##vreg, \
+ .owner = THIS_MODULE, \
+ .n_voltages = 1, \
+ .enable_reg = enreg, \
+ .enable_mask = BIT(enbit), \
+ .min_uV = volt, \
+ }, \
+ .status_reg = MT6358_LDO_##vreg##_CON1, \
+ .qi = BIT(15), \
+}
+
+static const struct regulator_linear_range buck_volt_range1[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
+};
+
+static const struct regulator_linear_range buck_volt_range2[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500),
+};
+
+static const struct regulator_linear_range buck_volt_range3[] = {
+ REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
+};
+
+static const struct regulator_linear_range buck_volt_range4[] = {
+ REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500),
+};
+
+static const u32 vdram2_voltages[] = {
+ 600000, 1800000,
+};
+
+static const u32 vsim1_voltages[] = {
+ 1700000, 1800000, 2700000, 3000000, 3100000,
+};
+
+static const u32 vibr_voltages[] = {
+ 1200000, 1300000, 1500000, 1800000,
+ 2000000, 2800000, 3000000, 3300000,
+};
+
+static const u32 vusb_voltages[] = {
+ 3000000, 3100000,
+};
+
+static const u32 vcamd_voltages[] = {
+ 900000, 1000000, 1100000, 1200000,
+ 1300000, 1500000, 1800000,
+};
+
+static const u32 vefuse_voltages[] = {
+ 1700000, 1800000, 1900000,
+};
+
+static const u32 vmch_voltages[] = {
+ 2900000, 3000000, 3300000,
+};
+
+static const u32 vcama1_voltages[] = {
+ 1800000, 2500000, 2700000,
+ 2800000, 2900000, 3000000,
+};
+
+static const u32 vemc_voltages[] = {
+ 2900000, 3000000, 3300000,
+};
+
+static const u32 vcn33_bt_voltages[] = {
+ 3300000, 3400000, 3500000,
+};
+
+static const u32 vcn33_wifi_voltages[] = {
+ 3300000, 3400000, 3500000,
+};
+
+static const u32 vcama2_voltages[] = {
+ 1800000, 2500000, 2700000,
+ 2800000, 2900000, 3000000,
+};
+
+static const u32 vmc_voltages[] = {
+ 1800000, 2900000, 3000000, 3300000,
+};
+
+static const u32 vldo28_voltages[] = {
+ 2800000, 3000000,
+};
+
+static const u32 vsim2_voltages[] = {
+ 1700000, 1800000, 2700000,
+ 3000000, 3100000,
+};
+
+static const u32 vdram2_idx[] = {
+ 0, 12,
+};
+
+static const u32 vsim1_idx[] = {
+ 3, 4, 8, 11, 12,
+};
+
+static const u32 vibr_idx[] = {
+ 0, 1, 2, 4, 5, 9, 11, 13,
+};
+
+static const u32 vusb_idx[] = {
+ 3, 4,
+};
+
+static const u32 vcamd_idx[] = {
+ 3, 4, 5, 6, 7, 9, 12,
+};
+
+static const u32 vefuse_idx[] = {
+ 11, 12, 13,
+};
+
+static const u32 vmch_idx[] = {
+ 2, 3, 5,
+};
+
+static const u32 vcama1_idx[] = {
+ 0, 7, 9, 10, 11, 12,
+};
+
+static const u32 vemc_idx[] = {
+ 2, 3, 5,
+};
+
+static const u32 vcn33_bt_idx[] = {
+ 1, 2, 3,
+};
+
+static const u32 vcn33_wifi_idx[] = {
+ 1, 2, 3,
+};
+
+static const u32 vcama2_idx[] = {
+ 0, 7, 9, 10, 11, 12,
+};
+
+static const u32 vmc_idx[] = {
+ 4, 10, 11, 13,
+};
+
+static const u32 vldo28_idx[] = {
+ 1, 3,
+};
+
+static const u32 vsim2_idx[] = {
+ 3, 4, 8, 11, 12,
+};
+
+static inline unsigned int mt6358_map_mode(unsigned int mode)
+{
+ return mode == MT6358_BUCK_MODE_FORCE_PWM ?
+ REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
+}
+
+static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned int selector)
+{
+ int idx, ret;
+ const u32 *pvol;
+ struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+
+ pvol = (const u32 *)info->index_table;
+
+ idx = pvol[selector];
+ ret = regmap_update_bits(rdev->regmap, info->desc.vsel_reg,
+ info->desc.vsel_mask,
+ idx << info->vsel_shift);
+
+ return ret;
+}
+
+static int mt6358_get_voltage_sel(struct regulator_dev *rdev)
+{
+ int idx, ret;
+ u32 selector;
+ struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+ const u32 *pvol;
+
+ ret = regmap_read(rdev->regmap, info->desc.vsel_reg, &selector);
+ if (ret != 0) {
+ dev_info(&rdev->dev,
+ "Failed to get mt6358 %s vsel reg: %d\n",
+ info->desc.name, ret);
+ return ret;
+ }
+
+ selector = (selector & info->desc.vsel_mask) >> info->vsel_shift;
+ pvol = (const u32 *)info->index_table;
+ ret = -1;
+ for (idx = 0; idx < info->desc.n_voltages; idx++) {
+ if (pvol[idx] == selector) {
+ ret = idx;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
+{
+ int ret, regval;
+ struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+
+ ret = regmap_read(rdev->regmap, info->da_vsel_reg, ®val);
+ if (ret != 0) {
+ dev_info(&rdev->dev,
+ "Failed to get mt6358 Buck %s vsel reg: %d\n",
+ info->desc.name, ret);
+ return ret;
+ }
+
+ ret = (regval >> info->da_vsel_shift) & info->da_vsel_mask;
+
+ return ret;
+}
+
+static int mt6358_get_status(struct regulator_dev *rdev)
+{
+ int ret;
+ u32 regval;
+ struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+
+ ret = regmap_read(rdev->regmap, info->status_reg, ®val);
+ if (ret != 0) {
+ dev_info(&rdev->dev, "Failed to get enable reg: %d\n", ret);
+ return ret;
+ }
+
+ return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
+}
+
+static int mt6358_regulator_set_mode(struct regulator_dev *rdev,
+ unsigned int mode)
+{
+ struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+ int ret, val;
+
+ switch (mode) {
+ case REGULATOR_MODE_FAST:
+ val = MT6358_BUCK_MODE_FORCE_PWM;
+ break;
+ case REGULATOR_MODE_NORMAL:
+ val = MT6358_BUCK_MODE_AUTO;
+ break;
+ default:
+ ret = -EINVAL;
+ goto err_mode;
+ }
+
+ dev_dbg(&rdev->dev, "mt6358 buck set_mode %#x, %#x, %#x, %#x\n",
+ info->modeset_reg, info->modeset_mask,
+ info->modeset_shift, val);
+
+ val <<= info->modeset_shift;
+ ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
+ info->modeset_mask, val);
+err_mode:
+ if (ret != 0) {
+ dev_err(&rdev->dev,
+ "Failed to set mt6358 buck mode: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
+{
+ struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+ int ret, regval;
+
+ ret = regmap_read(rdev->regmap, info->modeset_reg, ®val);
+ if (ret != 0) {
+ dev_err(&rdev->dev,
+ "Failed to get mt6358 buck mode: %d\n", ret);
+ return ret;
+ }
+
+ switch ((regval & info->modeset_mask) >> info->modeset_shift) {
+ case MT6358_BUCK_MODE_AUTO:
+ return REGULATOR_MODE_NORMAL;
+ case MT6358_BUCK_MODE_FORCE_PWM:
+ return REGULATOR_MODE_FAST;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct regulator_ops mt6358_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 = mt6358_get_buck_voltage_sel,
+ .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 = mt6358_get_status,
+ .set_mode = mt6358_regulator_set_mode,
+ .get_mode = mt6358_regulator_get_mode,
+};
+
+static const struct regulator_ops mt6358_volt_table_ops = {
+ .list_voltage = regulator_list_voltage_table,
+ .map_voltage = regulator_map_voltage_iterate,
+ .set_voltage_sel = mt6358_set_voltage_sel,
+ .get_voltage_sel = mt6358_get_voltage_sel,
+ .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 = mt6358_get_status,
+};
+
+static const struct regulator_ops mt6358_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 = mt6358_get_status,
+};
+
+/* The array is indexed by id(MT6358_ID_XXX) */
+static struct mt6358_regulator_info mt6358_regulators[] = {
+ MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
+ buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
+ 0, MT6358_VDRAM1_ANA_CON0, 8),
+ MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
+ buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
+ 0, MT6358_VCORE_VGPU_ANA_CON0, 1),
+ MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
+ buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, 0,
+ MT6358_VPA_ANA_CON0, 3),
+ MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
+ buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
+ 0, MT6358_VPROC_ANA_CON0, 1),
+ MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
+ buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
+ 0, MT6358_VPROC_ANA_CON0, 2),
+ MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
+ buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_DBG0, 0x7f, 0,
+ MT6358_VCORE_VGPU_ANA_CON0, 2),
+ MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
+ buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, 0,
+ MT6358_VS2_ANA_CON0, 8),
+ MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
+ buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
+ 0, MT6358_VMODEM_ANA_CON0, 8),
+ MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
+ buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, 0,
+ MT6358_VS1_ANA_CON0, 8),
+ MT6358_REG_FIXED("ldo_vrf12", VRF12,
+ MT6358_LDO_VRF12_CON0, 0, 1200000),
+ MT6358_REG_FIXED("ldo_vio18", VIO18,
+ MT6358_LDO_VIO18_CON0, 0, 1800000),
+ MT6358_REG_FIXED("ldo_vcamio", VCAMIO,
+ MT6358_LDO_VCAMIO_CON0, 0, 1800000),
+ MT6358_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
+ MT6358_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
+ MT6358_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
+ MT6358_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
+ MT6358_REG_FIXED("ldo_vaux18", VAUX18,
+ MT6358_LDO_VAUX18_CON0, 0, 1800000),
+ MT6358_REG_FIXED("ldo_vbif28", VBIF28,
+ MT6358_LDO_VBIF28_CON0, 0, 2800000),
+ MT6358_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
+ MT6358_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
+ MT6358_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
+ MT6358_REG_FIXED("ldo_vaud28", VAUD28,
+ MT6358_LDO_VAUD28_CON0, 0, 2800000),
+ MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
+ MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10, 0),
+ MT6358_LDO("ldo_vsim1", VSIM1, vsim1_voltages, vsim1_idx,
+ MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00, 8),
+ MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
+ MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00, 8),
+ MT6358_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
+ MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700, 8),
+ MT6358_LDO("ldo_vcamd", VCAMD, vcamd_voltages, vcamd_idx,
+ MT6358_LDO_VCAMD_CON0, 0, MT6358_VCAMD_ANA_CON0, 0xf00, 8),
+ MT6358_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
+ MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00, 8),
+ MT6358_LDO("ldo_vmch", VMCH, vmch_voltages, vmch_idx,
+ MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700, 8),
+ MT6358_LDO("ldo_vcama1", VCAMA1, vcama1_voltages, vcama1_idx,
+ MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00, 8),
+ MT6358_LDO("ldo_vemc", VEMC, vemc_voltages, vemc_idx,
+ MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700, 8),
+ MT6358_LDO("ldo_vcn33_bt", VCN33_BT, vcn33_bt_voltages, vcn33_bt_idx,
+ MT6358_LDO_VCN33_CON0_0, 0, MT6358_VCN33_ANA_CON0, 0x300, 8),
+ MT6358_LDO("ldo_vcn33_wifi", VCN33_WIFI, vcn33_wifi_voltages,
+ vcn33_wifi_idx, MT6358_LDO_VCN33_CON0_1,
+ 0, MT6358_VCN33_ANA_CON0, 0x300, 8),
+ MT6358_LDO("ldo_vcama2", VCAMA2, vcama2_voltages, vcama2_idx,
+ MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00, 8),
+ MT6358_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
+ MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00, 8),
+ MT6358_LDO("ldo_vldo28", VLDO28, vldo28_voltages, vldo28_idx,
+ MT6358_LDO_VLDO28_CON0_0, 0,
+ MT6358_VLDO28_ANA_CON0, 0x300, 8),
+ MT6358_LDO("ldo_vsim2", VSIM2, vsim2_voltages, vsim2_idx,
+ MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00, 8),
+ MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
+ buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f, 8,
+ MT6358_LDO_VSRAM_CON0, 0x7f),
+ MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
+ buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f, 8,
+ MT6358_LDO_VSRAM_CON2, 0x7f),
+ MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
+ buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f, 8,
+ MT6358_LDO_VSRAM_CON3, 0x7f),
+ MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
+ buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f, 8,
+ MT6358_LDO_VSRAM_CON1, 0x7f),
+};
+
+static int mt6358_regulator_probe(struct platform_device *pdev)
+{
+ struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
+ struct regulator_config config = {};
+ struct regulator_dev *rdev;
+ int i;
+ u32 reg_value;
+
+ /* Read PMIC chip revision to update constraints and voltage table */
+ if (regmap_read(mt6397->regmap, MT6358_SWCID, ®_value) < 0) {
+ dev_err(&pdev->dev, "Failed to read Chip ID\n");
+ return -EIO;
+ }
+
+ for (i = 0; i < MT6358_MAX_REGULATOR; i++) {
+ config.dev = &pdev->dev;
+ config.driver_data = &mt6358_regulators[i];
+ config.regmap = mt6397->regmap;
+
+ rdev = devm_regulator_register(&pdev->dev,
+ &mt6358_regulators[i].desc,
+ &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register %s\n",
+ mt6358_regulators[i].desc.name);
+ return PTR_ERR(rdev);
+ }
+ }
+
+ return 0;
+}
+
+static const struct platform_device_id mt6358_platform_ids[] = {
+ {"mt6358-regulator", 0},
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, mt6358_platform_ids);
+
+static struct platform_driver mt6358_regulator_driver = {
+ .driver = {
+ .name = "mt6358-regulator",
+ },
+ .probe = mt6358_regulator_probe,
+ .id_table = mt6358_platform_ids,
+};
+
+module_platform_driver(mt6358_regulator_driver);
+
+MODULE_AUTHOR("Hsin-Hsiung Wang <[email protected]>");
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6358 PMIC");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/regulator/mt6358-regulator.h b/include/linux/regulator/mt6358-regulator.h
new file mode 100644
index 0000000..1cc3049
--- /dev/null
+++ b/include/linux/regulator/mt6358-regulator.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef __LINUX_REGULATOR_MT6358_H
+#define __LINUX_REGULATOR_MT6358_H
+
+enum {
+ MT6358_ID_VDRAM1 = 0,
+ MT6358_ID_VCORE,
+ MT6358_ID_VPA,
+ MT6358_ID_VPROC11,
+ MT6358_ID_VPROC12,
+ MT6358_ID_VGPU,
+ MT6358_ID_VS2,
+ MT6358_ID_VMODEM,
+ MT6358_ID_VS1,
+ MT6358_ID_VDRAM2 = 9,
+ MT6358_ID_VSIM1,
+ MT6358_ID_VIBR,
+ MT6358_ID_VRF12,
+ MT6358_ID_VIO18,
+ MT6358_ID_VUSB,
+ MT6358_ID_VCAMIO,
+ MT6358_ID_VCAMD,
+ MT6358_ID_VCN18,
+ MT6358_ID_VFE28,
+ MT6358_ID_VSRAM_PROC11,
+ MT6358_ID_VCN28,
+ MT6358_ID_VSRAM_OTHERS,
+ MT6358_ID_VSRAM_GPU,
+ MT6358_ID_VXO22,
+ MT6358_ID_VEFUSE,
+ MT6358_ID_VAUX18,
+ MT6358_ID_VMCH,
+ MT6358_ID_VBIF28,
+ MT6358_ID_VSRAM_PROC12,
+ MT6358_ID_VCAMA1,
+ MT6358_ID_VEMC,
+ MT6358_ID_VIO28,
+ MT6358_ID_VA12,
+ MT6358_ID_VRF18,
+ MT6358_ID_VCN33_BT,
+ MT6358_ID_VCN33_WIFI,
+ MT6358_ID_VCAMA2,
+ MT6358_ID_VMC,
+ MT6358_ID_VLDO28,
+ MT6358_ID_VAUD28,
+ MT6358_ID_VSIM2,
+ MT6358_ID_RG_MAX,
+};
+
+#define MT6358_MAX_REGULATOR MT6358_ID_RG_MAX
+
+#endif /* __LINUX_REGULATOR_MT6358_H */
--
1.9.1
add dt-binding document for MediaTek MT6358 PMIC
Signed-off-by: Hsin-Hsiung Wang <[email protected]>
---
.../bindings/regulator/mt6358-regulator.txt | 318 +++++++++++++++++++++
1 file changed, 318 insertions(+)
create mode 100644 Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
diff --git a/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
new file mode 100644
index 0000000..3ea8073
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
@@ -0,0 +1,318 @@
+Mediatek MT6358 Regulator
+
+Required properties:
+- compatible: "mediatek,mt6358-regulator"
+- mt6358regulator: List of regulators provided by this controller. It is named
+ according to its regulator type, buck_<name> and ldo_<name>.
+ The definition for each of these nodes is defined using the standard binding
+ for regulators at Documentation/devicetree/bindings/regulator/regulator.txt.
+
+The valid names for regulators are::
+BUCK:
+ buck_vdram1, buck_vcore, buck_vpa, buck_vproc11, buck_vproc12, buck_vgpu,
+ buck_vs2, buck_vmodem, buck_vs1
+LDO:
+ ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio,
+ ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others,
+ ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28,
+ ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18,
+ ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
+ ldo_vsim2
+
+Example:
+ pmic {
+ compatible = "mediatek,mt6358";
+
+ mt6358regulator: mt6358regulator {
+ compatible = "mediatek,mt6358-regulator";
+
+ mt6358_vdram1_reg: buck_vdram1 {
+ regulator-compatible = "buck_vdram1";
+ regulator-name = "vdram1";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2087500>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <0>;
+ regulator-always-on;
+ };
+ mt6358_vcore_reg: buck_vcore {
+ regulator-name = "vcore";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-always-on;
+ };
+ mt6358_vpa_reg: buck_vpa {
+ regulator-name = "vpa";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3650000>;
+ regulator-ramp-delay = <50000>;
+ regulator-enable-ramp-delay = <250>;
+ };
+ mt6358_vproc11_reg: buck_vproc11 {
+ regulator-name = "vproc11";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-always-on;
+ };
+ mt6358_vproc12_reg: buck_vproc12 {
+ regulator-name = "vproc12";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-always-on;
+ };
+ mt6358_vgpu_reg: buck_vgpu {
+ regulator-name = "vgpu";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ };
+ mt6358_vs2_reg: buck_vs2 {
+ regulator-name = "vs2";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2087500>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <0>;
+ regulator-always-on;
+ };
+ mt6358_vmodem_reg: buck_vmodem {
+ regulator-name = "vmodem";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <900>;
+ regulator-always-on;
+ };
+ mt6358_vs1_reg: buck_vs1 {
+ regulator-name = "vs1";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <2587500>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <0>;
+ regulator-always-on;
+ };
+ mt6358_vdram2_reg: ldo_vdram2 {
+ regulator-name = "vdram2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <3300>;
+ };
+ mt6358_vsim1_reg: ldo_vsim1 {
+ regulator-name = "vsim1";
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-enable-ramp-delay = <540>;
+ };
+ mt6358_vibr_reg: ldo_vibr {
+ regulator-name = "vibr";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+ mt6358_vrf12_reg: ldo_vrf12 {
+ compatible = "regulator-fixed";
+ regulator-name = "vrf12";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-enable-ramp-delay = <120>;
+ };
+ mt6358_vio18_reg: ldo_vio18 {
+ compatible = "regulator-fixed";
+ regulator-name = "vio18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <2700>;
+ regulator-always-on;
+ };
+ mt6358_vusb_reg: ldo_vusb {
+ regulator-name = "vusb";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-enable-ramp-delay = <270>;
+ regulator-always-on;
+ };
+ mt6358_vcamio_reg: ldo_vcamio {
+ compatible = "regulator-fixed";
+ regulator-name = "vcamio";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vcamd_reg: ldo_vcamd {
+ regulator-name = "vcamd";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vcn18_reg: ldo_vcn18 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcn18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vfe28_reg: ldo_vfe28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vfe28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vsram_proc11_reg: ldo_vsram_proc11 {
+ regulator-name = "vsram_proc11";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-always-on;
+ };
+ mt6358_vcn28_reg: ldo_vcn28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcn28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vsram_others_reg: ldo_vsram_others {
+ regulator-name = "vsram_others";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-always-on;
+ };
+ mt6358_vsram_gpu_reg: ldo_vsram_gpu {
+ regulator-name = "vsram_gpu";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ };
+ mt6358_vxo22_reg: ldo_vxo22 {
+ compatible = "regulator-fixed";
+ regulator-name = "vxo22";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ regulator-enable-ramp-delay = <120>;
+ regulator-always-on;
+ };
+ mt6358_vefuse_reg: ldo_vefuse {
+ regulator-name = "vefuse";
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <1900000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vaux18_reg: ldo_vaux18 {
+ compatible = "regulator-fixed";
+ regulator-name = "vaux18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vmch_reg: ldo_vmch {
+ regulator-name = "vmch";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+ mt6358_vbif28_reg: ldo_vbif28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbif28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vsram_proc12_reg: ldo_vsram_proc12 {
+ regulator-name = "vsram_proc12";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-always-on;
+ };
+ mt6358_vcama1_reg: ldo_vcama1 {
+ regulator-name = "vcama1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vemc_reg: ldo_vemc {
+ regulator-name = "vemc";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <60>;
+ regulator-always-on;
+ };
+ mt6358_vio28_reg: ldo_vio28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vio28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_va12_reg: ldo_va12 {
+ compatible = "regulator-fixed";
+ regulator-name = "va12";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-enable-ramp-delay = <270>;
+ regulator-always-on;
+ };
+ mt6358_vrf18_reg: ldo_vrf18 {
+ compatible = "regulator-fixed";
+ regulator-name = "vrf18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <120>;
+ };
+ mt6358_vcn33_bt_reg: ldo_vcn33_bt {
+ regulator-name = "vcn33_bt";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3500000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vcn33_wifi_reg: ldo_vcn33_wifi {
+ regulator-name = "vcn33_wifi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3500000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vcama2_reg: ldo_vcama2 {
+ regulator-name = "vcama2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vmc_reg: ldo_vmc {
+ regulator-name = "vmc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+ mt6358_vldo28_reg: ldo_vldo28 {
+ regulator-name = "vldo28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vaud28_reg: ldo_vaud28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vaud28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vsim2_reg: ldo_vsim2 {
+ regulator-name = "vsim2";
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-enable-ramp-delay = <540>;
+ };
+ };
+ };
--
1.9.1
In order to support different types of irq design, we decide to add
separate irq drivers for different design and keep mt6397 mfd core
simple and reusable to all generations of PMICs so far.
Signed-off-by: Hsin-Hsiung Wang <[email protected]>
---
drivers/mfd/Makefile | 2 +-
drivers/mfd/mt6397-core.c | 228 ++++++----------------------------------
drivers/mfd/mt6397-irq.c | 214 +++++++++++++++++++++++++++++++++++++
include/linux/mfd/mt6397/core.h | 12 +++
4 files changed, 259 insertions(+), 197 deletions(-)
create mode 100644 drivers/mfd/mt6397-irq.c
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 12980a4..088e249 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -230,7 +230,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
-obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
+obj-$(CONFIG_MFD_MT6397) += mt6397-core.o mt6397-irq.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index acb9812..53f1edc 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -12,7 +12,6 @@
* GNU General Public License for more details.
*/
-#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
@@ -26,10 +25,6 @@
#define MT6397_RTC_BASE 0xe000
#define MT6397_RTC_SIZE 0x3e
-#define MT6323_CHIP_ID 0x23
-#define MT6391_CHIP_ID 0x91
-#define MT6397_CHIP_ID 0x97
-
static const struct resource mt6397_rtc_resources[] = {
{
.start = MT6397_RTC_BASE,
@@ -94,182 +89,24 @@
}
};
-static void mt6397_irq_lock(struct irq_data *data)
-{
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
-
- mutex_lock(&mt6397->irqlock);
-}
-
-static void mt6397_irq_sync_unlock(struct irq_data *data)
-{
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
-
- regmap_write(mt6397->regmap, mt6397->int_con[0],
- mt6397->irq_masks_cur[0]);
- regmap_write(mt6397->regmap, mt6397->int_con[1],
- mt6397->irq_masks_cur[1]);
-
- mutex_unlock(&mt6397->irqlock);
-}
-
-static void mt6397_irq_disable(struct irq_data *data)
-{
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
- int shift = data->hwirq & 0xf;
- int reg = data->hwirq >> 4;
-
- mt6397->irq_masks_cur[reg] &= ~BIT(shift);
-}
-
-static void mt6397_irq_enable(struct irq_data *data)
-{
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
- int shift = data->hwirq & 0xf;
- int reg = data->hwirq >> 4;
-
- mt6397->irq_masks_cur[reg] |= BIT(shift);
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
-{
- struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
- int shift = irq_data->hwirq & 0xf;
- int reg = irq_data->hwirq >> 4;
-
- if (on)
- mt6397->wake_mask[reg] |= BIT(shift);
- else
- mt6397->wake_mask[reg] &= ~BIT(shift);
-
- return 0;
-}
-#else
-#define mt6397_irq_set_wake NULL
-#endif
-
-static struct irq_chip mt6397_irq_chip = {
- .name = "mt6397-irq",
- .irq_bus_lock = mt6397_irq_lock,
- .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
- .irq_enable = mt6397_irq_enable,
- .irq_disable = mt6397_irq_disable,
- .irq_set_wake = mt6397_irq_set_wake,
+struct chip_data {
+ u32 cid_addr;
};
-static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
- int irqbase)
-{
- unsigned int status;
- int i, irq, ret;
-
- ret = regmap_read(mt6397->regmap, reg, &status);
- if (ret) {
- dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
- return;
- }
-
- for (i = 0; i < 16; i++) {
- if (status & BIT(i)) {
- irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
- if (irq)
- handle_nested_irq(irq);
- }
- }
-
- regmap_write(mt6397->regmap, reg, status);
-}
-
-static irqreturn_t mt6397_irq_thread(int irq, void *data)
-{
- struct mt6397_chip *mt6397 = data;
-
- mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
- mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
-
- return IRQ_HANDLED;
-}
-
-static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hw)
-{
- struct mt6397_chip *mt6397 = d->host_data;
-
- irq_set_chip_data(irq, mt6397);
- irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
- irq_set_nested_thread(irq, 1);
- irq_set_noprobe(irq);
-
- return 0;
-}
-
-static const struct irq_domain_ops mt6397_irq_domain_ops = {
- .map = mt6397_irq_domain_map,
+static const struct chip_data mt6323_core = {
+ .cid_addr = MT6323_CID,
};
-static int mt6397_irq_init(struct mt6397_chip *mt6397)
-{
- int ret;
-
- mutex_init(&mt6397->irqlock);
-
- /* Mask all interrupt sources */
- regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
- regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
-
- mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
- MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
- if (!mt6397->irq_domain) {
- dev_err(mt6397->dev, "could not create irq domain\n");
- return -ENOMEM;
- }
-
- ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL,
- mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397);
- if (ret) {
- dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n",
- mt6397->irq, ret);
- return ret;
- }
-
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int mt6397_irq_suspend(struct device *dev)
-{
- struct mt6397_chip *chip = dev_get_drvdata(dev);
-
- regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
- regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
-
- enable_irq_wake(chip->irq);
-
- return 0;
-}
-
-static int mt6397_irq_resume(struct device *dev)
-{
- struct mt6397_chip *chip = dev_get_drvdata(dev);
-
- regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
- regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
-
- disable_irq_wake(chip->irq);
-
- return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
- mt6397_irq_resume);
+static const struct chip_data mt6397_core = {
+ .cid_addr = MT6397_CID,
+};
static int mt6397_probe(struct platform_device *pdev)
{
int ret;
unsigned int id;
struct mt6397_chip *pmic;
+ const struct chip_data *pmic_core;
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic)
@@ -285,28 +122,30 @@ static int mt6397_probe(struct platform_device *pdev)
if (!pmic->regmap)
return -ENODEV;
- platform_set_drvdata(pdev, pmic);
+ pmic_core = of_device_get_match_data(&pdev->dev);
+ if (!pmic_core)
+ return -ENODEV;
- ret = regmap_read(pmic->regmap, MT6397_CID, &id);
+ ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
if (ret) {
- dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
+ dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);
return ret;
}
+ pmic->chip_id = id & 0xff;
+
+ platform_set_drvdata(pdev, pmic);
+
pmic->irq = platform_get_irq(pdev, 0);
if (pmic->irq <= 0)
return pmic->irq;
- switch (id & 0xff) {
- case MT6323_CHIP_ID:
- pmic->int_con[0] = MT6323_INT_CON0;
- pmic->int_con[1] = MT6323_INT_CON1;
- pmic->int_status[0] = MT6323_INT_STATUS0;
- pmic->int_status[1] = MT6323_INT_STATUS1;
- ret = mt6397_irq_init(pmic);
- if (ret)
- return ret;
+ ret = mt6397_irq_init(pmic);
+ if (ret)
+ return ret;
+ switch (pmic->chip_id) {
+ case MT6323_CHIP_ID:
ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
ARRAY_SIZE(mt6323_devs), NULL,
0, pmic->irq_domain);
@@ -314,21 +153,13 @@ static int mt6397_probe(struct platform_device *pdev)
case MT6391_CHIP_ID:
case MT6397_CHIP_ID:
- pmic->int_con[0] = MT6397_INT_CON0;
- pmic->int_con[1] = MT6397_INT_CON1;
- pmic->int_status[0] = MT6397_INT_STATUS0;
- pmic->int_status[1] = MT6397_INT_STATUS1;
- ret = mt6397_irq_init(pmic);
- if (ret)
- return ret;
-
ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
ARRAY_SIZE(mt6397_devs), NULL,
0, pmic->irq_domain);
break;
default:
- dev_err(&pdev->dev, "unsupported chip: %d\n", id);
+ dev_err(&pdev->dev, "unsupported chip: %d\n", pmic->chip_id);
ret = -ENODEV;
break;
}
@@ -342,9 +173,15 @@ 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,mt6323",
+ .data = &mt6323_core,
+ }, {
+ .compatible = "mediatek,mt6397",
+ .data = &mt6397_core,
+ }, {
+ /* sentinel */
+ }
};
MODULE_DEVICE_TABLE(of, mt6397_of_match);
@@ -359,7 +196,6 @@ static int mt6397_probe(struct platform_device *pdev)
.driver = {
.name = "mt6397",
.of_match_table = of_match_ptr(mt6397_of_match),
- .pm = &mt6397_pm_ops,
},
.id_table = mt6397_id,
};
diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c
new file mode 100644
index 0000000..669e93d
--- /dev/null
+++ b/drivers/mfd/mt6397-irq.c
@@ -0,0 +1,214 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2019 MediaTek Inc.
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/suspend.h>
+#include <linux/mfd/mt6323/core.h>
+#include <linux/mfd/mt6323/registers.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/mfd/mt6397/registers.h>
+
+static void mt6397_irq_lock(struct irq_data *data)
+{
+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&mt6397->irqlock);
+}
+
+static void mt6397_irq_sync_unlock(struct irq_data *data)
+{
+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
+
+ regmap_write(mt6397->regmap, mt6397->int_con[0],
+ mt6397->irq_masks_cur[0]);
+ regmap_write(mt6397->regmap, mt6397->int_con[1],
+ mt6397->irq_masks_cur[1]);
+
+ mutex_unlock(&mt6397->irqlock);
+}
+
+static void mt6397_irq_disable(struct irq_data *data)
+{
+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
+ int shift = data->hwirq & 0xf;
+ int reg = data->hwirq >> 4;
+
+ mt6397->irq_masks_cur[reg] &= ~BIT(shift);
+}
+
+static void mt6397_irq_enable(struct irq_data *data)
+{
+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
+ int shift = data->hwirq & 0xf;
+ int reg = data->hwirq >> 4;
+
+ mt6397->irq_masks_cur[reg] |= BIT(shift);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
+{
+ struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
+ int shift = irq_data->hwirq & 0xf;
+ int reg = irq_data->hwirq >> 4;
+
+ if (on)
+ mt6397->wake_mask[reg] |= BIT(shift);
+ else
+ mt6397->wake_mask[reg] &= ~BIT(shift);
+
+ return 0;
+}
+#else
+#define mt6397_irq_set_wake NULL
+#endif
+
+static struct irq_chip mt6397_irq_chip = {
+ .name = "mt6397-irq",
+ .irq_bus_lock = mt6397_irq_lock,
+ .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
+ .irq_enable = mt6397_irq_enable,
+ .irq_disable = mt6397_irq_disable,
+ .irq_set_wake = mt6397_irq_set_wake,
+};
+
+static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
+ int irqbase)
+{
+ unsigned int status;
+ int i, irq, ret;
+
+ ret = regmap_read(mt6397->regmap, reg, &status);
+ if (ret) {
+ dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
+ return;
+ }
+
+ for (i = 0; i < 16; i++) {
+ if (status & BIT(i)) {
+ irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
+ if (irq)
+ handle_nested_irq(irq);
+ }
+ }
+
+ regmap_write(mt6397->regmap, reg, status);
+}
+
+static irqreturn_t mt6397_irq_thread(int irq, void *data)
+{
+ struct mt6397_chip *mt6397 = data;
+
+ mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
+ mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
+
+ return IRQ_HANDLED;
+}
+
+static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ struct mt6397_chip *mt6397 = d->host_data;
+
+ irq_set_chip_data(irq, mt6397);
+ irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
+ irq_set_nested_thread(irq, 1);
+ irq_set_noprobe(irq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops mt6397_irq_domain_ops = {
+ .map = mt6397_irq_domain_map,
+};
+
+static int mt6397_irq_pm_notifier(struct notifier_block *notifier,
+ unsigned long pm_event, void *unused)
+{
+ struct mt6397_chip *chip =
+ container_of(notifier, struct mt6397_chip, pm_nb);
+
+ switch (pm_event) {
+ case PM_SUSPEND_PREPARE:
+ regmap_write(chip->regmap,
+ chip->int_con[0], chip->wake_mask[0]);
+ regmap_write(chip->regmap,
+ chip->int_con[1], chip->wake_mask[1]);
+ enable_irq_wake(chip->irq);
+ break;
+
+ case PM_POST_SUSPEND:
+ regmap_write(chip->regmap,
+ chip->int_con[0], chip->irq_masks_cur[0]);
+ regmap_write(chip->regmap,
+ chip->int_con[1], chip->irq_masks_cur[1]);
+ disable_irq_wake(chip->irq);
+ break;
+
+ default:
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+int mt6397_irq_init(struct mt6397_chip *chip)
+{
+ int ret;
+
+ mutex_init(&chip->irqlock);
+
+ switch (chip->chip_id) {
+ case MT6323_CHIP_ID:
+ chip->int_con[0] = MT6323_INT_CON0;
+ chip->int_con[1] = MT6323_INT_CON1;
+ chip->int_status[0] = MT6323_INT_STATUS0;
+ chip->int_status[1] = MT6323_INT_STATUS1;
+ break;
+
+ case MT6391_CHIP_ID:
+ case MT6397_CHIP_ID:
+ chip->int_con[0] = MT6397_INT_CON0;
+ chip->int_con[1] = MT6397_INT_CON1;
+ chip->int_status[0] = MT6397_INT_STATUS0;
+ chip->int_status[1] = MT6397_INT_STATUS1;
+ break;
+
+ default:
+ dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
+ return -ENODEV;
+ }
+
+ /* Mask all interrupt sources */
+ regmap_write(chip->regmap, chip->int_con[0], 0x0);
+ regmap_write(chip->regmap, chip->int_con[1], 0x0);
+
+ chip->pm_nb.notifier_call = mt6397_irq_pm_notifier;
+ chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
+ MT6397_IRQ_NR,
+ &mt6397_irq_domain_ops,
+ chip);
+ if (!chip->irq_domain) {
+ dev_err(chip->dev, "could not create irq domain\n");
+ return -ENOMEM;
+ }
+
+ ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL,
+ mt6397_irq_thread, IRQF_ONESHOT,
+ "mt6397-pmic", chip);
+ if (ret) {
+ dev_err(chip->dev, "failed to register irq=%d; err: %d\n",
+ chip->irq, ret);
+ return ret;
+ }
+
+ register_pm_notifier(&chip->pm_nb);
+ return 0;
+}
diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
index d678f52..23c8c6a 100644
--- a/include/linux/mfd/mt6397/core.h
+++ b/include/linux/mfd/mt6397/core.h
@@ -15,6 +15,14 @@
#ifndef __MFD_MT6397_CORE_H__
#define __MFD_MT6397_CORE_H__
+#include <linux/notifier.h>
+
+enum chip_id {
+ MT6323_CHIP_ID = 0x23,
+ MT6391_CHIP_ID = 0x91,
+ MT6397_CHIP_ID = 0x97,
+};
+
enum mt6397_irq_numbers {
MT6397_IRQ_SPKL_AB = 0,
MT6397_IRQ_SPKR_AB,
@@ -54,6 +62,7 @@ enum mt6397_irq_numbers {
struct mt6397_chip {
struct device *dev;
struct regmap *regmap;
+ struct notifier_block pm_nb;
int irq;
struct irq_domain *irq_domain;
struct mutex irqlock;
@@ -62,6 +71,9 @@ struct mt6397_chip {
u16 irq_masks_cache[2];
u16 int_con[2];
u16 int_status[2];
+ u16 chip_id;
};
+int mt6397_irq_init(struct mt6397_chip *mt6397);
+
#endif /* __MFD_MT6397_CORE_H__ */
--
1.9.1
This adds compatible for the MediaTek MT6358 PMIC.
Signed-off-by: Hsin-Hsiung Wang <[email protected]>
---
Documentation/devicetree/bindings/mfd/mt6397.txt | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
index 0ebd08a..62f1c17 100644
--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
@@ -17,22 +17,27 @@ Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
This document describes the binding for MFD device and its sub module.
Required properties:
-compatible: "mediatek,mt6397" or "mediatek,mt6323"
+compatible:
+ "mediatek,mt6323" for PMIC MT6323
+ "mediatek,mt6358" for PMIC MT6358
+ "mediatek,mt6397" for PMIC MT6397
Optional subnodes:
- rtc
Required properties:
- - compatible: "mediatek,mt6397-rtc"
+ - compatible: "mediatek,mt6397-rtc" or "mediatek,mt6358-rtc"
- regulators
Required properties:
- compatible: "mediatek,mt6397-regulator"
see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt
+ - compatible: "mediatek,mt6358-regulator"
+ see Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
- compatible: "mediatek,mt6323-regulator"
see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
- codec
Required properties:
- - compatible: "mediatek,mt6397-codec"
+ - compatible: "mediatek,mt6397-codec" or "mediatek,mt6358-sound"
- clk
Required properties:
- compatible: "mediatek,mt6397-clk"
--
1.9.1
From: Ran Bi <[email protected]>
This add support for the MediaTek MT6358 RTC. MT6397 mfd will pass
RTC_WRTGR address offset to RTC driver.
Signed-off-by: Ran Bi <[email protected]>
---
drivers/rtc/rtc-mt6397.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
index f85f1fc..c8a0090 100644
--- a/drivers/rtc/rtc-mt6397.c
+++ b/drivers/rtc/rtc-mt6397.c
@@ -27,7 +27,7 @@
#define RTC_BBPU 0x0000
#define RTC_BBPU_CBUSY BIT(6)
-#define RTC_WRTGR 0x003c
+#define RTC_WRTGR_DEFAULT 0x003c
#define RTC_IRQ_STA 0x0002
#define RTC_IRQ_STA_AL BIT(0)
@@ -78,6 +78,7 @@ struct mt6397_rtc {
struct regmap *regmap;
int irq;
u32 addr_base;
+ u32 wrtgr_offset;
};
static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
@@ -86,7 +87,8 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
int ret;
u32 data;
- ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1);
+ ret = regmap_write(rtc->regmap,
+ rtc->addr_base + rtc->wrtgr_offset, 1);
if (ret < 0)
return ret;
@@ -341,6 +343,15 @@ static int mtk_rtc_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rtc->addr_base = res->start;
+ res = platform_get_resource(pdev, IORESOURCE_REG, 0);
+ if (res) {
+ rtc->wrtgr_offset = res->start;
+ dev_info(&pdev->dev, "register offset:%d\n", rtc->wrtgr_offset);
+ } else {
+ rtc->wrtgr_offset = RTC_WRTGR_DEFAULT;
+ dev_err(&pdev->dev, "Failed to get register offset\n");
+ }
+
rtc->irq = platform_get_irq(pdev, 0);
if (rtc->irq < 0)
return rtc->irq;
@@ -420,6 +431,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
mt6397_rtc_resume);
static const struct of_device_id mt6397_rtc_of_match[] = {
+ { .compatible = "mediatek,mt6358-rtc", },
{ .compatible = "mediatek,mt6397-rtc", },
{ }
};
--
1.9.1
add PMIC MT6358 related nodes which is for mt8183 platform
Signed-off-by: Hsin-Hsiung Wang <[email protected]>
---
arch/arm64/boot/dts/mediatek/mt6358.dtsi | 318 +++++++++++++++++++++++++++++++
1 file changed, 318 insertions(+)
create mode 100644 arch/arm64/boot/dts/mediatek/mt6358.dtsi
diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
new file mode 100644
index 0000000..a7c02ab
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
@@ -0,0 +1,318 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+&pwrap {
+ pmic: mt6358 {
+ compatible = "mediatek,mt6358";
+ interrupt-controller;
+ interrupt-parent = <&pio>;
+ interrupts = <182 IRQ_TYPE_LEVEL_HIGH 190 0>;
+ #interrupt-cells = <2>;
+
+ mt6358codec: mt6358codec {
+ compatible = "mediatek,mt6358-sound";
+ };
+
+ mt6358regulator: mt6358regulator {
+ compatible = "mediatek,mt6358-regulator";
+
+ mt6358_vdram1_reg: buck_vdram1 {
+ regulator-compatible = "buck_vdram1";
+ regulator-name = "vdram1";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2087500>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <0>;
+ regulator-always-on;
+ regulator-allowed-modes = <0 1>;
+ };
+ mt6358_vcore_reg: buck_vcore {
+ regulator-name = "vcore";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-always-on;
+ regulator-allowed-modes = <0 1>;
+ };
+ mt6358_vpa_reg: buck_vpa {
+ regulator-name = "vpa";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <3650000>;
+ regulator-ramp-delay = <50000>;
+ regulator-enable-ramp-delay = <250>;
+ regulator-allowed-modes = <0 1>;
+ };
+ mt6358_vproc11_reg: buck_vproc11 {
+ regulator-name = "vproc11";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-always-on;
+ regulator-allowed-modes = <0 1>;
+ };
+ mt6358_vproc12_reg: buck_vproc12 {
+ regulator-name = "vproc12";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-always-on;
+ regulator-allowed-modes = <0 1>;
+ };
+ mt6358_vgpu_reg: buck_vgpu {
+ regulator-name = "vgpu";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <200>;
+ regulator-allowed-modes = <0 1>;
+ };
+ mt6358_vs2_reg: buck_vs2 {
+ regulator-name = "vs2";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <2087500>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <0>;
+ regulator-always-on;
+ };
+ mt6358_vmodem_reg: buck_vmodem {
+ regulator-name = "vmodem";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <900>;
+ regulator-always-on;
+ regulator-allowed-modes = <0 1>;
+ };
+ mt6358_vs1_reg: buck_vs1 {
+ regulator-name = "vs1";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <2587500>;
+ regulator-ramp-delay = <12500>;
+ regulator-enable-ramp-delay = <0>;
+ regulator-always-on;
+ };
+ mt6358_vdram2_reg: ldo_vdram2 {
+ regulator-name = "vdram2";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <3300>;
+ };
+ mt6358_vsim1_reg: ldo_vsim1 {
+ regulator-name = "vsim1";
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-enable-ramp-delay = <540>;
+ };
+ mt6358_vibr_reg: ldo_vibr {
+ regulator-name = "vibr";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+ mt6358_vrf12_reg: ldo_vrf12 {
+ compatible = "regulator-fixed";
+ regulator-name = "vrf12";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-enable-ramp-delay = <120>;
+ };
+ mt6358_vio18_reg: ldo_vio18 {
+ compatible = "regulator-fixed";
+ regulator-name = "vio18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <2700>;
+ regulator-always-on;
+ };
+ mt6358_vusb_reg: ldo_vusb {
+ regulator-name = "vusb";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-enable-ramp-delay = <270>;
+ regulator-always-on;
+ };
+ mt6358_vcamio_reg: ldo_vcamio {
+ compatible = "regulator-fixed";
+ regulator-name = "vcamio";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vcamd_reg: ldo_vcamd {
+ regulator-name = "vcamd";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vcn18_reg: ldo_vcn18 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcn18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vfe28_reg: ldo_vfe28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vfe28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vsram_proc11_reg: ldo_vsram_proc11 {
+ regulator-name = "vsram_proc11";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-always-on;
+ };
+ mt6358_vcn28_reg: ldo_vcn28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcn28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vsram_others_reg: ldo_vsram_others {
+ regulator-name = "vsram_others";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-always-on;
+ };
+ mt6358_vsram_gpu_reg: ldo_vsram_gpu {
+ regulator-name = "vsram_gpu";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ };
+ mt6358_vxo22_reg: ldo_vxo22 {
+ compatible = "regulator-fixed";
+ regulator-name = "vxo22";
+ regulator-min-microvolt = <2200000>;
+ regulator-max-microvolt = <2200000>;
+ regulator-enable-ramp-delay = <120>;
+ regulator-always-on;
+ };
+ mt6358_vefuse_reg: ldo_vefuse {
+ regulator-name = "vefuse";
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <1900000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vaux18_reg: ldo_vaux18 {
+ compatible = "regulator-fixed";
+ regulator-name = "vaux18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vmch_reg: ldo_vmch {
+ regulator-name = "vmch";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+ mt6358_vbif28_reg: ldo_vbif28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbif28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vsram_proc12_reg: ldo_vsram_proc12 {
+ regulator-name = "vsram_proc12";
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1293750>;
+ regulator-ramp-delay = <6250>;
+ regulator-enable-ramp-delay = <240>;
+ regulator-always-on;
+ };
+ mt6358_vcama1_reg: ldo_vcama1 {
+ regulator-name = "vcama1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vemc_reg: ldo_vemc {
+ regulator-name = "vemc";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <60>;
+ regulator-always-on;
+ };
+ mt6358_vio28_reg: ldo_vio28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vio28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_va12_reg: ldo_va12 {
+ compatible = "regulator-fixed";
+ regulator-name = "va12";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-enable-ramp-delay = <270>;
+ regulator-always-on;
+ };
+ mt6358_vrf18_reg: ldo_vrf18 {
+ compatible = "regulator-fixed";
+ regulator-name = "vrf18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-enable-ramp-delay = <120>;
+ };
+ mt6358_vcn33_bt_reg: ldo_vcn33_bt {
+ regulator-name = "vcn33_bt";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3500000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vcn33_wifi_reg: ldo_vcn33_wifi {
+ regulator-name = "vcn33_wifi";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3500000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vcama2_reg: ldo_vcama2 {
+ regulator-name = "vcama2";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vmc_reg: ldo_vmc {
+ regulator-name = "vmc";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-enable-ramp-delay = <60>;
+ };
+ mt6358_vldo28_reg: ldo_vldo28 {
+ regulator-name = "vldo28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vaud28_reg: ldo_vaud28 {
+ compatible = "regulator-fixed";
+ regulator-name = "vaud28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-enable-ramp-delay = <270>;
+ };
+ mt6358_vsim2_reg: ldo_vsim2 {
+ regulator-name = "vsim2";
+ regulator-min-microvolt = <1700000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-enable-ramp-delay = <540>;
+ };
+ };
+ };
+};
--
1.9.1
On Mon, 2019-03-11 at 11:46 +0800, Hsin-Hsiung Wang wrote:
> From: Ran Bi <[email protected]>
>
> Alarm registers high byte was reserved for other functions.
> This add mask in alarm registers operation functions.
> This also fix error condition in interrupt handler.
>
> Fixes: fc2979118f3f ("rtc: mediatek: Add MT6397 RTC driver")
>
> Signed-off-by: Ran Bi <[email protected]>
> ---
> drivers/rtc/rtc-mt6397.c | 47 +++++++++++++++++++++++++++++++++--------------
> 1 file changed, 33 insertions(+), 14 deletions(-)
>
Thanks your interrupt and race condition fix
Acked-by: Eddie Huang <[email protected]>
On Mon, 2019-03-11 at 11:46 +0800, Hsin-Hsiung Wang wrote:
> From: Ran Bi <[email protected]>
>
> This add support for the MediaTek MT6358 RTC. MT6397 mfd will pass
> RTC_WRTGR address offset to RTC driver.
>
> Signed-off-by: Ran Bi <[email protected]>
> ---
> drivers/rtc/rtc-mt6397.c | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
> index f85f1fc..c8a0090 100644
> --- a/drivers/rtc/rtc-mt6397.c
> +++ b/drivers/rtc/rtc-mt6397.c
> @@ -27,7 +27,7 @@
> #define RTC_BBPU 0x0000
> #define RTC_BBPU_CBUSY BIT(6)
>
> -#define RTC_WRTGR 0x003c
> +#define RTC_WRTGR_DEFAULT 0x003c
>
> #define RTC_IRQ_STA 0x0002
> #define RTC_IRQ_STA_AL BIT(0)
> @@ -78,6 +78,7 @@ struct mt6397_rtc {
> struct regmap *regmap;
> int irq;
> u32 addr_base;
> + u32 wrtgr_offset;
It is strange that hardware change trigger register offset, I think we
have no choice to add a field to describe it.
> };
>
> static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
> @@ -86,7 +87,8 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
> int ret;
> u32 data;
>
> - ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1);
> + ret = regmap_write(rtc->regmap,
> + rtc->addr_base + rtc->wrtgr_offset, 1);
> if (ret < 0)
> return ret;
>
> @@ -341,6 +343,15 @@ static int mtk_rtc_probe(struct platform_device *pdev)
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> rtc->addr_base = res->start;
>
> + res = platform_get_resource(pdev, IORESOURCE_REG, 0);
> + if (res) {
> + rtc->wrtgr_offset = res->start;
> + dev_info(&pdev->dev, "register offset:%d\n", rtc->wrtgr_offset);
Nit: useless log
> + } else {
> + rtc->wrtgr_offset = RTC_WRTGR_DEFAULT;
> + dev_err(&pdev->dev, "Failed to get register offset\n");
> + }
> +
> rtc->irq = platform_get_irq(pdev, 0);
> if (rtc->irq < 0)
> return rtc->irq;
> @@ -420,6 +431,7 @@ static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
> mt6397_rtc_resume);
>
> static const struct of_device_id mt6397_rtc_of_match[] = {
> + { .compatible = "mediatek,mt6358-rtc", },
> { .compatible = "mediatek,mt6397-rtc", },
> { }
> };
Without the log, you can my get
Acked-by: Eddie Huang <eddie.huang@mediatekcom>
Hi,
On Sun, Mar 10, 2019 at 8:48 PM Hsin-Hsiung Wang
<[email protected]> wrote:
>
> clean up code
>
> Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> ---
> drivers/mfd/mt6397-core.c | 16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
> index 77b64bd..acb9812 100644
> --- a/drivers/mfd/mt6397-core.c
> +++ b/drivers/mfd/mt6397-core.c
> @@ -18,17 +18,17 @@
> #include <linux/of_irq.h>
> #include <linux/regmap.h>
> #include <linux/mfd/core.h>
> -#include <linux/mfd/mt6397/core.h>
> #include <linux/mfd/mt6323/core.h>
> -#include <linux/mfd/mt6397/registers.h>
> +#include <linux/mfd/mt6397/core.h>
> #include <linux/mfd/mt6323/registers.h>
> +#include <linux/mfd/mt6397/registers.h>
>
> #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 MT6323_CHIP_ID 0x23
> +#define MT6391_CHIP_ID 0x91
> +#define MT6397_CHIP_ID 0x97
>
It would be not necessary to simply rename the definition or do you
have a strong reason to do that?
> static const struct resource mt6397_rtc_resources[] = {
> {
> @@ -298,7 +298,7 @@ static int mt6397_probe(struct platform_device *pdev)
> return pmic->irq;
>
> switch (id & 0xff) {
> - case MT6323_CID_CODE:
> + case MT6323_CHIP_ID:
> pmic->int_con[0] = MT6323_INT_CON0;
> pmic->int_con[1] = MT6323_INT_CON1;
> pmic->int_status[0] = MT6323_INT_STATUS0;
> @@ -312,8 +312,8 @@ static int mt6397_probe(struct platform_device *pdev)
> 0, pmic->irq_domain);
> break;
>
> - case MT6397_CID_CODE:
> - case MT6391_CID_CODE:
> + case MT6391_CHIP_ID:
> + case MT6397_CHIP_ID:
> pmic->int_con[0] = MT6397_INT_CON0;
> pmic->int_con[1] = MT6397_INT_CON1;
> pmic->int_status[0] = MT6397_INT_STATUS0;
> --
> 1.9.1
>
>
> _______________________________________________
> Linux-mediatek mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
Hi,
I would expect the patch just a migration patch that just moves the
code and should not add something changed or something new in the
patch.
but a new mt6397_irq_pm_notifier is being added into mt6397-irq.c so I
guessed the patch is needed to be refined and split into several
patches on advance if required.
Sean
On Sun, Mar 10, 2019 at 8:49 PM Hsin-Hsiung Wang
<[email protected]> wrote:
>
> In order to support different types of irq design, we decide to add
> separate irq drivers for different design and keep mt6397 mfd core
> simple and reusable to all generations of PMICs so far.
>
> Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> ---
> drivers/mfd/Makefile | 2 +-
> drivers/mfd/mt6397-core.c | 228 ++++++----------------------------------
> drivers/mfd/mt6397-irq.c | 214 +++++++++++++++++++++++++++++++++++++
> include/linux/mfd/mt6397/core.h | 12 +++
> 4 files changed, 259 insertions(+), 197 deletions(-)
> create mode 100644 drivers/mfd/mt6397-irq.c
>
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 12980a4..088e249 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -230,7 +230,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
> obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
> obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
> obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
> -obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
> +obj-$(CONFIG_MFD_MT6397) += mt6397-core.o mt6397-irq.o
>
> obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
> obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
> diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
> index acb9812..53f1edc 100644
> --- a/drivers/mfd/mt6397-core.c
> +++ b/drivers/mfd/mt6397-core.c
> @@ -12,7 +12,6 @@
> * GNU General Public License for more details.
> */
>
> -#include <linux/interrupt.h>
> #include <linux/module.h>
> #include <linux/of_device.h>
> #include <linux/of_irq.h>
> @@ -26,10 +25,6 @@
> #define MT6397_RTC_BASE 0xe000
> #define MT6397_RTC_SIZE 0x3e
>
> -#define MT6323_CHIP_ID 0x23
> -#define MT6391_CHIP_ID 0x91
> -#define MT6397_CHIP_ID 0x97
> -
> static const struct resource mt6397_rtc_resources[] = {
> {
> .start = MT6397_RTC_BASE,
> @@ -94,182 +89,24 @@
> }
> };
>
> -static void mt6397_irq_lock(struct irq_data *data)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> -
> - mutex_lock(&mt6397->irqlock);
> -}
> -
> -static void mt6397_irq_sync_unlock(struct irq_data *data)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> -
> - regmap_write(mt6397->regmap, mt6397->int_con[0],
> - mt6397->irq_masks_cur[0]);
> - regmap_write(mt6397->regmap, mt6397->int_con[1],
> - mt6397->irq_masks_cur[1]);
> -
> - mutex_unlock(&mt6397->irqlock);
> -}
> -
> -static void mt6397_irq_disable(struct irq_data *data)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> - int shift = data->hwirq & 0xf;
> - int reg = data->hwirq >> 4;
> -
> - mt6397->irq_masks_cur[reg] &= ~BIT(shift);
> -}
> -
> -static void mt6397_irq_enable(struct irq_data *data)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> - int shift = data->hwirq & 0xf;
> - int reg = data->hwirq >> 4;
> -
> - mt6397->irq_masks_cur[reg] |= BIT(shift);
> -}
> -
> -#ifdef CONFIG_PM_SLEEP
> -static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
> - int shift = irq_data->hwirq & 0xf;
> - int reg = irq_data->hwirq >> 4;
> -
> - if (on)
> - mt6397->wake_mask[reg] |= BIT(shift);
> - else
> - mt6397->wake_mask[reg] &= ~BIT(shift);
> -
> - return 0;
> -}
> -#else
> -#define mt6397_irq_set_wake NULL
> -#endif
> -
> -static struct irq_chip mt6397_irq_chip = {
> - .name = "mt6397-irq",
> - .irq_bus_lock = mt6397_irq_lock,
> - .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
> - .irq_enable = mt6397_irq_enable,
> - .irq_disable = mt6397_irq_disable,
> - .irq_set_wake = mt6397_irq_set_wake,
> +struct chip_data {
> + u32 cid_addr;
> };
>
> -static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
> - int irqbase)
> -{
> - unsigned int status;
> - int i, irq, ret;
> -
> - ret = regmap_read(mt6397->regmap, reg, &status);
> - if (ret) {
> - dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
> - return;
> - }
> -
> - for (i = 0; i < 16; i++) {
> - if (status & BIT(i)) {
> - irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
> - if (irq)
> - handle_nested_irq(irq);
> - }
> - }
> -
> - regmap_write(mt6397->regmap, reg, status);
> -}
> -
> -static irqreturn_t mt6397_irq_thread(int irq, void *data)
> -{
> - struct mt6397_chip *mt6397 = data;
> -
> - mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
> - mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
> -
> - return IRQ_HANDLED;
> -}
> -
> -static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
> - irq_hw_number_t hw)
> -{
> - struct mt6397_chip *mt6397 = d->host_data;
> -
> - irq_set_chip_data(irq, mt6397);
> - irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
> - irq_set_nested_thread(irq, 1);
> - irq_set_noprobe(irq);
> -
> - return 0;
> -}
> -
> -static const struct irq_domain_ops mt6397_irq_domain_ops = {
> - .map = mt6397_irq_domain_map,
> +static const struct chip_data mt6323_core = {
> + .cid_addr = MT6323_CID,
> };
>
> -static int mt6397_irq_init(struct mt6397_chip *mt6397)
> -{
> - int ret;
> -
> - mutex_init(&mt6397->irqlock);
> -
> - /* Mask all interrupt sources */
> - regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
> - regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
> -
> - mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
> - MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
> - if (!mt6397->irq_domain) {
> - dev_err(mt6397->dev, "could not create irq domain\n");
> - return -ENOMEM;
> - }
> -
> - ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL,
> - mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397);
> - if (ret) {
> - dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n",
> - mt6397->irq, ret);
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> -#ifdef CONFIG_PM_SLEEP
> -static int mt6397_irq_suspend(struct device *dev)
> -{
> - struct mt6397_chip *chip = dev_get_drvdata(dev);
> -
> - regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
> - regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
> -
> - enable_irq_wake(chip->irq);
> -
> - return 0;
> -}
> -
> -static int mt6397_irq_resume(struct device *dev)
> -{
> - struct mt6397_chip *chip = dev_get_drvdata(dev);
> -
> - regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
> - regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
> -
> - disable_irq_wake(chip->irq);
> -
> - return 0;
> -}
> -#endif
> -
> -static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
> - mt6397_irq_resume);
> +static const struct chip_data mt6397_core = {
> + .cid_addr = MT6397_CID,
> +};
>
> static int mt6397_probe(struct platform_device *pdev)
> {
> int ret;
> unsigned int id;
> struct mt6397_chip *pmic;
> + const struct chip_data *pmic_core;
>
> pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
> if (!pmic)
> @@ -285,28 +122,30 @@ static int mt6397_probe(struct platform_device *pdev)
> if (!pmic->regmap)
> return -ENODEV;
>
> - platform_set_drvdata(pdev, pmic);
> + pmic_core = of_device_get_match_data(&pdev->dev);
> + if (!pmic_core)
> + return -ENODEV;
>
> - ret = regmap_read(pmic->regmap, MT6397_CID, &id);
> + ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
> if (ret) {
> - dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
> + dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);
> return ret;
> }
>
> + pmic->chip_id = id & 0xff;
> +
> + platform_set_drvdata(pdev, pmic);
> +
> pmic->irq = platform_get_irq(pdev, 0);
> if (pmic->irq <= 0)
> return pmic->irq;
>
> - switch (id & 0xff) {
> - case MT6323_CHIP_ID:
> - pmic->int_con[0] = MT6323_INT_CON0;
> - pmic->int_con[1] = MT6323_INT_CON1;
> - pmic->int_status[0] = MT6323_INT_STATUS0;
> - pmic->int_status[1] = MT6323_INT_STATUS1;
> - ret = mt6397_irq_init(pmic);
> - if (ret)
> - return ret;
> + ret = mt6397_irq_init(pmic);
> + if (ret)
> + return ret;
>
> + switch (pmic->chip_id) {
> + case MT6323_CHIP_ID:
> ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
> ARRAY_SIZE(mt6323_devs), NULL,
> 0, pmic->irq_domain);
> @@ -314,21 +153,13 @@ static int mt6397_probe(struct platform_device *pdev)
>
> case MT6391_CHIP_ID:
> case MT6397_CHIP_ID:
> - pmic->int_con[0] = MT6397_INT_CON0;
> - pmic->int_con[1] = MT6397_INT_CON1;
> - pmic->int_status[0] = MT6397_INT_STATUS0;
> - pmic->int_status[1] = MT6397_INT_STATUS1;
> - ret = mt6397_irq_init(pmic);
> - if (ret)
> - return ret;
> -
> ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
> ARRAY_SIZE(mt6397_devs), NULL,
> 0, pmic->irq_domain);
> break;
>
> default:
> - dev_err(&pdev->dev, "unsupported chip: %d\n", id);
> + dev_err(&pdev->dev, "unsupported chip: %d\n", pmic->chip_id);
> ret = -ENODEV;
> break;
> }
> @@ -342,9 +173,15 @@ 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,mt6323",
> + .data = &mt6323_core,
> + }, {
> + .compatible = "mediatek,mt6397",
> + .data = &mt6397_core,
> + }, {
> + /* sentinel */
> + }
> };
> MODULE_DEVICE_TABLE(of, mt6397_of_match);
>
> @@ -359,7 +196,6 @@ static int mt6397_probe(struct platform_device *pdev)
> .driver = {
> .name = "mt6397",
> .of_match_table = of_match_ptr(mt6397_of_match),
> - .pm = &mt6397_pm_ops,
> },
> .id_table = mt6397_id,
> };
> diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c
> new file mode 100644
> index 0000000..669e93d
> --- /dev/null
> +++ b/drivers/mfd/mt6397-irq.c
> @@ -0,0 +1,214 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Copyright (c) 2019 MediaTek Inc.
> +
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/suspend.h>
> +#include <linux/mfd/mt6323/core.h>
> +#include <linux/mfd/mt6323/registers.h>
> +#include <linux/mfd/mt6397/core.h>
> +#include <linux/mfd/mt6397/registers.h>
> +
> +static void mt6397_irq_lock(struct irq_data *data)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> +
> + mutex_lock(&mt6397->irqlock);
> +}
> +
> +static void mt6397_irq_sync_unlock(struct irq_data *data)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> +
> + regmap_write(mt6397->regmap, mt6397->int_con[0],
> + mt6397->irq_masks_cur[0]);
> + regmap_write(mt6397->regmap, mt6397->int_con[1],
> + mt6397->irq_masks_cur[1]);
> +
> + mutex_unlock(&mt6397->irqlock);
> +}
> +
> +static void mt6397_irq_disable(struct irq_data *data)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> + int shift = data->hwirq & 0xf;
> + int reg = data->hwirq >> 4;
> +
> + mt6397->irq_masks_cur[reg] &= ~BIT(shift);
> +}
> +
> +static void mt6397_irq_enable(struct irq_data *data)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> + int shift = data->hwirq & 0xf;
> + int reg = data->hwirq >> 4;
> +
> + mt6397->irq_masks_cur[reg] |= BIT(shift);
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
> + int shift = irq_data->hwirq & 0xf;
> + int reg = irq_data->hwirq >> 4;
> +
> + if (on)
> + mt6397->wake_mask[reg] |= BIT(shift);
> + else
> + mt6397->wake_mask[reg] &= ~BIT(shift);
> +
> + return 0;
> +}
> +#else
> +#define mt6397_irq_set_wake NULL
> +#endif
> +
> +static struct irq_chip mt6397_irq_chip = {
> + .name = "mt6397-irq",
> + .irq_bus_lock = mt6397_irq_lock,
> + .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
> + .irq_enable = mt6397_irq_enable,
> + .irq_disable = mt6397_irq_disable,
> + .irq_set_wake = mt6397_irq_set_wake,
> +};
> +
> +static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
> + int irqbase)
> +{
> + unsigned int status;
> + int i, irq, ret;
> +
> + ret = regmap_read(mt6397->regmap, reg, &status);
> + if (ret) {
> + dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
> + return;
> + }
> +
> + for (i = 0; i < 16; i++) {
> + if (status & BIT(i)) {
> + irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
> + if (irq)
> + handle_nested_irq(irq);
> + }
> + }
> +
> + regmap_write(mt6397->regmap, reg, status);
> +}
> +
> +static irqreturn_t mt6397_irq_thread(int irq, void *data)
> +{
> + struct mt6397_chip *mt6397 = data;
> +
> + mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
> + mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hw)
> +{
> + struct mt6397_chip *mt6397 = d->host_data;
> +
> + irq_set_chip_data(irq, mt6397);
> + irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
> + irq_set_nested_thread(irq, 1);
> + irq_set_noprobe(irq);
> +
> + return 0;
> +}
> +
> +static const struct irq_domain_ops mt6397_irq_domain_ops = {
> + .map = mt6397_irq_domain_map,
> +};
> +
> +static int mt6397_irq_pm_notifier(struct notifier_block *notifier,
> + unsigned long pm_event, void *unused)
> +{
> + struct mt6397_chip *chip =
> + container_of(notifier, struct mt6397_chip, pm_nb);
> +
> + switch (pm_event) {
> + case PM_SUSPEND_PREPARE:
> + regmap_write(chip->regmap,
> + chip->int_con[0], chip->wake_mask[0]);
> + regmap_write(chip->regmap,
> + chip->int_con[1], chip->wake_mask[1]);
> + enable_irq_wake(chip->irq);
> + break;
> +
> + case PM_POST_SUSPEND:
> + regmap_write(chip->regmap,
> + chip->int_con[0], chip->irq_masks_cur[0]);
> + regmap_write(chip->regmap,
> + chip->int_con[1], chip->irq_masks_cur[1]);
> + disable_irq_wake(chip->irq);
> + break;
> +
> + default:
> + break;
> + }
> +
> + return NOTIFY_DONE;
> +}
> +
> +int mt6397_irq_init(struct mt6397_chip *chip)
> +{
> + int ret;
> +
> + mutex_init(&chip->irqlock);
> +
> + switch (chip->chip_id) {
> + case MT6323_CHIP_ID:
> + chip->int_con[0] = MT6323_INT_CON0;
> + chip->int_con[1] = MT6323_INT_CON1;
> + chip->int_status[0] = MT6323_INT_STATUS0;
> + chip->int_status[1] = MT6323_INT_STATUS1;
> + break;
> +
> + case MT6391_CHIP_ID:
> + case MT6397_CHIP_ID:
> + chip->int_con[0] = MT6397_INT_CON0;
> + chip->int_con[1] = MT6397_INT_CON1;
> + chip->int_status[0] = MT6397_INT_STATUS0;
> + chip->int_status[1] = MT6397_INT_STATUS1;
> + break;
> +
> + default:
> + dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
> + return -ENODEV;
> + }
> +
> + /* Mask all interrupt sources */
> + regmap_write(chip->regmap, chip->int_con[0], 0x0);
> + regmap_write(chip->regmap, chip->int_con[1], 0x0);
> +
> + chip->pm_nb.notifier_call = mt6397_irq_pm_notifier;
> + chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
> + MT6397_IRQ_NR,
> + &mt6397_irq_domain_ops,
> + chip);
> + if (!chip->irq_domain) {
> + dev_err(chip->dev, "could not create irq domain\n");
> + return -ENOMEM;
> + }
> +
> + ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL,
> + mt6397_irq_thread, IRQF_ONESHOT,
> + "mt6397-pmic", chip);
> + if (ret) {
> + dev_err(chip->dev, "failed to register irq=%d; err: %d\n",
> + chip->irq, ret);
> + return ret;
> + }
> +
> + register_pm_notifier(&chip->pm_nb);
> + return 0;
> +}
> diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
> index d678f52..23c8c6a 100644
> --- a/include/linux/mfd/mt6397/core.h
> +++ b/include/linux/mfd/mt6397/core.h
> @@ -15,6 +15,14 @@
> #ifndef __MFD_MT6397_CORE_H__
> #define __MFD_MT6397_CORE_H__
>
> +#include <linux/notifier.h>
> +
> +enum chip_id {
> + MT6323_CHIP_ID = 0x23,
> + MT6391_CHIP_ID = 0x91,
> + MT6397_CHIP_ID = 0x97,
> +};
> +
> enum mt6397_irq_numbers {
> MT6397_IRQ_SPKL_AB = 0,
> MT6397_IRQ_SPKR_AB,
> @@ -54,6 +62,7 @@ enum mt6397_irq_numbers {
> struct mt6397_chip {
> struct device *dev;
> struct regmap *regmap;
> + struct notifier_block pm_nb;
> int irq;
> struct irq_domain *irq_domain;
> struct mutex irqlock;
> @@ -62,6 +71,9 @@ struct mt6397_chip {
> u16 irq_masks_cache[2];
> u16 int_con[2];
> u16 int_status[2];
> + u16 chip_id;
> };
>
> +int mt6397_irq_init(struct mt6397_chip *mt6397);
> +
> #endif /* __MFD_MT6397_CORE_H__ */
> --
> 1.9.1
>
>
> _______________________________________________
> Linux-mediatek mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
Hi,
Always put the patches about dt-binding changes at the head of the
series to let the related maintainer more easily find them.
On Sun, Mar 10, 2019 at 8:48 PM Hsin-Hsiung Wang
<[email protected]> wrote:
>
> This adds compatible for the MediaTek MT6358 PMIC.
>
> Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> ---
> Documentation/devicetree/bindings/mfd/mt6397.txt | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
> index 0ebd08a..62f1c17 100644
> --- a/Documentation/devicetree/bindings/mfd/mt6397.txt
> +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
> @@ -17,22 +17,27 @@ Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
> This document describes the binding for MFD device and its sub module.
>
> Required properties:
> -compatible: "mediatek,mt6397" or "mediatek,mt6323"
> +compatible:
> + "mediatek,mt6323" for PMIC MT6323
> + "mediatek,mt6358" for PMIC MT6358
> + "mediatek,mt6397" for PMIC MT6397
don't change anything not related MT6358
>
> Optional subnodes:
>
> - rtc
> Required properties:
> - - compatible: "mediatek,mt6397-rtc"
> + - compatible: "mediatek,mt6397-rtc" or "mediatek,mt6358-rtc"
> - regulators
> Required properties:
> - compatible: "mediatek,mt6397-regulator"
> see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt
> + - compatible: "mediatek,mt6358-regulator"
> + see Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
> - compatible: "mediatek,mt6323-regulator"
> see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
> - codec
> Required properties:
> - - compatible: "mediatek,mt6397-codec"
> + - compatible: "mediatek,mt6397-codec" or "mediatek,mt6358-sound"
why didn't we use a more consistent naming as mt6358-codec?
> - clk
> Required properties:
> - compatible: "mediatek,mt6397-clk"
> --
> 1.9.1
>
>
> _______________________________________________
> Linux-mediatek mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
Hi,
add a dt-bindings prefix and move the patch to the first order in the series.
On Sun, Mar 10, 2019 at 9:03 PM Hsin-Hsiung Wang
<[email protected]> wrote:
>
> add dt-binding document for MediaTek MT6358 PMIC
>
> Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> ---
> .../bindings/regulator/mt6358-regulator.txt | 318 +++++++++++++++++++++
> 1 file changed, 318 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
>
> diff --git a/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
> new file mode 100644
> index 0000000..3ea8073
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
> @@ -0,0 +1,318 @@
> +Mediatek MT6358 Regulator
MediaTek
> +
> +Required properties:
> +- compatible: "mediatek,mt6358-regulator"
> +- mt6358regulator: List of regulators provided by this controller. It is named
mt6358regulator is not a required property, it is just a node alias.
> + according to its regulator type, buck_<name> and ldo_<name>.
> + The definition for each of these nodes is defined using the standard binding
> + for regulators at Documentation/devicetree/bindings/regulator/regulator.txt.
> +
> +The valid names for regulators are::
> +BUCK:
> + buck_vdram1, buck_vcore, buck_vpa, buck_vproc11, buck_vproc12, buck_vgpu,
> + buck_vs2, buck_vmodem, buck_vs1
> +LDO:
> + ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio,
> + ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others,
> + ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28,
> + ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18,
> + ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
> + ldo_vsim2
> +
> +Example:
> + pmic {
> + compatible = "mediatek,mt6358";
it is not necessary to document the PMIC part in the regulator binding
and you can refer to mt6380-regulator.txt or mt6323-regulator.txt
first to make the
style about the PMIC description and example be more consistent.
> +
> + mt6358regulator: mt6358regulator {
> + compatible = "mediatek,mt6358-regulator";
use a generic node, regulators, something like
regulators {
compatible = "mediatek,mt6358-regulator";
> +
> + mt6358_vdram1_reg: buck_vdram1 {
> + regulator-compatible = "buck_vdram1";
> + regulator-name = "vdram1";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <2087500>;
> + regulator-ramp-delay = <12500>;
> + regulator-enable-ramp-delay = <0>;
> + regulator-always-on;
> + };
add a blank line between subnodes which includes all below occurrences
> + mt6358_vcore_reg: buck_vcore {
> + regulator-name = "vcore";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-always-on;
> + };
> + mt6358_vpa_reg: buck_vpa {
> + regulator-name = "vpa";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <3650000>;
> + regulator-ramp-delay = <50000>;
> + regulator-enable-ramp-delay = <250>;
> + };
> + mt6358_vproc11_reg: buck_vproc11 {
> + regulator-name = "vproc11";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-always-on;
> + };
> + mt6358_vproc12_reg: buck_vproc12 {
> + regulator-name = "vproc12";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-always-on;
> + };
> + mt6358_vgpu_reg: buck_vgpu {
> + regulator-name = "vgpu";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <200>;
> + };
> + mt6358_vs2_reg: buck_vs2 {
> + regulator-name = "vs2";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <2087500>;
> + regulator-ramp-delay = <12500>;
> + regulator-enable-ramp-delay = <0>;
> + regulator-always-on;
> + };
> + mt6358_vmodem_reg: buck_vmodem {
> + regulator-name = "vmodem";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <900>;
> + regulator-always-on;
> + };
> + mt6358_vs1_reg: buck_vs1 {
> + regulator-name = "vs1";
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <2587500>;
> + regulator-ramp-delay = <12500>;
> + regulator-enable-ramp-delay = <0>;
> + regulator-always-on;
> + };
> + mt6358_vdram2_reg: ldo_vdram2 {
> + regulator-name = "vdram2";
> + regulator-min-microvolt = <600000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <3300>;
> + };
> + mt6358_vsim1_reg: ldo_vsim1 {
> + regulator-name = "vsim1";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <3100000>;
> + regulator-enable-ramp-delay = <540>;
> + };
> + mt6358_vibr_reg: ldo_vibr {
> + regulator-name = "vibr";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <60>;
> + };
> + mt6358_vrf12_reg: ldo_vrf12 {
> + compatible = "regulator-fixed";
> + regulator-name = "vrf12";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-enable-ramp-delay = <120>;
> + };
> + mt6358_vio18_reg: ldo_vio18 {
> + compatible = "regulator-fixed";
> + regulator-name = "vio18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <2700>;
> + regulator-always-on;
> + };
> + mt6358_vusb_reg: ldo_vusb {
> + regulator-name = "vusb";
> + regulator-min-microvolt = <3000000>;
> + regulator-max-microvolt = <3100000>;
> + regulator-enable-ramp-delay = <270>;
> + regulator-always-on;
> + };
> + mt6358_vcamio_reg: ldo_vcamio {
> + compatible = "regulator-fixed";
> + regulator-name = "vcamio";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vcamd_reg: ldo_vcamd {
> + regulator-name = "vcamd";
> + regulator-min-microvolt = <900000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vcn18_reg: ldo_vcn18 {
> + compatible = "regulator-fixed";
> + regulator-name = "vcn18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vfe28_reg: ldo_vfe28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vfe28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vsram_proc11_reg: ldo_vsram_proc11 {
> + regulator-name = "vsram_proc11";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <240>;
> + regulator-always-on;
> + };
> + mt6358_vcn28_reg: ldo_vcn28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vcn28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vsram_others_reg: ldo_vsram_others {
> + regulator-name = "vsram_others";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <240>;
> + regulator-always-on;
> + };
> + mt6358_vsram_gpu_reg: ldo_vsram_gpu {
> + regulator-name = "vsram_gpu";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <240>;
> + };
> + mt6358_vxo22_reg: ldo_vxo22 {
> + compatible = "regulator-fixed";
> + regulator-name = "vxo22";
> + regulator-min-microvolt = <2200000>;
> + regulator-max-microvolt = <2200000>;
> + regulator-enable-ramp-delay = <120>;
> + regulator-always-on;
> + };
> + mt6358_vefuse_reg: ldo_vefuse {
> + regulator-name = "vefuse";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <1900000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vaux18_reg: ldo_vaux18 {
> + compatible = "regulator-fixed";
> + regulator-name = "vaux18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vmch_reg: ldo_vmch {
> + regulator-name = "vmch";
> + regulator-min-microvolt = <2900000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <60>;
> + };
> + mt6358_vbif28_reg: ldo_vbif28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vbif28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vsram_proc12_reg: ldo_vsram_proc12 {
> + regulator-name = "vsram_proc12";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <240>;
> + regulator-always-on;
> + };
> + mt6358_vcama1_reg: ldo_vcama1 {
> + regulator-name = "vcama1";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vemc_reg: ldo_vemc {
> + regulator-name = "vemc";
> + regulator-min-microvolt = <2900000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <60>;
> + regulator-always-on;
> + };
> + mt6358_vio28_reg: ldo_vio28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vio28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_va12_reg: ldo_va12 {
> + compatible = "regulator-fixed";
> + regulator-name = "va12";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-enable-ramp-delay = <270>;
> + regulator-always-on;
> + };
> + mt6358_vrf18_reg: ldo_vrf18 {
> + compatible = "regulator-fixed";
> + regulator-name = "vrf18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <120>;
> + };
> + mt6358_vcn33_bt_reg: ldo_vcn33_bt {
> + regulator-name = "vcn33_bt";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3500000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vcn33_wifi_reg: ldo_vcn33_wifi {
> + regulator-name = "vcn33_wifi";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3500000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vcama2_reg: ldo_vcama2 {
> + regulator-name = "vcama2";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vmc_reg: ldo_vmc {
> + regulator-name = "vmc";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <60>;
> + };
> + mt6358_vldo28_reg: ldo_vldo28 {
> + regulator-name = "vldo28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vaud28_reg: ldo_vaud28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vaud28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vsim2_reg: ldo_vsim2 {
> + regulator-name = "vsim2";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <3100000>;
> + regulator-enable-ramp-delay = <540>;
> + };
> + };
> + };
> --
> 1.9.1
>
>
> _______________________________________________
> Linux-mediatek mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
Hi,
On Sun, Mar 10, 2019 at 8:49 PM Hsin-Hsiung Wang
<[email protected]> wrote:
>
> add PMIC MT6358 related nodes which is for mt8183 platform
>
s/MT8183/mt8183/
> Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> ---
> arch/arm64/boot/dts/mediatek/mt6358.dtsi | 318 +++++++++++++++++++++++++++++++
> 1 file changed, 318 insertions(+)
> create mode 100644 arch/arm64/boot/dts/mediatek/mt6358.dtsi
>
> diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
> new file mode 100644
> index 0000000..a7c02ab
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
> @@ -0,0 +1,318 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (c) 2019 MediaTek Inc.
> + */
> +
> +&pwrap {
> + pmic: mt6358 {
use a generic name
pmic {
> + compatible = "mediatek,mt6358";
> + interrupt-controller;
> + interrupt-parent = <&pio>;
> + interrupts = <182 IRQ_TYPE_LEVEL_HIGH 190 0>;
> + #interrupt-cells = <2>;
> +
> + mt6358codec: mt6358codec {
use a generic name
audio-codec {
> + compatible = "mediatek,mt6358-sound";
> + };
> +
> + mt6358regulator: mt6358regulator {
use a generic name
regulators {
> + compatible = "mediatek,mt6358-regulator";
> +
> + mt6358_vdram1_reg: buck_vdram1 {
> + regulator-compatible = "buck_vdram1";
> + regulator-name = "vdram1";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <2087500>;
> + regulator-ramp-delay = <12500>;
> + regulator-enable-ramp-delay = <0>;
> + regulator-always-on;
> + regulator-allowed-modes = <0 1>;
> + };
add a blank line here and for all below occurrences
> + mt6358_vcore_reg: buck_vcore {
> + regulator-name = "vcore";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-always-on;
> + regulator-allowed-modes = <0 1>;
> + };
> + mt6358_vpa_reg: buck_vpa {
> + regulator-name = "vpa";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <3650000>;
> + regulator-ramp-delay = <50000>;
> + regulator-enable-ramp-delay = <250>;
> + regulator-allowed-modes = <0 1>;
> + };
> + mt6358_vproc11_reg: buck_vproc11 {
> + regulator-name = "vproc11";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-always-on;
> + regulator-allowed-modes = <0 1>;
> + };
> + mt6358_vproc12_reg: buck_vproc12 {
> + regulator-name = "vproc12";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-always-on;
> + regulator-allowed-modes = <0 1>;
> + };
> + mt6358_vgpu_reg: buck_vgpu {
> + regulator-name = "vgpu";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <200>;
> + regulator-allowed-modes = <0 1>;
> + };
> + mt6358_vs2_reg: buck_vs2 {
> + regulator-name = "vs2";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <2087500>;
> + regulator-ramp-delay = <12500>;
> + regulator-enable-ramp-delay = <0>;
> + regulator-always-on;
> + };
> + mt6358_vmodem_reg: buck_vmodem {
> + regulator-name = "vmodem";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <900>;
> + regulator-always-on;
> + regulator-allowed-modes = <0 1>;
> + };
> + mt6358_vs1_reg: buck_vs1 {
> + regulator-name = "vs1";
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <2587500>;
> + regulator-ramp-delay = <12500>;
> + regulator-enable-ramp-delay = <0>;
> + regulator-always-on;
> + };
> + mt6358_vdram2_reg: ldo_vdram2 {
> + regulator-name = "vdram2";
> + regulator-min-microvolt = <600000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <3300>;
> + };
> + mt6358_vsim1_reg: ldo_vsim1 {
> + regulator-name = "vsim1";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <3100000>;
> + regulator-enable-ramp-delay = <540>;
> + };
> + mt6358_vibr_reg: ldo_vibr {
> + regulator-name = "vibr";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <60>;
> + };
> + mt6358_vrf12_reg: ldo_vrf12 {
> + compatible = "regulator-fixed";
> + regulator-name = "vrf12";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-enable-ramp-delay = <120>;
> + };
> + mt6358_vio18_reg: ldo_vio18 {
> + compatible = "regulator-fixed";
> + regulator-name = "vio18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <2700>;
> + regulator-always-on;
> + };
> + mt6358_vusb_reg: ldo_vusb {
> + regulator-name = "vusb";
> + regulator-min-microvolt = <3000000>;
> + regulator-max-microvolt = <3100000>;
> + regulator-enable-ramp-delay = <270>;
> + regulator-always-on;
> + };
> + mt6358_vcamio_reg: ldo_vcamio {
> + compatible = "regulator-fixed";
> + regulator-name = "vcamio";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vcamd_reg: ldo_vcamd {
> + regulator-name = "vcamd";
> + regulator-min-microvolt = <900000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vcn18_reg: ldo_vcn18 {
> + compatible = "regulator-fixed";
> + regulator-name = "vcn18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vfe28_reg: ldo_vfe28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vfe28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vsram_proc11_reg: ldo_vsram_proc11 {
> + regulator-name = "vsram_proc11";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <240>;
> + regulator-always-on;
> + };
> + mt6358_vcn28_reg: ldo_vcn28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vcn28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vsram_others_reg: ldo_vsram_others {
> + regulator-name = "vsram_others";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <240>;
> + regulator-always-on;
> + };
> + mt6358_vsram_gpu_reg: ldo_vsram_gpu {
> + regulator-name = "vsram_gpu";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <240>;
> + };
> + mt6358_vxo22_reg: ldo_vxo22 {
> + compatible = "regulator-fixed";
> + regulator-name = "vxo22";
> + regulator-min-microvolt = <2200000>;
> + regulator-max-microvolt = <2200000>;
> + regulator-enable-ramp-delay = <120>;
> + regulator-always-on;
> + };
> + mt6358_vefuse_reg: ldo_vefuse {
> + regulator-name = "vefuse";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <1900000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vaux18_reg: ldo_vaux18 {
> + compatible = "regulator-fixed";
> + regulator-name = "vaux18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vmch_reg: ldo_vmch {
> + regulator-name = "vmch";
> + regulator-min-microvolt = <2900000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <60>;
> + };
> + mt6358_vbif28_reg: ldo_vbif28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vbif28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vsram_proc12_reg: ldo_vsram_proc12 {
> + regulator-name = "vsram_proc12";
> + regulator-min-microvolt = <500000>;
> + regulator-max-microvolt = <1293750>;
> + regulator-ramp-delay = <6250>;
> + regulator-enable-ramp-delay = <240>;
> + regulator-always-on;
> + };
> + mt6358_vcama1_reg: ldo_vcama1 {
> + regulator-name = "vcama1";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vemc_reg: ldo_vemc {
> + regulator-name = "vemc";
> + regulator-min-microvolt = <2900000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <60>;
> + regulator-always-on;
> + };
> + mt6358_vio28_reg: ldo_vio28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vio28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_va12_reg: ldo_va12 {
> + compatible = "regulator-fixed";
> + regulator-name = "va12";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-enable-ramp-delay = <270>;
> + regulator-always-on;
> + };
> + mt6358_vrf18_reg: ldo_vrf18 {
> + compatible = "regulator-fixed";
> + regulator-name = "vrf18";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <120>;
> + };
> + mt6358_vcn33_bt_reg: ldo_vcn33_bt {
> + regulator-name = "vcn33_bt";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3500000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vcn33_wifi_reg: ldo_vcn33_wifi {
> + regulator-name = "vcn33_wifi";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3500000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vcama2_reg: ldo_vcama2 {
> + regulator-name = "vcama2";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vmc_reg: ldo_vmc {
> + regulator-name = "vmc";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <60>;
> + };
> + mt6358_vldo28_reg: ldo_vldo28 {
> + regulator-name = "vldo28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vaud28_reg: ldo_vaud28 {
> + compatible = "regulator-fixed";
> + regulator-name = "vaud28";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-enable-ramp-delay = <270>;
> + };
> + mt6358_vsim2_reg: ldo_vsim2 {
> + regulator-name = "vsim2";
> + regulator-min-microvolt = <1700000>;
> + regulator-max-microvolt = <3100000>;
> + regulator-enable-ramp-delay = <540>;
> + };
> + };
> + };
> +};
> --
> 1.9.1
>
>
> _______________________________________________
> Linux-mediatek mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
Hi,
On Sun, Mar 10, 2019 at 8:49 PM Hsin-Hsiung Wang
<[email protected]> wrote:
>
> From: Ran Bi <[email protected]>
>
> Alarm registers high byte was reserved for other functions.
> This add mask in alarm registers operation functions.
> This also fix error condition in interrupt handler.
>
> Fixes: fc2979118f3f ("rtc: mediatek: Add MT6397 RTC driver")
>
add a Cc: [email protected] here to apply to all stable kernels
for the critical fixup patch.
> Signed-off-by: Ran Bi <[email protected]>
> ---
> drivers/rtc/rtc-mt6397.c | 47 +++++++++++++++++++++++++++++++++--------------
> 1 file changed, 33 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
> index e9a25ec..f85f1fc 100644
> --- a/drivers/rtc/rtc-mt6397.c
> +++ b/drivers/rtc/rtc-mt6397.c
> @@ -55,6 +55,14 @@
>
> #define RTC_AL_SEC 0x0018
>
> +#define RTC_AL_SEC_MASK 0x003f
> +#define RTC_AL_MIN_MASK 0x003f
> +#define RTC_AL_HOU_MASK 0x001f
> +#define RTC_AL_DOM_MASK 0x001f
> +#define RTC_AL_DOW_MASK 0x0007
> +#define RTC_AL_MTH_MASK 0x000f
> +#define RTC_AL_YEA_MASK 0x007f
> +
> #define RTC_PDN2 0x002e
> #define RTC_PDN2_PWRON_ALARM BIT(4)
>
> @@ -111,7 +119,7 @@ static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data)
> irqen = irqsta & ~RTC_IRQ_EN_AL;
> mutex_lock(&rtc->lock);
> if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN,
> - irqen) < 0)
> + irqen) == 0)
> mtk_rtc_write_trigger(rtc);
> mutex_unlock(&rtc->lock);
>
> @@ -233,12 +241,12 @@ static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
> alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM);
> mutex_unlock(&rtc->lock);
>
> - tm->tm_sec = data[RTC_OFFSET_SEC];
> - tm->tm_min = data[RTC_OFFSET_MIN];
> - tm->tm_hour = data[RTC_OFFSET_HOUR];
> - tm->tm_mday = data[RTC_OFFSET_DOM];
> - tm->tm_mon = data[RTC_OFFSET_MTH];
> - tm->tm_year = data[RTC_OFFSET_YEAR];
> + tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK;
> + tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK;
> + tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK;
> + tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK;
> + tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK;
> + tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK;
>
> tm->tm_year += RTC_MIN_YEAR_OFFSET;
> tm->tm_mon--;
> @@ -259,14 +267,25 @@ static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
> tm->tm_year -= RTC_MIN_YEAR_OFFSET;
> tm->tm_mon++;
>
> - data[RTC_OFFSET_SEC] = tm->tm_sec;
> - data[RTC_OFFSET_MIN] = tm->tm_min;
> - data[RTC_OFFSET_HOUR] = tm->tm_hour;
> - data[RTC_OFFSET_DOM] = tm->tm_mday;
> - data[RTC_OFFSET_MTH] = tm->tm_mon;
> - data[RTC_OFFSET_YEAR] = tm->tm_year;
> -
> mutex_lock(&rtc->lock);
> + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC,
> + data, RTC_OFFSET_COUNT);
> + if (ret < 0)
> + goto exit;
> +
Why did we need an additional regmap_bulk_read here? I would suppose
data[RTC_OFFSET_*] & ~(RTC_AL_*_MASK) is always equal to 0.
It might be another fixup since change is not being mentioned in the
git message.
> + data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) |
> + (tm->tm_sec & RTC_AL_SEC_MASK));
> + data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) |
> + (tm->tm_min & RTC_AL_MIN_MASK));
> + data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) |
> + (tm->tm_hour & RTC_AL_HOU_MASK));
> + data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) |
> + (tm->tm_mday & RTC_AL_DOM_MASK));
> + data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) |
> + (tm->tm_mon & RTC_AL_MTH_MASK));
> + data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) |
> + (tm->tm_year & RTC_AL_YEA_MASK));
> +
> if (alm->enabled) {
> ret = regmap_bulk_write(rtc->regmap,
> rtc->addr_base + RTC_AL_SEC,
> --
> 1.9.1
>
>
> _______________________________________________
> Linux-mediatek mailing list
> [email protected]
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
Hello,
On 11/03/2019 11:46:22+0800, Hsin-Hsiung Wang wrote:
> This patchset including refactoring interrupt add support to MT6358 PMIC.
> MT6358 is the primary PMIC for MT8183 platform.
>
> changes since v1:
> - refine for better code quality.
> - remove of_match_table in the MT6358 regulator driver.
> - some minor bug fix of mfd driver, like getting pmic id flow.
> - add support for the MediaTek MT6358 RTC.
>
> Hsin-Hsiung Wang (7):
> mfd: mt6397: clean up code
> mfd: mt6397: extract irq related code from core driver
> dt-bindings: mfd: Add compatible for the MediaTek MT6358 PMIC
> regulator: Add document for MT6358 regulator
> mfd: Add support for the MediaTek MT6358 PMIC
> regulator: mt6358: Add support for MT6358 regulator
> arm64: dts: mt6358: add PMIC MT6358 related nodes
>
> Ran Bi (2):
> rtc: mt6397: fix alarm register overwrite
> rtc: Add support for the MediaTek MT6358 RTC
>
It seems that those two patches are quite independent from the other
changes. How do you expect those to be merged?
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On Mon, Mar 11, 2019 at 12:19:32PM -0700, Sean Wang wrote:
> Hi,
>
> Always put the patches about dt-binding changes at the head of the
> series to let the related maintainer more easily find them.
>
> On Sun, Mar 10, 2019 at 8:48 PM Hsin-Hsiung Wang
> <[email protected]> wrote:
> >
> > This adds compatible for the MediaTek MT6358 PMIC.
> >
> > Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> > ---
> > Documentation/devicetree/bindings/mfd/mt6397.txt | 11 ++++++++---
> > 1 file changed, 8 insertions(+), 3 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
> > index 0ebd08a..62f1c17 100644
> > --- a/Documentation/devicetree/bindings/mfd/mt6397.txt
> > +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
> > @@ -17,22 +17,27 @@ Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
> > This document describes the binding for MFD device and its sub module.
> >
> > Required properties:
> > -compatible: "mediatek,mt6397" or "mediatek,mt6323"
> > +compatible:
> > + "mediatek,mt6323" for PMIC MT6323
> > + "mediatek,mt6358" for PMIC MT6358
> > + "mediatek,mt6397" for PMIC MT6397
>
> don't change anything not related MT6358
Reformatting like this is preferred.
Rob
On Mon, Mar 11, 2019 at 3:06 PM Rob Herring <[email protected]> wrote:
>
> On Mon, Mar 11, 2019 at 12:19:32PM -0700, Sean Wang wrote:
> > Hi,
> >
> > Always put the patches about dt-binding changes at the head of the
> > series to let the related maintainer more easily find them.
> >
> > On Sun, Mar 10, 2019 at 8:48 PM Hsin-Hsiung Wang
> > <[email protected]> wrote:
> > >
> > > This adds compatible for the MediaTek MT6358 PMIC.
> > >
> > > Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> > > ---
> > > Documentation/devicetree/bindings/mfd/mt6397.txt | 11 ++++++++---
> > > 1 file changed, 8 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
> > > index 0ebd08a..62f1c17 100644
> > > --- a/Documentation/devicetree/bindings/mfd/mt6397.txt
> > > +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
> > > @@ -17,22 +17,27 @@ Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
> > > This document describes the binding for MFD device and its sub module.
> > >
> > > Required properties:
> > > -compatible: "mediatek,mt6397" or "mediatek,mt6323"
> > > +compatible:
> > > + "mediatek,mt6323" for PMIC MT6323
> > > + "mediatek,mt6358" for PMIC MT6358
> > > + "mediatek,mt6397" for PMIC MT6397
> >
> > don't change anything not related MT6358
>
> Reformatting like this is preferred.
>
Sure, it's fine to me for the purpose.
> Rob
On 11/03/2019 20:01, Sean Wang wrote:
> Hi,
>
> On Sun, Mar 10, 2019 at 8:48 PM Hsin-Hsiung Wang
> <[email protected]> wrote:
>>
>> clean up code
>>
>> Signed-off-by: Hsin-Hsiung Wang <[email protected]>
>> ---
>> drivers/mfd/mt6397-core.c | 16 ++++++++--------
>> 1 file changed, 8 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
>> index 77b64bd..acb9812 100644
>> --- a/drivers/mfd/mt6397-core.c
>> +++ b/drivers/mfd/mt6397-core.c
>> @@ -18,17 +18,17 @@
>> #include <linux/of_irq.h>
>> #include <linux/regmap.h>
>> #include <linux/mfd/core.h>
>> -#include <linux/mfd/mt6397/core.h>
>> #include <linux/mfd/mt6323/core.h>
>> -#include <linux/mfd/mt6397/registers.h>
>> +#include <linux/mfd/mt6397/core.h>
>> #include <linux/mfd/mt6323/registers.h>
>> +#include <linux/mfd/mt6397/registers.h>
>>
>> #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 MT6323_CHIP_ID 0x23
>> +#define MT6391_CHIP_ID 0x91
>> +#define MT6397_CHIP_ID 0x97
>>
>
> It would be not necessary to simply rename the definition or do you
> have a strong reason to do that?
>
I agree, apart, please provide a sound commit message.
"clean up code" is difficult to understand.
Regards,
Matthias
>> static const struct resource mt6397_rtc_resources[] = {
>> {
>> @@ -298,7 +298,7 @@ static int mt6397_probe(struct platform_device *pdev)
>> return pmic->irq;
>>
>> switch (id & 0xff) {
>> - case MT6323_CID_CODE:
>> + case MT6323_CHIP_ID:
>> pmic->int_con[0] = MT6323_INT_CON0;
>> pmic->int_con[1] = MT6323_INT_CON1;
>> pmic->int_status[0] = MT6323_INT_STATUS0;
>> @@ -312,8 +312,8 @@ static int mt6397_probe(struct platform_device *pdev)
>> 0, pmic->irq_domain);
>> break;
>>
>> - case MT6397_CID_CODE:
>> - case MT6391_CID_CODE:
>> + case MT6391_CHIP_ID:
>> + case MT6397_CHIP_ID:
>> pmic->int_con[0] = MT6397_INT_CON0;
>> pmic->int_con[1] = MT6397_INT_CON1;
>> pmic->int_status[0] = MT6397_INT_STATUS0;
>> --
>> 1.9.1
>>
>>
>> _______________________________________________
>> Linux-mediatek mailing list
>> [email protected]
>> http://lists.infradead.org/mailman/listinfo/linux-mediatek
On Mon, Mar 11, 2019 at 11:46:28AM +0800, Hsin-Hsiung Wang wrote:
> +static const u32 vefuse_voltages[] = {
> + 1700000, 1800000, 1900000,
> +};
This and a bunch of the other regulators look like they're just linear
ranges and could use the linear range helpers.
> +static const u32 vcn33_bt_voltages[] = {
> + 3300000, 3400000, 3500000,
> +};
> +
> +static const u32 vcn33_wifi_voltages[] = {
> + 3300000, 3400000, 3500000,
> +};
These also have the same range so no matter which helpers are used I'd
expect the data to be shared, I think some of the other regulators might
have shared tables but didn't confirm.
> +static inline unsigned int mt6358_map_mode(unsigned int mode)
> +{
> + return mode == MT6358_BUCK_MODE_FORCE_PWM ?
> + REGULATOR_MODE_FAST : REGULATOR_MODE_NORMAL;
> +}
Please write normal if statements, it makes the code more readable.
> +static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
> + unsigned int selector)
> +{
> + int idx, ret;
> + const u32 *pvol;
> + struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
> +
> + pvol = (const u32 *)info->index_table;
> +
> + idx = pvol[selector];
> + ret = regmap_update_bits(rdev->regmap, info->desc.vsel_reg,
> + info->desc.vsel_mask,
> + idx << info->vsel_shift);
> +
> + return ret;
> +}
This looks like something other devices might do - rather than implement
it in the driver it would be a bit better to add it to helpers.c as a
reusable function.
> +static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
> +{
> + int ret, regval;
> + struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
> +
> + ret = regmap_read(rdev->regmap, info->da_vsel_reg, ®val);
> + if (ret != 0) {
> + dev_info(&rdev->dev,
> + "Failed to get mt6358 Buck %s vsel reg: %d\n",
> + info->desc.name, ret);
> + return ret;
> + }
> +
> + ret = (regval >> info->da_vsel_shift) & info->da_vsel_mask;
> +
> + return ret;
> +}
This is just the generic get_voltage_sel() as far as I can see?
> + /* Read PMIC chip revision to update constraints and voltage table */
> + if (regmap_read(mt6397->regmap, MT6358_SWCID, ®_value) < 0) {
> + dev_err(&pdev->dev, "Failed to read Chip ID\n");
> + return -EIO;
> + }
We never use the value we read here?
Hi,
On Mon, 2019-03-11 at 13:50 -0700, Sean Wang wrote:
> Hi,
>
> On Sun, Mar 10, 2019 at 8:49 PM Hsin-Hsiung Wang
> <[email protected]> wrote:
> >
> > From: Ran Bi <[email protected]>
> >
> > Alarm registers high byte was reserved for other functions.
> > This add mask in alarm registers operation functions.
> > This also fix error condition in interrupt handler.
> >
> > Fixes: fc2979118f3f ("rtc: mediatek: Add MT6397 RTC driver")
> >
>
> add a Cc: [email protected] here to apply to all stable kernels
> for the critical fixup patch.
>
> > Signed-off-by: Ran Bi <[email protected]>
> > ---
> > drivers/rtc/rtc-mt6397.c | 47 +++++++++++++++++++++++++++++++++--------------
> > 1 file changed, 33 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
> > index e9a25ec..f85f1fc 100644
> > --- a/drivers/rtc/rtc-mt6397.c
> > +++ b/drivers/rtc/rtc-mt6397.c
> > @@ -55,6 +55,14 @@
> >
> > #define RTC_AL_SEC 0x0018
> >
> > +#define RTC_AL_SEC_MASK 0x003f
> > +#define RTC_AL_MIN_MASK 0x003f
> > +#define RTC_AL_HOU_MASK 0x001f
> > +#define RTC_AL_DOM_MASK 0x001f
> > +#define RTC_AL_DOW_MASK 0x0007
> > +#define RTC_AL_MTH_MASK 0x000f
> > +#define RTC_AL_YEA_MASK 0x007f
> > +
> > #define RTC_PDN2 0x002e
> > #define RTC_PDN2_PWRON_ALARM BIT(4)
> >
> > @@ -111,7 +119,7 @@ static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data)
> > irqen = irqsta & ~RTC_IRQ_EN_AL;
> > mutex_lock(&rtc->lock);
> > if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN,
> > - irqen) < 0)
> > + irqen) == 0)
> > mtk_rtc_write_trigger(rtc);
> > mutex_unlock(&rtc->lock);
> >
> > @@ -233,12 +241,12 @@ static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
> > alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM);
> > mutex_unlock(&rtc->lock);
> >
> > - tm->tm_sec = data[RTC_OFFSET_SEC];
> > - tm->tm_min = data[RTC_OFFSET_MIN];
> > - tm->tm_hour = data[RTC_OFFSET_HOUR];
> > - tm->tm_mday = data[RTC_OFFSET_DOM];
> > - tm->tm_mon = data[RTC_OFFSET_MTH];
> > - tm->tm_year = data[RTC_OFFSET_YEAR];
> > + tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK;
> > + tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK;
> > + tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK;
> > + tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK;
> > + tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK;
> > + tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK;
> >
> > tm->tm_year += RTC_MIN_YEAR_OFFSET;
> > tm->tm_mon--;
> > @@ -259,14 +267,25 @@ static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
> > tm->tm_year -= RTC_MIN_YEAR_OFFSET;
> > tm->tm_mon++;
> >
> > - data[RTC_OFFSET_SEC] = tm->tm_sec;
> > - data[RTC_OFFSET_MIN] = tm->tm_min;
> > - data[RTC_OFFSET_HOUR] = tm->tm_hour;
> > - data[RTC_OFFSET_DOM] = tm->tm_mday;
> > - data[RTC_OFFSET_MTH] = tm->tm_mon;
> > - data[RTC_OFFSET_YEAR] = tm->tm_year;
> > -
> > mutex_lock(&rtc->lock);
> > + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC,
> > + data, RTC_OFFSET_COUNT);
> > + if (ret < 0)
> > + goto exit;
> > +
>
> Why did we need an additional regmap_bulk_read here? I would suppose
> data[RTC_OFFSET_*] & ~(RTC_AL_*_MASK) is always equal to 0.
In bootloader, RTC init part need to operate these RTC_AL_* registers
high byte for RTC operating mode settings and data storage, while
RTC_AL_* low byte was used as alarm register here. So we need an
additional regmap_bulk_read here to keep the RTC settings correct.
>
> It might be another fixup since change is not being mentioned in the
> git message.
>
> > + data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) |
> > + (tm->tm_sec & RTC_AL_SEC_MASK));
> > + data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) |
> > + (tm->tm_min & RTC_AL_MIN_MASK));
> > + data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) |
> > + (tm->tm_hour & RTC_AL_HOU_MASK));
> > + data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) |
> > + (tm->tm_mday & RTC_AL_DOM_MASK));
> > + data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) |
> > + (tm->tm_mon & RTC_AL_MTH_MASK));
> > + data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) |
> > + (tm->tm_year & RTC_AL_YEA_MASK));
> > +
> > if (alm->enabled) {
> > ret = regmap_bulk_write(rtc->regmap,
> > rtc->addr_base + RTC_AL_SEC,
> > --
> > 1.9.1
> >
> >
> > _______________________________________________
> > Linux-mediatek mailing list
> > [email protected]
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek
On Mon, Mar 11, 2019 at 11:48 AM Hsin-Hsiung Wang
<[email protected]> wrote:
>
> In order to support different types of irq design, we decide to add
> separate irq drivers for different design and keep mt6397 mfd core
> simple and reusable to all generations of PMICs so far.
>
> Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> ---
> drivers/mfd/Makefile | 2 +-
> drivers/mfd/mt6397-core.c | 228 ++++++----------------------------------
> drivers/mfd/mt6397-irq.c | 214 +++++++++++++++++++++++++++++++++++++
> include/linux/mfd/mt6397/core.h | 12 +++
> 4 files changed, 259 insertions(+), 197 deletions(-)
> create mode 100644 drivers/mfd/mt6397-irq.c
>
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 12980a4..088e249 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -230,7 +230,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
> obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
> obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
> obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
> -obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
> +obj-$(CONFIG_MFD_MT6397) += mt6397-core.o mt6397-irq.o
Guenter reported the following issue with this
(https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/1524423):
"""
Building the mt6397/mt6358 driver as module results in the following errors.
ERROR: "mt6397_irq_init" [drivers/mfd/mt6397-core.ko] undefined!
ERROR: "mt6358_irq_init" [drivers/mfd/mt6397-core.ko] undefined!
This is because the irq code for mt6358 and mt6397_irq is built as
separate modules, but the functions implemented by those modules are
not exported. We could export the functions, but that seems to be
quite pointless since the driver always requires both interrupt
handlers. Modify the Makefile to build a single module instead.
"""
His fix looks like this:
@@ -230,7 +230,9 @@
obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
-obj-$(CONFIG_MFD_MT6397) += mt6397-core.o mt6397-irq.o mt6358-irq.o
+
+mt6397-objs := mt6397-core.o mt6397-irq.o mt6358-irq.o
+obj-$(CONFIG_MFD_MT6397) += mt6397.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
>
> obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
> obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
> diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
> index acb9812..53f1edc 100644
> --- a/drivers/mfd/mt6397-core.c
> +++ b/drivers/mfd/mt6397-core.c
> @@ -12,7 +12,6 @@
> * GNU General Public License for more details.
> */
>
> -#include <linux/interrupt.h>
> #include <linux/module.h>
> #include <linux/of_device.h>
> #include <linux/of_irq.h>
> @@ -26,10 +25,6 @@
> #define MT6397_RTC_BASE 0xe000
> #define MT6397_RTC_SIZE 0x3e
>
> -#define MT6323_CHIP_ID 0x23
> -#define MT6391_CHIP_ID 0x91
> -#define MT6397_CHIP_ID 0x97
> -
> static const struct resource mt6397_rtc_resources[] = {
> {
> .start = MT6397_RTC_BASE,
> @@ -94,182 +89,24 @@
> }
> };
>
> -static void mt6397_irq_lock(struct irq_data *data)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> -
> - mutex_lock(&mt6397->irqlock);
> -}
> -
> -static void mt6397_irq_sync_unlock(struct irq_data *data)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> -
> - regmap_write(mt6397->regmap, mt6397->int_con[0],
> - mt6397->irq_masks_cur[0]);
> - regmap_write(mt6397->regmap, mt6397->int_con[1],
> - mt6397->irq_masks_cur[1]);
> -
> - mutex_unlock(&mt6397->irqlock);
> -}
> -
> -static void mt6397_irq_disable(struct irq_data *data)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> - int shift = data->hwirq & 0xf;
> - int reg = data->hwirq >> 4;
> -
> - mt6397->irq_masks_cur[reg] &= ~BIT(shift);
> -}
> -
> -static void mt6397_irq_enable(struct irq_data *data)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> - int shift = data->hwirq & 0xf;
> - int reg = data->hwirq >> 4;
> -
> - mt6397->irq_masks_cur[reg] |= BIT(shift);
> -}
> -
> -#ifdef CONFIG_PM_SLEEP
> -static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
> -{
> - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
> - int shift = irq_data->hwirq & 0xf;
> - int reg = irq_data->hwirq >> 4;
> -
> - if (on)
> - mt6397->wake_mask[reg] |= BIT(shift);
> - else
> - mt6397->wake_mask[reg] &= ~BIT(shift);
> -
> - return 0;
> -}
> -#else
> -#define mt6397_irq_set_wake NULL
> -#endif
> -
> -static struct irq_chip mt6397_irq_chip = {
> - .name = "mt6397-irq",
> - .irq_bus_lock = mt6397_irq_lock,
> - .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
> - .irq_enable = mt6397_irq_enable,
> - .irq_disable = mt6397_irq_disable,
> - .irq_set_wake = mt6397_irq_set_wake,
> +struct chip_data {
> + u32 cid_addr;
> };
>
> -static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
> - int irqbase)
> -{
> - unsigned int status;
> - int i, irq, ret;
> -
> - ret = regmap_read(mt6397->regmap, reg, &status);
> - if (ret) {
> - dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
> - return;
> - }
> -
> - for (i = 0; i < 16; i++) {
> - if (status & BIT(i)) {
> - irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
> - if (irq)
> - handle_nested_irq(irq);
> - }
> - }
> -
> - regmap_write(mt6397->regmap, reg, status);
> -}
> -
> -static irqreturn_t mt6397_irq_thread(int irq, void *data)
> -{
> - struct mt6397_chip *mt6397 = data;
> -
> - mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
> - mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
> -
> - return IRQ_HANDLED;
> -}
> -
> -static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
> - irq_hw_number_t hw)
> -{
> - struct mt6397_chip *mt6397 = d->host_data;
> -
> - irq_set_chip_data(irq, mt6397);
> - irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
> - irq_set_nested_thread(irq, 1);
> - irq_set_noprobe(irq);
> -
> - return 0;
> -}
> -
> -static const struct irq_domain_ops mt6397_irq_domain_ops = {
> - .map = mt6397_irq_domain_map,
> +static const struct chip_data mt6323_core = {
> + .cid_addr = MT6323_CID,
> };
>
> -static int mt6397_irq_init(struct mt6397_chip *mt6397)
> -{
> - int ret;
> -
> - mutex_init(&mt6397->irqlock);
> -
> - /* Mask all interrupt sources */
> - regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0);
> - regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0);
> -
> - mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
> - MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
> - if (!mt6397->irq_domain) {
> - dev_err(mt6397->dev, "could not create irq domain\n");
> - return -ENOMEM;
> - }
> -
> - ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL,
> - mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397);
> - if (ret) {
> - dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n",
> - mt6397->irq, ret);
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> -#ifdef CONFIG_PM_SLEEP
> -static int mt6397_irq_suspend(struct device *dev)
> -{
> - struct mt6397_chip *chip = dev_get_drvdata(dev);
> -
> - regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]);
> - regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]);
> -
> - enable_irq_wake(chip->irq);
> -
> - return 0;
> -}
> -
> -static int mt6397_irq_resume(struct device *dev)
> -{
> - struct mt6397_chip *chip = dev_get_drvdata(dev);
> -
> - regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]);
> - regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]);
> -
> - disable_irq_wake(chip->irq);
> -
> - return 0;
> -}
> -#endif
> -
> -static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend,
> - mt6397_irq_resume);
> +static const struct chip_data mt6397_core = {
> + .cid_addr = MT6397_CID,
> +};
>
> static int mt6397_probe(struct platform_device *pdev)
> {
> int ret;
> unsigned int id;
> struct mt6397_chip *pmic;
> + const struct chip_data *pmic_core;
>
> pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
> if (!pmic)
> @@ -285,28 +122,30 @@ static int mt6397_probe(struct platform_device *pdev)
> if (!pmic->regmap)
> return -ENODEV;
>
> - platform_set_drvdata(pdev, pmic);
> + pmic_core = of_device_get_match_data(&pdev->dev);
> + if (!pmic_core)
> + return -ENODEV;
>
> - ret = regmap_read(pmic->regmap, MT6397_CID, &id);
> + ret = regmap_read(pmic->regmap, pmic_core->cid_addr, &id);
> if (ret) {
> - dev_err(pmic->dev, "Failed to read chip id: %d\n", ret);
> + dev_err(&pdev->dev, "Failed to read chip id: %d\n", ret);
> return ret;
> }
>
> + pmic->chip_id = id & 0xff;
> +
> + platform_set_drvdata(pdev, pmic);
> +
> pmic->irq = platform_get_irq(pdev, 0);
> if (pmic->irq <= 0)
> return pmic->irq;
>
> - switch (id & 0xff) {
> - case MT6323_CHIP_ID:
> - pmic->int_con[0] = MT6323_INT_CON0;
> - pmic->int_con[1] = MT6323_INT_CON1;
> - pmic->int_status[0] = MT6323_INT_STATUS0;
> - pmic->int_status[1] = MT6323_INT_STATUS1;
> - ret = mt6397_irq_init(pmic);
> - if (ret)
> - return ret;
> + ret = mt6397_irq_init(pmic);
> + if (ret)
> + return ret;
>
> + switch (pmic->chip_id) {
> + case MT6323_CHIP_ID:
> ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
> ARRAY_SIZE(mt6323_devs), NULL,
> 0, pmic->irq_domain);
> @@ -314,21 +153,13 @@ static int mt6397_probe(struct platform_device *pdev)
>
> case MT6391_CHIP_ID:
> case MT6397_CHIP_ID:
> - pmic->int_con[0] = MT6397_INT_CON0;
> - pmic->int_con[1] = MT6397_INT_CON1;
> - pmic->int_status[0] = MT6397_INT_STATUS0;
> - pmic->int_status[1] = MT6397_INT_STATUS1;
> - ret = mt6397_irq_init(pmic);
> - if (ret)
> - return ret;
> -
> ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
> ARRAY_SIZE(mt6397_devs), NULL,
> 0, pmic->irq_domain);
> break;
>
> default:
> - dev_err(&pdev->dev, "unsupported chip: %d\n", id);
> + dev_err(&pdev->dev, "unsupported chip: %d\n", pmic->chip_id);
> ret = -ENODEV;
> break;
> }
> @@ -342,9 +173,15 @@ 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,mt6323",
> + .data = &mt6323_core,
> + }, {
> + .compatible = "mediatek,mt6397",
> + .data = &mt6397_core,
> + }, {
> + /* sentinel */
> + }
> };
> MODULE_DEVICE_TABLE(of, mt6397_of_match);
>
> @@ -359,7 +196,6 @@ static int mt6397_probe(struct platform_device *pdev)
> .driver = {
> .name = "mt6397",
> .of_match_table = of_match_ptr(mt6397_of_match),
> - .pm = &mt6397_pm_ops,
> },
> .id_table = mt6397_id,
> };
> diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c
> new file mode 100644
> index 0000000..669e93d
> --- /dev/null
> +++ b/drivers/mfd/mt6397-irq.c
> @@ -0,0 +1,214 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Copyright (c) 2019 MediaTek Inc.
> +
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/suspend.h>
> +#include <linux/mfd/mt6323/core.h>
> +#include <linux/mfd/mt6323/registers.h>
> +#include <linux/mfd/mt6397/core.h>
> +#include <linux/mfd/mt6397/registers.h>
> +
> +static void mt6397_irq_lock(struct irq_data *data)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> +
> + mutex_lock(&mt6397->irqlock);
> +}
> +
> +static void mt6397_irq_sync_unlock(struct irq_data *data)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> +
> + regmap_write(mt6397->regmap, mt6397->int_con[0],
> + mt6397->irq_masks_cur[0]);
> + regmap_write(mt6397->regmap, mt6397->int_con[1],
> + mt6397->irq_masks_cur[1]);
> +
> + mutex_unlock(&mt6397->irqlock);
> +}
> +
> +static void mt6397_irq_disable(struct irq_data *data)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> + int shift = data->hwirq & 0xf;
> + int reg = data->hwirq >> 4;
> +
> + mt6397->irq_masks_cur[reg] &= ~BIT(shift);
> +}
> +
> +static void mt6397_irq_enable(struct irq_data *data)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data);
> + int shift = data->hwirq & 0xf;
> + int reg = data->hwirq >> 4;
> +
> + mt6397->irq_masks_cur[reg] |= BIT(shift);
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on)
> +{
> + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data);
> + int shift = irq_data->hwirq & 0xf;
> + int reg = irq_data->hwirq >> 4;
> +
> + if (on)
> + mt6397->wake_mask[reg] |= BIT(shift);
> + else
> + mt6397->wake_mask[reg] &= ~BIT(shift);
> +
> + return 0;
> +}
> +#else
> +#define mt6397_irq_set_wake NULL
> +#endif
> +
> +static struct irq_chip mt6397_irq_chip = {
> + .name = "mt6397-irq",
> + .irq_bus_lock = mt6397_irq_lock,
> + .irq_bus_sync_unlock = mt6397_irq_sync_unlock,
> + .irq_enable = mt6397_irq_enable,
> + .irq_disable = mt6397_irq_disable,
> + .irq_set_wake = mt6397_irq_set_wake,
> +};
> +
> +static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
> + int irqbase)
> +{
> + unsigned int status;
> + int i, irq, ret;
> +
> + ret = regmap_read(mt6397->regmap, reg, &status);
> + if (ret) {
> + dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
> + return;
> + }
> +
> + for (i = 0; i < 16; i++) {
> + if (status & BIT(i)) {
> + irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
> + if (irq)
> + handle_nested_irq(irq);
> + }
> + }
> +
> + regmap_write(mt6397->regmap, reg, status);
> +}
> +
> +static irqreturn_t mt6397_irq_thread(int irq, void *data)
> +{
> + struct mt6397_chip *mt6397 = data;
> +
> + mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0);
> + mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
> + irq_hw_number_t hw)
> +{
> + struct mt6397_chip *mt6397 = d->host_data;
> +
> + irq_set_chip_data(irq, mt6397);
> + irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
> + irq_set_nested_thread(irq, 1);
> + irq_set_noprobe(irq);
> +
> + return 0;
> +}
> +
> +static const struct irq_domain_ops mt6397_irq_domain_ops = {
> + .map = mt6397_irq_domain_map,
> +};
> +
> +static int mt6397_irq_pm_notifier(struct notifier_block *notifier,
> + unsigned long pm_event, void *unused)
> +{
> + struct mt6397_chip *chip =
> + container_of(notifier, struct mt6397_chip, pm_nb);
> +
> + switch (pm_event) {
> + case PM_SUSPEND_PREPARE:
> + regmap_write(chip->regmap,
> + chip->int_con[0], chip->wake_mask[0]);
> + regmap_write(chip->regmap,
> + chip->int_con[1], chip->wake_mask[1]);
> + enable_irq_wake(chip->irq);
> + break;
> +
> + case PM_POST_SUSPEND:
> + regmap_write(chip->regmap,
> + chip->int_con[0], chip->irq_masks_cur[0]);
> + regmap_write(chip->regmap,
> + chip->int_con[1], chip->irq_masks_cur[1]);
> + disable_irq_wake(chip->irq);
> + break;
> +
> + default:
> + break;
> + }
> +
> + return NOTIFY_DONE;
> +}
> +
> +int mt6397_irq_init(struct mt6397_chip *chip)
> +{
> + int ret;
> +
> + mutex_init(&chip->irqlock);
> +
> + switch (chip->chip_id) {
> + case MT6323_CHIP_ID:
> + chip->int_con[0] = MT6323_INT_CON0;
> + chip->int_con[1] = MT6323_INT_CON1;
> + chip->int_status[0] = MT6323_INT_STATUS0;
> + chip->int_status[1] = MT6323_INT_STATUS1;
> + break;
> +
> + case MT6391_CHIP_ID:
> + case MT6397_CHIP_ID:
> + chip->int_con[0] = MT6397_INT_CON0;
> + chip->int_con[1] = MT6397_INT_CON1;
> + chip->int_status[0] = MT6397_INT_STATUS0;
> + chip->int_status[1] = MT6397_INT_STATUS1;
> + break;
> +
> + default:
> + dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id);
> + return -ENODEV;
> + }
> +
> + /* Mask all interrupt sources */
> + regmap_write(chip->regmap, chip->int_con[0], 0x0);
> + regmap_write(chip->regmap, chip->int_con[1], 0x0);
> +
> + chip->pm_nb.notifier_call = mt6397_irq_pm_notifier;
> + chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
> + MT6397_IRQ_NR,
> + &mt6397_irq_domain_ops,
> + chip);
> + if (!chip->irq_domain) {
> + dev_err(chip->dev, "could not create irq domain\n");
> + return -ENOMEM;
> + }
> +
> + ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL,
> + mt6397_irq_thread, IRQF_ONESHOT,
> + "mt6397-pmic", chip);
> + if (ret) {
> + dev_err(chip->dev, "failed to register irq=%d; err: %d\n",
> + chip->irq, ret);
> + return ret;
> + }
> +
> + register_pm_notifier(&chip->pm_nb);
> + return 0;
> +}
> diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
> index d678f52..23c8c6a 100644
> --- a/include/linux/mfd/mt6397/core.h
> +++ b/include/linux/mfd/mt6397/core.h
> @@ -15,6 +15,14 @@
> #ifndef __MFD_MT6397_CORE_H__
> #define __MFD_MT6397_CORE_H__
>
> +#include <linux/notifier.h>
> +
> +enum chip_id {
> + MT6323_CHIP_ID = 0x23,
> + MT6391_CHIP_ID = 0x91,
> + MT6397_CHIP_ID = 0x97,
> +};
> +
> enum mt6397_irq_numbers {
> MT6397_IRQ_SPKL_AB = 0,
> MT6397_IRQ_SPKR_AB,
> @@ -54,6 +62,7 @@ enum mt6397_irq_numbers {
> struct mt6397_chip {
> struct device *dev;
> struct regmap *regmap;
> + struct notifier_block pm_nb;
> int irq;
> struct irq_domain *irq_domain;
> struct mutex irqlock;
> @@ -62,6 +71,9 @@ struct mt6397_chip {
> u16 irq_masks_cache[2];
> u16 int_con[2];
> u16 int_status[2];
> + u16 chip_id;
> };
>
> +int mt6397_irq_init(struct mt6397_chip *mt6397);
> +
> #endif /* __MFD_MT6397_CORE_H__ */
> --
> 1.9.1
>
Hi,
Should use 'rtc: mt6397: ' as prefix for this patch.
On Mon, 2019-03-11 at 11:46 +0800, Hsin-Hsiung Wang wrote:
> From: Ran Bi <[email protected]>
>
> This add support for the MediaTek MT6358 RTC. MT6397 mfd will pass
> RTC_WRTGR address offset to RTC driver.
>
> Signed-off-by: Ran Bi <[email protected]>
> ---
> drivers/rtc/rtc-mt6397.c | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
> index f85f1fc..c8a0090 100644
> --- a/drivers/rtc/rtc-mt6397.c
> +++ b/drivers/rtc/rtc-mt6397.c
> @@ -27,7 +27,7 @@
> #define RTC_BBPU 0x0000
> #define RTC_BBPU_CBUSY BIT(6)
>
> -#define RTC_WRTGR 0x003c
> +#define RTC_WRTGR_DEFAULT 0x003c
>
> #define RTC_IRQ_STA 0x0002
> #define RTC_IRQ_STA_AL BIT(0)
> @@ -78,6 +78,7 @@ struct mt6397_rtc {
> struct regmap *regmap;
> int irq;
> u32 addr_base;
> + u32 wrtgr_offset;
> };
>
> static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
> @@ -86,7 +87,8 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
> int ret;
> u32 data;
>
> - ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1);
> + ret = regmap_write(rtc->regmap,
> + rtc->addr_base + rtc->wrtgr_offset, 1);
> if (ret < 0)
> return ret;
>
> @@ -341,6 +343,15 @@ static int mtk_rtc_probe(struct platform_device *pdev)
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> rtc->addr_base = res->start;
>
> + res = platform_get_resource(pdev, IORESOURCE_REG, 0);
> + if (res) {
> + rtc->wrtgr_offset = res->start;
> + dev_info(&pdev->dev, "register offset:%d\n", rtc->wrtgr_offset);
> + } else {
> + rtc->wrtgr_offset = RTC_WRTGR_DEFAULT;
> + dev_err(&pdev->dev, "Failed to get register offset\n");
> + }
> +
Since this will be passed by MFD, do we still need to keep the DEFAULT?
Any case this platform_get_resource will failed?
It's too bad HW changed this offset, but I'm not sure about passing this
information from MFD. We have 1 register that have different offset now,
and might have others for future chips, adding each one by
IORESOURCE_IRQ doesn't looks like a good solution. Keeping this
information in RTC driver only also looks better.
Joe.C
On Mon, 11 Mar 2019, Hsin-Hsiung Wang wrote:
> clean up code
Please explain what it is that you're cleaning up.
> Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> ---
> drivers/mfd/mt6397-core.c | 16 ++++++++--------
> 1 file changed, 8 insertions(+), 8 deletions(-)
The patch is fine though. When you resubmit, please add my:
For my own reference:
Acked-for-MFD-by: Lee Jones <[email protected]>
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
On Mon, 11 Mar 2019, Hsin-Hsiung Wang wrote:
> This adds compatible for the MediaTek MT6358 PMIC.
>
> Signed-off-by: Hsin-Hsiung Wang <[email protected]>
> ---
> Documentation/devicetree/bindings/mfd/mt6397.txt | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
For my own reference:
Acked-for-MFD-by: Lee Jones <[email protected]>
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
On 21/03/2019 17:51:26+0800, Yingjoe Chen wrote:
>
> Hi,
>
>
> Should use 'rtc: mt6397: ' as prefix for this patch.
>
>
> On Mon, 2019-03-11 at 11:46 +0800, Hsin-Hsiung Wang wrote:
> > From: Ran Bi <[email protected]>
> >
> > This add support for the MediaTek MT6358 RTC. MT6397 mfd will pass
> > RTC_WRTGR address offset to RTC driver.
> >
> > Signed-off-by: Ran Bi <[email protected]>
> > ---
> > drivers/rtc/rtc-mt6397.c | 16 ++++++++++++++--
> > 1 file changed, 14 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
> > index f85f1fc..c8a0090 100644
> > --- a/drivers/rtc/rtc-mt6397.c
> > +++ b/drivers/rtc/rtc-mt6397.c
> > @@ -27,7 +27,7 @@
> > #define RTC_BBPU 0x0000
> > #define RTC_BBPU_CBUSY BIT(6)
> >
> > -#define RTC_WRTGR 0x003c
> > +#define RTC_WRTGR_DEFAULT 0x003c
> >
> > #define RTC_IRQ_STA 0x0002
> > #define RTC_IRQ_STA_AL BIT(0)
> > @@ -78,6 +78,7 @@ struct mt6397_rtc {
> > struct regmap *regmap;
> > int irq;
> > u32 addr_base;
> > + u32 wrtgr_offset;
> > };
> >
> > static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
> > @@ -86,7 +87,8 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
> > int ret;
> > u32 data;
> >
> > - ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1);
> > + ret = regmap_write(rtc->regmap,
> > + rtc->addr_base + rtc->wrtgr_offset, 1);
> > if (ret < 0)
> > return ret;
> >
> > @@ -341,6 +343,15 @@ static int mtk_rtc_probe(struct platform_device *pdev)
> > res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > rtc->addr_base = res->start;
> >
> > + res = platform_get_resource(pdev, IORESOURCE_REG, 0);
> > + if (res) {
> > + rtc->wrtgr_offset = res->start;
> > + dev_info(&pdev->dev, "register offset:%d\n", rtc->wrtgr_offset);
> > + } else {
> > + rtc->wrtgr_offset = RTC_WRTGR_DEFAULT;
> > + dev_err(&pdev->dev, "Failed to get register offset\n");
> > + }
> > +
>
> Since this will be passed by MFD, do we still need to keep the DEFAULT?
> Any case this platform_get_resource will failed?
>
> It's too bad HW changed this offset, but I'm not sure about passing this
> information from MFD. We have 1 register that have different offset now,
> and might have others for future chips, adding each one by
> IORESOURCE_IRQ doesn't looks like a good solution. Keeping this
> information in RTC driver only also looks better.
>
I agree, this would be better.
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
On 11/03/2019 11:46:30+0800, Hsin-Hsiung Wang wrote:
> From: Ran Bi <[email protected]>
>
> Alarm registers high byte was reserved for other functions.
> This add mask in alarm registers operation functions.
> This also fix error condition in interrupt handler.
>
> Fixes: fc2979118f3f ("rtc: mediatek: Add MT6397 RTC driver")
>
> Signed-off-by: Ran Bi <[email protected]>
Acked-by: Alexandre Belloni <[email protected]>
> ---
> drivers/rtc/rtc-mt6397.c | 47 +++++++++++++++++++++++++++++++++--------------
> 1 file changed, 33 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c
> index e9a25ec..f85f1fc 100644
> --- a/drivers/rtc/rtc-mt6397.c
> +++ b/drivers/rtc/rtc-mt6397.c
> @@ -55,6 +55,14 @@
>
> #define RTC_AL_SEC 0x0018
>
> +#define RTC_AL_SEC_MASK 0x003f
> +#define RTC_AL_MIN_MASK 0x003f
> +#define RTC_AL_HOU_MASK 0x001f
> +#define RTC_AL_DOM_MASK 0x001f
> +#define RTC_AL_DOW_MASK 0x0007
> +#define RTC_AL_MTH_MASK 0x000f
> +#define RTC_AL_YEA_MASK 0x007f
> +
> #define RTC_PDN2 0x002e
> #define RTC_PDN2_PWRON_ALARM BIT(4)
>
> @@ -111,7 +119,7 @@ static irqreturn_t mtk_rtc_irq_handler_thread(int irq, void *data)
> irqen = irqsta & ~RTC_IRQ_EN_AL;
> mutex_lock(&rtc->lock);
> if (regmap_write(rtc->regmap, rtc->addr_base + RTC_IRQ_EN,
> - irqen) < 0)
> + irqen) == 0)
> mtk_rtc_write_trigger(rtc);
> mutex_unlock(&rtc->lock);
>
> @@ -233,12 +241,12 @@ static int mtk_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
> alm->pending = !!(pdn2 & RTC_PDN2_PWRON_ALARM);
> mutex_unlock(&rtc->lock);
>
> - tm->tm_sec = data[RTC_OFFSET_SEC];
> - tm->tm_min = data[RTC_OFFSET_MIN];
> - tm->tm_hour = data[RTC_OFFSET_HOUR];
> - tm->tm_mday = data[RTC_OFFSET_DOM];
> - tm->tm_mon = data[RTC_OFFSET_MTH];
> - tm->tm_year = data[RTC_OFFSET_YEAR];
> + tm->tm_sec = data[RTC_OFFSET_SEC] & RTC_AL_SEC_MASK;
> + tm->tm_min = data[RTC_OFFSET_MIN] & RTC_AL_MIN_MASK;
> + tm->tm_hour = data[RTC_OFFSET_HOUR] & RTC_AL_HOU_MASK;
> + tm->tm_mday = data[RTC_OFFSET_DOM] & RTC_AL_DOM_MASK;
> + tm->tm_mon = data[RTC_OFFSET_MTH] & RTC_AL_MTH_MASK;
> + tm->tm_year = data[RTC_OFFSET_YEAR] & RTC_AL_YEA_MASK;
>
> tm->tm_year += RTC_MIN_YEAR_OFFSET;
> tm->tm_mon--;
> @@ -259,14 +267,25 @@ static int mtk_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
> tm->tm_year -= RTC_MIN_YEAR_OFFSET;
> tm->tm_mon++;
>
> - data[RTC_OFFSET_SEC] = tm->tm_sec;
> - data[RTC_OFFSET_MIN] = tm->tm_min;
> - data[RTC_OFFSET_HOUR] = tm->tm_hour;
> - data[RTC_OFFSET_DOM] = tm->tm_mday;
> - data[RTC_OFFSET_MTH] = tm->tm_mon;
> - data[RTC_OFFSET_YEAR] = tm->tm_year;
> -
> mutex_lock(&rtc->lock);
> + ret = regmap_bulk_read(rtc->regmap, rtc->addr_base + RTC_AL_SEC,
> + data, RTC_OFFSET_COUNT);
> + if (ret < 0)
> + goto exit;
> +
> + data[RTC_OFFSET_SEC] = ((data[RTC_OFFSET_SEC] & ~(RTC_AL_SEC_MASK)) |
> + (tm->tm_sec & RTC_AL_SEC_MASK));
> + data[RTC_OFFSET_MIN] = ((data[RTC_OFFSET_MIN] & ~(RTC_AL_MIN_MASK)) |
> + (tm->tm_min & RTC_AL_MIN_MASK));
> + data[RTC_OFFSET_HOUR] = ((data[RTC_OFFSET_HOUR] & ~(RTC_AL_HOU_MASK)) |
> + (tm->tm_hour & RTC_AL_HOU_MASK));
> + data[RTC_OFFSET_DOM] = ((data[RTC_OFFSET_DOM] & ~(RTC_AL_DOM_MASK)) |
> + (tm->tm_mday & RTC_AL_DOM_MASK));
> + data[RTC_OFFSET_MTH] = ((data[RTC_OFFSET_MTH] & ~(RTC_AL_MTH_MASK)) |
> + (tm->tm_mon & RTC_AL_MTH_MASK));
> + data[RTC_OFFSET_YEAR] = ((data[RTC_OFFSET_YEAR] & ~(RTC_AL_YEA_MASK)) |
> + (tm->tm_year & RTC_AL_YEA_MASK));
> +
> if (alm->enabled) {
> ret = regmap_bulk_write(rtc->regmap,
> rtc->addr_base + RTC_AL_SEC,
> --
> 1.9.1
>
--
Alexandre Belloni, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com