Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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
...

+2630 -83
+8
Documentation/ABI/testing/sysfs-class-power-mp2629
··· 1 + What: /sys/class/power_supply/mp2629_battery/batt_impedance_compen 2 + Date: April 2020 3 + KernelVersion: 5.7 4 + Description: 5 + Represents a battery impedance compensation to accelerate charging. 6 + 7 + Access: Read, Write 8 + Valid values: Represented in milli-ohms. Valid range is [0, 140].
+62
Documentation/devicetree/bindings/mfd/mps,mp2629.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/mfd/mps,mp2629.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MP2629 Battery Charger PMIC from Monolithic Power System. 8 + 9 + maintainers: 10 + - Saravanan Sekar <sravanhome@gmail.com> 11 + 12 + description: | 13 + MP2629 is a PMIC providing battery charging and power supply for smartphones, 14 + wireless camera and portable devices. Chip is controlled over I2C. 15 + 16 + The battery charge management device handles battery charger controller and 17 + ADC IIO device for battery, system voltage 18 + 19 + properties: 20 + compatible: 21 + const: mps,mp2629 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + interrupts: 27 + maxItems: 1 28 + 29 + interrupt-controller: true 30 + 31 + "#interrupt-cells": 32 + const: 2 33 + description: 34 + The first cell is the IRQ number, the second cell is the trigger type. 35 + 36 + required: 37 + - compatible 38 + - reg 39 + - interrupts 40 + - interrupt-controller 41 + - "#interrupt-cells" 42 + 43 + additionalProperties: false 44 + 45 + examples: 46 + - | 47 + #include <dt-bindings/interrupt-controller/irq.h> 48 + #include <dt-bindings/input/linux-event-codes.h> 49 + i2c { 50 + #address-cells = <1>; 51 + #size-cells = <0>; 52 + 53 + pmic@4b { 54 + compatible = "mps,mp2629"; 55 + reg = <0x4b>; 56 + 57 + interrupt-controller; 58 + interrupt-parent = <&gpio2>; 59 + #interrupt-cells = <2>; 60 + interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; 61 + }; 62 + };
+15 -4
Documentation/devicetree/bindings/mfd/mt6397.txt
··· 18 18 This document describes the binding for MFD device and its sub module. 19 19 20 20 Required properties: 21 - compatible: "mediatek,mt6397" or "mediatek,mt6323" 21 + compatible: 22 + "mediatek,mt6323" for PMIC MT6323 23 + "mediatek,mt6358" for PMIC MT6358 24 + "mediatek,mt6397" for PMIC MT6397 22 25 23 26 Optional subnodes: 24 27 25 28 - rtc 26 29 Required properties: Should be one of follows 27 30 - compatible: "mediatek,mt6323-rtc" 31 + - compatible: "mediatek,mt6358-rtc" 28 32 - compatible: "mediatek,mt6397-rtc" 29 33 For details, see ../rtc/rtc-mt6397.txt 30 34 - regulators 31 35 Required properties: 32 - - compatible: "mediatek,mt6397-regulator" 33 - see ../regulator/mt6397-regulator.txt 34 36 - compatible: "mediatek,mt6323-regulator" 35 37 see ../regulator/mt6323-regulator.txt 38 + - compatible: "mediatek,mt6358-regulator" 39 + see ../regulator/mt6358-regulator.txt 40 + - compatible: "mediatek,mt6397-regulator" 41 + see ../regulator/mt6397-regulator.txt 36 42 - codec 37 43 Required properties: 38 - - compatible: "mediatek,mt6397-codec" 44 + - compatible: "mediatek,mt6397-codec" or "mediatek,mt6358-sound" 39 45 - clk 40 46 Required properties: 41 47 - compatible: "mediatek,mt6397-clk" ··· 59 53 Required properties: 60 54 - compatible: "mediatek,mt6323-pwrc" 61 55 For details, see ../power/reset/mt6323-poweroff.txt 56 + 57 + - pin-controller 58 + Required properties: 59 + - compatible: "mediatek,mt6397-pinctrl" 60 + For details, see ../pinctrl/pinctrl-mt65xx.txt 62 61 63 62 Example: 64 63 pwrap: pwrap@1000f000 {
+5
MAINTAINERS
··· 11474 11474 MONOLITHIC POWER SYSTEM PMIC DRIVER 11475 11475 M: Saravanan Sekar <sravanhome@gmail.com> 11476 11476 S: Maintained 11477 + F: Documentation/devicetree/bindings/mfd/mps,mp2629.yaml 11477 11478 F: Documentation/devicetree/bindings/regulator/mps,mp*.yaml 11479 + F: drivers/iio/adc/mp2629_adc.c 11480 + F: drivers/mfd/mp2629.c 11481 + F: drivers/power/supply/mp2629_charger.c 11478 11482 F: drivers/regulator/mp5416.c 11479 11483 F: drivers/regulator/mpq7920.c 11480 11484 F: drivers/regulator/mpq7920.h 11485 + F: include/linux/mfd/mp2629.h 11481 11486 11482 11487 MOTION EYE VAIO PICTUREBOOK CAMERA DRIVER 11483 11488 S: Orphan
+10
drivers/iio/adc/Kconfig
··· 692 692 To compile this driver as a module, choose M here: the 693 693 module will be called meson_saradc. 694 694 695 + config MP2629_ADC 696 + tristate "Monolithic MP2629 ADC driver" 697 + depends on MFD_MP2629 698 + help 699 + Say yes to have support for battery charger IC MP2629 ADC device 700 + accessed over I2C. 701 + 702 + This driver provides ADC conversion of system, input power supply 703 + and battery voltage & current information. 704 + 695 705 config NAU7802 696 706 tristate "Nuvoton NAU7802 ADC driver" 697 707 depends on I2C
+1
drivers/iio/adc/Makefile
··· 65 65 obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o 66 66 obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o 67 67 obj-$(CONFIG_MESON_SARADC) += meson_saradc.o 68 + obj-$(CONFIG_MP2629_ADC) += mp2629_adc.o 68 69 obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o 69 70 obj-$(CONFIG_NAU7802) += nau7802.o 70 71 obj-$(CONFIG_NPCM_ADC) += npcm_adc.o
+208
drivers/iio/adc/mp2629_adc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * MP2629 Driver for ADC 4 + * 5 + * Copyright 2020 Monolithic Power Systems, Inc 6 + * 7 + * Author: Saravanan Sekar <sravanhome@gmail.com> 8 + */ 9 + 10 + #include <linux/iio/driver.h> 11 + #include <linux/iio/iio.h> 12 + #include <linux/iio/machine.h> 13 + #include <linux/mfd/mp2629.h> 14 + #include <linux/module.h> 15 + #include <linux/mutex.h> 16 + #include <linux/platform_device.h> 17 + #include <linux/regmap.h> 18 + 19 + #define MP2629_REG_ADC_CTRL 0x03 20 + #define MP2629_REG_BATT_VOLT 0x0e 21 + #define MP2629_REG_SYSTEM_VOLT 0x0f 22 + #define MP2629_REG_INPUT_VOLT 0x11 23 + #define MP2629_REG_BATT_CURRENT 0x12 24 + #define MP2629_REG_INPUT_CURRENT 0x13 25 + 26 + #define MP2629_ADC_START BIT(7) 27 + #define MP2629_ADC_CONTINUOUS BIT(6) 28 + 29 + #define MP2629_MAP(_mp, _mpc) IIO_MAP(#_mp, "mp2629_charger", "mp2629-"_mpc) 30 + 31 + #define MP2629_ADC_CHAN(_ch, _type) { \ 32 + .type = _type, \ 33 + .indexed = 1, \ 34 + .datasheet_name = #_ch, \ 35 + .channel = MP2629_ ## _ch, \ 36 + .address = MP2629_REG_ ## _ch, \ 37 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 38 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 39 + } 40 + 41 + struct mp2629_adc { 42 + struct regmap *regmap; 43 + struct device *dev; 44 + }; 45 + 46 + static struct iio_chan_spec mp2629_channels[] = { 47 + MP2629_ADC_CHAN(BATT_VOLT, IIO_VOLTAGE), 48 + MP2629_ADC_CHAN(SYSTEM_VOLT, IIO_VOLTAGE), 49 + MP2629_ADC_CHAN(INPUT_VOLT, IIO_VOLTAGE), 50 + MP2629_ADC_CHAN(BATT_CURRENT, IIO_CURRENT), 51 + MP2629_ADC_CHAN(INPUT_CURRENT, IIO_CURRENT) 52 + }; 53 + 54 + static struct iio_map mp2629_adc_maps[] = { 55 + MP2629_MAP(BATT_VOLT, "batt-volt"), 56 + MP2629_MAP(SYSTEM_VOLT, "system-volt"), 57 + MP2629_MAP(INPUT_VOLT, "input-volt"), 58 + MP2629_MAP(BATT_CURRENT, "batt-current"), 59 + MP2629_MAP(INPUT_CURRENT, "input-current") 60 + }; 61 + 62 + static int mp2629_read_raw(struct iio_dev *indio_dev, 63 + struct iio_chan_spec const *chan, 64 + int *val, int *val2, long mask) 65 + { 66 + struct mp2629_adc *info = iio_priv(indio_dev); 67 + unsigned int rval; 68 + int ret; 69 + 70 + switch (mask) { 71 + case IIO_CHAN_INFO_RAW: 72 + ret = regmap_read(info->regmap, chan->address, &rval); 73 + if (ret) 74 + return ret; 75 + 76 + if (chan->address == MP2629_INPUT_VOLT) 77 + rval &= GENMASK(6, 0); 78 + *val = rval; 79 + return IIO_VAL_INT; 80 + 81 + case IIO_CHAN_INFO_SCALE: 82 + switch (chan->channel) { 83 + case MP2629_BATT_VOLT: 84 + case MP2629_SYSTEM_VOLT: 85 + *val = 20; 86 + return IIO_VAL_INT; 87 + 88 + case MP2629_INPUT_VOLT: 89 + *val = 60; 90 + return IIO_VAL_INT; 91 + 92 + case MP2629_BATT_CURRENT: 93 + *val = 175; 94 + *val2 = 10; 95 + return IIO_VAL_FRACTIONAL; 96 + 97 + case MP2629_INPUT_CURRENT: 98 + *val = 133; 99 + *val2 = 10; 100 + return IIO_VAL_FRACTIONAL; 101 + 102 + default: 103 + return -EINVAL; 104 + } 105 + 106 + default: 107 + return -EINVAL; 108 + } 109 + } 110 + 111 + static const struct iio_info mp2629_adc_info = { 112 + .read_raw = &mp2629_read_raw, 113 + }; 114 + 115 + static int mp2629_adc_probe(struct platform_device *pdev) 116 + { 117 + struct device *dev = &pdev->dev; 118 + struct mp2629_data *ddata = dev_get_drvdata(dev->parent); 119 + struct mp2629_adc *info; 120 + struct iio_dev *indio_dev; 121 + int ret; 122 + 123 + indio_dev = devm_iio_device_alloc(dev, sizeof(*info)); 124 + if (!indio_dev) 125 + return -ENOMEM; 126 + 127 + info = iio_priv(indio_dev); 128 + info->regmap = ddata->regmap; 129 + info->dev = dev; 130 + platform_set_drvdata(pdev, indio_dev); 131 + 132 + ret = regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL, 133 + MP2629_ADC_START | MP2629_ADC_CONTINUOUS, 134 + MP2629_ADC_START | MP2629_ADC_CONTINUOUS); 135 + if (ret) { 136 + dev_err(dev, "adc enable fail: %d\n", ret); 137 + return ret; 138 + } 139 + 140 + ret = iio_map_array_register(indio_dev, mp2629_adc_maps); 141 + if (ret) { 142 + dev_err(dev, "IIO maps register fail: %d\n", ret); 143 + goto fail_disable; 144 + } 145 + 146 + indio_dev->name = "mp2629-adc"; 147 + indio_dev->dev.parent = dev; 148 + indio_dev->channels = mp2629_channels; 149 + indio_dev->num_channels = ARRAY_SIZE(mp2629_channels); 150 + indio_dev->modes = INDIO_DIRECT_MODE; 151 + indio_dev->info = &mp2629_adc_info; 152 + 153 + ret = iio_device_register(indio_dev); 154 + if (ret) { 155 + dev_err(dev, "IIO device register fail: %d\n", ret); 156 + goto fail_map_unregister; 157 + } 158 + 159 + return 0; 160 + 161 + fail_map_unregister: 162 + iio_map_array_unregister(indio_dev); 163 + 164 + fail_disable: 165 + regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL, 166 + MP2629_ADC_CONTINUOUS, 0); 167 + regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL, 168 + MP2629_ADC_START, 0); 169 + 170 + return ret; 171 + } 172 + 173 + static int mp2629_adc_remove(struct platform_device *pdev) 174 + { 175 + struct iio_dev *indio_dev = platform_get_drvdata(pdev); 176 + struct mp2629_adc *info = iio_priv(indio_dev); 177 + 178 + iio_device_unregister(indio_dev); 179 + 180 + iio_map_array_unregister(indio_dev); 181 + 182 + regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL, 183 + MP2629_ADC_CONTINUOUS, 0); 184 + regmap_update_bits(info->regmap, MP2629_REG_ADC_CTRL, 185 + MP2629_ADC_START, 0); 186 + 187 + return 0; 188 + } 189 + 190 + static const struct of_device_id mp2629_adc_of_match[] = { 191 + { .compatible = "mps,mp2629_adc"}, 192 + {} 193 + }; 194 + MODULE_DEVICE_TABLE(of, mp2629_adc_of_match); 195 + 196 + static struct platform_driver mp2629_adc_driver = { 197 + .driver = { 198 + .name = "mp2629_adc", 199 + .of_match_table = mp2629_adc_of_match, 200 + }, 201 + .probe = mp2629_adc_probe, 202 + .remove = mp2629_adc_remove, 203 + }; 204 + module_platform_driver(mp2629_adc_driver); 205 + 206 + MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>"); 207 + MODULE_DESCRIPTION("MP2629 ADC driver"); 208 + MODULE_LICENSE("GPL");
+21
drivers/mfd/Kconfig
··· 449 449 help 450 450 Select this if your MC13xxx is connected via an I2C bus. 451 451 452 + config MFD_MP2629 453 + tristate "Monolithic Power Systems MP2629 ADC and Battery charger" 454 + depends on I2C 455 + select REGMAP_I2C 456 + help 457 + Select this option to enable support for Monolithic Power Systems 458 + battery charger. This provides ADC, thermal and battery charger power 459 + management functions. 460 + 452 461 config MFD_MXS_LRADC 453 462 tristate "Freescale i.MX23/i.MX28 LRADC" 454 463 depends on ARCH_MXS || COMPILE_TEST ··· 907 898 This driver provides common support for accessing the device, 908 899 additional drivers must be enabled in order to use the functionality 909 900 of the device. 901 + 902 + config MFD_MT6360 903 + tristate "Mediatek MT6360 SubPMIC" 904 + select MFD_CORE 905 + select REGMAP_I2C 906 + select REGMAP_IRQ 907 + depends on I2C 908 + help 909 + Say Y here to enable MT6360 PMU/PMIC/LDO functional support. 910 + PMU part includes Charger, Flashlight, RGB LED 911 + PMIC part includes 2-channel BUCKs and 2-channel LDOs 912 + LDO part includes 4-channel LDOs 910 913 911 914 config MFD_MT6397 912 915 tristate "MediaTek MT6397 PMIC Support"
+4 -1
drivers/mfd/Makefile
··· 171 171 obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o 172 172 obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o 173 173 174 + obj-$(CONFIG_MFD_MP2629) += mp2629.o 175 + 174 176 pcf50633-objs := pcf50633-core.o pcf50633-irq.o 175 177 obj-$(CONFIG_MFD_PCF50633) += pcf50633.o 176 178 obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o ··· 243 241 obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o 244 242 obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o 245 243 obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o 246 - mt6397-objs := mt6397-core.o mt6397-irq.o 244 + obj-$(CONFIG_MFD_MT6360) += mt6360-core.o 245 + mt6397-objs := mt6397-core.o mt6397-irq.o mt6358-irq.o 247 246 obj-$(CONFIG_MFD_MT6397) += mt6397.o 248 247 obj-$(CONFIG_INTEL_SOC_PMIC_MRFLD) += intel_soc_pmic_mrfld.o 249 248
+3 -3
drivers/mfd/htc-i2cpld.c
··· 355 355 info.platform_data = chip; 356 356 357 357 /* Add the I2C device. This calls the probe() function. */ 358 - client = i2c_new_device(adapter, &info); 359 - if (!client) { 358 + client = i2c_new_client_device(adapter, &info); 359 + if (IS_ERR(client)) { 360 360 /* I2C device registration failed, contineu with the next */ 361 361 dev_warn(dev, "Unable to add I2C device for 0x%x\n", 362 362 plat_chip_data->addr); 363 - return -ENODEV; 363 + return PTR_ERR(client); 364 364 } 365 365 366 366 i2c_set_clientdata(client, chip);
+1 -1
drivers/mfd/intel-lpss-pci.c
··· 250 250 { PCI_VDEVICE(INTEL, 0x4da9), (kernel_ulong_t)&spt_uart_info }, 251 251 { PCI_VDEVICE(INTEL, 0x4daa), (kernel_ulong_t)&spt_info }, 252 252 { PCI_VDEVICE(INTEL, 0x4dab), (kernel_ulong_t)&spt_info }, 253 - { PCI_VDEVICE(INTEL, 0x4daf), (kernel_ulong_t)&spt_uart_info }, 254 253 { PCI_VDEVICE(INTEL, 0x4dc5), (kernel_ulong_t)&bxt_i2c_info }, 255 254 { PCI_VDEVICE(INTEL, 0x4dc6), (kernel_ulong_t)&bxt_i2c_info }, 255 + { PCI_VDEVICE(INTEL, 0x4dc7), (kernel_ulong_t)&spt_uart_info }, 256 256 { PCI_VDEVICE(INTEL, 0x4de8), (kernel_ulong_t)&bxt_i2c_info }, 257 257 { PCI_VDEVICE(INTEL, 0x4de9), (kernel_ulong_t)&bxt_i2c_info }, 258 258 { PCI_VDEVICE(INTEL, 0x4dea), (kernel_ulong_t)&bxt_i2c_info },
+1
drivers/mfd/max77620.c
··· 177 177 .rd_table = &max77620_readable_table, 178 178 .wr_table = &max77620_writable_table, 179 179 .volatile_table = &max77620_volatile_table, 180 + .use_single_write = true, 180 181 }; 181 182 182 183 static const struct regmap_config max20024_regmap_config = {
+79
drivers/mfd/mp2629.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * MP2629 parent driver for ADC and battery charger 4 + * 5 + * Copyright 2020 Monolithic Power Systems, Inc 6 + * 7 + * Author: Saravanan Sekar <sravanhome@gmail.com> 8 + */ 9 + 10 + #include <linux/i2c.h> 11 + #include <linux/kernel.h> 12 + #include <linux/mfd/core.h> 13 + #include <linux/mfd/mp2629.h> 14 + #include <linux/module.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/regmap.h> 17 + #include <linux/slab.h> 18 + 19 + static const struct mfd_cell mp2629_cell[] = { 20 + { 21 + .name = "mp2629_adc", 22 + .of_compatible = "mps,mp2629_adc", 23 + }, 24 + { 25 + .name = "mp2629_charger", 26 + .of_compatible = "mps,mp2629_charger", 27 + } 28 + }; 29 + 30 + static const struct regmap_config mp2629_regmap_config = { 31 + .reg_bits = 8, 32 + .val_bits = 8, 33 + .max_register = 0x17, 34 + }; 35 + 36 + static int mp2629_probe(struct i2c_client *client) 37 + { 38 + struct mp2629_data *ddata; 39 + int ret; 40 + 41 + ddata = devm_kzalloc(&client->dev, sizeof(*ddata), GFP_KERNEL); 42 + if (!ddata) 43 + return -ENOMEM; 44 + 45 + ddata->dev = &client->dev; 46 + i2c_set_clientdata(client, ddata); 47 + 48 + ddata->regmap = devm_regmap_init_i2c(client, &mp2629_regmap_config); 49 + if (IS_ERR(ddata->regmap)) { 50 + dev_err(ddata->dev, "Failed to allocate regmap\n"); 51 + return PTR_ERR(ddata->regmap); 52 + } 53 + 54 + ret = devm_mfd_add_devices(ddata->dev, PLATFORM_DEVID_AUTO, mp2629_cell, 55 + ARRAY_SIZE(mp2629_cell), NULL, 0, NULL); 56 + if (ret) 57 + dev_err(ddata->dev, "Failed to register sub-devices %d\n", ret); 58 + 59 + return ret; 60 + } 61 + 62 + static const struct of_device_id mp2629_of_match[] = { 63 + { .compatible = "mps,mp2629"}, 64 + { } 65 + }; 66 + MODULE_DEVICE_TABLE(of, mp2629_of_match); 67 + 68 + static struct i2c_driver mp2629_driver = { 69 + .driver = { 70 + .name = "mp2629", 71 + .of_match_table = mp2629_of_match, 72 + }, 73 + .probe_new = mp2629_probe, 74 + }; 75 + module_i2c_driver(mp2629_driver); 76 + 77 + MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>"); 78 + MODULE_DESCRIPTION("MP2629 Battery charger parent driver"); 79 + MODULE_LICENSE("GPL");
+235
drivers/mfd/mt6358-irq.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // Copyright (c) 2020 MediaTek Inc. 4 + 5 + #include <linux/interrupt.h> 6 + #include <linux/mfd/mt6358/core.h> 7 + #include <linux/mfd/mt6358/registers.h> 8 + #include <linux/mfd/mt6397/core.h> 9 + #include <linux/module.h> 10 + #include <linux/of.h> 11 + #include <linux/of_device.h> 12 + #include <linux/of_irq.h> 13 + #include <linux/platform_device.h> 14 + #include <linux/regmap.h> 15 + 16 + static struct irq_top_t mt6358_ints[] = { 17 + MT6358_TOP_GEN(BUCK), 18 + MT6358_TOP_GEN(LDO), 19 + MT6358_TOP_GEN(PSC), 20 + MT6358_TOP_GEN(SCK), 21 + MT6358_TOP_GEN(BM), 22 + MT6358_TOP_GEN(HK), 23 + MT6358_TOP_GEN(AUD), 24 + MT6358_TOP_GEN(MISC), 25 + }; 26 + 27 + static void pmic_irq_enable(struct irq_data *data) 28 + { 29 + unsigned int hwirq = irqd_to_hwirq(data); 30 + struct mt6397_chip *chip = irq_data_get_irq_chip_data(data); 31 + struct pmic_irq_data *irqd = chip->irq_data; 32 + 33 + irqd->enable_hwirq[hwirq] = true; 34 + } 35 + 36 + static void pmic_irq_disable(struct irq_data *data) 37 + { 38 + unsigned int hwirq = irqd_to_hwirq(data); 39 + struct mt6397_chip *chip = irq_data_get_irq_chip_data(data); 40 + struct pmic_irq_data *irqd = chip->irq_data; 41 + 42 + irqd->enable_hwirq[hwirq] = false; 43 + } 44 + 45 + static void pmic_irq_lock(struct irq_data *data) 46 + { 47 + struct mt6397_chip *chip = irq_data_get_irq_chip_data(data); 48 + 49 + mutex_lock(&chip->irqlock); 50 + } 51 + 52 + static void pmic_irq_sync_unlock(struct irq_data *data) 53 + { 54 + unsigned int i, top_gp, gp_offset, en_reg, int_regs, shift; 55 + struct mt6397_chip *chip = irq_data_get_irq_chip_data(data); 56 + struct pmic_irq_data *irqd = chip->irq_data; 57 + 58 + for (i = 0; i < irqd->num_pmic_irqs; i++) { 59 + if (irqd->enable_hwirq[i] == irqd->cache_hwirq[i]) 60 + continue; 61 + 62 + /* Find out the IRQ group */ 63 + top_gp = 0; 64 + while ((top_gp + 1) < irqd->num_top && 65 + i >= mt6358_ints[top_gp + 1].hwirq_base) 66 + top_gp++; 67 + 68 + /* Find the IRQ registers */ 69 + gp_offset = i - mt6358_ints[top_gp].hwirq_base; 70 + int_regs = gp_offset / MT6358_REG_WIDTH; 71 + shift = gp_offset % MT6358_REG_WIDTH; 72 + en_reg = mt6358_ints[top_gp].en_reg + 73 + (mt6358_ints[top_gp].en_reg_shift * int_regs); 74 + 75 + regmap_update_bits(chip->regmap, en_reg, BIT(shift), 76 + irqd->enable_hwirq[i] << shift); 77 + 78 + irqd->cache_hwirq[i] = irqd->enable_hwirq[i]; 79 + } 80 + mutex_unlock(&chip->irqlock); 81 + } 82 + 83 + static struct irq_chip mt6358_irq_chip = { 84 + .name = "mt6358-irq", 85 + .flags = IRQCHIP_SKIP_SET_WAKE, 86 + .irq_enable = pmic_irq_enable, 87 + .irq_disable = pmic_irq_disable, 88 + .irq_bus_lock = pmic_irq_lock, 89 + .irq_bus_sync_unlock = pmic_irq_sync_unlock, 90 + }; 91 + 92 + static void mt6358_irq_sp_handler(struct mt6397_chip *chip, 93 + unsigned int top_gp) 94 + { 95 + unsigned int irq_status, sta_reg, status; 96 + unsigned int hwirq, virq; 97 + int i, j, ret; 98 + 99 + for (i = 0; i < mt6358_ints[top_gp].num_int_regs; i++) { 100 + sta_reg = mt6358_ints[top_gp].sta_reg + 101 + mt6358_ints[top_gp].sta_reg_shift * i; 102 + 103 + ret = regmap_read(chip->regmap, sta_reg, &irq_status); 104 + if (ret) { 105 + dev_err(chip->dev, 106 + "Failed to read IRQ status, ret=%d\n", ret); 107 + return; 108 + } 109 + 110 + if (!irq_status) 111 + continue; 112 + 113 + status = irq_status; 114 + do { 115 + j = __ffs(status); 116 + 117 + hwirq = mt6358_ints[top_gp].hwirq_base + 118 + MT6358_REG_WIDTH * i + j; 119 + 120 + virq = irq_find_mapping(chip->irq_domain, hwirq); 121 + if (virq) 122 + handle_nested_irq(virq); 123 + 124 + status &= ~BIT(j); 125 + } while (status); 126 + 127 + regmap_write(chip->regmap, sta_reg, irq_status); 128 + } 129 + } 130 + 131 + static irqreturn_t mt6358_irq_handler(int irq, void *data) 132 + { 133 + struct mt6397_chip *chip = data; 134 + struct pmic_irq_data *mt6358_irq_data = chip->irq_data; 135 + unsigned int bit, i, top_irq_status = 0; 136 + int ret; 137 + 138 + ret = regmap_read(chip->regmap, 139 + mt6358_irq_data->top_int_status_reg, 140 + &top_irq_status); 141 + if (ret) { 142 + dev_err(chip->dev, 143 + "Failed to read status from the device, ret=%d\n", ret); 144 + return IRQ_NONE; 145 + } 146 + 147 + for (i = 0; i < mt6358_irq_data->num_top; i++) { 148 + bit = BIT(mt6358_ints[i].top_offset); 149 + if (top_irq_status & bit) { 150 + mt6358_irq_sp_handler(chip, i); 151 + top_irq_status &= ~bit; 152 + if (!top_irq_status) 153 + break; 154 + } 155 + } 156 + 157 + return IRQ_HANDLED; 158 + } 159 + 160 + static int pmic_irq_domain_map(struct irq_domain *d, unsigned int irq, 161 + irq_hw_number_t hw) 162 + { 163 + struct mt6397_chip *mt6397 = d->host_data; 164 + 165 + irq_set_chip_data(irq, mt6397); 166 + irq_set_chip_and_handler(irq, &mt6358_irq_chip, handle_level_irq); 167 + irq_set_nested_thread(irq, 1); 168 + irq_set_noprobe(irq); 169 + 170 + return 0; 171 + } 172 + 173 + static const struct irq_domain_ops mt6358_irq_domain_ops = { 174 + .map = pmic_irq_domain_map, 175 + .xlate = irq_domain_xlate_twocell, 176 + }; 177 + 178 + int mt6358_irq_init(struct mt6397_chip *chip) 179 + { 180 + int i, j, ret; 181 + struct pmic_irq_data *irqd; 182 + 183 + irqd = devm_kzalloc(chip->dev, sizeof(*irqd), GFP_KERNEL); 184 + if (!irqd) 185 + return -ENOMEM; 186 + 187 + chip->irq_data = irqd; 188 + 189 + mutex_init(&chip->irqlock); 190 + irqd->top_int_status_reg = MT6358_TOP_INT_STATUS0; 191 + irqd->num_pmic_irqs = MT6358_IRQ_NR; 192 + irqd->num_top = ARRAY_SIZE(mt6358_ints); 193 + 194 + irqd->enable_hwirq = devm_kcalloc(chip->dev, 195 + irqd->num_pmic_irqs, 196 + sizeof(*irqd->enable_hwirq), 197 + GFP_KERNEL); 198 + if (!irqd->enable_hwirq) 199 + return -ENOMEM; 200 + 201 + irqd->cache_hwirq = devm_kcalloc(chip->dev, 202 + irqd->num_pmic_irqs, 203 + sizeof(*irqd->cache_hwirq), 204 + GFP_KERNEL); 205 + if (!irqd->cache_hwirq) 206 + return -ENOMEM; 207 + 208 + /* Disable all interrupts for initializing */ 209 + for (i = 0; i < irqd->num_top; i++) { 210 + for (j = 0; j < mt6358_ints[i].num_int_regs; j++) 211 + regmap_write(chip->regmap, 212 + mt6358_ints[i].en_reg + 213 + mt6358_ints[i].en_reg_shift * j, 0); 214 + } 215 + 216 + chip->irq_domain = irq_domain_add_linear(chip->dev->of_node, 217 + irqd->num_pmic_irqs, 218 + &mt6358_irq_domain_ops, chip); 219 + if (!chip->irq_domain) { 220 + dev_err(chip->dev, "Could not create IRQ domain\n"); 221 + return -ENODEV; 222 + } 223 + 224 + ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL, 225 + mt6358_irq_handler, IRQF_ONESHOT, 226 + mt6358_irq_chip.name, chip); 227 + if (ret) { 228 + dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n", 229 + chip->irq, ret); 230 + return ret; 231 + } 232 + 233 + enable_irq_wake(chip->irq); 234 + return ret; 235 + }
+424
drivers/mfd/mt6360-core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (c) 2020 MediaTek Inc. 4 + * 5 + * Author: Gene Chen <gene_chen@richtek.com> 6 + */ 7 + 8 + #include <linux/i2c.h> 9 + #include <linux/init.h> 10 + #include <linux/interrupt.h> 11 + #include <linux/kernel.h> 12 + #include <linux/mfd/core.h> 13 + #include <linux/module.h> 14 + #include <linux/of_irq.h> 15 + #include <linux/of_platform.h> 16 + #include <linux/version.h> 17 + 18 + #include <linux/mfd/mt6360.h> 19 + 20 + /* reg 0 -> 0 ~ 7 */ 21 + #define MT6360_CHG_TREG_EVT (4) 22 + #define MT6360_CHG_AICR_EVT (5) 23 + #define MT6360_CHG_MIVR_EVT (6) 24 + #define MT6360_PWR_RDY_EVT (7) 25 + /* REG 1 -> 8 ~ 15 */ 26 + #define MT6360_CHG_BATSYSUV_EVT (9) 27 + #define MT6360_FLED_CHG_VINOVP_EVT (11) 28 + #define MT6360_CHG_VSYSUV_EVT (12) 29 + #define MT6360_CHG_VSYSOV_EVT (13) 30 + #define MT6360_CHG_VBATOV_EVT (14) 31 + #define MT6360_CHG_VBUSOV_EVT (15) 32 + /* REG 2 -> 16 ~ 23 */ 33 + /* REG 3 -> 24 ~ 31 */ 34 + #define MT6360_WD_PMU_DET (25) 35 + #define MT6360_WD_PMU_DONE (26) 36 + #define MT6360_CHG_TMRI (27) 37 + #define MT6360_CHG_ADPBADI (29) 38 + #define MT6360_CHG_RVPI (30) 39 + #define MT6360_OTPI (31) 40 + /* REG 4 -> 32 ~ 39 */ 41 + #define MT6360_CHG_AICCMEASL (32) 42 + #define MT6360_CHGDET_DONEI (34) 43 + #define MT6360_WDTMRI (35) 44 + #define MT6360_SSFINISHI (36) 45 + #define MT6360_CHG_RECHGI (37) 46 + #define MT6360_CHG_TERMI (38) 47 + #define MT6360_CHG_IEOCI (39) 48 + /* REG 5 -> 40 ~ 47 */ 49 + #define MT6360_PUMPX_DONEI (40) 50 + #define MT6360_BAT_OVP_ADC_EVT (41) 51 + #define MT6360_TYPEC_OTP_EVT (42) 52 + #define MT6360_ADC_WAKEUP_EVT (43) 53 + #define MT6360_ADC_DONEI (44) 54 + #define MT6360_BST_BATUVI (45) 55 + #define MT6360_BST_VBUSOVI (46) 56 + #define MT6360_BST_OLPI (47) 57 + /* REG 6 -> 48 ~ 55 */ 58 + #define MT6360_ATTACH_I (48) 59 + #define MT6360_DETACH_I (49) 60 + #define MT6360_QC30_STPDONE (51) 61 + #define MT6360_QC_VBUSDET_DONE (52) 62 + #define MT6360_HVDCP_DET (53) 63 + #define MT6360_CHGDETI (54) 64 + #define MT6360_DCDTI (55) 65 + /* REG 7 -> 56 ~ 63 */ 66 + #define MT6360_FOD_DONE_EVT (56) 67 + #define MT6360_FOD_OV_EVT (57) 68 + #define MT6360_CHRDET_UVP_EVT (58) 69 + #define MT6360_CHRDET_OVP_EVT (59) 70 + #define MT6360_CHRDET_EXT_EVT (60) 71 + #define MT6360_FOD_LR_EVT (61) 72 + #define MT6360_FOD_HR_EVT (62) 73 + #define MT6360_FOD_DISCHG_FAIL_EVT (63) 74 + /* REG 8 -> 64 ~ 71 */ 75 + #define MT6360_USBID_EVT (64) 76 + #define MT6360_APWDTRST_EVT (65) 77 + #define MT6360_EN_EVT (66) 78 + #define MT6360_QONB_RST_EVT (67) 79 + #define MT6360_MRSTB_EVT (68) 80 + #define MT6360_OTP_EVT (69) 81 + #define MT6360_VDDAOV_EVT (70) 82 + #define MT6360_SYSUV_EVT (71) 83 + /* REG 9 -> 72 ~ 79 */ 84 + #define MT6360_FLED_STRBPIN_EVT (72) 85 + #define MT6360_FLED_TORPIN_EVT (73) 86 + #define MT6360_FLED_TX_EVT (74) 87 + #define MT6360_FLED_LVF_EVT (75) 88 + #define MT6360_FLED2_SHORT_EVT (78) 89 + #define MT6360_FLED1_SHORT_EVT (79) 90 + /* REG 10 -> 80 ~ 87 */ 91 + #define MT6360_FLED2_STRB_EVT (80) 92 + #define MT6360_FLED1_STRB_EVT (81) 93 + #define MT6360_FLED2_STRB_TO_EVT (82) 94 + #define MT6360_FLED1_STRB_TO_EVT (83) 95 + #define MT6360_FLED2_TOR_EVT (84) 96 + #define MT6360_FLED1_TOR_EVT (85) 97 + /* REG 11 -> 88 ~ 95 */ 98 + /* REG 12 -> 96 ~ 103 */ 99 + #define MT6360_BUCK1_PGB_EVT (96) 100 + #define MT6360_BUCK1_OC_EVT (100) 101 + #define MT6360_BUCK1_OV_EVT (101) 102 + #define MT6360_BUCK1_UV_EVT (102) 103 + /* REG 13 -> 104 ~ 111 */ 104 + #define MT6360_BUCK2_PGB_EVT (104) 105 + #define MT6360_BUCK2_OC_EVT (108) 106 + #define MT6360_BUCK2_OV_EVT (109) 107 + #define MT6360_BUCK2_UV_EVT (110) 108 + /* REG 14 -> 112 ~ 119 */ 109 + #define MT6360_LDO1_OC_EVT (113) 110 + #define MT6360_LDO2_OC_EVT (114) 111 + #define MT6360_LDO3_OC_EVT (115) 112 + #define MT6360_LDO5_OC_EVT (117) 113 + #define MT6360_LDO6_OC_EVT (118) 114 + #define MT6360_LDO7_OC_EVT (119) 115 + /* REG 15 -> 120 ~ 127 */ 116 + #define MT6360_LDO1_PGB_EVT (121) 117 + #define MT6360_LDO2_PGB_EVT (122) 118 + #define MT6360_LDO3_PGB_EVT (123) 119 + #define MT6360_LDO5_PGB_EVT (125) 120 + #define MT6360_LDO6_PGB_EVT (126) 121 + #define MT6360_LDO7_PGB_EVT (127) 122 + 123 + static const struct regmap_irq mt6360_pmu_irqs[] = { 124 + REGMAP_IRQ_REG_LINE(MT6360_CHG_TREG_EVT, 8), 125 + REGMAP_IRQ_REG_LINE(MT6360_CHG_AICR_EVT, 8), 126 + REGMAP_IRQ_REG_LINE(MT6360_CHG_MIVR_EVT, 8), 127 + REGMAP_IRQ_REG_LINE(MT6360_PWR_RDY_EVT, 8), 128 + REGMAP_IRQ_REG_LINE(MT6360_CHG_BATSYSUV_EVT, 8), 129 + REGMAP_IRQ_REG_LINE(MT6360_FLED_CHG_VINOVP_EVT, 8), 130 + REGMAP_IRQ_REG_LINE(MT6360_CHG_VSYSUV_EVT, 8), 131 + REGMAP_IRQ_REG_LINE(MT6360_CHG_VSYSOV_EVT, 8), 132 + REGMAP_IRQ_REG_LINE(MT6360_CHG_VBATOV_EVT, 8), 133 + REGMAP_IRQ_REG_LINE(MT6360_CHG_VBUSOV_EVT, 8), 134 + REGMAP_IRQ_REG_LINE(MT6360_WD_PMU_DET, 8), 135 + REGMAP_IRQ_REG_LINE(MT6360_WD_PMU_DONE, 8), 136 + REGMAP_IRQ_REG_LINE(MT6360_CHG_TMRI, 8), 137 + REGMAP_IRQ_REG_LINE(MT6360_CHG_ADPBADI, 8), 138 + REGMAP_IRQ_REG_LINE(MT6360_CHG_RVPI, 8), 139 + REGMAP_IRQ_REG_LINE(MT6360_OTPI, 8), 140 + REGMAP_IRQ_REG_LINE(MT6360_CHG_AICCMEASL, 8), 141 + REGMAP_IRQ_REG_LINE(MT6360_CHGDET_DONEI, 8), 142 + REGMAP_IRQ_REG_LINE(MT6360_WDTMRI, 8), 143 + REGMAP_IRQ_REG_LINE(MT6360_SSFINISHI, 8), 144 + REGMAP_IRQ_REG_LINE(MT6360_CHG_RECHGI, 8), 145 + REGMAP_IRQ_REG_LINE(MT6360_CHG_TERMI, 8), 146 + REGMAP_IRQ_REG_LINE(MT6360_CHG_IEOCI, 8), 147 + REGMAP_IRQ_REG_LINE(MT6360_PUMPX_DONEI, 8), 148 + REGMAP_IRQ_REG_LINE(MT6360_BAT_OVP_ADC_EVT, 8), 149 + REGMAP_IRQ_REG_LINE(MT6360_TYPEC_OTP_EVT, 8), 150 + REGMAP_IRQ_REG_LINE(MT6360_ADC_WAKEUP_EVT, 8), 151 + REGMAP_IRQ_REG_LINE(MT6360_ADC_DONEI, 8), 152 + REGMAP_IRQ_REG_LINE(MT6360_BST_BATUVI, 8), 153 + REGMAP_IRQ_REG_LINE(MT6360_BST_VBUSOVI, 8), 154 + REGMAP_IRQ_REG_LINE(MT6360_BST_OLPI, 8), 155 + REGMAP_IRQ_REG_LINE(MT6360_ATTACH_I, 8), 156 + REGMAP_IRQ_REG_LINE(MT6360_DETACH_I, 8), 157 + REGMAP_IRQ_REG_LINE(MT6360_QC30_STPDONE, 8), 158 + REGMAP_IRQ_REG_LINE(MT6360_QC_VBUSDET_DONE, 8), 159 + REGMAP_IRQ_REG_LINE(MT6360_HVDCP_DET, 8), 160 + REGMAP_IRQ_REG_LINE(MT6360_CHGDETI, 8), 161 + REGMAP_IRQ_REG_LINE(MT6360_DCDTI, 8), 162 + REGMAP_IRQ_REG_LINE(MT6360_FOD_DONE_EVT, 8), 163 + REGMAP_IRQ_REG_LINE(MT6360_FOD_OV_EVT, 8), 164 + REGMAP_IRQ_REG_LINE(MT6360_CHRDET_UVP_EVT, 8), 165 + REGMAP_IRQ_REG_LINE(MT6360_CHRDET_OVP_EVT, 8), 166 + REGMAP_IRQ_REG_LINE(MT6360_CHRDET_EXT_EVT, 8), 167 + REGMAP_IRQ_REG_LINE(MT6360_FOD_LR_EVT, 8), 168 + REGMAP_IRQ_REG_LINE(MT6360_FOD_HR_EVT, 8), 169 + REGMAP_IRQ_REG_LINE(MT6360_FOD_DISCHG_FAIL_EVT, 8), 170 + REGMAP_IRQ_REG_LINE(MT6360_USBID_EVT, 8), 171 + REGMAP_IRQ_REG_LINE(MT6360_APWDTRST_EVT, 8), 172 + REGMAP_IRQ_REG_LINE(MT6360_EN_EVT, 8), 173 + REGMAP_IRQ_REG_LINE(MT6360_QONB_RST_EVT, 8), 174 + REGMAP_IRQ_REG_LINE(MT6360_MRSTB_EVT, 8), 175 + REGMAP_IRQ_REG_LINE(MT6360_OTP_EVT, 8), 176 + REGMAP_IRQ_REG_LINE(MT6360_VDDAOV_EVT, 8), 177 + REGMAP_IRQ_REG_LINE(MT6360_SYSUV_EVT, 8), 178 + REGMAP_IRQ_REG_LINE(MT6360_FLED_STRBPIN_EVT, 8), 179 + REGMAP_IRQ_REG_LINE(MT6360_FLED_TORPIN_EVT, 8), 180 + REGMAP_IRQ_REG_LINE(MT6360_FLED_TX_EVT, 8), 181 + REGMAP_IRQ_REG_LINE(MT6360_FLED_LVF_EVT, 8), 182 + REGMAP_IRQ_REG_LINE(MT6360_FLED2_SHORT_EVT, 8), 183 + REGMAP_IRQ_REG_LINE(MT6360_FLED1_SHORT_EVT, 8), 184 + REGMAP_IRQ_REG_LINE(MT6360_FLED2_STRB_EVT, 8), 185 + REGMAP_IRQ_REG_LINE(MT6360_FLED1_STRB_EVT, 8), 186 + REGMAP_IRQ_REG_LINE(MT6360_FLED2_STRB_TO_EVT, 8), 187 + REGMAP_IRQ_REG_LINE(MT6360_FLED1_STRB_TO_EVT, 8), 188 + REGMAP_IRQ_REG_LINE(MT6360_FLED2_TOR_EVT, 8), 189 + REGMAP_IRQ_REG_LINE(MT6360_FLED1_TOR_EVT, 8), 190 + REGMAP_IRQ_REG_LINE(MT6360_BUCK1_PGB_EVT, 8), 191 + REGMAP_IRQ_REG_LINE(MT6360_BUCK1_OC_EVT, 8), 192 + REGMAP_IRQ_REG_LINE(MT6360_BUCK1_OV_EVT, 8), 193 + REGMAP_IRQ_REG_LINE(MT6360_BUCK1_UV_EVT, 8), 194 + REGMAP_IRQ_REG_LINE(MT6360_BUCK2_PGB_EVT, 8), 195 + REGMAP_IRQ_REG_LINE(MT6360_BUCK2_OC_EVT, 8), 196 + REGMAP_IRQ_REG_LINE(MT6360_BUCK2_OV_EVT, 8), 197 + REGMAP_IRQ_REG_LINE(MT6360_BUCK2_UV_EVT, 8), 198 + REGMAP_IRQ_REG_LINE(MT6360_LDO1_OC_EVT, 8), 199 + REGMAP_IRQ_REG_LINE(MT6360_LDO2_OC_EVT, 8), 200 + REGMAP_IRQ_REG_LINE(MT6360_LDO3_OC_EVT, 8), 201 + REGMAP_IRQ_REG_LINE(MT6360_LDO5_OC_EVT, 8), 202 + REGMAP_IRQ_REG_LINE(MT6360_LDO6_OC_EVT, 8), 203 + REGMAP_IRQ_REG_LINE(MT6360_LDO7_OC_EVT, 8), 204 + REGMAP_IRQ_REG_LINE(MT6360_LDO1_PGB_EVT, 8), 205 + REGMAP_IRQ_REG_LINE(MT6360_LDO2_PGB_EVT, 8), 206 + REGMAP_IRQ_REG_LINE(MT6360_LDO3_PGB_EVT, 8), 207 + REGMAP_IRQ_REG_LINE(MT6360_LDO5_PGB_EVT, 8), 208 + REGMAP_IRQ_REG_LINE(MT6360_LDO6_PGB_EVT, 8), 209 + REGMAP_IRQ_REG_LINE(MT6360_LDO7_PGB_EVT, 8), 210 + }; 211 + 212 + static int mt6360_pmu_handle_post_irq(void *irq_drv_data) 213 + { 214 + struct mt6360_pmu_data *mpd = irq_drv_data; 215 + 216 + return regmap_update_bits(mpd->regmap, 217 + MT6360_PMU_IRQ_SET, MT6360_IRQ_RETRIG, MT6360_IRQ_RETRIG); 218 + } 219 + 220 + static struct regmap_irq_chip mt6360_pmu_irq_chip = { 221 + .irqs = mt6360_pmu_irqs, 222 + .num_irqs = ARRAY_SIZE(mt6360_pmu_irqs), 223 + .num_regs = MT6360_PMU_IRQ_REGNUM, 224 + .mask_base = MT6360_PMU_CHG_MASK1, 225 + .status_base = MT6360_PMU_CHG_IRQ1, 226 + .ack_base = MT6360_PMU_CHG_IRQ1, 227 + .init_ack_masked = true, 228 + .use_ack = true, 229 + .handle_post_irq = mt6360_pmu_handle_post_irq, 230 + }; 231 + 232 + static const struct regmap_config mt6360_pmu_regmap_config = { 233 + .reg_bits = 8, 234 + .val_bits = 8, 235 + .max_register = MT6360_PMU_MAXREG, 236 + }; 237 + 238 + static const struct resource mt6360_adc_resources[] = { 239 + DEFINE_RES_IRQ_NAMED(MT6360_ADC_DONEI, "adc_donei"), 240 + }; 241 + 242 + static const struct resource mt6360_chg_resources[] = { 243 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_TREG_EVT, "chg_treg_evt"), 244 + DEFINE_RES_IRQ_NAMED(MT6360_PWR_RDY_EVT, "pwr_rdy_evt"), 245 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_BATSYSUV_EVT, "chg_batsysuv_evt"), 246 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_VSYSUV_EVT, "chg_vsysuv_evt"), 247 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_VSYSOV_EVT, "chg_vsysov_evt"), 248 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_VBATOV_EVT, "chg_vbatov_evt"), 249 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_VBUSOV_EVT, "chg_vbusov_evt"), 250 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_AICCMEASL, "chg_aiccmeasl"), 251 + DEFINE_RES_IRQ_NAMED(MT6360_WDTMRI, "wdtmri"), 252 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_RECHGI, "chg_rechgi"), 253 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_TERMI, "chg_termi"), 254 + DEFINE_RES_IRQ_NAMED(MT6360_CHG_IEOCI, "chg_ieoci"), 255 + DEFINE_RES_IRQ_NAMED(MT6360_PUMPX_DONEI, "pumpx_donei"), 256 + DEFINE_RES_IRQ_NAMED(MT6360_ATTACH_I, "attach_i"), 257 + DEFINE_RES_IRQ_NAMED(MT6360_CHRDET_EXT_EVT, "chrdet_ext_evt"), 258 + }; 259 + 260 + static const struct resource mt6360_led_resources[] = { 261 + DEFINE_RES_IRQ_NAMED(MT6360_FLED_CHG_VINOVP_EVT, "fled_chg_vinovp_evt"), 262 + DEFINE_RES_IRQ_NAMED(MT6360_FLED_LVF_EVT, "fled_lvf_evt"), 263 + DEFINE_RES_IRQ_NAMED(MT6360_FLED2_SHORT_EVT, "fled2_short_evt"), 264 + DEFINE_RES_IRQ_NAMED(MT6360_FLED1_SHORT_EVT, "fled1_short_evt"), 265 + DEFINE_RES_IRQ_NAMED(MT6360_FLED2_STRB_TO_EVT, "fled2_strb_to_evt"), 266 + DEFINE_RES_IRQ_NAMED(MT6360_FLED1_STRB_TO_EVT, "fled1_strb_to_evt"), 267 + }; 268 + 269 + static const struct resource mt6360_pmic_resources[] = { 270 + DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_PGB_EVT, "buck1_pgb_evt"), 271 + DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OC_EVT, "buck1_oc_evt"), 272 + DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OV_EVT, "buck1_ov_evt"), 273 + DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_UV_EVT, "buck1_uv_evt"), 274 + DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_PGB_EVT, "buck2_pgb_evt"), 275 + DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OC_EVT, "buck2_oc_evt"), 276 + DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_OV_EVT, "buck2_ov_evt"), 277 + DEFINE_RES_IRQ_NAMED(MT6360_BUCK2_UV_EVT, "buck2_uv_evt"), 278 + DEFINE_RES_IRQ_NAMED(MT6360_LDO6_OC_EVT, "ldo6_oc_evt"), 279 + DEFINE_RES_IRQ_NAMED(MT6360_LDO7_OC_EVT, "ldo7_oc_evt"), 280 + DEFINE_RES_IRQ_NAMED(MT6360_LDO6_PGB_EVT, "ldo6_pgb_evt"), 281 + DEFINE_RES_IRQ_NAMED(MT6360_LDO7_PGB_EVT, "ldo7_pgb_evt"), 282 + }; 283 + 284 + static const struct resource mt6360_ldo_resources[] = { 285 + DEFINE_RES_IRQ_NAMED(MT6360_LDO1_OC_EVT, "ldo1_oc_evt"), 286 + DEFINE_RES_IRQ_NAMED(MT6360_LDO2_OC_EVT, "ldo2_oc_evt"), 287 + DEFINE_RES_IRQ_NAMED(MT6360_LDO3_OC_EVT, "ldo3_oc_evt"), 288 + DEFINE_RES_IRQ_NAMED(MT6360_LDO5_OC_EVT, "ldo5_oc_evt"), 289 + DEFINE_RES_IRQ_NAMED(MT6360_LDO1_PGB_EVT, "ldo1_pgb_evt"), 290 + DEFINE_RES_IRQ_NAMED(MT6360_LDO2_PGB_EVT, "ldo2_pgb_evt"), 291 + DEFINE_RES_IRQ_NAMED(MT6360_LDO3_PGB_EVT, "ldo3_pgb_evt"), 292 + DEFINE_RES_IRQ_NAMED(MT6360_LDO5_PGB_EVT, "ldo5_pgb_evt"), 293 + }; 294 + 295 + static const struct mfd_cell mt6360_devs[] = { 296 + OF_MFD_CELL("mt6360_adc", mt6360_adc_resources, 297 + NULL, 0, 0, "mediatek,mt6360_adc"), 298 + OF_MFD_CELL("mt6360_chg", mt6360_chg_resources, 299 + NULL, 0, 0, "mediatek,mt6360_chg"), 300 + OF_MFD_CELL("mt6360_led", mt6360_led_resources, 301 + NULL, 0, 0, "mediatek,mt6360_led"), 302 + OF_MFD_CELL("mt6360_pmic", mt6360_pmic_resources, 303 + NULL, 0, 0, "mediatek,mt6360_pmic"), 304 + OF_MFD_CELL("mt6360_ldo", mt6360_ldo_resources, 305 + NULL, 0, 0, "mediatek,mt6360_ldo"), 306 + OF_MFD_CELL("mt6360_tcpc", NULL, 307 + NULL, 0, 0, "mediatek,mt6360_tcpc"), 308 + }; 309 + 310 + static const unsigned short mt6360_slave_addr[MT6360_SLAVE_MAX] = { 311 + MT6360_PMU_SLAVEID, 312 + MT6360_PMIC_SLAVEID, 313 + MT6360_LDO_SLAVEID, 314 + MT6360_TCPC_SLAVEID, 315 + }; 316 + 317 + static int mt6360_pmu_probe(struct i2c_client *client) 318 + { 319 + struct mt6360_pmu_data *mpd; 320 + unsigned int reg_data; 321 + int i, ret; 322 + 323 + mpd = devm_kzalloc(&client->dev, sizeof(*mpd), GFP_KERNEL); 324 + if (!mpd) 325 + return -ENOMEM; 326 + 327 + mpd->dev = &client->dev; 328 + i2c_set_clientdata(client, mpd); 329 + 330 + mpd->regmap = devm_regmap_init_i2c(client, &mt6360_pmu_regmap_config); 331 + if (IS_ERR(mpd->regmap)) { 332 + dev_err(&client->dev, "Failed to register regmap\n"); 333 + return PTR_ERR(mpd->regmap); 334 + } 335 + 336 + ret = regmap_read(mpd->regmap, MT6360_PMU_DEV_INFO, &reg_data); 337 + if (ret) { 338 + dev_err(&client->dev, "Device not found\n"); 339 + return ret; 340 + } 341 + 342 + mpd->chip_rev = reg_data & CHIP_REV_MASK; 343 + if (mpd->chip_rev != CHIP_VEN_MT6360) { 344 + dev_err(&client->dev, "Device not supported\n"); 345 + return -ENODEV; 346 + } 347 + 348 + mt6360_pmu_irq_chip.irq_drv_data = mpd; 349 + ret = devm_regmap_add_irq_chip(&client->dev, mpd->regmap, client->irq, 350 + IRQF_TRIGGER_FALLING, 0, 351 + &mt6360_pmu_irq_chip, &mpd->irq_data); 352 + if (ret) { 353 + dev_err(&client->dev, "Failed to add Regmap IRQ Chip\n"); 354 + return ret; 355 + } 356 + 357 + mpd->i2c[0] = client; 358 + for (i = 1; i < MT6360_SLAVE_MAX; i++) { 359 + mpd->i2c[i] = devm_i2c_new_dummy_device(&client->dev, 360 + client->adapter, 361 + mt6360_slave_addr[i]); 362 + if (IS_ERR(mpd->i2c[i])) { 363 + dev_err(&client->dev, 364 + "Failed to get new dummy I2C device for address 0x%x", 365 + mt6360_slave_addr[i]); 366 + return PTR_ERR(mpd->i2c[i]); 367 + } 368 + i2c_set_clientdata(mpd->i2c[i], mpd); 369 + } 370 + 371 + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, 372 + mt6360_devs, ARRAY_SIZE(mt6360_devs), NULL, 373 + 0, regmap_irq_get_domain(mpd->irq_data)); 374 + if (ret) { 375 + dev_err(&client->dev, 376 + "Failed to register subordinate devices\n"); 377 + return ret; 378 + } 379 + 380 + return 0; 381 + } 382 + 383 + static int __maybe_unused mt6360_pmu_suspend(struct device *dev) 384 + { 385 + struct i2c_client *i2c = to_i2c_client(dev); 386 + 387 + if (device_may_wakeup(dev)) 388 + enable_irq_wake(i2c->irq); 389 + 390 + return 0; 391 + } 392 + 393 + static int __maybe_unused mt6360_pmu_resume(struct device *dev) 394 + { 395 + 396 + struct i2c_client *i2c = to_i2c_client(dev); 397 + 398 + if (device_may_wakeup(dev)) 399 + disable_irq_wake(i2c->irq); 400 + 401 + return 0; 402 + } 403 + 404 + static SIMPLE_DEV_PM_OPS(mt6360_pmu_pm_ops, 405 + mt6360_pmu_suspend, mt6360_pmu_resume); 406 + 407 + static const struct of_device_id __maybe_unused mt6360_pmu_of_id[] = { 408 + { .compatible = "mediatek,mt6360_pmu", }, 409 + {}, 410 + }; 411 + MODULE_DEVICE_TABLE(of, mt6360_pmu_of_id); 412 + 413 + static struct i2c_driver mt6360_pmu_driver = { 414 + .driver = { 415 + .pm = &mt6360_pmu_pm_ops, 416 + .of_match_table = of_match_ptr(mt6360_pmu_of_id), 417 + }, 418 + .probe_new = mt6360_pmu_probe, 419 + }; 420 + module_i2c_driver(mt6360_pmu_driver); 421 + 422 + MODULE_AUTHOR("Gene Chen <gene_chen@richtek.com>"); 423 + MODULE_DESCRIPTION("MT6360 PMU I2C Driver"); 424 + MODULE_LICENSE("GPL v2");
+50 -51
drivers/mfd/mt6397-core.c
··· 12 12 #include <linux/regmap.h> 13 13 #include <linux/mfd/core.h> 14 14 #include <linux/mfd/mt6323/core.h> 15 + #include <linux/mfd/mt6358/core.h> 15 16 #include <linux/mfd/mt6397/core.h> 16 17 #include <linux/mfd/mt6323/registers.h> 18 + #include <linux/mfd/mt6358/registers.h> 17 19 #include <linux/mfd/mt6397/registers.h> 18 20 19 21 #define MT6323_RTC_BASE 0x8000 20 22 #define MT6323_RTC_SIZE 0x40 23 + 24 + #define MT6358_RTC_BASE 0x0588 25 + #define MT6358_RTC_SIZE 0x3c 21 26 22 27 #define MT6397_RTC_BASE 0xe000 23 28 #define MT6397_RTC_SIZE 0x3e ··· 33 28 static const struct resource mt6323_rtc_resources[] = { 34 29 DEFINE_RES_MEM(MT6323_RTC_BASE, MT6323_RTC_SIZE), 35 30 DEFINE_RES_IRQ(MT6323_IRQ_STATUS_RTC), 31 + }; 32 + 33 + static const struct resource mt6358_rtc_resources[] = { 34 + DEFINE_RES_MEM(MT6358_RTC_BASE, MT6358_RTC_SIZE), 35 + DEFINE_RES_IRQ(MT6358_IRQ_RTC), 36 36 }; 37 37 38 38 static const struct resource mt6397_rtc_resources[] = { ··· 84 74 }, 85 75 }; 86 76 77 + static const struct mfd_cell mt6358_devs[] = { 78 + { 79 + .name = "mt6358-regulator", 80 + .of_compatible = "mediatek,mt6358-regulator" 81 + }, { 82 + .name = "mt6358-rtc", 83 + .num_resources = ARRAY_SIZE(mt6358_rtc_resources), 84 + .resources = mt6358_rtc_resources, 85 + .of_compatible = "mediatek,mt6358-rtc", 86 + }, { 87 + .name = "mt6358-sound", 88 + .of_compatible = "mediatek,mt6358-sound" 89 + }, 90 + }; 91 + 87 92 static const struct mfd_cell mt6397_devs[] = { 88 93 { 89 94 .name = "mt6397-rtc", ··· 125 100 } 126 101 }; 127 102 128 - #ifdef CONFIG_PM_SLEEP 129 - static int mt6397_irq_suspend(struct device *dev) 130 - { 131 - struct mt6397_chip *chip = dev_get_drvdata(dev); 132 - 133 - regmap_write(chip->regmap, chip->int_con[0], chip->wake_mask[0]); 134 - regmap_write(chip->regmap, chip->int_con[1], chip->wake_mask[1]); 135 - 136 - enable_irq_wake(chip->irq); 137 - 138 - return 0; 139 - } 140 - 141 - static int mt6397_irq_resume(struct device *dev) 142 - { 143 - struct mt6397_chip *chip = dev_get_drvdata(dev); 144 - 145 - regmap_write(chip->regmap, chip->int_con[0], chip->irq_masks_cur[0]); 146 - regmap_write(chip->regmap, chip->int_con[1], chip->irq_masks_cur[1]); 147 - 148 - disable_irq_wake(chip->irq); 149 - 150 - return 0; 151 - } 152 - #endif 153 - 154 - static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_irq_suspend, 155 - mt6397_irq_resume); 156 - 157 103 struct chip_data { 158 104 u32 cid_addr; 159 105 u32 cid_shift; 106 + const struct mfd_cell *cells; 107 + int cell_size; 108 + int (*irq_init)(struct mt6397_chip *chip); 160 109 }; 161 110 162 111 static const struct chip_data mt6323_core = { 163 112 .cid_addr = MT6323_CID, 164 113 .cid_shift = 0, 114 + .cells = mt6323_devs, 115 + .cell_size = ARRAY_SIZE(mt6323_devs), 116 + .irq_init = mt6397_irq_init, 117 + }; 118 + 119 + static const struct chip_data mt6358_core = { 120 + .cid_addr = MT6358_SWCID, 121 + .cid_shift = 8, 122 + .cells = mt6358_devs, 123 + .cell_size = ARRAY_SIZE(mt6358_devs), 124 + .irq_init = mt6358_irq_init, 165 125 }; 166 126 167 127 static const struct chip_data mt6397_core = { 168 128 .cid_addr = MT6397_CID, 169 129 .cid_shift = 0, 130 + .cells = mt6397_devs, 131 + .cell_size = ARRAY_SIZE(mt6397_devs), 132 + .irq_init = mt6397_irq_init, 170 133 }; 171 134 172 135 static int mt6397_probe(struct platform_device *pdev) 173 136 { 174 137 int ret; 175 - unsigned int id; 138 + unsigned int id = 0; 176 139 struct mt6397_chip *pmic; 177 140 const struct chip_data *pmic_core; 178 141 ··· 196 183 if (pmic->irq <= 0) 197 184 return pmic->irq; 198 185 199 - ret = mt6397_irq_init(pmic); 186 + ret = pmic_core->irq_init(pmic); 200 187 if (ret) 201 188 return ret; 202 189 203 - switch (pmic->chip_id) { 204 - case MT6323_CHIP_ID: 205 - ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, 206 - mt6323_devs, ARRAY_SIZE(mt6323_devs), 207 - NULL, 0, pmic->irq_domain); 208 - break; 209 - 210 - case MT6391_CHIP_ID: 211 - case MT6397_CHIP_ID: 212 - ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, 213 - mt6397_devs, ARRAY_SIZE(mt6397_devs), 214 - NULL, 0, pmic->irq_domain); 215 - break; 216 - 217 - default: 218 - dev_err(&pdev->dev, "unsupported chip: %d\n", pmic->chip_id); 219 - return -ENODEV; 220 - } 221 - 190 + ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, 191 + pmic_core->cells, pmic_core->cell_size, 192 + NULL, 0, pmic->irq_domain); 222 193 if (ret) { 223 194 irq_domain_remove(pmic->irq_domain); 224 195 dev_err(&pdev->dev, "failed to add child devices: %d\n", ret); ··· 215 218 { 216 219 .compatible = "mediatek,mt6323", 217 220 .data = &mt6323_core, 221 + }, { 222 + .compatible = "mediatek,mt6358", 223 + .data = &mt6358_core, 218 224 }, { 219 225 .compatible = "mediatek,mt6397", 220 226 .data = &mt6397_core, ··· 238 238 .driver = { 239 239 .name = "mt6397", 240 240 .of_match_table = of_match_ptr(mt6397_of_match), 241 - .pm = &mt6397_pm_ops, 242 241 }, 243 242 .id_table = mt6397_id, 244 243 };
+34 -1
drivers/mfd/mt6397-irq.c
··· 9 9 #include <linux/of_irq.h> 10 10 #include <linux/platform_device.h> 11 11 #include <linux/regmap.h> 12 + #include <linux/suspend.h> 12 13 #include <linux/mfd/mt6323/core.h> 13 14 #include <linux/mfd/mt6323/registers.h> 14 15 #include <linux/mfd/mt6397/core.h> ··· 82 81 static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg, 83 82 int irqbase) 84 83 { 85 - unsigned int status; 84 + unsigned int status = 0; 86 85 int i, irq, ret; 87 86 88 87 ret = regmap_read(mt6397->regmap, reg, &status); ··· 129 128 .map = mt6397_irq_domain_map, 130 129 }; 131 130 131 + static int mt6397_irq_pm_notifier(struct notifier_block *notifier, 132 + unsigned long pm_event, void *unused) 133 + { 134 + struct mt6397_chip *chip = 135 + container_of(notifier, struct mt6397_chip, pm_nb); 136 + 137 + switch (pm_event) { 138 + case PM_SUSPEND_PREPARE: 139 + regmap_write(chip->regmap, 140 + chip->int_con[0], chip->wake_mask[0]); 141 + regmap_write(chip->regmap, 142 + chip->int_con[1], chip->wake_mask[1]); 143 + enable_irq_wake(chip->irq); 144 + break; 145 + 146 + case PM_POST_SUSPEND: 147 + regmap_write(chip->regmap, 148 + chip->int_con[0], chip->irq_masks_cur[0]); 149 + regmap_write(chip->regmap, 150 + chip->int_con[1], chip->irq_masks_cur[1]); 151 + disable_irq_wake(chip->irq); 152 + break; 153 + 154 + default: 155 + break; 156 + } 157 + 158 + return NOTIFY_DONE; 159 + } 160 + 132 161 int mt6397_irq_init(struct mt6397_chip *chip) 133 162 { 134 163 int ret; ··· 190 159 regmap_write(chip->regmap, chip->int_con[0], 0x0); 191 160 regmap_write(chip->regmap, chip->int_con[1], 0x0); 192 161 162 + chip->pm_nb.notifier_call = mt6397_irq_pm_notifier; 193 163 chip->irq_domain = irq_domain_add_linear(chip->dev->of_node, 194 164 MT6397_IRQ_NR, 195 165 &mt6397_irq_domain_ops, ··· 209 177 return ret; 210 178 } 211 179 180 + register_pm_notifier(&chip->pm_nb); 212 181 return 0; 213 182 }
-1
drivers/mfd/sprd-sc27xx-spi.c
··· 284 284 static struct spi_driver sprd_pmic_driver = { 285 285 .driver = { 286 286 .name = "sc27xx-pmic", 287 - .bus = &spi_bus_type, 288 287 .of_match_table = sprd_pmic_match, 289 288 }, 290 289 .probe = sprd_pmic_probe,
+23 -9
drivers/mfd/stm32-timers.c
··· 167 167 regmap_write(ddata->regmap, TIM_ARR, 0x0); 168 168 } 169 169 170 - static void stm32_timers_dma_probe(struct device *dev, 170 + static int stm32_timers_dma_probe(struct device *dev, 171 171 struct stm32_timers *ddata) 172 172 { 173 173 int i; 174 + int ret = 0; 174 175 char name[4]; 175 176 176 177 init_completion(&ddata->dma.completion); ··· 180 179 /* Optional DMA support: get valid DMA channel(s) or NULL */ 181 180 for (i = STM32_TIMERS_DMA_CH1; i <= STM32_TIMERS_DMA_CH4; i++) { 182 181 snprintf(name, ARRAY_SIZE(name), "ch%1d", i + 1); 183 - ddata->dma.chans[i] = dma_request_slave_channel(dev, name); 182 + ddata->dma.chans[i] = dma_request_chan(dev, name); 184 183 } 185 - ddata->dma.chans[STM32_TIMERS_DMA_UP] = 186 - dma_request_slave_channel(dev, "up"); 187 - ddata->dma.chans[STM32_TIMERS_DMA_TRIG] = 188 - dma_request_slave_channel(dev, "trig"); 189 - ddata->dma.chans[STM32_TIMERS_DMA_COM] = 190 - dma_request_slave_channel(dev, "com"); 184 + ddata->dma.chans[STM32_TIMERS_DMA_UP] = dma_request_chan(dev, "up"); 185 + ddata->dma.chans[STM32_TIMERS_DMA_TRIG] = dma_request_chan(dev, "trig"); 186 + ddata->dma.chans[STM32_TIMERS_DMA_COM] = dma_request_chan(dev, "com"); 187 + 188 + for (i = STM32_TIMERS_DMA_CH1; i < STM32_TIMERS_MAX_DMAS; i++) { 189 + if (IS_ERR(ddata->dma.chans[i])) { 190 + /* Save the first error code to return */ 191 + if (PTR_ERR(ddata->dma.chans[i]) != -ENODEV && !ret) 192 + ret = PTR_ERR(ddata->dma.chans[i]); 193 + 194 + ddata->dma.chans[i] = NULL; 195 + } 196 + } 197 + 198 + return ret; 191 199 } 192 200 193 201 static void stm32_timers_dma_remove(struct device *dev, ··· 240 230 241 231 stm32_timers_get_arr_size(ddata); 242 232 243 - stm32_timers_dma_probe(dev, ddata); 233 + ret = stm32_timers_dma_probe(dev, ddata); 234 + if (ret) { 235 + stm32_timers_dma_remove(dev, ddata); 236 + return ret; 237 + } 244 238 245 239 platform_set_drvdata(pdev, ddata); 246 240
+20 -2
drivers/mfd/stmfx.c
··· 287 287 288 288 ret = regmap_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, irqoutpin); 289 289 if (ret) 290 - return ret; 290 + goto irq_exit; 291 291 292 292 ret = devm_request_threaded_irq(stmfx->dev, client->irq, 293 293 NULL, stmfx_irq_handler, 294 294 irqtrigger | IRQF_ONESHOT, 295 295 "stmfx", stmfx); 296 296 if (ret) 297 - stmfx_irq_exit(client); 297 + goto irq_exit; 298 + 299 + stmfx->irq = client->irq; 300 + 301 + return 0; 302 + 303 + irq_exit: 304 + stmfx_irq_exit(client); 298 305 299 306 return ret; 300 307 } ··· 488 481 if (ret) 489 482 return ret; 490 483 484 + disable_irq(stmfx->irq); 485 + 491 486 if (stmfx->vdd) 492 487 return regulator_disable(stmfx->vdd); 493 488 ··· 510 501 } 511 502 } 512 503 504 + /* Reset STMFX - supply has been stopped during suspend */ 505 + ret = stmfx_chip_reset(stmfx); 506 + if (ret) { 507 + dev_err(stmfx->dev, "Failed to reset chip: %d\n", ret); 508 + return ret; 509 + } 510 + 513 511 ret = regmap_raw_write(stmfx->map, STMFX_REG_SYS_CTRL, 514 512 &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl)); 515 513 if (ret) ··· 532 516 &stmfx->irq_src, sizeof(stmfx->irq_src)); 533 517 if (ret) 534 518 return ret; 519 + 520 + enable_irq(stmfx->irq); 535 521 536 522 return 0; 537 523 }
+1 -1
drivers/mfd/stpmic1.c
··· 59 59 .n_yes_ranges = ARRAY_SIZE(stpmic1_volatile_ranges), 60 60 }; 61 61 62 - const struct regmap_config stpmic1_regmap_config = { 62 + static const struct regmap_config stpmic1_regmap_config = { 63 63 .reg_bits = 8, 64 64 .val_bits = 8, 65 65 .cache_type = REGCACHE_RBTREE,
+1 -1
drivers/mfd/tqmx86.c
··· 274 274 275 275 module_init(tqmx86_init); 276 276 277 - MODULE_DESCRIPTION("TQx86 PLD Core Driver"); 277 + MODULE_DESCRIPTION("TQMx86 PLD Core Driver"); 278 278 MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>"); 279 279 MODULE_LICENSE("GPL"); 280 280 MODULE_ALIAS("platform:tqmx86");
-1
drivers/mfd/wcd934x.c
··· 280 280 281 281 regulator_bulk_disable(WCD934X_MAX_SUPPLY, ddata->supplies); 282 282 mfd_remove_devices(&sdev->dev); 283 - kfree(ddata); 284 283 } 285 284 286 285 static const struct slim_device_id wcd934x_slim_id[] = {
+7 -1
drivers/mfd/wm8994-core.c
··· 393 393 ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies, 394 394 wm8994->supplies); 395 395 if (ret != 0) { 396 - dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); 396 + if (ret != -EPROBE_DEFER) 397 + dev_err(wm8994->dev, "Failed to get supplies: %d\n", 398 + ret); 397 399 goto err; 398 400 } 399 401 ··· 586 584 goto err_irq; 587 585 } 588 586 587 + pm_runtime_set_active(wm8994->dev); 589 588 pm_runtime_enable(wm8994->dev); 590 589 pm_runtime_idle(wm8994->dev); 591 590 ··· 606 603 607 604 static void wm8994_device_exit(struct wm8994 *wm8994) 608 605 { 606 + pm_runtime_get_sync(wm8994->dev); 609 607 pm_runtime_disable(wm8994->dev); 608 + pm_runtime_put_noidle(wm8994->dev); 610 609 wm8994_irq_exit(wm8994); 611 610 regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); 612 611 regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); ··· 695 690 MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC"); 696 691 MODULE_LICENSE("GPL"); 697 692 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 693 + MODULE_SOFTDEP("pre: wm8994_regulator");
+1 -1
drivers/power/reset/mt6323-poweroff.c
··· 30 30 int ret; 31 31 32 32 regmap_write(pwrc->regmap, pwrc->base + RTC_BBPU, RTC_BBPU_KEY); 33 - regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR, 1); 33 + regmap_write(pwrc->regmap, pwrc->base + RTC_WRTGR_MT6323, 1); 34 34 35 35 ret = regmap_read_poll_timeout(pwrc->regmap, 36 36 pwrc->base + RTC_BBPU, val,
+10
drivers/power/supply/Kconfig
··· 541 541 Say Y to enable support for the battery charger control sysfs and 542 542 platform data of MAX8998/LP3974 PMICs. 543 543 544 + config CHARGER_MP2629 545 + tristate "Monolithic power system MP2629 Battery charger" 546 + depends on MFD_MP2629 547 + depends on MP2629_ADC 548 + depends on IIO 549 + help 550 + Select this option to enable support for Monolithic power system 551 + Battery charger. This driver provides Battery charger power management 552 + functions on the systems. 553 + 544 554 config CHARGER_QCOM_SMBB 545 555 tristate "Qualcomm Switch-Mode Battery Charger and Boost" 546 556 depends on MFD_SPMI_PMIC || COMPILE_TEST
+1
drivers/power/supply/Makefile
··· 75 75 obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o 76 76 obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o 77 77 obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o 78 + obj-$(CONFIG_CHARGER_MP2629) += mp2629_charger.o 78 79 obj-$(CONFIG_CHARGER_QCOM_SMBB) += qcom_smbb.o 79 80 obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o 80 81 obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o
+669
drivers/power/supply/mp2629_charger.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * MP2629 battery charger driver 4 + * 5 + * Copyright 2020 Monolithic Power Systems, Inc 6 + * 7 + * Author: Saravanan Sekar <sravanhome@gmail.com> 8 + */ 9 + 10 + #include <linux/bits.h> 11 + #include <linux/iio/consumer.h> 12 + #include <linux/iio/types.h> 13 + #include <linux/interrupt.h> 14 + #include <linux/mfd/mp2629.h> 15 + #include <linux/module.h> 16 + #include <linux/mod_devicetable.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/power_supply.h> 19 + #include <linux/regmap.h> 20 + 21 + #define MP2629_REG_INPUT_ILIM 0x00 22 + #define MP2629_REG_INPUT_VLIM 0x01 23 + #define MP2629_REG_CHARGE_CTRL 0x04 24 + #define MP2629_REG_CHARGE_ILIM 0x05 25 + #define MP2629_REG_PRECHARGE 0x06 26 + #define MP2629_REG_TERM_CURRENT 0x06 27 + #define MP2629_REG_CHARGE_VLIM 0x07 28 + #define MP2629_REG_TIMER_CTRL 0x08 29 + #define MP2629_REG_IMPEDANCE_COMP 0x09 30 + #define MP2629_REG_INTERRUPT 0x0b 31 + #define MP2629_REG_STATUS 0x0c 32 + #define MP2629_REG_FAULT 0x0d 33 + 34 + #define MP2629_MASK_INPUT_TYPE GENMASK(7, 5) 35 + #define MP2629_MASK_CHARGE_TYPE GENMASK(4, 3) 36 + #define MP2629_MASK_CHARGE_CTRL GENMASK(5, 4) 37 + #define MP2629_MASK_WDOG_CTRL GENMASK(5, 4) 38 + #define MP2629_MASK_IMPEDANCE GENMASK(7, 4) 39 + 40 + #define MP2629_INPUTSOURCE_CHANGE GENMASK(7, 5) 41 + #define MP2629_CHARGING_CHANGE GENMASK(4, 3) 42 + #define MP2629_FAULT_BATTERY BIT(3) 43 + #define MP2629_FAULT_THERMAL BIT(4) 44 + #define MP2629_FAULT_INPUT BIT(5) 45 + #define MP2629_FAULT_OTG BIT(6) 46 + 47 + #define MP2629_MAX_BATT_CAPACITY 100 48 + 49 + #define MP2629_PROPS(_idx, _min, _max, _step) \ 50 + [_idx] = { \ 51 + .min = _min, \ 52 + .max = _max, \ 53 + .step = _step, \ 54 + } 55 + 56 + enum mp2629_source_type { 57 + MP2629_SOURCE_TYPE_NO_INPUT, 58 + MP2629_SOURCE_TYPE_NON_STD, 59 + MP2629_SOURCE_TYPE_SDP, 60 + MP2629_SOURCE_TYPE_CDP, 61 + MP2629_SOURCE_TYPE_DCP, 62 + MP2629_SOURCE_TYPE_OTG = 7, 63 + }; 64 + 65 + enum mp2629_field { 66 + INPUT_ILIM, 67 + INPUT_VLIM, 68 + CHARGE_ILIM, 69 + CHARGE_VLIM, 70 + PRECHARGE, 71 + TERM_CURRENT, 72 + MP2629_MAX_FIELD 73 + }; 74 + 75 + struct mp2629_charger { 76 + struct device *dev; 77 + int status; 78 + int fault; 79 + 80 + struct regmap *regmap; 81 + struct regmap_field *regmap_fields[MP2629_MAX_FIELD]; 82 + struct mutex lock; 83 + struct power_supply *usb; 84 + struct power_supply *battery; 85 + struct iio_channel *iiochan[MP2629_ADC_CHAN_END]; 86 + }; 87 + 88 + struct mp2629_prop { 89 + int reg; 90 + int mask; 91 + int min; 92 + int max; 93 + int step; 94 + int shift; 95 + }; 96 + 97 + static enum power_supply_usb_type mp2629_usb_types[] = { 98 + POWER_SUPPLY_USB_TYPE_SDP, 99 + POWER_SUPPLY_USB_TYPE_DCP, 100 + POWER_SUPPLY_USB_TYPE_CDP, 101 + POWER_SUPPLY_USB_TYPE_PD_DRP, 102 + POWER_SUPPLY_USB_TYPE_UNKNOWN 103 + }; 104 + 105 + static enum power_supply_property mp2629_charger_usb_props[] = { 106 + POWER_SUPPLY_PROP_ONLINE, 107 + POWER_SUPPLY_PROP_USB_TYPE, 108 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 109 + POWER_SUPPLY_PROP_CURRENT_NOW, 110 + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 111 + POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT, 112 + }; 113 + 114 + static enum power_supply_property mp2629_charger_bat_props[] = { 115 + POWER_SUPPLY_PROP_STATUS, 116 + POWER_SUPPLY_PROP_HEALTH, 117 + POWER_SUPPLY_PROP_CHARGE_TYPE, 118 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 119 + POWER_SUPPLY_PROP_CURRENT_NOW, 120 + POWER_SUPPLY_PROP_CAPACITY, 121 + POWER_SUPPLY_PROP_PRECHARGE_CURRENT, 122 + POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, 123 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 124 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE, 125 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 126 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 127 + }; 128 + 129 + static struct mp2629_prop props[] = { 130 + MP2629_PROPS(INPUT_ILIM, 100000, 3250000, 50000), 131 + MP2629_PROPS(INPUT_VLIM, 3800000, 5300000, 100000), 132 + MP2629_PROPS(CHARGE_ILIM, 320000, 4520000, 40000), 133 + MP2629_PROPS(CHARGE_VLIM, 3400000, 4670000, 10000), 134 + MP2629_PROPS(PRECHARGE, 120000, 720000, 40000), 135 + MP2629_PROPS(TERM_CURRENT, 80000, 680000, 40000), 136 + }; 137 + 138 + static const struct reg_field mp2629_reg_fields[] = { 139 + [INPUT_ILIM] = REG_FIELD(MP2629_REG_INPUT_ILIM, 0, 5), 140 + [INPUT_VLIM] = REG_FIELD(MP2629_REG_INPUT_VLIM, 0, 3), 141 + [CHARGE_ILIM] = REG_FIELD(MP2629_REG_CHARGE_ILIM, 0, 6), 142 + [CHARGE_VLIM] = REG_FIELD(MP2629_REG_CHARGE_VLIM, 1, 7), 143 + [PRECHARGE] = REG_FIELD(MP2629_REG_PRECHARGE, 4, 7), 144 + [TERM_CURRENT] = REG_FIELD(MP2629_REG_TERM_CURRENT, 0, 3), 145 + }; 146 + 147 + static char *adc_chan_name[] = { 148 + "mp2629-batt-volt", 149 + "mp2629-system-volt", 150 + "mp2629-input-volt", 151 + "mp2629-batt-current", 152 + "mp2629-input-current", 153 + }; 154 + 155 + static int mp2629_read_adc(struct mp2629_charger *charger, 156 + enum mp2629_adc_chan ch, 157 + union power_supply_propval *val) 158 + { 159 + int ret; 160 + int chval; 161 + 162 + ret = iio_read_channel_processed(charger->iiochan[ch], &chval); 163 + if (ret) 164 + return ret; 165 + 166 + val->intval = chval * 1000; 167 + 168 + return 0; 169 + } 170 + 171 + static int mp2629_get_prop(struct mp2629_charger *charger, 172 + enum mp2629_field fld, 173 + union power_supply_propval *val) 174 + { 175 + int ret; 176 + unsigned int rval; 177 + 178 + ret = regmap_field_read(charger->regmap_fields[fld], &rval); 179 + if (ret) 180 + return ret; 181 + 182 + val->intval = rval * props[fld].step + props[fld].min; 183 + 184 + return 0; 185 + } 186 + 187 + static int mp2629_set_prop(struct mp2629_charger *charger, 188 + enum mp2629_field fld, 189 + const union power_supply_propval *val) 190 + { 191 + unsigned int rval; 192 + 193 + if (val->intval < props[fld].min || val->intval > props[fld].max) 194 + return -EINVAL; 195 + 196 + rval = (val->intval - props[fld].min) / props[fld].step; 197 + return regmap_field_write(charger->regmap_fields[fld], rval); 198 + } 199 + 200 + static int mp2629_get_battery_capacity(struct mp2629_charger *charger, 201 + union power_supply_propval *val) 202 + { 203 + union power_supply_propval vnow, vlim; 204 + int ret; 205 + 206 + ret = mp2629_read_adc(charger, MP2629_BATT_VOLT, &vnow); 207 + if (ret) 208 + return ret; 209 + 210 + ret = mp2629_get_prop(charger, CHARGE_VLIM, &vlim); 211 + if (ret) 212 + return ret; 213 + 214 + val->intval = (vnow.intval * 100) / vlim.intval; 215 + val->intval = min(val->intval, MP2629_MAX_BATT_CAPACITY); 216 + 217 + return 0; 218 + } 219 + 220 + static int mp2629_charger_battery_get_prop(struct power_supply *psy, 221 + enum power_supply_property psp, 222 + union power_supply_propval *val) 223 + { 224 + struct mp2629_charger *charger = dev_get_drvdata(psy->dev.parent); 225 + unsigned int rval; 226 + int ret = 0; 227 + 228 + switch (psp) { 229 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 230 + ret = mp2629_read_adc(charger, MP2629_BATT_VOLT, val); 231 + break; 232 + 233 + case POWER_SUPPLY_PROP_CURRENT_NOW: 234 + ret = mp2629_read_adc(charger, MP2629_BATT_CURRENT, val); 235 + break; 236 + 237 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 238 + val->intval = 4520000; 239 + break; 240 + 241 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX: 242 + val->intval = 4670000; 243 + break; 244 + 245 + case POWER_SUPPLY_PROP_CAPACITY: 246 + ret = mp2629_get_battery_capacity(charger, val); 247 + break; 248 + 249 + case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 250 + ret = mp2629_get_prop(charger, TERM_CURRENT, val); 251 + break; 252 + 253 + case POWER_SUPPLY_PROP_PRECHARGE_CURRENT: 254 + ret = mp2629_get_prop(charger, PRECHARGE, val); 255 + break; 256 + 257 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 258 + ret = mp2629_get_prop(charger, CHARGE_VLIM, val); 259 + break; 260 + 261 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 262 + ret = mp2629_get_prop(charger, CHARGE_ILIM, val); 263 + break; 264 + 265 + case POWER_SUPPLY_PROP_HEALTH: 266 + if (!charger->fault) 267 + val->intval = POWER_SUPPLY_HEALTH_GOOD; 268 + if (MP2629_FAULT_BATTERY & charger->fault) 269 + val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 270 + else if (MP2629_FAULT_THERMAL & charger->fault) 271 + val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 272 + else if (MP2629_FAULT_INPUT & charger->fault) 273 + val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 274 + break; 275 + 276 + case POWER_SUPPLY_PROP_STATUS: 277 + ret = regmap_read(charger->regmap, MP2629_REG_STATUS, &rval); 278 + if (ret) 279 + break; 280 + 281 + rval = (rval & MP2629_MASK_CHARGE_TYPE) >> 3; 282 + switch (rval) { 283 + case 0x00: 284 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 285 + break; 286 + case 0x01: 287 + case 0x10: 288 + val->intval = POWER_SUPPLY_STATUS_CHARGING; 289 + break; 290 + case 0x11: 291 + val->intval = POWER_SUPPLY_STATUS_FULL; 292 + } 293 + break; 294 + 295 + case POWER_SUPPLY_PROP_CHARGE_TYPE: 296 + ret = regmap_read(charger->regmap, MP2629_REG_STATUS, &rval); 297 + if (ret) 298 + break; 299 + 300 + rval = (rval & MP2629_MASK_CHARGE_TYPE) >> 3; 301 + switch (rval) { 302 + case 0x00: 303 + val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE; 304 + break; 305 + case 0x01: 306 + val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; 307 + break; 308 + case 0x10: 309 + val->intval = POWER_SUPPLY_CHARGE_TYPE_STANDARD; 310 + break; 311 + default: 312 + val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; 313 + } 314 + break; 315 + 316 + default: 317 + return -EINVAL; 318 + } 319 + 320 + return ret; 321 + } 322 + 323 + static int mp2629_charger_battery_set_prop(struct power_supply *psy, 324 + enum power_supply_property psp, 325 + const union power_supply_propval *val) 326 + { 327 + struct mp2629_charger *charger = dev_get_drvdata(psy->dev.parent); 328 + 329 + switch (psp) { 330 + case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 331 + return mp2629_set_prop(charger, TERM_CURRENT, val); 332 + 333 + case POWER_SUPPLY_PROP_PRECHARGE_CURRENT: 334 + return mp2629_set_prop(charger, PRECHARGE, val); 335 + 336 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: 337 + return mp2629_set_prop(charger, CHARGE_VLIM, val); 338 + 339 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 340 + return mp2629_set_prop(charger, CHARGE_ILIM, val); 341 + 342 + default: 343 + return -EINVAL; 344 + } 345 + } 346 + 347 + static int mp2629_charger_usb_get_prop(struct power_supply *psy, 348 + enum power_supply_property psp, 349 + union power_supply_propval *val) 350 + { 351 + struct mp2629_charger *charger = dev_get_drvdata(psy->dev.parent); 352 + unsigned int rval; 353 + int ret; 354 + 355 + switch (psp) { 356 + case POWER_SUPPLY_PROP_ONLINE: 357 + ret = regmap_read(charger->regmap, MP2629_REG_STATUS, &rval); 358 + if (ret) 359 + break; 360 + 361 + val->intval = !!(rval & MP2629_MASK_INPUT_TYPE); 362 + break; 363 + 364 + case POWER_SUPPLY_PROP_USB_TYPE: 365 + ret = regmap_read(charger->regmap, MP2629_REG_STATUS, &rval); 366 + if (ret) 367 + break; 368 + 369 + rval = (rval & MP2629_MASK_INPUT_TYPE) >> 5; 370 + switch (rval) { 371 + case MP2629_SOURCE_TYPE_SDP: 372 + val->intval = POWER_SUPPLY_USB_TYPE_SDP; 373 + break; 374 + case MP2629_SOURCE_TYPE_CDP: 375 + val->intval = POWER_SUPPLY_USB_TYPE_CDP; 376 + break; 377 + case MP2629_SOURCE_TYPE_DCP: 378 + val->intval = POWER_SUPPLY_USB_TYPE_DCP; 379 + break; 380 + case MP2629_SOURCE_TYPE_OTG: 381 + val->intval = POWER_SUPPLY_USB_TYPE_PD_DRP; 382 + break; 383 + default: 384 + val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN; 385 + break; 386 + } 387 + break; 388 + 389 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 390 + ret = mp2629_read_adc(charger, MP2629_INPUT_VOLT, val); 391 + break; 392 + 393 + case POWER_SUPPLY_PROP_CURRENT_NOW: 394 + ret = mp2629_read_adc(charger, MP2629_INPUT_CURRENT, val); 395 + break; 396 + 397 + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: 398 + ret = mp2629_get_prop(charger, INPUT_VLIM, val); 399 + break; 400 + 401 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 402 + ret = mp2629_get_prop(charger, INPUT_ILIM, val); 403 + break; 404 + 405 + default: 406 + return -EINVAL; 407 + } 408 + 409 + return ret; 410 + } 411 + 412 + static int mp2629_charger_usb_set_prop(struct power_supply *psy, 413 + enum power_supply_property psp, 414 + const union power_supply_propval *val) 415 + { 416 + struct mp2629_charger *charger = dev_get_drvdata(psy->dev.parent); 417 + 418 + switch (psp) { 419 + case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: 420 + return mp2629_set_prop(charger, INPUT_VLIM, val); 421 + 422 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 423 + return mp2629_set_prop(charger, INPUT_ILIM, val); 424 + 425 + default: 426 + return -EINVAL; 427 + } 428 + } 429 + 430 + static int mp2629_charger_battery_prop_writeable(struct power_supply *psy, 431 + enum power_supply_property psp) 432 + { 433 + return (psp == POWER_SUPPLY_PROP_PRECHARGE_CURRENT) || 434 + (psp == POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT) || 435 + (psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT) || 436 + (psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE); 437 + } 438 + 439 + static int mp2629_charger_usb_prop_writeable(struct power_supply *psy, 440 + enum power_supply_property psp) 441 + { 442 + return (psp == POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT) || 443 + (psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT); 444 + } 445 + 446 + static irqreturn_t mp2629_irq_handler(int irq, void *dev_id) 447 + { 448 + struct mp2629_charger *charger = dev_id; 449 + unsigned int rval; 450 + int ret; 451 + 452 + mutex_lock(&charger->lock); 453 + 454 + ret = regmap_read(charger->regmap, MP2629_REG_FAULT, &rval); 455 + if (ret) 456 + goto unlock; 457 + 458 + if (rval) { 459 + charger->fault = rval; 460 + if (MP2629_FAULT_BATTERY & rval) 461 + dev_err(charger->dev, "Battery fault OVP\n"); 462 + else if (MP2629_FAULT_THERMAL & rval) 463 + dev_err(charger->dev, "Thermal shutdown fault\n"); 464 + else if (MP2629_FAULT_INPUT & rval) 465 + dev_err(charger->dev, "no input or input OVP\n"); 466 + else if (MP2629_FAULT_OTG & rval) 467 + dev_err(charger->dev, "VIN overloaded\n"); 468 + 469 + goto unlock; 470 + } 471 + 472 + ret = regmap_read(charger->regmap, MP2629_REG_STATUS, &rval); 473 + if (ret) 474 + goto unlock; 475 + 476 + if (rval & MP2629_INPUTSOURCE_CHANGE) 477 + power_supply_changed(charger->usb); 478 + else if (rval & MP2629_CHARGING_CHANGE) 479 + power_supply_changed(charger->battery); 480 + 481 + unlock: 482 + mutex_unlock(&charger->lock); 483 + 484 + return IRQ_HANDLED; 485 + } 486 + 487 + static const struct power_supply_desc mp2629_usb_desc = { 488 + .name = "mp2629_usb", 489 + .type = POWER_SUPPLY_TYPE_USB, 490 + .usb_types = mp2629_usb_types, 491 + .num_usb_types = ARRAY_SIZE(mp2629_usb_types), 492 + .properties = mp2629_charger_usb_props, 493 + .num_properties = ARRAY_SIZE(mp2629_charger_usb_props), 494 + .get_property = mp2629_charger_usb_get_prop, 495 + .set_property = mp2629_charger_usb_set_prop, 496 + .property_is_writeable = mp2629_charger_usb_prop_writeable, 497 + }; 498 + 499 + static const struct power_supply_desc mp2629_battery_desc = { 500 + .name = "mp2629_battery", 501 + .type = POWER_SUPPLY_TYPE_BATTERY, 502 + .properties = mp2629_charger_bat_props, 503 + .num_properties = ARRAY_SIZE(mp2629_charger_bat_props), 504 + .get_property = mp2629_charger_battery_get_prop, 505 + .set_property = mp2629_charger_battery_set_prop, 506 + .property_is_writeable = mp2629_charger_battery_prop_writeable, 507 + }; 508 + 509 + static ssize_t batt_impedance_compensation_show(struct device *dev, 510 + struct device_attribute *attr, 511 + char *buf) 512 + { 513 + struct mp2629_charger *charger = dev_get_drvdata(dev->parent); 514 + unsigned int rval; 515 + int ret; 516 + 517 + ret = regmap_read(charger->regmap, MP2629_REG_IMPEDANCE_COMP, &rval); 518 + if (ret) 519 + return ret; 520 + 521 + rval = (rval >> 4) * 10; 522 + return sprintf(buf, "%d mohm\n", rval); 523 + } 524 + 525 + static ssize_t batt_impedance_compensation_store(struct device *dev, 526 + struct device_attribute *attr, 527 + const char *buf, 528 + size_t count) 529 + { 530 + struct mp2629_charger *charger = dev_get_drvdata(dev->parent); 531 + unsigned int val; 532 + int ret; 533 + 534 + ret = kstrtouint(buf, 10, &val); 535 + if (ret) 536 + return ret; 537 + 538 + if (val > 140) 539 + return -ERANGE; 540 + 541 + /* multiples of 10 mohm so round off */ 542 + val = val / 10; 543 + ret = regmap_update_bits(charger->regmap, MP2629_REG_IMPEDANCE_COMP, 544 + MP2629_MASK_IMPEDANCE, val << 4); 545 + if (ret) 546 + return ret; 547 + 548 + return count; 549 + } 550 + 551 + static DEVICE_ATTR_RW(batt_impedance_compensation); 552 + 553 + static struct attribute *mp2629_charger_sysfs_attrs[] = { 554 + &dev_attr_batt_impedance_compensation.attr, 555 + NULL 556 + }; 557 + ATTRIBUTE_GROUPS(mp2629_charger_sysfs); 558 + 559 + static void mp2629_charger_disable(void *data) 560 + { 561 + struct mp2629_charger *charger = data; 562 + 563 + regmap_update_bits(charger->regmap, MP2629_REG_CHARGE_CTRL, 564 + MP2629_MASK_CHARGE_CTRL, 0); 565 + } 566 + 567 + static int mp2629_charger_probe(struct platform_device *pdev) 568 + { 569 + struct device *dev = &pdev->dev; 570 + struct mp2629_data *ddata = dev_get_drvdata(dev->parent); 571 + struct mp2629_charger *charger; 572 + struct power_supply_config psy_cfg = {}; 573 + int ret, i, irq; 574 + 575 + charger = devm_kzalloc(dev, sizeof(*charger), GFP_KERNEL); 576 + if (!charger) 577 + return -ENOMEM; 578 + 579 + charger->regmap = ddata->regmap; 580 + charger->dev = dev; 581 + platform_set_drvdata(pdev, charger); 582 + 583 + irq = platform_get_irq_optional(to_platform_device(dev->parent), 0); 584 + if (irq < 0) { 585 + dev_err(dev, "get irq fail: %d\n", irq); 586 + return irq; 587 + } 588 + 589 + for (i = 0; i < MP2629_MAX_FIELD; i++) { 590 + charger->regmap_fields[i] = devm_regmap_field_alloc(dev, 591 + charger->regmap, mp2629_reg_fields[i]); 592 + if (IS_ERR(charger->regmap_fields[i])) { 593 + dev_err(dev, "regmap field alloc fail %d\n", i); 594 + return PTR_ERR(charger->regmap_fields[i]); 595 + } 596 + } 597 + 598 + for (i = 0; i < MP2629_ADC_CHAN_END; i++) { 599 + charger->iiochan[i] = devm_iio_channel_get(dev, 600 + adc_chan_name[i]); 601 + if (IS_ERR(charger->iiochan[i])) { 602 + dev_err(dev, "iio chan get %s err\n", adc_chan_name[i]); 603 + return PTR_ERR(charger->iiochan[i]); 604 + } 605 + } 606 + 607 + ret = devm_add_action_or_reset(dev, mp2629_charger_disable, charger); 608 + if (ret) 609 + return ret; 610 + 611 + charger->usb = devm_power_supply_register(dev, &mp2629_usb_desc, NULL); 612 + if (IS_ERR(charger->usb)) { 613 + dev_err(dev, "power supply register usb failed\n"); 614 + return PTR_ERR(charger->usb); 615 + } 616 + 617 + psy_cfg.drv_data = charger; 618 + psy_cfg.attr_grp = mp2629_charger_sysfs_groups; 619 + charger->battery = devm_power_supply_register(dev, 620 + &mp2629_battery_desc, &psy_cfg); 621 + if (IS_ERR(charger->battery)) { 622 + dev_err(dev, "power supply register battery failed\n"); 623 + return PTR_ERR(charger->battery); 624 + } 625 + 626 + ret = regmap_update_bits(charger->regmap, MP2629_REG_CHARGE_CTRL, 627 + MP2629_MASK_CHARGE_CTRL, BIT(4)); 628 + if (ret) { 629 + dev_err(dev, "enable charge fail: %d\n", ret); 630 + return ret; 631 + } 632 + 633 + regmap_update_bits(charger->regmap, MP2629_REG_TIMER_CTRL, 634 + MP2629_MASK_WDOG_CTRL, 0); 635 + 636 + mutex_init(&charger->lock); 637 + 638 + ret = devm_request_threaded_irq(dev, irq, NULL, mp2629_irq_handler, 639 + IRQF_ONESHOT | IRQF_TRIGGER_RISING, 640 + "mp2629-charger", charger); 641 + if (ret) { 642 + dev_err(dev, "failed to request gpio IRQ\n"); 643 + return ret; 644 + } 645 + 646 + regmap_update_bits(charger->regmap, MP2629_REG_INTERRUPT, 647 + GENMASK(6, 5), BIT(6) | BIT(5)); 648 + 649 + return 0; 650 + } 651 + 652 + static const struct of_device_id mp2629_charger_of_match[] = { 653 + { .compatible = "mps,mp2629_charger"}, 654 + {} 655 + }; 656 + MODULE_DEVICE_TABLE(of, mp2629_charger_of_match); 657 + 658 + static struct platform_driver mp2629_charger_driver = { 659 + .driver = { 660 + .name = "mp2629_charger", 661 + .of_match_table = mp2629_charger_of_match, 662 + }, 663 + .probe = mp2629_charger_probe, 664 + }; 665 + module_platform_driver(mp2629_charger_driver); 666 + 667 + MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>"); 668 + MODULE_DESCRIPTION("MP2629 Charger driver"); 669 + MODULE_LICENSE("GPL");
+15 -3
drivers/rtc/rtc-mt6397.c
··· 9 9 #include <linux/mfd/mt6397/core.h> 10 10 #include <linux/module.h> 11 11 #include <linux/mutex.h> 12 + #include <linux/of_device.h> 12 13 #include <linux/platform_device.h> 13 14 #include <linux/regmap.h> 14 15 #include <linux/rtc.h> ··· 21 20 int ret; 22 21 u32 data; 23 22 24 - ret = regmap_write(rtc->regmap, rtc->addr_base + RTC_WRTGR, 1); 23 + ret = regmap_write(rtc->regmap, rtc->addr_base + rtc->data->wrtgr, 1); 25 24 if (ret < 0) 26 25 return ret; 27 26 ··· 270 269 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 271 270 rtc->addr_base = res->start; 272 271 272 + rtc->data = of_device_get_match_data(&pdev->dev); 273 + 273 274 rtc->irq = platform_get_irq(pdev, 0); 274 275 if (rtc->irq < 0) 275 276 return rtc->irq; ··· 328 325 static SIMPLE_DEV_PM_OPS(mt6397_pm_ops, mt6397_rtc_suspend, 329 326 mt6397_rtc_resume); 330 327 328 + static const struct mtk_rtc_data mt6358_rtc_data = { 329 + .wrtgr = RTC_WRTGR_MT6358, 330 + }; 331 + 332 + static const struct mtk_rtc_data mt6397_rtc_data = { 333 + .wrtgr = RTC_WRTGR_MT6397, 334 + }; 335 + 331 336 static const struct of_device_id mt6397_rtc_of_match[] = { 332 - { .compatible = "mediatek,mt6323-rtc", }, 333 - { .compatible = "mediatek,mt6397-rtc", }, 337 + { .compatible = "mediatek,mt6323-rtc", .data = &mt6397_rtc_data }, 338 + { .compatible = "mediatek,mt6358-rtc", .data = &mt6358_rtc_data }, 339 + { .compatible = "mediatek,mt6397-rtc", .data = &mt6397_rtc_data }, 334 340 { } 335 341 }; 336 342 MODULE_DEVICE_TABLE(of, mt6397_rtc_of_match);
+1 -1
include/linux/mfd/core.h
··· 70 70 size_t pdata_size; 71 71 72 72 /* device properties passed to the sub devices drivers */ 73 - struct property_entry *properties; 73 + const struct property_entry *properties; 74 74 75 75 /* 76 76 * Device Tree compatible string
+26
include/linux/mfd/mp2629.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + /* 3 + * Copyright 2020 Monolithic Power Systems, Inc 4 + */ 5 + 6 + #ifndef __MP2629_H__ 7 + #define __MP2629_H__ 8 + 9 + #include <linux/device.h> 10 + #include <linux/regmap.h> 11 + 12 + struct mp2629_data { 13 + struct device *dev; 14 + struct regmap *regmap; 15 + }; 16 + 17 + enum mp2629_adc_chan { 18 + MP2629_BATT_VOLT, 19 + MP2629_SYSTEM_VOLT, 20 + MP2629_INPUT_VOLT, 21 + MP2629_BATT_CURRENT, 22 + MP2629_INPUT_CURRENT, 23 + MP2629_ADC_CHAN_END 24 + }; 25 + 26 + #endif
+158
include/linux/mfd/mt6358/core.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2020 MediaTek Inc. 4 + */ 5 + 6 + #ifndef __MFD_MT6358_CORE_H__ 7 + #define __MFD_MT6358_CORE_H__ 8 + 9 + #define MT6358_REG_WIDTH 16 10 + 11 + struct irq_top_t { 12 + int hwirq_base; 13 + unsigned int num_int_regs; 14 + unsigned int num_int_bits; 15 + unsigned int en_reg; 16 + unsigned int en_reg_shift; 17 + unsigned int sta_reg; 18 + unsigned int sta_reg_shift; 19 + unsigned int top_offset; 20 + }; 21 + 22 + struct pmic_irq_data { 23 + unsigned int num_top; 24 + unsigned int num_pmic_irqs; 25 + unsigned short top_int_status_reg; 26 + bool *enable_hwirq; 27 + bool *cache_hwirq; 28 + }; 29 + 30 + enum mt6358_irq_top_status_shift { 31 + MT6358_BUCK_TOP = 0, 32 + MT6358_LDO_TOP, 33 + MT6358_PSC_TOP, 34 + MT6358_SCK_TOP, 35 + MT6358_BM_TOP, 36 + MT6358_HK_TOP, 37 + MT6358_AUD_TOP, 38 + MT6358_MISC_TOP, 39 + }; 40 + 41 + enum mt6358_irq_numbers { 42 + MT6358_IRQ_VPROC11_OC = 0, 43 + MT6358_IRQ_VPROC12_OC, 44 + MT6358_IRQ_VCORE_OC, 45 + MT6358_IRQ_VGPU_OC, 46 + MT6358_IRQ_VMODEM_OC, 47 + MT6358_IRQ_VDRAM1_OC, 48 + MT6358_IRQ_VS1_OC, 49 + MT6358_IRQ_VS2_OC, 50 + MT6358_IRQ_VPA_OC, 51 + MT6358_IRQ_VCORE_PREOC, 52 + MT6358_IRQ_VFE28_OC = 16, 53 + MT6358_IRQ_VXO22_OC, 54 + MT6358_IRQ_VRF18_OC, 55 + MT6358_IRQ_VRF12_OC, 56 + MT6358_IRQ_VEFUSE_OC, 57 + MT6358_IRQ_VCN33_OC, 58 + MT6358_IRQ_VCN28_OC, 59 + MT6358_IRQ_VCN18_OC, 60 + MT6358_IRQ_VCAMA1_OC, 61 + MT6358_IRQ_VCAMA2_OC, 62 + MT6358_IRQ_VCAMD_OC, 63 + MT6358_IRQ_VCAMIO_OC, 64 + MT6358_IRQ_VLDO28_OC, 65 + MT6358_IRQ_VA12_OC, 66 + MT6358_IRQ_VAUX18_OC, 67 + MT6358_IRQ_VAUD28_OC, 68 + MT6358_IRQ_VIO28_OC, 69 + MT6358_IRQ_VIO18_OC, 70 + MT6358_IRQ_VSRAM_PROC11_OC, 71 + MT6358_IRQ_VSRAM_PROC12_OC, 72 + MT6358_IRQ_VSRAM_OTHERS_OC, 73 + MT6358_IRQ_VSRAM_GPU_OC, 74 + MT6358_IRQ_VDRAM2_OC, 75 + MT6358_IRQ_VMC_OC, 76 + MT6358_IRQ_VMCH_OC, 77 + MT6358_IRQ_VEMC_OC, 78 + MT6358_IRQ_VSIM1_OC, 79 + MT6358_IRQ_VSIM2_OC, 80 + MT6358_IRQ_VIBR_OC, 81 + MT6358_IRQ_VUSB_OC, 82 + MT6358_IRQ_VBIF28_OC, 83 + MT6358_IRQ_PWRKEY = 48, 84 + MT6358_IRQ_HOMEKEY, 85 + MT6358_IRQ_PWRKEY_R, 86 + MT6358_IRQ_HOMEKEY_R, 87 + MT6358_IRQ_NI_LBAT_INT, 88 + MT6358_IRQ_CHRDET, 89 + MT6358_IRQ_CHRDET_EDGE, 90 + MT6358_IRQ_VCDT_HV_DET, 91 + MT6358_IRQ_RTC = 64, 92 + MT6358_IRQ_FG_BAT0_H = 80, 93 + MT6358_IRQ_FG_BAT0_L, 94 + MT6358_IRQ_FG_CUR_H, 95 + MT6358_IRQ_FG_CUR_L, 96 + MT6358_IRQ_FG_ZCV, 97 + MT6358_IRQ_FG_BAT1_H, 98 + MT6358_IRQ_FG_BAT1_L, 99 + MT6358_IRQ_FG_N_CHARGE_L, 100 + MT6358_IRQ_FG_IAVG_H, 101 + MT6358_IRQ_FG_IAVG_L, 102 + MT6358_IRQ_FG_TIME_H, 103 + MT6358_IRQ_FG_DISCHARGE, 104 + MT6358_IRQ_FG_CHARGE, 105 + MT6358_IRQ_BATON_LV = 96, 106 + MT6358_IRQ_BATON_HT, 107 + MT6358_IRQ_BATON_BAT_IN, 108 + MT6358_IRQ_BATON_BAT_OUT, 109 + MT6358_IRQ_BIF, 110 + MT6358_IRQ_BAT_H = 112, 111 + MT6358_IRQ_BAT_L, 112 + MT6358_IRQ_BAT2_H, 113 + MT6358_IRQ_BAT2_L, 114 + MT6358_IRQ_BAT_TEMP_H, 115 + MT6358_IRQ_BAT_TEMP_L, 116 + MT6358_IRQ_AUXADC_IMP, 117 + MT6358_IRQ_NAG_C_DLTV, 118 + MT6358_IRQ_AUDIO = 128, 119 + MT6358_IRQ_ACCDET = 133, 120 + MT6358_IRQ_ACCDET_EINT0, 121 + MT6358_IRQ_ACCDET_EINT1, 122 + MT6358_IRQ_SPI_CMD_ALERT = 144, 123 + MT6358_IRQ_NR, 124 + }; 125 + 126 + #define MT6358_IRQ_BUCK_BASE MT6358_IRQ_VPROC11_OC 127 + #define MT6358_IRQ_LDO_BASE MT6358_IRQ_VFE28_OC 128 + #define MT6358_IRQ_PSC_BASE MT6358_IRQ_PWRKEY 129 + #define MT6358_IRQ_SCK_BASE MT6358_IRQ_RTC 130 + #define MT6358_IRQ_BM_BASE MT6358_IRQ_FG_BAT0_H 131 + #define MT6358_IRQ_HK_BASE MT6358_IRQ_BAT_H 132 + #define MT6358_IRQ_AUD_BASE MT6358_IRQ_AUDIO 133 + #define MT6358_IRQ_MISC_BASE MT6358_IRQ_SPI_CMD_ALERT 134 + 135 + #define MT6358_IRQ_BUCK_BITS (MT6358_IRQ_VCORE_PREOC - MT6358_IRQ_BUCK_BASE + 1) 136 + #define MT6358_IRQ_LDO_BITS (MT6358_IRQ_VBIF28_OC - MT6358_IRQ_LDO_BASE + 1) 137 + #define MT6358_IRQ_PSC_BITS (MT6358_IRQ_VCDT_HV_DET - MT6358_IRQ_PSC_BASE + 1) 138 + #define MT6358_IRQ_SCK_BITS (MT6358_IRQ_RTC - MT6358_IRQ_SCK_BASE + 1) 139 + #define MT6358_IRQ_BM_BITS (MT6358_IRQ_BIF - MT6358_IRQ_BM_BASE + 1) 140 + #define MT6358_IRQ_HK_BITS (MT6358_IRQ_NAG_C_DLTV - MT6358_IRQ_HK_BASE + 1) 141 + #define MT6358_IRQ_AUD_BITS (MT6358_IRQ_ACCDET_EINT1 - MT6358_IRQ_AUD_BASE + 1) 142 + #define MT6358_IRQ_MISC_BITS \ 143 + (MT6358_IRQ_SPI_CMD_ALERT - MT6358_IRQ_MISC_BASE + 1) 144 + 145 + #define MT6358_TOP_GEN(sp) \ 146 + { \ 147 + .hwirq_base = MT6358_IRQ_##sp##_BASE, \ 148 + .num_int_regs = \ 149 + ((MT6358_IRQ_##sp##_BITS - 1) / MT6358_REG_WIDTH) + 1, \ 150 + .num_int_bits = MT6358_IRQ_##sp##_BITS, \ 151 + .en_reg = MT6358_##sp##_TOP_INT_CON0, \ 152 + .en_reg_shift = 0x6, \ 153 + .sta_reg = MT6358_##sp##_TOP_INT_STATUS0, \ 154 + .sta_reg_shift = 0x2, \ 155 + .top_offset = MT6358_##sp##_TOP, \ 156 + } 157 + 158 + #endif /* __MFD_MT6358_CORE_H__ */
+282
include/linux/mfd/mt6358/registers.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2020 MediaTek Inc. 4 + */ 5 + 6 + #ifndef __MFD_MT6358_REGISTERS_H__ 7 + #define __MFD_MT6358_REGISTERS_H__ 8 + 9 + /* PMIC Registers */ 10 + #define MT6358_SWCID 0xa 11 + #define MT6358_MISC_TOP_INT_CON0 0x188 12 + #define MT6358_MISC_TOP_INT_STATUS0 0x194 13 + #define MT6358_TOP_INT_STATUS0 0x19e 14 + #define MT6358_SCK_TOP_INT_CON0 0x52e 15 + #define MT6358_SCK_TOP_INT_STATUS0 0x53a 16 + #define MT6358_EOSC_CALI_CON0 0x540 17 + #define MT6358_EOSC_CALI_CON1 0x542 18 + #define MT6358_RTC_MIX_CON0 0x544 19 + #define MT6358_RTC_MIX_CON1 0x546 20 + #define MT6358_RTC_MIX_CON2 0x548 21 + #define MT6358_RTC_DSN_ID 0x580 22 + #define MT6358_RTC_DSN_REV0 0x582 23 + #define MT6358_RTC_DBI 0x584 24 + #define MT6358_RTC_DXI 0x586 25 + #define MT6358_RTC_BBPU 0x588 26 + #define MT6358_RTC_IRQ_STA 0x58a 27 + #define MT6358_RTC_IRQ_EN 0x58c 28 + #define MT6358_RTC_CII_EN 0x58e 29 + #define MT6358_RTC_AL_MASK 0x590 30 + #define MT6358_RTC_TC_SEC 0x592 31 + #define MT6358_RTC_TC_MIN 0x594 32 + #define MT6358_RTC_TC_HOU 0x596 33 + #define MT6358_RTC_TC_DOM 0x598 34 + #define MT6358_RTC_TC_DOW 0x59a 35 + #define MT6358_RTC_TC_MTH 0x59c 36 + #define MT6358_RTC_TC_YEA 0x59e 37 + #define MT6358_RTC_AL_SEC 0x5a0 38 + #define MT6358_RTC_AL_MIN 0x5a2 39 + #define MT6358_RTC_AL_HOU 0x5a4 40 + #define MT6358_RTC_AL_DOM 0x5a6 41 + #define MT6358_RTC_AL_DOW 0x5a8 42 + #define MT6358_RTC_AL_MTH 0x5aa 43 + #define MT6358_RTC_AL_YEA 0x5ac 44 + #define MT6358_RTC_OSC32CON 0x5ae 45 + #define MT6358_RTC_POWERKEY1 0x5b0 46 + #define MT6358_RTC_POWERKEY2 0x5b2 47 + #define MT6358_RTC_PDN1 0x5b4 48 + #define MT6358_RTC_PDN2 0x5b6 49 + #define MT6358_RTC_SPAR0 0x5b8 50 + #define MT6358_RTC_SPAR1 0x5ba 51 + #define MT6358_RTC_PROT 0x5bc 52 + #define MT6358_RTC_DIFF 0x5be 53 + #define MT6358_RTC_CALI 0x5c0 54 + #define MT6358_RTC_WRTGR 0x5c2 55 + #define MT6358_RTC_CON 0x5c4 56 + #define MT6358_RTC_SEC_CTRL 0x5c6 57 + #define MT6358_RTC_INT_CNT 0x5c8 58 + #define MT6358_RTC_SEC_DAT0 0x5ca 59 + #define MT6358_RTC_SEC_DAT1 0x5cc 60 + #define MT6358_RTC_SEC_DAT2 0x5ce 61 + #define MT6358_RTC_SEC_DSN_ID 0x600 62 + #define MT6358_RTC_SEC_DSN_REV0 0x602 63 + #define MT6358_RTC_SEC_DBI 0x604 64 + #define MT6358_RTC_SEC_DXI 0x606 65 + #define MT6358_RTC_TC_SEC_SEC 0x608 66 + #define MT6358_RTC_TC_MIN_SEC 0x60a 67 + #define MT6358_RTC_TC_HOU_SEC 0x60c 68 + #define MT6358_RTC_TC_DOM_SEC 0x60e 69 + #define MT6358_RTC_TC_DOW_SEC 0x610 70 + #define MT6358_RTC_TC_MTH_SEC 0x612 71 + #define MT6358_RTC_TC_YEA_SEC 0x614 72 + #define MT6358_RTC_SEC_CK_PDN 0x616 73 + #define MT6358_RTC_SEC_WRTGR 0x618 74 + #define MT6358_PSC_TOP_INT_CON0 0x910 75 + #define MT6358_PSC_TOP_INT_STATUS0 0x91c 76 + #define MT6358_BM_TOP_INT_CON0 0xc32 77 + #define MT6358_BM_TOP_INT_CON1 0xc38 78 + #define MT6358_BM_TOP_INT_STATUS0 0xc4a 79 + #define MT6358_BM_TOP_INT_STATUS1 0xc4c 80 + #define MT6358_HK_TOP_INT_CON0 0xf92 81 + #define MT6358_HK_TOP_INT_STATUS0 0xf9e 82 + #define MT6358_BUCK_TOP_INT_CON0 0x1318 83 + #define MT6358_BUCK_TOP_INT_STATUS0 0x1324 84 + #define MT6358_BUCK_VPROC11_CON0 0x1388 85 + #define MT6358_BUCK_VPROC11_DBG0 0x139e 86 + #define MT6358_BUCK_VPROC11_DBG1 0x13a0 87 + #define MT6358_BUCK_VPROC11_ELR0 0x13a6 88 + #define MT6358_BUCK_VPROC12_CON0 0x1408 89 + #define MT6358_BUCK_VPROC12_DBG0 0x141e 90 + #define MT6358_BUCK_VPROC12_DBG1 0x1420 91 + #define MT6358_BUCK_VPROC12_ELR0 0x1426 92 + #define MT6358_BUCK_VCORE_CON0 0x1488 93 + #define MT6358_BUCK_VCORE_DBG0 0x149e 94 + #define MT6358_BUCK_VCORE_DBG1 0x14a0 95 + #define MT6358_BUCK_VCORE_ELR0 0x14aa 96 + #define MT6358_BUCK_VGPU_CON0 0x1508 97 + #define MT6358_BUCK_VGPU_DBG0 0x151e 98 + #define MT6358_BUCK_VGPU_DBG1 0x1520 99 + #define MT6358_BUCK_VGPU_ELR0 0x1526 100 + #define MT6358_BUCK_VMODEM_CON0 0x1588 101 + #define MT6358_BUCK_VMODEM_DBG0 0x159e 102 + #define MT6358_BUCK_VMODEM_DBG1 0x15a0 103 + #define MT6358_BUCK_VMODEM_ELR0 0x15a6 104 + #define MT6358_BUCK_VDRAM1_CON0 0x1608 105 + #define MT6358_BUCK_VDRAM1_DBG0 0x161e 106 + #define MT6358_BUCK_VDRAM1_DBG1 0x1620 107 + #define MT6358_BUCK_VDRAM1_ELR0 0x1626 108 + #define MT6358_BUCK_VS1_CON0 0x1688 109 + #define MT6358_BUCK_VS1_DBG0 0x169e 110 + #define MT6358_BUCK_VS1_DBG1 0x16a0 111 + #define MT6358_BUCK_VS1_ELR0 0x16ae 112 + #define MT6358_BUCK_VS2_CON0 0x1708 113 + #define MT6358_BUCK_VS2_DBG0 0x171e 114 + #define MT6358_BUCK_VS2_DBG1 0x1720 115 + #define MT6358_BUCK_VS2_ELR0 0x172e 116 + #define MT6358_BUCK_VPA_CON0 0x1788 117 + #define MT6358_BUCK_VPA_CON1 0x178a 118 + #define MT6358_BUCK_VPA_ELR0 MT6358_BUCK_VPA_CON1 119 + #define MT6358_BUCK_VPA_DBG0 0x1792 120 + #define MT6358_BUCK_VPA_DBG1 0x1794 121 + #define MT6358_VPROC_ANA_CON0 0x180c 122 + #define MT6358_VCORE_VGPU_ANA_CON0 0x1828 123 + #define MT6358_VMODEM_ANA_CON0 0x1888 124 + #define MT6358_VDRAM1_ANA_CON0 0x1896 125 + #define MT6358_VS1_ANA_CON0 0x18a2 126 + #define MT6358_VS2_ANA_CON0 0x18ae 127 + #define MT6358_VPA_ANA_CON0 0x18ba 128 + #define MT6358_LDO_TOP_INT_CON0 0x1a50 129 + #define MT6358_LDO_TOP_INT_CON1 0x1a56 130 + #define MT6358_LDO_TOP_INT_STATUS0 0x1a68 131 + #define MT6358_LDO_TOP_INT_STATUS1 0x1a6a 132 + #define MT6358_LDO_VXO22_CON0 0x1a88 133 + #define MT6358_LDO_VXO22_CON1 0x1a96 134 + #define MT6358_LDO_VA12_CON0 0x1a9c 135 + #define MT6358_LDO_VA12_CON1 0x1aaa 136 + #define MT6358_LDO_VAUX18_CON0 0x1ab0 137 + #define MT6358_LDO_VAUX18_CON1 0x1abe 138 + #define MT6358_LDO_VAUD28_CON0 0x1ac4 139 + #define MT6358_LDO_VAUD28_CON1 0x1ad2 140 + #define MT6358_LDO_VIO28_CON0 0x1ad8 141 + #define MT6358_LDO_VIO28_CON1 0x1ae6 142 + #define MT6358_LDO_VIO18_CON0 0x1aec 143 + #define MT6358_LDO_VIO18_CON1 0x1afa 144 + #define MT6358_LDO_VDRAM2_CON0 0x1b08 145 + #define MT6358_LDO_VDRAM2_CON1 0x1b16 146 + #define MT6358_LDO_VEMC_CON0 0x1b1c 147 + #define MT6358_LDO_VEMC_CON1 0x1b2a 148 + #define MT6358_LDO_VUSB_CON0_0 0x1b30 149 + #define MT6358_LDO_VUSB_CON1 0x1b40 150 + #define MT6358_LDO_VSRAM_PROC11_CON0 0x1b46 151 + #define MT6358_LDO_VSRAM_PROC11_DBG0 0x1b60 152 + #define MT6358_LDO_VSRAM_PROC11_DBG1 0x1b62 153 + #define MT6358_LDO_VSRAM_PROC11_TRACKING_CON0 0x1b64 154 + #define MT6358_LDO_VSRAM_PROC11_TRACKING_CON1 0x1b66 155 + #define MT6358_LDO_VSRAM_PROC11_TRACKING_CON2 0x1b68 156 + #define MT6358_LDO_VSRAM_PROC11_TRACKING_CON3 0x1b6a 157 + #define MT6358_LDO_VSRAM_PROC12_TRACKING_CON0 0x1b6c 158 + #define MT6358_LDO_VSRAM_PROC12_TRACKING_CON1 0x1b6e 159 + #define MT6358_LDO_VSRAM_PROC12_TRACKING_CON2 0x1b70 160 + #define MT6358_LDO_VSRAM_PROC12_TRACKING_CON3 0x1b72 161 + #define MT6358_LDO_VSRAM_WAKEUP_CON0 0x1b74 162 + #define MT6358_LDO_GON1_ELR_NUM 0x1b76 163 + #define MT6358_LDO_VDRAM2_ELR0 0x1b78 164 + #define MT6358_LDO_VSRAM_PROC12_CON0 0x1b88 165 + #define MT6358_LDO_VSRAM_PROC12_DBG0 0x1ba2 166 + #define MT6358_LDO_VSRAM_PROC12_DBG1 0x1ba4 167 + #define MT6358_LDO_VSRAM_OTHERS_CON0 0x1ba6 168 + #define MT6358_LDO_VSRAM_OTHERS_DBG0 0x1bc0 169 + #define MT6358_LDO_VSRAM_OTHERS_DBG1 0x1bc2 170 + #define MT6358_LDO_VSRAM_GPU_CON0 0x1bc8 171 + #define MT6358_LDO_VSRAM_GPU_DBG0 0x1be2 172 + #define MT6358_LDO_VSRAM_GPU_DBG1 0x1be4 173 + #define MT6358_LDO_VSRAM_CON0 0x1bee 174 + #define MT6358_LDO_VSRAM_CON1 0x1bf0 175 + #define MT6358_LDO_VSRAM_CON2 0x1bf2 176 + #define MT6358_LDO_VSRAM_CON3 0x1bf4 177 + #define MT6358_LDO_VFE28_CON0 0x1c08 178 + #define MT6358_LDO_VFE28_CON1 0x1c16 179 + #define MT6358_LDO_VFE28_CON2 0x1c18 180 + #define MT6358_LDO_VFE28_CON3 0x1c1a 181 + #define MT6358_LDO_VRF18_CON0 0x1c1c 182 + #define MT6358_LDO_VRF18_CON1 0x1c2a 183 + #define MT6358_LDO_VRF18_CON2 0x1c2c 184 + #define MT6358_LDO_VRF18_CON3 0x1c2e 185 + #define MT6358_LDO_VRF12_CON0 0x1c30 186 + #define MT6358_LDO_VRF12_CON1 0x1c3e 187 + #define MT6358_LDO_VRF12_CON2 0x1c40 188 + #define MT6358_LDO_VRF12_CON3 0x1c42 189 + #define MT6358_LDO_VEFUSE_CON0 0x1c44 190 + #define MT6358_LDO_VEFUSE_CON1 0x1c52 191 + #define MT6358_LDO_VEFUSE_CON2 0x1c54 192 + #define MT6358_LDO_VEFUSE_CON3 0x1c56 193 + #define MT6358_LDO_VCN18_CON0 0x1c58 194 + #define MT6358_LDO_VCN18_CON1 0x1c66 195 + #define MT6358_LDO_VCN18_CON2 0x1c68 196 + #define MT6358_LDO_VCN18_CON3 0x1c6a 197 + #define MT6358_LDO_VCAMA1_CON0 0x1c6c 198 + #define MT6358_LDO_VCAMA1_CON1 0x1c7a 199 + #define MT6358_LDO_VCAMA1_CON2 0x1c7c 200 + #define MT6358_LDO_VCAMA1_CON3 0x1c7e 201 + #define MT6358_LDO_VCAMA2_CON0 0x1c88 202 + #define MT6358_LDO_VCAMA2_CON1 0x1c96 203 + #define MT6358_LDO_VCAMA2_CON2 0x1c98 204 + #define MT6358_LDO_VCAMA2_CON3 0x1c9a 205 + #define MT6358_LDO_VCAMD_CON0 0x1c9c 206 + #define MT6358_LDO_VCAMD_CON1 0x1caa 207 + #define MT6358_LDO_VCAMD_CON2 0x1cac 208 + #define MT6358_LDO_VCAMD_CON3 0x1cae 209 + #define MT6358_LDO_VCAMIO_CON0 0x1cb0 210 + #define MT6358_LDO_VCAMIO_CON1 0x1cbe 211 + #define MT6358_LDO_VCAMIO_CON2 0x1cc0 212 + #define MT6358_LDO_VCAMIO_CON3 0x1cc2 213 + #define MT6358_LDO_VMC_CON0 0x1cc4 214 + #define MT6358_LDO_VMC_CON1 0x1cd2 215 + #define MT6358_LDO_VMC_CON2 0x1cd4 216 + #define MT6358_LDO_VMC_CON3 0x1cd6 217 + #define MT6358_LDO_VMCH_CON0 0x1cd8 218 + #define MT6358_LDO_VMCH_CON1 0x1ce6 219 + #define MT6358_LDO_VMCH_CON2 0x1ce8 220 + #define MT6358_LDO_VMCH_CON3 0x1cea 221 + #define MT6358_LDO_VIBR_CON0 0x1d08 222 + #define MT6358_LDO_VIBR_CON1 0x1d16 223 + #define MT6358_LDO_VIBR_CON2 0x1d18 224 + #define MT6358_LDO_VIBR_CON3 0x1d1a 225 + #define MT6358_LDO_VCN33_CON0_0 0x1d1c 226 + #define MT6358_LDO_VCN33_CON0_1 0x1d2a 227 + #define MT6358_LDO_VCN33_CON1 0x1d2c 228 + #define MT6358_LDO_VCN33_BT_CON1 MT6358_LDO_VCN33_CON1 229 + #define MT6358_LDO_VCN33_WIFI_CON1 MT6358_LDO_VCN33_CON1 230 + #define MT6358_LDO_VCN33_CON2 0x1d2e 231 + #define MT6358_LDO_VCN33_CON3 0x1d30 232 + #define MT6358_LDO_VLDO28_CON0_0 0x1d32 233 + #define MT6358_LDO_VLDO28_CON0_1 0x1d40 234 + #define MT6358_LDO_VLDO28_CON1 0x1d42 235 + #define MT6358_LDO_VLDO28_CON2 0x1d44 236 + #define MT6358_LDO_VLDO28_CON3 0x1d46 237 + #define MT6358_LDO_VSIM1_CON0 0x1d48 238 + #define MT6358_LDO_VSIM1_CON1 0x1d56 239 + #define MT6358_LDO_VSIM1_CON2 0x1d58 240 + #define MT6358_LDO_VSIM1_CON3 0x1d5a 241 + #define MT6358_LDO_VSIM2_CON0 0x1d5c 242 + #define MT6358_LDO_VSIM2_CON1 0x1d6a 243 + #define MT6358_LDO_VSIM2_CON2 0x1d6c 244 + #define MT6358_LDO_VSIM2_CON3 0x1d6e 245 + #define MT6358_LDO_VCN28_CON0 0x1d88 246 + #define MT6358_LDO_VCN28_CON1 0x1d96 247 + #define MT6358_LDO_VCN28_CON2 0x1d98 248 + #define MT6358_LDO_VCN28_CON3 0x1d9a 249 + #define MT6358_VRTC28_CON0 0x1d9c 250 + #define MT6358_LDO_VBIF28_CON0 0x1d9e 251 + #define MT6358_LDO_VBIF28_CON1 0x1dac 252 + #define MT6358_LDO_VBIF28_CON2 0x1dae 253 + #define MT6358_LDO_VBIF28_CON3 0x1db0 254 + #define MT6358_VCAMA1_ANA_CON0 0x1e08 255 + #define MT6358_VCAMA2_ANA_CON0 0x1e0c 256 + #define MT6358_VCN33_ANA_CON0 0x1e28 257 + #define MT6358_VSIM1_ANA_CON0 0x1e2c 258 + #define MT6358_VSIM2_ANA_CON0 0x1e30 259 + #define MT6358_VUSB_ANA_CON0 0x1e34 260 + #define MT6358_VEMC_ANA_CON0 0x1e38 261 + #define MT6358_VLDO28_ANA_CON0 0x1e3c 262 + #define MT6358_VIO28_ANA_CON0 0x1e40 263 + #define MT6358_VIBR_ANA_CON0 0x1e44 264 + #define MT6358_VMCH_ANA_CON0 0x1e48 265 + #define MT6358_VMC_ANA_CON0 0x1e4c 266 + #define MT6358_VRF18_ANA_CON0 0x1e88 267 + #define MT6358_VCN18_ANA_CON0 0x1e8c 268 + #define MT6358_VCAMIO_ANA_CON0 0x1e90 269 + #define MT6358_VIO18_ANA_CON0 0x1e94 270 + #define MT6358_VEFUSE_ANA_CON0 0x1e98 271 + #define MT6358_VRF12_ANA_CON0 0x1e9c 272 + #define MT6358_VSRAM_PROC11_ANA_CON0 0x1ea0 273 + #define MT6358_VSRAM_PROC12_ANA_CON0 0x1ea4 274 + #define MT6358_VSRAM_OTHERS_ANA_CON0 0x1ea6 275 + #define MT6358_VSRAM_GPU_ANA_CON0 0x1ea8 276 + #define MT6358_VDRAM2_ANA_CON0 0x1eaa 277 + #define MT6358_VCAMD_ANA_CON0 0x1eae 278 + #define MT6358_VA12_ANA_CON0 0x1eb2 279 + #define MT6358_AUD_TOP_INT_CON0 0x2228 280 + #define MT6358_AUD_TOP_INT_STATUS0 0x2234 281 + 282 + #endif /* __MFD_MT6358_REGISTERS_H__ */
+240
include/linux/mfd/mt6360.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2020 MediaTek Inc. 4 + */ 5 + 6 + #ifndef __MT6360_H__ 7 + #define __MT6360_H__ 8 + 9 + #include <linux/regmap.h> 10 + 11 + enum { 12 + MT6360_SLAVE_PMU = 0, 13 + MT6360_SLAVE_PMIC, 14 + MT6360_SLAVE_LDO, 15 + MT6360_SLAVE_TCPC, 16 + MT6360_SLAVE_MAX, 17 + }; 18 + 19 + #define MT6360_PMU_SLAVEID (0x34) 20 + #define MT6360_PMIC_SLAVEID (0x1A) 21 + #define MT6360_LDO_SLAVEID (0x64) 22 + #define MT6360_TCPC_SLAVEID (0x4E) 23 + 24 + struct mt6360_pmu_data { 25 + struct i2c_client *i2c[MT6360_SLAVE_MAX]; 26 + struct device *dev; 27 + struct regmap *regmap; 28 + struct regmap_irq_chip_data *irq_data; 29 + unsigned int chip_rev; 30 + }; 31 + 32 + /* PMU register defininition */ 33 + #define MT6360_PMU_DEV_INFO (0x00) 34 + #define MT6360_PMU_CORE_CTRL1 (0x01) 35 + #define MT6360_PMU_RST1 (0x02) 36 + #define MT6360_PMU_CRCEN (0x03) 37 + #define MT6360_PMU_RST_PAS_CODE1 (0x04) 38 + #define MT6360_PMU_RST_PAS_CODE2 (0x05) 39 + #define MT6360_PMU_CORE_CTRL2 (0x06) 40 + #define MT6360_PMU_TM_PAS_CODE1 (0x07) 41 + #define MT6360_PMU_TM_PAS_CODE2 (0x08) 42 + #define MT6360_PMU_TM_PAS_CODE3 (0x09) 43 + #define MT6360_PMU_TM_PAS_CODE4 (0x0A) 44 + #define MT6360_PMU_IRQ_IND (0x0B) 45 + #define MT6360_PMU_IRQ_MASK (0x0C) 46 + #define MT6360_PMU_IRQ_SET (0x0D) 47 + #define MT6360_PMU_SHDN_CTRL (0x0E) 48 + #define MT6360_PMU_TM_INF (0x0F) 49 + #define MT6360_PMU_I2C_CTRL (0x10) 50 + #define MT6360_PMU_CHG_CTRL1 (0x11) 51 + #define MT6360_PMU_CHG_CTRL2 (0x12) 52 + #define MT6360_PMU_CHG_CTRL3 (0x13) 53 + #define MT6360_PMU_CHG_CTRL4 (0x14) 54 + #define MT6360_PMU_CHG_CTRL5 (0x15) 55 + #define MT6360_PMU_CHG_CTRL6 (0x16) 56 + #define MT6360_PMU_CHG_CTRL7 (0x17) 57 + #define MT6360_PMU_CHG_CTRL8 (0x18) 58 + #define MT6360_PMU_CHG_CTRL9 (0x19) 59 + #define MT6360_PMU_CHG_CTRL10 (0x1A) 60 + #define MT6360_PMU_CHG_CTRL11 (0x1B) 61 + #define MT6360_PMU_CHG_CTRL12 (0x1C) 62 + #define MT6360_PMU_CHG_CTRL13 (0x1D) 63 + #define MT6360_PMU_CHG_CTRL14 (0x1E) 64 + #define MT6360_PMU_CHG_CTRL15 (0x1F) 65 + #define MT6360_PMU_CHG_CTRL16 (0x20) 66 + #define MT6360_PMU_CHG_AICC_RESULT (0x21) 67 + #define MT6360_PMU_DEVICE_TYPE (0x22) 68 + #define MT6360_PMU_QC_CONTROL1 (0x23) 69 + #define MT6360_PMU_QC_CONTROL2 (0x24) 70 + #define MT6360_PMU_QC30_CONTROL1 (0x25) 71 + #define MT6360_PMU_QC30_CONTROL2 (0x26) 72 + #define MT6360_PMU_USB_STATUS1 (0x27) 73 + #define MT6360_PMU_QC_STATUS1 (0x28) 74 + #define MT6360_PMU_QC_STATUS2 (0x29) 75 + #define MT6360_PMU_CHG_PUMP (0x2A) 76 + #define MT6360_PMU_CHG_CTRL17 (0x2B) 77 + #define MT6360_PMU_CHG_CTRL18 (0x2C) 78 + #define MT6360_PMU_CHRDET_CTRL1 (0x2D) 79 + #define MT6360_PMU_CHRDET_CTRL2 (0x2E) 80 + #define MT6360_PMU_DPDN_CTRL (0x2F) 81 + #define MT6360_PMU_CHG_HIDDEN_CTRL1 (0x30) 82 + #define MT6360_PMU_CHG_HIDDEN_CTRL2 (0x31) 83 + #define MT6360_PMU_CHG_HIDDEN_CTRL3 (0x32) 84 + #define MT6360_PMU_CHG_HIDDEN_CTRL4 (0x33) 85 + #define MT6360_PMU_CHG_HIDDEN_CTRL5 (0x34) 86 + #define MT6360_PMU_CHG_HIDDEN_CTRL6 (0x35) 87 + #define MT6360_PMU_CHG_HIDDEN_CTRL7 (0x36) 88 + #define MT6360_PMU_CHG_HIDDEN_CTRL8 (0x37) 89 + #define MT6360_PMU_CHG_HIDDEN_CTRL9 (0x38) 90 + #define MT6360_PMU_CHG_HIDDEN_CTRL10 (0x39) 91 + #define MT6360_PMU_CHG_HIDDEN_CTRL11 (0x3A) 92 + #define MT6360_PMU_CHG_HIDDEN_CTRL12 (0x3B) 93 + #define MT6360_PMU_CHG_HIDDEN_CTRL13 (0x3C) 94 + #define MT6360_PMU_CHG_HIDDEN_CTRL14 (0x3D) 95 + #define MT6360_PMU_CHG_HIDDEN_CTRL15 (0x3E) 96 + #define MT6360_PMU_CHG_HIDDEN_CTRL16 (0x3F) 97 + #define MT6360_PMU_CHG_HIDDEN_CTRL17 (0x40) 98 + #define MT6360_PMU_CHG_HIDDEN_CTRL18 (0x41) 99 + #define MT6360_PMU_CHG_HIDDEN_CTRL19 (0x42) 100 + #define MT6360_PMU_CHG_HIDDEN_CTRL20 (0x43) 101 + #define MT6360_PMU_CHG_HIDDEN_CTRL21 (0x44) 102 + #define MT6360_PMU_CHG_HIDDEN_CTRL22 (0x45) 103 + #define MT6360_PMU_CHG_HIDDEN_CTRL23 (0x46) 104 + #define MT6360_PMU_CHG_HIDDEN_CTRL24 (0x47) 105 + #define MT6360_PMU_CHG_HIDDEN_CTRL25 (0x48) 106 + #define MT6360_PMU_BC12_CTRL (0x49) 107 + #define MT6360_PMU_CHG_STAT (0x4A) 108 + #define MT6360_PMU_RESV1 (0x4B) 109 + #define MT6360_PMU_TYPEC_OTP_TH_SEL_CODEH (0x4E) 110 + #define MT6360_PMU_TYPEC_OTP_TH_SEL_CODEL (0x4F) 111 + #define MT6360_PMU_TYPEC_OTP_HYST_TH (0x50) 112 + #define MT6360_PMU_TYPEC_OTP_CTRL (0x51) 113 + #define MT6360_PMU_ADC_BAT_DATA_H (0x52) 114 + #define MT6360_PMU_ADC_BAT_DATA_L (0x53) 115 + #define MT6360_PMU_IMID_BACKBST_ON (0x54) 116 + #define MT6360_PMU_IMID_BACKBST_OFF (0x55) 117 + #define MT6360_PMU_ADC_CONFIG (0x56) 118 + #define MT6360_PMU_ADC_EN2 (0x57) 119 + #define MT6360_PMU_ADC_IDLE_T (0x58) 120 + #define MT6360_PMU_ADC_RPT_1 (0x5A) 121 + #define MT6360_PMU_ADC_RPT_2 (0x5B) 122 + #define MT6360_PMU_ADC_RPT_3 (0x5C) 123 + #define MT6360_PMU_ADC_RPT_ORG1 (0x5D) 124 + #define MT6360_PMU_ADC_RPT_ORG2 (0x5E) 125 + #define MT6360_PMU_BAT_OVP_TH_SEL_CODEH (0x5F) 126 + #define MT6360_PMU_BAT_OVP_TH_SEL_CODEL (0x60) 127 + #define MT6360_PMU_CHG_CTRL19 (0x61) 128 + #define MT6360_PMU_VDDASUPPLY (0x62) 129 + #define MT6360_PMU_BC12_MANUAL (0x63) 130 + #define MT6360_PMU_CHGDET_FUNC (0x64) 131 + #define MT6360_PMU_FOD_CTRL (0x65) 132 + #define MT6360_PMU_CHG_CTRL20 (0x66) 133 + #define MT6360_PMU_CHG_HIDDEN_CTRL26 (0x67) 134 + #define MT6360_PMU_CHG_HIDDEN_CTRL27 (0x68) 135 + #define MT6360_PMU_RESV2 (0x69) 136 + #define MT6360_PMU_USBID_CTRL1 (0x6D) 137 + #define MT6360_PMU_USBID_CTRL2 (0x6E) 138 + #define MT6360_PMU_USBID_CTRL3 (0x6F) 139 + #define MT6360_PMU_FLED_CFG (0x70) 140 + #define MT6360_PMU_RESV3 (0x71) 141 + #define MT6360_PMU_FLED1_CTRL (0x72) 142 + #define MT6360_PMU_FLED_STRB_CTRL (0x73) 143 + #define MT6360_PMU_FLED1_STRB_CTRL2 (0x74) 144 + #define MT6360_PMU_FLED1_TOR_CTRL (0x75) 145 + #define MT6360_PMU_FLED2_CTRL (0x76) 146 + #define MT6360_PMU_RESV4 (0x77) 147 + #define MT6360_PMU_FLED2_STRB_CTRL2 (0x78) 148 + #define MT6360_PMU_FLED2_TOR_CTRL (0x79) 149 + #define MT6360_PMU_FLED_VMIDTRK_CTRL1 (0x7A) 150 + #define MT6360_PMU_FLED_VMID_RTM (0x7B) 151 + #define MT6360_PMU_FLED_VMIDTRK_CTRL2 (0x7C) 152 + #define MT6360_PMU_FLED_PWSEL (0x7D) 153 + #define MT6360_PMU_FLED_EN (0x7E) 154 + #define MT6360_PMU_FLED_Hidden1 (0x7F) 155 + #define MT6360_PMU_RGB_EN (0x80) 156 + #define MT6360_PMU_RGB1_ISNK (0x81) 157 + #define MT6360_PMU_RGB2_ISNK (0x82) 158 + #define MT6360_PMU_RGB3_ISNK (0x83) 159 + #define MT6360_PMU_RGB_ML_ISNK (0x84) 160 + #define MT6360_PMU_RGB1_DIM (0x85) 161 + #define MT6360_PMU_RGB2_DIM (0x86) 162 + #define MT6360_PMU_RGB3_DIM (0x87) 163 + #define MT6360_PMU_RESV5 (0x88) 164 + #define MT6360_PMU_RGB12_Freq (0x89) 165 + #define MT6360_PMU_RGB34_Freq (0x8A) 166 + #define MT6360_PMU_RGB1_Tr (0x8B) 167 + #define MT6360_PMU_RGB1_Tf (0x8C) 168 + #define MT6360_PMU_RGB1_TON_TOFF (0x8D) 169 + #define MT6360_PMU_RGB2_Tr (0x8E) 170 + #define MT6360_PMU_RGB2_Tf (0x8F) 171 + #define MT6360_PMU_RGB2_TON_TOFF (0x90) 172 + #define MT6360_PMU_RGB3_Tr (0x91) 173 + #define MT6360_PMU_RGB3_Tf (0x92) 174 + #define MT6360_PMU_RGB3_TON_TOFF (0x93) 175 + #define MT6360_PMU_RGB_Hidden_CTRL1 (0x94) 176 + #define MT6360_PMU_RGB_Hidden_CTRL2 (0x95) 177 + #define MT6360_PMU_RESV6 (0x97) 178 + #define MT6360_PMU_SPARE1 (0x9A) 179 + #define MT6360_PMU_SPARE2 (0xA0) 180 + #define MT6360_PMU_SPARE3 (0xB0) 181 + #define MT6360_PMU_SPARE4 (0xC0) 182 + #define MT6360_PMU_CHG_IRQ1 (0xD0) 183 + #define MT6360_PMU_CHG_IRQ2 (0xD1) 184 + #define MT6360_PMU_CHG_IRQ3 (0xD2) 185 + #define MT6360_PMU_CHG_IRQ4 (0xD3) 186 + #define MT6360_PMU_CHG_IRQ5 (0xD4) 187 + #define MT6360_PMU_CHG_IRQ6 (0xD5) 188 + #define MT6360_PMU_QC_IRQ (0xD6) 189 + #define MT6360_PMU_FOD_IRQ (0xD7) 190 + #define MT6360_PMU_BASE_IRQ (0xD8) 191 + #define MT6360_PMU_FLED_IRQ1 (0xD9) 192 + #define MT6360_PMU_FLED_IRQ2 (0xDA) 193 + #define MT6360_PMU_RGB_IRQ (0xDB) 194 + #define MT6360_PMU_BUCK1_IRQ (0xDC) 195 + #define MT6360_PMU_BUCK2_IRQ (0xDD) 196 + #define MT6360_PMU_LDO_IRQ1 (0xDE) 197 + #define MT6360_PMU_LDO_IRQ2 (0xDF) 198 + #define MT6360_PMU_CHG_STAT1 (0xE0) 199 + #define MT6360_PMU_CHG_STAT2 (0xE1) 200 + #define MT6360_PMU_CHG_STAT3 (0xE2) 201 + #define MT6360_PMU_CHG_STAT4 (0xE3) 202 + #define MT6360_PMU_CHG_STAT5 (0xE4) 203 + #define MT6360_PMU_CHG_STAT6 (0xE5) 204 + #define MT6360_PMU_QC_STAT (0xE6) 205 + #define MT6360_PMU_FOD_STAT (0xE7) 206 + #define MT6360_PMU_BASE_STAT (0xE8) 207 + #define MT6360_PMU_FLED_STAT1 (0xE9) 208 + #define MT6360_PMU_FLED_STAT2 (0xEA) 209 + #define MT6360_PMU_RGB_STAT (0xEB) 210 + #define MT6360_PMU_BUCK1_STAT (0xEC) 211 + #define MT6360_PMU_BUCK2_STAT (0xED) 212 + #define MT6360_PMU_LDO_STAT1 (0xEE) 213 + #define MT6360_PMU_LDO_STAT2 (0xEF) 214 + #define MT6360_PMU_CHG_MASK1 (0xF0) 215 + #define MT6360_PMU_CHG_MASK2 (0xF1) 216 + #define MT6360_PMU_CHG_MASK3 (0xF2) 217 + #define MT6360_PMU_CHG_MASK4 (0xF3) 218 + #define MT6360_PMU_CHG_MASK5 (0xF4) 219 + #define MT6360_PMU_CHG_MASK6 (0xF5) 220 + #define MT6360_PMU_QC_MASK (0xF6) 221 + #define MT6360_PMU_FOD_MASK (0xF7) 222 + #define MT6360_PMU_BASE_MASK (0xF8) 223 + #define MT6360_PMU_FLED_MASK1 (0xF9) 224 + #define MT6360_PMU_FLED_MASK2 (0xFA) 225 + #define MT6360_PMU_FAULTB_MASK (0xFB) 226 + #define MT6360_PMU_BUCK1_MASK (0xFC) 227 + #define MT6360_PMU_BUCK2_MASK (0xFD) 228 + #define MT6360_PMU_LDO_MASK1 (0xFE) 229 + #define MT6360_PMU_LDO_MASK2 (0xFF) 230 + #define MT6360_PMU_MAXREG (MT6360_PMU_LDO_MASK2) 231 + 232 + /* MT6360_PMU_IRQ_SET */ 233 + #define MT6360_PMU_IRQ_REGNUM (MT6360_PMU_LDO_IRQ2 - MT6360_PMU_CHG_IRQ1 + 1) 234 + #define MT6360_IRQ_RETRIG BIT(2) 235 + 236 + #define CHIP_VEN_MASK (0xF0) 237 + #define CHIP_VEN_MT6360 (0x50) 238 + #define CHIP_REV_MASK (0x0F) 239 + 240 + #endif /* __MT6360_H__ */
+5
include/linux/mfd/mt6397/core.h
··· 8 8 #define __MFD_MT6397_CORE_H__ 9 9 10 10 #include <linux/mutex.h> 11 + #include <linux/notifier.h> 11 12 12 13 enum chip_id { 13 14 MT6323_CHIP_ID = 0x23, 15 + MT6358_CHIP_ID = 0x58, 14 16 MT6391_CHIP_ID = 0x91, 15 17 MT6397_CHIP_ID = 0x97, 16 18 }; ··· 56 54 struct mt6397_chip { 57 55 struct device *dev; 58 56 struct regmap *regmap; 57 + struct notifier_block pm_nb; 59 58 int irq; 60 59 struct irq_domain *irq_domain; 61 60 struct mutex irqlock; ··· 66 63 u16 int_con[2]; 67 64 u16 int_status[2]; 68 65 u16 chip_id; 66 + void *irq_data; 69 67 }; 70 68 69 + int mt6358_irq_init(struct mt6397_chip *chip); 71 70 int mt6397_irq_init(struct mt6397_chip *chip); 72 71 73 72 #endif /* __MFD_MT6397_CORE_H__ */
+8 -1
include/linux/mfd/mt6397/rtc.h
··· 18 18 #define RTC_BBPU_CBUSY BIT(6) 19 19 #define RTC_BBPU_KEY (0x43 << 8) 20 20 21 - #define RTC_WRTGR 0x003c 21 + #define RTC_WRTGR_MT6358 0x003a 22 + #define RTC_WRTGR_MT6397 0x003c 23 + #define RTC_WRTGR_MT6323 RTC_WRTGR_MT6397 22 24 23 25 #define RTC_IRQ_STA 0x0002 24 26 #define RTC_IRQ_STA_AL BIT(0) ··· 67 65 #define MTK_RTC_POLL_DELAY_US 10 68 66 #define MTK_RTC_POLL_TIMEOUT (jiffies_to_usecs(HZ)) 69 67 68 + struct mtk_rtc_data { 69 + u32 wrtgr; 70 + }; 71 + 70 72 struct mt6397_rtc { 71 73 struct device *dev; 72 74 struct rtc_device *rtc_dev; ··· 80 74 struct regmap *regmap; 81 75 int irq; 82 76 u32 addr_base; 77 + const struct mtk_rtc_data *data; 83 78 }; 84 79 85 80 #endif /* _LINUX_MFD_MT6397_RTC_H_ */
+1
include/linux/mfd/stmfx.h
··· 109 109 struct device *dev; 110 110 struct regmap *map; 111 111 struct regulator *vdd; 112 + int irq; 112 113 struct irq_domain *irq_domain; 113 114 struct mutex lock; /* IRQ bus lock */ 114 115 u8 irq_src;