forked from Minki/linux
- New Device Support
- Add support for 88pm860; 88pm80x - Add support for 24c08 EEPROM; at24 - Add support for Broxton Whiskey Cove; intel* - Add support for RTS522A; rts5227 - Add support for I2C devices; intel_quark_i2c_gpio - New Functionality - Add microphone support; arizona - Add general purpose switch support; arizona - Add fuel-gauge support; da9150-core - Add shutdown support; sec-core - Add charger support; tps65217 - Add flexible serial communication unit support; atmel-flexcom - Add power button support; axp20x - Add led-flash support; rt5033 - Core Frameworks - Supply a generic macro for defining Regmap IRQs - Rework ACPI child device matching - Fix-ups - Use Regmap to access registers; tps6105x - Use DEFINE_RES_IRQ_NAMED() macro; da9150 - Re-arrange device registration order; intel_quark_i2c_gpio - Allow OF matching; cros_ec_i2c, atmel-hlcdc, hi6421-pmic, max8997, sm501 - Handle deferred probe; twl6040 - Improve accuracy of headphone detect; arizona - Unnecessary MODULE_ALIAS() removal; bcm590xx, rt5033 - Remove unused code; htc-i2cpld, arizona, pcf50633-irq, sec-core - Simplify code; kempld, rts5209, da903x, lm3533, da9052, arizona - Remove #iffery; arizona - DT binding adaptions; many - Bug Fixes - Fix possible NULL pointer dereference; wm831x, tps6105x - Fix 64bit bug; intel_soc_pmic_bxtwc - Fix signedness issue; arizona -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWOzEbAAoJEFGvii+H/HdhbUEQAIBHvNaunWp362L2D2lOOQMa cBlGiR2yXCpsFGAcvpr50zX5soFuNITGea1CidJmp/ZIHIG7hVUz5E8wQZ8HdiyG 03UKsa6xkVx9i+PhV5agUjxi6MDgUvxsPwdbVw6LTw1wQejIrfxq7ObdcPo30OTI 4r0tjLonQkGaFFdGqC4Jr7Grs7pvzmKzHu08AaknaoTyhUl/E9Wtq12HJFr8kUCw WNgEyiPzNk0h9EByCUiG7iFwyg1EJLsF1U973Th8Utvl7PFe8REQVZ46v9iYAM9J 1OeSrsKhtyhQqAP/FJ5odZCXwTy9q6ifGfELyyS26/okCYWDzxDcF+hAp0VNbzb4 zYvEnKue101Y+WEsF9bNaya3avf45obJuRaRukoGMZ/brW6+d1ub0kwUKMD8MqOn UFL3oZwfPQ8mWB5ddELl97dzJDwHbEIhWe7yKQVpTaJ2pCm6JSS5Vb0TU+A1Zywp Hie1Yr0y36npnCbml4W74O9H/rblpNpgFlaupfB6mHRWZyTsyQNeKJ6FWTirncgQ xy8Ti+ZsXlMTvWCzzS3GcjP9rAK0e5dKurOE8t+krZmTul96+OYsnvxRC0nyo7XC 1PKomkWO+3if2DsnurFX/QKfE55PCKermJRO5mDZbsWp6aJAhKW5UwxAgkHpUHsJ hHaT+npBczXbq8jvEMTt =99/D -----END PGP SIGNATURE----- Merge tag 'mfd-for-linus-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "New Device Support: - Add support for 88pm860; 88pm80x - Add support for 24c08 EEPROM; at24 - Add support for Broxton Whiskey Cove; intel* - Add support for RTS522A; rts5227 - Add support for I2C devices; intel_quark_i2c_gpio New Functionality: - Add microphone support; arizona - Add general purpose switch support; arizona - Add fuel-gauge support; da9150-core - Add shutdown support; sec-core - Add charger support; tps65217 - Add flexible serial communication unit support; atmel-flexcom - Add power button support; axp20x - Add led-flash support; rt5033 Core Frameworks: - Supply a generic macro for defining Regmap IRQs - Rework ACPI child device matching Fix-ups: - Use Regmap to access registers; tps6105x - Use DEFINE_RES_IRQ_NAMED() macro; da9150 - Re-arrange device registration order; intel_quark_i2c_gpio - Allow OF matching; cros_ec_i2c, atmel-hlcdc, hi6421-pmic, max8997, sm501 - Handle deferred probe; twl6040 - Improve accuracy of headphone detect; arizona - Unnecessary MODULE_ALIAS() removal; bcm590xx, rt5033 - Remove unused code; htc-i2cpld, arizona, pcf50633-irq, sec-core - Simplify code; kempld, rts5209, da903x, lm3533, da9052, arizona - Remove #iffery; arizona - DT binding adaptions; many Bug Fixes: - Fix possible NULL pointer dereference; wm831x, tps6105x - Fix 64bit bug; intel_soc_pmic_bxtwc - Fix signedness issue; arizona" * tag 'mfd-for-linus-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (73 commits) bindings: mfd: s2mps11: Add documentation for s2mps15 PMIC mfd: sec-core: Remove unused s2mpu02-rtc and s2mpu02-clk children extcon: arizona: Add extcon specific device tree binding document MAINTAINERS: Add binding docs for Cirrus Logic/Wolfson Arizona devices mfd: arizona: Remove bindings covered in new subsystem specific docs mfd: rt5033: Add RT5033 Flash led sub device mfd: lpss: Add Intel Broxton PCI IDs mfd: lpss: Add Broxton ACPI IDs mfd: arizona: Signedness bug in arizona_runtime_suspend() mfd: axp20x: Add a cell for the power button part of the, axp288 PMICs mfd: dt-bindings: Document pulled down WRSTBI pin on S2MPS1X mfd: sec-core: Disable buck voltage reset on watchdog falling edge mfd: sec-core: Dump PMIC revision to find out the HW mfd: arizona: Use correct type ID for device tree config mfd: arizona: Remove use of codec build config #ifdefs mfd: arizona: Simplify adding subdevices mfd: arizona: Downgrade type mismatch messages to dev_warn mfd: arizona: Factor out checking of jack detection state mfd: arizona: Factor out DCVDD isolation control mfd: Make TPS6105X select REGMAP_I2C ...
This commit is contained in:
commit
bc914532a0
@ -347,13 +347,18 @@ For the first case, the MFD drivers do not need to do anything. The
|
||||
resulting child platform device will have its ACPI_COMPANION() set to point
|
||||
to the parent device.
|
||||
|
||||
If the ACPI namespace has a device that we can match using an ACPI id,
|
||||
the id should be set like:
|
||||
If the ACPI namespace has a device that we can match using an ACPI id or ACPI
|
||||
adr, the cell should be set like:
|
||||
|
||||
static struct mfd_cell_acpi_match my_subdevice_cell_acpi_match = {
|
||||
.pnpid = "XYZ0001",
|
||||
.adr = 0,
|
||||
};
|
||||
|
||||
static struct mfd_cell my_subdevice_cell = {
|
||||
.name = "my_subdevice",
|
||||
/* set the resources relative to the parent */
|
||||
.acpi_pnpid = "XYZ0001",
|
||||
.acpi_match = &my_subdevice_cell_acpi_match,
|
||||
};
|
||||
|
||||
The ACPI id "XYZ0001" is then used to lookup an ACPI device directly under
|
||||
|
15
Documentation/devicetree/bindings/extcon/extcon-arizona.txt
Normal file
15
Documentation/devicetree/bindings/extcon/extcon-arizona.txt
Normal file
@ -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.
|
@ -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 <dt-bindings/mfd/arizona.txt>. 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:
|
||||
|
||||
|
63
Documentation/devicetree/bindings/mfd/atmel-flexcom.txt
Normal file
63
Documentation/devicetree/bindings/mfd/atmel-flexcom.txt
Normal file
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
@ -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:
|
||||
|
||||
|
@ -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>;
|
||||
};
|
||||
|
||||
da9150-charger {
|
||||
...
|
||||
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";
|
||||
};
|
||||
|
||||
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>
|
||||
};
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
* Samsung S2MPS11, S2MPS13, S2MPS14 and S2MPU02 Voltage and Current Regulator
|
||||
* Samsung S2MPS11/13/14/15 and S2MPU02 Voltage and Current Regulator
|
||||
|
||||
The Samsung S2MPS11 is a multi-function device which includes voltage and
|
||||
current regulators, RTC, charger controller and other sub-blocks. It is
|
||||
@ -7,17 +7,24 @@ interfaced to the host controller using an I2C interface. Each sub-block is
|
||||
addressed by the host system using different I2C slave addresses.
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "samsung,s2mps11-pmic" or "samsung,s2mps13-pmic"
|
||||
or "samsung,s2mps14-pmic" or "samsung,s2mpu02-pmic".
|
||||
- compatible: Should be one of the following
|
||||
- "samsung,s2mps11-pmic"
|
||||
- "samsung,s2mps13-pmic"
|
||||
- "samsung,s2mps14-pmic"
|
||||
- "samsung,s2mps15-pmic"
|
||||
- "samsung,s2mpu02-pmic".
|
||||
- reg: Specifies the I2C slave address of the pmic block. It should be 0x66.
|
||||
|
||||
Optional properties:
|
||||
- interrupt-parent: Specifies the phandle of the interrupt controller to which
|
||||
the interrupts from s2mps11 are delivered to.
|
||||
- interrupts: Interrupt specifiers for interrupt sources.
|
||||
- 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
|
||||
- clocks: s2mps11, s2mps13, s2mps15 and s5m8767 provide three(AP/CP/BT) buffered 32.768
|
||||
KHz outputs, so to register these as clocks with common clock framework
|
||||
instantiate a sub-node named "clocks". It uses the common clock binding
|
||||
documented in :
|
||||
@ -30,12 +37,13 @@ Optional nodes:
|
||||
the clock which they consume.
|
||||
Clock ID Devices
|
||||
----------------------------------------------------------
|
||||
32KhzAP 0 S2MPS11, S2MPS13, S2MPS14, S5M8767
|
||||
32KhzCP 1 S2MPS11, S2MPS13, S5M8767
|
||||
32KhzBT 2 S2MPS11, S2MPS13, S2MPS14, S5M8767
|
||||
32KhzAP 0 S2MPS11, S2MPS13, S2MPS14, S2MPS15, S5M8767
|
||||
32KhzCP 1 S2MPS11, S2MPS13, S2MPS15, S5M8767
|
||||
32KhzBT 2 S2MPS11, S2MPS13, S2MPS14, S2MPS15, S5M8767
|
||||
|
||||
- compatible: Should be one of: "samsung,s2mps11-clk", "samsung,s2mps13-clk",
|
||||
"samsung,s2mps14-clk", "samsung,s5m8767-clk"
|
||||
The s2msp15 uses the same compatible as s2mps13, as both provides similar clocks.
|
||||
|
||||
- regulators: The regulators of s2mps11 that have to be instantiated should be
|
||||
included in a sub-node named 'regulators'. Regulator nodes included in this
|
||||
@ -83,6 +91,7 @@ as per the datasheet of s2mps11.
|
||||
- S2MPS11: 1 to 38
|
||||
- S2MPS13: 1 to 40
|
||||
- S2MPS14: 1 to 25
|
||||
- S2MPS15: 1 to 27
|
||||
- S2MPU02: 1 to 28
|
||||
- Example: LDO1, LDO2, LDO28
|
||||
- BUCKn
|
||||
@ -90,6 +99,7 @@ as per the datasheet of s2mps11.
|
||||
- S2MPS11: 1 to 10
|
||||
- S2MPS13: 1 to 10
|
||||
- S2MPS14: 1 to 5
|
||||
- S2MPS15: 1 to 10
|
||||
- S2MPU02: 1 to 7
|
||||
- Example: BUCK1, BUCK2, BUCK9
|
||||
|
||||
|
23
Documentation/devicetree/bindings/power/da9150-fg.txt
Normal file
23
Documentation/devicetree/bindings/power/da9150-fg.txt
Normal file
@ -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>;
|
||||
};
|
@ -7162,7 +7162,6 @@ F: drivers/media/i2c/mt9v032.c
|
||||
F: include/media/mt9v032.h
|
||||
|
||||
MULTIFUNCTION DEVICES (MFD)
|
||||
M: Samuel Ortiz <sameo@linux.intel.com>
|
||||
M: Lee Jones <lee.jones@linaro.org>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
|
||||
S: Supported
|
||||
@ -11567,6 +11566,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
|
||||
|
@ -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},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/mfd/arizona/core.h>
|
||||
#include <linux/mfd/arizona/registers.h>
|
||||
@ -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;
|
||||
if (IS_ENABLED(CONFIG_MFD_WM8998)) {
|
||||
switch (arizona->type) {
|
||||
case WM8998:
|
||||
type_name = "WM8998";
|
||||
break;
|
||||
|
||||
case WM1814:
|
||||
type_name = "WM1814";
|
||||
break;
|
||||
case WM1814:
|
||||
type_name = "WM1814";
|
||||
break;
|
||||
|
||||
default:
|
||||
type_name = "WM8998";
|
||||
dev_err(arizona->dev, "WM8998 registered as %d\n",
|
||||
arizona->type);
|
||||
arizona->type = WM8998;
|
||||
default:
|
||||
type_name = "WM8998";
|
||||
dev_warn(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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
104
drivers/mfd/atmel-flexcom.c
Normal file
104
drivers/mfd/atmel-flexcom.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Driver for Atmel Flexcom
|
||||
*
|
||||
* Copyright (C) 2015 Atmel Corporation
|
||||
*
|
||||
* Author: Cyrille Pitchen <cyrille.pitchen@atmel.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <dt-bindings/mfd/atmel-flexcom.h>
|
||||
|
||||
/* 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 <cyrille.pitchen@atmel.com>");
|
||||
MODULE_DESCRIPTION("Atmel Flexcom MFD driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -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,
|
||||
|
@ -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",
|
||||
},
|
||||
|
@ -128,4 +128,3 @@ module_i2c_driver(bcm590xx_i2c_driver);
|
||||
MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
|
||||
MODULE_DESCRIPTION("BCM590xx multi-function driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("i2c:bcm590xx");
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -23,6 +23,77 @@
|
||||
#include <linux/mfd/da9150/core.h>
|
||||
#include <linux/mfd/da9150/registers.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -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 = {
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
|
@ -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 },
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/seq_file.h>
|
||||
|
||||
#include <asm-generic/io-64-nonatomic-lo-hi.h>
|
||||
|
||||
#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)
|
||||
|
@ -31,6 +31,10 @@
|
||||
#define MFD_I2C_BAR 0
|
||||
#define MFD_GPIO_BAR 1
|
||||
|
||||
/* ACPI _ADR value to match the child node */
|
||||
#define MFD_ACPI_MATCH_GPIO 0ULL
|
||||
#define MFD_ACPI_MATCH_I2C 1ULL
|
||||
|
||||
/* The base GPIO number under GPIOLIB framework */
|
||||
#define INTEL_QUARK_MFD_GPIO_BASE 8
|
||||
|
||||
@ -82,27 +86,37 @@ static struct resource intel_quark_i2c_res[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell_acpi_match intel_quark_acpi_match_i2c = {
|
||||
.adr = MFD_ACPI_MATCH_I2C,
|
||||
};
|
||||
|
||||
static struct resource intel_quark_gpio_res[] = {
|
||||
[INTEL_QUARK_IORES_MEM] = {
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell_acpi_match intel_quark_acpi_match_gpio = {
|
||||
.adr = MFD_ACPI_MATCH_GPIO,
|
||||
};
|
||||
|
||||
static struct mfd_cell intel_quark_mfd_cells[] = {
|
||||
{
|
||||
.id = MFD_I2C_BAR,
|
||||
.name = "i2c_designware",
|
||||
.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
|
||||
.resources = intel_quark_i2c_res,
|
||||
.ignore_resource_conflicts = true,
|
||||
},
|
||||
{
|
||||
.id = MFD_GPIO_BAR,
|
||||
.name = "gpio-dwapb",
|
||||
.acpi_match = &intel_quark_acpi_match_gpio,
|
||||
.num_resources = ARRAY_SIZE(intel_quark_gpio_res),
|
||||
.resources = intel_quark_gpio_res,
|
||||
.ignore_resource_conflicts = true,
|
||||
},
|
||||
{
|
||||
.id = MFD_I2C_BAR,
|
||||
.name = "i2c_designware",
|
||||
.acpi_match = &intel_quark_acpi_match_i2c,
|
||||
.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
|
||||
.resources = intel_quark_i2c_res,
|
||||
.ignore_resource_conflicts = true,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct pci_device_id intel_quark_mfd_ids[] = {
|
||||
@ -248,12 +262,11 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
|
||||
|
||||
dev_set_drvdata(&pdev->dev, quark_mfd);
|
||||
|
||||
ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[MFD_I2C_BAR]);
|
||||
ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = intel_quark_gpio_setup(pdev,
|
||||
&intel_quark_mfd_cells[MFD_GPIO_BAR]);
|
||||
ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
477
drivers/mfd/intel_soc_pmic_bxtwc.c
Normal file
477
drivers/mfd/intel_soc_pmic_bxtwc.c
Normal file
@ -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 <linux/module.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/intel_bxtwc.h>
|
||||
#include <asm/intel_pmc_ipc.h>
|
||||
|
||||
/* 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<qipeng.zha@intel.com>");
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -82,29 +82,49 @@ static int mfd_platform_add_cell(struct platform_device *pdev,
|
||||
static void mfd_acpi_add_device(const struct mfd_cell *cell,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_device *parent_adev;
|
||||
const struct mfd_cell_acpi_match *match = cell->acpi_match;
|
||||
struct acpi_device *parent, *child;
|
||||
struct acpi_device *adev;
|
||||
|
||||
parent_adev = ACPI_COMPANION(pdev->dev.parent);
|
||||
if (!parent_adev)
|
||||
parent = ACPI_COMPANION(pdev->dev.parent);
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
/*
|
||||
* MFD child device gets its ACPI handle either from the ACPI
|
||||
* device directly under the parent that matches the acpi_pnpid or
|
||||
* it will use the parent handle if is no acpi_pnpid is given.
|
||||
* MFD child device gets its ACPI handle either from the ACPI device
|
||||
* directly under the parent that matches the either _HID or _CID, or
|
||||
* _ADR or it will use the parent handle if is no ID is given.
|
||||
*
|
||||
* Note that use of _ADR is a grey area in the ACPI specification,
|
||||
* though Intel Galileo Gen2 is using it to distinguish the children
|
||||
* devices.
|
||||
*/
|
||||
adev = parent_adev;
|
||||
if (cell->acpi_pnpid) {
|
||||
struct acpi_device_id ids[2] = {};
|
||||
struct acpi_device *child_adev;
|
||||
adev = parent;
|
||||
if (match) {
|
||||
if (match->pnpid) {
|
||||
struct acpi_device_id ids[2] = {};
|
||||
|
||||
strlcpy(ids[0].id, cell->acpi_pnpid, sizeof(ids[0].id));
|
||||
list_for_each_entry(child_adev, &parent_adev->children, node)
|
||||
if (acpi_match_device_ids(child_adev, ids)) {
|
||||
adev = child_adev;
|
||||
break;
|
||||
strlcpy(ids[0].id, match->pnpid, sizeof(ids[0].id));
|
||||
list_for_each_entry(child, &parent->children, node) {
|
||||
if (acpi_match_device_ids(child, ids)) {
|
||||
adev = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned long long adr;
|
||||
acpi_status status;
|
||||
|
||||
list_for_each_entry(child, &parent->children, node) {
|
||||
status = acpi_evaluate_integer(child->handle,
|
||||
"_ADR", NULL,
|
||||
&adr);
|
||||
if (ACPI_SUCCESS(status) && match->adr == adr) {
|
||||
adev = child;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ACPI_COMPANION_SET(&pdev->dev, adev);
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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 <beomho.seo@samsung.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
};
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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:
|
||||
|
@ -64,27 +64,47 @@ 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)
|
||||
@ -96,7 +116,6 @@ static int tps6105x_probe(struct i2c_client *client,
|
||||
|
||||
i2c_set_clientdata(client, tps6105x);
|
||||
tps6105x->client = client;
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
tps6105x->pdata = pdata;
|
||||
|
||||
ret = tps6105x_startup(tps6105x);
|
||||
@ -105,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)
|
||||
|
@ -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",
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 },
|
||||
@ -1633,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 */
|
||||
@ -2710,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:
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/platform_data/at24.h>
|
||||
|
||||
@ -131,6 +132,12 @@ static const struct i2c_device_id at24_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, at24_ids);
|
||||
|
||||
static const struct acpi_device_id at24_acpi_ids[] = {
|
||||
{ "INT3499", AT24_DEVICE_MAGIC(8192 / 8, 0) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, at24_acpi_ids);
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
@ -467,21 +474,29 @@ static void at24_get_ofdata(struct i2c_client *client,
|
||||
static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
struct at24_platform_data chip;
|
||||
kernel_ulong_t magic = 0;
|
||||
bool writable;
|
||||
int use_smbus = 0;
|
||||
int use_smbus_write = 0;
|
||||
struct at24_data *at24;
|
||||
int err;
|
||||
unsigned i, num_addresses;
|
||||
kernel_ulong_t magic;
|
||||
|
||||
if (client->dev.platform_data) {
|
||||
chip = *(struct at24_platform_data *)client->dev.platform_data;
|
||||
} else {
|
||||
if (!id->driver_data)
|
||||
if (id) {
|
||||
magic = id->driver_data;
|
||||
} else {
|
||||
const struct acpi_device_id *aid;
|
||||
|
||||
aid = acpi_match_device(at24_acpi_ids, &client->dev);
|
||||
if (aid)
|
||||
magic = aid->driver_data;
|
||||
}
|
||||
if (!magic)
|
||||
return -ENODEV;
|
||||
|
||||
magic = id->driver_data;
|
||||
chip.byte_len = BIT(magic & AT24_BITMASK(AT24_SIZE_BYTELEN));
|
||||
magic >>= AT24_SIZE_BYTELEN;
|
||||
chip.flags = magic & AT24_BITMASK(AT24_SIZE_FLAGS);
|
||||
@ -661,6 +676,7 @@ static int at24_remove(struct i2c_client *client)
|
||||
static struct i2c_driver at24_driver = {
|
||||
.driver = {
|
||||
.name = "at24",
|
||||
.acpi_match_table = ACPI_PTR(at24_acpi_ids),
|
||||
},
|
||||
.probe = at24_probe,
|
||||
.remove = at24_remove,
|
||||
|
@ -932,6 +932,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
|
||||
|
@ -203,6 +203,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
|
||||
|
@ -34,6 +34,7 @@ obj-$(CONFIG_BATTERY_BQ27XXX) += bq27xxx_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
|
||||
|
579
drivers/power/da9150-fg.c
Normal file
579
drivers/power/da9150-fg.c
Normal file
@ -0,0 +1,579 @@
|
||||
/*
|
||||
* DA9150 Fuel-Gauge Driver
|
||||
*
|
||||
* Copyright (c) 2015 Dialog Semiconductor
|
||||
*
|
||||
* Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
|
||||
*
|
||||
* 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 <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/list.h>
|
||||
#include <asm/div64.h>
|
||||
#include <linux/mfd/da9150/core.h>
|
||||
#include <linux/mfd/da9150/registers.h>
|
||||
|
||||
/* 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 <Adam.Thomson.Opensource@diasemi.com>");
|
||||
MODULE_LICENSE("GPL");
|
26
include/dt-bindings/mfd/atmel-flexcom.h
Normal file
26
include/dt-bindings/mfd/atmel-flexcom.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* This header provides macros for Atmel Flexcom DT bindings.
|
||||
*
|
||||
* Copyright (C) 2015 Cyrille Pitchen <cyrille.pitchen@atmel.com>
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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__ */
|
@ -21,6 +21,7 @@ enum {
|
||||
CHIP_INVALID = 0,
|
||||
CHIP_PM800,
|
||||
CHIP_PM805,
|
||||
CHIP_PM860,
|
||||
CHIP_MAX,
|
||||
};
|
||||
|
||||
|
@ -1065,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
|
||||
@ -8050,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
|
||||
*/
|
||||
|
@ -18,6 +18,12 @@
|
||||
|
||||
struct irq_domain;
|
||||
|
||||
/* Matches ACPI PNP id, either _HID or _CID, or ACPI _ADR */
|
||||
struct mfd_cell_acpi_match {
|
||||
const char *pnpid;
|
||||
const unsigned long long adr;
|
||||
};
|
||||
|
||||
/*
|
||||
* This struct describes the MFD part ("cell").
|
||||
* After registration the copy of this structure will become the platform data
|
||||
@ -44,8 +50,8 @@ struct mfd_cell {
|
||||
*/
|
||||
const char *of_compatible;
|
||||
|
||||
/* Matches ACPI PNP id, either _HID or _CID */
|
||||
const char *acpi_pnpid;
|
||||
/* Matches ACPI */
|
||||
const struct mfd_cell_acpi_match *acpi_match;
|
||||
|
||||
/*
|
||||
* These resources can be specified relative to the parent device.
|
||||
|
@ -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 */
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define __DA9150_CORE_H
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
@ -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 */
|
||||
|
69
include/linux/mfd/intel_bxtwc.h
Normal file
69
include/linux/mfd/intel_bxtwc.h
Normal file
@ -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 <linux/mfd/intel_soc_pmic.h>
|
||||
|
||||
#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
|
@ -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__ */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user