From: Stephen Rothwell Date: Thu, 5 Nov 2015 01:27:26 +0000 (+1100) Subject: Merge remote-tracking branch 'mfd/for-mfd-next' X-Git-Tag: KARO-TXUL-2015-12-04~83 X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-linux.git;a=commitdiff_plain;h=722fb30f8c80a06aed4ab11e2a09b8ed6a2791f0;hp=8fc781f6d45291fde1bf1ff70fa29a18fd4d30d7 Merge remote-tracking branch 'mfd/for-mfd-next' --- diff --git a/Documentation/devicetree/bindings/extcon/extcon-arizona.txt b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt new file mode 100644 index 000000000000..e1705fae63a8 --- /dev/null +++ b/Documentation/devicetree/bindings/extcon/extcon-arizona.txt @@ -0,0 +1,15 @@ +Cirrus Logic Arizona class audio SoCs + +These devices are audio SoCs with extensive digital capabilities and a range +of analogue I/O. + +This document lists Extcon specific bindings, see the primary binding document: + ../mfd/arizona.txt + +Optional properties: + + - wlf,hpdet-channel : Headphone detection channel. + ARIZONA_ACCDET_MODE_HPL or 1 - Headphone detect mode is set to HPDETL + ARIZONA_ACCDET_MODE_HPR or 2 - Headphone detect mode is set to HPDETR + If this node is not mentioned or if the value is unknown, then + headphone detection mode is set to HPDETL. diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt index a8fee60dc20d..18be0cbfb456 100644 --- a/Documentation/devicetree/bindings/mfd/arizona.txt +++ b/Documentation/devicetree/bindings/mfd/arizona.txt @@ -44,7 +44,6 @@ Required properties: Optional properties: - wlf,reset : GPIO specifier for the GPIO controlling /RESET - - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA - wlf,gpio-defaults : A list of GPIO configuration register values. Defines for the appropriate values can found in . If @@ -67,21 +66,13 @@ Optional properties: present, the number of values should be less than or equal to the number of inputs, unspecified inputs will use the chip default. - - wlf,hpdet-channel : Headphone detection channel. - ARIZONA_ACCDET_MODE_HPL or 1 - Headphone detect mode is set to HPDETL - ARIZONA_ACCDET_MODE_HPR or 2 - Headphone detect mode is set to HPDETR - If this node is not mentioned or if the value is unknown, then - headphone detection mode is set to HPDETL. - - DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if they are being externally supplied. As covered in Documentation/devicetree/bindings/regulator/regulator.txt -Optional subnodes: - - ldo1 : Initial data for the LDO1 regulator, as covered in - Documentation/devicetree/bindings/regulator/regulator.txt - - micvdd : Initial data for the MICVDD regulator, as covered in - Documentation/devicetree/bindings/regulator/regulator.txt +Also see child specific device properties: + Regulator - ../regulator/arizona-regulator.txt + Extcon - ../extcon/extcon-arizona.txt Example: diff --git a/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt b/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt new file mode 100644 index 000000000000..692300117c64 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/atmel-flexcom.txt @@ -0,0 +1,63 @@ +* Device tree bindings for Atmel Flexcom (Flexible Serial Communication Unit) + +The Atmel Flexcom is just a wrapper which embeds a SPI controller, an I2C +controller and an USART. Only one function can be used at a time and is chosen +at boot time according to the device tree. + +Required properties: +- compatible: Should be "atmel,sama5d2-flexcom" +- reg: Should be the offset/length value for Flexcom dedicated + I/O registers (without USART, TWI or SPI registers). +- clocks: Should be the Flexcom peripheral clock from PMC. +- #address-cells: Should be <1> +- #size-cells: Should be <1> +- ranges: Should be one range for the full I/O register region + (including USART, TWI and SPI registers). +- atmel,flexcom-mode: Should be one of the following values: + - <1> for USART + - <2> for SPI + - <3> for I2C + +Required child: +A single available child device of type matching the "atmel,flexcom-mode" +property. + +The phandle provided by the clocks property of the child is the same as one for +the Flexcom parent. + +For other properties, please refer to the documentations of the respective +device: +- ../serial/atmel-usart.txt +- ../spi/spi_atmel.txt +- ../i2c/i2c-at91.txt + +Example: + +flexcom@f8034000 { + compatible = "atmel,sama5d2-flexcom"; + reg = <0xf8034000 0x200>; + clocks = <&flx0_clk>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0xf8034000 0x800>; + atmel,flexcom-mode = <2>; + + spi@400 { + compatible = "atmel,at91rm9200-spi"; + reg = <0x400 0x200>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flx0_default>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&flx0_clk>; + clock-names = "spi_clk"; + atmel,fifo-size = <32>; + + mtd_dataflash@0 { + compatible = "atmel,at25f512b"; + reg = <0>; + spi-max-frequency = <20000000>; + }; + }; +}; diff --git a/Documentation/devicetree/bindings/mfd/cros-ec.txt b/Documentation/devicetree/bindings/mfd/cros-ec.txt index 1777916e9e28..136e0c2da44d 100644 --- a/Documentation/devicetree/bindings/mfd/cros-ec.txt +++ b/Documentation/devicetree/bindings/mfd/cros-ec.txt @@ -34,6 +34,10 @@ Required properties (LPC): - compatible: "google,cros-ec-lpc" - reg: List of (IO address, size) pairs defining the interface uses +Optional properties (all): +- google,has-vbc-nvram: Some implementations of the EC include a small + nvram space used to store verified boot context data. This boolean flag + is used to specify whether this nvram is present or not. Example for I2C: diff --git a/Documentation/devicetree/bindings/mfd/da9150.txt b/Documentation/devicetree/bindings/mfd/da9150.txt index d0588eaa0d71..fd4dca7f4aba 100644 --- a/Documentation/devicetree/bindings/mfd/da9150.txt +++ b/Documentation/devicetree/bindings/mfd/da9150.txt @@ -6,6 +6,7 @@ Device Description ------ ----------- da9150-gpadc : General Purpose ADC da9150-charger : Battery Charger +da9150-fg : Battery Fuel-Gauge ====== @@ -16,13 +17,13 @@ Required properties: the IRQs from da9150 are delivered to. - interrupts: IRQ line info for da9150 chip. - interrupt-controller: da9150 has internal IRQs (own IRQ domain). - (See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for + (See ../interrupt-controller/interrupts.txt for further information relating to interrupt properties) Sub-devices: -- da9150-gpadc: See Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt -- da9150-charger: See Documentation/devicetree/bindings/power/da9150-charger.txt - +- da9150-gpadc: See ../iio/adc/da9150-gpadc.txt +- da9150-charger: See ../power/da9150-charger.txt +- da9150-fg: See ../power/da9150-fg.txt Example: @@ -34,10 +35,28 @@ Example: interrupt-controller; gpadc: da9150-gpadc { - ... + compatible = "dlg,da9150-gpadc"; + #io-channel-cells = <1>; + }; + + charger { + compatible = "dlg,da9150-charger"; + + io-channels = <&gpadc 0>, + <&gpadc 2>, + <&gpadc 8>, + <&gpadc 5>; + io-channel-names = "CHAN_IBUS", + "CHAN_VBUS", + "CHAN_TJUNC", + "CHAN_VBAT"; }; - da9150-charger { - ... + fuel-gauge { + compatible = "dlg,da9150-fuel-gauge"; + + dlg,update-interval = <10000>; + dlg,warn-soc-level = /bits/ 8 <15>; + dlg,crit-soc-level = /bits/ 8 <5> }; }; diff --git a/Documentation/devicetree/bindings/mfd/s2mps11.txt b/Documentation/devicetree/bindings/mfd/s2mps11.txt index 90eaef393325..890f0b0e1643 100644 --- a/Documentation/devicetree/bindings/mfd/s2mps11.txt +++ b/Documentation/devicetree/bindings/mfd/s2mps11.txt @@ -19,6 +19,9 @@ Optional properties: connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1 register to turn off the power. Usually the ACOKB is pulled up to VBATT so when PWRHOLD pin goes low, the rising ACOKB will trigger power off. +- samsung,s2mps11-wrstbi-ground: Indicates that WRSTBI pin of PMIC is pulled + down. When the system is suspended it will always go down thus triggerring + unwanted buck warm reset (setting buck voltages to default values). Optional nodes: - clocks: s2mps11, s2mps13 and s5m8767 provide three(AP/CP/BT) buffered 32.768 diff --git a/Documentation/devicetree/bindings/power/da9150-fg.txt b/Documentation/devicetree/bindings/power/da9150-fg.txt new file mode 100644 index 000000000000..00236fe3ea31 --- /dev/null +++ b/Documentation/devicetree/bindings/power/da9150-fg.txt @@ -0,0 +1,23 @@ +Dialog Semiconductor DA9150 Fuel-Gauge Power Supply bindings + +Required properties: +- compatible: "dlg,da9150-fuel-gauge" for DA9150 Fuel-Gauge Power Supply + +Optional properties: +- dlg,update-interval: Interval time (milliseconds) between battery level checks. +- dlg,warn-soc-level: Battery discharge level (%) where warning event raised. + [1 - 100] +- dlg,crit-soc-level: Battery discharge level (%) where critical event raised. + This value should be lower than the warning level. + [1 - 100] + + +Example: + + fuel-gauge { + compatible = "dlg,da9150-fuel-gauge"; + + dlg,update-interval = <10000>; + dlg,warn-soc-level = /bits/ 8 <15>; + dlg,crit-soc-level = /bits/ 8 <5>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index accfbfa673b1..5d9e7fd176c5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7132,7 +7132,6 @@ F: drivers/media/i2c/mt9v032.c F: include/media/mt9v032.h MULTIFUNCTION DEVICES (MFD) -M: Samuel Ortiz M: Lee Jones T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git S: Supported @@ -11545,6 +11544,9 @@ T: git https://github.com/CirrusLogic/linux-drivers.git W: https://github.com/CirrusLogic/linux-drivers/wiki S: Supported F: Documentation/hwmon/wm83?? +F: Documentation/devicetree/bindings/extcon/extcon-arizona.txt +F: Documentation/devicetree/bindings/regulator/arizona-regulator.txt +F: Documentation/devicetree/bindings/mfd/arizona.txt F: arch/arm/mach-s3c64xx/mach-crag6410* F: drivers/clk/clk-wm83*.c F: drivers/extcon/extcon-arizona.c diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c index 4b9f09cc38d8..4479781ee941 100644 --- a/drivers/extcon/extcon-arizona.c +++ b/drivers/extcon/extcon-arizona.c @@ -43,11 +43,18 @@ #define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9 #define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb +#define ARIZONA_TST_CAP_DEFAULT 0x3 +#define ARIZONA_TST_CAP_CLAMP 0x1 + #define ARIZONA_HPDET_MAX 10000 #define HPDET_DEBOUNCE 500 #define DEFAULT_MICD_TIMEOUT 2000 +#define QUICK_HEADPHONE_MAX_OHM 3 +#define MICROPHONE_MIN_OHM 1257 +#define MICROPHONE_MAX_OHM 30000 + #define MICD_DBTIME_TWO_READINGS 2 #define MICD_DBTIME_FOUR_READINGS 4 @@ -117,12 +124,15 @@ static const struct arizona_micd_range micd_default_ranges[] = { { .max = 430, .key = BTN_5 }, }; +/* The number of levels in arizona_micd_levels valid for button thresholds */ +#define ARIZONA_NUM_MICD_BUTTON_LEVELS 64 + static const int arizona_micd_levels[] = { 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 34, 36, 39, 41, 44, 46, 49, 52, 54, 57, 60, 62, 65, 67, 70, 73, 75, 78, 81, 83, 89, 94, 100, 105, 111, 116, 122, 127, 139, 150, 161, 173, 186, 196, 209, 220, 245, 270, 295, 321, 348, 375, 402, 430, 489, 550, 614, 681, 752, 903, 1071, - 1257, + 1257, 30000, }; static const unsigned int arizona_cable[] = { @@ -140,6 +150,7 @@ static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info, { struct arizona *arizona = info->arizona; unsigned int mask = 0, val = 0; + unsigned int cap_sel = 0; int ret; switch (arizona->type) { @@ -147,10 +158,21 @@ static void arizona_extcon_hp_clamp(struct arizona_extcon_info *info, case WM8280: mask = ARIZONA_HP1L_SHRTO | ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI; - if (clamp) + if (clamp) { val = ARIZONA_HP1L_SHRTO; - else + cap_sel = ARIZONA_TST_CAP_CLAMP; + } else { val = ARIZONA_HP1L_FLWR | ARIZONA_HP1L_SHRTI; + cap_sel = ARIZONA_TST_CAP_DEFAULT; + } + + ret = regmap_update_bits(arizona->regmap, + ARIZONA_HP_TEST_CTRL_1, + ARIZONA_HP1_TST_CAP_SEL_MASK, + cap_sel); + if (ret != 0) + dev_warn(arizona->dev, + "Failed to set TST_CAP_SEL: %d\n", ret); break; default: mask = ARIZONA_RMV_SHRT_HP1L; @@ -270,6 +292,7 @@ static void arizona_start_mic(struct arizona_extcon_info *info) struct arizona *arizona = info->arizona; bool change; int ret; + unsigned int mode; /* Microphone detection can't use idle mode */ pm_runtime_get(info->dev); @@ -295,9 +318,14 @@ static void arizona_start_mic(struct arizona_extcon_info *info) regmap_write(arizona->regmap, 0x80, 0x0); } + if (info->detecting && arizona->pdata.micd_software_compare) + mode = ARIZONA_ACCDET_MODE_ADC; + else + mode = ARIZONA_ACCDET_MODE_MIC; + regmap_update_bits(arizona->regmap, ARIZONA_ACCESSORY_DETECT_MODE_1, - ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); + ARIZONA_ACCDET_MODE_MASK, mode); arizona_extcon_pulse_micbias(info); @@ -804,6 +832,37 @@ static void arizona_micd_detect(struct work_struct *work) return; } + if (info->detecting && arizona->pdata.micd_software_compare) { + /* Must disable MICD before we read the ADCVAL */ + regmap_update_bits(arizona->regmap, ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_ENA, 0); + ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_4, &val); + if (ret != 0) { + dev_err(arizona->dev, + "Failed to read MICDET_ADCVAL: %d\n", + ret); + mutex_unlock(&info->lock); + return; + } + + dev_dbg(arizona->dev, "MICDET_ADCVAL: %x\n", val); + + val &= ARIZONA_MICDET_ADCVAL_MASK; + if (val < ARRAY_SIZE(arizona_micd_levels)) + val = arizona_micd_levels[val]; + else + val = INT_MAX; + + if (val <= QUICK_HEADPHONE_MAX_OHM) + val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_0; + else if (val <= MICROPHONE_MIN_OHM) + val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_1; + else if (val <= MICROPHONE_MAX_OHM) + val = ARIZONA_MICD_STS | ARIZONA_MICD_LVL_8; + else + val = ARIZONA_MICD_LVL_8; + } + for (i = 0; i < 10 && !(val & MICD_LVL_0_TO_8); i++) { ret = regmap_read(arizona->regmap, ARIZONA_MIC_DETECT_3, &val); if (ret != 0) { @@ -932,10 +991,17 @@ static void arizona_micd_detect(struct work_struct *work) } handled: - if (info->detecting) + if (info->detecting) { + if (arizona->pdata.micd_software_compare) + regmap_update_bits(arizona->regmap, + ARIZONA_MIC_DETECT_1, + ARIZONA_MICD_ENA, + ARIZONA_MICD_ENA); + queue_delayed_work(system_power_efficient_wq, &info->micd_timeout_work, msecs_to_jiffies(info->micd_timeout)); + } pm_runtime_mark_last_busy(info->dev); mutex_unlock(&info->lock); @@ -991,12 +1057,9 @@ static irqreturn_t arizona_jackdet(int irq, void *data) mutex_lock(&info->lock); - if (arizona->pdata.jd_gpio5) { + if (info->micd_clamp) { mask = ARIZONA_MICD_CLAMP_STS; - if (arizona->pdata.jd_invert) - present = ARIZONA_MICD_CLAMP_STS; - else - present = 0; + present = 0; } else { mask = ARIZONA_JD1_STS; if (arizona->pdata.jd_invert) @@ -1055,9 +1118,11 @@ static irqreturn_t arizona_jackdet(int irq, void *data) msecs_to_jiffies(HPDET_DEBOUNCE)); } - regmap_update_bits(arizona->regmap, - ARIZONA_JACK_DETECT_DEBOUNCE, - ARIZONA_MICD_CLAMP_DB | ARIZONA_JD1_DB, 0); + if (info->micd_clamp || !arizona->pdata.jd_invert) + regmap_update_bits(arizona->regmap, + ARIZONA_JACK_DETECT_DEBOUNCE, + ARIZONA_MICD_CLAMP_DB | + ARIZONA_JD1_DB, 0); } else { dev_dbg(arizona->dev, "Detected jack removal\n"); @@ -1259,6 +1324,10 @@ static int arizona_extcon_probe(struct platform_device *pdev) info->micd_num_modes = ARRAY_SIZE(micd_default_modes); } + if (arizona->pdata.gpsw > 0) + regmap_update_bits(arizona->regmap, ARIZONA_GP_SWITCH_1, + ARIZONA_SW1_MODE_MASK, arizona->pdata.gpsw); + if (arizona->pdata.micd_pol_gpio > 0) { if (info->micd_modes[0].gpio) mode = GPIOF_OUT_INIT_HIGH; @@ -1335,7 +1404,8 @@ static int arizona_extcon_probe(struct platform_device *pdev) break; } - BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) != 0x40); + BUILD_BUG_ON(ARRAY_SIZE(arizona_micd_levels) < + ARIZONA_NUM_MICD_BUTTON_LEVELS); if (arizona->pdata.num_micd_ranges) { info->micd_ranges = pdata->micd_ranges; @@ -1368,11 +1438,11 @@ static int arizona_extcon_probe(struct platform_device *pdev) /* Set up all the buttons the user specified */ for (i = 0; i < info->num_micd_ranges; i++) { - for (j = 0; j < ARRAY_SIZE(arizona_micd_levels); j++) + for (j = 0; j < ARIZONA_NUM_MICD_BUTTON_LEVELS; j++) if (arizona_micd_levels[j] >= info->micd_ranges[i].max) break; - if (j == ARRAY_SIZE(arizona_micd_levels)) { + if (j == ARIZONA_NUM_MICD_BUTTON_LEVELS) { dev_err(arizona->dev, "Unsupported MICD level %d\n", info->micd_ranges[i].max); ret = -EINVAL; @@ -1436,7 +1506,7 @@ static int arizona_extcon_probe(struct platform_device *pdev) pm_runtime_idle(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - if (arizona->pdata.jd_gpio5) { + if (info->micd_clamp) { jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE; jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL; } else { @@ -1541,7 +1611,7 @@ static int arizona_extcon_remove(struct platform_device *pdev) ARIZONA_MICD_CLAMP_CONTROL, ARIZONA_MICD_CLAMP_MODE_MASK, 0); - if (arizona->pdata.jd_gpio5) { + if (info->micd_clamp) { jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE; jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL; } else { diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c index 5e72f65ef94c..63445ea6b0bf 100644 --- a/drivers/mfd/88pm80x.c +++ b/drivers/mfd/88pm80x.c @@ -33,6 +33,8 @@ static struct pm80x_chip_mapping chip_mapping[] = { {0x3, CHIP_PM800}, /* 88PM805 chip id number */ {0x0, CHIP_PM805}, + /* 88PM860 chip id number */ + {0x4, CHIP_PM860}, }; /* diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 99d63675f073..4d92df6ef9fe 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -60,6 +60,17 @@ config MFD_AAT2870_CORE additional drivers must be enabled in order to use the functionality of the device. +config MFD_ATMEL_FLEXCOM + tristate "Atmel Flexcom (Flexible Serial Communication Unit)" + select MFD_CORE + depends on OF + help + Select this to get support for Atmel Flexcom. This is a wrapper + which embeds a SPI controller, a I2C controller and a USART. Only + one function can be used at a time. The choice is done at boot time + by the probe function of this MFD driver according to a device tree + property. + config MFD_ATMEL_HLCDC tristate "Atmel HLCDC (High-end LCD Controller)" select MFD_CORE @@ -725,9 +736,10 @@ config MFD_RTSX_PCI select MFD_CORE help This supports for Realtek PCI-Express card reader including rts5209, - rts5229, rtl8411, etc. Realtek card reader supports access to many - types of memory cards, such as Memory Stick, Memory Stick Pro, - Secure Digital and MultiMediaCard. + rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, etc. + Realtek card reader supports access to many types of memory cards, + such as Memory Stick, Memory Stick Pro, Secure Digital and + MultiMediaCard. config MFD_RT5033 tristate "Richtek RT5033 Power Management IC" @@ -1059,6 +1071,7 @@ config MFD_PALMAS config TPS6105X tristate "TI TPS61050/61052 Boost Converters" depends on I2C + select REGMAP_I2C select REGULATOR select MFD_CORE select REGULATOR_FIXED_VOLTAGE @@ -1471,7 +1484,7 @@ config MFD_WM8994 config MFD_STW481X tristate "Support for ST Microelectronics STw481x" - depends on I2C && ARCH_NOMADIK + depends on I2C && (ARCH_NOMADIK || COMPILE_TEST) select REGMAP_I2C select MFD_CORE help diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index a59e3fcc8626..a8b76b81b467 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -164,6 +164,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o obj-$(CONFIG_MFD_TPS65090) += tps65090.o obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o +obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o obj-$(CONFIG_MFD_INTEL_LPSS) += intel-lpss.o obj-$(CONFIG_MFD_INTEL_LPSS_PCI) += intel-lpss-pci.o @@ -190,5 +191,6 @@ obj-$(CONFIG_MFD_RT5033) += rt5033.o obj-$(CONFIG_MFD_SKY81452) += sky81452.o intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o +intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_MFD_MT6397) += mt6397-core.o diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 44cfdbb295db..d474732cc65c 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -69,8 +70,6 @@ EXPORT_SYMBOL_GPL(arizona_clk32k_enable); int arizona_clk32k_disable(struct arizona *arizona) { - int ret = 0; - mutex_lock(&arizona->clk_lock); BUG_ON(arizona->clk32k_ref <= 0); @@ -90,7 +89,7 @@ int arizona_clk32k_disable(struct arizona *arizona) mutex_unlock(&arizona->clk_lock); - return ret; + return 0; } EXPORT_SYMBOL_GPL(arizona_clk32k_disable); @@ -462,6 +461,50 @@ static int wm5102_clear_write_sequencer(struct arizona *arizona) } #ifdef CONFIG_PM +static int arizona_isolate_dcvdd(struct arizona *arizona) +{ + int ret; + + ret = regmap_update_bits(arizona->regmap, + ARIZONA_ISOLATION_CONTROL, + ARIZONA_ISOLATE_DCVDD1, + ARIZONA_ISOLATE_DCVDD1); + if (ret != 0) + dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n", ret); + + return ret; +} + +static int arizona_connect_dcvdd(struct arizona *arizona) +{ + int ret; + + ret = regmap_update_bits(arizona->regmap, + ARIZONA_ISOLATION_CONTROL, + ARIZONA_ISOLATE_DCVDD1, 0); + if (ret != 0) + dev_err(arizona->dev, "Failed to connect DCVDD: %d\n", ret); + + return ret; +} + +static int arizona_is_jack_det_active(struct arizona *arizona) +{ + unsigned int val; + int ret; + + ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val); + if (ret) { + dev_err(arizona->dev, + "Failed to check jack det status: %d\n", ret); + return ret; + } else if (val & ARIZONA_JD1_ENA) { + return 1; + } else { + return 0; + } +} + static int arizona_runtime_resume(struct device *dev) { struct arizona *arizona = dev_get_drvdata(dev); @@ -501,14 +544,9 @@ static int arizona_runtime_resume(struct device *dev) switch (arizona->type) { case WM5102: if (arizona->external_dcvdd) { - ret = regmap_update_bits(arizona->regmap, - ARIZONA_ISOLATION_CONTROL, - ARIZONA_ISOLATE_DCVDD1, 0); - if (ret != 0) { - dev_err(arizona->dev, - "Failed to connect DCVDD: %d\n", ret); + ret = arizona_connect_dcvdd(arizona); + if (ret != 0) goto err; - } } ret = wm5102_patch(arizona); @@ -533,14 +571,9 @@ static int arizona_runtime_resume(struct device *dev) goto err; if (arizona->external_dcvdd) { - ret = regmap_update_bits(arizona->regmap, - ARIZONA_ISOLATION_CONTROL, - ARIZONA_ISOLATE_DCVDD1, 0); - if (ret) { - dev_err(arizona->dev, - "Failed to connect DCVDD: %d\n", ret); + ret = arizona_connect_dcvdd(arizona); + if (ret != 0) goto err; - } } else { /* * As this is only called for the internal regulator @@ -571,14 +604,9 @@ static int arizona_runtime_resume(struct device *dev) goto err; if (arizona->external_dcvdd) { - ret = regmap_update_bits(arizona->regmap, - ARIZONA_ISOLATION_CONTROL, - ARIZONA_ISOLATE_DCVDD1, 0); - if (ret != 0) { - dev_err(arizona->dev, - "Failed to connect DCVDD: %d\n", ret); + ret = arizona_connect_dcvdd(arizona); + if (ret != 0) goto err; - } } break; } @@ -600,49 +628,50 @@ err: static int arizona_runtime_suspend(struct device *dev) { struct arizona *arizona = dev_get_drvdata(dev); - unsigned int val; + int jd_active = 0; int ret; dev_dbg(arizona->dev, "Entering AoD mode\n"); - ret = regmap_read(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, &val); - if (ret) { - dev_err(dev, "Failed to check jack det status: %d\n", ret); - return ret; - } - - if (arizona->external_dcvdd) { - ret = regmap_update_bits(arizona->regmap, - ARIZONA_ISOLATION_CONTROL, - ARIZONA_ISOLATE_DCVDD1, - ARIZONA_ISOLATE_DCVDD1); - if (ret != 0) { - dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n", - ret); - return ret; - } - } - switch (arizona->type) { case WM5110: case WM8280: - if (arizona->external_dcvdd) - break; + jd_active = arizona_is_jack_det_active(arizona); + if (jd_active < 0) + return jd_active; - /* - * As this is only called for the internal regulator - * (where we know voltage ranges available) it is ok - * to request an exact range. - */ - ret = regulator_set_voltage(arizona->dcvdd, 1175000, 1175000); - if (ret < 0) { - dev_err(arizona->dev, - "Failed to set suspend voltage: %d\n", ret); - return ret; + if (arizona->external_dcvdd) { + ret = arizona_isolate_dcvdd(arizona); + if (ret != 0) + return ret; + } else { + /* + * As this is only called for the internal regulator + * (where we know voltage ranges available) it is ok + * to request an exact range. + */ + ret = regulator_set_voltage(arizona->dcvdd, + 1175000, 1175000); + if (ret < 0) { + dev_err(arizona->dev, + "Failed to set suspend voltage: %d\n", + ret); + return ret; + } } break; case WM5102: - if (!(val & ARIZONA_JD1_ENA)) { + jd_active = arizona_is_jack_det_active(arizona); + if (jd_active < 0) + return jd_active; + + if (arizona->external_dcvdd) { + ret = arizona_isolate_dcvdd(arizona); + if (ret != 0) + return ret; + } + + if (!jd_active) { ret = regmap_write(arizona->regmap, ARIZONA_WRITE_SEQUENCER_CTRL_3, 0x0); if (ret) { @@ -654,6 +683,15 @@ static int arizona_runtime_suspend(struct device *dev) } break; default: + jd_active = arizona_is_jack_det_active(arizona); + if (jd_active < 0) + return jd_active; + + if (arizona->external_dcvdd) { + ret = arizona_isolate_dcvdd(arizona); + if (ret != 0) + return ret; + } break; } @@ -662,7 +700,7 @@ static int arizona_runtime_suspend(struct device *dev) regulator_disable(arizona->dcvdd); /* Allow us to completely power down if no jack detection */ - if (!(val & ARIZONA_JD1_ENA)) { + if (!jd_active) { dev_dbg(arizona->dev, "Fully powering off\n"); arizona->has_fully_powered_off = true; @@ -928,7 +966,8 @@ int arizona_dev_init(struct arizona *arizona) const char *type_name; unsigned int reg, val, mask; int (*apply_patch)(struct arizona *) = NULL; - int ret, i; + const struct mfd_cell *subdevs = NULL; + int n_subdevs, ret, i; dev_set_drvdata(arizona->dev, arizona); mutex_init(&arizona->clk_lock); @@ -1089,74 +1128,95 @@ int arizona_dev_init(struct arizona *arizona) arizona->rev &= ARIZONA_DEVICE_REVISION_MASK; switch (reg) { -#ifdef CONFIG_MFD_WM5102 case 0x5102: - type_name = "WM5102"; - if (arizona->type != WM5102) { - dev_err(arizona->dev, "WM5102 registered as %d\n", - arizona->type); - arizona->type = WM5102; + if (IS_ENABLED(CONFIG_MFD_WM5102)) { + type_name = "WM5102"; + if (arizona->type != WM5102) { + dev_warn(arizona->dev, + "WM5102 registered as %d\n", + arizona->type); + arizona->type = WM5102; + } + + apply_patch = wm5102_patch; + arizona->rev &= 0x7; + subdevs = wm5102_devs; + n_subdevs = ARRAY_SIZE(wm5102_devs); } - apply_patch = wm5102_patch; - arizona->rev &= 0x7; break; -#endif -#ifdef CONFIG_MFD_WM5110 case 0x5110: - switch (arizona->type) { - case WM5110: - type_name = "WM5110"; - break; - case WM8280: - type_name = "WM8280"; - break; - default: - type_name = "WM5110"; - dev_err(arizona->dev, "WM5110 registered as %d\n", - arizona->type); - arizona->type = WM5110; - break; + if (IS_ENABLED(CONFIG_MFD_WM5110)) { + switch (arizona->type) { + case WM5110: + type_name = "WM5110"; + break; + case WM8280: + type_name = "WM8280"; + break; + default: + type_name = "WM5110"; + dev_warn(arizona->dev, + "WM5110 registered as %d\n", + arizona->type); + arizona->type = WM5110; + break; + } + + apply_patch = wm5110_patch; + subdevs = wm5110_devs; + n_subdevs = ARRAY_SIZE(wm5110_devs); } - apply_patch = wm5110_patch; break; -#endif -#ifdef CONFIG_MFD_WM8997 case 0x8997: - type_name = "WM8997"; - if (arizona->type != WM8997) { - dev_err(arizona->dev, "WM8997 registered as %d\n", - arizona->type); - arizona->type = WM8997; + if (IS_ENABLED(CONFIG_MFD_WM8997)) { + type_name = "WM8997"; + if (arizona->type != WM8997) { + dev_warn(arizona->dev, + "WM8997 registered as %d\n", + arizona->type); + arizona->type = WM8997; + } + + apply_patch = wm8997_patch; + subdevs = wm8997_devs; + n_subdevs = ARRAY_SIZE(wm8997_devs); } - apply_patch = wm8997_patch; break; -#endif -#ifdef CONFIG_MFD_WM8998 case 0x6349: - switch (arizona->type) { - case WM8998: - type_name = "WM8998"; - break; - - case WM1814: - type_name = "WM1814"; - break; + if (IS_ENABLED(CONFIG_MFD_WM8998)) { + switch (arizona->type) { + case WM8998: + type_name = "WM8998"; + break; + + case WM1814: + type_name = "WM1814"; + break; + + default: + type_name = "WM8998"; + dev_warn(arizona->dev, + "WM8998 registered as %d\n", + arizona->type); + arizona->type = WM8998; + } - default: - type_name = "WM8998"; - dev_err(arizona->dev, "WM8998 registered as %d\n", - arizona->type); - arizona->type = WM8998; + apply_patch = wm8998_patch; + subdevs = wm8998_devs; + n_subdevs = ARRAY_SIZE(wm8998_devs); } - - apply_patch = wm8998_patch; break; -#endif default: dev_err(arizona->dev, "Unknown device ID %x\n", reg); goto err_reset; } + if (!subdevs) { + dev_err(arizona->dev, + "No kernel support for device ID %x\n", reg); + goto err_reset; + } + dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A'); if (apply_patch) { @@ -1342,28 +1402,10 @@ int arizona_dev_init(struct arizona *arizona) arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked", arizona_underclocked, arizona); - switch (arizona->type) { - case WM5102: - ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, - ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); - break; - case WM5110: - case WM8280: - ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, - ARRAY_SIZE(wm5110_devs), NULL, 0, NULL); - break; - case WM8997: - ret = mfd_add_devices(arizona->dev, -1, wm8997_devs, - ARRAY_SIZE(wm8997_devs), NULL, 0, NULL); - break; - case WM8998: - case WM1814: - ret = mfd_add_devices(arizona->dev, -1, wm8998_devs, - ARRAY_SIZE(wm8998_devs), NULL, 0, NULL); - break; - } + ret = mfd_add_devices(arizona->dev, PLATFORM_DEVID_NONE, + subdevs, n_subdevs, NULL, 0, NULL); - if (ret != 0) { + if (ret) { dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret); goto err_irq; } diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c index cea1b409fa27..4e3afd1861fc 100644 --- a/drivers/mfd/arizona-i2c.c +++ b/drivers/mfd/arizona-i2c.c @@ -27,7 +27,7 @@ static int arizona_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct arizona *arizona; - const struct regmap_config *regmap_config; + const struct regmap_config *regmap_config = NULL; unsigned long type; int ret; @@ -37,31 +37,32 @@ static int arizona_i2c_probe(struct i2c_client *i2c, type = id->driver_data; switch (type) { -#ifdef CONFIG_MFD_WM5102 case WM5102: - regmap_config = &wm5102_i2c_regmap; + if (IS_ENABLED(CONFIG_MFD_WM5102)) + regmap_config = &wm5102_i2c_regmap; break; -#endif -#ifdef CONFIG_MFD_WM5110 case WM5110: case WM8280: - regmap_config = &wm5110_i2c_regmap; + if (IS_ENABLED(CONFIG_MFD_WM5110)) + regmap_config = &wm5110_i2c_regmap; break; -#endif -#ifdef CONFIG_MFD_WM8997 case WM8997: - regmap_config = &wm8997_i2c_regmap; + if (IS_ENABLED(CONFIG_MFD_WM8997)) + regmap_config = &wm8997_i2c_regmap; break; -#endif -#ifdef CONFIG_MFD_WM8998 case WM8998: case WM1814: - regmap_config = &wm8998_i2c_regmap; + if (IS_ENABLED(CONFIG_MFD_WM8998)) + regmap_config = &wm8998_i2c_regmap; break; -#endif default: - dev_err(&i2c->dev, "Unknown device type %ld\n", - id->driver_data); + dev_err(&i2c->dev, "Unknown device type %ld\n", type); + return -EINVAL; + } + + if (!regmap_config) { + dev_err(&i2c->dev, + "No kernel support for device type %ld\n", type); return -EINVAL; } @@ -77,7 +78,7 @@ static int arizona_i2c_probe(struct i2c_client *i2c, return ret; } - arizona->type = id->driver_data; + arizona->type = type; arizona->dev = &i2c->dev; arizona->irq = i2c->irq; diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 2cac4f463f1e..3d425e93ce84 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c @@ -169,7 +169,7 @@ static struct irq_chip arizona_irq_chip = { static int arizona_irq_map(struct irq_domain *h, unsigned int virq, irq_hw_number_t hw) { - struct regmap_irq_chip_data *data = h->host_data; + struct arizona *data = h->host_data; irq_set_chip_data(virq, data); irq_set_chip_and_handler(virq, &arizona_irq_chip, handle_simple_irq); diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index 1e845f6d407b..8cffb1cfe73d 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c @@ -27,7 +27,7 @@ static int arizona_spi_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); struct arizona *arizona; - const struct regmap_config *regmap_config; + const struct regmap_config *regmap_config = NULL; unsigned long type; int ret; @@ -37,20 +37,23 @@ static int arizona_spi_probe(struct spi_device *spi) type = id->driver_data; switch (type) { -#ifdef CONFIG_MFD_WM5102 case WM5102: - regmap_config = &wm5102_spi_regmap; + if (IS_ENABLED(CONFIG_MFD_WM5102)) + regmap_config = &wm5102_spi_regmap; break; -#endif -#ifdef CONFIG_MFD_WM5110 case WM5110: case WM8280: - regmap_config = &wm5110_spi_regmap; + if (IS_ENABLED(CONFIG_MFD_WM5110)) + regmap_config = &wm5110_spi_regmap; break; -#endif default: - dev_err(&spi->dev, "Unknown device type %ld\n", - id->driver_data); + dev_err(&spi->dev, "Unknown device type %ld\n", type); + return -EINVAL; + } + + if (!regmap_config) { + dev_err(&spi->dev, + "No kernel support for device type %ld\n", type); return -EINVAL; } @@ -66,7 +69,7 @@ static int arizona_spi_probe(struct spi_device *spi) return ret; } - arizona->type = id->driver_data; + arizona->type = type; arizona->dev = &spi->dev; arizona->irq = spi->irq; diff --git a/drivers/mfd/atmel-flexcom.c b/drivers/mfd/atmel-flexcom.c new file mode 100644 index 000000000000..e8e67be6b493 --- /dev/null +++ b/drivers/mfd/atmel-flexcom.c @@ -0,0 +1,104 @@ +/* + * Driver for Atmel Flexcom + * + * Copyright (C) 2015 Atmel Corporation + * + * Author: Cyrille Pitchen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* I/O register offsets */ +#define FLEX_MR 0x0 /* Mode Register */ +#define FLEX_VERSION 0xfc /* Version Register */ + +/* Mode Register bit fields */ +#define FLEX_MR_OPMODE_OFFSET (0) /* Operating Mode */ +#define FLEX_MR_OPMODE_MASK (0x3 << FLEX_MR_OPMODE_OFFSET) +#define FLEX_MR_OPMODE(opmode) (((opmode) << FLEX_MR_OPMODE_OFFSET) & \ + FLEX_MR_OPMODE_MASK) + + +static int atmel_flexcom_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct clk *clk; + struct resource *res; + void __iomem *base; + u32 opmode; + int err; + + err = of_property_read_u32(np, "atmel,flexcom-mode", &opmode); + if (err) + return err; + + if (opmode < ATMEL_FLEXCOM_MODE_USART || + opmode > ATMEL_FLEXCOM_MODE_TWI) + return -EINVAL; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + + err = clk_prepare_enable(clk); + if (err) + return err; + + /* + * Set the Operating Mode in the Mode Register: only the selected device + * is clocked. Hence, registers of the other serial devices remain + * inaccessible and are read as zero. Also the external I/O lines of the + * Flexcom are muxed to reach the selected device. + */ + writel(FLEX_MR_OPMODE(opmode), base + FLEX_MR); + + clk_disable_unprepare(clk); + + return of_platform_populate(np, NULL, NULL, &pdev->dev); +} + +static const struct of_device_id atmel_flexcom_of_match[] = { + { .compatible = "atmel,sama5d2-flexcom" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match); + +static struct platform_driver atmel_flexcom_driver = { + .probe = atmel_flexcom_probe, + .driver = { + .name = "atmel_flexcom", + .of_match_table = atmel_flexcom_of_match, + }, +}; + +module_platform_driver(atmel_flexcom_driver); + +MODULE_AUTHOR("Cyrille Pitchen "); +MODULE_DESCRIPTION("Atmel Flexcom MFD driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c index 3fff6b5d0426..06c205868573 100644 --- a/drivers/mfd/atmel-hlcdc.c +++ b/drivers/mfd/atmel-hlcdc.c @@ -148,6 +148,7 @@ static const struct of_device_id atmel_hlcdc_match[] = { { .compatible = "atmel,sama5d4-hlcdc" }, { /* sentinel */ }, }; +MODULE_DEVICE_TABLE(of, atmel_hlcdc_match); static struct platform_driver atmel_hlcdc_driver = { .probe = atmel_hlcdc_probe, diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 3f576b76c322..9842199e2e6c 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -161,6 +161,21 @@ static struct resource axp22x_pek_resources[] = { }, }; +static struct resource axp288_power_button_resources[] = { + { + .name = "PEK_DBR", + .start = AXP288_IRQ_POKN, + .end = AXP288_IRQ_POKN, + .flags = IORESOURCE_IRQ, + }, + { + .name = "PEK_DBF", + .start = AXP288_IRQ_POKP, + .end = AXP288_IRQ_POKP, + .flags = IORESOURCE_IRQ, + }, +}; + static struct resource axp288_fuel_gauge_resources[] = { { .start = AXP288_IRQ_QWBTU, @@ -571,6 +586,11 @@ static struct mfd_cell axp288_cells[] = { .num_resources = ARRAY_SIZE(axp288_fuel_gauge_resources), .resources = axp288_fuel_gauge_resources, }, + { + .name = "axp20x-pek", + .num_resources = ARRAY_SIZE(axp288_power_button_resources), + .resources = axp288_power_button_resources, + }, { .name = "axp288_pmic_acpi", }, diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c index da2af5b4f855..320aaefee718 100644 --- a/drivers/mfd/bcm590xx.c +++ b/drivers/mfd/bcm590xx.c @@ -128,4 +128,3 @@ module_i2c_driver(bcm590xx_i2c_driver); MODULE_AUTHOR("Matt Porter "); MODULE_DESCRIPTION("BCM590xx multi-function driver"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("i2c:bcm590xx"); diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c index d06e4b46db80..56a466469664 100644 --- a/drivers/mfd/cros_ec_i2c.c +++ b/drivers/mfd/cros_ec_i2c.c @@ -344,6 +344,12 @@ static int cros_ec_i2c_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(cros_ec_i2c_pm_ops, cros_ec_i2c_suspend, cros_ec_i2c_resume); +static const struct of_device_id cros_ec_i2c_of_match[] = { + { .compatible = "google,cros-ec-i2c", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match); + static const struct i2c_device_id cros_ec_i2c_id[] = { { "cros-ec-i2c", 0 }, { } @@ -353,6 +359,7 @@ MODULE_DEVICE_TABLE(i2c, cros_ec_i2c_id); static struct i2c_driver cros_ec_driver = { .driver = { .name = "cros-ec-i2c", + .of_match_table = of_match_ptr(cros_ec_i2c_of_match), .pm = &cros_ec_i2c_pm_ops, }, .probe = cros_ec_i2c_probe, diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c index ef7fe2ae2fa4..37e4426ef061 100644 --- a/drivers/mfd/da903x.c +++ b/drivers/mfd/da903x.c @@ -532,11 +532,7 @@ static int da903x_probe(struct i2c_client *client, return ret; } - ret = da903x_add_subdevs(chip, pdata); - if (ret) - return ret; - - return 0; + return da903x_add_subdevs(chip, pdata); } static int da903x_remove(struct i2c_client *client) diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 46e3840c7a37..c0bf68a3e614 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c @@ -51,6 +51,9 @@ static bool da9052_reg_readable(struct device *dev, unsigned int reg) case DA9052_GPIO_2_3_REG: case DA9052_GPIO_4_5_REG: case DA9052_GPIO_6_7_REG: + case DA9052_GPIO_8_9_REG: + case DA9052_GPIO_10_11_REG: + case DA9052_GPIO_12_13_REG: case DA9052_GPIO_14_15_REG: case DA9052_ID_0_1_REG: case DA9052_ID_2_3_REG: @@ -178,6 +181,9 @@ static bool da9052_reg_writeable(struct device *dev, unsigned int reg) case DA9052_GPIO_2_3_REG: case DA9052_GPIO_4_5_REG: case DA9052_GPIO_6_7_REG: + case DA9052_GPIO_8_9_REG: + case DA9052_GPIO_10_11_REG: + case DA9052_GPIO_12_13_REG: case DA9052_GPIO_14_15_REG: case DA9052_ID_0_1_REG: case DA9052_ID_2_3_REG: diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index 02887001e800..2697ffb08009 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c @@ -174,11 +174,7 @@ static int da9052_i2c_probe(struct i2c_client *client, return ret; } - ret = da9052_device_init(da9052, id->driver_data); - if (ret != 0) - return ret; - - return 0; + return da9052_device_init(da9052, id->driver_data); } static int da9052_i2c_remove(struct i2c_client *client) diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c index b5de8a6856c0..0f5e2c2858c1 100644 --- a/drivers/mfd/da9052-spi.c +++ b/drivers/mfd/da9052-spi.c @@ -56,11 +56,7 @@ static int da9052_spi_probe(struct spi_device *spi) return ret; } - ret = da9052_device_init(da9052, id->driver_data); - if (ret != 0) - return ret; - - return 0; + return da9052_device_init(da9052, id->driver_data); } static int da9052_spi_remove(struct spi_device *spi) diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c index f80d9471f2e7..a9ad024ec6b0 100644 --- a/drivers/mfd/da9062-core.c +++ b/drivers/mfd/da9062-core.c @@ -198,7 +198,7 @@ static int da9062_clear_fault_log(struct da9062 *chip) return ret; } -int get_device_type(struct da9062 *chip) +static int da9062_get_device_type(struct da9062 *chip) { int device_id, variant_id, variant_mrc; int ret; @@ -466,7 +466,7 @@ static int da9062_i2c_probe(struct i2c_client *i2c, if (ret < 0) dev_warn(chip->dev, "Cannot clear fault log\n"); - ret = get_device_type(chip); + ret = da9062_get_device_type(chip); if (ret) return ret; diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c index 94b9bbd1a69b..195fdcfa1a0d 100644 --- a/drivers/mfd/da9150-core.c +++ b/drivers/mfd/da9150-core.c @@ -23,6 +23,77 @@ #include #include +/* Raw device access, used for QIF */ +static int da9150_i2c_read_device(struct i2c_client *client, u8 addr, int count, + u8 *buf) +{ + struct i2c_msg xfer; + int ret; + + /* + * Read is split into two transfers as device expects STOP/START rather + * than repeated start to carry out this kind of access. + */ + + /* Write address */ + xfer.addr = client->addr; + xfer.flags = 0; + xfer.len = 1; + xfer.buf = &addr; + + ret = i2c_transfer(client->adapter, &xfer, 1); + if (ret != 1) { + if (ret < 0) + return ret; + else + return -EIO; + } + + /* Read data */ + xfer.addr = client->addr; + xfer.flags = I2C_M_RD; + xfer.len = count; + xfer.buf = buf; + + ret = i2c_transfer(client->adapter, &xfer, 1); + if (ret == 1) + return 0; + else if (ret < 0) + return ret; + else + return -EIO; +} + +static int da9150_i2c_write_device(struct i2c_client *client, u8 addr, + int count, const u8 *buf) +{ + struct i2c_msg xfer; + u8 *reg_data; + int ret; + + reg_data = kzalloc(1 + count, GFP_KERNEL); + if (!reg_data) + return -ENOMEM; + + reg_data[0] = addr; + memcpy(®_data[1], buf, count); + + /* Write address & data */ + xfer.addr = client->addr; + xfer.flags = 0; + xfer.len = 1 + count; + xfer.buf = reg_data; + + ret = i2c_transfer(client->adapter, &xfer, 1); + kfree(reg_data); + if (ret == 1) + return 0; + else if (ret < 0) + return ret; + else + return -EIO; +} + static bool da9150_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -107,6 +178,28 @@ static const struct regmap_config da9150_regmap_config = { .volatile_reg = da9150_volatile_reg, }; +void da9150_read_qif(struct da9150 *da9150, u8 addr, int count, u8 *buf) +{ + int ret; + + ret = da9150_i2c_read_device(da9150->core_qif, addr, count, buf); + if (ret < 0) + dev_err(da9150->dev, "Failed to read from QIF 0x%x: %d\n", + addr, ret); +} +EXPORT_SYMBOL_GPL(da9150_read_qif); + +void da9150_write_qif(struct da9150 *da9150, u8 addr, int count, const u8 *buf) +{ + int ret; + + ret = da9150_i2c_write_device(da9150->core_qif, addr, count, buf); + if (ret < 0) + dev_err(da9150->dev, "Failed to write to QIF 0x%x: %d\n", + addr, ret); +} +EXPORT_SYMBOL_GPL(da9150_write_qif); + u8 da9150_reg_read(struct da9150 *da9150, u16 reg) { int val, ret; @@ -262,54 +355,45 @@ static const struct regmap_irq_chip da9150_regmap_irq_chip = { }; static struct resource da9150_gpadc_resources[] = { - { - .name = "GPADC", - .start = DA9150_IRQ_GPADC, - .end = DA9150_IRQ_GPADC, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_GPADC, "GPADC"), }; static struct resource da9150_charger_resources[] = { - { - .name = "CHG_STATUS", - .start = DA9150_IRQ_CHG, - .end = DA9150_IRQ_CHG, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CHG_TJUNC", - .start = DA9150_IRQ_TJUNC, - .end = DA9150_IRQ_TJUNC, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CHG_VFAULT", - .start = DA9150_IRQ_VFAULT, - .end = DA9150_IRQ_VFAULT, - .flags = IORESOURCE_IRQ, - }, - { - .name = "CHG_VBUS", - .start = DA9150_IRQ_VBUS, - .end = DA9150_IRQ_VBUS, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_CHG, "CHG_STATUS"), + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_TJUNC, "CHG_TJUNC"), + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_VFAULT, "CHG_VFAULT"), + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_VBUS, "CHG_VBUS"), +}; + +static struct resource da9150_fg_resources[] = { + DEFINE_RES_IRQ_NAMED(DA9150_IRQ_FG, "FG"), +}; + +enum da9150_dev_idx { + DA9150_GPADC_IDX = 0, + DA9150_CHARGER_IDX, + DA9150_FG_IDX, }; static struct mfd_cell da9150_devs[] = { - { + [DA9150_GPADC_IDX] = { .name = "da9150-gpadc", .of_compatible = "dlg,da9150-gpadc", .resources = da9150_gpadc_resources, .num_resources = ARRAY_SIZE(da9150_gpadc_resources), }, - { + [DA9150_CHARGER_IDX] = { .name = "da9150-charger", .of_compatible = "dlg,da9150-charger", .resources = da9150_charger_resources, .num_resources = ARRAY_SIZE(da9150_charger_resources), }, + [DA9150_FG_IDX] = { + .name = "da9150-fuel-gauge", + .of_compatible = "dlg,da9150-fuel-gauge", + .resources = da9150_fg_resources, + .num_resources = ARRAY_SIZE(da9150_fg_resources), + }, }; static int da9150_probe(struct i2c_client *client, @@ -317,6 +401,7 @@ static int da9150_probe(struct i2c_client *client, { struct da9150 *da9150; struct da9150_pdata *pdata = dev_get_platdata(&client->dev); + int qif_addr; int ret; da9150 = devm_kzalloc(&client->dev, sizeof(*da9150), GFP_KERNEL); @@ -335,16 +420,41 @@ static int da9150_probe(struct i2c_client *client, return ret; } - da9150->irq_base = pdata ? pdata->irq_base : -1; + /* Setup secondary I2C interface for QIF access */ + qif_addr = da9150_reg_read(da9150, DA9150_CORE2WIRE_CTRL_A); + qif_addr = (qif_addr & DA9150_CORE_BASE_ADDR_MASK) >> 1; + qif_addr |= DA9150_QIF_I2C_ADDR_LSB; + da9150->core_qif = i2c_new_dummy(client->adapter, qif_addr); + if (!da9150->core_qif) { + dev_err(da9150->dev, "Failed to attach QIF client\n"); + return -ENODEV; + } + + i2c_set_clientdata(da9150->core_qif, da9150); + + if (pdata) { + da9150->irq_base = pdata->irq_base; + + da9150_devs[DA9150_FG_IDX].platform_data = pdata->fg_pdata; + da9150_devs[DA9150_FG_IDX].pdata_size = + sizeof(struct da9150_fg_pdata); + } else { + da9150->irq_base = -1; + } ret = regmap_add_irq_chip(da9150->regmap, da9150->irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, da9150->irq_base, &da9150_regmap_irq_chip, &da9150->regmap_irq_data); - if (ret) - return ret; + if (ret) { + dev_err(da9150->dev, "Failed to add regmap irq chip: %d\n", + ret); + goto regmap_irq_fail; + } + da9150->irq_base = regmap_irq_chip_get_base(da9150->regmap_irq_data); + enable_irq_wake(da9150->irq); ret = mfd_add_devices(da9150->dev, -1, da9150_devs, @@ -352,11 +462,17 @@ static int da9150_probe(struct i2c_client *client, da9150->irq_base, NULL); if (ret) { dev_err(da9150->dev, "Failed to add child devices: %d\n", ret); - regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); - return ret; + goto mfd_fail; } return 0; + +mfd_fail: + regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); +regmap_irq_fail: + i2c_unregister_device(da9150->core_qif); + + return ret; } static int da9150_remove(struct i2c_client *client) @@ -365,6 +481,7 @@ static int da9150_remove(struct i2c_client *client) regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); mfd_remove_devices(da9150->dev); + i2c_unregister_device(da9150->core_qif); return 0; } diff --git a/drivers/mfd/hi6421-pmic-core.c b/drivers/mfd/hi6421-pmic-core.c index 95b2ff8f223a..f9ded45a992d 100644 --- a/drivers/mfd/hi6421-pmic-core.c +++ b/drivers/mfd/hi6421-pmic-core.c @@ -97,6 +97,7 @@ static const struct of_device_id of_hi6421_pmic_match_tbl[] = { { .compatible = "hisilicon,hi6421-pmic", }, { }, }; +MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match_tbl); static struct platform_driver hi6421_pmic_driver = { .driver = { diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 1bd5b042c8b3..0c6ff727b2ec 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c @@ -318,7 +318,6 @@ static int htcpld_setup_chip_irq( struct htcpld_data *htcpld; struct htcpld_chip *chip; unsigned int irq, irq_end; - int ret = 0; /* Get the platform and driver data */ htcpld = platform_get_drvdata(pdev); @@ -333,7 +332,7 @@ static int htcpld_setup_chip_irq( irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); } - return ret; + return 0; } static int htcpld_register_chip_i2c( diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c index 0d92d73bfa0e..b6fd9041f82f 100644 --- a/drivers/mfd/intel-lpss-acpi.c +++ b/drivers/mfd/intel-lpss-acpi.c @@ -25,10 +25,26 @@ static const struct intel_lpss_platform_info spt_info = { .clk_rate = 120000000, }; +static const struct intel_lpss_platform_info bxt_info = { + .clk_rate = 100000000, +}; + +static const struct intel_lpss_platform_info bxt_i2c_info = { + .clk_rate = 133000000, +}; + static const struct acpi_device_id intel_lpss_acpi_ids[] = { /* SPT */ { "INT3446", (kernel_ulong_t)&spt_info }, { "INT3447", (kernel_ulong_t)&spt_info }, + /* BXT */ + { "80860AAC", (kernel_ulong_t)&bxt_i2c_info }, + { "80860ABC", (kernel_ulong_t)&bxt_info }, + { "80860AC2", (kernel_ulong_t)&bxt_info }, + /* APL */ + { "80865AAC", (kernel_ulong_t)&bxt_i2c_info }, + { "80865ABC", (kernel_ulong_t)&bxt_info }, + { "80865AC2", (kernel_ulong_t)&bxt_info }, { } }; MODULE_DEVICE_TABLE(acpi, intel_lpss_acpi_ids); diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 9236dffeb4d6..5bfdfccbb9a1 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -70,7 +70,52 @@ static const struct intel_lpss_platform_info spt_uart_info = { .clk_con_id = "baudclk", }; +static const struct intel_lpss_platform_info bxt_info = { + .clk_rate = 100000000, +}; + +static const struct intel_lpss_platform_info bxt_uart_info = { + .clk_rate = 100000000, + .clk_con_id = "baudclk", +}; + +static const struct intel_lpss_platform_info bxt_i2c_info = { + .clk_rate = 133000000, +}; + static const struct pci_device_id intel_lpss_pci_ids[] = { + /* BXT */ + { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x0ab0), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x0ab2), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x0ab4), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x0ab6), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x0ab8), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x0aba), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x0abc), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x0abe), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x0ac0), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x0ac2), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x0ac4), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x0ac6), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x0aee), (kernel_ulong_t)&bxt_uart_info }, + /* APL */ + { PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x5ab0), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x5ab2), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x5ab4), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x5ab6), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x5ab8), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x5aba), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x5abc), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x5abe), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x5ac0), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x5ac2), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info }, /* SPT-LP */ { PCI_VDEVICE(INTEL, 0x9d27), (kernel_ulong_t)&spt_uart_info }, { PCI_VDEVICE(INTEL, 0x9d28), (kernel_ulong_t)&spt_uart_info }, diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c index fdf4d5c1add2..001a7d7708ce 100644 --- a/drivers/mfd/intel-lpss.c +++ b/drivers/mfd/intel-lpss.c @@ -26,6 +26,8 @@ #include #include +#include + #include "intel-lpss.h" #define LPSS_DEV_OFFSET 0x000 @@ -52,8 +54,7 @@ #define LPSS_PRIV_SSP_REG 0x20 #define LPSS_PRIV_SSP_REG_DIS_DMA_FIN BIT(0) -#define LPSS_PRIV_REMAP_ADDR_LO 0x40 -#define LPSS_PRIV_REMAP_ADDR_HI 0x44 +#define LPSS_PRIV_REMAP_ADDR 0x40 #define LPSS_PRIV_CAPS 0xfc #define LPSS_PRIV_CAPS_NO_IDMA BIT(8) @@ -250,12 +251,7 @@ static void intel_lpss_set_remap_addr(const struct intel_lpss *lpss) { resource_size_t addr = lpss->info->mem->start; - writel(addr, lpss->priv + LPSS_PRIV_REMAP_ADDR_LO); -#if BITS_PER_LONG > 32 - writel(addr >> 32, lpss->priv + LPSS_PRIV_REMAP_ADDR_HI); -#else - writel(0, lpss->priv + LPSS_PRIV_REMAP_ADDR_HI); -#endif + lo_hi_writeq(addr, lpss->priv + LPSS_PRIV_REMAP_ADDR); } static void intel_lpss_deassert_reset(const struct intel_lpss *lpss) diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c new file mode 100644 index 000000000000..b9428767e615 --- /dev/null +++ b/drivers/mfd/intel_soc_pmic_bxtwc.c @@ -0,0 +1,477 @@ +/* + * MFD core driver for Intel Broxton Whiskey Cove PMIC + * + * Copyright (C) 2015 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* PMIC device registers */ +#define REG_ADDR_MASK 0xFF00 +#define REG_ADDR_SHIFT 8 +#define REG_OFFSET_MASK 0xFF + +/* Interrupt Status Registers */ +#define BXTWC_IRQLVL1 0x4E02 +#define BXTWC_PWRBTNIRQ 0x4E03 + +#define BXTWC_THRM0IRQ 0x4E04 +#define BXTWC_THRM1IRQ 0x4E05 +#define BXTWC_THRM2IRQ 0x4E06 +#define BXTWC_BCUIRQ 0x4E07 +#define BXTWC_ADCIRQ 0x4E08 +#define BXTWC_CHGR0IRQ 0x4E09 +#define BXTWC_CHGR1IRQ 0x4E0A +#define BXTWC_GPIOIRQ0 0x4E0B +#define BXTWC_GPIOIRQ1 0x4E0C +#define BXTWC_CRITIRQ 0x4E0D + +/* Interrupt MASK Registers */ +#define BXTWC_MIRQLVL1 0x4E0E +#define BXTWC_MPWRTNIRQ 0x4E0F + +#define BXTWC_MTHRM0IRQ 0x4E12 +#define BXTWC_MTHRM1IRQ 0x4E13 +#define BXTWC_MTHRM2IRQ 0x4E14 +#define BXTWC_MBCUIRQ 0x4E15 +#define BXTWC_MADCIRQ 0x4E16 +#define BXTWC_MCHGR0IRQ 0x4E17 +#define BXTWC_MCHGR1IRQ 0x4E18 +#define BXTWC_MGPIO0IRQ 0x4E19 +#define BXTWC_MGPIO1IRQ 0x4E1A +#define BXTWC_MCRITIRQ 0x4E1B + +/* Whiskey Cove PMIC share same ACPI ID between different platforms */ +#define BROXTON_PMIC_WC_HRV 4 + +/* Manage in two IRQ chips since mask registers are not consecutive */ +enum bxtwc_irqs { + /* Level 1 */ + BXTWC_PWRBTN_LVL1_IRQ = 0, + BXTWC_TMU_LVL1_IRQ, + BXTWC_THRM_LVL1_IRQ, + BXTWC_BCU_LVL1_IRQ, + BXTWC_ADC_LVL1_IRQ, + BXTWC_CHGR_LVL1_IRQ, + BXTWC_GPIO_LVL1_IRQ, + BXTWC_CRIT_LVL1_IRQ, + + /* Level 2 */ + BXTWC_PWRBTN_IRQ, +}; + +enum bxtwc_irqs_level2 { + /* Level 2 */ + BXTWC_THRM0_IRQ = 0, + BXTWC_THRM1_IRQ, + BXTWC_THRM2_IRQ, + BXTWC_BCU_IRQ, + BXTWC_ADC_IRQ, + BXTWC_CHGR0_IRQ, + BXTWC_CHGR1_IRQ, + BXTWC_GPIO0_IRQ, + BXTWC_GPIO1_IRQ, + BXTWC_CRIT_IRQ, +}; + +static const struct regmap_irq bxtwc_regmap_irqs[] = { + REGMAP_IRQ_REG(BXTWC_PWRBTN_LVL1_IRQ, 0, BIT(0)), + REGMAP_IRQ_REG(BXTWC_TMU_LVL1_IRQ, 0, BIT(1)), + REGMAP_IRQ_REG(BXTWC_THRM_LVL1_IRQ, 0, BIT(2)), + REGMAP_IRQ_REG(BXTWC_BCU_LVL1_IRQ, 0, BIT(3)), + REGMAP_IRQ_REG(BXTWC_ADC_LVL1_IRQ, 0, BIT(4)), + REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)), + REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)), + REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)), + REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03), +}; + +static const struct regmap_irq bxtwc_regmap_irqs_level2[] = { + REGMAP_IRQ_REG(BXTWC_THRM0_IRQ, 0, 0xff), + REGMAP_IRQ_REG(BXTWC_THRM1_IRQ, 1, 0xbf), + REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff), + REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f), + REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff), + REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f), + REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f), + REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff), + REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f), + REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03), +}; + +static struct regmap_irq_chip bxtwc_regmap_irq_chip = { + .name = "bxtwc_irq_chip", + .status_base = BXTWC_IRQLVL1, + .mask_base = BXTWC_MIRQLVL1, + .irqs = bxtwc_regmap_irqs, + .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs), + .num_regs = 2, +}; + +static struct regmap_irq_chip bxtwc_regmap_irq_chip_level2 = { + .name = "bxtwc_irq_chip_level2", + .status_base = BXTWC_THRM0IRQ, + .mask_base = BXTWC_MTHRM0IRQ, + .irqs = bxtwc_regmap_irqs_level2, + .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_level2), + .num_regs = 10, +}; + +static struct resource gpio_resources[] = { + DEFINE_RES_IRQ_NAMED(BXTWC_GPIO0_IRQ, "GPIO0"), + DEFINE_RES_IRQ_NAMED(BXTWC_GPIO1_IRQ, "GPIO1"), +}; + +static struct resource adc_resources[] = { + DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"), +}; + +static struct resource charger_resources[] = { + DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"), + DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"), +}; + +static struct resource thermal_resources[] = { + DEFINE_RES_IRQ(BXTWC_THRM0_IRQ), + DEFINE_RES_IRQ(BXTWC_THRM1_IRQ), + DEFINE_RES_IRQ(BXTWC_THRM2_IRQ), +}; + +static struct resource bcu_resources[] = { + DEFINE_RES_IRQ_NAMED(BXTWC_BCU_IRQ, "BCU"), +}; + +static struct mfd_cell bxt_wc_dev[] = { + { + .name = "bxt_wcove_gpadc", + .num_resources = ARRAY_SIZE(adc_resources), + .resources = adc_resources, + }, + { + .name = "bxt_wcove_thermal", + .num_resources = ARRAY_SIZE(thermal_resources), + .resources = thermal_resources, + }, + { + .name = "bxt_wcove_ext_charger", + .num_resources = ARRAY_SIZE(charger_resources), + .resources = charger_resources, + }, + { + .name = "bxt_wcove_bcu", + .num_resources = ARRAY_SIZE(bcu_resources), + .resources = bcu_resources, + }, + { + .name = "bxt_wcove_gpio", + .num_resources = ARRAY_SIZE(gpio_resources), + .resources = gpio_resources, + }, + { + .name = "bxt_wcove_region", + }, +}; + +static int regmap_ipc_byte_reg_read(void *context, unsigned int reg, + unsigned int *val) +{ + int ret; + int i2c_addr; + u8 ipc_in[2]; + u8 ipc_out[4]; + struct intel_soc_pmic *pmic = context; + + if (reg & REG_ADDR_MASK) + i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT; + else { + i2c_addr = BXTWC_DEVICE1_ADDR; + if (!i2c_addr) { + dev_err(pmic->dev, "I2C address not set\n"); + return -EINVAL; + } + } + reg &= REG_OFFSET_MASK; + + ipc_in[0] = reg; + ipc_in[1] = i2c_addr; + ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS, + PMC_IPC_PMIC_ACCESS_READ, + ipc_in, sizeof(ipc_in), (u32 *)ipc_out, 1); + if (ret) { + dev_err(pmic->dev, "Failed to read from PMIC\n"); + return ret; + } + *val = ipc_out[0]; + + return 0; +} + +static int regmap_ipc_byte_reg_write(void *context, unsigned int reg, + unsigned int val) +{ + int ret; + int i2c_addr; + u8 ipc_in[3]; + struct intel_soc_pmic *pmic = context; + + if (reg & REG_ADDR_MASK) + i2c_addr = (reg & REG_ADDR_MASK) >> REG_ADDR_SHIFT; + else { + i2c_addr = BXTWC_DEVICE1_ADDR; + if (!i2c_addr) { + dev_err(pmic->dev, "I2C address not set\n"); + return -EINVAL; + } + } + reg &= REG_OFFSET_MASK; + + ipc_in[0] = reg; + ipc_in[1] = i2c_addr; + ipc_in[2] = val; + ret = intel_pmc_ipc_command(PMC_IPC_PMIC_ACCESS, + PMC_IPC_PMIC_ACCESS_WRITE, + ipc_in, sizeof(ipc_in), NULL, 0); + if (ret) { + dev_err(pmic->dev, "Failed to write to PMIC\n"); + return ret; + } + + return 0; +} + +/* sysfs interfaces to r/w PMIC registers, required by initial script */ +static unsigned long bxtwc_reg_addr; +static ssize_t bxtwc_reg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "0x%lx\n", bxtwc_reg_addr); +} + +static ssize_t bxtwc_reg_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + if (kstrtoul(buf, 0, &bxtwc_reg_addr)) { + dev_err(dev, "Invalid register address\n"); + return -EINVAL; + } + return (ssize_t)count; +} + +static ssize_t bxtwc_val_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + unsigned int val; + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); + + ret = regmap_read(pmic->regmap, bxtwc_reg_addr, &val); + if (ret < 0) { + dev_err(dev, "Failed to read 0x%lx\n", bxtwc_reg_addr); + return -EIO; + } + + return sprintf(buf, "0x%02x\n", val); +} + +static ssize_t bxtwc_val_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int ret; + unsigned int val; + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); + + ret = kstrtouint(buf, 0, &val); + if (ret) + return ret; + + ret = regmap_write(pmic->regmap, bxtwc_reg_addr, val); + if (ret) { + dev_err(dev, "Failed to write value 0x%02x to address 0x%lx", + val, bxtwc_reg_addr); + return -EIO; + } + return count; +} + +static DEVICE_ATTR(addr, S_IWUSR | S_IRUSR, bxtwc_reg_show, bxtwc_reg_store); +static DEVICE_ATTR(val, S_IWUSR | S_IRUSR, bxtwc_val_show, bxtwc_val_store); +static struct attribute *bxtwc_attrs[] = { + &dev_attr_addr.attr, + &dev_attr_val.attr, + NULL +}; + +static const struct attribute_group bxtwc_group = { + .attrs = bxtwc_attrs, +}; + +static const struct regmap_config bxtwc_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .reg_write = regmap_ipc_byte_reg_write, + .reg_read = regmap_ipc_byte_reg_read, +}; + +static int bxtwc_probe(struct platform_device *pdev) +{ + int ret; + acpi_handle handle; + acpi_status status; + unsigned long long hrv; + struct intel_soc_pmic *pmic; + + handle = ACPI_HANDLE(&pdev->dev); + status = acpi_evaluate_integer(handle, "_HRV", NULL, &hrv); + if (ACPI_FAILURE(status)) { + dev_err(&pdev->dev, "Failed to get PMIC hardware revision\n"); + return -ENODEV; + } + if (hrv != BROXTON_PMIC_WC_HRV) { + dev_err(&pdev->dev, "Invalid PMIC hardware revision: %llu\n", + hrv); + return -ENODEV; + } + + pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); + if (!pmic) + return -ENOMEM; + + ret = platform_get_irq(pdev, 0); + if (ret < 0) { + dev_err(&pdev->dev, "Invalid IRQ\n"); + return ret; + } + pmic->irq = ret; + + dev_set_drvdata(&pdev->dev, pmic); + pmic->dev = &pdev->dev; + + pmic->regmap = devm_regmap_init(&pdev->dev, NULL, pmic, + &bxtwc_regmap_config); + if (IS_ERR(pmic->regmap)) { + ret = PTR_ERR(pmic->regmap); + dev_err(&pdev->dev, "Failed to initialise regmap: %d\n", ret); + return ret; + } + + ret = regmap_add_irq_chip(pmic->regmap, pmic->irq, + IRQF_ONESHOT | IRQF_SHARED, + 0, &bxtwc_regmap_irq_chip, + &pmic->irq_chip_data); + if (ret) { + dev_err(&pdev->dev, "Failed to add IRQ chip\n"); + return ret; + } + + ret = regmap_add_irq_chip(pmic->regmap, pmic->irq, + IRQF_ONESHOT | IRQF_SHARED, + 0, &bxtwc_regmap_irq_chip_level2, + &pmic->irq_chip_data_level2); + if (ret) { + dev_err(&pdev->dev, "Failed to add secondary IRQ chip\n"); + goto err_irq_chip_level2; + } + + ret = mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE, bxt_wc_dev, + ARRAY_SIZE(bxt_wc_dev), NULL, 0, + NULL); + if (ret) { + dev_err(&pdev->dev, "Failed to add devices\n"); + goto err_mfd; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &bxtwc_group); + if (ret) { + dev_err(&pdev->dev, "Failed to create sysfs group %d\n", ret); + goto err_sysfs; + } + + return 0; + +err_sysfs: + mfd_remove_devices(&pdev->dev); +err_mfd: + regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2); +err_irq_chip_level2: + regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); + + return ret; +} + +static int bxtwc_remove(struct platform_device *pdev) +{ + struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev); + + sysfs_remove_group(&pdev->dev.kobj, &bxtwc_group); + mfd_remove_devices(&pdev->dev); + regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); + regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data_level2); + + return 0; +} + +static void bxtwc_shutdown(struct platform_device *pdev) +{ + struct intel_soc_pmic *pmic = dev_get_drvdata(&pdev->dev); + + disable_irq(pmic->irq); +} + +#ifdef CONFIG_PM_SLEEP +static int bxtwc_suspend(struct device *dev) +{ + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); + + disable_irq(pmic->irq); + + return 0; +} + +static int bxtwc_resume(struct device *dev) +{ + struct intel_soc_pmic *pmic = dev_get_drvdata(dev); + + enable_irq(pmic->irq); + return 0; +} +#endif +static SIMPLE_DEV_PM_OPS(bxtwc_pm_ops, bxtwc_suspend, bxtwc_resume); + +static const struct acpi_device_id bxtwc_acpi_ids[] = { + { "INT34D3", }, + { } +}; +MODULE_DEVICE_TABLE(acpi, pmic_acpi_ids); + +static struct platform_driver bxtwc_driver = { + .probe = bxtwc_probe, + .remove = bxtwc_remove, + .shutdown = bxtwc_shutdown, + .driver = { + .name = "BXTWC PMIC", + .pm = &bxtwc_pm_ops, + .acpi_match_table = ACPI_PTR(bxtwc_acpi_ids), + }, +}; + +module_platform_driver(bxtwc_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Qipeng Zha"); diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index 463f4eae20c1..05b924542ee2 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c @@ -448,7 +448,6 @@ static int kempld_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct kempld_device_data *pld; struct resource *ioport; - int ret; pld = devm_kzalloc(dev, sizeof(*pld), GFP_KERNEL); if (!pld) @@ -471,11 +470,7 @@ static int kempld_probe(struct platform_device *pdev) mutex_init(&pld->lock); platform_set_drvdata(pdev, pld); - ret = kempld_detect_device(pld); - if (ret) - return ret; - - return 0; + return kempld_detect_device(pld); } static int kempld_remove(struct platform_device *pdev) @@ -756,7 +751,6 @@ MODULE_DEVICE_TABLE(dmi, kempld_dmi_table); static int __init kempld_init(void) { const struct dmi_system_id *id; - int ret; if (force_device_id[0]) { for (id = kempld_dmi_table; @@ -771,11 +765,7 @@ static int __init kempld_init(void) return -ENODEV; } - ret = platform_driver_register(&kempld_driver); - if (ret) - return ret; - - return 0; + return platform_driver_register(&kempld_driver); } static void __exit kempld_exit(void) diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c index 643f3750e830..5abcbb2e8849 100644 --- a/drivers/mfd/lm3533-core.c +++ b/drivers/mfd/lm3533-core.c @@ -472,11 +472,7 @@ static int lm3533_device_setup(struct lm3533 *lm3533, if (ret) return ret; - ret = lm3533_set_boost_ovp(lm3533, pdata->boost_ovp); - if (ret) - return ret; - - return 0; + return lm3533_set_boost_ovp(lm3533, pdata->boost_ovp); } static int lm3533_device_init(struct lm3533 *lm3533) @@ -596,7 +592,6 @@ static int lm3533_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct lm3533 *lm3533; - int ret; dev_dbg(&i2c->dev, "%s\n", __func__); @@ -613,11 +608,7 @@ static int lm3533_i2c_probe(struct i2c_client *i2c, lm3533->dev = &i2c->dev; lm3533->irq = i2c->irq; - ret = lm3533_device_init(lm3533); - if (ret) - return ret; - - return 0; + return lm3533_device_init(lm3533); } static int lm3533_i2c_remove(struct i2c_client *i2c) diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index c5a9a08b5dfb..b514f3cf140d 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c @@ -132,24 +132,18 @@ static struct resource gpio_ich_res[] = { }, }; -enum lpc_cells { - LPC_WDT = 0, - LPC_GPIO, +static struct mfd_cell lpc_ich_wdt_cell = { + .name = "iTCO_wdt", + .num_resources = ARRAY_SIZE(wdt_ich_res), + .resources = wdt_ich_res, + .ignore_resource_conflicts = true, }; -static struct mfd_cell lpc_ich_cells[] = { - [LPC_WDT] = { - .name = "iTCO_wdt", - .num_resources = ARRAY_SIZE(wdt_ich_res), - .resources = wdt_ich_res, - .ignore_resource_conflicts = true, - }, - [LPC_GPIO] = { - .name = "gpio_ich", - .num_resources = ARRAY_SIZE(gpio_ich_res), - .resources = gpio_ich_res, - .ignore_resource_conflicts = true, - }, +static struct mfd_cell lpc_ich_gpio_cell = { + .name = "gpio_ich", + .num_resources = ARRAY_SIZE(gpio_ich_res), + .resources = gpio_ich_res, + .ignore_resource_conflicts = true, }; /* chipset related info */ @@ -841,7 +835,7 @@ static int lpc_ich_finalize_wdt_cell(struct pci_dev *dev) struct itco_wdt_platform_data *pdata; struct lpc_ich_priv *priv = pci_get_drvdata(dev); struct lpc_ich_info *info; - struct mfd_cell *cell = &lpc_ich_cells[LPC_WDT]; + struct mfd_cell *cell = &lpc_ich_wdt_cell; pdata = devm_kzalloc(&dev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) @@ -860,7 +854,7 @@ static int lpc_ich_finalize_wdt_cell(struct pci_dev *dev) static void lpc_ich_finalize_gpio_cell(struct pci_dev *dev) { struct lpc_ich_priv *priv = pci_get_drvdata(dev); - struct mfd_cell *cell = &lpc_ich_cells[LPC_GPIO]; + struct mfd_cell *cell = &lpc_ich_gpio_cell; cell->platform_data = &lpc_chipset_info[priv->chipset]; cell->pdata_size = sizeof(struct lpc_ich_info); @@ -904,7 +898,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev) base_addr = base_addr_cfg & 0x0000ff80; if (!base_addr) { dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); - lpc_ich_cells[LPC_GPIO].num_resources--; + lpc_ich_gpio_cell.num_resources--; goto gpe0_done; } @@ -918,7 +912,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev) * the platform_device subsystem doesn't see this resource * or it will register an invalid region. */ - lpc_ich_cells[LPC_GPIO].num_resources--; + lpc_ich_gpio_cell.num_resources--; acpi_conflict = true; } else { lpc_ich_enable_acpi_space(dev); @@ -958,12 +952,12 @@ gpe0_done: lpc_ich_finalize_gpio_cell(dev); ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, - &lpc_ich_cells[LPC_GPIO], 1, NULL, 0, NULL); + &lpc_ich_gpio_cell, 1, NULL, 0, NULL); gpio_done: if (acpi_conflict) pr_warn("Resource conflict(s) found affecting %s\n", - lpc_ich_cells[LPC_GPIO].name); + lpc_ich_gpio_cell.name); return ret; } @@ -1007,7 +1001,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) */ if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { /* Don't register iomem for TCO ver 1 */ - lpc_ich_cells[LPC_WDT].num_resources--; + lpc_ich_wdt_cell.num_resources--; } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) { pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); base_addr = base_addr_cfg & 0xffffc000; @@ -1035,7 +1029,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) goto wdt_done; ret = mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, - &lpc_ich_cells[LPC_WDT], 1, NULL, 0, NULL); + &lpc_ich_wdt_cell, 1, NULL, 0, NULL); wdt_done: return ret; diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index d3cfa9cf5c8f..156ed6f92aa3 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -55,6 +55,7 @@ static const struct of_device_id max8997_pmic_dt_match[] = { { .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 }, {}, }; +MODULE_DEVICE_TABLE(of, max8997_pmic_dt_match); #endif int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) diff --git a/drivers/mfd/pcf50633-irq.c b/drivers/mfd/pcf50633-irq.c index 498286cbb530..71d43edf110c 100644 --- a/drivers/mfd/pcf50633-irq.c +++ b/drivers/mfd/pcf50633-irq.c @@ -55,7 +55,7 @@ EXPORT_SYMBOL_GPL(pcf50633_free_irq); static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask) { u8 reg, bit; - int ret = 0, idx; + int idx; idx = irq >> 3; reg = PCF50633_REG_INT1M + idx; @@ -72,7 +72,7 @@ static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask) mutex_unlock(&pcf->lock); - return ret; + return 0; } int pcf50633_irq_mask(struct pcf50633 *pcf, int irq) diff --git a/drivers/mfd/qcom_rpm.c b/drivers/mfd/qcom_rpm.c index 6afc9fabd94c..207a3bd68559 100644 --- a/drivers/mfd/qcom_rpm.c +++ b/drivers/mfd/qcom_rpm.c @@ -550,7 +550,7 @@ static int qcom_rpm_probe(struct platform_device *pdev) ret = devm_request_irq(&pdev->dev, irq_ack, qcom_rpm_ack_interrupt, - IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, + IRQF_TRIGGER_RISING, "qcom_rpm_ack", rpm); if (ret) { diff --git a/drivers/mfd/rt5033.c b/drivers/mfd/rt5033.c index d60f91619c4a..2b95485f0057 100644 --- a/drivers/mfd/rt5033.c +++ b/drivers/mfd/rt5033.c @@ -47,6 +47,9 @@ static const struct mfd_cell rt5033_devs[] = { }, { .name = "rt5033-battery", .of_compatible = "richtek,rt5033-battery", + }, { + .name = "rt5033-led", + .of_compatible = "richtek,rt5033-led", }, }; @@ -137,7 +140,6 @@ static struct i2c_driver rt5033_driver = { }; module_i2c_driver(rt5033_driver); -MODULE_ALIAS("i2c:rt5033"); MODULE_DESCRIPTION("Richtek RT5033 multi-function core driver"); MODULE_AUTHOR("Beomho Seo "); MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/rts5209.c b/drivers/mfd/rts5209.c index 373e253c33df..b95beecf767f 100644 --- a/drivers/mfd/rts5209.c +++ b/drivers/mfd/rts5209.c @@ -138,11 +138,7 @@ static int rts5209_card_power_on(struct rtsx_pcr *pcr, int card) rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL, pwr_mask, pwr_on); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, 0x00); - err = rtsx_pci_send_cmd(pcr, 100); - if (err < 0) - return err; - - return 0; + return rtsx_pci_send_cmd(pcr, 100); } static int rts5209_card_power_off(struct rtsx_pcr *pcr, int card) diff --git a/drivers/mfd/rts5227.c b/drivers/mfd/rts5227.c index ce012d78ce2a..ff296a4bf3d2 100644 --- a/drivers/mfd/rts5227.c +++ b/drivers/mfd/rts5227.c @@ -26,6 +26,14 @@ #include "rtsx_pcr.h" +static u8 rts5227_get_ic_version(struct rtsx_pcr *pcr) +{ + u8 val; + + rtsx_pci_read_register(pcr, DUMMY_REG_RESET_0, &val); + return val & 0x0F; +} + static void rts5227_fill_driving(struct rtsx_pcr *pcr, u8 voltage) { u8 driving_3v3[4][3] = { @@ -88,7 +96,7 @@ static void rts5227_force_power_down(struct rtsx_pcr *pcr, u8 pm_state) rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0); if (pm_state == HOST_ENTER_S3) - rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10); + rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3, 0x10, 0x10); rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03); } @@ -121,7 +129,7 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr) rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0xB8); else rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0x88); - rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00); + rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, pcr->reg_pm_ctrl3, 0x10, 0x00); return rtsx_pci_send_cmd(pcr, 100); } @@ -179,11 +187,7 @@ static int rts5227_card_power_on(struct rtsx_pcr *pcr, int card) SD_POWER_MASK, SD_POWER_ON); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, 0x06); - err = rtsx_pci_send_cmd(pcr, 100); - if (err < 0) - return err; - - return 0; + return rtsx_pci_send_cmd(pcr, 100); } static int rts5227_card_power_off(struct rtsx_pcr *pcr, int card) @@ -298,8 +302,73 @@ void rts5227_init_params(struct rtsx_pcr *pcr) pcr->tx_initial_phase = SET_CLOCK_PHASE(27, 27, 15); pcr->rx_initial_phase = SET_CLOCK_PHASE(30, 7, 7); + pcr->ic_version = rts5227_get_ic_version(pcr); pcr->sd_pull_ctl_enable_tbl = rts5227_sd_pull_ctl_enable_tbl; pcr->sd_pull_ctl_disable_tbl = rts5227_sd_pull_ctl_disable_tbl; pcr->ms_pull_ctl_enable_tbl = rts5227_ms_pull_ctl_enable_tbl; pcr->ms_pull_ctl_disable_tbl = rts5227_ms_pull_ctl_disable_tbl; + + pcr->reg_pm_ctrl3 = PM_CTRL3; +} + +static int rts522a_optimize_phy(struct rtsx_pcr *pcr) +{ + int err; + + err = rtsx_pci_write_register(pcr, RTS522A_PM_CTRL3, D3_DELINK_MODE_EN, + 0x00); + if (err < 0) + return err; + + if (is_version(pcr, 0x522A, IC_VER_A)) { + err = rtsx_pci_write_phy_register(pcr, PHY_RCR2, + PHY_RCR2_INIT_27S); + if (err) + return err; + + rtsx_pci_write_phy_register(pcr, PHY_RCR1, PHY_RCR1_INIT_27S); + rtsx_pci_write_phy_register(pcr, PHY_FLD0, PHY_FLD0_INIT_27S); + rtsx_pci_write_phy_register(pcr, PHY_FLD3, PHY_FLD3_INIT_27S); + rtsx_pci_write_phy_register(pcr, PHY_FLD4, PHY_FLD4_INIT_27S); + } + + return 0; +} + +static int rts522a_extra_init_hw(struct rtsx_pcr *pcr) +{ + rts5227_extra_init_hw(pcr); + + rtsx_pci_write_register(pcr, FUNC_FORCE_CTL, FUNC_FORCE_UPME_XMT_DBG, + FUNC_FORCE_UPME_XMT_DBG); + rtsx_pci_write_register(pcr, PCLK_CTL, 0x04, 0x04); + rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0); + rtsx_pci_write_register(pcr, PM_CLK_FORCE_CTL, 0xFF, 0x11); + + return 0; +} + +/* rts522a operations mainly derived from rts5227, except phy/hw init setting. + */ +static const struct pcr_ops rts522a_pcr_ops = { + .fetch_vendor_settings = rts5227_fetch_vendor_settings, + .extra_init_hw = rts522a_extra_init_hw, + .optimize_phy = rts522a_optimize_phy, + .turn_on_led = rts5227_turn_on_led, + .turn_off_led = rts5227_turn_off_led, + .enable_auto_blink = rts5227_enable_auto_blink, + .disable_auto_blink = rts5227_disable_auto_blink, + .card_power_on = rts5227_card_power_on, + .card_power_off = rts5227_card_power_off, + .switch_output_voltage = rts5227_switch_output_voltage, + .cd_deglitch = NULL, + .conv_clk_and_div_n = NULL, + .force_power_down = rts5227_force_power_down, +}; + +void rts522a_init_params(struct rtsx_pcr *pcr) +{ + rts5227_init_params(pcr); + + pcr->reg_pm_ctrl3 = RTS522A_PM_CTRL3; } diff --git a/drivers/mfd/rts5229.c b/drivers/mfd/rts5229.c index ace45384ec8b..9ed9dc84eac8 100644 --- a/drivers/mfd/rts5229.c +++ b/drivers/mfd/rts5229.c @@ -129,11 +129,7 @@ static int rts5229_card_power_on(struct rtsx_pcr *pcr, int card) SD_POWER_MASK, SD_POWER_ON); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, 0x06); - err = rtsx_pci_send_cmd(pcr, 100); - if (err < 0) - return err; - - return 0; + return rtsx_pci_send_cmd(pcr, 100); } static int rts5229_card_power_off(struct rtsx_pcr *pcr, int card) diff --git a/drivers/mfd/rts5249.c b/drivers/mfd/rts5249.c index eb2d5866f719..40f8bb14fc59 100644 --- a/drivers/mfd/rts5249.c +++ b/drivers/mfd/rts5249.c @@ -234,11 +234,7 @@ static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card) SD_POWER_MASK, SD_VCC_POWER_ON); rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PWR_GATE_CTRL, LDO3318_PWR_MASK, 0x06); - err = rtsx_pci_send_cmd(pcr, 100); - if (err < 0) - return err; - - return 0; + return rtsx_pci_send_cmd(pcr, 100); } static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card) diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index a66540a49079..f3820d08c9a3 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c @@ -55,6 +55,7 @@ static const struct pci_device_id rtsx_pci_ids[] = { { PCI_DEVICE(0x10EC, 0x5229), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x5227), PCI_CLASS_OTHERS << 16, 0xFF0000 }, + { PCI_DEVICE(0x10EC, 0x522A), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x5249), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x5287), PCI_CLASS_OTHERS << 16, 0xFF0000 }, { PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 }, @@ -571,11 +572,7 @@ static int rtsx_pci_set_pull_ctl(struct rtsx_pcr *pcr, const u32 *tbl) tbl++; } - err = rtsx_pci_send_cmd(pcr, 100); - if (err < 0) - return err; - - return 0; + return rtsx_pci_send_cmd(pcr, 100); } int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card) @@ -1102,6 +1099,10 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) rts5227_init_params(pcr); break; + case 0x522A: + rts522a_init_params(pcr); + break; + case 0x5249: rts5249_init_params(pcr); break; diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h index ce48842570d7..931d1ae3ce32 100644 --- a/drivers/mfd/rtsx_pcr.h +++ b/drivers/mfd/rtsx_pcr.h @@ -27,6 +27,8 @@ #define MIN_DIV_N_PCR 80 #define MAX_DIV_N_PCR 208 +#define RTS522A_PM_CTRL3 0xFF7E + #define RTS524A_PME_FORCE_CTL 0xFF78 #define RTS524A_PM_CTRL3 0xFF7E @@ -38,6 +40,7 @@ void rts5229_init_params(struct rtsx_pcr *pcr); void rtl8411_init_params(struct rtsx_pcr *pcr); void rtl8402_init_params(struct rtsx_pcr *pcr); void rts5227_init_params(struct rtsx_pcr *pcr); +void rts522a_init_params(struct rtsx_pcr *pcr); void rts5249_init_params(struct rtsx_pcr *pcr); void rts524a_init_params(struct rtsx_pcr *pcr); void rts525a_init_params(struct rtsx_pcr *pcr); diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index d206a3e8fe87..989076d6cb83 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -103,12 +103,9 @@ static const struct mfd_cell s2mpa01_devs[] = { }; static const struct mfd_cell s2mpu02_devs[] = { - { .name = "s2mpu02-pmic", }, - { .name = "s2mpu02-rtc", }, { - .name = "s2mpu02-clk", - .of_compatible = "samsung,s2mpu02-clk", - } + .name = "s2mpu02-pmic", + }, }; #ifdef CONFIG_OF @@ -253,6 +250,38 @@ static const struct regmap_config s5m8767_regmap_config = { .cache_type = REGCACHE_FLAT, }; +static void sec_pmic_dump_rev(struct sec_pmic_dev *sec_pmic) +{ + unsigned int val; + + /* For each device type, the REG_ID is always the first register */ + if (!regmap_read(sec_pmic->regmap_pmic, S2MPS11_REG_ID, &val)) + dev_dbg(sec_pmic->dev, "Revision: 0x%x\n", val); +} + +static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic) +{ + int err; + + if (sec_pmic->device_type != S2MPS13X) + return; + + if (sec_pmic->pdata->disable_wrstbi) { + /* + * If WRSTBI pin is pulled down this feature must be disabled + * because each Suspend to RAM will trigger buck voltage reset + * to default values. + */ + err = regmap_update_bits(sec_pmic->regmap_pmic, + S2MPS13_REG_WRSTBI, + S2MPS13_REG_WRSTBI_MASK, 0x0); + if (err) + dev_warn(sec_pmic->dev, + "Cannot initialize WRSTBI config: %d\n", + err); + } +} + #ifdef CONFIG_OF /* * Only the common platform data elements for s5m8767 are parsed here from the @@ -278,6 +307,10 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( * not parsed here. */ + pd->manual_poweroff = of_property_read_bool(dev->of_node, + "samsung,s2mps11-acokb-ground"); + pd->disable_wrstbi = of_property_read_bool(dev->of_node, + "samsung,s2mps11-wrstbi-ground"); return pd; } #else @@ -423,6 +456,8 @@ static int sec_pmic_probe(struct i2c_client *i2c, goto err_mfd; device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup); + sec_pmic_configure(sec_pmic); + sec_pmic_dump_rev(sec_pmic); return ret; @@ -440,6 +475,33 @@ static int sec_pmic_remove(struct i2c_client *i2c) return 0; } +static void sec_pmic_shutdown(struct i2c_client *i2c) +{ + struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); + unsigned int reg, mask; + + if (!sec_pmic->pdata->manual_poweroff) + return; + + switch (sec_pmic->device_type) { + case S2MPS11X: + reg = S2MPS11_REG_CTRL1; + mask = S2MPS11_CTRL1_PWRHOLD_MASK; + break; + default: + /* + * Currently only one board with S2MPS11 needs this, so just + * ignore the rest. + */ + dev_warn(sec_pmic->dev, + "Unsupported device %lu for manual power off\n", + sec_pmic->device_type); + return; + } + + regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, 0); +} + #ifdef CONFIG_PM_SLEEP static int sec_pmic_suspend(struct device *dev) { @@ -491,6 +553,7 @@ static struct i2c_driver sec_pmic_driver = { }, .probe = sec_pmic_probe, .remove = sec_pmic_remove, + .shutdown = sec_pmic_shutdown, .id_table = sec_pmic_id, }; diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 91077efc8050..c646784c5a7d 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1719,6 +1719,7 @@ static const struct of_device_id of_sm501_match_tbl[] = { { .compatible = "smi,sm501", }, { /* end */ } }; +MODULE_DEVICE_TABLE(of, of_sm501_match_tbl); static struct platform_driver sm501_plat_driver = { .driver = { diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index e971af86ce1e..8222e374e4b1 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c @@ -795,6 +795,7 @@ static int stmpe24xx_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) return 2; case STMPE_BLOCK_KEYPAD: + case STMPE_BLOCK_PWM: return 1; case STMPE_BLOCK_GPIO: diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index 5de95c265c1a..51c54951c220 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -25,73 +25,18 @@ #include #include -int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value) -{ - int ret; - - ret = mutex_lock_interruptible(&tps6105x->lock); - if (ret) - return ret; - ret = i2c_smbus_write_byte_data(tps6105x->client, reg, value); - mutex_unlock(&tps6105x->lock); - if (ret < 0) - return ret; - - return 0; -} -EXPORT_SYMBOL(tps6105x_set); - -int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf) -{ - int ret; - - ret = mutex_lock_interruptible(&tps6105x->lock); - if (ret) - return ret; - ret = i2c_smbus_read_byte_data(tps6105x->client, reg); - mutex_unlock(&tps6105x->lock); - if (ret < 0) - return ret; - - *buf = ret; - return 0; -} -EXPORT_SYMBOL(tps6105x_get); - -/* - * Masks off the bits in the mask and sets the bits in the bitvalues - * parameter in one atomic operation - */ -int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg, - u8 bitmask, u8 bitvalues) -{ - int ret; - u8 regval; - - ret = mutex_lock_interruptible(&tps6105x->lock); - if (ret) - return ret; - ret = i2c_smbus_read_byte_data(tps6105x->client, reg); - if (ret < 0) - goto fail; - regval = ret; - regval = (~bitmask & regval) | (bitmask & bitvalues); - ret = i2c_smbus_write_byte_data(tps6105x->client, reg, regval); -fail: - mutex_unlock(&tps6105x->lock); - if (ret < 0) - return ret; - - return 0; -} -EXPORT_SYMBOL(tps6105x_mask_and_set); +static struct regmap_config tps6105x_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = TPS6105X_REG_3, +}; static int tps6105x_startup(struct tps6105x *tps6105x) { int ret; - u8 regval; + unsigned int regval; - ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val); + ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val); if (ret) return ret; switch (regval >> TPS6105X_REG0_MODE_SHIFT) { @@ -119,37 +64,59 @@ static int tps6105x_startup(struct tps6105x *tps6105x) } /* - * MFD cells - we have one cell which is selected operation - * mode, and we always have a GPIO cell. + * MFD cells - we always have a GPIO cell and we have one cell + * which is selected operation mode. */ -static struct mfd_cell tps6105x_cells[] = { - { - /* name will be runtime assigned */ - .id = -1, - }, - { - .name = "tps6105x-gpio", - .id = -1, - }, +static struct mfd_cell tps6105x_gpio_cell = { + .name = "tps6105x-gpio", +}; + +static struct mfd_cell tps6105x_leds_cell = { + .name = "tps6105x-leds", +}; + +static struct mfd_cell tps6105x_flash_cell = { + .name = "tps6105x-flash", }; +static struct mfd_cell tps6105x_regulator_cell = { + .name = "tps6105x-regulator", +}; + +static int tps6105x_add_device(struct tps6105x *tps6105x, + struct mfd_cell *cell) +{ + cell->platform_data = tps6105x; + cell->pdata_size = sizeof(*tps6105x); + + return mfd_add_devices(&tps6105x->client->dev, + PLATFORM_DEVID_AUTO, cell, 1, NULL, 0, NULL); +} + static int tps6105x_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct tps6105x *tps6105x; struct tps6105x_platform_data *pdata; int ret; - int i; + + pdata = dev_get_platdata(&client->dev); + if (!pdata) { + dev_err(&client->dev, "missing platform data\n"); + return -ENODEV; + } tps6105x = devm_kmalloc(&client->dev, sizeof(*tps6105x), GFP_KERNEL); if (!tps6105x) return -ENOMEM; + tps6105x->regmap = devm_regmap_init_i2c(client, &tps6105x_regmap_config); + if (IS_ERR(tps6105x->regmap)) + return PTR_ERR(tps6105x->regmap); + i2c_set_clientdata(client, tps6105x); tps6105x->client = client; - pdata = dev_get_platdata(&client->dev); tps6105x->pdata = pdata; - mutex_init(&tps6105x->lock); ret = tps6105x_startup(tps6105x); if (ret) { @@ -157,38 +124,33 @@ static int tps6105x_probe(struct i2c_client *client, return ret; } - /* Remove warning texts when you implement new cell drivers */ + ret = tps6105x_add_device(tps6105x, &tps6105x_gpio_cell); + if (ret) + return ret; + switch (pdata->mode) { case TPS6105X_MODE_SHUTDOWN: dev_info(&client->dev, "present, not used for anything, only GPIO\n"); break; case TPS6105X_MODE_TORCH: - tps6105x_cells[0].name = "tps6105x-leds"; - dev_warn(&client->dev, - "torch mode is unsupported\n"); + ret = tps6105x_add_device(tps6105x, &tps6105x_leds_cell); break; case TPS6105X_MODE_TORCH_FLASH: - tps6105x_cells[0].name = "tps6105x-flash"; - dev_warn(&client->dev, - "flash mode is unsupported\n"); + ret = tps6105x_add_device(tps6105x, &tps6105x_flash_cell); break; case TPS6105X_MODE_VOLTAGE: - tps6105x_cells[0].name ="tps6105x-regulator"; + ret = tps6105x_add_device(tps6105x, &tps6105x_regulator_cell); break; default: + dev_warn(&client->dev, "invalid mode: %d\n", pdata->mode); break; } - /* Set up and register the platform devices. */ - for (i = 0; i < ARRAY_SIZE(tps6105x_cells); i++) { - /* One state holder for all drivers, this is simple */ - tps6105x_cells[i].platform_data = tps6105x; - tps6105x_cells[i].pdata_size = sizeof(*tps6105x); - } + if (ret) + mfd_remove_devices(&client->dev); - return mfd_add_devices(&client->dev, 0, tps6105x_cells, - ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL); + return ret; } static int tps6105x_remove(struct i2c_client *client) @@ -198,7 +160,7 @@ static int tps6105x_remove(struct i2c_client *client) mfd_remove_devices(&client->dev); /* Put chip in shutdown mode */ - tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0, + regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, TPS6105X_REG0_MODE_MASK, TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index 55add0453ae9..d32b54426b70 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c @@ -39,6 +39,10 @@ static const struct mfd_cell tps65217s[] = { .name = "tps65217-bl", .of_compatible = "ti,tps65217-bl", }, + { + .name = "tps65217-charger", + .of_compatible = "ti,tps65217-charger", + }, }; /** diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index a151ee2eed2a..08a693cd38cc 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c @@ -647,6 +647,8 @@ static int twl6040_probe(struct i2c_client *client, twl6040->clk32k = devm_clk_get(&client->dev, "clk32k"); if (IS_ERR(twl6040->clk32k)) { + if (PTR_ERR(twl6040->clk32k) == -EPROBE_DEFER) + return -EPROBE_DEFER; dev_info(&client->dev, "clk32k is not handled\n"); twl6040->clk32k = NULL; } diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c index c4b9374efd76..2bb2d0467a92 100644 --- a/drivers/mfd/wm5110-tables.c +++ b/drivers/mfd/wm5110-tables.c @@ -250,7 +250,7 @@ static const struct reg_sequence wm5110_revd_patch[] = { }; /* Add extra headphone write sequence locations */ -static const struct reg_default wm5110_reve_patch[] = { +static const struct reg_sequence wm5110_reve_patch[] = { { 0x80, 0x3 }, { 0x80, 0x3 }, { 0x4b, 0x138 }, @@ -1481,6 +1481,7 @@ static const struct reg_default wm5110_reg_default[] = { { 0x00000C04, 0xA101 }, /* R3076 - GPIO5 CTRL */ { 0x00000C0F, 0x0400 }, /* R3087 - IRQ CTRL 1 */ { 0x00000C10, 0x1000 }, /* R3088 - GPIO Debounce Config */ + { 0x00000C18, 0x0000 }, /* R3096 - GP Switch 1 */ { 0x00000C20, 0x8002 }, /* R3104 - Misc Pad Ctrl 1 */ { 0x00000C21, 0x8001 }, /* R3105 - Misc Pad Ctrl 2 */ { 0x00000C22, 0x0000 }, /* R3106 - Misc Pad Ctrl 3 */ @@ -1632,6 +1633,185 @@ static const struct reg_default wm5110_reg_default[] = { { 0x00000EF8, 0x0000 }, /* R3832 - ISRC 3 CTRL 3 */ { 0x00000F00, 0x0000 }, /* R3840 - Clock Control */ { 0x00000F01, 0x0000 }, /* R3841 - ANC_SRC */ + { 0x00000F08, 0x001c }, /* R3848 - ANC Coefficient */ + { 0x00000F09, 0x0000 }, /* R3849 - ANC Coefficient */ + { 0x00000F0A, 0x0000 }, /* R3850 - ANC Coefficient */ + { 0x00000F0B, 0x0000 }, /* R3851 - ANC Coefficient */ + { 0x00000F0C, 0x0000 }, /* R3852 - ANC Coefficient */ + { 0x00000F0D, 0x0000 }, /* R3853 - ANC Coefficient */ + { 0x00000F0E, 0x0000 }, /* R3854 - ANC Coefficient */ + { 0x00000F0F, 0x0000 }, /* R3855 - ANC Coefficient */ + { 0x00000F10, 0x0000 }, /* R3856 - ANC Coefficient */ + { 0x00000F11, 0x0000 }, /* R3857 - ANC Coefficient */ + { 0x00000F12, 0x0000 }, /* R3858 - ANC Coefficient */ + { 0x00000F15, 0x0000 }, /* R3861 - FCL Filter Control */ + { 0x00000F17, 0x0004 }, /* R3863 - FCL ADC Reformatter Control */ + { 0x00000F18, 0x0004 }, /* R3864 - ANC Coefficient */ + { 0x00000F19, 0x0002 }, /* R3865 - ANC Coefficient */ + { 0x00000F1A, 0x0000 }, /* R3866 - ANC Coefficient */ + { 0x00000F1B, 0x0010 }, /* R3867 - ANC Coefficient */ + { 0x00000F1C, 0x0000 }, /* R3868 - ANC Coefficient */ + { 0x00000F1D, 0x0000 }, /* R3869 - ANC Coefficient */ + { 0x00000F1E, 0x0000 }, /* R3870 - ANC Coefficient */ + { 0x00000F1F, 0x0000 }, /* R3871 - ANC Coefficient */ + { 0x00000F20, 0x0000 }, /* R3872 - ANC Coefficient */ + { 0x00000F21, 0x0000 }, /* R3873 - ANC Coefficient */ + { 0x00000F22, 0x0000 }, /* R3874 - ANC Coefficient */ + { 0x00000F23, 0x0000 }, /* R3875 - ANC Coefficient */ + { 0x00000F24, 0x0000 }, /* R3876 - ANC Coefficient */ + { 0x00000F25, 0x0000 }, /* R3877 - ANC Coefficient */ + { 0x00000F26, 0x0000 }, /* R3878 - ANC Coefficient */ + { 0x00000F27, 0x0000 }, /* R3879 - ANC Coefficient */ + { 0x00000F28, 0x0000 }, /* R3880 - ANC Coefficient */ + { 0x00000F29, 0x0000 }, /* R3881 - ANC Coefficient */ + { 0x00000F2A, 0x0000 }, /* R3882 - ANC Coefficient */ + { 0x00000F2B, 0x0000 }, /* R3883 - ANC Coefficient */ + { 0x00000F2C, 0x0000 }, /* R3884 - ANC Coefficient */ + { 0x00000F2D, 0x0000 }, /* R3885 - ANC Coefficient */ + { 0x00000F2E, 0x0000 }, /* R3886 - ANC Coefficient */ + { 0x00000F2F, 0x0000 }, /* R3887 - ANC Coefficient */ + { 0x00000F30, 0x0000 }, /* R3888 - ANC Coefficient */ + { 0x00000F31, 0x0000 }, /* R3889 - ANC Coefficient */ + { 0x00000F32, 0x0000 }, /* R3890 - ANC Coefficient */ + { 0x00000F33, 0x0000 }, /* R3891 - ANC Coefficient */ + { 0x00000F34, 0x0000 }, /* R3892 - ANC Coefficient */ + { 0x00000F35, 0x0000 }, /* R3893 - ANC Coefficient */ + { 0x00000F36, 0x0000 }, /* R3894 - ANC Coefficient */ + { 0x00000F37, 0x0000 }, /* R3895 - ANC Coefficient */ + { 0x00000F38, 0x0000 }, /* R3896 - ANC Coefficient */ + { 0x00000F39, 0x0000 }, /* R3897 - ANC Coefficient */ + { 0x00000F3A, 0x0000 }, /* R3898 - ANC Coefficient */ + { 0x00000F3B, 0x0000 }, /* R3899 - ANC Coefficient */ + { 0x00000F3C, 0x0000 }, /* R3900 - ANC Coefficient */ + { 0x00000F3D, 0x0000 }, /* R3901 - ANC Coefficient */ + { 0x00000F3E, 0x0000 }, /* R3902 - ANC Coefficient */ + { 0x00000F3F, 0x0000 }, /* R3903 - ANC Coefficient */ + { 0x00000F40, 0x0000 }, /* R3904 - ANC Coefficient */ + { 0x00000F41, 0x0000 }, /* R3905 - ANC Coefficient */ + { 0x00000F42, 0x0000 }, /* R3906 - ANC Coefficient */ + { 0x00000F43, 0x0000 }, /* R3907 - ANC Coefficient */ + { 0x00000F44, 0x0000 }, /* R3908 - ANC Coefficient */ + { 0x00000F45, 0x0000 }, /* R3909 - ANC Coefficient */ + { 0x00000F46, 0x0000 }, /* R3910 - ANC Coefficient */ + { 0x00000F47, 0x0000 }, /* R3911 - ANC Coefficient */ + { 0x00000F48, 0x0000 }, /* R3912 - ANC Coefficient */ + { 0x00000F49, 0x0000 }, /* R3913 - ANC Coefficient */ + { 0x00000F4A, 0x0000 }, /* R3914 - ANC Coefficient */ + { 0x00000F4B, 0x0000 }, /* R3915 - ANC Coefficient */ + { 0x00000F4C, 0x0000 }, /* R3916 - ANC Coefficient */ + { 0x00000F4D, 0x0000 }, /* R3917 - ANC Coefficient */ + { 0x00000F4E, 0x0000 }, /* R3918 - ANC Coefficient */ + { 0x00000F4F, 0x0000 }, /* R3919 - ANC Coefficient */ + { 0x00000F50, 0x0000 }, /* R3920 - ANC Coefficient */ + { 0x00000F51, 0x0000 }, /* R3921 - ANC Coefficient */ + { 0x00000F52, 0x0000 }, /* R3922 - ANC Coefficient */ + { 0x00000F53, 0x0000 }, /* R3923 - ANC Coefficient */ + { 0x00000F54, 0x0000 }, /* R3924 - ANC Coefficient */ + { 0x00000F55, 0x0000 }, /* R3925 - ANC Coefficient */ + { 0x00000F56, 0x0000 }, /* R3926 - ANC Coefficient */ + { 0x00000F57, 0x0000 }, /* R3927 - ANC Coefficient */ + { 0x00000F58, 0x0000 }, /* R3928 - ANC Coefficient */ + { 0x00000F59, 0x0000 }, /* R3929 - ANC Coefficient */ + { 0x00000F5A, 0x0000 }, /* R3930 - ANC Coefficient */ + { 0x00000F5B, 0x0000 }, /* R3931 - ANC Coefficient */ + { 0x00000F5C, 0x0000 }, /* R3932 - ANC Coefficient */ + { 0x00000F5D, 0x0000 }, /* R3933 - ANC Coefficient */ + { 0x00000F5E, 0x0000 }, /* R3934 - ANC Coefficient */ + { 0x00000F5F, 0x0000 }, /* R3935 - ANC Coefficient */ + { 0x00000F60, 0x0000 }, /* R3936 - ANC Coefficient */ + { 0x00000F61, 0x0000 }, /* R3937 - ANC Coefficient */ + { 0x00000F62, 0x0000 }, /* R3938 - ANC Coefficient */ + { 0x00000F63, 0x0000 }, /* R3939 - ANC Coefficient */ + { 0x00000F64, 0x0000 }, /* R3940 - ANC Coefficient */ + { 0x00000F65, 0x0000 }, /* R3941 - ANC Coefficient */ + { 0x00000F66, 0x0000 }, /* R3942 - ANC Coefficient */ + { 0x00000F67, 0x0000 }, /* R3943 - ANC Coefficient */ + { 0x00000F68, 0x0000 }, /* R3944 - ANC Coefficient */ + { 0x00000F69, 0x0000 }, /* R3945 - ANC Coefficient */ + { 0x00000F70, 0x0000 }, /* R3952 - FCR Filter Control */ + { 0x00000F72, 0x0004 }, /* R3954 - FCR ADC Reformatter Control */ + { 0x00000F73, 0x0004 }, /* R3955 - ANC Coefficient */ + { 0x00000F74, 0x0002 }, /* R3956 - ANC Coefficient */ + { 0x00000F75, 0x0000 }, /* R3957 - ANC Coefficient */ + { 0x00000F76, 0x0010 }, /* R3958 - ANC Coefficient */ + { 0x00000F77, 0x0000 }, /* R3959 - ANC Coefficient */ + { 0x00000F78, 0x0000 }, /* R3960 - ANC Coefficient */ + { 0x00000F79, 0x0000 }, /* R3961 - ANC Coefficient */ + { 0x00000F7A, 0x0000 }, /* R3962 - ANC Coefficient */ + { 0x00000F7B, 0x0000 }, /* R3963 - ANC Coefficient */ + { 0x00000F7C, 0x0000 }, /* R3964 - ANC Coefficient */ + { 0x00000F7D, 0x0000 }, /* R3965 - ANC Coefficient */ + { 0x00000F7E, 0x0000 }, /* R3966 - ANC Coefficient */ + { 0x00000F7F, 0x0000 }, /* R3967 - ANC Coefficient */ + { 0x00000F80, 0x0000 }, /* R3968 - ANC Coefficient */ + { 0x00000F81, 0x0000 }, /* R3969 - ANC Coefficient */ + { 0x00000F82, 0x0000 }, /* R3970 - ANC Coefficient */ + { 0x00000F83, 0x0000 }, /* R3971 - ANC Coefficient */ + { 0x00000F84, 0x0000 }, /* R3972 - ANC Coefficient */ + { 0x00000F85, 0x0000 }, /* R3973 - ANC Coefficient */ + { 0x00000F86, 0x0000 }, /* R3974 - ANC Coefficient */ + { 0x00000F87, 0x0000 }, /* R3975 - ANC Coefficient */ + { 0x00000F88, 0x0000 }, /* R3976 - ANC Coefficient */ + { 0x00000F89, 0x0000 }, /* R3977 - ANC Coefficient */ + { 0x00000F8A, 0x0000 }, /* R3978 - ANC Coefficient */ + { 0x00000F8B, 0x0000 }, /* R3979 - ANC Coefficient */ + { 0x00000F8C, 0x0000 }, /* R3980 - ANC Coefficient */ + { 0x00000F8D, 0x0000 }, /* R3981 - ANC Coefficient */ + { 0x00000F8E, 0x0000 }, /* R3982 - ANC Coefficient */ + { 0x00000F8F, 0x0000 }, /* R3983 - ANC Coefficient */ + { 0x00000F90, 0x0000 }, /* R3984 - ANC Coefficient */ + { 0x00000F91, 0x0000 }, /* R3985 - ANC Coefficient */ + { 0x00000F92, 0x0000 }, /* R3986 - ANC Coefficient */ + { 0x00000F93, 0x0000 }, /* R3987 - ANC Coefficient */ + { 0x00000F94, 0x0000 }, /* R3988 - ANC Coefficient */ + { 0x00000F95, 0x0000 }, /* R3989 - ANC Coefficient */ + { 0x00000F96, 0x0000 }, /* R3990 - ANC Coefficient */ + { 0x00000F97, 0x0000 }, /* R3991 - ANC Coefficient */ + { 0x00000F98, 0x0000 }, /* R3992 - ANC Coefficient */ + { 0x00000F99, 0x0000 }, /* R3993 - ANC Coefficient */ + { 0x00000F9A, 0x0000 }, /* R3994 - ANC Coefficient */ + { 0x00000F9B, 0x0000 }, /* R3995 - ANC Coefficient */ + { 0x00000F9C, 0x0000 }, /* R3996 - ANC Coefficient */ + { 0x00000F9D, 0x0000 }, /* R3997 - ANC Coefficient */ + { 0x00000F9E, 0x0000 }, /* R3998 - ANC Coefficient */ + { 0x00000F9F, 0x0000 }, /* R3999 - ANC Coefficient */ + { 0x00000FA0, 0x0000 }, /* R4000 - ANC Coefficient */ + { 0x00000FA1, 0x0000 }, /* R4001 - ANC Coefficient */ + { 0x00000FA2, 0x0000 }, /* R4002 - ANC Coefficient */ + { 0x00000FA3, 0x0000 }, /* R4003 - ANC Coefficient */ + { 0x00000FA4, 0x0000 }, /* R4004 - ANC Coefficient */ + { 0x00000FA5, 0x0000 }, /* R4005 - ANC Coefficient */ + { 0x00000FA6, 0x0000 }, /* R4006 - ANC Coefficient */ + { 0x00000FA7, 0x0000 }, /* R4007 - ANC Coefficient */ + { 0x00000FA8, 0x0000 }, /* R4008 - ANC Coefficient */ + { 0x00000FA9, 0x0000 }, /* R4009 - ANC Coefficient */ + { 0x00000FAA, 0x0000 }, /* R4010 - ANC Coefficient */ + { 0x00000FAB, 0x0000 }, /* R4011 - ANC Coefficient */ + { 0x00000FAC, 0x0000 }, /* R4012 - ANC Coefficient */ + { 0x00000FAD, 0x0000 }, /* R4013 - ANC Coefficient */ + { 0x00000FAE, 0x0000 }, /* R4014 - ANC Coefficient */ + { 0x00000FAF, 0x0000 }, /* R4015 - ANC Coefficient */ + { 0x00000FB0, 0x0000 }, /* R4016 - ANC Coefficient */ + { 0x00000FB1, 0x0000 }, /* R4017 - ANC Coefficient */ + { 0x00000FB2, 0x0000 }, /* R4018 - ANC Coefficient */ + { 0x00000FB3, 0x0000 }, /* R4019 - ANC Coefficient */ + { 0x00000FB4, 0x0000 }, /* R4020 - ANC Coefficient */ + { 0x00000FB5, 0x0000 }, /* R4021 - ANC Coefficient */ + { 0x00000FB6, 0x0000 }, /* R4022 - ANC Coefficient */ + { 0x00000FB7, 0x0000 }, /* R4023 - ANC Coefficient */ + { 0x00000FB8, 0x0000 }, /* R4024 - ANC Coefficient */ + { 0x00000FB9, 0x0000 }, /* R4025 - ANC Coefficient */ + { 0x00000FBA, 0x0000 }, /* R4026 - ANC Coefficient */ + { 0x00000FBB, 0x0000 }, /* R4027 - ANC Coefficient */ + { 0x00000FBC, 0x0000 }, /* R4028 - ANC Coefficient */ + { 0x00000FBD, 0x0000 }, /* R4029 - ANC Coefficient */ + { 0x00000FBE, 0x0000 }, /* R4030 - ANC Coefficient */ + { 0x00000FBF, 0x0000 }, /* R4031 - ANC Coefficient */ + { 0x00000FC0, 0x0000 }, /* R4032 - ANC Coefficient */ + { 0x00000FC1, 0x0000 }, /* R4033 - ANC Coefficient */ + { 0x00000FC2, 0x0000 }, /* R4034 - ANC Coefficient */ + { 0x00000FC3, 0x0000 }, /* R4035 - ANC Coefficient */ + { 0x00000FC4, 0x0000 }, /* R4036 - ANC Coefficient */ { 0x00001100, 0x0010 }, /* R4352 - DSP1 Control 1 */ { 0x00001200, 0x0010 }, /* R4608 - DSP2 Control 1 */ { 0x00001300, 0x0010 }, /* R4864 - DSP3 Control 1 */ @@ -1811,6 +1991,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) case ARIZONA_MIC_DETECT_1: case ARIZONA_MIC_DETECT_2: case ARIZONA_MIC_DETECT_3: + case ARIZONA_MIC_DETECT_4: case ARIZONA_MIC_DETECT_LEVEL_1: case ARIZONA_MIC_DETECT_LEVEL_2: case ARIZONA_MIC_DETECT_LEVEL_3: @@ -1910,6 +2091,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) case ARIZONA_HP1_SHORT_CIRCUIT_CTRL: case ARIZONA_HP2_SHORT_CIRCUIT_CTRL: case ARIZONA_HP3_SHORT_CIRCUIT_CTRL: + case ARIZONA_HP_TEST_CTRL_1: case ARIZONA_AIF1_BCLK_CTRL: case ARIZONA_AIF1_TX_PIN_CTRL: case ARIZONA_AIF1_RX_PIN_CTRL: @@ -2527,6 +2709,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) case ARIZONA_GPIO5_CTRL: case ARIZONA_IRQ_CTRL_1: case ARIZONA_GPIO_DEBOUNCE_CONFIG: + case ARIZONA_GP_SWITCH_1: case ARIZONA_MISC_PAD_CTRL_1: case ARIZONA_MISC_PAD_CTRL_2: case ARIZONA_MISC_PAD_CTRL_3: @@ -2706,6 +2889,13 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) case ARIZONA_CLOCK_CONTROL: case ARIZONA_ANC_SRC: case ARIZONA_DSP_STATUS: + case ARIZONA_ANC_COEFF_START ... ARIZONA_ANC_COEFF_END: + case ARIZONA_FCL_FILTER_CONTROL: + case ARIZONA_FCL_ADC_REFORMATTER_CONTROL: + case ARIZONA_FCL_COEFF_START ... ARIZONA_FCL_COEFF_END: + case ARIZONA_FCR_FILTER_CONTROL: + case ARIZONA_FCR_ADC_REFORMATTER_CONTROL: + case ARIZONA_FCR_COEFF_START ... ARIZONA_FCR_COEFF_END: case ARIZONA_DSP1_CONTROL_1: case ARIZONA_DSP1_CLOCKING_1: case ARIZONA_DSP1_STATUS_1: @@ -2847,12 +3037,14 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg) case ARIZONA_ASYNC_SAMPLE_RATE_1_STATUS: case ARIZONA_ASYNC_SAMPLE_RATE_2_STATUS: case ARIZONA_MIC_DETECT_3: + case ARIZONA_MIC_DETECT_4: case ARIZONA_HP_CTRL_1L: case ARIZONA_HP_CTRL_1R: case ARIZONA_HEADPHONE_DETECT_2: case ARIZONA_INPUT_ENABLES_STATUS: case ARIZONA_OUTPUT_STATUS_1: case ARIZONA_RAW_OUTPUT_STATUS_1: + case ARIZONA_HP_TEST_CTRL_1: case ARIZONA_SLIMBUS_RX_PORT_STATUS: case ARIZONA_SLIMBUS_TX_PORT_STATUS: case ARIZONA_INTERRUPT_STATUS_1: diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 28366a90e1ad..3e0e99ec5836 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -1626,7 +1626,9 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) mutex_init(&wm831x->io_lock); mutex_init(&wm831x->key_lock); dev_set_drvdata(wm831x->dev, wm831x); - wm831x->soft_shutdown = pdata->soft_shutdown; + + if (pdata) + wm831x->soft_shutdown = pdata->soft_shutdown; ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID); if (ret < 0) { diff --git a/drivers/mfd/wm8998-tables.c b/drivers/mfd/wm8998-tables.c index e6de3cd8a9aa..4c2dce77cdfc 100644 --- a/drivers/mfd/wm8998-tables.c +++ b/drivers/mfd/wm8998-tables.c @@ -21,7 +21,7 @@ #define WM8998_NUM_AOD_ISR 2 #define WM8998_NUM_ISR 5 -static const struct reg_default wm8998_rev_a_patch[] = { +static const struct reg_sequence wm8998_rev_a_patch[] = { { 0x0212, 0x0000 }, { 0x0211, 0x0014 }, { 0x04E4, 0x0E0D }, @@ -199,8 +199,6 @@ static const struct reg_default wm8998_reg_default[] = { { 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 4 */ { 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 5 */ { 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence Select 6 */ - { 0x0000006E, 0x01FF }, /* R110 - Trigger Sequence Select 32 */ - { 0x0000006F, 0x01FF }, /* R111 - Trigger Sequence Select 33 */ { 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */ { 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */ { 0x00000092, 0x0000 }, /* R146 - Haptics phase 1 intensity */ @@ -270,16 +268,13 @@ static const struct reg_default wm8998_reg_default[] = { { 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */ { 0x00000293, 0x0080 }, /* R659 - Accessory Detect Mode 1 */ { 0x0000029B, 0x0000 }, /* R667 - Headphone Detect 1 */ - { 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */ { 0x000002A2, 0x0000 }, /* R674 - Micd Clamp control */ { 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */ { 0x000002A4, 0x009F }, /* R676 - Mic Detect 2 */ - { 0x000002A5, 0x0000 }, /* R677 - Mic Detect 3 */ { 0x000002A6, 0x3737 }, /* R678 - Mic Detect Level 1 */ { 0x000002A7, 0x2C37 }, /* R679 - Mic Detect Level 2 */ { 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */ { 0x000002A9, 0x030A }, /* R681 - Mic Detect Level 4 */ - { 0x000002AB, 0x0000 }, /* R683 - Mic Detect 4 */ { 0x000002CB, 0x0000 }, /* R715 - Isolation control */ { 0x000002D3, 0x0000 }, /* R723 - Jack detect analogue */ { 0x00000300, 0x0000 }, /* R768 - Input Enables */ @@ -707,13 +702,11 @@ static const struct reg_default wm8998_reg_default[] = { { 0x00000D1A, 0xFFFF }, /* R3354 - IRQ2 Status 3 Mask */ { 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */ { 0x00000D1C, 0xFEFF }, /* R3356 - IRQ2 Status 5 Mask */ - { 0x00000D1D, 0xFFFF }, /* R3357 - IRQ2 Status 6 Mask */ { 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */ { 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */ { 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */ { 0x00000D56, 0x0000 }, /* R3414 - Jack detect debounce */ { 0x00000E00, 0x0000 }, /* R3584 - FX_Ctrl1 */ - { 0x00000E01, 0x0000 }, /* R3585 - FX_Ctrl2 */ { 0x00000E10, 0x6318 }, /* R3600 - EQ1_1 */ { 0x00000E11, 0x6300 }, /* R3601 - EQ1_2 */ { 0x00000E12, 0x0FC8 }, /* R3602 - EQ1_3 */ @@ -833,7 +826,6 @@ static bool wm8998_readable_register(struct device *dev, unsigned int reg) switch (reg) { case ARIZONA_SOFTWARE_RESET: case ARIZONA_DEVICE_REVISION: - case ARIZONA_CTRL_IF_SPI_CFG_1: case ARIZONA_CTRL_IF_I2C1_CFG_1: case ARIZONA_CTRL_IF_I2C1_CFG_2: case ARIZONA_WRITE_SEQUENCER_CTRL_0: diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index c69bb703f483..744cb80fccbc 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -914,6 +914,7 @@ config PVPANIC config INTEL_PMC_IPC tristate "Intel PMC IPC Driver" + depends on ACPI ---help--- This driver provides support for PMC control on some Intel platforms. The PMC is an ARC processor which defines IPC commands for communication diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index f8758d6febf8..8d53f58f20dd 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -204,6 +204,16 @@ config CHARGER_DA9150 This driver can also be built as a module. If so, the module will be called da9150-charger. +config BATTERY_DA9150 + tristate "Dialog Semiconductor DA9150 Fuel Gauge support" + depends on MFD_DA9150 + help + Say Y here to enable support for the Fuel-Gauge unit of the DA9150 + Integrated Charger & Fuel-Gauge IC + + This driver can also be built as a module. If so, the module will be + called da9150-fg. + config AXP288_CHARGER tristate "X-Powers AXP288 Charger" depends on MFD_AXP20X && EXTCON_AXP288 diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 5752ce818f51..cbdf89d595a3 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o obj-$(CONFIG_CHARGER_DA9150) += da9150-charger.o +obj-$(CONFIG_BATTERY_DA9150) += da9150-fg.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o obj-$(CONFIG_BATTERY_MAX17042) += max17042_battery.o obj-$(CONFIG_BATTERY_Z2) += z2_battery.o diff --git a/drivers/power/da9150-fg.c b/drivers/power/da9150-fg.c new file mode 100644 index 000000000000..8b8ce978656a --- /dev/null +++ b/drivers/power/da9150-fg.c @@ -0,0 +1,579 @@ +/* + * DA9150 Fuel-Gauge Driver + * + * Copyright (c) 2015 Dialog Semiconductor + * + * Author: Adam Thomson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Core2Wire */ +#define DA9150_QIF_READ (0x0 << 7) +#define DA9150_QIF_WRITE (0x1 << 7) +#define DA9150_QIF_CODE_MASK 0x7F + +#define DA9150_QIF_BYTE_SIZE 8 +#define DA9150_QIF_BYTE_MASK 0xFF +#define DA9150_QIF_SHORT_SIZE 2 +#define DA9150_QIF_LONG_SIZE 4 + +/* QIF Codes */ +#define DA9150_QIF_UAVG 6 +#define DA9150_QIF_UAVG_SIZE DA9150_QIF_LONG_SIZE +#define DA9150_QIF_IAVG 8 +#define DA9150_QIF_IAVG_SIZE DA9150_QIF_LONG_SIZE +#define DA9150_QIF_NTCAVG 12 +#define DA9150_QIF_NTCAVG_SIZE DA9150_QIF_LONG_SIZE +#define DA9150_QIF_SHUNT_VAL 36 +#define DA9150_QIF_SHUNT_VAL_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_SD_GAIN 38 +#define DA9150_QIF_SD_GAIN_SIZE DA9150_QIF_LONG_SIZE +#define DA9150_QIF_FCC_MAH 40 +#define DA9150_QIF_FCC_MAH_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_SOC_PCT 43 +#define DA9150_QIF_SOC_PCT_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_CHARGE_LIMIT 44 +#define DA9150_QIF_CHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_DISCHARGE_LIMIT 45 +#define DA9150_QIF_DISCHARGE_LIMIT_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_FW_MAIN_VER 118 +#define DA9150_QIF_FW_MAIN_VER_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_E_FG_STATUS 126 +#define DA9150_QIF_E_FG_STATUS_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_SYNC 127 +#define DA9150_QIF_SYNC_SIZE DA9150_QIF_SHORT_SIZE +#define DA9150_QIF_MAX_CODES 128 + +/* QIF Sync Timeout */ +#define DA9150_QIF_SYNC_TIMEOUT 1000 +#define DA9150_QIF_SYNC_RETRIES 10 + +/* QIF E_FG_STATUS */ +#define DA9150_FG_IRQ_LOW_SOC_MASK (1 << 0) +#define DA9150_FG_IRQ_HIGH_SOC_MASK (1 << 1) +#define DA9150_FG_IRQ_SOC_MASK \ + (DA9150_FG_IRQ_LOW_SOC_MASK | DA9150_FG_IRQ_HIGH_SOC_MASK) + +/* Private data */ +struct da9150_fg { + struct da9150 *da9150; + struct device *dev; + + struct mutex io_lock; + + struct power_supply *battery; + struct delayed_work work; + u32 interval; + + int warn_soc; + int crit_soc; + int soc; +}; + +/* Battery Properties */ +static u32 da9150_fg_read_attr(struct da9150_fg *fg, u8 code, u8 size) + +{ + u8 buf[size]; + u8 read_addr; + u32 res = 0; + int i; + + /* Set QIF code (READ mode) */ + read_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_READ; + + da9150_read_qif(fg->da9150, read_addr, size, buf); + for (i = 0; i < size; ++i) + res |= (buf[i] << (i * DA9150_QIF_BYTE_SIZE)); + + return res; +} + +static void da9150_fg_write_attr(struct da9150_fg *fg, u8 code, u8 size, + u32 val) + +{ + u8 buf[size]; + u8 write_addr; + int i; + + /* Set QIF code (WRITE mode) */ + write_addr = (code & DA9150_QIF_CODE_MASK) | DA9150_QIF_WRITE; + + for (i = 0; i < size; ++i) { + buf[i] = (val >> (i * DA9150_QIF_BYTE_SIZE)) & + DA9150_QIF_BYTE_MASK; + } + da9150_write_qif(fg->da9150, write_addr, size, buf); +} + +/* Trigger QIF Sync to update QIF readable data */ +static void da9150_fg_read_sync_start(struct da9150_fg *fg) +{ + int i = 0; + u32 res = 0; + + mutex_lock(&fg->io_lock); + + /* Check if QIF sync already requested, and write to sync if not */ + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + if (res > 0) + da9150_fg_write_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE, 0); + + /* Wait for sync to complete */ + res = 0; + while ((res == 0) && (i++ < DA9150_QIF_SYNC_RETRIES)) { + usleep_range(DA9150_QIF_SYNC_TIMEOUT, + DA9150_QIF_SYNC_TIMEOUT * 2); + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + } + + /* Check if sync completed */ + if (res == 0) + dev_err(fg->dev, "Failed to perform QIF read sync!\n"); +} + +/* + * Should always be called after QIF sync read has been performed, and all + * attributes required have been accessed. + */ +static inline void da9150_fg_read_sync_end(struct da9150_fg *fg) +{ + mutex_unlock(&fg->io_lock); +} + +/* Sync read of single QIF attribute */ +static u32 da9150_fg_read_attr_sync(struct da9150_fg *fg, u8 code, u8 size) +{ + u32 val; + + da9150_fg_read_sync_start(fg); + val = da9150_fg_read_attr(fg, code, size); + da9150_fg_read_sync_end(fg); + + return val; +} + +/* Wait for QIF Sync, write QIF data and wait for ack */ +static void da9150_fg_write_attr_sync(struct da9150_fg *fg, u8 code, u8 size, + u32 val) +{ + int i = 0; + u32 res = 0, sync_val; + + mutex_lock(&fg->io_lock); + + /* Check if QIF sync already requested */ + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + + /* Wait for an existing sync to complete */ + while ((res == 0) && (i++ < DA9150_QIF_SYNC_RETRIES)) { + usleep_range(DA9150_QIF_SYNC_TIMEOUT, + DA9150_QIF_SYNC_TIMEOUT * 2); + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + } + + if (res == 0) { + dev_err(fg->dev, "Timeout waiting for existing QIF sync!\n"); + mutex_unlock(&fg->io_lock); + return; + } + + /* Write value for QIF code */ + da9150_fg_write_attr(fg, code, size, val); + + /* Wait for write acknowledgment */ + i = 0; + sync_val = res; + while ((res == sync_val) && (i++ < DA9150_QIF_SYNC_RETRIES)) { + usleep_range(DA9150_QIF_SYNC_TIMEOUT, + DA9150_QIF_SYNC_TIMEOUT * 2); + res = da9150_fg_read_attr(fg, DA9150_QIF_SYNC, + DA9150_QIF_SYNC_SIZE); + } + + mutex_unlock(&fg->io_lock); + + /* Check write was actually successful */ + if (res != (sync_val + 1)) + dev_err(fg->dev, "Error performing QIF sync write for code %d\n", + code); +} + +/* Power Supply attributes */ +static int da9150_fg_capacity(struct da9150_fg *fg, + union power_supply_propval *val) +{ + val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_SOC_PCT, + DA9150_QIF_SOC_PCT_SIZE); + + if (val->intval > 100) + val->intval = 100; + + return 0; +} + +static int da9150_fg_current_avg(struct da9150_fg *fg, + union power_supply_propval *val) +{ + u32 iavg, sd_gain, shunt_val; + u64 div, res; + + da9150_fg_read_sync_start(fg); + iavg = da9150_fg_read_attr(fg, DA9150_QIF_IAVG, + DA9150_QIF_IAVG_SIZE); + shunt_val = da9150_fg_read_attr(fg, DA9150_QIF_SHUNT_VAL, + DA9150_QIF_SHUNT_VAL_SIZE); + sd_gain = da9150_fg_read_attr(fg, DA9150_QIF_SD_GAIN, + DA9150_QIF_SD_GAIN_SIZE); + da9150_fg_read_sync_end(fg); + + div = (u64) (sd_gain * shunt_val * 65536ULL); + do_div(div, 1000000); + res = (u64) (iavg * 1000000ULL); + do_div(res, div); + + val->intval = (int) res; + + return 0; +} + +static int da9150_fg_voltage_avg(struct da9150_fg *fg, + union power_supply_propval *val) +{ + u64 res; + + val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_UAVG, + DA9150_QIF_UAVG_SIZE); + + res = (u64) (val->intval * 186ULL); + do_div(res, 10000); + val->intval = (int) res; + + return 0; +} + +static int da9150_fg_charge_full(struct da9150_fg *fg, + union power_supply_propval *val) +{ + val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_FCC_MAH, + DA9150_QIF_FCC_MAH_SIZE); + + val->intval = val->intval * 1000; + + return 0; +} + +/* + * Temperature reading from device is only valid if battery/system provides + * valid NTC to associated pin of DA9150 chip. + */ +static int da9150_fg_temp(struct da9150_fg *fg, + union power_supply_propval *val) +{ + val->intval = da9150_fg_read_attr_sync(fg, DA9150_QIF_NTCAVG, + DA9150_QIF_NTCAVG_SIZE); + + val->intval = (val->intval * 10) / 1048576; + + return 0; +} + +static enum power_supply_property da9150_fg_props[] = { + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CURRENT_AVG, + POWER_SUPPLY_PROP_VOLTAGE_AVG, + POWER_SUPPLY_PROP_CHARGE_FULL, + POWER_SUPPLY_PROP_TEMP, +}; + +static int da9150_fg_get_prop(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct da9150_fg *fg = dev_get_drvdata(psy->dev.parent); + int ret; + + switch (psp) { + case POWER_SUPPLY_PROP_CAPACITY: + ret = da9150_fg_capacity(fg, val); + break; + case POWER_SUPPLY_PROP_CURRENT_AVG: + ret = da9150_fg_current_avg(fg, val); + break; + case POWER_SUPPLY_PROP_VOLTAGE_AVG: + ret = da9150_fg_voltage_avg(fg, val); + break; + case POWER_SUPPLY_PROP_CHARGE_FULL: + ret = da9150_fg_charge_full(fg, val); + break; + case POWER_SUPPLY_PROP_TEMP: + ret = da9150_fg_temp(fg, val); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +/* Repeated SOC check */ +static bool da9150_fg_soc_changed(struct da9150_fg *fg) +{ + union power_supply_propval val; + + da9150_fg_capacity(fg, &val); + if (val.intval != fg->soc) { + fg->soc = val.intval; + return true; + } + + return false; +} + +static void da9150_fg_work(struct work_struct *work) +{ + struct da9150_fg *fg = container_of(work, struct da9150_fg, work.work); + + /* Report if SOC has changed */ + if (da9150_fg_soc_changed(fg)) + power_supply_changed(fg->battery); + + schedule_delayed_work(&fg->work, msecs_to_jiffies(fg->interval)); +} + +/* SOC level event configuration */ +static void da9150_fg_soc_event_config(struct da9150_fg *fg) +{ + int soc; + + soc = da9150_fg_read_attr_sync(fg, DA9150_QIF_SOC_PCT, + DA9150_QIF_SOC_PCT_SIZE); + + if (soc > fg->warn_soc) { + /* If SOC > warn level, set discharge warn level event */ + da9150_fg_write_attr_sync(fg, DA9150_QIF_DISCHARGE_LIMIT, + DA9150_QIF_DISCHARGE_LIMIT_SIZE, + fg->warn_soc + 1); + } else if ((soc <= fg->warn_soc) && (soc > fg->crit_soc)) { + /* + * If SOC <= warn level, set discharge crit level event, + * and set charge warn level event. + */ + da9150_fg_write_attr_sync(fg, DA9150_QIF_DISCHARGE_LIMIT, + DA9150_QIF_DISCHARGE_LIMIT_SIZE, + fg->crit_soc + 1); + + da9150_fg_write_attr_sync(fg, DA9150_QIF_CHARGE_LIMIT, + DA9150_QIF_CHARGE_LIMIT_SIZE, + fg->warn_soc); + } else if (soc <= fg->crit_soc) { + /* If SOC <= crit level, set charge crit level event */ + da9150_fg_write_attr_sync(fg, DA9150_QIF_CHARGE_LIMIT, + DA9150_QIF_CHARGE_LIMIT_SIZE, + fg->crit_soc); + } +} + +static irqreturn_t da9150_fg_irq(int irq, void *data) +{ + struct da9150_fg *fg = data; + u32 e_fg_status; + + /* Read FG IRQ status info */ + e_fg_status = da9150_fg_read_attr(fg, DA9150_QIF_E_FG_STATUS, + DA9150_QIF_E_FG_STATUS_SIZE); + + /* Handle warning/critical threhold events */ + if (e_fg_status & DA9150_FG_IRQ_SOC_MASK) + da9150_fg_soc_event_config(fg); + + /* Clear any FG IRQs */ + da9150_fg_write_attr(fg, DA9150_QIF_E_FG_STATUS, + DA9150_QIF_E_FG_STATUS_SIZE, e_fg_status); + + return IRQ_HANDLED; +} + +static struct da9150_fg_pdata *da9150_fg_dt_pdata(struct device *dev) +{ + struct device_node *fg_node = dev->of_node; + struct da9150_fg_pdata *pdata; + + pdata = devm_kzalloc(dev, sizeof(struct da9150_fg_pdata), GFP_KERNEL); + if (!pdata) + return NULL; + + of_property_read_u32(fg_node, "dlg,update-interval", + &pdata->update_interval); + of_property_read_u8(fg_node, "dlg,warn-soc-level", + &pdata->warn_soc_lvl); + of_property_read_u8(fg_node, "dlg,crit-soc-level", + &pdata->crit_soc_lvl); + + return pdata; +} + +static const struct power_supply_desc fg_desc = { + .name = "da9150-fg", + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = da9150_fg_props, + .num_properties = ARRAY_SIZE(da9150_fg_props), + .get_property = da9150_fg_get_prop, +}; + +static int da9150_fg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct da9150 *da9150 = dev_get_drvdata(dev->parent); + struct da9150_fg_pdata *fg_pdata = dev_get_platdata(dev); + struct da9150_fg *fg; + int ver, irq, ret = 0; + + fg = devm_kzalloc(dev, sizeof(*fg), GFP_KERNEL); + if (fg == NULL) + return -ENOMEM; + + platform_set_drvdata(pdev, fg); + fg->da9150 = da9150; + fg->dev = dev; + + mutex_init(&fg->io_lock); + + /* Enable QIF */ + da9150_set_bits(da9150, DA9150_CORE2WIRE_CTRL_A, DA9150_FG_QIF_EN_MASK, + DA9150_FG_QIF_EN_MASK); + + fg->battery = devm_power_supply_register(dev, &fg_desc, NULL); + if (IS_ERR(fg->battery)) { + ret = PTR_ERR(fg->battery); + return ret; + } + + ver = da9150_fg_read_attr(fg, DA9150_QIF_FW_MAIN_VER, + DA9150_QIF_FW_MAIN_VER_SIZE); + dev_info(dev, "Version: 0x%x\n", ver); + + /* Handle DT data if provided */ + if (dev->of_node) { + fg_pdata = da9150_fg_dt_pdata(dev); + dev->platform_data = fg_pdata; + } + + /* Handle any pdata provided */ + if (fg_pdata) { + fg->interval = fg_pdata->update_interval; + + if (fg_pdata->warn_soc_lvl > 100) + dev_warn(dev, "Invalid SOC warning level provided, Ignoring"); + else + fg->warn_soc = fg_pdata->warn_soc_lvl; + + if ((fg_pdata->crit_soc_lvl > 100) || + (fg_pdata->crit_soc_lvl >= fg_pdata->warn_soc_lvl)) + dev_warn(dev, "Invalid SOC critical level provided, Ignoring"); + else + fg->crit_soc = fg_pdata->crit_soc_lvl; + + + } + + /* Configure initial SOC level events */ + da9150_fg_soc_event_config(fg); + + /* + * If an interval period has been provided then setup repeating + * work for reporting data updates. + */ + if (fg->interval) { + INIT_DELAYED_WORK(&fg->work, da9150_fg_work); + schedule_delayed_work(&fg->work, + msecs_to_jiffies(fg->interval)); + } + + /* Register IRQ */ + irq = platform_get_irq_byname(pdev, "FG"); + if (irq < 0) { + dev_err(dev, "Failed to get IRQ FG: %d\n", irq); + ret = irq; + goto irq_fail; + } + + ret = devm_request_threaded_irq(dev, irq, NULL, da9150_fg_irq, + IRQF_ONESHOT, "FG", fg); + if (ret) { + dev_err(dev, "Failed to request IRQ %d: %d\n", irq, ret); + goto irq_fail; + } + + return 0; + +irq_fail: + if (fg->interval) + cancel_delayed_work(&fg->work); + + return ret; +} + +static int da9150_fg_remove(struct platform_device *pdev) +{ + struct da9150_fg *fg = platform_get_drvdata(pdev); + + if (fg->interval) + cancel_delayed_work(&fg->work); + + return 0; +} + +static int da9150_fg_resume(struct platform_device *pdev) +{ + struct da9150_fg *fg = platform_get_drvdata(pdev); + + /* + * Trigger SOC check to happen now so as to indicate any value change + * since last check before suspend. + */ + if (fg->interval) + flush_delayed_work(&fg->work); + + return 0; +} + +static struct platform_driver da9150_fg_driver = { + .driver = { + .name = "da9150-fuel-gauge", + }, + .probe = da9150_fg_probe, + .remove = da9150_fg_remove, + .resume = da9150_fg_resume, +}; + +module_platform_driver(da9150_fg_driver); + +MODULE_DESCRIPTION("Fuel-Gauge Driver for DA9150"); +MODULE_AUTHOR("Adam Thomson "); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index 3510b3e7330a..ddc4f10e268a 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -33,7 +33,7 @@ static int tps6105x_regulator_enable(struct regulator_dev *rdev) int ret; /* Activate voltage mode */ - ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0, + ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, TPS6105X_REG0_MODE_MASK, TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT); if (ret) @@ -48,7 +48,7 @@ static int tps6105x_regulator_disable(struct regulator_dev *rdev) int ret; /* Set into shutdown mode */ - ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0, + ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, TPS6105X_REG0_MODE_MASK, TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); if (ret) @@ -60,10 +60,10 @@ static int tps6105x_regulator_disable(struct regulator_dev *rdev) static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev) { struct tps6105x *tps6105x = rdev_get_drvdata(rdev); - u8 regval; + unsigned int regval; int ret; - ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val); + ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val); if (ret) return ret; regval &= TPS6105X_REG0_MODE_MASK; @@ -78,10 +78,10 @@ static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev) static int tps6105x_regulator_get_voltage_sel(struct regulator_dev *rdev) { struct tps6105x *tps6105x = rdev_get_drvdata(rdev); - u8 regval; + unsigned int regval; int ret; - ret = tps6105x_get(tps6105x, TPS6105X_REG_0, ®val); + ret = regmap_read(tps6105x->regmap, TPS6105X_REG_0, ®val); if (ret) return ret; @@ -96,7 +96,7 @@ static int tps6105x_regulator_set_voltage_sel(struct regulator_dev *rdev, struct tps6105x *tps6105x = rdev_get_drvdata(rdev); int ret; - ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0, + ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0, TPS6105X_REG0_VOLTAGE_MASK, selector << TPS6105X_REG0_VOLTAGE_SHIFT); if (ret) diff --git a/include/dt-bindings/mfd/arizona.h b/include/dt-bindings/mfd/arizona.h index 7b2000cead43..c40f665e2712 100644 --- a/include/dt-bindings/mfd/arizona.h +++ b/include/dt-bindings/mfd/arizona.h @@ -107,5 +107,7 @@ #define ARIZONA_ACCDET_MODE_MIC 0 #define ARIZONA_ACCDET_MODE_HPL 1 #define ARIZONA_ACCDET_MODE_HPR 2 +#define ARIZONA_ACCDET_MODE_HPM 4 +#define ARIZONA_ACCDET_MODE_ADC 7 #endif diff --git a/include/dt-bindings/mfd/atmel-flexcom.h b/include/dt-bindings/mfd/atmel-flexcom.h new file mode 100644 index 000000000000..a266fe4ee945 --- /dev/null +++ b/include/dt-bindings/mfd/atmel-flexcom.h @@ -0,0 +1,26 @@ +/* + * This header provides macros for Atmel Flexcom DT bindings. + * + * Copyright (C) 2015 Cyrille Pitchen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef __DT_BINDINGS_ATMEL_FLEXCOM_H__ +#define __DT_BINDINGS_ATMEL_FLEXCOM_H__ + +#define ATMEL_FLEXCOM_MODE_USART 1 +#define ATMEL_FLEXCOM_MODE_SPI 2 +#define ATMEL_FLEXCOM_MODE_TWI 3 + +#endif /* __DT_BINDINGS_ATMEL_FLEXCOM_H__ */ diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h index 8fcad63fab55..d409ceb2231e 100644 --- a/include/linux/mfd/88pm80x.h +++ b/include/linux/mfd/88pm80x.h @@ -21,6 +21,7 @@ enum { CHIP_INVALID = 0, CHIP_PM800, CHIP_PM805, + CHIP_PM860, CHIP_MAX, }; diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index 1dc385850ba2..57b45caaea80 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -124,6 +124,9 @@ struct arizona_pdata { /** Channel to use for headphone detection */ unsigned int hpdet_channel; + /** Use software comparison to determine mic presence */ + bool micd_software_compare; + /** Extra debounce timeout used during initial mic detection (ms) */ unsigned int micd_detect_debounce; @@ -181,6 +184,9 @@ struct arizona_pdata { /** GPIO for primary IRQ (used for edge triggered emulation) */ int irq_gpio; + + /** General purpose switch control */ + unsigned int gpsw; }; #endif diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h index fdd70b3c7418..cd7e78eae006 100644 --- a/include/linux/mfd/arizona/registers.h +++ b/include/linux/mfd/arizona/registers.h @@ -242,6 +242,7 @@ #define ARIZONA_HP1_SHORT_CIRCUIT_CTRL 0x4A0 #define ARIZONA_HP2_SHORT_CIRCUIT_CTRL 0x4A1 #define ARIZONA_HP3_SHORT_CIRCUIT_CTRL 0x4A2 +#define ARIZONA_HP_TEST_CTRL_1 0x4A4 #define ARIZONA_SPK_CTRL_2 0x4B5 #define ARIZONA_SPK_CTRL_3 0x4B6 #define ARIZONA_DAC_COMP_1 0x4DC @@ -1064,6 +1065,16 @@ #define ARIZONA_CLOCK_CONTROL 0xF00 #define ARIZONA_ANC_SRC 0xF01 #define ARIZONA_DSP_STATUS 0xF02 +#define ARIZONA_ANC_COEFF_START 0xF08 +#define ARIZONA_ANC_COEFF_END 0xF12 +#define ARIZONA_FCL_FILTER_CONTROL 0xF15 +#define ARIZONA_FCL_ADC_REFORMATTER_CONTROL 0xF17 +#define ARIZONA_FCL_COEFF_START 0xF18 +#define ARIZONA_FCL_COEFF_END 0xF69 +#define ARIZONA_FCR_FILTER_CONTROL 0xF70 +#define ARIZONA_FCR_ADC_REFORMATTER_CONTROL 0xF72 +#define ARIZONA_FCR_COEFF_START 0xF73 +#define ARIZONA_FCR_COEFF_END 0xFC4 #define ARIZONA_DSP1_CONTROL_1 0x1100 #define ARIZONA_DSP1_CLOCKING_1 0x1101 #define ARIZONA_DSP1_STATUS_1 0x1104 @@ -2359,9 +2370,9 @@ #define ARIZONA_ACCDET_SRC_MASK 0x2000 /* ACCDET_SRC */ #define ARIZONA_ACCDET_SRC_SHIFT 13 /* ACCDET_SRC */ #define ARIZONA_ACCDET_SRC_WIDTH 1 /* ACCDET_SRC */ -#define ARIZONA_ACCDET_MODE_MASK 0x0003 /* ACCDET_MODE - [1:0] */ -#define ARIZONA_ACCDET_MODE_SHIFT 0 /* ACCDET_MODE - [1:0] */ -#define ARIZONA_ACCDET_MODE_WIDTH 2 /* ACCDET_MODE - [1:0] */ +#define ARIZONA_ACCDET_MODE_MASK 0x0007 /* ACCDET_MODE - [2:0] */ +#define ARIZONA_ACCDET_MODE_SHIFT 0 /* ACCDET_MODE - [2:0] */ +#define ARIZONA_ACCDET_MODE_WIDTH 3 /* ACCDET_MODE - [2:0] */ /* * R667 (0x29B) - Headphone Detect 1 @@ -3701,6 +3712,13 @@ #define ARIZONA_HP3_SC_ENA_SHIFT 12 /* HP3_SC_ENA */ #define ARIZONA_HP3_SC_ENA_WIDTH 1 /* HP3_SC_ENA */ +/* + * R1188 (0x4A4) HP Test Ctrl 1 + */ +#define ARIZONA_HP1_TST_CAP_SEL_MASK 0x0003 /* HP1_TST_CAP_SEL - [1:0] */ +#define ARIZONA_HP1_TST_CAP_SEL_SHIFT 0 /* HP1_TST_CAP_SEL - [1:0] */ +#define ARIZONA_HP1_TST_CAP_SEL_WIDTH 2 /* HP1_TST_CAP_SEL - [1:0] */ + /* * R1244 (0x4DC) - DAC comp 1 */ @@ -8042,6 +8060,66 @@ #define ARIZONA_ISRC3_NOTCH_ENA_SHIFT 0 /* ISRC3_NOTCH_ENA */ #define ARIZONA_ISRC3_NOTCH_ENA_WIDTH 1 /* ISRC3_NOTCH_ENA */ +/* + * R3840 (0xF00) - Clock Control + */ +#define ARIZONA_EXT_NG_SEL_CLR 0x0080 /* EXT_NG_SEL_CLR */ +#define ARIZONA_EXT_NG_SEL_CLR_MASK 0x0080 /* EXT_NG_SEL_CLR */ +#define ARIZONA_EXT_NG_SEL_CLR_SHIFT 7 /* EXT_NG_SEL_CLR */ +#define ARIZONA_EXT_NG_SEL_CLR_WIDTH 1 /* EXT_NG_SEL_CLR */ +#define ARIZONA_EXT_NG_SEL_SET 0x0040 /* EXT_NG_SEL_SET */ +#define ARIZONA_EXT_NG_SEL_SET_MASK 0x0040 /* EXT_NG_SEL_SET */ +#define ARIZONA_EXT_NG_SEL_SET_SHIFT 6 /* EXT_NG_SEL_SET */ +#define ARIZONA_EXT_NG_SEL_SET_WIDTH 1 /* EXT_NG_SEL_SET */ +#define ARIZONA_CLK_R_ENA_CLR 0x0020 /* CLK_R_ENA_CLR */ +#define ARIZONA_CLK_R_ENA_CLR_MASK 0x0020 /* CLK_R_ENA_CLR */ +#define ARIZONA_CLK_R_ENA_CLR_SHIFT 5 /* CLK_R_ENA_CLR */ +#define ARIZONA_CLK_R_ENA_CLR_WIDTH 1 /* CLK_R_ENA_CLR */ +#define ARIZONA_CLK_R_ENA_SET 0x0010 /* CLK_R_ENA_SET */ +#define ARIZONA_CLK_R_ENA_SET_MASK 0x0010 /* CLK_R_ENA_SET */ +#define ARIZONA_CLK_R_ENA_SET_SHIFT 4 /* CLK_R_ENA_SET */ +#define ARIZONA_CLK_R_ENA_SET_WIDTH 1 /* CLK_R_ENA_SET */ +#define ARIZONA_CLK_NG_ENA_CLR 0x0008 /* CLK_NG_ENA_CLR */ +#define ARIZONA_CLK_NG_ENA_CLR_MASK 0x0008 /* CLK_NG_ENA_CLR */ +#define ARIZONA_CLK_NG_ENA_CLR_SHIFT 3 /* CLK_NG_ENA_CLR */ +#define ARIZONA_CLK_NG_ENA_CLR_WIDTH 1 /* CLK_NG_ENA_CLR */ +#define ARIZONA_CLK_NG_ENA_SET 0x0004 /* CLK_NG_ENA_SET */ +#define ARIZONA_CLK_NG_ENA_SET_MASK 0x0004 /* CLK_NG_ENA_SET */ +#define ARIZONA_CLK_NG_ENA_SET_SHIFT 2 /* CLK_NG_ENA_SET */ +#define ARIZONA_CLK_NG_ENA_SET_WIDTH 1 /* CLK_NG_ENA_SET */ +#define ARIZONA_CLK_L_ENA_CLR 0x0002 /* CLK_L_ENA_CLR */ +#define ARIZONA_CLK_L_ENA_CLR_MASK 0x0002 /* CLK_L_ENA_CLR */ +#define ARIZONA_CLK_L_ENA_CLR_SHIFT 1 /* CLK_L_ENA_CLR */ +#define ARIZONA_CLK_L_ENA_CLR_WIDTH 1 /* CLK_L_ENA_CLR */ +#define ARIZONA_CLK_L_ENA_SET 0x0001 /* CLK_L_ENA_SET */ +#define ARIZONA_CLK_L_ENA_SET_MASK 0x0001 /* CLK_L_ENA_SET */ +#define ARIZONA_CLK_L_ENA_SET_SHIFT 0 /* CLK_L_ENA_SET */ +#define ARIZONA_CLK_L_ENA_SET_WIDTH 1 /* CLK_L_ENA_SET */ + +/* + * R3841 (0xF01) - ANC SRC + */ +#define ARIZONA_IN_RXANCR_SEL_MASK 0x0070 /* IN_RXANCR_SEL - [4:6] */ +#define ARIZONA_IN_RXANCR_SEL_SHIFT 4 /* IN_RXANCR_SEL - [4:6] */ +#define ARIZONA_IN_RXANCR_SEL_WIDTH 3 /* IN_RXANCR_SEL - [4:6] */ +#define ARIZONA_IN_RXANCL_SEL_MASK 0x0007 /* IN_RXANCL_SEL - [0:2] */ +#define ARIZONA_IN_RXANCL_SEL_SHIFT 0 /* IN_RXANCL_SEL - [0:2] */ +#define ARIZONA_IN_RXANCL_SEL_WIDTH 3 /* IN_RXANCL_SEL - [0:2] */ + +/* + * R3863 (0xF17) - FCL ADC Reformatter Control + */ +#define ARIZONA_FCL_MIC_MODE_SEL 0x000C /* FCL_MIC_MODE_SEL - [2:3] */ +#define ARIZONA_FCL_MIC_MODE_SEL_SHIFT 2 /* FCL_MIC_MODE_SEL - [2:3] */ +#define ARIZONA_FCL_MIC_MODE_SEL_WIDTH 2 /* FCL_MIC_MODE_SEL - [2:3] */ + +/* + * R3954 (0xF72) - FCR ADC Reformatter Control + */ +#define ARIZONA_FCR_MIC_MODE_SEL 0x000C /* FCR_MIC_MODE_SEL - [2:3] */ +#define ARIZONA_FCR_MIC_MODE_SEL_SHIFT 2 /* FCR_MIC_MODE_SEL - [2:3] */ +#define ARIZONA_FCR_MIC_MODE_SEL_WIDTH 2 /* FCR_MIC_MODE_SEL - [2:3] */ + /* * R4352 (0x1100) - DSP1 Control 1 */ diff --git a/include/linux/mfd/da9052/reg.h b/include/linux/mfd/da9052/reg.h index c4dd3a8add21..5010f978725c 100644 --- a/include/linux/mfd/da9052/reg.h +++ b/include/linux/mfd/da9052/reg.h @@ -65,6 +65,9 @@ #define DA9052_GPIO_2_3_REG 22 #define DA9052_GPIO_4_5_REG 23 #define DA9052_GPIO_6_7_REG 24 +#define DA9052_GPIO_8_9_REG 25 +#define DA9052_GPIO_10_11_REG 26 +#define DA9052_GPIO_12_13_REG 27 #define DA9052_GPIO_14_15_REG 28 /* POWER SEQUENCER CONTROL REGISTERS */ diff --git a/include/linux/mfd/da9150/core.h b/include/linux/mfd/da9150/core.h index 76e668933a77..1bf50caeb9fa 100644 --- a/include/linux/mfd/da9150/core.h +++ b/include/linux/mfd/da9150/core.h @@ -15,6 +15,7 @@ #define __DA9150_CORE_H #include +#include #include #include @@ -46,23 +47,39 @@ #define DA9150_IRQ_GPADC 19 #define DA9150_IRQ_WKUP 20 +/* I2C sub-device address */ +#define DA9150_QIF_I2C_ADDR_LSB 0x5 + +struct da9150_fg_pdata { + u32 update_interval; /* msecs */ + u8 warn_soc_lvl; /* % value */ + u8 crit_soc_lvl; /* % value */ +}; + struct da9150_pdata { int irq_base; + struct da9150_fg_pdata *fg_pdata; }; struct da9150 { struct device *dev; struct regmap *regmap; + struct i2c_client *core_qif; + struct regmap_irq_chip_data *regmap_irq_data; int irq; int irq_base; }; -/* Device I/O */ +/* Device I/O - Query Interface for FG and standard register access */ +void da9150_read_qif(struct da9150 *da9150, u8 addr, int count, u8 *buf); +void da9150_write_qif(struct da9150 *da9150, u8 addr, int count, const u8 *buf); + u8 da9150_reg_read(struct da9150 *da9150, u16 reg); void da9150_reg_write(struct da9150 *da9150, u16 reg, u8 val); void da9150_set_bits(struct da9150 *da9150, u16 reg, u8 mask, u8 val); void da9150_bulk_read(struct da9150 *da9150, u16 reg, int count, u8 *buf); void da9150_bulk_write(struct da9150 *da9150, u16 reg, int count, const u8 *buf); + #endif /* __DA9150_CORE_H */ diff --git a/include/linux/mfd/intel_bxtwc.h b/include/linux/mfd/intel_bxtwc.h new file mode 100644 index 000000000000..1a0ee9d6efe9 --- /dev/null +++ b/include/linux/mfd/intel_bxtwc.h @@ -0,0 +1,69 @@ +/* + * intel_bxtwc.h - Header file for Intel Broxton Whiskey Cove PMIC + * + * Copyright (C) 2015 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include + +#ifndef __INTEL_BXTWC_H__ +#define __INTEL_BXTWC_H__ + +/* BXT WC devices */ +#define BXTWC_DEVICE1_ADDR 0x4E +#define BXTWC_DEVICE2_ADDR 0x4F +#define BXTWC_DEVICE3_ADDR 0x5E + +/* device1 Registers */ +#define BXTWC_CHIPID 0x4E00 +#define BXTWC_CHIPVER 0x4E01 + +#define BXTWC_SCHGRIRQ0_ADDR 0x5E1A +#define BXTWC_CHGRCTRL0_ADDR 0x5E16 +#define BXTWC_CHGRCTRL1_ADDR 0x5E17 +#define BXTWC_CHGRCTRL2_ADDR 0x5E18 +#define BXTWC_CHGRSTATUS_ADDR 0x5E19 +#define BXTWC_THRMBATZONE_ADDR 0x4F22 + +#define BXTWC_USBPATH_ADDR 0x5E19 +#define BXTWC_USBPHYCTRL_ADDR 0x5E07 +#define BXTWC_USBIDCTRL_ADDR 0x5E05 +#define BXTWC_USBIDEN_MASK 0x01 +#define BXTWC_USBIDSTAT_ADDR 0x00FF +#define BXTWC_USBSRCDETSTATUS_ADDR 0x5E29 + +#define BXTWC_DBGUSBBC1_ADDR 0x5FE0 +#define BXTWC_DBGUSBBC2_ADDR 0x5FE1 +#define BXTWC_DBGUSBBCSTAT_ADDR 0x5FE2 + +#define BXTWC_WAKESRC_ADDR 0x4E22 +#define BXTWC_WAKESRC2_ADDR 0x4EE5 +#define BXTWC_CHRTTADDR_ADDR 0x5E22 +#define BXTWC_CHRTTDATA_ADDR 0x5E23 + +#define BXTWC_STHRMIRQ0_ADDR 0x4F19 +#define WC_MTHRMIRQ1_ADDR 0x4E12 +#define WC_STHRMIRQ1_ADDR 0x4F1A +#define WC_STHRMIRQ2_ADDR 0x4F1B + +#define BXTWC_THRMZN0H_ADDR 0x4F44 +#define BXTWC_THRMZN0L_ADDR 0x4F45 +#define BXTWC_THRMZN1H_ADDR 0x4F46 +#define BXTWC_THRMZN1L_ADDR 0x4F47 +#define BXTWC_THRMZN2H_ADDR 0x4F48 +#define BXTWC_THRMZN2L_ADDR 0x4F49 +#define BXTWC_THRMZN3H_ADDR 0x4F4A +#define BXTWC_THRMZN3L_ADDR 0x4F4B +#define BXTWC_THRMZN4H_ADDR 0x4F4C +#define BXTWC_THRMZN4L_ADDR 0x4F4D + +#endif diff --git a/include/linux/mfd/intel_soc_pmic.h b/include/linux/mfd/intel_soc_pmic.h index abcbfcf32d10..cf619dbeace2 100644 --- a/include/linux/mfd/intel_soc_pmic.h +++ b/include/linux/mfd/intel_soc_pmic.h @@ -25,6 +25,8 @@ struct intel_soc_pmic { int irq; struct regmap *regmap; struct regmap_irq_chip_data *irq_chip_data; + struct regmap_irq_chip_data *irq_chip_data_level2; + struct device *dev; }; #endif /* __INTEL_SOC_PMIC_H__ */ diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index ff843e7ca23d..7eb7cbac0a9a 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h @@ -589,6 +589,7 @@ #define FORCE_ASPM_NO_ASPM 0x00 #define PM_CLK_FORCE_CTL 0xFE58 #define FUNC_FORCE_CTL 0xFE59 +#define FUNC_FORCE_UPME_XMT_DBG 0x02 #define PERST_GLITCH_WIDTH 0xFE5C #define CHANGE_LINK_STATE 0xFE5B #define RESET_LOAD_REG 0xFE5E @@ -712,6 +713,7 @@ #define PHY_RCR1 0x02 #define PHY_RCR1_ADP_TIME_4 0x0400 #define PHY_RCR1_VCO_COARSE 0x001F +#define PHY_RCR1_INIT_27S 0x0A1F #define PHY_SSCCR2 0x02 #define PHY_SSCCR2_PLL_NCODE 0x0A00 #define PHY_SSCCR2_TIME0 0x001C @@ -724,6 +726,7 @@ #define PHY_RCR2_FREQSEL_12 0x0040 #define PHY_RCR2_CDR_SC_12P 0x0010 #define PHY_RCR2_CALIB_LATE 0x0002 +#define PHY_RCR2_INIT_27S 0xC152 #define PHY_SSCCR3 0x03 #define PHY_SSCCR3_STEP_IN 0x2740 #define PHY_SSCCR3_CHECK_DELAY 0x0008 @@ -800,12 +803,14 @@ #define PHY_ANA1A_RXT_BIST 0x0500 #define PHY_ANA1A_TXR_BIST 0x0040 #define PHY_ANA1A_REV 0x0006 +#define PHY_FLD0_INIT_27S 0x2546 #define PHY_FLD1 0x1B #define PHY_FLD2 0x1C #define PHY_FLD3 0x1D #define PHY_FLD3_TIMER_4 0x0800 #define PHY_FLD3_TIMER_6 0x0020 #define PHY_FLD3_RXDELINK 0x0004 +#define PHY_FLD3_INIT_27S 0x0004 #define PHY_ANA1D 0x1D #define PHY_ANA1D_DEBUG_ADDR 0x0004 #define _PHY_FLD0 0x1D @@ -824,6 +829,7 @@ #define PHY_FLD4_BER_COUNT 0x00E0 #define PHY_FLD4_BER_TIMER 0x000A #define PHY_FLD4_BER_CHK_EN 0x0001 +#define PHY_FLD4_INIT_27S 0x5C7F #define PHY_DIG1E 0x1E #define PHY_DIG1E_REV 0x4000 #define PHY_DIG1E_D0_X_D1 0x1000 diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index 75115384f3fc..a06098639399 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h @@ -132,6 +132,10 @@ struct sec_platform_data { int buck2_init; int buck3_init; int buck4_init; + /* Whether or not manually set PWRHOLD to low during shutdown. */ + bool manual_poweroff; + /* Disable the WRSTBI (buck voltage warm reset) when probing? */ + bool disable_wrstbi; }; /** diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h index 7981a9d77d3f..b288965e8101 100644 --- a/include/linux/mfd/samsung/s2mps11.h +++ b/include/linux/mfd/samsung/s2mps11.h @@ -179,6 +179,7 @@ enum s2mps11_regulators { #define S2MPS11_BUCK_N_VOLTAGES (S2MPS11_BUCK_VSEL_MASK + 1) #define S2MPS11_RAMP_DELAY 25000 /* uV/us */ +#define S2MPS11_CTRL1_PWRHOLD_MASK BIT(4) #define S2MPS11_BUCK2_RAMP_SHIFT 6 #define S2MPS11_BUCK34_RAMP_SHIFT 4 diff --git a/include/linux/mfd/samsung/s2mps13.h b/include/linux/mfd/samsung/s2mps13.h index b1fd675fa36f..239e977ba45d 100644 --- a/include/linux/mfd/samsung/s2mps13.h +++ b/include/linux/mfd/samsung/s2mps13.h @@ -184,5 +184,6 @@ enum s2mps13_regulators { * Let's assume that default value will be set. */ #define S2MPS13_BUCK_RAMP_DELAY 12500 +#define S2MPS13_REG_WRSTBI_MASK BIT(5) #endif /* __LINUX_MFD_S2MPS13_H */ diff --git a/include/linux/mfd/tps6105x.h b/include/linux/mfd/tps6105x.h index 386743dd931c..8bc51180800a 100644 --- a/include/linux/mfd/tps6105x.h +++ b/include/linux/mfd/tps6105x.h @@ -10,6 +10,7 @@ #define MFD_TPS6105X_H #include +#include #include /* @@ -82,20 +83,15 @@ struct tps6105x_platform_data { /** * struct tps6105x - state holder for the TPS6105x drivers - * @mutex: mutex to serialize I2C accesses * @i2c_client: corresponding I2C client * @regulator: regulator device if used in voltage mode + * @regmap: used for i2c communcation on accessing registers */ struct tps6105x { struct tps6105x_platform_data *pdata; - struct mutex lock; struct i2c_client *client; struct regulator_dev *regulator; + struct regmap *regmap; }; -extern int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value); -extern int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf); -extern int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg, - u8 bitmask, u8 bitvalues); - #endif