Commit 512b7d37 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mfd-next-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "Core Frameworks:
   - Constify 'properties' attribute in core header file

  New Drivers:
   - Add support for Gateworks System Controller
   - Add support for MediaTek MT6358 PMIC
   - Add support for Mediatek MT6360 PMIC
   - Add support for Monolithic Power Systems MP2629 ADC and Battery charger

  Fix-ups:
   - Use new I2C API in htc-i2cpld
   - Remove superfluous code in sprd-sc27xx-spi
   - Improve error handling in stm32-timers
   - Device Tree additions/fixes in mt6397
   - Defer probe betterment in wm8994-core
   - Improve module handling in wm8994-core
   - Staticify in stpmic1
   - Trivial (spelling, formatting) in tqmx86

  Bug Fixes:
   - Fix incorrect register/PCI IDs in intel-lpss-pci
   - Fix unbalanced Regulator API calls in wm8994-core
   - Fix double free() in wcd934x
   - Remove IRQ domain on failure in stmfx
   - Reset chip on resume in stmfx
   - Disable/enable IRQs on suspend/resume in stmfx
   - Do not use bulk writes on H/W which does not support them in max77620"

* tag 'mfd-next-5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (29 commits)
  mfd: mt6360: Remove duplicate REGMAP_IRQ_REG_LINE() entry
  mfd: Add support for PMIC MT6360
  mfd: max77620: Use single-byte writes on MAX77620
  mfd: wcd934x: Drop kfree for memory allocated with devm_kzalloc
  mfd: stmfx: Disable IRQ in suspend to avoid spurious interrupt
  mfd: stmfx: Fix stmfx_irq_init error path
  mfd: stmfx: Reset chip on resume as supply was disabled
  mfd: wm8994: Silence warning about supplies during deferred probe
  mfd: wm8994: Fix unbalanced calls to regulator_bulk_disable()
  mfd: wm8994: Fix driver operation if loaded as modules
  dt-bindings: mfd: mediatek: Add MT6397 Pin Controller
  mfd: Constify properties in mfd_cell
  mfd: stm32-timers: Use dma_request_chan() instead dma_request_slave_channel()
  mfd: sprd: Remove unnecessary spi_bus_type setting
  mfd: intel-lpss: Update LPSS UART #2 PCI ID for Jasper Lake
  mfd: tqmx86: Fix a typo in MODULE_DESCRIPTION
  mfd: stpmic1: Make stpmic1_regmap_config static
  mfd: htc-i2cpld: Convert to use i2c_new_client_device()
  MAINTAINERS: Add entry for mp2629 Battery Charger driver
  power: supply: mp2629: Add impedance compensation config
  ...
parents acf25aa6 098c4adf
What: /sys/class/power_supply/mp2629_battery/batt_impedance_compen
Date: April 2020
KernelVersion: 5.7
Description:
Represents a battery impedance compensation to accelerate charging.
Access: Read, Write
Valid values: Represented in milli-ohms. Valid range is [0, 140].
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/mfd/mps,mp2629.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MP2629 Battery Charger PMIC from Monolithic Power System.
maintainers:
- Saravanan Sekar <sravanhome@gmail.com>
description: |
MP2629 is a PMIC providing battery charging and power supply for smartphones,
wireless camera and portable devices. Chip is controlled over I2C.
The battery charge management device handles battery charger controller and
ADC IIO device for battery, system voltage
properties:
compatible:
const: mps,mp2629
reg:
maxItems: 1
interrupts:
maxItems: 1
interrupt-controller: true
"#interrupt-cells":
const: 2
description:
The first cell is the IRQ number, the second cell is the trigger type.
required:
- compatible
- reg
- interrupts
- interrupt-controller
- "#interrupt-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/input/linux-event-codes.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@4b {
compatible = "mps,mp2629";
reg = <0x4b>;
interrupt-controller;
interrupt-parent = <&gpio2>;
#interrupt-cells = <2>;
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
};
};
...@@ -18,24 +18,30 @@ See the following for pwarp node definitions: ...@@ -18,24 +18,30 @@ See the following for pwarp node definitions:
This document describes the binding for MFD device and its sub module. This document describes the binding for MFD device and its sub module.
Required properties: 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: Optional subnodes:
- rtc - rtc
Required properties: Should be one of follows Required properties: Should be one of follows
- compatible: "mediatek,mt6323-rtc" - compatible: "mediatek,mt6323-rtc"
- compatible: "mediatek,mt6358-rtc"
- compatible: "mediatek,mt6397-rtc" - compatible: "mediatek,mt6397-rtc"
For details, see ../rtc/rtc-mt6397.txt For details, see ../rtc/rtc-mt6397.txt
- regulators - regulators
Required properties: Required properties:
- compatible: "mediatek,mt6397-regulator"
see ../regulator/mt6397-regulator.txt
- compatible: "mediatek,mt6323-regulator" - compatible: "mediatek,mt6323-regulator"
see ../regulator/mt6323-regulator.txt see ../regulator/mt6323-regulator.txt
- compatible: "mediatek,mt6358-regulator"
see ../regulator/mt6358-regulator.txt
- compatible: "mediatek,mt6397-regulator"
see ../regulator/mt6397-regulator.txt
- codec - codec
Required properties: Required properties:
- compatible: "mediatek,mt6397-codec" - compatible: "mediatek,mt6397-codec" or "mediatek,mt6358-sound"
- clk - clk
Required properties: Required properties:
- compatible: "mediatek,mt6397-clk" - compatible: "mediatek,mt6397-clk"
...@@ -54,6 +60,11 @@ Optional subnodes: ...@@ -54,6 +60,11 @@ Optional subnodes:
- compatible: "mediatek,mt6323-pwrc" - compatible: "mediatek,mt6323-pwrc"
For details, see ../power/reset/mt6323-poweroff.txt For details, see ../power/reset/mt6323-poweroff.txt
- pin-controller
Required properties:
- compatible: "mediatek,mt6397-pinctrl"
For details, see ../pinctrl/pinctrl-mt65xx.txt
Example: Example:
pwrap: pwrap@1000f000 { pwrap: pwrap@1000f000 {
compatible = "mediatek,mt8135-pwrap"; compatible = "mediatek,mt8135-pwrap";
......
...@@ -11474,10 +11474,15 @@ F: kernel/module.c ...@@ -11474,10 +11474,15 @@ F: kernel/module.c
MONOLITHIC POWER SYSTEM PMIC DRIVER MONOLITHIC POWER SYSTEM PMIC DRIVER
M: Saravanan Sekar <sravanhome@gmail.com> M: Saravanan Sekar <sravanhome@gmail.com>
S: Maintained S: Maintained
F: Documentation/devicetree/bindings/mfd/mps,mp2629.yaml
F: Documentation/devicetree/bindings/regulator/mps,mp*.yaml F: Documentation/devicetree/bindings/regulator/mps,mp*.yaml
F: drivers/iio/adc/mp2629_adc.c
F: drivers/mfd/mp2629.c
F: drivers/power/supply/mp2629_charger.c
F: drivers/regulator/mp5416.c F: drivers/regulator/mp5416.c
F: drivers/regulator/mpq7920.c F: drivers/regulator/mpq7920.c
F: drivers/regulator/mpq7920.h F: drivers/regulator/mpq7920.h
F: include/linux/mfd/mp2629.h
MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER
S: Orphan S: Orphan
......
...@@ -692,6 +692,16 @@ config MESON_SARADC ...@@ -692,6 +692,16 @@ config MESON_SARADC
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called meson_saradc. module will be called meson_saradc.
config MP2629_ADC
tristate "Monolithic MP2629 ADC driver"
depends on MFD_MP2629
help
Say yes to have support for battery charger IC MP2629 ADC device
accessed over I2C.
This driver provides ADC conversion of system, input power supply
and battery voltage & current information.
config NAU7802 config NAU7802
tristate "Nuvoton NAU7802 ADC driver" tristate "Nuvoton NAU7802 ADC driver"
depends on I2C depends on I2C
......
...@@ -65,6 +65,7 @@ obj-$(CONFIG_MCP3911) += mcp3911.o ...@@ -65,6 +65,7 @@ obj-$(CONFIG_MCP3911) += mcp3911.o
obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
obj-$(CONFIG_MESON_SARADC) += meson_saradc.o obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
obj-$(CONFIG_MP2629_ADC) += mp2629_adc.o
obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o
obj-$(CONFIG_NAU7802) += nau7802.o obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_NPCM_ADC) += npcm_adc.o obj-$(CONFIG_NPCM_ADC) += npcm_adc.o
......
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* MP2629 Driver for ADC
*
* Copyright 2020 Monolithic Power Systems, Inc
*
* Author: Saravanan Sekar <sravanhome@gmail.com>
*/
#include <linux/iio/driver.h>
#include <linux/iio/iio.h>
#include <linux/iio/machine.h>
#include <linux/mfd/mp2629.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#define MP2629_REG_ADC_CTRL 0x03
#define MP2629_REG_BATT_VOLT 0x0e
#define MP2629_REG_SYSTEM_VOLT 0x0f
#define MP2629_REG_INPUT_VOLT 0x11
#define MP2629_REG_BATT_CURRENT 0x12
#define MP2629_REG_INPUT_CURRENT 0x13
#define MP2629_ADC_START BIT(7)
#define MP2629_ADC_CONTINUOUS BIT(6)
#define MP2629_MAP(_mp, _mpc) IIO_MAP(#_mp, "mp2629_charger", "mp2629-"_mpc)
#define MP2629_ADC_CHAN(_ch, _type) { \
.type = _type, \
.indexed = 1, \
.datasheet_name = #_ch, \
.channel = MP2629_ ## _ch, \
.address = MP2629_REG_ ## _ch, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
}
struct mp2629_adc {
struct regmap *regmap;
struct device *dev;
};
static struct iio_chan_spec mp2629_channels[] = {
MP2629_ADC_CHAN(BATT_VOLT, IIO_VOLTAGE),
MP2629_ADC_CHAN(SYSTEM_VOLT, IIO_VOLTAGE),
MP2629_ADC_CHAN(INPUT_VOLT, IIO_VOLTAGE),
MP2629_ADC_CHAN(BATT_CURRENT, IIO_CURRENT),
MP2629_ADC_CHAN(INPUT_CURRENT, IIO_CURRENT)
};
static struct iio_map mp2629_adc_maps[] = {
MP2629_MAP(BATT_VOLT, "batt-volt"),
MP2629_MAP(SYSTEM_VOLT, "system-volt"),
MP2629_MAP(INPUT_VOLT, "input-volt"),
MP2629_MAP(BATT_CURRENT, "batt-current"),
MP2629_MAP(INPUT_CURRENT, "input-current")
};
static int mp2629_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct mp2629_adc *info = iio_priv(indio_dev);
unsigned int rval;
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = regmap_read(info->regmap, chan->address, &rval);
if (ret)
return ret;
if (chan->address == MP2629_INPUT_VOLT)
rval &= GENMASK(6, 0);
*val = rval;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
switch (chan->channel) {
case MP2629_BATT_VOLT:
case MP2629_SYSTEM_VOLT:
*val = 20;
return IIO_VAL_INT;
case MP2629_INPUT_VOLT:
*val = 60;
return IIO_VAL_INT;
case MP2629_BATT_CURRENT:
*val = 175;
*val2 = 10;
return IIO_VAL_FRACTIONAL;
case MP2629_INPUT_CURRENT:
*val = 133;
*val2 = 10;
return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
}
default:
return -EINVAL;
}
}
static const struct iio_info mp2629_adc_info = {
.read_raw = &mp2629_read_raw,
};
static int mp2629_adc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct mp2629_data *ddata = dev_get_drvdata(dev->parent);
struct mp2629_adc *info;
struct iio_dev *indio_dev;
int ret;
indio_dev = devm_iio_device_alloc(dev, sizeof(*info));
if (!indio_dev)
return -ENOMEM;
info = iio_priv(indio_dev);
info->regmap = ddata->regmap;
info->dev = dev;
platform_set_drvdata(pdev, indio_dev);
ret = regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL,
MP2629_ADC_START | MP2629_ADC_CONTINUOUS,
MP2629_ADC_START | MP2629_ADC_CONTINUOUS);
if (ret) {
dev_err(dev, "adc enable fail: %d\n", ret);
return ret;
}
ret = iio_map_array_register(indio_dev, mp2629_adc_maps);
if (ret) {
dev_err(dev, "IIO maps register fail: %d\n", ret);
goto fail_disable;
}
indio_dev->name = "mp2629-adc";
indio_dev->dev.parent = dev;
indio_dev->channels = mp2629_channels;
indio_dev->num_channels = ARRAY_SIZE(mp2629_channels);
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &mp2629_adc_info;
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(dev, "IIO device register fail: %d\n", ret);
goto fail_map_unregister;
}
return 0;
fail_map_unregister:
iio_map_array_unregister(indio_dev);
fail_disable:
regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL,
MP2629_ADC_CONTINUOUS, 0);
regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL,
MP2629_ADC_START, 0);
return ret;
}
static int mp2629_adc_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct mp2629_adc *info = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
iio_map_array_unregister(indio_dev);
regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL,
MP2629_ADC_CONTINUOUS, 0);
regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL,
MP2629_ADC_START, 0);
return 0;
}
static const struct of_device_id mp2629_adc_of_match[] = {
{ .compatible = "mps,mp2629_adc"},
{}
};
MODULE_DEVICE_TABLE(of, mp2629_adc_of_match);
static struct platform_driver mp2629_adc_driver = {
.driver = {
.name = "mp2629_adc",
.of_match_table = mp2629_adc_of_match,
},
.probe = mp2629_adc_probe,
.remove = mp2629_adc_remove,
};
module_platform_driver(mp2629_adc_driver);
MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>");
MODULE_DESCRIPTION("MP2629 ADC driver");
MODULE_LICENSE("GPL");
...@@ -449,6 +449,15 @@ config MFD_MC13XXX_I2C ...@@ -449,6 +449,15 @@ config MFD_MC13XXX_I2C
help help
Select this if your MC13xxx is connected via an I2C bus. Select this if your MC13xxx is connected via an I2C bus.
config MFD_MP2629
tristate "Monolithic Power Systems MP2629 ADC and Battery charger"
depends on I2C
select REGMAP_I2C
help
Select this option to enable support for Monolithic Power Systems
battery charger. This provides ADC, thermal and battery charger power
management functions.
config MFD_MXS_LRADC config MFD_MXS_LRADC
tristate "Freescale i.MX23/i.MX28 LRADC" tristate "Freescale i.MX23/i.MX28 LRADC"
depends on ARCH_MXS || COMPILE_TEST depends on ARCH_MXS || COMPILE_TEST
...@@ -899,6 +908,18 @@ config MFD_MAX8998 ...@@ -899,6 +908,18 @@ config MFD_MAX8998
additional drivers must be enabled in order to use the functionality additional drivers must be enabled in order to use the functionality
of the device. of the device.
config MFD_MT6360
tristate "Mediatek MT6360 SubPMIC"
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
depends on I2C
help
Say Y here to enable MT6360 PMU/PMIC/LDO functional support.
PMU part includes Charger, Flashlight, RGB LED
PMIC part includes 2-channel BUCKs and 2-channel LDOs
LDO part includes 4-channel LDOs
config MFD_MT6397 config MFD_MT6397
tristate "MediaTek MT6397 PMIC Support" tristate "MediaTek MT6397 PMIC Support"
select MFD_CORE select MFD_CORE
......
...@@ -171,6 +171,8 @@ obj-$(CONFIG_MFD_MAX8925) += max8925.o ...@@ -171,6 +171,8 @@ obj-$(CONFIG_MFD_MAX8925) += max8925.o
obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o
obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o
obj-$(CONFIG_MFD_MP2629) += mp2629.o
pcf50633-objs := pcf50633-core.o pcf50633-irq.o pcf50633-objs := pcf50633-core.o pcf50633-irq.o
obj-$(CONFIG_MFD_PCF50633) += pcf50633.o obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
...@@ -241,7 +243,8 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o ...@@ -241,7 +243,8 @@ 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_BXTWC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.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_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
mt6397-objs := mt6397-core.o mt6397-irq.o obj-$(CONFIG_MFD_MT6360) += mt6360-core.o
mt6397-objs := mt6397-core.o mt6397-irq.o mt6358-irq.o
obj-$(CONFIG_MFD_MT6397) += mt6397.o obj-$(CONFIG_MFD_MT6397) += mt6397.o
obj-$(CONFIG_INTEL_SOC_PMIC_MRFLD) += intel_soc_pmic_mrfld.o obj-$(CONFIG_INTEL_SOC_PMIC_MRFLD) += intel_soc_pmic_mrfld.o
......
...@@ -355,12 +355,12 @@ static int htcpld_register_chip_i2c( ...@@ -355,12 +355,12 @@ static int htcpld_register_chip_i2c(
info.platform_data = chip; info.platform_data = chip;
/* Add the I2C device. This calls the probe() function. */ /* Add the I2C device. This calls the probe() function. */
client = i2c_new_device(adapter, &info); client = i2c_new_client_device(adapter, &info);
if (!client) { if (IS_ERR(client)) {
/* I2C device registration failed, contineu with the next */ /* I2C device registration failed, contineu with the next */
dev_warn(dev, "Unable to add I2C device for 0x%x\n", dev_warn(dev, "Unable to add I2C device for 0x%x\n",
plat_chip_data->addr); plat_chip_data->addr);
return -ENODEV; return PTR_ERR(client);
} }
i2c_set_clientdata(client, chip); i2c_set_clientdata(client, chip);
......
...@@ -250,9 +250,9 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { ...@@ -250,9 +250,9 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x4da9), (kernel_ulong_t)&spt_uart_info }, { PCI_VDEVICE(INTEL, 0x4da9), (kernel_ulong_t)&spt_uart_info },
{ PCI_VDEVICE(INTEL, 0x4daa), (kernel_ulong_t)&spt_info }, { PCI_VDEVICE(INTEL, 0x4daa), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0x4dab), (kernel_ulong_t)&spt_info }, { PCI_VDEVICE(INTEL, 0x4dab), (kernel_ulong_t)&spt_info },
{ PCI_VDEVICE(INTEL, 0x4daf), (kernel_ulong_t)&spt_uart_info },
{ PCI_VDEVICE(INTEL, 0x4dc5), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x4dc5), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x4dc6), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x4dc6), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x4dc7), (kernel_ulong_t)&spt_uart_info },
{ PCI_VDEVICE(INTEL, 0x4de8), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x4de8), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x4de9), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x4de9), (kernel_ulong_t)&bxt_i2c_info },
{ PCI_VDEVICE(INTEL, 0x4dea), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x4dea), (kernel_ulong_t)&bxt_i2c_info },
......
...@@ -177,6 +177,7 @@ static const struct regmap_config max77620_regmap_config = { ...@@ -177,6 +177,7 @@ static const struct regmap_config max77620_regmap_config = {
.rd_table = &max77620_readable_table, .rd_table = &max77620_readable_table,
.wr_table = &max77620_writable_table, .wr_table = &max77620_writable_table,
.volatile_table = &max77620_volatile_table, .volatile_table = &max77620_volatile_table,
.use_single_write = true,
}; };
static const struct regmap_config max20024_regmap_config = { static const struct regmap_config max20024_regmap_config = {
......
// SPDX-License-Identifier: GPL-2.0+
/*
* MP2629 parent driver for ADC and battery charger
*
* Copyright 2020 Monolithic Power Systems, Inc
*
* Author: Saravanan Sekar <sravanhome@gmail.com>
*/
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/mp2629.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
static const struct mfd_cell mp2629_cell[] = {
{
.name = "mp2629_adc",
.of_compatible = "mps,mp2629_adc",
},
{
.name = "mp2629_charger",
.of_compatible = "mps,mp2629_charger",
}
};
static const struct regmap_config mp2629_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x17,
};
static int mp2629_probe(struct i2c_client *client)
{
struct mp2629_data *ddata;
int ret;
ddata = devm_kzalloc(&client->dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
ddata->dev = &client->dev;
i2c_set_clientdata(client, ddata);
ddata->regmap = devm_regmap_init_i2c(client, &mp2629_regmap_config);
if (IS_ERR(ddata->regmap)) {
dev_err(ddata->dev, "Failed to allocate regmap\n");
return PTR_ERR(ddata->regmap);
}
ret = devm_mfd_add_devices(ddata->dev, PLATFORM_DEVID_AUTO, mp2629_cell,
ARRAY_SIZE(mp2629_cell), NULL, 0, NULL);
if (ret)
dev_err(ddata->dev, "Failed to register sub-devices %d\n", ret);
return ret;
}
static const struct of_device_id mp2629_of_match[] = {
{ .compatible = "mps,mp2629"},
{ }
};
MODULE_DEVICE_TABLE(of, mp2629_of_match);
static struct i2c_driver mp2629_driver = {
.driver = {
.name = "mp2629",
.of_match_table = mp2629_of_match,
},
.probe_new = mp2629_probe,
};
module_i2c_driver(mp2629_driver);
MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>");
MODULE_DESCRIPTION("MP2629 Battery charger parent driver");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2020 MediaTek Inc.
#include <linux/interrupt.h>
#include <linux/mfd/mt6358/core.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6397/core.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>
static struct irq_top_t mt6358_ints[] = {
MT6358_TOP_GEN(BUCK),
MT6358_TOP_GEN(LDO),
MT6358_TOP_GEN(PSC),
MT6358_TOP_GEN(SCK),
MT6358_TOP_GEN(BM),
MT6358_TOP_GEN(HK),
MT6358_TOP_GEN(AUD),
MT6358_TOP_GEN(MISC),
};
static void pmic_irq_enable(struct irq_data *data)
{
unsigned int hwirq = irqd_to_hwirq(data);
struct mt6397_chip *chip = irq_data_get_irq_chip_data(data);
struct pmic_irq_data *irqd = chip->irq_data;
irqd->enable_hwirq[hwirq] = true;
}
static void pmic_irq_disable(struct irq_data *data)
{
unsigned int hwirq = irqd_to_hwirq(data);
struct mt6397_chip *chip = irq_data_get_irq_chip_data(data);
struct pmic_irq_data *irqd = chip->irq_data;
irqd->enable_hwirq[hwirq] = false;
}
static void pmic_irq_lock(struct irq_data *data)
{
struct mt6397_chip *chip = irq_data_get_irq_chip_data(data);
mutex_lock(&chip->irqlock);
}
static void pmic_irq_sync_unlock(struct irq_data *data)
{
unsigned int i, top_gp, gp_offset, en_reg, int_regs, shift;
struct mt6397_chip *chip = irq_data_get_irq_chip_data(data);
struct pmic_irq_data *irqd = chip->irq_data;
for (i = 0; i < irqd->num_pmic_irqs; i++) {
if (irqd->enable_hwirq[i] == irqd->cache_hwirq[i])
continue;
/* Find out the IRQ group */
top_gp = 0;
while ((top_gp + 1) < irqd->num_top &&
i >= mt6358_ints[top_gp + 1].hwirq_base)
top_gp++;
/* Find the IRQ registers */
gp_offset = i - mt6358_ints[top_gp].hwirq_base;
int_regs = gp_offset / MT6358_REG_WIDTH;
shift = gp_offset % MT6358_REG_WIDTH;
en_reg = mt6358_ints[top_gp].en_reg +
(mt6358_ints[top_gp].en_reg_shift * int_regs);
regmap_update_bits(chip->regmap, en_reg, BIT(shift),
irqd->enable_hwirq[i] << shift);
irqd->cache_hwirq[i] = irqd->enable_hwirq[i];
}
mutex_unlock(&chip->irqlock);
}
static struct irq_chip mt6358_irq_chip = {
.name = "mt6358-irq",
.flags = IRQCHIP_SKIP_SET_WAKE,
.irq_enable = pmic_irq_enable,
.irq_disable = pmic_irq_disable,
.irq_bus_lock = pmic_irq_lock,
.irq_bus_sync_unlock = pmic_irq_sync_unlock,
};
static void mt6358_irq_sp_handler(struct mt6397_chip *chip,
unsigned int top_gp)
{
unsigned int irq_status, sta_reg, status;
unsigned int hwirq, virq;
int i, j, ret;
for (i = 0; i < mt6358_ints[top_gp].num_int_regs; i++) {
sta_reg = mt6358_ints[top_gp].sta_reg +
mt6358_ints[top_gp].sta_reg_shift * i;
ret = regmap_read(chip->regmap, sta_reg, &irq_status);
if (ret) {
dev_err(chip->dev,
"Failed to read IRQ status, ret=%d\n", ret);
return;
}
if (!irq_status)
continue;
status = irq_status;
do {
j = __ffs(status);
hwirq = mt6358_ints[top_gp].hwirq_base +
MT6358_REG_WIDTH * i + j;
virq = irq_find_mapping(chip->irq_domain, hwirq);
if (virq)
handle_nested_irq(virq);
status &= ~BIT(j);
} while (status);
regmap_write(chip->regmap, sta_reg, irq_status);
}
}
static irqreturn_t mt6358_irq_handler(int irq, void *data)
{
struct mt6397_chip *chip = data;
struct pmic_irq_data *mt6358_irq_data = chip->irq_data;
unsigned int bit, i, top_irq_status = 0;
int ret;
ret = regmap_read(chip->regmap,
mt6358_irq_data->top_int_status_reg,
&top_irq_status);
if (ret) {
dev_err(chip->dev,
"Failed to read status from the device, ret=%d\n", ret);
return IRQ_NONE;
}
for (i = 0; i < mt6358_irq_data->num_top; i++) {
bit = BIT(mt6358_ints[i].top_offset);
if (top_irq_status & bit) {
mt6358_irq_sp_handler(chip, i);
top_irq_status &= ~bit;
if (!top_irq_status)
break;
}
}
return IRQ_HANDLED;
}
static int pmic_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, &mt6358_irq_chip, handle_level_irq);
irq_set_nested_thread(irq, 1);
irq_set_noprobe(irq);
return 0;
}
static const struct irq_domain_ops mt6358_irq_domain_ops = {
.map = pmic_irq_domain_map,
.xlate = irq_domain_xlate_twocell,
};
int mt6358_irq_init(struct mt6397_chip *chip)
{
int i, j, ret;
struct pmic_irq_data *irqd;
irqd = devm_kzalloc(chip->dev, sizeof(*irqd), GFP_KERNEL);
if (!irqd)
return -ENOMEM;
chip->irq_data = irqd;
mutex_init(&chip->irqlock);
irqd->top_int_status_reg = MT6358_TOP_INT_STATUS0;
irqd->num_pmic_irqs = MT6358_IRQ_NR;
irqd->num_top = ARRAY_SIZE(mt6358_ints);
irqd->enable_hwirq = devm_kcalloc(chip->dev,
irqd->num_pmic_irqs,
sizeof(*irqd->enable_hwirq),
GFP_KERNEL);
if (!irqd->enable_hwirq)
return -ENOMEM;
irqd->cache_hwirq = devm_kcalloc(chip->dev,
irqd->num_pmic_irqs,
sizeof(*irqd->cache_hwirq),
GFP_KERNEL);
if (!irqd->cache_hwirq)
return -ENOMEM;
/* Disable all interrupts for initializing */
for (i = 0; i < irqd->num_top; i++) {
for (j = 0; j < mt6358_ints[i].num_int_regs; j++)
regmap_write(chip->regmap,
mt6358_ints[i].en_reg +
mt6358_ints[i].en_reg_shift * j, 0);
}
chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
irqd->num_pmic_irqs,
&mt6358_irq_domain_ops, chip);
if (!chip->irq_domain) {
dev_err(chip->dev, "Could not create IRQ domain\n");
return -ENODEV;
}
ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL,
mt6358_irq_handler, IRQF_ONESHOT,
mt6358_irq_chip.name, chip);
if (ret) {
dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n",
chip->irq, ret);
return ret;
}
enable_irq_wake(chip->irq);
return ret;
}
This diff is collapsed.
...@@ -12,13 +12,18 @@ ...@@ -12,13 +12,18 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/mt6323/core.h> #include <linux/mfd/mt6323/core.h>
#include <linux/mfd/mt6358/core.h>
#include <linux/mfd/mt6397/core.h> #include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6323/registers.h> #include <linux/mfd/mt6323/registers.h>
#include <linux/mfd/mt6358/registers.h>
#include <linux/mfd/mt6397/registers.h> #include <linux/mfd/mt6397/registers.h>
#define MT6323_RTC_BASE 0x8000 #define MT6323_RTC_BASE 0x8000
#define MT6323_RTC_SIZE 0x40 #define MT6323_RTC_SIZE 0x40
#define MT6358_RTC_BASE 0x0588
#define MT6358_RTC_SIZE 0x3c
#define MT6397_RTC_BASE 0xe000 #define MT6397_RTC_BASE 0xe000
#define MT6397_RTC_SIZE 0x3e #define MT6397_RTC_SIZE 0x3e
...@@ -30,6 +35,11 @@ static const struct resource mt6323_rtc_resources[] = { ...@@ -30,6 +35,11 @@ static const struct resource mt6323_rtc_resources[] = {
DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC), DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC),
}; };
static const struct resource mt6358_rtc_resources[] = {
DEFINE_RES_MEM(MT6358_RTC_BASE, MT6358_RTC_SIZE),
DEFINE_RES_IRQ(MT6358_IRQ_RTC),
};
static const struct resource mt6397_rtc_resources[] = { static const struct resource mt6397_rtc_resources[] = {
DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE), DEFINE_RES_MEM(MT6397_RTC_BASE, MT6397_RTC_SIZE),
DEFINE_RES_IRQ(MT6397_IRQ_RTC), DEFINE_RES_IRQ(MT6397_IRQ_RTC),
...@@ -74,6 +84,21 @@ static const struct mfd_cell mt6323_devs[] = { ...@@ -74,6 +84,21 @@ static const struct mfd_cell mt6323_devs[] = {
}, },
}; };
static const struct mfd_cell mt6358_devs[] = {
{
.name = "mt6358-regulator",
.of_compatible = "mediatek,mt6358-regulator"
}, {
.name = "mt6358-rtc",
.num_resources = ARRAY_SIZE(mt6358_rtc_resources),
.resources = mt6358_rtc_resources,
.of_compatible = "mediatek,mt6358-rtc",
}, {
.name = "mt6358-sound",
.of_compatible = "mediatek,mt6358-sound"
},
};
static const struct mfd_cell mt6397_devs[] = { static const struct mfd_cell mt6397_devs[] = {
{ {
.name = "mt6397-rtc", .name = "mt6397-rtc",
...@@ -100,54 +125,42 @@ static const struct mfd_cell mt6397_devs[] = { ...@@ -100,54 +125,42 @@ static const struct mfd_cell mt6397_devs[] = {
} }
}; };
#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);
struct chip_data { struct chip_data {
u32 cid_addr; u32 cid_addr;
u32 cid_shift; u32 cid_shift;
const struct mfd_cell *cells;
int cell_size;
int (*irq_init)(struct mt6397_chip *chip);
}; };
static const struct chip_data mt6323_core = { static const struct chip_data mt6323_core = {
.cid_addr = MT6323_CID, .cid_addr = MT6323_CID,
.cid_shift = 0, .cid_shift = 0,
.cells = mt6323_devs,
.cell_size = ARRAY_SIZE(mt6323_devs),
.irq_init = mt6397_irq_init,
};
static const struct chip_data mt6358_core = {
.cid_addr = MT6358_SWCID,
.cid_shift = 8,
.cells = mt6358_devs,
.cell_size = ARRAY_SIZE(mt6358_devs),
.irq_init = mt6358_irq_init,
}; };
static const struct chip_data mt6397_core = { static const struct chip_data mt6397_core = {
.cid_addr = MT6397_CID, .cid_addr = MT6397_CID,
.cid_shift = 0, .cid_shift = 0,
.cells = mt6397_devs,
.cell_size = ARRAY_SIZE(mt6397_devs),
.irq_init = mt6397_irq_init,
}; };
static int mt6397_probe(struct platform_device *pdev) static int mt6397_probe(struct platform_device *pdev)
{ {
int ret; int ret;
unsigned int id; unsigned int id = 0;
struct mt6397_chip *pmic; struct mt6397_chip *pmic;
const struct chip_data *pmic_core; const struct chip_data *pmic_core;
...@@ -183,29 +196,13 @@ static int mt6397_probe(struct platform_device *pdev) ...@@ -183,29 +196,13 @@ static int mt6397_probe(struct platform_device *pdev)
if (pmic->irq <= 0) if (pmic->irq <= 0)
return pmic->irq; return pmic->irq;
ret = mt6397_irq_init(pmic); ret = pmic_core->irq_init(pmic);
if (ret) if (ret)
return ret; return ret;
switch (pmic->chip_id) { ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
case MT6323_CHIP_ID: pmic_core->cells, pmic_core->cell_size,
ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, NULL, 0, pmic->irq_domain);
mt6323_devs, ARRAY_SIZE(mt6323_devs),
NULL, 0, pmic->irq_domain);
break;
case MT6391_CHIP_ID:
case MT6397_CHIP_ID:
ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
mt6397_devs, ARRAY_SIZE(mt6397_devs),
NULL, 0, pmic->irq_domain);
break;
default:
dev_err(&pdev->dev, "unsupported chip: %d\n", pmic->chip_id);
return -ENODEV;
}
if (ret) { if (ret) {
irq_domain_remove(pmic->irq_domain); irq_domain_remove(pmic->irq_domain);
dev_err(&pdev->dev, "failed to add child devices: %d\n", ret); dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
...@@ -218,6 +215,9 @@ static const struct of_device_id mt6397_of_match[] = { ...@@ -218,6 +215,9 @@ static const struct of_device_id mt6397_of_match[] = {
{ {
.compatible = "mediatek,mt6323", .compatible = "mediatek,mt6323",
.data = &mt6323_core, .data = &mt6323_core,
}, {
.compatible = "mediatek,mt6358",
.data = &mt6358_core,
}, { }, {
.compatible = "mediatek,mt6397", .compatible = "mediatek,mt6397",
.data = &mt6397_core, .data = &mt6397_core,
...@@ -238,7 +238,6 @@ static struct platform_driver mt6397_driver = { ...@@ -238,7 +238,6 @@ static struct platform_driver mt6397_driver = {
.driver = { .driver = {
.name = "mt6397", .name = "mt6397",
.of_match_table = of_match_ptr(mt6397_of_match), .of_match_table = of_match_ptr(mt6397_of_match),
.pm = &mt6397_pm_ops,
}, },
.id_table = mt6397_id, .id_table = mt6397_id,
}; };
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/suspend.h>
#include <linux/mfd/mt6323/core.h> #include <linux/mfd/mt6323/core.h>
#include <linux/mfd/mt6323/registers.h> #include <linux/mfd/mt6323/registers.h>
#include <linux/mfd/mt6397/core.h> #include <linux/mfd/mt6397/core.h>
...@@ -81,7 +82,7 @@ static struct irq_chip mt6397_irq_chip = { ...@@ -81,7 +82,7 @@ static struct irq_chip mt6397_irq_chip = {
static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg, static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
int irqbase) int irqbase)
{ {
unsigned int status; unsigned int status = 0;
int i, irq, ret; int i, irq, ret;
ret = regmap_read(mt6397->regmap, reg, &status); ret = regmap_read(mt6397->regmap, reg, &status);
...@@ -128,6 +129,36 @@ static const struct irq_domain_ops mt6397_irq_domain_ops = { ...@@ -128,6 +129,36 @@ static const struct irq_domain_ops mt6397_irq_domain_ops = {
.map = mt6397_irq_domain_map, .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 mt6397_irq_init(struct mt6397_chip *chip)
{ {
int ret; int ret;
...@@ -159,6 +190,7 @@ int mt6397_irq_init(struct mt6397_chip *chip) ...@@ -159,6 +190,7 @@ int mt6397_irq_init(struct mt6397_chip *chip)
regmap_write(chip->regmap, chip->int_con[0], 0x0); regmap_write(chip->regmap, chip->int_con[0], 0x0);
regmap_write(chip->regmap, chip->int_con[1], 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, chip->irq_domain = irq_domain_add_linear(chip->dev->of_node,
MT6397_IRQ_NR, MT6397_IRQ_NR,
&mt6397_irq_domain_ops, &mt6397_irq_domain_ops,
...@@ -177,5 +209,6 @@ int mt6397_irq_init(struct mt6397_chip *chip) ...@@ -177,5 +209,6 @@ int mt6397_irq_init(struct mt6397_chip *chip)
return ret; return ret;
} }
register_pm_notifier(&chip->pm_nb);
return 0; return 0;
} }
...@@ -284,7 +284,6 @@ MODULE_DEVICE_TABLE(of, sprd_pmic_match); ...@@ -284,7 +284,6 @@ MODULE_DEVICE_TABLE(of, sprd_pmic_match);
static struct spi_driver sprd_pmic_driver = { static struct spi_driver sprd_pmic_driver = {
.driver = { .driver = {
.name = "sc27xx-pmic", .name = "sc27xx-pmic",
.bus = &spi_bus_type,
.of_match_table = sprd_pmic_match, .of_match_table = sprd_pmic_match,
}, },
.probe = sprd_pmic_probe, .probe = sprd_pmic_probe,
......
...@@ -167,10 +167,11 @@ static void stm32_timers_get_arr_size(struct stm32_timers *ddata) ...@@ -167,10 +167,11 @@ static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
regmap_write(ddata->regmap, TIM_ARR, 0x0); regmap_write(ddata->regmap, TIM_ARR, 0x0);
} }
static void stm32_timers_dma_probe(struct device *dev, static int stm32_timers_dma_probe(struct device *dev,
struct stm32_timers *ddata) struct stm32_timers *ddata)
{ {
int i; int i;
int ret = 0;
char name[4]; char name[4];
init_completion(&ddata->dma.completion); init_completion(&ddata->dma.completion);
...@@ -179,14 +180,23 @@ static void stm32_timers_dma_probe(struct device *dev, ...@@ -179,14 +180,23 @@ static void stm32_timers_dma_probe(struct device *dev,
/* Optional DMA support: get valid DMA channel(s) or NULL */ /* Optional DMA support: get valid DMA channel(s) or NULL */
for (i = STM32_TIMERS_DMA_CH1; i <= STM32_TIMERS_DMA_CH4; i++) { for (i = STM32_TIMERS_DMA_CH1; i <= STM32_TIMERS_DMA_CH4; i++) {
snprintf(name, ARRAY_SIZE(name), "ch%1d", i + 1); snprintf(name, ARRAY_SIZE(name), "ch%1d", i + 1);
ddata->dma.chans[i] = dma_request_slave_channel(dev, name); ddata->dma.chans[i] = dma_request_chan(dev, name);
} }
ddata->dma.chans[STM32_TIMERS_DMA_UP] = ddata->dma.chans[STM32_TIMERS_DMA_UP] = dma_request_chan(dev, "up");
dma_request_slave_channel(dev, "up"); ddata->dma.chans[STM32_TIMERS_DMA_TRIG] = dma_request_chan(dev, "trig");
ddata->dma.chans[STM32_TIMERS_DMA_TRIG] = ddata->dma.chans[STM32_TIMERS_DMA_COM] = dma_request_chan(dev, "com");
dma_request_slave_channel(dev, "trig");
ddata->dma.chans[STM32_TIMERS_DMA_COM] = for (i = STM32_TIMERS_DMA_CH1; i < STM32_TIMERS_MAX_DMAS; i++) {
dma_request_slave_channel(dev, "com"); if (IS_ERR(ddata->dma.chans[i])) {
/* Save the first error code to return */
if (PTR_ERR(ddata->dma.chans[i]) != -ENODEV && !ret)
ret = PTR_ERR(ddata->dma.chans[i]);
ddata->dma.chans[i] = NULL;
}
}
return ret;
} }
static void stm32_timers_dma_remove(struct device *dev, static void stm32_timers_dma_remove(struct device *dev,
...@@ -230,7 +240,11 @@ static int stm32_timers_probe(struct platform_device *pdev) ...@@ -230,7 +240,11 @@ static int stm32_timers_probe(struct platform_device *pdev)
stm32_timers_get_arr_size(ddata); stm32_timers_get_arr_size(ddata);
stm32_timers_dma_probe(dev, ddata); ret = stm32_timers_dma_probe(dev, ddata);
if (ret) {
stm32_timers_dma_remove(dev, ddata);
return ret;
}
platform_set_drvdata(pdev, ddata); platform_set_drvdata(pdev, ddata);
......
...@@ -287,14 +287,21 @@ static int stmfx_irq_init(struct i2c_client *client) ...@@ -287,14 +287,21 @@ static int stmfx_irq_init(struct i2c_client *client)
ret = regmap_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, irqoutpin); ret = regmap_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, irqoutpin);
if (ret) if (ret)
return ret; goto irq_exit;
ret = devm_request_threaded_irq(stmfx->dev, client->irq, ret = devm_request_threaded_irq(stmfx->dev, client->irq,
NULL, stmfx_irq_handler, NULL, stmfx_irq_handler,
irqtrigger | IRQF_ONESHOT, irqtrigger | IRQF_ONESHOT,
"stmfx", stmfx); "stmfx", stmfx);
if (ret) if (ret)
stmfx_irq_exit(client); goto irq_exit;
stmfx->irq = client->irq;
return 0;
irq_exit:
stmfx_irq_exit(client);
return ret; return ret;
} }
...@@ -481,6 +488,8 @@ static int stmfx_suspend(struct device *dev) ...@@ -481,6 +488,8 @@ static int stmfx_suspend(struct device *dev)
if (ret) if (ret)
return ret; return ret;
disable_irq(stmfx->irq);
if (stmfx->vdd) if (stmfx->vdd)
return regulator_disable(stmfx->vdd); return regulator_disable(stmfx->vdd);
...@@ -501,6 +510,13 @@ static int stmfx_resume(struct device *dev) ...@@ -501,6 +510,13 @@ static int stmfx_resume(struct device *dev)
} }
} }
/* Reset STMFX - supply has been stopped during suspend */
ret = stmfx_chip_reset(stmfx);
if (ret) {
dev_err(stmfx->dev, "Failed to reset chip: %d\n", ret);
return ret;
}
ret = regmap_raw_write(stmfx->map, STMFX_REG_SYS_CTRL, ret = regmap_raw_write(stmfx->map, STMFX_REG_SYS_CTRL,
&stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl)); &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl));
if (ret) if (ret)
...@@ -517,6 +533,8 @@ static int stmfx_resume(struct device *dev) ...@@ -517,6 +533,8 @@ static int stmfx_resume(struct device *dev)
if (ret) if (ret)
return ret; return ret;
enable_irq(stmfx->irq);
return 0; return 0;
} }
#endif #endif
......
...@@ -59,7 +59,7 @@ static const struct regmap_access_table stpmic1_volatile_table = { ...@@ -59,7 +59,7 @@ static const struct regmap_access_table stpmic1_volatile_table = {
.n_yes_ranges = ARRAY_SIZE(stpmic1_volatile_ranges), .n_yes_ranges = ARRAY_SIZE(stpmic1_volatile_ranges),
}; };
const struct regmap_config stpmic1_regmap_config = { static const struct regmap_config stpmic1_regmap_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
.cache_type = REGCACHE_RBTREE, .cache_type = REGCACHE_RBTREE,
......
...@@ -274,7 +274,7 @@ static int __init tqmx86_init(void) ...@@ -274,7 +274,7 @@ static int __init tqmx86_init(void)
module_init(tqmx86_init); module_init(tqmx86_init);
MODULE_DESCRIPTION("TQx86 PLD Core Driver"); MODULE_DESCRIPTION("TQMx86 PLD Core Driver");
MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>"); MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:tqmx86"); MODULE_ALIAS("platform:tqmx86");
...@@ -280,7 +280,6 @@ static void wcd934x_slim_remove(struct slim_device *sdev) ...@@ -280,7 +280,6 @@ static void wcd934x_slim_remove(struct slim_device *sdev)
regulator_bulk_disable(WCD934X_MAX_SUPPLY, ddata->supplies); regulator_bulk_disable(WCD934X_MAX_SUPPLY, ddata->supplies);
mfd_remove_devices(&sdev->dev); mfd_remove_devices(&sdev->dev);
kfree(ddata);
} }
static const struct slim_device_id wcd934x_slim_id[] = { static const struct slim_device_id wcd934x_slim_id[] = {
......
...@@ -393,7 +393,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) ...@@ -393,7 +393,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies, ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
wm8994->supplies); wm8994->supplies);
if (ret != 0) { if (ret != 0) {
dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); if (ret != -EPROBE_DEFER)
dev_err(wm8994->dev, "Failed to get supplies: %d\n",
ret);
goto err; goto err;
} }
...@@ -584,6 +586,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) ...@@ -584,6 +586,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
goto err_irq; goto err_irq;
} }
pm_runtime_set_active(wm8994->dev);
pm_runtime_enable(wm8994->dev); pm_runtime_enable(wm8994->dev);
pm_runtime_idle(wm8994->dev); pm_runtime_idle(wm8994->dev);
...@@ -603,7 +606,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) ...@@ -603,7 +606,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
static void wm8994_device_exit(struct wm8994 *wm8994) static void wm8994_device_exit(struct wm8994 *wm8994)
{ {
pm_runtime_get_sync(wm8994->dev);
pm_runtime_disable(wm8994->dev); pm_runtime_disable(wm8994->dev);
pm_runtime_put_noidle(wm8994->dev);
wm8994_irq_exit(wm8994); wm8994_irq_exit(wm8994);
regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies);
regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
...@@ -690,3 +695,4 @@ module_i2c_driver(wm8994_i2c_driver); ...@@ -690,3 +695,4 @@ module_i2c_driver(wm8994_i2c_driver);
MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC"); MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
MODULE_SOFTDEP("pre: wm8994_regulator");
...@@ -30,7 +30,7 @@ static void mt6323_do_pwroff(void) ...@@ -30,7 +30,7 @@ static void mt6323_do_pwroff(void)
int ret; int ret;
regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY); regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY);
regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR, 1); regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR_MT6323, 1);
ret = regmap_read_poll_timeout(pwrc->regmap, ret = regmap_read_poll_timeout(pwrc->regmap,
pwrc->base + RTC_BBPU, val, pwrc->base + RTC_BBPU, val,
......
...@@ -541,6 +541,16 @@ config CHARGER_MAX8998 ...@@ -541,6 +541,16 @@ config CHARGER_MAX8998
Say Y to enable support for the battery charger control sysfs and Say Y to enable support for the battery charger control sysfs and
platform data of MAX8998/LP3974 PMICs. platform data of MAX8998/LP3974 PMICs.
config CHARGER_MP2629
tristate "Monolithic power system MP2629 Battery charger"
depends on MFD_MP2629
depends on MP2629_ADC
depends on IIO
help
Select this option to enable support for Monolithic power system
Battery charger. This driver provides Battery charger power management
functions on the systems.
config CHARGER_QCOM_SMBB config CHARGER_QCOM_SMBB
tristate "Qualcomm Switch-Mode Battery Charger and Boost" tristate "Qualcomm Switch-Mode Battery Charger and Boost"
depends on MFD_SPMI_PMIC || COMPILE_TEST depends on MFD_SPMI_PMIC || COMPILE_TEST
......
...@@ -75,6 +75,7 @@ obj-$(CONFIG_CHARGER_MAX77650) += max77650-charger.o ...@@ -75,6 +75,7 @@ obj-$(CONFIG_CHARGER_MAX77650) += max77650-charger.o
obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
obj-$(CONFIG_CHARGER_MP2629) += mp2629_charger.o
obj-$(CONFIG_CHARGER_QCOM_SMBB) += qcom_smbb.o obj-$(CONFIG_CHARGER_QCOM_SMBB) += qcom_smbb.o
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o
......
This diff is collapsed.
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/mfd/mt6397/core.h> #include <linux/mfd/mt6397/core.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/rtc.h> #include <linux/rtc.h>
...@@ -20,7 +21,7 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc) ...@@ -20,7 +21,7 @@ static int mtk_rtc_write_trigger(struct mt6397_rtc *rtc)
int ret; int ret;
u32 data; u32 data;
ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1); ret = regmap_write(rtc->regmap, rtc->addr_base + rtc->data->wrtgr, 1);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -269,6 +270,8 @@ static int mtk_rtc_probe(struct platform_device *pdev) ...@@ -269,6 +270,8 @@ static int mtk_rtc_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
rtc->addr_base = res->start; rtc->addr_base = res->start;
rtc->data = of_device_get_match_data(&pdev->dev);
rtc->irq = platform_get_irq(pdev, 0); rtc->irq = platform_get_irq(pdev, 0);
if (rtc->irq < 0) if (rtc->irq < 0)
return rtc->irq; return rtc->irq;
...@@ -325,9 +328,18 @@ static int mt6397_rtc_resume(struct device *dev) ...@@ -325,9 +328,18 @@ static int mt6397_rtc_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend, static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend,
mt6397_rtc_resume); mt6397_rtc_resume);
static const struct mtk_rtc_data mt6358_rtc_data = {
.wrtgr = RTC_WRTGR_MT6358,
};
static const struct mtk_rtc_data mt6397_rtc_data = {
.wrtgr = RTC_WRTGR_MT6397,
};
static const struct of_device_id mt6397_rtc_of_match[] = { static const struct of_device_id mt6397_rtc_of_match[] = {
{ .compatible = "mediatek,mt6323-rtc", }, { .compatible = "mediatek,mt6323-rtc", .data = &mt6397_rtc_data },
{ .compatible = "mediatek,mt6397-rtc", }, { .compatible = "mediatek,mt6358-rtc", .data = &mt6358_rtc_data },
{ .compatible = "mediatek,mt6397-rtc", .data = &mt6397_rtc_data },
{ } { }
}; };
MODULE_DEVICE_TABLE(of, mt6397_rtc_of_match); MODULE_DEVICE_TABLE(of, mt6397_rtc_of_match);
......
...@@ -70,7 +70,7 @@ struct mfd_cell { ...@@ -70,7 +70,7 @@ struct mfd_cell {
size_t pdata_size; size_t pdata_size;
/* device properties passed to the sub devices drivers */ /* device properties passed to the sub devices drivers */
struct property_entry *properties; const struct property_entry *properties;
/* /*
* Device Tree compatible string * Device Tree compatible string
......
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2020 Monolithic Power Systems, Inc
*/
#ifndef __MP2629_H__
#define __MP2629_H__
#include <linux/device.h>
#include <linux/regmap.h>
struct mp2629_data {
struct device *dev;
struct regmap *regmap;
};
enum mp2629_adc_chan {
MP2629_BATT_VOLT,
MP2629_SYSTEM_VOLT,
MP2629_INPUT_VOLT,
MP2629_BATT_CURRENT,
MP2629_INPUT_CURRENT,
MP2629_ADC_CHAN_END
};
#endif
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2020 MediaTek Inc.
*/
#ifndef __MFD_MT6358_CORE_H__
#define __MFD_MT6358_CORE_H__
#define MT6358_REG_WIDTH 16
struct irq_top_t {
int hwirq_base;
unsigned int num_int_regs;
unsigned int num_int_bits;
unsigned int en_reg;
unsigned int en_reg_shift;
unsigned int sta_reg;
unsigned int sta_reg_shift;
unsigned int top_offset;
};
struct pmic_irq_data {
unsigned int num_top;
unsigned int num_pmic_irqs;
unsigned short top_int_status_reg;
bool *enable_hwirq;
bool *cache_hwirq;
};
enum mt6358_irq_top_status_shift {
MT6358_BUCK_TOP = 0,
MT6358_LDO_TOP,
MT6358_PSC_TOP,
MT6358_SCK_TOP,
MT6358_BM_TOP,
MT6358_HK_TOP,
MT6358_AUD_TOP,
MT6358_MISC_TOP,
};
enum mt6358_irq_numbers {
MT6358_IRQ_VPROC11_OC = 0,
MT6358_IRQ_VPROC12_OC,
MT6358_IRQ_VCORE_OC,
MT6358_IRQ_VGPU_OC,
MT6358_IRQ_VMODEM_OC,
MT6358_IRQ_VDRAM1_OC,
MT6358_IRQ_VS1_OC,
MT6358_IRQ_VS2_OC,
MT6358_IRQ_VPA_OC,
MT6358_IRQ_VCORE_PREOC,
MT6358_IRQ_VFE28_OC = 16,
MT6358_IRQ_VXO22_OC,
MT6358_IRQ_VRF18_OC,
MT6358_IRQ_VRF12_OC,
MT6358_IRQ_VEFUSE_OC,
MT6358_IRQ_VCN33_OC,
MT6358_IRQ_VCN28_OC,
MT6358_IRQ_VCN18_OC,
MT6358_IRQ_VCAMA1_OC,
MT6358_IRQ_VCAMA2_OC,
MT6358_IRQ_VCAMD_OC,
MT6358_IRQ_VCAMIO_OC,
MT6358_IRQ_VLDO28_OC,
MT6358_IRQ_VA12_OC,
MT6358_IRQ_VAUX18_OC,
MT6358_IRQ_VAUD28_OC,
MT6358_IRQ_VIO28_OC,
MT6358_IRQ_VIO18_OC,
MT6358_IRQ_VSRAM_PROC11_OC,
MT6358_IRQ_VSRAM_PROC12_OC,
MT6358_IRQ_VSRAM_OTHERS_OC,
MT6358_IRQ_VSRAM_GPU_OC,
MT6358_IRQ_VDRAM2_OC,
MT6358_IRQ_VMC_OC,
MT6358_IRQ_VMCH_OC,
MT6358_IRQ_VEMC_OC,
MT6358_IRQ_VSIM1_OC,
MT6358_IRQ_VSIM2_OC,
MT6358_IRQ_VIBR_OC,
MT6358_IRQ_VUSB_OC,
MT6358_IRQ_VBIF28_OC,
MT6358_IRQ_PWRKEY = 48,
MT6358_IRQ_HOMEKEY,
MT6358_IRQ_PWRKEY_R,
MT6358_IRQ_HOMEKEY_R,
MT6358_IRQ_NI_LBAT_INT,
MT6358_IRQ_CHRDET,
MT6358_IRQ_CHRDET_EDGE,
MT6358_IRQ_VCDT_HV_DET,
MT6358_IRQ_RTC = 64,
MT6358_IRQ_FG_BAT0_H = 80,
MT6358_IRQ_FG_BAT0_L,
MT6358_IRQ_FG_CUR_H,
MT6358_IRQ_FG_CUR_L,
MT6358_IRQ_FG_ZCV,
MT6358_IRQ_FG_BAT1_H,
MT6358_IRQ_FG_BAT1_L,
MT6358_IRQ_FG_N_CHARGE_L,
MT6358_IRQ_FG_IAVG_H,
MT6358_IRQ_FG_IAVG_L,
MT6358_IRQ_FG_TIME_H,
MT6358_IRQ_FG_DISCHARGE,
MT6358_IRQ_FG_CHARGE,
MT6358_IRQ_BATON_LV = 96,
MT6358_IRQ_BATON_HT,
MT6358_IRQ_BATON_BAT_IN,
MT6358_IRQ_BATON_BAT_OUT,
MT6358_IRQ_BIF,
MT6358_IRQ_BAT_H = 112,
MT6358_IRQ_BAT_L,
MT6358_IRQ_BAT2_H,
MT6358_IRQ_BAT2_L,
MT6358_IRQ_BAT_TEMP_H,
MT6358_IRQ_BAT_TEMP_L,
MT6358_IRQ_AUXADC_IMP,
MT6358_IRQ_NAG_C_DLTV,
MT6358_IRQ_AUDIO = 128,
MT6358_IRQ_ACCDET = 133,
MT6358_IRQ_ACCDET_EINT0,
MT6358_IRQ_ACCDET_EINT1,
MT6358_IRQ_SPI_CMD_ALERT = 144,
MT6358_IRQ_NR,
};
#define MT6358_IRQ_BUCK_BASE MT6358_IRQ_VPROC11_OC
#define MT6358_IRQ_LDO_BASE MT6358_IRQ_VFE28_OC
#define MT6358_IRQ_PSC_BASE MT6358_IRQ_PWRKEY
#define MT6358_IRQ_SCK_BASE MT6358_IRQ_RTC
#define MT6358_IRQ_BM_BASE MT6358_IRQ_FG_BAT0_H
#define MT6358_IRQ_HK_BASE MT6358_IRQ_BAT_H
#define MT6358_IRQ_AUD_BASE MT6358_IRQ_AUDIO
#define MT6358_IRQ_MISC_BASE MT6358_IRQ_SPI_CMD_ALERT
#define MT6358_IRQ_BUCK_BITS (MT6358_IRQ_VCORE_PREOC - MT6358_IRQ_BUCK_BASE + 1)
#define MT6358_IRQ_LDO_BITS (MT6358_IRQ_VBIF28_OC - MT6358_IRQ_LDO_BASE + 1)
#define MT6358_IRQ_PSC_BITS (MT6358_IRQ_VCDT_HV_DET - MT6358_IRQ_PSC_BASE + 1)
#define MT6358_IRQ_SCK_BITS (MT6358_IRQ_RTC - MT6358_IRQ_SCK_BASE + 1)
#define MT6358_IRQ_BM_BITS (MT6358_IRQ_BIF - MT6358_IRQ_BM_BASE + 1)
#define MT6358_IRQ_HK_BITS (MT6358_IRQ_NAG_C_DLTV - MT6358_IRQ_HK_BASE + 1)
#define MT6358_IRQ_AUD_BITS (MT6358_IRQ_ACCDET_EINT1 - MT6358_IRQ_AUD_BASE + 1)
#define MT6358_IRQ_MISC_BITS \
(MT6358_IRQ_SPI_CMD_ALERT - MT6358_IRQ_MISC_BASE + 1)
#define MT6358_TOP_GEN(sp) \
{ \
.hwirq_base = MT6358_IRQ_##sp##_BASE, \
.num_int_regs = \
((MT6358_IRQ_##sp##_BITS - 1) / MT6358_REG_WIDTH) + 1, \
.num_int_bits = MT6358_IRQ_##sp##_BITS, \
.en_reg = MT6358_##sp##_TOP_INT_CON0, \
.en_reg_shift = 0x6, \
.sta_reg = MT6358_##sp##_TOP_INT_STATUS0, \
.sta_reg_shift = 0x2, \
.top_offset = MT6358_##sp##_TOP, \
}
#endif /* __MFD_MT6358_CORE_H__ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2020 MediaTek Inc.
*/
#ifndef __MT6360_H__
#define __MT6360_H__
#include <linux/regmap.h>
enum {
MT6360_SLAVE_PMU = 0,
MT6360_SLAVE_PMIC,
MT6360_SLAVE_LDO,
MT6360_SLAVE_TCPC,
MT6360_SLAVE_MAX,
};
#define MT6360_PMU_SLAVEID (0x34)
#define MT6360_PMIC_SLAVEID (0x1A)
#define MT6360_LDO_SLAVEID (0x64)
#define MT6360_TCPC_SLAVEID (0x4E)
struct mt6360_pmu_data {
struct i2c_client *i2c[MT6360_SLAVE_MAX];
struct device *dev;
struct regmap *regmap;
struct regmap_irq_chip_data *irq_data;
unsigned int chip_rev;
};
/* PMU register defininition */
#define MT6360_PMU_DEV_INFO (0x00)
#define MT6360_PMU_CORE_CTRL1 (0x01)
#define MT6360_PMU_RST1 (0x02)
#define MT6360_PMU_CRCEN (0x03)
#define MT6360_PMU_RST_PAS_CODE1 (0x04)
#define MT6360_PMU_RST_PAS_CODE2 (0x05)
#define MT6360_PMU_CORE_CTRL2 (0x06)
#define MT6360_PMU_TM_PAS_CODE1 (0x07)
#define MT6360_PMU_TM_PAS_CODE2 (0x08)
#define MT6360_PMU_TM_PAS_CODE3 (0x09)
#define MT6360_PMU_TM_PAS_CODE4 (0x0A)
#define MT6360_PMU_IRQ_IND (0x0B)
#define MT6360_PMU_IRQ_MASK (0x0C)
#define MT6360_PMU_IRQ_SET (0x0D)
#define MT6360_PMU_SHDN_CTRL (0x0E)
#define MT6360_PMU_TM_INF (0x0F)
#define MT6360_PMU_I2C_CTRL (0x10)
#define MT6360_PMU_CHG_CTRL1 (0x11)
#define MT6360_PMU_CHG_CTRL2 (0x12)
#define MT6360_PMU_CHG_CTRL3 (0x13)
#define MT6360_PMU_CHG_CTRL4 (0x14)
#define MT6360_PMU_CHG_CTRL5 (0x15)
#define MT6360_PMU_CHG_CTRL6 (0x16)
#define MT6360_PMU_CHG_CTRL7 (0x17)
#define MT6360_PMU_CHG_CTRL8 (0x18)
#define MT6360_PMU_CHG_CTRL9 (0x19)
#define MT6360_PMU_CHG_CTRL10 (0x1A)
#define MT6360_PMU_CHG_CTRL11 (0x1B)
#define MT6360_PMU_CHG_CTRL12 (0x1C)
#define MT6360_PMU_CHG_CTRL13 (0x1D)
#define MT6360_PMU_CHG_CTRL14 (0x1E)
#define MT6360_PMU_CHG_CTRL15 (0x1F)
#define MT6360_PMU_CHG_CTRL16 (0x20)
#define MT6360_PMU_CHG_AICC_RESULT (0x21)
#define MT6360_PMU_DEVICE_TYPE (0x22)
#define MT6360_PMU_QC_CONTROL1 (0x23)
#define MT6360_PMU_QC_CONTROL2 (0x24)
#define MT6360_PMU_QC30_CONTROL1 (0x25)
#define MT6360_PMU_QC30_CONTROL2 (0x26)
#define MT6360_PMU_USB_STATUS1 (0x27)
#define MT6360_PMU_QC_STATUS1 (0x28)
#define MT6360_PMU_QC_STATUS2 (0x29)
#define MT6360_PMU_CHG_PUMP (0x2A)
#define MT6360_PMU_CHG_CTRL17 (0x2B)
#define MT6360_PMU_CHG_CTRL18 (0x2C)
#define MT6360_PMU_CHRDET_CTRL1 (0x2D)
#define MT6360_PMU_CHRDET_CTRL2 (0x2E)
#define MT6360_PMU_DPDN_CTRL (0x2F)
#define MT6360_PMU_CHG_HIDDEN_CTRL1 (0x30)
#define MT6360_PMU_CHG_HIDDEN_CTRL2 (0x31)
#define MT6360_PMU_CHG_HIDDEN_CTRL3 (0x32)
#define MT6360_PMU_CHG_HIDDEN_CTRL4 (0x33)
#define MT6360_PMU_CHG_HIDDEN_CTRL5 (0x34)
#define MT6360_PMU_CHG_HIDDEN_CTRL6 (0x35)
#define MT6360_PMU_CHG_HIDDEN_CTRL7 (0x36)
#define MT6360_PMU_CHG_HIDDEN_CTRL8 (0x37)
#define MT6360_PMU_CHG_HIDDEN_CTRL9 (0x38)
#define MT6360_PMU_CHG_HIDDEN_CTRL10 (0x39)
#define MT6360_PMU_CHG_HIDDEN_CTRL11 (0x3A)
#define MT6360_PMU_CHG_HIDDEN_CTRL12 (0x3B)
#define MT6360_PMU_CHG_HIDDEN_CTRL13 (0x3C)
#define MT6360_PMU_CHG_HIDDEN_CTRL14 (0x3D)
#define MT6360_PMU_CHG_HIDDEN_CTRL15 (0x3E)
#define MT6360_PMU_CHG_HIDDEN_CTRL16 (0x3F)
#define MT6360_PMU_CHG_HIDDEN_CTRL17 (0x40)
#define MT6360_PMU_CHG_HIDDEN_CTRL18 (0x41)
#define MT6360_PMU_CHG_HIDDEN_CTRL19 (0x42)
#define MT6360_PMU_CHG_HIDDEN_CTRL20 (0x43)
#define MT6360_PMU_CHG_HIDDEN_CTRL21 (0x44)
#define MT6360_PMU_CHG_HIDDEN_CTRL22 (0x45)
#define MT6360_PMU_CHG_HIDDEN_CTRL23 (0x46)
#define MT6360_PMU_CHG_HIDDEN_CTRL24 (0x47)
#define MT6360_PMU_CHG_HIDDEN_CTRL25 (0x48)
#define MT6360_PMU_BC12_CTRL (0x49)
#define MT6360_PMU_CHG_STAT (0x4A)
#define MT6360_PMU_RESV1 (0x4B)
#define MT6360_PMU_TYPEC_OTP_TH_SEL_CODEH (0x4E)
#define MT6360_PMU_TYPEC_OTP_TH_SEL_CODEL (0x4F)
#define MT6360_PMU_TYPEC_OTP_HYST_TH (0x50)
#define MT6360_PMU_TYPEC_OTP_CTRL (0x51)
#define MT6360_PMU_ADC_BAT_DATA_H (0x52)
#define MT6360_PMU_ADC_BAT_DATA_L (0x53)
#define MT6360_PMU_IMID_BACKBST_ON (0x54)
#define MT6360_PMU_IMID_BACKBST_OFF (0x55)
#define MT6360_PMU_ADC_CONFIG (0x56)
#define MT6360_PMU_ADC_EN2 (0x57)
#define MT6360_PMU_ADC_IDLE_T (0x58)
#define MT6360_PMU_ADC_RPT_1 (0x5A)
#define MT6360_PMU_ADC_RPT_2 (0x5B)
#define MT6360_PMU_ADC_RPT_3 (0x5C)
#define MT6360_PMU_ADC_RPT_ORG1 (0x5D)
#define MT6360_PMU_ADC_RPT_ORG2 (0x5E)
#define MT6360_PMU_BAT_OVP_TH_SEL_CODEH (0x5F)
#define MT6360_PMU_BAT_OVP_TH_SEL_CODEL (0x60)
#define MT6360_PMU_CHG_CTRL19 (0x61)
#define MT6360_PMU_VDDASUPPLY (0x62)
#define MT6360_PMU_BC12_MANUAL (0x63)
#define MT6360_PMU_CHGDET_FUNC (0x64)
#define MT6360_PMU_FOD_CTRL (0x65)
#define MT6360_PMU_CHG_CTRL20 (0x66)
#define MT6360_PMU_CHG_HIDDEN_CTRL26 (0x67)
#define MT6360_PMU_CHG_HIDDEN_CTRL27 (0x68)
#define MT6360_PMU_RESV2 (0x69)
#define MT6360_PMU_USBID_CTRL1 (0x6D)
#define MT6360_PMU_USBID_CTRL2 (0x6E)
#define MT6360_PMU_USBID_CTRL3 (0x6F)
#define MT6360_PMU_FLED_CFG (0x70)
#define MT6360_PMU_RESV3 (0x71)
#define MT6360_PMU_FLED1_CTRL (0x72)
#define MT6360_PMU_FLED_STRB_CTRL (0x73)
#define MT6360_PMU_FLED1_STRB_CTRL2 (0x74)
#define MT6360_PMU_FLED1_TOR_CTRL (0x75)
#define MT6360_PMU_FLED2_CTRL (0x76)
#define MT6360_PMU_RESV4 (0x77)
#define MT6360_PMU_FLED2_STRB_CTRL2 (0x78)
#define MT6360_PMU_FLED2_TOR_CTRL (0x79)
#define MT6360_PMU_FLED_VMIDTRK_CTRL1 (0x7A)
#define MT6360_PMU_FLED_VMID_RTM (0x7B)
#define MT6360_PMU_FLED_VMIDTRK_CTRL2 (0x7C)
#define MT6360_PMU_FLED_PWSEL (0x7D)
#define MT6360_PMU_FLED_EN (0x7E)
#define MT6360_PMU_FLED_Hidden1 (0x7F)
#define MT6360_PMU_RGB_EN (0x80)
#define MT6360_PMU_RGB1_ISNK (0x81)
#define MT6360_PMU_RGB2_ISNK (0x82)
#define MT6360_PMU_RGB3_ISNK (0x83)
#define MT6360_PMU_RGB_ML_ISNK (0x84)
#define MT6360_PMU_RGB1_DIM (0x85)
#define MT6360_PMU_RGB2_DIM (0x86)
#define MT6360_PMU_RGB3_DIM (0x87)
#define MT6360_PMU_RESV5 (0x88)
#define MT6360_PMU_RGB12_Freq (0x89)
#define MT6360_PMU_RGB34_Freq (0x8A)
#define MT6360_PMU_RGB1_Tr (0x8B)
#define MT6360_PMU_RGB1_Tf (0x8C)
#define MT6360_PMU_RGB1_TON_TOFF (0x8D)
#define MT6360_PMU_RGB2_Tr (0x8E)
#define MT6360_PMU_RGB2_Tf (0x8F)
#define MT6360_PMU_RGB2_TON_TOFF (0x90)
#define MT6360_PMU_RGB3_Tr (0x91)
#define MT6360_PMU_RGB3_Tf (0x92)
#define MT6360_PMU_RGB3_TON_TOFF (0x93)
#define MT6360_PMU_RGB_Hidden_CTRL1 (0x94)
#define MT6360_PMU_RGB_Hidden_CTRL2 (0x95)
#define MT6360_PMU_RESV6 (0x97)
#define MT6360_PMU_SPARE1 (0x9A)
#define MT6360_PMU_SPARE2 (0xA0)
#define MT6360_PMU_SPARE3 (0xB0)
#define MT6360_PMU_SPARE4 (0xC0)
#define MT6360_PMU_CHG_IRQ1 (0xD0)
#define MT6360_PMU_CHG_IRQ2 (0xD1)
#define MT6360_PMU_CHG_IRQ3 (0xD2)
#define MT6360_PMU_CHG_IRQ4 (0xD3)
#define MT6360_PMU_CHG_IRQ5 (0xD4)
#define MT6360_PMU_CHG_IRQ6 (0xD5)
#define MT6360_PMU_QC_IRQ (0xD6)
#define MT6360_PMU_FOD_IRQ (0xD7)
#define MT6360_PMU_BASE_IRQ (0xD8)
#define MT6360_PMU_FLED_IRQ1 (0xD9)
#define MT6360_PMU_FLED_IRQ2 (0xDA)
#define MT6360_PMU_RGB_IRQ (0xDB)
#define MT6360_PMU_BUCK1_IRQ (0xDC)
#define MT6360_PMU_BUCK2_IRQ (0xDD)
#define MT6360_PMU_LDO_IRQ1 (0xDE)
#define MT6360_PMU_LDO_IRQ2 (0xDF)
#define MT6360_PMU_CHG_STAT1 (0xE0)
#define MT6360_PMU_CHG_STAT2 (0xE1)
#define MT6360_PMU_CHG_STAT3 (0xE2)
#define MT6360_PMU_CHG_STAT4 (0xE3)
#define MT6360_PMU_CHG_STAT5 (0xE4)
#define MT6360_PMU_CHG_STAT6 (0xE5)
#define MT6360_PMU_QC_STAT (0xE6)
#define MT6360_PMU_FOD_STAT (0xE7)
#define MT6360_PMU_BASE_STAT (0xE8)
#define MT6360_PMU_FLED_STAT1 (0xE9)
#define MT6360_PMU_FLED_STAT2 (0xEA)
#define MT6360_PMU_RGB_STAT (0xEB)
#define MT6360_PMU_BUCK1_STAT (0xEC)
#define MT6360_PMU_BUCK2_STAT (0xED)
#define MT6360_PMU_LDO_STAT1 (0xEE)
#define MT6360_PMU_LDO_STAT2 (0xEF)
#define MT6360_PMU_CHG_MASK1 (0xF0)
#define MT6360_PMU_CHG_MASK2 (0xF1)
#define MT6360_PMU_CHG_MASK3 (0xF2)
#define MT6360_PMU_CHG_MASK4 (0xF3)
#define MT6360_PMU_CHG_MASK5 (0xF4)
#define MT6360_PMU_CHG_MASK6 (0xF5)
#define MT6360_PMU_QC_MASK (0xF6)
#define MT6360_PMU_FOD_MASK (0xF7)
#define MT6360_PMU_BASE_MASK (0xF8)
#define MT6360_PMU_FLED_MASK1 (0xF9)
#define MT6360_PMU_FLED_MASK2 (0xFA)
#define MT6360_PMU_FAULTB_MASK (0xFB)
#define MT6360_PMU_BUCK1_MASK (0xFC)
#define MT6360_PMU_BUCK2_MASK (0xFD)
#define MT6360_PMU_LDO_MASK1 (0xFE)
#define MT6360_PMU_LDO_MASK2 (0xFF)
#define MT6360_PMU_MAXREG (MT6360_PMU_LDO_MASK2)
/* MT6360_PMU_IRQ_SET */
#define MT6360_PMU_IRQ_REGNUM (MT6360_PMU_LDO_IRQ2 - MT6360_PMU_CHG_IRQ1 + 1)
#define MT6360_IRQ_RETRIG BIT(2)
#define CHIP_VEN_MASK (0xF0)
#define CHIP_VEN_MT6360 (0x50)
#define CHIP_REV_MASK (0x0F)
#endif /* __MT6360_H__ */
...@@ -8,9 +8,11 @@ ...@@ -8,9 +8,11 @@
#define __MFD_MT6397_CORE_H__ #define __MFD_MT6397_CORE_H__
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/notifier.h>
enum chip_id { enum chip_id {
MT6323_CHIP_ID = 0x23, MT6323_CHIP_ID = 0x23,
MT6358_CHIP_ID = 0x58,
MT6391_CHIP_ID = 0x91, MT6391_CHIP_ID = 0x91,
MT6397_CHIP_ID = 0x97, MT6397_CHIP_ID = 0x97,
}; };
...@@ -54,6 +56,7 @@ enum mt6397_irq_numbers { ...@@ -54,6 +56,7 @@ enum mt6397_irq_numbers {
struct mt6397_chip { struct mt6397_chip {
struct device *dev; struct device *dev;
struct regmap *regmap; struct regmap *regmap;
struct notifier_block pm_nb;
int irq; int irq;
struct irq_domain *irq_domain; struct irq_domain *irq_domain;
struct mutex irqlock; struct mutex irqlock;
...@@ -63,8 +66,10 @@ struct mt6397_chip { ...@@ -63,8 +66,10 @@ struct mt6397_chip {
u16 int_con[2]; u16 int_con[2];
u16 int_status[2]; u16 int_status[2];
u16 chip_id; u16 chip_id;
void *irq_data;
}; };
int mt6358_irq_init(struct mt6397_chip *chip);
int mt6397_irq_init(struct mt6397_chip *chip); int mt6397_irq_init(struct mt6397_chip *chip);
#endif /* __MFD_MT6397_CORE_H__ */ #endif /* __MFD_MT6397_CORE_H__ */
...@@ -18,7 +18,9 @@ ...@@ -18,7 +18,9 @@
#define RTC_BBPU_CBUSY BIT(6) #define RTC_BBPU_CBUSY BIT(6)
#define RTC_BBPU_KEY (0x43 << 8) #define RTC_BBPU_KEY (0x43 << 8)
#define RTC_WRTGR 0x003c #define RTC_WRTGR_MT6358 0x003a
#define RTC_WRTGR_MT6397 0x003c
#define RTC_WRTGR_MT6323 RTC_WRTGR_MT6397
#define RTC_IRQ_STA 0x0002 #define RTC_IRQ_STA 0x0002
#define RTC_IRQ_STA_AL BIT(0) #define RTC_IRQ_STA_AL BIT(0)
...@@ -65,6 +67,10 @@ ...@@ -65,6 +67,10 @@
#define MTK_RTC_POLL_DELAY_US 10 #define MTK_RTC_POLL_DELAY_US 10
#define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ)) #define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ))
struct mtk_rtc_data {
u32 wrtgr;
};
struct mt6397_rtc { struct mt6397_rtc {
struct device *dev; struct device *dev;
struct rtc_device *rtc_dev; struct rtc_device *rtc_dev;
...@@ -74,6 +80,7 @@ struct mt6397_rtc { ...@@ -74,6 +80,7 @@ struct mt6397_rtc {
struct regmap *regmap; struct regmap *regmap;
int irq; int irq;
u32 addr_base; u32 addr_base;
const struct mtk_rtc_data *data;
}; };
#endif /* _LINUX_MFD_MT6397_RTC_H_ */ #endif /* _LINUX_MFD_MT6397_RTC_H_ */
...@@ -109,6 +109,7 @@ struct stmfx { ...@@ -109,6 +109,7 @@ struct stmfx {
struct device *dev; struct device *dev;
struct regmap *map; struct regmap *map;
struct regulator *vdd; struct regulator *vdd;
int irq;
struct irq_domain *irq_domain; struct irq_domain *irq_domain;
struct mutex lock; /* IRQ bus lock */ struct mutex lock; /* IRQ bus lock */
u8 irq_src; u8 irq_src;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment