- New Device Support

- Add support for s2mps15; sec-core
    - Add support for Lewisburg; lpc_ich
    - Add support for cs47l24 and wm1831; arizona
  - New Functionality
    - Allow user to select syscon register width; syscon
  - Fix-ups
    - Lots of Checkpatch fixes
    - Rename -pmic/-regulator; s2mps11
    - Build driver components into a single module; wm8994-*
    - Better handing of IRQ during suspend/resume; as3722
    - Constify things; da903x
    - Remove unused code; ab8500-core
    - Improve error handing; qcom_rpm
    - Simplify code: wm831x-otp, sta2x11-mfd
    - Improve locking; cros_ec_spi
    - Fix incorrect DT binding filename reference; arizona, palmas,
                                                   snps-dwapb-gpio, wm8994
  - Bug Fixes
    - Fix broken SYSFS 'show ID' call; wm831x-otp
    - Protect reads from non-existent registers; qcom-spmi-pmic
    - Repair build warnings; as3722
    - Fix IRQ request ordering; arizona-irq
    - Ensure return value is boolean; ucb1x00-core, tps65010, tc6393xb,
                                      htc-egpio, dm355evm_msp, asic3,
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJWl2AcAAoJEFGvii+H/Hdh3OQP/0h84f++G5lPznRRf6Vmevbl
 XnACJHbM+L5jilTr9ISHzrzZrsf5y7FYPEVH3MyJnzFSqeAKwhI0kZ39P5imntOf
 4wvDvmxU+2V/JcSVNaZHxTiKEnEKQMseht4WQo5xaGx44FB+f9nIDJt7XQPG/2E4
 S7X8UG6wH8q0NiV7nesIldFL16EtO2EGY6Pjm62/v6EZQYHoy33QhjqrL4Iyigai
 BA4bsLg8Cz1ihfPFEynkMHL8A1sgG9UDJFvxa97b3w44GINLD42h3LGoIQ4isfIO
 XR6VEhDF7FIeaBqiYW106FYN+DmmBNLDp1I01hdWORYFY3U4q3uw0qDAIw8ZQIeJ
 Gx8OBeQgbJQ84PcA+EYWStEP0fteKqFpWo7ZEeueWZLqY8EQJKx1v2wvQF0eiyVt
 MCD6mmAZbLJ1CbPrMu5E8HWA/YjJs6SLS6BpcFqlSgmnEWLsIkYmtMCsUWfzQlxg
 zSNrXCH5IVafxGVHJYaUyudqd88idUnXXthOag8A+Yita5dnlnNBvvRlNjPXJFM+
 4U/OP2peMVsSPa99S2KfAtiNmZc9kUuwZmERaAOiFAGou1yKtGgLayNb0Kxtc1qo
 Icf508V7Gvom1jN14aQ0/H5tagyy0/bKRpF+7ikV1Q+2767dEjiIeigtUuQI2447
 3+7HAsrNSK4CE2f57Nrk
 =IY7O
 -----END PGP SIGNATURE-----

Merge tag 'mfd-for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "New Device Support:
   - Add support for s2mps15; sec-core
   - Add support for Lewisburg; lpc_ich
   - Add support for cs47l24 and wm1831; arizona

  New Functionality:
   - Allow user to select syscon register width; syscon

  Fix-ups:
   - Lots of Checkpatch fixes
   - Rename -pmic/-regulator; s2mps11
   - Build driver components into a single module; wm8994-*
   - Better handing of IRQ during suspend/resume; as3722
   - Constify things; da903x
   - Remove unused code; ab8500-core
   - Improve error handing; qcom_rpm
   - Simplify code: wm831x-otp, sta2x11-mfd
   - Improve locking; cros_ec_spi
   - Fix incorrect DT binding filename reference; arizona, palmas,
     snps-dwapb-gpio, wm8994

  Bug Fixes:
   - Fix broken SYSFS 'show ID' call; wm831x-otp
   - Protect reads from non-existent registers; qcom-spmi-pmic
   - Repair build warnings; as3722
   - Fix IRQ request ordering; arizona-irq
   - Ensure return value is boolean; ucb1x00-core, tps65010, tc6393xb,
     htc-egpio, dm355evm_msp, asic3"

* tag 'mfd-for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (58 commits)
  mfd: davinci_voicecodec: Remove pointless 'out of memory' error message
  mfd: da9052-irq: Fix trivial 'space before comma' error
  mfd: da9052-i2c: Fix tabbing/whitespace issue
  mfd: da903x: Fix white space and split string issues
  mfd: cs5535-mfd: Add missing line spacing and make local array static
  mfd: cros_ec_spi: Repair comparison ordering issue
  mfd: cros_ec_i2c: Fix trivial 'tabs before spaces' whitespace issue.
  mfd: asic3: Fix a plethora of Checkpatch errors and warnings
  mfd: as3711: Repair OOM and 'line over 80 chars' formatting warnings
  mfd: arizona-i2c: Add blank line formatting after declaration
  mfd: arizona-core: msleep() is unreliable for anything <20ms use usleep_range() instead
  mfd: adp5520: Some trivial 'no space before tab' fixes
  mfd: ab8500-sysctrl: Fix Constify, printk => pr_info and formatting issues
  mfd: ab8500-gpadc: Squash a whole bunch of Checkpatch warnings and one error
  mfd: ab8500-debugfs: Clean-up non-conforming commenting and print formatting
  mfd: ab8500-core: Fix many warnings reported by Checkpatch
  mfd: ab2100-otp: Remove pointless 'out of memory' error message
  mfd: ab3100-core.c: Fix multiple warnings reported by Checkpatch
  mfd: aat2870-core: Remove unnecessary 'out of memory' message
  mfd: 88pm860x-core: Fix commenting and declaration spacing
  ...
This commit is contained in:
Linus Torvalds 2016-01-14 10:53:15 -08:00
commit cf8d7e3850
73 changed files with 2984 additions and 1231 deletions

View file

@ -0,0 +1,49 @@
Binding for Samsung S2M and S5M family clock generator block
============================================================
This is a part of device tree bindings for S2M and S5M family multi-function
devices.
More information can be found in bindings/mfd/sec-core.txt file.
The S2MPS11/13/15 and S5M8767 provide three(AP/CP/BT) buffered 32.768 kHz
outputs. The S2MPS14 provides two (AP/BT) buffered 32.768 KHz outputs.
To register these as clocks with common clock framework instantiate under
main device node a sub-node named "clocks".
It uses the common clock binding documented in:
- Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties of the "clocks" sub-node:
- #clock-cells: should be 1.
- compatible: Should be one of: "samsung,s2mps11-clk", "samsung,s2mps13-clk",
"samsung,s2mps14-clk", "samsung,s5m8767-clk"
The S2MPS15 uses the same compatible as S2MPS13, as both provides similar
clocks.
Each clock is assigned an identifier and client nodes use this identifier
to specify the clock which they consume.
Clock ID Devices
----------------------------------------------------------
32KhzAP 0 S2MPS11/13/14/15, S5M8767
32KhzCP 1 S2MPS11/13/15, S5M8767
32KhzBT 2 S2MPS11/13/14/15, S5M8767
Include dt-bindings/clock/samsung,s2mps11.h file to use preprocessor defines
in device tree sources.
Example:
s2mps11_pmic@66 {
compatible = "samsung,s2mps11-pmic";
reg = <0x66>;
s2m_osc: clocks {
compatible = "samsung,s2mps11-clk";
#clock-cells = <1>;
clock-output-names = "xx", "yy", "zz";
};
};

View file

@ -24,7 +24,7 @@ controller.
- #interrupt-cells : Specifies the number of cells needed to encode an
interrupt. Shall be set to 2. The first cell defines the interrupt number,
the second encodes the triger flags encoded as described in
Documentation/devicetree/bindings/interrupts.txt
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
- interrupt-parent : The parent interrupt controller.
- interrupts : The interrupt to the parent controller raised when GPIOs
generate the interrupts.

View file

@ -1,4 +1,4 @@
Wolfson Arizona class audio SoCs
Cirrus Logic/Wolfson Microelectronics Arizona class audio SoCs
These devices are audio SoCs with extensive digital capabilites and a range
of analogue I/O.
@ -6,12 +6,14 @@ of analogue I/O.
Required properties:
- compatible : One of the following chip-specific strings:
"cirrus,cs47l24"
"wlf,wm5102"
"wlf,wm5110"
"wlf,wm8280"
"wlf,wm8997"
"wlf,wm8998"
"wlf,wm1814"
"wlf,wm1831"
- reg : I2C slave address when connected using I2C, chip select number when
using SPI.
@ -24,7 +26,7 @@ Required properties:
- #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
The first cell is the IRQ number.
The second cell is the flags, encoded as the trigger masks from
Documentation/devicetree/bindings/interrupts.txt
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
- gpio-controller : Indicates this device is a GPIO controller.
- #gpio-cells : Must be 2. The first cell is the pin number and the
@ -41,10 +43,21 @@ Required properties:
- SPKVDD-supply : Speaker driver power supply (wm8997)
- DCVDD-supply : Main power supply (cs47l24, wm1831)
- MICVDD-supply : Microphone power supply (cs47l24, wm1831)
Optional properties:
- wlf,reset : GPIO specifier for the GPIO controlling /RESET
- clocks: Should reference the clocks supplied on MCLK1 and MCLK2
- clock-names: Should contains two strings:
"mclk1" for the clock supplied on MCLK1, recommended to be a high
quality audio reference clock
"mclk2" for the clock supplied on MCLK2, recommended to be an always on
32k clock
- wlf,gpio-defaults : A list of GPIO configuration register values. Defines
for the appropriate values can found in <dt-bindings/mfd/arizona.txt>. If
absent, no configuration of these registers is performed. If any entry has
@ -59,6 +72,12 @@ Optional properties:
that have not been specified are set to 0 by default. Entries are:
<IN1, IN2, IN3, IN4> (wm5102, wm5110, wm8280, wm8997)
<IN1A, IN2A, IN1B, IN2B> (wm8998, wm1814)
- wlf,out-mono : A list of boolean values indicating whether each output is
mono or stereo. Position within the list indicates the output affected
(eg. First entry in the list corresponds to output 1). A non-zero value
indicates a mono output. If present, the number of values should be less
than or equal to the number of outputs, if less values are supplied the
additional outputs will be treated as stereo.
- wlf,dmic-ref : DMIC reference voltage source for each input, can be
selected from either MICVDD or one of the MICBIAS's, defines
@ -69,6 +88,7 @@ Optional properties:
- 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
(wm5102, wm5110, wm8280, wm8997, wm8998, wm1814)
Also see child specific device properties:
Regulator - ../regulator/arizona-regulator.txt

View file

@ -24,7 +24,7 @@ and also the generic series names
- #interrupt-cells : should be set to 2 for IRQ number and flags
The first cell is the IRQ number.
The second cell is the flags, encoded as the trigger masks from
Documentation/devicetree/bindings/interrupts.txt
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
- interrupt-parent : The parent interrupt controller.
Optional properties:

View file

@ -1,90 +0,0 @@
* Samsung S2MPA01 Voltage and Current Regulator
The Samsung S2MPA01 is a multi-function device which includes high
efficiency buck converters including Dual-Phase buck converter, various LDOs,
and an RTC. It is 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,s2mpa01-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 s2mpa01 are delivered to.
- interrupts: An interrupt specifier for the sole interrupt generated by the
device.
Optional nodes:
- regulators: The regulators of s2mpa01 that have to be instantiated should be
included in a sub-node named 'regulators'. Regulator nodes and constraints
included in this sub-node use the standard regulator bindings which are
documented elsewhere.
Properties for BUCK regulator nodes:
- regulator-ramp-delay: ramp delay in uV/us. May be 6250, 12500
(default), 25000, or 50000. May be 0 for disabling the ramp delay on
BUCK{1,2,3,4}.
In the absence of the regulator-ramp-delay property, the default ramp
delay will be used.
NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set
for a particular group of BUCKs. So provide same regulator-ramp-delay=<value>.
The following BUCKs share ramp settings:
* 1 and 6
* 2 and 4
* 8, 9, and 10
The following are the names of the regulators that the s2mpa01 PMIC block
supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
as per the datasheet of s2mpa01.
- LDOn
- valid values for n are 1 to 26
- Example: LDO1, LD02, LDO26
- BUCKn
- valid values for n are 1 to 10.
- Example: BUCK1, BUCK2, BUCK9
Example:
s2mpa01_pmic@66 {
compatible = "samsung,s2mpa01-pmic";
reg = <0x66>;
regulators {
ldo1_reg: LDO1 {
regulator-name = "VDD_ALIVE";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
};
ldo2_reg: LDO2 {
regulator-name = "VDDQ_MMC2";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "vdd_mif";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
buck2_reg: BUCK2 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <50000>;
};
};
};

View file

@ -1,153 +0,0 @@
* 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
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 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).
- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
register to turn off the power. Usually the ACOKB is pulled up to VBATT so
when PWRHOLD pin goes low, the rising ACOKB will trigger power off.
Optional nodes:
- 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 :
[Documentation/devicetree/bindings/clock/clock-bindings.txt]
The s2mps14 provides two (AP/BT) buffered 32.768 KHz outputs.
- #clock-cells: should be 1.
- The following is the list of clocks generated by the controller. Each clock
is assigned an identifier and client nodes use this identifier to specify
the clock which they consume.
Clock ID Devices
----------------------------------------------------------
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
sub-node should be of the format as listed below.
regulator_name {
[standard regulator constraints....];
};
regulator-ramp-delay for BUCKs = [6250/12500/25000(default)/50000] uV/us
BUCK[2/3/4/6] supports disabling ramp delay on hardware, so explicitly
regulator-ramp-delay = <0> can be used for them to disable ramp delay.
In the absence of the regulator-ramp-delay property, the default ramp
delay will be used.
NOTE: Some BUCKs share the ramp rate setting i.e. same ramp value will be set
for a particular group of BUCKs. So provide same regulator-ramp-delay<value>.
Grouping of BUCKs sharing ramp rate setting is as follow : BUCK[1, 6],
BUCK[3, 4], and BUCK[7, 8, 10]
On S2MPS14 the LDO10, LDO11 and LDO12 can be configured to external control
over GPIO. To turn this feature on this property must be added to the regulator
sub-node:
- samsung,ext-control-gpios: GPIO specifier for one GPIO
controlling this regulator (enable/disable);
Example:
LDO12 {
regulator-name = "V_EMMC_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
samsung,ext-control-gpios = <&gpk0 2 0>;
};
The regulator constraints inside the regulator nodes use the standard regulator
bindings which are documented elsewhere.
The following are the names of the regulators that the s2mps11 pmic block
supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
as per the datasheet of s2mps11.
- LDOn
- valid values for n are:
- 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
- valid values for n are:
- S2MPS11: 1 to 10
- S2MPS13: 1 to 10
- S2MPS14: 1 to 5
- S2MPS15: 1 to 10
- S2MPU02: 1 to 7
- Example: BUCK1, BUCK2, BUCK9
Example:
s2mps11_pmic@66 {
compatible = "samsung,s2mps11-pmic";
reg = <0x66>;
s2m_osc: clocks {
compatible = "samsung,s2mps11-clk";
#clock-cells = <1>;
clock-output-names = "xx", "yy", "zz";
};
regulators {
ldo1_reg: LDO1 {
regulator-name = "VDD_ABB_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
ldo2_reg: LDO2 {
regulator-name = "VDD_ALIVE_1.1V";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "vdd_mif";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
buck2_reg: BUCK2 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <50000>;
};
};
};

View file

@ -0,0 +1,88 @@
Binding for Samsung S2M and S5M family multi-function device
============================================================
This is a part of device tree bindings for S2M and S5M family multi-function
devices.
The Samsung S2MPA01, S2MPS11/13/14/15, S2MPU02 and S5M8767 is a family
of multi-function devices which include voltage and current regulators, RTC,
charger controller, clock outputs and other sub-blocks. It is interfaced
to the host controller using an I2C interface. Each sub-block is usually
addressed by the host system using different I2C slave addresses.
This document describes bindings for main device node. Optional sub-blocks
must be a sub-nodes to it. Bindings for them can be found in:
- bindings/regulator/samsung,s2mpa01.txt
- bindings/regulator/samsung,s2mps11.txt
- bindings/regulator/samsung,s5m8767.txt
- bindings/clock/samsung,s2mps11.txt
Required properties:
- compatible: Should be one of the following
- "samsung,s2mpa01-pmic",
- "samsung,s2mps11-pmic",
- "samsung,s2mps13-pmic",
- "samsung,s2mps14-pmic",
- "samsung,s2mps15-pmic",
- "samsung,s2mpu02-pmic",
- "samsung,s5m8767-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).
- samsung,s2mps11-acokb-ground: Indicates that ACOKB pin of S2MPS11 PMIC is
connected to the ground so the PMIC must manually set PWRHOLD bit in CTRL1
register to turn off the power. Usually the ACOKB is pulled up to VBATT so
when PWRHOLD pin goes low, the rising ACOKB will trigger power off.
Example:
s2mps11_pmic@66 {
compatible = "samsung,s2mps11-pmic";
reg = <0x66>;
s2m_osc: clocks {
compatible = "samsung,s2mps11-clk";
#clock-cells = <1>;
clock-output-names = "xx", "yy", "zz";
};
regulators {
ldo1_reg: LDO1 {
regulator-name = "VDD_ABB_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
ldo2_reg: LDO2 {
regulator-name = "VDD_ALIVE_1.1V";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "vdd_mif";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
buck2_reg: BUCK2 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <50000>;
};
};
};

View file

@ -13,6 +13,10 @@ Required properties:
- compatible: Should contain "syscon".
- reg: the register region can be accessed from syscon
Optional property:
- reg-io-width: the size (in bytes) of the IO accesses that should be
performed on the device.
Examples:
gpr: iomuxc-gpr@020e0000 {
compatible = "fsl,imx6q-iomuxc-gpr", "syscon";

View file

@ -1,163 +0,0 @@
* Samsung S5M8767 Voltage and Current Regulator
The Samsung S5M8767 is a multi-function device which includes voltage and
current regulators, rtc, charger controller and other sub-blocks. It is
interfaced to the host controller using a i2c interface. Each sub-block is
addressed by the host system using different i2c slave address. This document
describes the bindings for 'pmic' sub-block of s5m8767.
Required properties:
- compatible: Should be "samsung,s5m8767-pmic".
- reg: Specifies the i2c slave address of the pmic block. It should be 0x66.
- s5m8767,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
units for buck2 when changing voltage using gpio dvs. Refer to [1] below
for additional information.
- s5m8767,pmic-buck3-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
units for buck3 when changing voltage using gpio dvs. Refer to [1] below
for additional information.
- s5m8767,pmic-buck4-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
units for buck4 when changing voltage using gpio dvs. Refer to [1] below
for additional information.
- s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used
for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines.
[1] If none of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional
property is specified, the 's5m8767,pmic-buck[2/3/4]-dvs-voltage'
property should specify atleast one voltage level (which would be a
safe operating voltage).
If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional
property is specified, then all the eight voltage values for the
's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified.
Optional properties:
- interrupt-parent: Specifies the phandle of the interrupt controller to which
the interrupts from s5m8767 are delivered to.
- interrupts: Interrupt specifiers for two interrupt sources.
- First interrupt specifier is for 'irq1' interrupt.
- Second interrupt specifier is for 'alert' interrupt.
- s5m8767,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
- s5m8767,pmic-buck3-uses-gpio-dvs: 'buck3' can be controlled by gpio dvs.
- s5m8767,pmic-buck4-uses-gpio-dvs: 'buck4' can be controlled by gpio dvs.
Additional properties required if either of the optional properties are used:
- s5m8767,pmic-buck234-default-dvs-idx: Default voltage setting selected from
the possible 8 options selectable by the dvs gpios. The value of this
property should be between 0 and 7. If not specified or if out of range, the
default value of this property is set to 0.
- s5m8767,pmic-buck-dvs-gpios: GPIO specifiers for three host gpio's used
for dvs. The format of the gpio specifier depends in the gpio controller.
Regulators: The regulators of s5m8767 that have to be instantiated should be
included in a sub-node named 'regulators'. Regulator nodes included in this
sub-node should be of the format as listed below.
regulator_name {
ldo1_reg: LDO1 {
regulator-name = "VDD_ALIVE_1.0V";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
regulator-boot-on;
op_mode = <1>; /* Normal Mode */
};
};
The above regulator entries are defined in regulator bindings documentation
except these properties:
- op_mode: describes the different operating modes of the LDO's with
power mode change in SOC. The different possible values are,
0 - always off mode
1 - on in normal mode
2 - low power mode
3 - suspend mode
- s5m8767,pmic-ext-control-gpios: (optional) GPIO specifier for one
GPIO controlling this regulator (enable/disable); This is
valid only for buck9.
The following are the names of the regulators that the s5m8767 pmic block
supports. Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
as per the datasheet of s5m8767.
- LDOn
- valid values for n are 1 to 28
- Example: LDO1, LDO2, LDO28
- BUCKn
- valid values for n are 1 to 9.
- Example: BUCK1, BUCK2, BUCK9
The bindings inside the regulator nodes use the standard regulator bindings
which are documented elsewhere.
Example:
s5m8767_pmic@66 {
compatible = "samsung,s5m8767-pmic";
reg = <0x66>;
s5m8767,pmic-buck2-uses-gpio-dvs;
s5m8767,pmic-buck3-uses-gpio-dvs;
s5m8767,pmic-buck4-uses-gpio-dvs;
s5m8767,pmic-buck-default-dvs-idx = <0>;
s5m8767,pmic-buck-dvs-gpios = <&gpx0 0 0>, /* DVS1 */
<&gpx0 1 0>, /* DVS2 */
<&gpx0 2 0>; /* DVS3 */
s5m8767,pmic-buck-ds-gpios = <&gpx2 3 0>, /* SET1 */
<&gpx2 4 0>, /* SET2 */
<&gpx2 5 0>; /* SET3 */
s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>,
<1250000>, <1200000>,
<1150000>, <1100000>,
<1000000>, <950000>;
s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>,
<1100000>, <1100000>,
<1000000>, <1000000>,
<1000000>, <1000000>;
s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>,
<1200000>, <1200000>,
<1200000>, <1200000>,
<1200000>, <1200000>;
regulators {
ldo1_reg: LDO1 {
regulator-name = "VDD_ABB_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
op_mode = <1>; /* Normal Mode */
};
ldo2_reg: LDO2 {
regulator-name = "VDD_ALIVE_1.1V";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "VDD_MIF_1.2V";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
vemmc_reg: BUCK9 {
regulator-name = "VMEM_VDD_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
op_mode = <3>; /* Standby Mode */
s5m8767,pmic-ext-control-gpios = <&gpk0 2 0>;
};
};
};

View file

@ -0,0 +1,79 @@
Binding for Samsung S2MPA01 regulator block
===========================================
This is a part of device tree bindings for S2M family multi-function devices.
More information can be found in bindings/mfd/sec-core.txt file.
The S2MPA01 device provide buck and LDO regulators.
To register these with regulator framework instantiate under main device node
a sub-node named "regulators" with more sub-nodes for each regulator using the
common regulator binding documented in:
- Documentation/devicetree/bindings/regulator/regulator.txt
Names of regulators supported by S2MPA01 device:
- LDOn
- valid values for n are 1 to 26
- Example: LDO1, LD02, LDO26
- BUCKn
- valid values for n are 1 to 10.
- Example: BUCK1, BUCK2, BUCK9
Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
as per the datasheet of device.
Optional properties of buck regulator nodes under "regulators" sub-node:
- regulator-ramp-delay: ramp delay in uV/us. May be 6250, 12500
(default), 25000, or 50000. May be 0 for disabling the ramp delay on
BUCK{1,2,3,4}.
In the absence of the regulator-ramp-delay property, the default ramp
delay will be used.
Note: Some bucks share the ramp rate setting i.e. same ramp value
will be set for a particular group of bucks so provide the same
regulator-ramp-delay value for them.
Groups sharing ramp rate:
- buck{1,6},
- buck{2,4},
- buck{8,9,10}.
Example:
s2mpa01_pmic@66 {
compatible = "samsung,s2mpa01-pmic";
reg = <0x66>;
regulators {
ldo1_reg: LDO1 {
regulator-name = "VDD_ALIVE";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
};
ldo2_reg: LDO2 {
regulator-name = "VDDQ_MMC2";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "vdd_mif";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
buck2_reg: BUCK2 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <50000>;
};
};
};

View file

@ -0,0 +1,102 @@
Binding for Samsung S2M family regulator block
==============================================
This is a part of device tree bindings for S2M family multi-function devices.
More information can be found in bindings/mfd/sec-core.txt file.
The S2MPS11/13/14/15 and S2MPU02 devices provide buck and LDO regulators.
To register these with regulator framework instantiate under main device node
a sub-node named "regulators" with more sub-nodes for each regulator using the
common regulator binding documented in:
- Documentation/devicetree/bindings/regulator/regulator.txt
Names of regulators supported by different devices:
- LDOn
- valid values for n are:
- 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
- valid values for n are:
- S2MPS11: 1 to 10
- S2MPS13: 1 to 10
- S2MPS14: 1 to 5
- S2MPS15: 1 to 10
- S2MPU02: 1 to 7
- Example: BUCK1, BUCK2, BUCK9
Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
as per the datasheet of device.
Optional properties of the nodes under "regulators" sub-node:
- regulator-ramp-delay: ramp delay in uV/us. May be 6250, 12500,
25000 (default) or 50000.
Additionally S2MPS11 supports disabling ramp delay for BUCK{2,3,4,6}
by setting it to <0>.
Note: On S2MPS11 some bucks share the ramp rate setting i.e. same ramp value
will be set for a particular group of bucks so provide the same
regulator-ramp-delay value for them.
Groups sharing ramp rate:
- buck{1,6},
- buck{3,4},
- buck{7,8,10}.
- samsung,ext-control-gpios: On S2MPS14 the LDO10, LDO11 and LDO12 can be
configured to external control over GPIO. To turn this feature on this
property must be added to the regulator sub-node:
- samsung,ext-control-gpios: GPIO specifier for one GPIO
controlling this regulator (enable/disable)
Example:
LDO12 {
regulator-name = "V_EMMC_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
samsung,ext-control-gpios = <&gpk0 2 0>;
};
Example:
s2mps11_pmic@66 {
compatible = "samsung,s2mps11-pmic";
reg = <0x66>;
regulators {
ldo1_reg: LDO1 {
regulator-name = "VDD_ABB_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
ldo2_reg: LDO2 {
regulator-name = "VDD_ALIVE_1.1V";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "vdd_mif";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
buck2_reg: BUCK2 {
regulator-name = "vdd_arm";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
regulator-ramp-delay = <50000>;
};
};
};

View file

@ -0,0 +1,145 @@
Binding for Samsung S5M8767 regulator block
===========================================
This is a part of device tree bindings for S5M family multi-function devices.
More information can be found in bindings/mfd/sec-core.txt file.
The S5M8767 device provide buck and LDO regulators.
To register these with regulator framework instantiate under main device node
a sub-node named "regulators" with more sub-nodes for each regulator using the
common regulator binding documented in:
- Documentation/devicetree/bindings/regulator/regulator.txt
Required properties of the main device node (the parent!):
- s5m8767,pmic-buck2-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
units for buck2 when changing voltage using gpio dvs. Refer to [1] below
for additional information.
- s5m8767,pmic-buck3-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
units for buck3 when changing voltage using gpio dvs. Refer to [1] below
for additional information.
- s5m8767,pmic-buck4-dvs-voltage: A set of 8 voltage values in micro-volt (uV)
units for buck4 when changing voltage using gpio dvs. Refer to [1] below
for additional information.
- s5m8767,pmic-buck-ds-gpios: GPIO specifiers for three host gpio's used
for selecting GPIO DVS lines. It is one-to-one mapped to dvs gpio lines.
[1] If none of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional
property is specified, the 's5m8767,pmic-buck[2/3/4]-dvs-voltage'
property should specify atleast one voltage level (which would be a
safe operating voltage).
If either of the 's5m8767,pmic-buck[2/3/4]-uses-gpio-dvs' optional
property is specified, then all the eight voltage values for the
's5m8767,pmic-buck[2/3/4]-dvs-voltage' should be specified.
Optional properties of the main device node (the parent!):
- s5m8767,pmic-buck2-uses-gpio-dvs: 'buck2' can be controlled by gpio dvs.
- s5m8767,pmic-buck3-uses-gpio-dvs: 'buck3' can be controlled by gpio dvs.
- s5m8767,pmic-buck4-uses-gpio-dvs: 'buck4' can be controlled by gpio dvs.
Additional properties required if either of the optional properties are used:
- s5m8767,pmic-buck234-default-dvs-idx: Default voltage setting selected from
the possible 8 options selectable by the dvs gpios. The value of this
property should be between 0 and 7. If not specified or if out of range, the
default value of this property is set to 0.
- s5m8767,pmic-buck-dvs-gpios: GPIO specifiers for three host gpio's used
for dvs. The format of the gpio specifier depends in the gpio controller.
Names of regulators supported by S5M8767 device:
- LDOn
- valid values for n are 1 to 28
- Example: LDO1, LDO2, LDO28
- BUCKn
- valid values for n are 1 to 9.
- Example: BUCK1, BUCK2, BUCK9
Note: The 'n' in LDOn and BUCKn represents the LDO or BUCK number
as per the datasheet of device.
Optional properties of the nodes under "regulators" sub-node:
- op_mode: describes the different operating modes of the LDO's with
power mode change in SOC. The different possible values are,
0 - always off mode
1 - on in normal mode
2 - low power mode
3 - suspend mode
- s5m8767,pmic-ext-control-gpios: (optional) GPIO specifier for one
GPIO controlling this regulator
(enable/disable); This is valid only
for buck9.
Example:
s5m8767_pmic@66 {
compatible = "samsung,s5m8767-pmic";
reg = <0x66>;
s5m8767,pmic-buck2-uses-gpio-dvs;
s5m8767,pmic-buck3-uses-gpio-dvs;
s5m8767,pmic-buck4-uses-gpio-dvs;
s5m8767,pmic-buck-default-dvs-idx = <0>;
s5m8767,pmic-buck-dvs-gpios = <&gpx0 0 0>, /* DVS1 */
<&gpx0 1 0>, /* DVS2 */
<&gpx0 2 0>; /* DVS3 */
s5m8767,pmic-buck-ds-gpios = <&gpx2 3 0>, /* SET1 */
<&gpx2 4 0>, /* SET2 */
<&gpx2 5 0>; /* SET3 */
s5m8767,pmic-buck2-dvs-voltage = <1350000>, <1300000>,
<1250000>, <1200000>,
<1150000>, <1100000>,
<1000000>, <950000>;
s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>,
<1100000>, <1100000>,
<1000000>, <1000000>,
<1000000>, <1000000>;
s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>,
<1200000>, <1200000>,
<1200000>, <1200000>,
<1200000>, <1200000>;
regulators {
ldo1_reg: LDO1 {
regulator-name = "VDD_ABB_3.3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
op_mode = <1>; /* Normal Mode */
};
ldo2_reg: LDO2 {
regulator-name = "VDD_ALIVE_1.1V";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "VDD_MIF_1.2V";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1350000>;
regulator-always-on;
regulator-boot-on;
};
vemmc_reg: BUCK9 {
regulator-name = "VMEM_VDD_2.8V";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
op_mode = <3>; /* Standby Mode */
s5m8767,pmic-ext-control-gpios = <&gpk0 2 0>;
};
};
};

View file

@ -30,7 +30,7 @@ Optional properties:
- #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
The first cell is the IRQ number.
The second cell is the flags, encoded as the trigger masks from
Documentation/devicetree/bindings/interrupts.txt
Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
- clocks : A list of up to two phandle and clock specifier pairs
- clock-names : A list of clock names sorted in the same order as clocks.

View file

@ -9285,8 +9285,10 @@ F: drivers/regulator/s5m*.c
F: drivers/clk/clk-s2mps11.c
F: drivers/rtc/rtc-s5m.c
F: include/linux/mfd/samsung/
F: Documentation/devicetree/bindings/regulator/s5m8767-regulator.txt
F: Documentation/devicetree/bindings/mfd/s2mp*.txt
F: Documentation/devicetree/bindings/mfd/samsung,sec-core.txt
F: Documentation/devicetree/bindings/regulator/samsung,s2m*.txt
F: Documentation/devicetree/bindings/regulator/samsung,s5m*.txt
F: Documentation/devicetree/bindings/clock/samsung,s2mps11.txt
SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
M: Kyungmin Park <kyungmin.park@samsung.com>
@ -11743,6 +11745,7 @@ F: drivers/input/touchscreen/wm831x-ts.c
F: drivers/input/touchscreen/wm97*.c
F: drivers/mfd/arizona*
F: drivers/mfd/wm*.c
F: drivers/mfd/cs47l24*
F: drivers/power/wm83*.c
F: drivers/rtc/rtc-wm83*.c
F: drivers/regulator/wm8*.c
@ -11756,6 +11759,7 @@ F: include/linux/wm97xx.h
F: include/sound/wm????.h
F: sound/soc/codecs/arizona.?
F: sound/soc/codecs/wm*
F: sound/soc/codecs/cs47l24*
WORKQUEUE
M: Tejun Heo <tj@kernel.org>

View file

@ -122,6 +122,10 @@ static int arizona_gpio_probe(struct platform_device *pdev)
case WM1814:
arizona_gpio->gpio_chip.ngpio = 5;
break;
case WM1831:
case CS47L24:
arizona_gpio->gpio_chip.ngpio = 2;
break;
default:
dev_err(&pdev->dev, "Unknown chip variant %d\n",
arizona->type);

View file

@ -135,7 +135,7 @@ EXPORT_SYMBOL_GPL(pm80x_deinit);
#ifdef CONFIG_PM_SLEEP
static int pm80x_suspend(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
struct i2c_client *client = to_i2c_client(dev);
struct pm80x_chip *chip = i2c_get_clientdata(client);
if (chip && chip->wu_flag)
@ -147,7 +147,7 @@ static int pm80x_suspend(struct device *dev)
static int pm80x_resume(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
struct i2c_client *client = to_i2c_client(dev);
struct pm80x_chip *chip = i2c_get_clientdata(client);
if (chip && chip->wu_flag)

View file

@ -705,10 +705,12 @@ int pm8606_osc_disable(struct pm860x_chip *chip, unsigned short client)
chip->osc_status);
mutex_lock(&chip->osc_lock);
/*Update voting status */
/* Update voting status */
chip->osc_vote &= ~(client);
/* If reference group is off and this is the last client to release
* - turn off */
/*
* If reference group is off and this is the last client to release
* - turn off
*/
if ((chip->osc_status != PM8606_REF_GP_OSC_OFF) &&
(chip->osc_vote == REF_GP_NO_CLIENTS)) {
chip->osc_status = PM8606_REF_GP_OSC_UNKNOWN;
@ -1218,7 +1220,7 @@ static int pm860x_remove(struct i2c_client *client)
#ifdef CONFIG_PM_SLEEP
static int pm860x_suspend(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
struct i2c_client *client = to_i2c_client(dev);
struct pm860x_chip *chip = i2c_get_clientdata(client);
if (device_may_wakeup(dev) && chip->wakeup_flag)
@ -1228,7 +1230,7 @@ static int pm860x_suspend(struct device *dev)
static int pm860x_resume(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
struct i2c_client *client = to_i2c_client(dev);
struct pm860x_chip *chip = i2c_get_clientdata(client);
if (device_may_wakeup(dev) && chip->wakeup_flag)
@ -1265,6 +1267,7 @@ static struct i2c_driver pm860x_driver = {
static int __init pm860x_i2c_init(void)
{
int ret;
ret = i2c_add_driver(&pm860x_driver);
if (ret != 0)
pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);

View file

@ -211,7 +211,7 @@ config MFD_DA9062
of the device.
config MFD_DA9063
bool "Dialog Semiconductor DA9063 PMIC Support"
tristate "Dialog Semiconductor DA9063 PMIC Support"
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@ -1370,24 +1370,30 @@ config MFD_ARIZONA
bool
config MFD_ARIZONA_I2C
tristate "Wolfson Microelectronics Arizona platform with I2C"
tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with I2C"
select MFD_ARIZONA
select MFD_CORE
select REGMAP_I2C
depends on I2C
help
Support for the Wolfson Microelectronics Arizona platform audio SoC
core functionality controlled via I2C.
Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
audio SoC core functionality controlled via I2C.
config MFD_ARIZONA_SPI
tristate "Wolfson Microelectronics Arizona platform with SPI"
tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with SPI"
select MFD_ARIZONA
select MFD_CORE
select REGMAP_SPI
depends on SPI_MASTER
help
Support for the Wolfson Microelectronics Arizona platform audio SoC
core functionality controlled via I2C.
Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
audio SoC core functionality controlled via I2C.
config MFD_CS47L24
bool "Cirrus Logic CS47L24 and WM1831"
depends on MFD_ARIZONA
help
Support for Cirrus Logic CS47L24 and WM1831 low power audio SoC
config MFD_WM5102
bool "Wolfson Microelectronics WM5102"

View file

@ -51,6 +51,9 @@ endif
ifeq ($(CONFIG_MFD_WM8998),y)
obj-$(CONFIG_MFD_ARIZONA) += wm8998-tables.o
endif
ifeq ($(CONFIG_MFD_CS47L24),y)
obj-$(CONFIG_MFD_ARIZONA) += cs47l24-tables.o
endif
obj-$(CONFIG_MFD_WM8400) += wm8400-core.o
wm831x-objs := wm831x-core.o wm831x-irq.o wm831x-otp.o
wm831x-objs += wm831x-auxadc.o
@ -61,7 +64,8 @@ wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o
wm8350-objs += wm8350-irq.o
obj-$(CONFIG_MFD_WM8350) += wm8350.o
obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o wm8994-regmap.o
wm8994-objs := wm8994-core.o wm8994-irq.o wm8994-regmap.o
obj-$(CONFIG_MFD_WM8994) += wm8994.o
obj-$(CONFIG_TPS6105X) += tps6105x.o
obj-$(CONFIG_TPS65010) += tps65010.o

View file

@ -373,11 +373,8 @@ static int aat2870_i2c_probe(struct i2c_client *client,
aat2870 = devm_kzalloc(&client->dev, sizeof(struct aat2870_data),
GFP_KERNEL);
if (!aat2870) {
dev_err(&client->dev,
"Failed to allocate memory for aat2870\n");
if (!aat2870)
return -ENOMEM;
}
aat2870->dev = &client->dev;
dev_set_drvdata(aat2870->dev, aat2870);

View file

@ -381,9 +381,11 @@ static int ab3100_event_registers_startup_state_get(struct device *dev,
u8 *event)
{
struct ab3100 *ab3100 = dev_get_drvdata(dev->parent);
if (!ab3100->startup_events_read)
return -EAGAIN; /* Try again later */
memcpy(event, ab3100->startup_events, 3);
return 0;
}
@ -858,10 +860,8 @@ static int ab3100_probe(struct i2c_client *client,
int i;
ab3100 = devm_kzalloc(&client->dev, sizeof(struct ab3100), GFP_KERNEL);
if (!ab3100) {
dev_err(&client->dev, "could not allocate AB3100 device\n");
if (!ab3100)
return -ENOMEM;
}
/* Initialize data structure */
mutex_init(&ab3100->access_mutex);
@ -883,20 +883,17 @@ static int ab3100_probe(struct i2c_client *client,
for (i = 0; ids[i].id != 0x0; i++) {
if (ids[i].id == ab3100->chip_id) {
if (ids[i].name != NULL) {
snprintf(&ab3100->chip_name[0],
sizeof(ab3100->chip_name) - 1,
"AB3100 %s",
ids[i].name);
if (ids[i].name)
break;
} else {
dev_err(&client->dev,
"AB3000 is not supported\n");
goto exit_no_detect;
}
dev_err(&client->dev, "AB3000 is not supported\n");
goto exit_no_detect;
}
}
snprintf(&ab3100->chip_name[0],
sizeof(ab3100->chip_name) - 1, "AB3100 %s", ids[i].name);
if (ids[i].id == 0x0) {
dev_err(&client->dev, "unknown analog baseband chip id: 0x%x\n",
ab3100->chip_id);

View file

@ -188,10 +188,9 @@ static int __init ab3100_otp_probe(struct platform_device *pdev)
int i;
otp = devm_kzalloc(&pdev->dev, sizeof(struct ab3100_otp), GFP_KERNEL);
if (!otp) {
dev_err(&pdev->dev, "could not allocate AB3100 OTP device\n");
if (!otp)
return -ENOMEM;
}
otp->dev = &pdev->dev;
/* Replace platform data coming in with a local struct */

View file

@ -113,7 +113,7 @@
#define AB8500_SWITCH_OFF_STATUS 0x00
#define AB8500_TURN_ON_STATUS 0x00
#define AB8505_TURN_ON_STATUS_2 0x04
#define AB8505_TURN_ON_STATUS_2 0x04
#define AB8500_CH_USBCH_STAT1_REG 0x02
#define VBUS_DET_DBNC100 0x02
@ -211,7 +211,7 @@ static int set_register_interruptible(struct ab8500 *ab8500, u8 bank,
/*
* Put the u8 bank and u8 register together into a an u16.
* The bank on higher 8 bits and register in lower 8 bits.
* */
*/
u16 addr = ((u16)bank) << 8 | reg;
dev_vdbg(ab8500->dev, "wr: addr %#x <= %#x\n", addr, data);
@ -243,8 +243,6 @@ static int get_register_interruptible(struct ab8500 *ab8500, u8 bank,
u8 reg, u8 *value)
{
int ret;
/* put the u8 bank and u8 reg together into a an u16.
* bank on higher 8 bits and reg in lower */
u16 addr = ((u16)bank) << 8 | reg;
mutex_lock(&ab8500->lock);
@ -278,8 +276,6 @@ static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank,
u8 reg, u8 bitmask, u8 bitvalues)
{
int ret;
/* put the u8 bank and u8 reg together into a an u16.
* bank on higher 8 bits and reg in lower */
u16 addr = ((u16)bank) << 8 | reg;
mutex_lock(&ab8500->lock);
@ -449,12 +445,12 @@ static void update_latch_offset(u8 *offset, int i)
{
/* Fix inconsistent ITFromLatch25 bit mapping... */
if (unlikely(*offset == 17))
*offset = 24;
*offset = 24;
/* Fix inconsistent ab8540 bit mapping... */
if (unlikely(*offset == 16))
*offset = 25;
*offset = 25;
if ((i == 3) && (*offset >= 24))
*offset += 2;
*offset += 2;
}
static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500,
@ -590,12 +586,12 @@ static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np)
/* If ->irq_base is zero this will give a linear mapping */
ab8500->domain = irq_domain_add_simple(ab8500->dev->of_node,
num_irqs, 0,
&ab8500_irq_ops, ab8500);
num_irqs, 0,
&ab8500_irq_ops, ab8500);
if (!ab8500->domain) {
dev_err(ab8500->dev, "Failed to create irqdomain\n");
return -ENOSYS;
return -ENODEV;
}
return 0;
@ -609,442 +605,28 @@ int ab8500_suspend(struct ab8500 *ab8500)
return 0;
}
static struct resource ab8500_gpadc_resources[] = {
{
.name = "HW_CONV_END",
.start = AB8500_INT_GP_HW_ADC_CONV_END,
.end = AB8500_INT_GP_HW_ADC_CONV_END,
.flags = IORESOURCE_IRQ,
},
{
.name = "SW_CONV_END",
.start = AB8500_INT_GP_SW_ADC_CONV_END,
.end = AB8500_INT_GP_SW_ADC_CONV_END,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8505_gpadc_resources[] = {
{
.name = "SW_CONV_END",
.start = AB8500_INT_GP_SW_ADC_CONV_END,
.end = AB8500_INT_GP_SW_ADC_CONV_END,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8500_rtc_resources[] = {
{
.name = "60S",
.start = AB8500_INT_RTC_60S,
.end = AB8500_INT_RTC_60S,
.flags = IORESOURCE_IRQ,
},
{
.name = "ALARM",
.start = AB8500_INT_RTC_ALARM,
.end = AB8500_INT_RTC_ALARM,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8540_rtc_resources[] = {
{
.name = "1S",
.start = AB8540_INT_RTC_1S,
.end = AB8540_INT_RTC_1S,
.flags = IORESOURCE_IRQ,
},
{
.name = "ALARM",
.start = AB8500_INT_RTC_ALARM,
.end = AB8500_INT_RTC_ALARM,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8500_poweronkey_db_resources[] = {
{
.name = "ONKEY_DBF",
.start = AB8500_INT_PON_KEY1DB_F,
.end = AB8500_INT_PON_KEY1DB_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "ONKEY_DBR",
.start = AB8500_INT_PON_KEY1DB_R,
.end = AB8500_INT_PON_KEY1DB_R,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8500_av_acc_detect_resources[] = {
{
.name = "ACC_DETECT_1DB_F",
.start = AB8500_INT_ACC_DETECT_1DB_F,
.end = AB8500_INT_ACC_DETECT_1DB_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "ACC_DETECT_1DB_R",
.start = AB8500_INT_ACC_DETECT_1DB_R,
.end = AB8500_INT_ACC_DETECT_1DB_R,
.flags = IORESOURCE_IRQ,
},
{
.name = "ACC_DETECT_21DB_F",
.start = AB8500_INT_ACC_DETECT_21DB_F,
.end = AB8500_INT_ACC_DETECT_21DB_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "ACC_DETECT_21DB_R",
.start = AB8500_INT_ACC_DETECT_21DB_R,
.end = AB8500_INT_ACC_DETECT_21DB_R,
.flags = IORESOURCE_IRQ,
},
{
.name = "ACC_DETECT_22DB_F",
.start = AB8500_INT_ACC_DETECT_22DB_F,
.end = AB8500_INT_ACC_DETECT_22DB_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "ACC_DETECT_22DB_R",
.start = AB8500_INT_ACC_DETECT_22DB_R,
.end = AB8500_INT_ACC_DETECT_22DB_R,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8500_charger_resources[] = {
{
.name = "MAIN_CH_UNPLUG_DET",
.start = AB8500_INT_MAIN_CH_UNPLUG_DET,
.end = AB8500_INT_MAIN_CH_UNPLUG_DET,
.flags = IORESOURCE_IRQ,
},
{
.name = "MAIN_CHARGE_PLUG_DET",
.start = AB8500_INT_MAIN_CH_PLUG_DET,
.end = AB8500_INT_MAIN_CH_PLUG_DET,
.flags = IORESOURCE_IRQ,
},
{
.name = "VBUS_DET_R",
.start = AB8500_INT_VBUS_DET_R,
.end = AB8500_INT_VBUS_DET_R,
.flags = IORESOURCE_IRQ,
},
{
.name = "VBUS_DET_F",
.start = AB8500_INT_VBUS_DET_F,
.end = AB8500_INT_VBUS_DET_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "USB_LINK_STATUS",
.start = AB8500_INT_USB_LINK_STATUS,
.end = AB8500_INT_USB_LINK_STATUS,
.flags = IORESOURCE_IRQ,
},
{
.name = "VBUS_OVV",
.start = AB8500_INT_VBUS_OVV,
.end = AB8500_INT_VBUS_OVV,
.flags = IORESOURCE_IRQ,
},
{
.name = "USB_CH_TH_PROT_R",
.start = AB8500_INT_USB_CH_TH_PROT_R,
.end = AB8500_INT_USB_CH_TH_PROT_R,
.flags = IORESOURCE_IRQ,
},
{
.name = "USB_CH_TH_PROT_F",
.start = AB8500_INT_USB_CH_TH_PROT_F,
.end = AB8500_INT_USB_CH_TH_PROT_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "MAIN_EXT_CH_NOT_OK",
.start = AB8500_INT_MAIN_EXT_CH_NOT_OK,
.end = AB8500_INT_MAIN_EXT_CH_NOT_OK,
.flags = IORESOURCE_IRQ,
},
{
.name = "MAIN_CH_TH_PROT_R",
.start = AB8500_INT_MAIN_CH_TH_PROT_R,
.end = AB8500_INT_MAIN_CH_TH_PROT_R,
.flags = IORESOURCE_IRQ,
},
{
.name = "MAIN_CH_TH_PROT_F",
.start = AB8500_INT_MAIN_CH_TH_PROT_F,
.end = AB8500_INT_MAIN_CH_TH_PROT_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "USB_CHARGER_NOT_OKR",
.start = AB8500_INT_USB_CHARGER_NOT_OKR,
.end = AB8500_INT_USB_CHARGER_NOT_OKR,
.flags = IORESOURCE_IRQ,
},
{
.name = "CH_WD_EXP",
.start = AB8500_INT_CH_WD_EXP,
.end = AB8500_INT_CH_WD_EXP,
.flags = IORESOURCE_IRQ,
},
{
.name = "VBUS_CH_DROP_END",
.start = AB8500_INT_VBUS_CH_DROP_END,
.end = AB8500_INT_VBUS_CH_DROP_END,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8500_btemp_resources[] = {
{
.name = "BAT_CTRL_INDB",
.start = AB8500_INT_BAT_CTRL_INDB,
.end = AB8500_INT_BAT_CTRL_INDB,
.flags = IORESOURCE_IRQ,
},
{
.name = "BTEMP_LOW",
.start = AB8500_INT_BTEMP_LOW,
.end = AB8500_INT_BTEMP_LOW,
.flags = IORESOURCE_IRQ,
},
{
.name = "BTEMP_HIGH",
.start = AB8500_INT_BTEMP_HIGH,
.end = AB8500_INT_BTEMP_HIGH,
.flags = IORESOURCE_IRQ,
},
{
.name = "BTEMP_LOW_MEDIUM",
.start = AB8500_INT_BTEMP_LOW_MEDIUM,
.end = AB8500_INT_BTEMP_LOW_MEDIUM,
.flags = IORESOURCE_IRQ,
},
{
.name = "BTEMP_MEDIUM_HIGH",
.start = AB8500_INT_BTEMP_MEDIUM_HIGH,
.end = AB8500_INT_BTEMP_MEDIUM_HIGH,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8500_fg_resources[] = {
{
.name = "NCONV_ACCU",
.start = AB8500_INT_CCN_CONV_ACC,
.end = AB8500_INT_CCN_CONV_ACC,
.flags = IORESOURCE_IRQ,
},
{
.name = "BATT_OVV",
.start = AB8500_INT_BATT_OVV,
.end = AB8500_INT_BATT_OVV,
.flags = IORESOURCE_IRQ,
},
{
.name = "LOW_BAT_F",
.start = AB8500_INT_LOW_BAT_F,
.end = AB8500_INT_LOW_BAT_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "LOW_BAT_R",
.start = AB8500_INT_LOW_BAT_R,
.end = AB8500_INT_LOW_BAT_R,
.flags = IORESOURCE_IRQ,
},
{
.name = "CC_INT_CALIB",
.start = AB8500_INT_CC_INT_CALIB,
.end = AB8500_INT_CC_INT_CALIB,
.flags = IORESOURCE_IRQ,
},
{
.name = "CCEOC",
.start = AB8500_INT_CCEOC,
.end = AB8500_INT_CCEOC,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8500_chargalg_resources[] = {};
#ifdef CONFIG_DEBUG_FS
static struct resource ab8500_debug_resources[] = {
{
.name = "IRQ_AB8500",
/*
* Number will be filled in. NOTE: this is deliberately
* not flagged as an IRQ in ordet to avoid remapping using
* the irqdomain in the MFD core, so that this IRQ passes
* unremapped to the debug code.
*/
},
{
.name = "IRQ_FIRST",
.start = AB8500_INT_MAIN_EXT_CH_NOT_OK,
.end = AB8500_INT_MAIN_EXT_CH_NOT_OK,
.flags = IORESOURCE_IRQ,
},
{
.name = "IRQ_LAST",
.start = AB8500_INT_XTAL32K_KO,
.end = AB8500_INT_XTAL32K_KO,
.flags = IORESOURCE_IRQ,
},
};
#endif
static struct resource ab8500_usb_resources[] = {
{
.name = "ID_WAKEUP_R",
.start = AB8500_INT_ID_WAKEUP_R,
.end = AB8500_INT_ID_WAKEUP_R,
.flags = IORESOURCE_IRQ,
},
{
.name = "ID_WAKEUP_F",
.start = AB8500_INT_ID_WAKEUP_F,
.end = AB8500_INT_ID_WAKEUP_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "VBUS_DET_F",
.start = AB8500_INT_VBUS_DET_F,
.end = AB8500_INT_VBUS_DET_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "VBUS_DET_R",
.start = AB8500_INT_VBUS_DET_R,
.end = AB8500_INT_VBUS_DET_R,
.flags = IORESOURCE_IRQ,
},
{
.name = "USB_LINK_STATUS",
.start = AB8500_INT_USB_LINK_STATUS,
.end = AB8500_INT_USB_LINK_STATUS,
.flags = IORESOURCE_IRQ,
},
{
.name = "USB_ADP_PROBE_PLUG",
.start = AB8500_INT_ADP_PROBE_PLUG,
.end = AB8500_INT_ADP_PROBE_PLUG,
.flags = IORESOURCE_IRQ,
},
{
.name = "USB_ADP_PROBE_UNPLUG",
.start = AB8500_INT_ADP_PROBE_UNPLUG,
.end = AB8500_INT_ADP_PROBE_UNPLUG,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8505_iddet_resources[] = {
{
.name = "KeyDeglitch",
.start = AB8505_INT_KEYDEGLITCH,
.end = AB8505_INT_KEYDEGLITCH,
.flags = IORESOURCE_IRQ,
},
{
.name = "KP",
.start = AB8505_INT_KP,
.end = AB8505_INT_KP,
.flags = IORESOURCE_IRQ,
},
{
.name = "IKP",
.start = AB8505_INT_IKP,
.end = AB8505_INT_IKP,
.flags = IORESOURCE_IRQ,
},
{
.name = "IKR",
.start = AB8505_INT_IKR,
.end = AB8505_INT_IKR,
.flags = IORESOURCE_IRQ,
},
{
.name = "KeyStuck",
.start = AB8505_INT_KEYSTUCK,
.end = AB8505_INT_KEYSTUCK,
.flags = IORESOURCE_IRQ,
},
{
.name = "VBUS_DET_R",
.start = AB8500_INT_VBUS_DET_R,
.end = AB8500_INT_VBUS_DET_R,
.flags = IORESOURCE_IRQ,
},
{
.name = "VBUS_DET_F",
.start = AB8500_INT_VBUS_DET_F,
.end = AB8500_INT_VBUS_DET_F,
.flags = IORESOURCE_IRQ,
},
{
.name = "ID_DET_PLUGR",
.start = AB8500_INT_ID_DET_PLUGR,
.end = AB8500_INT_ID_DET_PLUGR,
.flags = IORESOURCE_IRQ,
},
{
.name = "ID_DET_PLUGF",
.start = AB8500_INT_ID_DET_PLUGF,
.end = AB8500_INT_ID_DET_PLUGF,
.flags = IORESOURCE_IRQ,
},
};
static struct resource ab8500_temp_resources[] = {
{
.name = "ABX500_TEMP_WARM",
.start = AB8500_INT_TEMP_WARM,
.end = AB8500_INT_TEMP_WARM,
.flags = IORESOURCE_IRQ,
},
};
static const struct mfd_cell ab8500_bm_devs[] = {
{
.name = "ab8500-charger",
.of_compatible = "stericsson,ab8500-charger",
.num_resources = ARRAY_SIZE(ab8500_charger_resources),
.resources = ab8500_charger_resources,
.platform_data = &ab8500_bm_data,
.pdata_size = sizeof(ab8500_bm_data),
},
{
.name = "ab8500-btemp",
.of_compatible = "stericsson,ab8500-btemp",
.num_resources = ARRAY_SIZE(ab8500_btemp_resources),
.resources = ab8500_btemp_resources,
.platform_data = &ab8500_bm_data,
.pdata_size = sizeof(ab8500_bm_data),
},
{
.name = "ab8500-fg",
.of_compatible = "stericsson,ab8500-fg",
.num_resources = ARRAY_SIZE(ab8500_fg_resources),
.resources = ab8500_fg_resources,
.platform_data = &ab8500_bm_data,
.pdata_size = sizeof(ab8500_bm_data),
},
{
.name = "ab8500-chargalg",
.of_compatible = "stericsson,ab8500-chargalg",
.num_resources = ARRAY_SIZE(ab8500_chargalg_resources),
.resources = ab8500_chargalg_resources,
.platform_data = &ab8500_bm_data,
.pdata_size = sizeof(ab8500_bm_data),
},
@ -1055,8 +637,6 @@ static const struct mfd_cell ab8500_devs[] = {
{
.name = "ab8500-debug",
.of_compatible = "stericsson,ab8500-debug",
.num_resources = ARRAY_SIZE(ab8500_debug_resources),
.resources = ab8500_debug_resources,
},
#endif
{
@ -1078,27 +658,19 @@ static const struct mfd_cell ab8500_devs[] = {
{
.name = "ab8500-gpadc",
.of_compatible = "stericsson,ab8500-gpadc",
.num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
.resources = ab8500_gpadc_resources,
},
{
.name = "ab8500-rtc",
.of_compatible = "stericsson,ab8500-rtc",
.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
.resources = ab8500_rtc_resources,
},
{
.name = "ab8500-acc-det",
.of_compatible = "stericsson,ab8500-acc-det",
.num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources),
.resources = ab8500_av_acc_detect_resources,
},
{
.name = "ab8500-poweron-key",
.of_compatible = "stericsson,ab8500-poweron-key",
.num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
.resources = ab8500_poweronkey_db_resources,
},
{
.name = "ab8500-pwm",
@ -1126,14 +698,10 @@ static const struct mfd_cell ab8500_devs[] = {
{
.name = "abx500-temp",
.of_compatible = "stericsson,abx500-temp",
.num_resources = ARRAY_SIZE(ab8500_temp_resources),
.resources = ab8500_temp_resources,
},
{
.name = "ab8500-usb",
.of_compatible = "stericsson,ab8500-usb",
.num_resources = ARRAY_SIZE(ab8500_usb_resources),
.resources = ab8500_usb_resources,
},
{
.name = "ab8500-codec",
@ -1145,8 +713,6 @@ static const struct mfd_cell ab9540_devs[] = {
#ifdef CONFIG_DEBUG_FS
{
.name = "ab8500-debug",
.num_resources = ARRAY_SIZE(ab8500_debug_resources),
.resources = ab8500_debug_resources,
},
#endif
{
@ -1165,23 +731,15 @@ static const struct mfd_cell ab9540_devs[] = {
{
.name = "ab8500-gpadc",
.of_compatible = "stericsson,ab8500-gpadc",
.num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
.resources = ab8500_gpadc_resources,
},
{
.name = "ab8500-rtc",
.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
.resources = ab8500_rtc_resources,
},
{
.name = "ab8500-acc-det",
.num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources),
.resources = ab8500_av_acc_detect_resources,
},
{
.name = "ab8500-poweron-key",
.num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
.resources = ab8500_poweronkey_db_resources,
},
{
.name = "ab8500-pwm",
@ -1189,8 +747,6 @@ static const struct mfd_cell ab9540_devs[] = {
},
{
.name = "abx500-temp",
.num_resources = ARRAY_SIZE(ab8500_temp_resources),
.resources = ab8500_temp_resources,
},
{
.name = "pinctrl-ab9540",
@ -1198,16 +754,12 @@ static const struct mfd_cell ab9540_devs[] = {
},
{
.name = "ab9540-usb",
.num_resources = ARRAY_SIZE(ab8500_usb_resources),
.resources = ab8500_usb_resources,
},
{
.name = "ab9540-codec",
},
{
.name = "ab-iddet",
.num_resources = ARRAY_SIZE(ab8505_iddet_resources),
.resources = ab8505_iddet_resources,
},
};
@ -1216,8 +768,6 @@ static const struct mfd_cell ab8505_devs[] = {
#ifdef CONFIG_DEBUG_FS
{
.name = "ab8500-debug",
.num_resources = ARRAY_SIZE(ab8500_debug_resources),
.resources = ab8500_debug_resources,
},
#endif
{
@ -1233,23 +783,15 @@ static const struct mfd_cell ab8505_devs[] = {
{
.name = "ab8500-gpadc",
.of_compatible = "stericsson,ab8500-gpadc",
.num_resources = ARRAY_SIZE(ab8505_gpadc_resources),
.resources = ab8505_gpadc_resources,
},
{
.name = "ab8500-rtc",
.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
.resources = ab8500_rtc_resources,
},
{
.name = "ab8500-acc-det",
.num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources),
.resources = ab8500_av_acc_detect_resources,
},
{
.name = "ab8500-poweron-key",
.num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
.resources = ab8500_poweronkey_db_resources,
},
{
.name = "ab8500-pwm",
@ -1260,16 +802,12 @@ static const struct mfd_cell ab8505_devs[] = {
},
{
.name = "ab8500-usb",
.num_resources = ARRAY_SIZE(ab8500_usb_resources),
.resources = ab8500_usb_resources,
},
{
.name = "ab8500-codec",
},
{
.name = "ab-iddet",
.num_resources = ARRAY_SIZE(ab8505_iddet_resources),
.resources = ab8505_iddet_resources,
},
};
@ -1277,8 +815,6 @@ static const struct mfd_cell ab8540_devs[] = {
#ifdef CONFIG_DEBUG_FS
{
.name = "ab8500-debug",
.num_resources = ARRAY_SIZE(ab8500_debug_resources),
.resources = ab8500_debug_resources,
},
#endif
{
@ -1297,18 +833,12 @@ static const struct mfd_cell ab8540_devs[] = {
{
.name = "ab8500-gpadc",
.of_compatible = "stericsson,ab8500-gpadc",
.num_resources = ARRAY_SIZE(ab8505_gpadc_resources),
.resources = ab8505_gpadc_resources,
},
{
.name = "ab8500-acc-det",
.num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources),
.resources = ab8500_av_acc_detect_resources,
},
{
.name = "ab8500-poweron-key",
.num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources),
.resources = ab8500_poweronkey_db_resources,
},
{
.name = "ab8500-pwm",
@ -1316,24 +846,18 @@ static const struct mfd_cell ab8540_devs[] = {
},
{
.name = "abx500-temp",
.num_resources = ARRAY_SIZE(ab8500_temp_resources),
.resources = ab8500_temp_resources,
},
{
.name = "pinctrl-ab8540",
},
{
.name = "ab8540-usb",
.num_resources = ARRAY_SIZE(ab8500_usb_resources),
.resources = ab8500_usb_resources,
},
{
.name = "ab8540-codec",
},
{
.name = "ab-iddet",
.num_resources = ARRAY_SIZE(ab8505_iddet_resources),
.resources = ab8505_iddet_resources,
},
};
@ -1341,8 +865,6 @@ static const struct mfd_cell ab8540_cut1_devs[] = {
{
.name = "ab8500-rtc",
.of_compatible = "stericsson,ab8500-rtc",
.num_resources = ARRAY_SIZE(ab8500_rtc_resources),
.resources = ab8500_rtc_resources,
},
};
@ -1350,8 +872,6 @@ static const struct mfd_cell ab8540_cut2_devs[] = {
{
.name = "ab8540-rtc",
.of_compatible = "stericsson,ab8540-rtc",
.num_resources = ARRAY_SIZE(ab8540_rtc_resources),
.resources = ab8540_rtc_resources,
},
};
@ -1549,7 +1069,7 @@ static struct attribute_group ab9540_attr_group = {
static int ab8500_probe(struct platform_device *pdev)
{
static const char *switch_off_status[] = {
static const char * const switch_off_status[] = {
"Swoff bit programming",
"Thermal protection activation",
"Vbat lower then BattOk falling threshold",
@ -1558,7 +1078,7 @@ static int ab8500_probe(struct platform_device *pdev)
"Battery level lower than power on reset threshold",
"Power on key 1 pressed longer than 10 seconds",
"DB8500 thermal shutdown"};
static const char *turn_on_status[] = {
static const char * const turn_on_status[] = {
"Battery rising (Vbat)",
"Power On Key 1 dbF",
"Power On Key 2 dbF",
@ -1750,12 +1270,6 @@ static int ab8500_probe(struct platform_device *pdev)
if (ret)
return ret;
#ifdef CONFIG_DEBUG_FS
/* Pass to debugfs */
ab8500_debug_resources[0].start = ab8500->irq;
ab8500_debug_resources[0].end = ab8500->irq;
#endif
if (is_ab9540(ab8500))
ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
ARRAY_SIZE(ab9540_devs), NULL,

View file

@ -242,8 +242,10 @@ static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
.first = 0x40,
.last = 0x44,
},
/* 0x80-0x8B is SIM registers and should
* not be accessed from here */
/*
* 0x80-0x8B are SIM registers and should
* not be accessed from here
*/
},
},
[AB8500_USB] = {
@ -587,8 +589,10 @@ static struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = {
.first = 0x40,
.last = 0x48,
},
/* 0x80-0x8B is SIM registers and should
* not be accessed from here */
/*
* 0x80-0x8B are SIM registers and should
* not be accessed from here
*/
},
},
[AB8500_USB] = {
@ -1306,8 +1310,10 @@ static int ab8500_registers_print(struct device *dev, u32 bank,
if (s) {
seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n",
bank, reg, value);
/* Error is not returned here since
* the output is wanted in any case */
/*
* Error is not returned here since
* the output is wanted in any case
*/
if (seq_has_overflowed(s))
return 0;
} else {
@ -2740,10 +2746,9 @@ static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg,
*cfg = loc;
#ifdef ABB_HWREG_DEBUG
pr_warn("HWREG request: %s, %s,\n"
" addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n",
(write) ? "write" : "read",
REG_FMT_DEC(cfg) ? "decimal" : "hexa",
pr_warn("HWREG request: %s, %s,\n", (write) ? "write" : "read",
REG_FMT_DEC(cfg) ? "decimal" : "hexa");
pr_warn(" addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n",
cfg->addr, cfg->mask, cfg->shift, val);
#endif

View file

@ -49,61 +49,61 @@
* OTP register offsets
* Bank : 0x15
*/
#define AB8500_GPADC_CAL_1 0x0F
#define AB8500_GPADC_CAL_2 0x10
#define AB8500_GPADC_CAL_3 0x11
#define AB8500_GPADC_CAL_4 0x12
#define AB8500_GPADC_CAL_5 0x13
#define AB8500_GPADC_CAL_6 0x14
#define AB8500_GPADC_CAL_7 0x15
#define AB8500_GPADC_CAL_1 0x0F
#define AB8500_GPADC_CAL_2 0x10
#define AB8500_GPADC_CAL_3 0x11
#define AB8500_GPADC_CAL_4 0x12
#define AB8500_GPADC_CAL_5 0x13
#define AB8500_GPADC_CAL_6 0x14
#define AB8500_GPADC_CAL_7 0x15
/* New calibration for 8540 */
#define AB8540_GPADC_OTP4_REG_7 0x38
#define AB8540_GPADC_OTP4_REG_6 0x39
#define AB8540_GPADC_OTP4_REG_5 0x3A
/* gpadc constants */
#define EN_VINTCORE12 0x04
#define EN_VTVOUT 0x02
#define EN_GPADC 0x01
#define DIS_GPADC 0x00
#define AVG_1 0x00
#define AVG_4 0x20
#define AVG_8 0x40
#define AVG_16 0x60
#define ADC_SW_CONV 0x04
#define EN_ICHAR 0x80
#define BTEMP_PULL_UP 0x08
#define EN_BUF 0x40
#define DIS_ZERO 0x00
#define GPADC_BUSY 0x01
#define EN_FALLING 0x10
#define EN_TRIG_EDGE 0x02
#define EN_VBIAS_XTAL_TEMP 0x02
#define EN_VINTCORE12 0x04
#define EN_VTVOUT 0x02
#define EN_GPADC 0x01
#define DIS_GPADC 0x00
#define AVG_1 0x00
#define AVG_4 0x20
#define AVG_8 0x40
#define AVG_16 0x60
#define ADC_SW_CONV 0x04
#define EN_ICHAR 0x80
#define BTEMP_PULL_UP 0x08
#define EN_BUF 0x40
#define DIS_ZERO 0x00
#define GPADC_BUSY 0x01
#define EN_FALLING 0x10
#define EN_TRIG_EDGE 0x02
#define EN_VBIAS_XTAL_TEMP 0x02
/* GPADC constants from AB8500 spec, UM0836 */
#define ADC_RESOLUTION 1024
#define ADC_CH_BTEMP_MIN 0
#define ADC_CH_BTEMP_MAX 1350
#define ADC_CH_DIETEMP_MIN 0
#define ADC_CH_DIETEMP_MAX 1350
#define ADC_CH_CHG_V_MIN 0
#define ADC_CH_CHG_V_MAX 20030
#define ADC_CH_ACCDET2_MIN 0
#define ADC_CH_ACCDET2_MAX 2500
#define ADC_CH_VBAT_MIN 2300
#define ADC_CH_VBAT_MAX 4800
#define ADC_CH_CHG_I_MIN 0
#define ADC_CH_CHG_I_MAX 1500
#define ADC_CH_BKBAT_MIN 0
#define ADC_CH_BKBAT_MAX 3200
#define ADC_RESOLUTION 1024
#define ADC_CH_BTEMP_MIN 0
#define ADC_CH_BTEMP_MAX 1350
#define ADC_CH_DIETEMP_MIN 0
#define ADC_CH_DIETEMP_MAX 1350
#define ADC_CH_CHG_V_MIN 0
#define ADC_CH_CHG_V_MAX 20030
#define ADC_CH_ACCDET2_MIN 0
#define ADC_CH_ACCDET2_MAX 2500
#define ADC_CH_VBAT_MIN 2300
#define ADC_CH_VBAT_MAX 4800
#define ADC_CH_CHG_I_MIN 0
#define ADC_CH_CHG_I_MAX 1500
#define ADC_CH_BKBAT_MIN 0
#define ADC_CH_BKBAT_MAX 3200
/* GPADC constants from AB8540 spec */
#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat*/
#define ADC_CH_IBAT_MAX 6000
#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat*/
#define ADC_CH_IBAT_MAX_V 60
#define IBAT_VDROP_L (-56) /* mV */
#define IBAT_VDROP_H 56
#define ADC_CH_IBAT_MIN (-6000) /* mA range measured by ADC for ibat */
#define ADC_CH_IBAT_MAX 6000
#define ADC_CH_IBAT_MIN_V (-60) /* mV range measured by ADC for ibat */
#define ADC_CH_IBAT_MAX_V 60
#define IBAT_VDROP_L (-56) /* mV */
#define IBAT_VDROP_H 56
/* This is used to not lose precision when dividing to get gain and offset */
#define CALIB_SCALE 1000
@ -179,7 +179,7 @@ struct ab8500_gpadc *ab8500_gpadc_get(char *name)
list_for_each_entry(gpadc, &ab8500_gpadc_list, node) {
if (!strcmp(name, dev_name(gpadc->dev)))
return gpadc;
return gpadc;
}
return ERR_PTR(-ENOENT);
@ -315,11 +315,12 @@ int ab8500_gpadc_sw_hw_convert(struct ab8500_gpadc *gpadc, u8 channel,
ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample,
trig_edge, trig_timer, conv_type);
/* On failure retry a second time */
/* On failure retry a second time */
if (ad_value < 0)
ad_value = ab8500_gpadc_read_raw(gpadc, channel, avg_sample,
trig_edge, trig_timer, conv_type);
if (ad_value < 0) {
if (ad_value < 0) {
dev_err(gpadc->dev, "GPADC raw value failed ch: %d\n",
channel);
return ad_value;
@ -327,8 +328,9 @@ if (ad_value < 0) {
voltage = ab8500_gpadc_ad_to_voltage(gpadc, channel, ad_value);
if (voltage < 0)
dev_err(gpadc->dev, "GPADC to voltage conversion failed ch:"
" %d AD: 0x%x\n", channel, ad_value);
dev_err(gpadc->dev,
"GPADC to voltage conversion failed ch: %d AD: 0x%x\n",
channel, ad_value);
return voltage;
}
@ -348,10 +350,9 @@ EXPORT_SYMBOL(ab8500_gpadc_sw_hw_convert);
int ab8500_gpadc_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
u8 avg_sample, u8 trig_edge, u8 trig_timer, u8 conv_type)
{
int raw_data;
raw_data = ab8500_gpadc_double_read_raw(gpadc, channel,
avg_sample, trig_edge, trig_timer, conv_type, NULL);
return raw_data;
return ab8500_gpadc_double_read_raw(gpadc, channel, avg_sample,
trig_edge, trig_timer, conv_type,
NULL);
}
int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
@ -388,7 +389,7 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
goto out;
if (!(val & GPADC_BUSY))
break;
msleep(10);
msleep(20);
} while (++looplimit < 10);
if (looplimit >= 10 && (val & GPADC_BUSY)) {
dev_err(gpadc->dev, "gpadc_conversion: GPADC busy");
@ -421,8 +422,7 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
val_reg1 |= EN_TRIG_EDGE;
if (trig_edge)
val_reg1 |= EN_FALLING;
}
else
} else
ret = abx500_set_register_interruptible(gpadc->dev,
AB8500_GPADC, AB8500_GPADC_CTRL2_REG, val);
if (ret < 0) {
@ -449,7 +449,7 @@ int ab8500_gpadc_double_read_raw(struct ab8500_gpadc *gpadc, u8 channel,
* remove when hardware will be availible
*/
delay_min = 1000; /* Delay in micro seconds */
delay_max = 10000; /* large range to optimise sleep mode */
delay_max = 10000; /* large range optimises sleepmode */
break;
}
/* Intentional fallthrough */
@ -785,9 +785,10 @@ static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
<< CALIB_SHIFT_IBAT)
/ (ADC_CH_IBAT_MAX_V - ADC_CH_IBAT_MIN_V);
gpadc->cal_data[ADC_INPUT_IBAT].gain = V_gain * V2A_gain;
gpadc->cal_data[ADC_INPUT_IBAT].offset = V_offset *
V2A_gain + V2A_offset;
gpadc->cal_data[ADC_INPUT_IBAT].gain =
V_gain * V2A_gain;
gpadc->cal_data[ADC_INPUT_IBAT].offset =
V_offset * V2A_gain + V2A_offset;
} else {
gpadc->cal_data[ADC_INPUT_IBAT].gain = 0;
}
@ -923,11 +924,10 @@ static int ab8500_gpadc_probe(struct platform_device *pdev)
int ret = 0;
struct ab8500_gpadc *gpadc;
gpadc = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_gpadc), GFP_KERNEL);
if (!gpadc) {
dev_err(&pdev->dev, "Error: No memory\n");
gpadc = devm_kzalloc(&pdev->dev,
sizeof(struct ab8500_gpadc), GFP_KERNEL);
if (!gpadc)
return -ENOMEM;
}
gpadc->irq_sw = platform_get_irq_byname(pdev, "SW_CONV_END");
if (gpadc->irq_sw < 0)
@ -1072,18 +1072,19 @@ void ab8540_gpadc_get_otp(struct ab8500_gpadc *gpadc,
*vmain_h = gpadc->cal_data[ADC_INPUT_VMAIN].otp_calib_hi;
*btemp_l = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_lo;
*btemp_h = gpadc->cal_data[ADC_INPUT_BTEMP].otp_calib_hi;
*vbat_l = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo;
*vbat_h = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi;
*ibat_l = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo;
*ibat_h = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi;
return ;
*vbat_l = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_lo;
*vbat_h = gpadc->cal_data[ADC_INPUT_VBAT].otp_calib_hi;
*ibat_l = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_lo;
*ibat_h = gpadc->cal_data[ADC_INPUT_IBAT].otp_calib_hi;
}
subsys_initcall_sync(ab8500_gpadc_init);
module_exit(ab8500_gpadc_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson,"
"M'boumba Cedric Madianga");
MODULE_AUTHOR("Arun R Murthy");
MODULE_AUTHOR("Daniel Willerud");
MODULE_AUTHOR("Johan Palsson");
MODULE_AUTHOR("M'boumba Cedric Madianga");
MODULE_ALIAS("platform:ab8500_gpadc");
MODULE_DESCRIPTION("AB8500 GPADC driver");

View file

@ -27,7 +27,7 @@ static void ab8500_power_off(void)
{
sigset_t old;
sigset_t all;
static char *pss[] = {"ab8500_ac", "pm2301", "ab8500_usb"};
static const char * const pss[] = {"ab8500_ac", "pm2301", "ab8500_usb"};
int i;
bool charger_present = false;
union power_supply_propval val;
@ -68,10 +68,9 @@ static void ab8500_power_off(void)
ret = power_supply_get_property(psy,
POWER_SUPPLY_PROP_TECHNOLOGY, &val);
if (!ret && val.intval != POWER_SUPPLY_TECHNOLOGY_UNKNOWN) {
printk(KERN_INFO
"Charger \"%s\" is connected with known battery."
" Rebooting.\n",
pss[i]);
pr_info("Charger '%s' is connected with known battery",
pss[i]);
pr_info(" - Rebooting.\n");
machine_restart("charging");
}
power_supply_put(psy);
@ -161,8 +160,8 @@ static int ab8500_sysctrl_probe(struct platform_device *pdev)
pdata->initial_req_buf_config[j]);
if (ret < 0) {
dev_err(&pdev->dev,
"unable to set sysClkReq%dRfClkBuf: "
"%d\n", j + 1, ret);
"Can't set sysClkReq%dRfClkBuf: %d\n",
j + 1, ret);
}
}
}

View file

@ -9,10 +9,10 @@
*
* Derived from da903x:
* Copyright (C) 2008 Compulab, Ltd.
* Mike Rapoport <mike@compulab.co.il>
* Mike Rapoport <mike@compulab.co.il>
*
* Copyright (C) 2006-2008 Marvell International Ltd.
* Eric Miao <eric.miao@marvell.com>
* Eric Miao <eric.miao@marvell.com>
*
* Licensed under the GPL-2 or later.
*/
@ -355,7 +355,7 @@ static struct i2c_driver adp5520_driver = {
},
.probe = adp5520_probe,
.remove = adp5520_remove,
.id_table = adp5520_id,
.id_table = adp5520_id,
};
module_i2c_driver(adp5520_driver);

View file

@ -238,7 +238,7 @@ static int arizona_poll_reg(struct arizona *arizona,
if ((val & mask) == target)
return 0;
msleep(1);
usleep_range(1000, 5000);
}
dev_err(arizona->dev, "Polling reg %u timed out: %x\n", reg, val);
@ -279,14 +279,14 @@ static void arizona_disable_reset(struct arizona *arizona)
case WM5110:
case WM8280:
/* Meet requirements for minimum reset duration */
msleep(5);
usleep_range(5000, 10000);
break;
default:
break;
}
gpio_set_value_cansleep(arizona->pdata.reset, 1);
msleep(1);
usleep_range(1000, 5000);
}
}
@ -598,6 +598,12 @@ static int arizona_runtime_resume(struct device *dev)
goto err;
}
break;
case WM1831:
case CS47L24:
ret = arizona_wait_for_boot(arizona);
if (ret != 0)
goto err;
break;
default:
ret = arizona_wait_for_boot(arizona);
if (ret != 0)
@ -682,6 +688,9 @@ static int arizona_runtime_suspend(struct device *dev)
}
}
break;
case WM1831:
case CS47L24:
break;
default:
jd_active = arizona_is_jack_det_active(arizona);
if (jd_active < 0)
@ -852,6 +861,16 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
count++;
}
count = 0;
of_property_for_each_u32(arizona->dev->of_node, "wlf,out-mono", prop,
cur, val) {
if (count == ARRAY_SIZE(pdata->out_mono))
break;
pdata->out_mono[count] = !!val;
count++;
}
return 0;
}
@ -862,6 +881,8 @@ const struct of_device_id arizona_of_match[] = {
{ .compatible = "wlf,wm8997", .data = (void *)WM8997 },
{ .compatible = "wlf,wm8998", .data = (void *)WM8998 },
{ .compatible = "wlf,wm1814", .data = (void *)WM1814 },
{ .compatible = "wlf,wm1831", .data = (void *)WM1831 },
{ .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 },
{},
};
EXPORT_SYMBOL_GPL(arizona_of_match);
@ -919,6 +940,23 @@ static const struct mfd_cell wm5110_devs[] = {
},
};
static const char * const cs47l24_supplies[] = {
"MICVDD",
"CPVDD",
"SPKVDD",
};
static const struct mfd_cell cs47l24_devs[] = {
{ .name = "arizona-gpio" },
{ .name = "arizona-haptics" },
{ .name = "arizona-pwm" },
{
.name = "cs47l24-codec",
.parent_supplies = cs47l24_supplies,
.num_parent_supplies = ARRAY_SIZE(cs47l24_supplies),
},
};
static const char * const wm8997_supplies[] = {
"MICVDD",
"DBVDD2",
@ -963,7 +1001,7 @@ static const struct mfd_cell wm8998_devs[] = {
int arizona_dev_init(struct arizona *arizona)
{
struct device *dev = arizona->dev;
const char *type_name;
const char *type_name = NULL;
unsigned int reg, val, mask;
int (*apply_patch)(struct arizona *) = NULL;
const struct mfd_cell *subdevs = NULL;
@ -987,6 +1025,8 @@ int arizona_dev_init(struct arizona *arizona)
case WM8997:
case WM8998:
case WM1814:
case WM1831:
case CS47L24:
for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
arizona->core_supplies[i].supply
= wm5102_core_supplies[i];
@ -1001,11 +1041,18 @@ int arizona_dev_init(struct arizona *arizona)
/* Mark DCVDD as external, LDO1 driver will clear if internal */
arizona->external_dcvdd = true;
ret = mfd_add_devices(arizona->dev, -1, early_devs,
ARRAY_SIZE(early_devs), NULL, 0, NULL);
if (ret != 0) {
dev_err(dev, "Failed to add early children: %d\n", ret);
return ret;
switch (arizona->type) {
case WM1831:
case CS47L24:
break; /* No LDO1 regulator */
default:
ret = mfd_add_devices(arizona->dev, -1, early_devs,
ARRAY_SIZE(early_devs), NULL, 0, NULL);
if (ret != 0) {
dev_err(dev, "Failed to add early children: %d\n", ret);
return ret;
}
break;
}
ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies,
@ -1069,6 +1116,7 @@ int arizona_dev_init(struct arizona *arizona)
case 0x5102:
case 0x5110:
case 0x6349:
case 0x6363:
case 0x8997:
break;
default:
@ -1084,7 +1132,7 @@ int arizona_dev_init(struct arizona *arizona)
goto err_reset;
}
msleep(1);
usleep_range(1000, 5000);
}
/* Ensure device startup is complete */
@ -1167,6 +1215,30 @@ int arizona_dev_init(struct arizona *arizona)
n_subdevs = ARRAY_SIZE(wm5110_devs);
}
break;
case 0x6363:
if (IS_ENABLED(CONFIG_MFD_CS47L24)) {
switch (arizona->type) {
case CS47L24:
type_name = "CS47L24";
break;
case WM1831:
type_name = "WM1831";
break;
default:
dev_warn(arizona->dev,
"CS47L24 registered as %d\n",
arizona->type);
arizona->type = CS47L24;
break;
}
apply_patch = cs47l24_patch;
subdevs = cs47l24_devs;
n_subdevs = ARRAY_SIZE(cs47l24_devs);
}
break;
case 0x8997:
if (IS_ENABLED(CONFIG_MFD_WM8997)) {
type_name = "WM8997";

View file

@ -88,7 +88,9 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
static int arizona_i2c_remove(struct i2c_client *i2c)
{
struct arizona *arizona = dev_get_drvdata(&i2c->dev);
arizona_dev_exit(arizona);
return 0;
}

View file

@ -30,11 +30,13 @@ static int arizona_map_irq(struct arizona *arizona, int irq)
{
int ret;
ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq);
if (ret < 0)
ret = regmap_irq_get_virq(arizona->irq_chip, irq);
if (arizona->aod_irq_chip) {
ret = regmap_irq_get_virq(arizona->aod_irq_chip, irq);
if (ret >= 0)
return ret;
}
return ret;
return regmap_irq_get_virq(arizona->irq_chip, irq);
}
int arizona_request_irq(struct arizona *arizona, int irq, char *name,
@ -107,8 +109,8 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
do {
poll = false;
/* Always handle the AoD domain */
handle_nested_irq(irq_find_mapping(arizona->virq, 0));
if (arizona->aod_irq_chip)
handle_nested_irq(irq_find_mapping(arizona->virq, 0));
/*
* Check if one of the main interrupts is asserted and only
@ -219,6 +221,15 @@ int arizona_irq_init(struct arizona *arizona)
arizona->ctrlif_error = false;
break;
#endif
#ifdef CONFIG_MFD_CS47L24
case WM1831:
case CS47L24:
aod = NULL;
irq = &cs47l24_irq;
arizona->ctrlif_error = false;
break;
#endif
#ifdef CONFIG_MFD_WM8997
case WM8997:
aod = &wm8997_aod;
@ -291,13 +302,16 @@ int arizona_irq_init(struct arizona *arizona)
goto err;
}
ret = regmap_add_irq_chip(arizona->regmap,
irq_create_mapping(arizona->virq, 0),
IRQF_ONESHOT, 0, aod,
&arizona->aod_irq_chip);
if (ret != 0) {
dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret);
goto err_domain;
if (aod) {
ret = regmap_add_irq_chip(arizona->regmap,
irq_create_mapping(arizona->virq, 0),
IRQF_ONESHOT, 0, aod,
&arizona->aod_irq_chip);
if (ret != 0) {
dev_err(arizona->dev,
"Failed to add AOD IRQs: %d\n", ret);
goto err;
}
}
ret = regmap_add_irq_chip(arizona->regmap,
@ -309,30 +323,6 @@ int arizona_irq_init(struct arizona *arizona)
goto err_aod;
}
/* Make sure the boot done IRQ is unmasked for resumes */
i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE);
ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT,
"Boot done", arizona);
if (ret != 0) {
dev_err(arizona->dev, "Failed to request boot done %d: %d\n",
arizona->irq, ret);
goto err_boot_done;
}
/* Handle control interface errors in the core */
if (arizona->ctrlif_error) {
i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
ret = request_threaded_irq(i, NULL, arizona_ctrlif_err,
IRQF_ONESHOT,
"Control interface error", arizona);
if (ret != 0) {
dev_err(arizona->dev,
"Failed to request CTRLIF_ERR %d: %d\n",
arizona->irq, ret);
goto err_ctrlif;
}
}
/* Used to emulate edge trigger and to work around broken pinmux */
if (arizona->pdata.irq_gpio) {
if (gpio_to_irq(arizona->pdata.irq_gpio) != arizona->irq) {
@ -362,21 +352,42 @@ int arizona_irq_init(struct arizona *arizona)
goto err_main_irq;
}
/* Make sure the boot done IRQ is unmasked for resumes */
i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE);
ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT,
"Boot done", arizona);
if (ret != 0) {
dev_err(arizona->dev, "Failed to request boot done %d: %d\n",
arizona->irq, ret);
goto err_boot_done;
}
/* Handle control interface errors in the core */
if (arizona->ctrlif_error) {
i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
ret = request_threaded_irq(i, NULL, arizona_ctrlif_err,
IRQF_ONESHOT,
"Control interface error", arizona);
if (ret != 0) {
dev_err(arizona->dev,
"Failed to request CTRLIF_ERR %d: %d\n",
arizona->irq, ret);
goto err_ctrlif;
}
}
return 0;
err_main_irq:
if (arizona->ctrlif_error)
free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR),
arizona);
err_ctrlif:
free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona);
err_boot_done:
free_irq(arizona->irq, arizona);
err_main_irq:
regmap_del_irq_chip(irq_create_mapping(arizona->virq, 1),
arizona->irq_chip);
err_aod:
regmap_del_irq_chip(irq_create_mapping(arizona->virq, 0),
arizona->aod_irq_chip);
err_domain:
err:
return ret;
}

View file

@ -46,6 +46,11 @@ static int arizona_spi_probe(struct spi_device *spi)
if (IS_ENABLED(CONFIG_MFD_WM5110))
regmap_config = &wm5110_spi_regmap;
break;
case WM1831:
case CS47L24:
if (IS_ENABLED(CONFIG_MFD_CS47L24))
regmap_config = &cs47l24_spi_regmap;
break;
default:
dev_err(&spi->dev, "Unknown device type %ld\n", type);
return -EINVAL;
@ -89,6 +94,8 @@ static const struct spi_device_id arizona_spi_ids[] = {
{ "wm5102", WM5102 },
{ "wm5110", WM5110 },
{ "wm8280", WM8280 },
{ "wm1831", WM1831 },
{ "cs47l24", CS47L24 },
{ },
};
MODULE_DEVICE_TABLE(spi, arizona_spi_ids);

View file

@ -25,6 +25,8 @@ extern const struct regmap_config wm5102_spi_regmap;
extern const struct regmap_config wm5110_i2c_regmap;
extern const struct regmap_config wm5110_spi_regmap;
extern const struct regmap_config cs47l24_spi_regmap;
extern const struct regmap_config wm8997_i2c_regmap;
extern const struct regmap_config wm8998_i2c_regmap;
@ -40,6 +42,8 @@ extern const struct regmap_irq_chip wm5110_aod;
extern const struct regmap_irq_chip wm5110_irq;
extern const struct regmap_irq_chip wm5110_revd_irq;
extern const struct regmap_irq_chip cs47l24_irq;
extern const struct regmap_irq_chip wm8997_aod;
extern const struct regmap_irq_chip wm8997_irq;

View file

@ -136,17 +136,13 @@ static int as3711_i2c_probe(struct i2c_client *client,
} else {
pdata = devm_kzalloc(&client->dev,
sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
dev_err(&client->dev, "Failed to allocate pdata\n");
if (!pdata)
return -ENOMEM;
}
}
as3711 = devm_kzalloc(&client->dev, sizeof(struct as3711), GFP_KERNEL);
if (!as3711) {
dev_err(&client->dev, "Memory allocation failed\n");
if (!as3711)
return -ENOMEM;
}
as3711->dev = &client->dev;
i2c_set_clientdata(client, as3711);
@ -157,7 +153,8 @@ static int as3711_i2c_probe(struct i2c_client *client,
as3711->regmap = devm_regmap_init_i2c(client, &as3711_regmap_config);
if (IS_ERR(as3711->regmap)) {
ret = PTR_ERR(as3711->regmap);
dev_err(&client->dev, "regmap initialization failed: %d\n", ret);
dev_err(&client->dev,
"regmap initialization failed: %d\n", ret);
return ret;
}
@ -172,12 +169,19 @@ static int as3711_i2c_probe(struct i2c_client *client,
return -ENODEV;
dev_info(as3711->dev, "AS3711 detected: %x:%x\n", id1, id2);
/* We can reuse as3711_subdevs[], it will be copied in mfd_add_devices() */
/*
* We can reuse as3711_subdevs[],
* it will be copied in mfd_add_devices()
*/
if (pdata) {
as3711_subdevs[AS3711_REGULATOR].platform_data = &pdata->regulator;
as3711_subdevs[AS3711_REGULATOR].pdata_size = sizeof(pdata->regulator);
as3711_subdevs[AS3711_BACKLIGHT].platform_data = &pdata->backlight;
as3711_subdevs[AS3711_BACKLIGHT].pdata_size = sizeof(pdata->backlight);
as3711_subdevs[AS3711_REGULATOR].platform_data =
&pdata->regulator;
as3711_subdevs[AS3711_REGULATOR].pdata_size =
sizeof(pdata->regulator);
as3711_subdevs[AS3711_BACKLIGHT].platform_data =
&pdata->backlight;
as3711_subdevs[AS3711_BACKLIGHT].pdata_size =
sizeof(pdata->backlight);
} else {
as3711_subdevs[AS3711_REGULATOR].platform_data = NULL;
as3711_subdevs[AS3711_REGULATOR].pdata_size = 0;

View file

@ -405,6 +405,8 @@ static int as3722_i2c_probe(struct i2c_client *i2c,
goto scrub;
}
device_init_wakeup(as3722->dev, true);
dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n");
return 0;
@ -422,6 +424,29 @@ static int as3722_i2c_remove(struct i2c_client *i2c)
return 0;
}
static int __maybe_unused as3722_i2c_suspend(struct device *dev)
{
struct as3722 *as3722 = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
enable_irq_wake(as3722->chip_irq);
disable_irq(as3722->chip_irq);
return 0;
}
static int __maybe_unused as3722_i2c_resume(struct device *dev)
{
struct as3722 *as3722 = dev_get_drvdata(dev);
enable_irq(as3722->chip_irq);
if (device_may_wakeup(dev))
disable_irq_wake(as3722->chip_irq);
return 0;
}
static const struct of_device_id as3722_of_match[] = {
{ .compatible = "ams,as3722", },
{},
@ -434,10 +459,15 @@ static const struct i2c_device_id as3722_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, as3722_i2c_id);
static const struct dev_pm_ops as3722_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(as3722_i2c_suspend, as3722_i2c_resume)
};
static struct i2c_driver as3722_i2c_driver = {
.driver = {
.name = "as3722",
.of_match_table = as3722_of_match,
.pm = &as3722_pm_ops,
},
.probe = as3722_i2c_probe,
.remove = as3722_i2c_remove,

View file

@ -167,7 +167,6 @@ static void asic3_irq_demux(struct irq_desc *desc)
base = ASIC3_GPIO_A_BASE
+ bank * ASIC3_GPIO_BASE_INCR;
spin_lock_irqsave(&asic->lock, flags);
istat = asic3_read_register(asic,
base +
@ -502,7 +501,8 @@ static int asic3_gpio_get(struct gpio_chip *chip,
return -EINVAL;
}
return asic3_read_register(asic, gpio_base + ASIC3_GPIO_STATUS) & mask;
return !!(asic3_read_register(asic,
gpio_base + ASIC3_GPIO_STATUS) & mask);
}
static void asic3_gpio_set(struct gpio_chip *chip,
@ -536,8 +536,6 @@ static void asic3_gpio_set(struct gpio_chip *chip,
asic3_write_register(asic, gpio_base + ASIC3_GPIO_OUT, out_reg);
spin_unlock_irqrestore(&asic->lock, flags);
return;
}
static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
@ -665,18 +663,18 @@ static int ds1wm_enable(struct platform_device *pdev)
asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX0]);
asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]);
asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_OWM]);
msleep(1);
usleep_range(1000, 5000);
/* Reset and enable DS1WM */
asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET),
ASIC3_EXTCF_OWM_RESET, 1);
msleep(1);
usleep_range(1000, 5000);
asic3_set_register(asic, ASIC3_OFFSET(EXTCF, RESET),
ASIC3_EXTCF_OWM_RESET, 0);
msleep(1);
usleep_range(1000, 5000);
asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
ASIC3_EXTCF_OWM_EN, 1);
msleep(1);
usleep_range(1000, 5000);
return 0;
}
@ -757,7 +755,7 @@ static int asic3_mmc_enable(struct platform_device *pdev)
* when HCLK is stopped.
*/
asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_EX1]);
msleep(1);
usleep_range(1000, 5000);
/* HCLK 24.576 MHz, BCLK 12.288 MHz: */
asic3_write_register(asic, ASIC3_OFFSET(CLOCK, SEL),
@ -765,7 +763,7 @@ static int asic3_mmc_enable(struct platform_device *pdev)
asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_HOST]);
asic3_clk_enable(asic, &asic->clocks[ASIC3_CLOCK_SD_BUS]);
msleep(1);
usleep_range(1000, 5000);
asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
ASIC3_EXTCF_SD_MEM_ENABLE, 1);
@ -841,7 +839,7 @@ static int asic3_leds_suspend(struct platform_device *pdev)
struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
while (asic3_gpio_get(&asic->gpio, ASIC3_GPIO(C, cell->id)) != 0)
msleep(1);
usleep_range(1000, 5000);
asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]);
@ -900,8 +898,8 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
/* MMC */
if (mem_sdio) {
asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) +
mem_sdio->start,
asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >>
asic->bus_shift) + mem_sdio->start,
ASIC3_SD_CONFIG_SIZE >> asic->bus_shift);
if (!asic->tmio_cnf) {
ret = -ENOMEM;
@ -962,10 +960,8 @@ static int __init asic3_probe(struct platform_device *pdev)
asic = devm_kzalloc(&pdev->dev,
sizeof(struct asic3), GFP_KERNEL);
if (asic == NULL) {
printk(KERN_ERR "kzalloc failed\n");
if (!asic)
return -ENOMEM;
}
spin_lock_init(&asic->lock);
platform_set_drvdata(pdev, asic);
@ -1074,7 +1070,9 @@ static struct platform_driver asic3_device_driver = {
static int __init asic3_init(void)
{
int retval = 0;
retval = platform_driver_probe(&asic3_device_driver, asic3_probe);
return retval;
}

View file

@ -292,7 +292,7 @@ static int cros_ec_i2c_probe(struct i2c_client *client,
struct cros_ec_device *ec_dev = NULL;
int err;
ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
if (!ec_dev)
return -ENOMEM;

View file

@ -113,7 +113,7 @@ static int terminate_request(struct cros_ec_device *ec_dev)
trans.delay_usecs = ec_spi->end_of_msg_delay;
spi_message_add_tail(&trans, &msg);
ret = spi_sync(ec_spi->spi, &msg);
ret = spi_sync_locked(ec_spi->spi, &msg);
/* Reset end-of-response timer */
ec_spi->last_transfer_ns = ktime_get_ns();
@ -147,7 +147,7 @@ static int receive_n_bytes(struct cros_ec_device *ec_dev, u8 *buf, int n)
spi_message_init(&msg);
spi_message_add_tail(&trans, &msg);
ret = spi_sync(ec_spi->spi, &msg);
ret = spi_sync_locked(ec_spi->spi, &msg);
if (ret < 0)
dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret);
@ -175,7 +175,7 @@ static int cros_ec_spi_receive_packet(struct cros_ec_device *ec_dev,
unsigned long deadline;
int todo;
BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size);
BUG_ON(ec_dev->din_size < EC_MSG_PREAMBLE_COUNT);
/* Receive data until we see the header byte */
deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
@ -283,7 +283,7 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev,
unsigned long deadline;
int todo;
BUG_ON(EC_MSG_PREAMBLE_COUNT > ec_dev->din_size);
BUG_ON(ec_dev->din_size < EC_MSG_PREAMBLE_COUNT);
/* Receive data until we see the header byte */
deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS);
@ -391,10 +391,10 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
}
rx_buf = kzalloc(len, GFP_KERNEL);
if (!rx_buf) {
ret = -ENOMEM;
goto exit;
}
if (!rx_buf)
return -ENOMEM;
spi_bus_lock(ec_spi->spi->master);
/*
* Leave a gap between CS assertion and clocking of data to allow the
@ -414,7 +414,7 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
trans.len = len;
trans.cs_change = 1;
spi_message_add_tail(&trans, &msg);
ret = spi_sync(ec_spi->spi, &msg);
ret = spi_sync_locked(ec_spi->spi, &msg);
/* Get the response */
if (!ret) {
@ -440,6 +440,9 @@ static int cros_ec_pkt_xfer_spi(struct cros_ec_device *ec_dev,
}
final_ret = terminate_request(ec_dev);
spi_bus_unlock(ec_spi->spi->master);
if (!ret)
ret = final_ret;
if (ret < 0)
@ -520,10 +523,10 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
}
rx_buf = kzalloc(len, GFP_KERNEL);
if (!rx_buf) {
ret = -ENOMEM;
goto exit;
}
if (!rx_buf)
return -ENOMEM;
spi_bus_lock(ec_spi->spi->master);
/* Transmit phase - send our message */
debug_packet(ec_dev->dev, "out", ec_dev->dout, len);
@ -534,7 +537,7 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
trans.cs_change = 1;
spi_message_init(&msg);
spi_message_add_tail(&trans, &msg);
ret = spi_sync(ec_spi->spi, &msg);
ret = spi_sync_locked(ec_spi->spi, &msg);
/* Get the response */
if (!ret) {
@ -560,6 +563,9 @@ static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev,
}
final_ret = terminate_request(ec_dev);
spi_bus_unlock(ec_spi->spi->master);
if (!ret)
ret = final_ret;
if (ret < 0)

1629
drivers/mfd/cs47l24-tables.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -60,6 +60,7 @@ static int cs5535_mfd_res_enable(struct platform_device *pdev)
static int cs5535_mfd_res_disable(struct platform_device *pdev)
{
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (!res) {
dev_err(&pdev->dev, "can't fetch device resource info\n");
@ -114,7 +115,10 @@ static struct mfd_cell cs5535_mfd_cells[] = {
#ifdef CONFIG_OLPC
static void cs5535_clone_olpc_cells(void)
{
const char *acpi_clones[] = { "olpc-xo1-pm-acpi", "olpc-xo1-sci-acpi" };
static const char *acpi_clones[] = {
"olpc-xo1-pm-acpi",
"olpc-xo1-sci-acpi"
};
if (!machine_is_olpc())
return;

View file

@ -2,10 +2,10 @@
* Base driver for Dialog Semiconductor DA9030/DA9034
*
* Copyright (C) 2008 Compulab, Ltd.
* Mike Rapoport <mike@compulab.co.il>
* Mike Rapoport <mike@compulab.co.il>
*
* Copyright (C) 2006-2008 Marvell International Ltd.
* Eric Miao <eric.miao@marvell.com>
* Eric Miao <eric.miao@marvell.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
@ -60,7 +60,7 @@ struct da903x_chip_ops {
struct da903x_chip {
struct i2c_client *client;
struct device *dev;
struct da903x_chip_ops *ops;
const struct da903x_chip_ops *ops;
int type;
uint32_t events_mask;
@ -424,7 +424,7 @@ static irqreturn_t da903x_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
static struct da903x_chip_ops da903x_ops[] = {
static const struct da903x_chip_ops da903x_ops[] = {
[0] = {
.init_chip = da9030_init_chip,
.unmask_events = da9030_unmask_events,
@ -565,6 +565,6 @@ static void __exit da903x_exit(void)
module_exit(da903x_exit);
MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034");
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
"Mike Rapoport <mike@compulab.co.il>");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
MODULE_LICENSE("GPL v2");

View file

@ -70,7 +70,7 @@ static int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg)
case DA9053_BA:
case DA9053_BB:
/* A dummy read to a safe register address. */
if (!i2c_safe_reg(reg))
if (!i2c_safe_reg(reg))
return regmap_read(da9052->regmap,
DA9052_PARK_REGISTER,
&val);

View file

@ -283,7 +283,7 @@ int da9052_irq_init(struct da9052 *da9052)
int da9052_irq_exit(struct da9052 *da9052)
{
da9052_free_irq(da9052, DA9052_IRQ_ADC_EOM , da9052);
da9052_free_irq(da9052, DA9052_IRQ_ADC_EOM, da9052);
regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data);
return 0;

View file

@ -47,11 +47,8 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
davinci_vc = devm_kzalloc(&pdev->dev,
sizeof(struct davinci_vc), GFP_KERNEL);
if (!davinci_vc) {
dev_dbg(&pdev->dev,
"could not allocate memory for private data\n");
if (!davinci_vc)
return -ENOMEM;
}
davinci_vc->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(davinci_vc->clk)) {

View file

@ -147,7 +147,7 @@ static int msp_gpio_get(struct gpio_chip *chip, unsigned offset)
return status;
if (reg == DM355EVM_MSP_LED)
msp_led_cache = status;
return status & MSP_GPIO_MASK(offset);
return !!(status & MSP_GPIO_MASK(offset));
}
static int msp_gpio_out(struct gpio_chip *chip, unsigned offset, int value)

View file

@ -163,7 +163,7 @@ static int egpio_get(struct gpio_chip *chip, unsigned offset)
value = egpio_readw(ei, reg);
pr_debug("readw(%p + %x) = %x\n",
ei->base_addr, reg << ei->bus_shift, value);
return value & bit;
return !!(value & bit);
}
static int egpio_direction_input(struct gpio_chip *chip, unsigned offset)

View file

@ -55,6 +55,7 @@
* document number TBD : Coleto Creek
* document number TBD : Wildcat Point-LP
* document number TBD : 9 Series
* document number TBD : Lewisburg
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@ -213,6 +214,7 @@ enum lpc_chipsets {
LPC_COLETO, /* Coleto Creek */
LPC_WPT_LP, /* Wildcat Point-LP */
LPC_BRASWELL, /* Braswell SoC */
LPC_LEWISBURG, /* Lewisburg */
LPC_9S, /* 9 Series */
};
@ -521,6 +523,10 @@ static struct lpc_ich_info lpc_chipset_info[] = {
.name = "Braswell SoC",
.iTCO_version = 3,
},
[LPC_LEWISBURG] = {
.name = "Lewisburg",
.iTCO_version = 2,
},
[LPC_9S] = {
.name = "9 Series",
.iTCO_version = 2,
@ -757,6 +763,15 @@ static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x9cc6), LPC_WPT_LP},
{ PCI_VDEVICE(INTEL, 0x9cc7), LPC_WPT_LP},
{ PCI_VDEVICE(INTEL, 0x9cc9), LPC_WPT_LP},
{ PCI_VDEVICE(INTEL, 0xa1c1), LPC_LEWISBURG},
{ PCI_VDEVICE(INTEL, 0xa1c2), LPC_LEWISBURG},
{ PCI_VDEVICE(INTEL, 0xa1c3), LPC_LEWISBURG},
{ PCI_VDEVICE(INTEL, 0xa1c4), LPC_LEWISBURG},
{ PCI_VDEVICE(INTEL, 0xa1c5), LPC_LEWISBURG},
{ PCI_VDEVICE(INTEL, 0xa1c6), LPC_LEWISBURG},
{ PCI_VDEVICE(INTEL, 0xa1c7), LPC_LEWISBURG},
{ PCI_VDEVICE(INTEL, 0xa242), LPC_LEWISBURG},
{ PCI_VDEVICE(INTEL, 0xa243), LPC_LEWISBURG},
{ 0, }, /* End of list */
};
MODULE_DEVICE_TABLE(pci, lpc_ich_ids);

View file

@ -495,7 +495,7 @@ MODULE_DEVICE_TABLE(i2c, max14577_i2c_id);
#ifdef CONFIG_PM_SLEEP
static int max14577_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max14577 *max14577 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
@ -516,7 +516,7 @@ static int max14577_suspend(struct device *dev)
static int max14577_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max14577 *max14577 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))

View file

@ -352,7 +352,7 @@ MODULE_DEVICE_TABLE(i2c, max77686_i2c_id);
#ifdef CONFIG_PM_SLEEP
static int max77686_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
@ -374,7 +374,7 @@ static int max77686_suspend(struct device *dev)
static int max77686_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max77686_dev *max77686 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))

View file

@ -334,7 +334,7 @@ MODULE_DEVICE_TABLE(i2c, max77693_i2c_id);
static int max77693_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev)) {
@ -347,7 +347,7 @@ static int max77693_suspend(struct device *dev)
static int max77693_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev)) {

View file

@ -197,7 +197,7 @@ MODULE_DEVICE_TABLE(i2c, max77843_id);
static int __maybe_unused max77843_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
disable_irq(max77843->irq);
@ -209,7 +209,7 @@ static int __maybe_unused max77843_suspend(struct device *dev)
static int __maybe_unused max77843_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))

View file

@ -215,7 +215,7 @@ static int max8925_remove(struct i2c_client *client)
#ifdef CONFIG_PM_SLEEP
static int max8925_suspend(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
struct i2c_client *client = to_i2c_client(dev);
struct max8925_chip *chip = i2c_get_clientdata(client);
if (device_may_wakeup(dev) && chip->wakeup_flag)
@ -225,7 +225,7 @@ static int max8925_suspend(struct device *dev)
static int max8925_resume(struct device *dev)
{
struct i2c_client *client = container_of(dev, struct i2c_client, dev);
struct i2c_client *client = to_i2c_client(dev);
struct max8925_chip *chip = i2c_get_clientdata(client);
if (device_may_wakeup(dev) && chip->wakeup_flag)

View file

@ -437,7 +437,7 @@ static u8 max8997_dumpaddr_haptic[] = {
static int max8997_freeze(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
int i;
@ -459,7 +459,7 @@ static int max8997_freeze(struct device *dev)
static int max8997_restore(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
int i;
@ -481,7 +481,7 @@ static int max8997_restore(struct device *dev)
static int max8997_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
@ -491,7 +491,7 @@ static int max8997_suspend(struct device *dev)
static int max8997_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))

View file

@ -274,7 +274,7 @@ MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
static int max8998_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
@ -284,7 +284,7 @@ static int max8998_suspend(struct device *dev)
static int max8998_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
@ -344,7 +344,7 @@ static struct max8998_reg_dump max8998_dump[] = {
/* Save registers before hibernation */
static int max8998_freeze(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
int i;
for (i = 0; i < ARRAY_SIZE(max8998_dump); i++)
@ -357,7 +357,7 @@ static int max8998_freeze(struct device *dev)
/* Restore registers after hibernation */
static int max8998_restore(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
int i;
for (i = 0; i < ARRAY_SIZE(max8998_dump); i++)

View file

@ -383,16 +383,16 @@ static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx)
if (!np)
return -ENODEV;
if (of_get_property(np, "fsl,mc13xxx-uses-adc", NULL))
if (of_property_read_bool(np, "fsl,mc13xxx-uses-adc"))
mc13xxx->flags |= MC13XXX_USE_ADC;
if (of_get_property(np, "fsl,mc13xxx-uses-codec", NULL))
if (of_property_read_bool(np, "fsl,mc13xxx-uses-codec"))
mc13xxx->flags |= MC13XXX_USE_CODEC;
if (of_get_property(np, "fsl,mc13xxx-uses-rtc", NULL))
if (of_property_read_bool(np, "fsl,mc13xxx-uses-rtc"))
mc13xxx->flags |= MC13XXX_USE_RTC;
if (of_get_property(np, "fsl,mc13xxx-uses-touch", NULL))
if (of_property_read_bool(np, "fsl,mc13xxx-uses-touch"))
mc13xxx->flags |= MC13XXX_USE_TOUCHSCREEN;
return 0;

View file

@ -127,7 +127,9 @@ static int pmic_spmi_probe(struct spmi_device *sdev)
if (IS_ERR(regmap))
return PTR_ERR(regmap);
pmic_spmi_show_revid(regmap, &sdev->dev);
/* Only the first slave id for a PMIC contains this information */
if (sdev->usid % 2 == 0)
pmic_spmi_show_revid(regmap, &sdev->dev);
return of_platform_populate(root, NULL, NULL, &sdev->dev);
}

View file

@ -495,6 +495,8 @@ static int qcom_rpm_probe(struct platform_device *pdev)
}
match = of_match_device(qcom_rpm_of_match, &pdev->dev);
if (!match)
return -ENODEV;
rpm->data = match->data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

View file

@ -29,6 +29,7 @@
#include <linux/mfd/samsung/s2mps11.h>
#include <linux/mfd/samsung/s2mps13.h>
#include <linux/mfd/samsung/s2mps14.h>
#include <linux/mfd/samsung/s2mps15.h>
#include <linux/mfd/samsung/s2mpu02.h>
#include <linux/mfd/samsung/s5m8763.h>
#include <linux/mfd/samsung/s5m8767.h>
@ -67,7 +68,7 @@ static const struct mfd_cell s5m8767_devs[] = {
static const struct mfd_cell s2mps11_devs[] = {
{
.name = "s2mps11-pmic",
.name = "s2mps11-regulator",
}, {
.name = "s2mps14-rtc",
}, {
@ -77,7 +78,7 @@ static const struct mfd_cell s2mps11_devs[] = {
};
static const struct mfd_cell s2mps13_devs[] = {
{ .name = "s2mps13-pmic", },
{ .name = "s2mps13-regulator", },
{ .name = "s2mps13-rtc", },
{
.name = "s2mps13-clk",
@ -87,7 +88,7 @@ static const struct mfd_cell s2mps13_devs[] = {
static const struct mfd_cell s2mps14_devs[] = {
{
.name = "s2mps14-pmic",
.name = "s2mps14-regulator",
}, {
.name = "s2mps14-rtc",
}, {
@ -96,6 +97,17 @@ static const struct mfd_cell s2mps14_devs[] = {
}
};
static const struct mfd_cell s2mps15_devs[] = {
{
.name = "s2mps15-regulator",
}, {
.name = "s2mps15-rtc",
}, {
.name = "s2mps13-clk",
.of_compatible = "samsung,s2mps13-clk",
},
};
static const struct mfd_cell s2mpa01_devs[] = {
{
.name = "s2mpa01-pmic",
@ -104,7 +116,7 @@ static const struct mfd_cell s2mpa01_devs[] = {
static const struct mfd_cell s2mpu02_devs[] = {
{
.name = "s2mpu02-pmic",
.name = "s2mpu02-regulator",
},
};
@ -121,6 +133,9 @@ static const struct of_device_id sec_dt_match[] = {
}, {
.compatible = "samsung,s2mps14-pmic",
.data = (void *)S2MPS14X,
}, {
.compatible = "samsung,s2mps15-pmic",
.data = (void *)S2MPS15X,
}, {
.compatible = "samsung,s2mpa01-pmic",
.data = (void *)S2MPA01,
@ -223,6 +238,15 @@ static const struct regmap_config s2mps14_regmap_config = {
.cache_type = REGCACHE_FLAT,
};
static const struct regmap_config s2mps15_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = S2MPS15_REG_LDODSCH4,
.volatile_reg = s2mps11_volatile,
.cache_type = REGCACHE_FLAT,
};
static const struct regmap_config s2mpu02_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@ -384,6 +408,9 @@ static int sec_pmic_probe(struct i2c_client *i2c,
case S2MPS14X:
regmap = &s2mps14_regmap_config;
break;
case S2MPS15X:
regmap = &s2mps15_regmap_config;
break;
case S5M8763X:
regmap = &s5m8763_regmap_config;
break;
@ -442,6 +469,10 @@ static int sec_pmic_probe(struct i2c_client *i2c,
sec_devs = s2mps14_devs;
num_sec_devs = ARRAY_SIZE(s2mps14_devs);
break;
case S2MPS15X:
sec_devs = s2mps15_devs;
num_sec_devs = ARRAY_SIZE(s2mps15_devs);
break;
case S2MPU02:
sec_devs = s2mpu02_devs;
num_sec_devs = ARRAY_SIZE(s2mpu02_devs);
@ -505,7 +536,7 @@ static void sec_pmic_shutdown(struct i2c_client *i2c)
#ifdef CONFIG_PM_SLEEP
static int sec_pmic_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
@ -526,7 +557,7 @@ static int sec_pmic_suspend(struct device *dev)
static int sec_pmic_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct i2c_client *i2c = to_i2c_client(dev);
struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))

View file

@ -407,6 +407,11 @@ static const struct regmap_irq_chip s2mps14_irq_chip = {
S2MPS1X_IRQ_CHIP_COMMON_DATA,
};
static const struct regmap_irq_chip s2mps15_irq_chip = {
.name = "s2mps15",
S2MPS1X_IRQ_CHIP_COMMON_DATA,
};
static const struct regmap_irq_chip s2mpu02_irq_chip = {
.name = "s2mpu02",
.irqs = s2mpu02_irqs,
@ -466,6 +471,9 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
case S2MPS14X:
sec_irq_chip = &s2mps14_irq_chip;
break;
case S2MPS15X:
sec_irq_chip = &s2mps15_irq_chip;
break;
case S2MPU02:
sec_irq_chip = &s2mpu02_irq_chip;
break;

View file

@ -372,12 +372,6 @@ static struct platform_driver sta2x11_sctl_platform_driver = {
.probe = sta2x11_sctl_probe,
};
static int __init sta2x11_sctl_init(void)
{
pr_info("%s\n", __func__);
return platform_driver_register(&sta2x11_sctl_platform_driver);
}
static struct platform_driver sta2x11_platform_driver = {
.driver = {
.name = STA2X11_MFD_APBREG_NAME,
@ -385,12 +379,6 @@ static struct platform_driver sta2x11_platform_driver = {
.probe = sta2x11_apbreg_probe,
};
static int __init sta2x11_apbreg_init(void)
{
pr_info("%s\n", __func__);
return platform_driver_register(&sta2x11_platform_driver);
}
static struct platform_driver sta2x11_apb_soc_regs_platform_driver = {
.driver = {
.name = STA2X11_MFD_APB_SOC_REGS_NAME,
@ -398,12 +386,6 @@ static struct platform_driver sta2x11_apb_soc_regs_platform_driver = {
.probe = sta2x11_apb_soc_regs_probe,
};
static int __init sta2x11_apb_soc_regs_init(void)
{
pr_info("%s\n", __func__);
return platform_driver_register(&sta2x11_apb_soc_regs_platform_driver);
}
static struct platform_driver sta2x11_scr_platform_driver = {
.driver = {
.name = STA2X11_MFD_SCR_NAME,
@ -411,12 +393,17 @@ static struct platform_driver sta2x11_scr_platform_driver = {
.probe = sta2x11_scr_probe,
};
static int __init sta2x11_scr_init(void)
{
pr_info("%s\n", __func__);
return platform_driver_register(&sta2x11_scr_platform_driver);
}
static struct platform_driver * const drivers[] = {
&sta2x11_platform_driver,
&sta2x11_sctl_platform_driver,
&sta2x11_apb_soc_regs_platform_driver,
&sta2x11_scr_platform_driver,
};
static int __init sta2x11_drivers_init(void)
{
return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
}
/*
* What follows are the PCI devices that host the above pdevs.
@ -664,10 +651,7 @@ static int __init sta2x11_mfd_init(void)
* prepares platform drivers very early and probe the PCI device later,
* but before other PCI devices.
*/
subsys_initcall(sta2x11_apbreg_init);
subsys_initcall(sta2x11_sctl_init);
subsys_initcall(sta2x11_apb_soc_regs_init);
subsys_initcall(sta2x11_scr_init);
subsys_initcall(sta2x11_drivers_init);
rootfs_initcall(sta2x11_mfd_init);
MODULE_LICENSE("GPL v2");

View file

@ -47,6 +47,7 @@ static struct syscon *of_syscon_register(struct device_node *np)
struct syscon *syscon;
struct regmap *regmap;
void __iomem *base;
u32 reg_io_width;
int ret;
struct regmap_config syscon_config = syscon_regmap_config;
@ -69,6 +70,18 @@ static struct syscon *of_syscon_register(struct device_node *np)
else if (of_property_read_bool(np, "little-endian"))
syscon_config.val_format_endian = REGMAP_ENDIAN_LITTLE;
/*
* search for reg-io-width property in DT. If it is not provided,
* default to 4 bytes. regmap_init_mmio will return an error if values
* are invalid so there is no need to check them here.
*/
ret = of_property_read_u32(np, "reg-io-width", &reg_io_width);
if (ret)
reg_io_width = 4;
syscon_config.reg_stride = reg_io_width;
syscon_config.val_bits = reg_io_width * 8;
regmap = regmap_init_mmio(NULL, base, &syscon_config);
if (IS_ERR(regmap)) {
pr_err("regmap init failed\n");

View file

@ -437,8 +437,8 @@ static int tc6393xb_gpio_get(struct gpio_chip *chip,
struct tc6393xb *tc6393xb = container_of(chip, struct tc6393xb, gpio);
/* XXX: does dsr also represent inputs? */
return tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8))
& TC_GPIO_BIT(offset);
return !!(tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8))
& TC_GPIO_BIT(offset));
}
static void __tc6393xb_gpio_set(struct gpio_chip *chip,

View file

@ -499,11 +499,11 @@ static int tps65010_gpio_get(struct gpio_chip *chip, unsigned offset)
if (offset < 4) {
value = i2c_smbus_read_byte_data(tps->client, TPS_DEFGPIO);
if (value < 0)
return 0;
return value;
if (value & (1 << (offset + 4))) /* output */
return !(value & (1 << offset));
else /* input */
return (value & (1 << offset));
return !!(value & (1 << offset));
}
/* REVISIT we *could* report LED1/nPG and LED2 state ... */

View file

@ -133,7 +133,7 @@ static int ucb1x00_gpio_get(struct gpio_chip *chip, unsigned offset)
val = ucb1x00_reg_read(ucb, UCB_IO_DATA);
ucb1x00_disable(ucb);
return val & (1 << offset);
return !!(val & (1 << offset));
}
static int ucb1x00_gpio_direction_input(struct gpio_chip *chip, unsigned offset)

View file

@ -762,9 +762,9 @@ static const struct reg_default wm5110_reg_default[] = {
{ 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */
{ 0x00000210, 0x0184 }, /* R528 - LDO1 Control 1 */
{ 0x00000213, 0x03E4 }, /* R531 - LDO2 Control 1 */
{ 0x00000218, 0x01A6 }, /* R536 - Mic Bias Ctrl 1 */
{ 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */
{ 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */
{ 0x00000218, 0x00E6 }, /* R536 - Mic Bias Ctrl 1 */
{ 0x00000219, 0x00E6 }, /* R537 - Mic Bias Ctrl 2 */
{ 0x0000021A, 0x00E6 }, /* R538 - Mic Bias Ctrl 3 */
{ 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */
{ 0x0000029B, 0x0028 }, /* R667 - Headphone Detect 1 */
{ 0x000002A2, 0x0000 }, /* R674 - Micd clamp control */

View file

@ -47,20 +47,14 @@ static ssize_t wm831x_unique_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct wm831x *wm831x = dev_get_drvdata(dev);
int i, rval;
int rval;
char id[WM831X_UNIQUE_ID_LEN];
ssize_t ret = 0;
rval = wm831x_unique_id_read(wm831x, id);
if (rval < 0)
return 0;
for (i = 0; i < WM831X_UNIQUE_ID_LEN; i++)
ret += sprintf(&buf[ret], "%02x", buf[i]);
ret += sprintf(&buf[ret], "\n");
return ret;
return sprintf(buf, "%*phN\n", WM831X_UNIQUE_ID_LEN, id);
}
static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL);

View file

@ -588,10 +588,10 @@ config REGULATOR_S2MPA01
via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs.
config REGULATOR_S2MPS11
tristate "Samsung S2MPS11/S2MPS13/S2MPS14/S2MPU02 voltage regulator"
tristate "Samsung S2MPS11/13/14/15/S2MPU02 voltage regulator"
depends on MFD_SEC_CORE
help
This driver supports a Samsung S2MPS11/S2MPS13/S2MPS14/S2MPU02 voltage
This driver supports a Samsung S2MPS11/13/14/15/S2MPU02 voltage
output regulator via I2C bus. The chip is comprised of high efficient
Buck converters including Dual-Phase Buck converter, Buck-Boost
converter, various LDOs.

View file

@ -32,6 +32,7 @@
#include <linux/mfd/samsung/s2mps11.h>
#include <linux/mfd/samsung/s2mps13.h>
#include <linux/mfd/samsung/s2mps14.h>
#include <linux/mfd/samsung/s2mps15.h>
#include <linux/mfd/samsung/s2mpu02.h>
/* The highest number of possible regulators for supported devices. */
@ -661,6 +662,133 @@ static const struct regulator_desc s2mps14_regulators[] = {
S2MPS14_BUCK1235_START_SEL),
};
static struct regulator_ops s2mps15_reg_ldo_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static struct regulator_ops s2mps15_reg_buck_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
};
#define regulator_desc_s2mps15_ldo(num, range) { \
.name = "LDO"#num, \
.id = S2MPS15_LDO##num, \
.ops = &s2mps15_reg_ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.linear_ranges = range, \
.n_linear_ranges = ARRAY_SIZE(range), \
.n_voltages = S2MPS15_LDO_N_VOLTAGES, \
.vsel_reg = S2MPS15_REG_L1CTRL + num - 1, \
.vsel_mask = S2MPS15_LDO_VSEL_MASK, \
.enable_reg = S2MPS15_REG_L1CTRL + num - 1, \
.enable_mask = S2MPS15_ENABLE_MASK \
}
#define regulator_desc_s2mps15_buck(num, range) { \
.name = "BUCK"#num, \
.id = S2MPS15_BUCK##num, \
.ops = &s2mps15_reg_buck_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.linear_ranges = range, \
.n_linear_ranges = ARRAY_SIZE(range), \
.ramp_delay = 12500, \
.n_voltages = S2MPS15_BUCK_N_VOLTAGES, \
.vsel_reg = S2MPS15_REG_B1CTRL2 + ((num - 1) * 2), \
.vsel_mask = S2MPS15_BUCK_VSEL_MASK, \
.enable_reg = S2MPS15_REG_B1CTRL1 + ((num - 1) * 2), \
.enable_mask = S2MPS15_ENABLE_MASK \
}
/* voltage range for s2mps15 LDO 3, 5, 15, 16, 18, 20, 23 and 27 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges1[] = {
REGULATOR_LINEAR_RANGE(1000000, 0xc, 0x38, 25000),
};
/* voltage range for s2mps15 LDO 2, 6, 14, 17, 19, 21, 24 and 25 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges2[] = {
REGULATOR_LINEAR_RANGE(1800000, 0x0, 0x3f, 25000),
};
/* voltage range for s2mps15 LDO 4, 11, 12, 13, 22 and 26 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges3[] = {
REGULATOR_LINEAR_RANGE(700000, 0x0, 0x34, 12500),
};
/* voltage range for s2mps15 LDO 7, 8, 9 and 10 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges4[] = {
REGULATOR_LINEAR_RANGE(700000, 0xc, 0x18, 25000),
};
/* voltage range for s2mps15 LDO 1 */
static const struct regulator_linear_range s2mps15_ldo_voltage_ranges5[] = {
REGULATOR_LINEAR_RANGE(500000, 0x0, 0x20, 12500),
};
/* voltage range for s2mps15 BUCK 1, 2, 3, 4, 5, 6 and 7 */
static const struct regulator_linear_range s2mps15_buck_voltage_ranges1[] = {
REGULATOR_LINEAR_RANGE(500000, 0x20, 0xb0, 6250),
};
/* voltage range for s2mps15 BUCK 8, 9 and 10 */
static const struct regulator_linear_range s2mps15_buck_voltage_ranges2[] = {
REGULATOR_LINEAR_RANGE(1000000, 0x20, 0xc0, 12500),
};
static const struct regulator_desc s2mps15_regulators[] = {
regulator_desc_s2mps15_ldo(1, s2mps15_ldo_voltage_ranges5),
regulator_desc_s2mps15_ldo(2, s2mps15_ldo_voltage_ranges2),
regulator_desc_s2mps15_ldo(3, s2mps15_ldo_voltage_ranges1),
regulator_desc_s2mps15_ldo(4, s2mps15_ldo_voltage_ranges3),
regulator_desc_s2mps15_ldo(5, s2mps15_ldo_voltage_ranges1),
regulator_desc_s2mps15_ldo(6, s2mps15_ldo_voltage_ranges2),
regulator_desc_s2mps15_ldo(7, s2mps15_ldo_voltage_ranges4),
regulator_desc_s2mps15_ldo(8, s2mps15_ldo_voltage_ranges4),
regulator_desc_s2mps15_ldo(9, s2mps15_ldo_voltage_ranges4),
regulator_desc_s2mps15_ldo(10, s2mps15_ldo_voltage_ranges4),
regulator_desc_s2mps15_ldo(11, s2mps15_ldo_voltage_ranges3),
regulator_desc_s2mps15_ldo(12, s2mps15_ldo_voltage_ranges3),
regulator_desc_s2mps15_ldo(13, s2mps15_ldo_voltage_ranges3),
regulator_desc_s2mps15_ldo(14, s2mps15_ldo_voltage_ranges2),
regulator_desc_s2mps15_ldo(15, s2mps15_ldo_voltage_ranges1),
regulator_desc_s2mps15_ldo(16, s2mps15_ldo_voltage_ranges1),
regulator_desc_s2mps15_ldo(17, s2mps15_ldo_voltage_ranges2),
regulator_desc_s2mps15_ldo(18, s2mps15_ldo_voltage_ranges1),
regulator_desc_s2mps15_ldo(19, s2mps15_ldo_voltage_ranges2),
regulator_desc_s2mps15_ldo(20, s2mps15_ldo_voltage_ranges1),
regulator_desc_s2mps15_ldo(21, s2mps15_ldo_voltage_ranges2),
regulator_desc_s2mps15_ldo(22, s2mps15_ldo_voltage_ranges3),
regulator_desc_s2mps15_ldo(23, s2mps15_ldo_voltage_ranges1),
regulator_desc_s2mps15_ldo(24, s2mps15_ldo_voltage_ranges2),
regulator_desc_s2mps15_ldo(25, s2mps15_ldo_voltage_ranges2),
regulator_desc_s2mps15_ldo(26, s2mps15_ldo_voltage_ranges3),
regulator_desc_s2mps15_ldo(27, s2mps15_ldo_voltage_ranges1),
regulator_desc_s2mps15_buck(1, s2mps15_buck_voltage_ranges1),
regulator_desc_s2mps15_buck(2, s2mps15_buck_voltage_ranges1),
regulator_desc_s2mps15_buck(3, s2mps15_buck_voltage_ranges1),
regulator_desc_s2mps15_buck(4, s2mps15_buck_voltage_ranges1),
regulator_desc_s2mps15_buck(5, s2mps15_buck_voltage_ranges1),
regulator_desc_s2mps15_buck(6, s2mps15_buck_voltage_ranges1),
regulator_desc_s2mps15_buck(7, s2mps15_buck_voltage_ranges1),
regulator_desc_s2mps15_buck(8, s2mps15_buck_voltage_ranges2),
regulator_desc_s2mps15_buck(9, s2mps15_buck_voltage_ranges2),
regulator_desc_s2mps15_buck(10, s2mps15_buck_voltage_ranges2),
};
static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11,
struct regulator_dev *rdev)
{
@ -974,6 +1102,10 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
regulators = s2mps14_regulators;
BUILD_BUG_ON(S2MPS_REGULATOR_MAX < s2mps11->rdev_num);
break;
case S2MPS15X:
s2mps11->rdev_num = ARRAY_SIZE(s2mps15_regulators);
regulators = s2mps15_regulators;
break;
case S2MPU02:
s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators);
regulators = s2mpu02_regulators;
@ -1067,10 +1199,11 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id s2mps11_pmic_id[] = {
{ "s2mps11-pmic", S2MPS11X},
{ "s2mps13-pmic", S2MPS13X},
{ "s2mps14-pmic", S2MPS14X},
{ "s2mpu02-pmic", S2MPU02},
{ "s2mps11-regulator", S2MPS11X},
{ "s2mps13-regulator", S2MPS13X},
{ "s2mps14-regulator", S2MPS14X},
{ "s2mps15-regulator", S2MPS15X},
{ "s2mpu02-regulator", S2MPU02},
{ },
};
MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id);
@ -1097,5 +1230,5 @@ module_exit(s2mps11_pmic_exit);
/* Module information */
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPU02 Regulator Driver");
MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver");
MODULE_LICENSE("GPL");

View file

@ -188,6 +188,7 @@ static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info,
ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val);
val &= S5M_ALARM0_STATUS;
break;
case S2MPS15X:
case S2MPS14X:
case S2MPS13X:
ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2,
@ -219,9 +220,22 @@ static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
return ret;
}
data |= info->regs->rtc_udr_mask;
if (info->device_type == S5M8763X || info->device_type == S5M8767X)
data |= S5M_RTC_TIME_EN_MASK;
switch (info->device_type) {
case S5M8763X:
case S5M8767X:
data |= info->regs->rtc_udr_mask | S5M_RTC_TIME_EN_MASK;
case S2MPS15X:
/* As per UM, for write time register, set WUDR bit to high */
data |= S2MPS15_RTC_WUDR_MASK;
break;
case S2MPS14X:
case S2MPS13X:
data |= info->regs->rtc_udr_mask;
break;
default:
return -EINVAL;
}
ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data);
if (ret < 0) {
@ -252,6 +266,11 @@ static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
case S5M8767X:
data &= ~S5M_RTC_TIME_EN_MASK;
break;
case S2MPS15X:
/* As per UM, for write alarm, set A_UDR(bit[4]) to high
* rtc_udr_mask above sets bit[4]
*/
break;
case S2MPS14X:
data |= S2MPS_RTC_RUDR_MASK;
break;
@ -317,7 +336,8 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
u8 data[info->regs->regs_count];
int ret;
if (info->device_type == S2MPS14X || info->device_type == S2MPS13X) {
if (info->device_type == S2MPS15X || info->device_type == S2MPS14X ||
info->device_type == S2MPS13X) {
ret = regmap_update_bits(info->regmap,
info->regs->rtc_udr_update,
S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK);
@ -339,6 +359,7 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
break;
case S5M8767X:
case S2MPS15X:
case S2MPS14X:
case S2MPS13X:
s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode);
@ -366,6 +387,7 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
s5m8763_tm_to_data(tm, data);
break;
case S5M8767X:
case S2MPS15X:
case S2MPS14X:
case S2MPS13X:
ret = s5m8767_tm_to_data(tm, data);
@ -414,6 +436,7 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
break;
case S5M8767X:
case S2MPS15X:
case S2MPS14X:
case S2MPS13X:
s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
@ -463,6 +486,7 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
break;
case S5M8767X:
case S2MPS15X:
case S2MPS14X:
case S2MPS13X:
for (i = 0; i < info->regs->regs_count; i++)
@ -508,6 +532,7 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
break;
case S5M8767X:
case S2MPS15X:
case S2MPS14X:
case S2MPS13X:
data[RTC_SEC] |= ALARM_ENABLE_MASK;
@ -548,6 +573,7 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
break;
case S5M8767X:
case S2MPS15X:
case S2MPS14X:
case S2MPS13X:
s5m8767_tm_to_data(&alrm->time, data);
@ -631,6 +657,7 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2);
break;
case S2MPS15X:
case S2MPS14X:
case S2MPS13X:
data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
@ -679,6 +706,7 @@ static int s5m_rtc_probe(struct platform_device *pdev)
return -ENOMEM;
switch (platform_get_device_id(pdev)->driver_data) {
case S2MPS15X:
case S2MPS14X:
case S2MPS13X:
regmap_cfg = &s2mps14_rtc_regmap_config;
@ -805,6 +833,7 @@ static const struct platform_device_id s5m_rtc_id[] = {
{ "s5m-rtc", S5M8767X },
{ "s2mps13-rtc", S2MPS13X },
{ "s2mps14-rtc", S2MPS14X },
{ "s2mps15-rtc", S2MPS15X },
{ },
};
MODULE_DEVICE_TABLE(platform, s5m_rtc_id);

View file

@ -27,6 +27,8 @@ enum arizona_type {
WM8280 = 4,
WM8998 = 5,
WM1814 = 6,
WM1831 = 7,
CS47L24 = 8,
};
#define ARIZONA_IRQ_GP1 0
@ -166,6 +168,7 @@ static inline int wm5102_patch(struct arizona *arizona)
#endif
int wm5110_patch(struct arizona *arizona);
int cs47l24_patch(struct arizona *arizona);
int wm8997_patch(struct arizona *arizona);
int wm8998_patch(struct arizona *arizona);

View file

@ -171,7 +171,7 @@ struct arizona_pdata {
int inmode[ARIZONA_MAX_INPUT];
/** Mode for outputs */
bool out_mono[ARIZONA_MAX_OUTPUT];
int out_mono[ARIZONA_MAX_OUTPUT];
/** PDM speaker mute setting */
unsigned int spk_mute[ARIZONA_MAX_PDM_SPK];

View file

@ -44,6 +44,7 @@ enum sec_device_type {
S2MPS11X,
S2MPS13X,
S2MPS14X,
S2MPS15X,
S2MPU02,
};

View file

@ -107,6 +107,8 @@ enum s2mps_rtc_reg {
#define S2MPS_RTC_WUDR_MASK (1 << S2MPS_RTC_WUDR_SHIFT)
#define S2MPS13_RTC_AUDR_SHIFT 1
#define S2MPS13_RTC_AUDR_MASK (1 << S2MPS13_RTC_AUDR_SHIFT)
#define S2MPS15_RTC_WUDR_SHIFT 1
#define S2MPS15_RTC_WUDR_MASK (1 << S2MPS15_RTC_WUDR_SHIFT)
#define S2MPS_RTC_RUDR_SHIFT 0
#define S2MPS_RTC_RUDR_MASK (1 << S2MPS_RTC_RUDR_SHIFT)
#define RTC_TCON_SHIFT 1

View file

@ -0,0 +1,158 @@
/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd
* http://www.samsung.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.
*
* 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.
*/
#ifndef __LINUX_MFD_S2MPS15_H
#define __LINUX_MFD_S2MPS15_H
/* S2MPS15 registers */
enum s2mps15_reg {
S2MPS15_REG_ID,
S2MPS15_REG_INT1,
S2MPS15_REG_INT2,
S2MPS15_REG_INT3,
S2MPS15_REG_INT1M,
S2MPS15_REG_INT2M,
S2MPS15_REG_INT3M,
S2MPS15_REG_ST1,
S2MPS15_REG_ST2,
S2MPS15_REG_PWRONSRC,
S2MPS15_REG_OFFSRC,
S2MPS15_REG_BU_CHG,
S2MPS15_REG_RTC_BUF,
S2MPS15_REG_CTRL1,
S2MPS15_REG_CTRL2,
S2MPS15_REG_RSVD1,
S2MPS15_REG_RSVD2,
S2MPS15_REG_RSVD3,
S2MPS15_REG_RSVD4,
S2MPS15_REG_RSVD5,
S2MPS15_REG_RSVD6,
S2MPS15_REG_CTRL3,
S2MPS15_REG_RSVD7,
S2MPS15_REG_RSVD8,
S2MPS15_REG_RSVD9,
S2MPS15_REG_B1CTRL1,
S2MPS15_REG_B1CTRL2,
S2MPS15_REG_B2CTRL1,
S2MPS15_REG_B2CTRL2,
S2MPS15_REG_B3CTRL1,
S2MPS15_REG_B3CTRL2,
S2MPS15_REG_B4CTRL1,
S2MPS15_REG_B4CTRL2,
S2MPS15_REG_B5CTRL1,
S2MPS15_REG_B5CTRL2,
S2MPS15_REG_B6CTRL1,
S2MPS15_REG_B6CTRL2,
S2MPS15_REG_B7CTRL1,
S2MPS15_REG_B7CTRL2,
S2MPS15_REG_B8CTRL1,
S2MPS15_REG_B8CTRL2,
S2MPS15_REG_B9CTRL1,
S2MPS15_REG_B9CTRL2,
S2MPS15_REG_B10CTRL1,
S2MPS15_REG_B10CTRL2,
S2MPS15_REG_BBCTRL1,
S2MPS15_REG_BBCTRL2,
S2MPS15_REG_BRAMP,
S2MPS15_REG_LDODVS1,
S2MPS15_REG_LDODVS2,
S2MPS15_REG_LDODVS3,
S2MPS15_REG_LDODVS4,
S2MPS15_REG_L1CTRL,
S2MPS15_REG_L2CTRL,
S2MPS15_REG_L3CTRL,
S2MPS15_REG_L4CTRL,
S2MPS15_REG_L5CTRL,
S2MPS15_REG_L6CTRL,
S2MPS15_REG_L7CTRL,
S2MPS15_REG_L8CTRL,
S2MPS15_REG_L9CTRL,
S2MPS15_REG_L10CTRL,
S2MPS15_REG_L11CTRL,
S2MPS15_REG_L12CTRL,
S2MPS15_REG_L13CTRL,
S2MPS15_REG_L14CTRL,
S2MPS15_REG_L15CTRL,
S2MPS15_REG_L16CTRL,
S2MPS15_REG_L17CTRL,
S2MPS15_REG_L18CTRL,
S2MPS15_REG_L19CTRL,
S2MPS15_REG_L20CTRL,
S2MPS15_REG_L21CTRL,
S2MPS15_REG_L22CTRL,
S2MPS15_REG_L23CTRL,
S2MPS15_REG_L24CTRL,
S2MPS15_REG_L25CTRL,
S2MPS15_REG_L26CTRL,
S2MPS15_REG_L27CTRL,
S2MPS15_REG_LDODSCH1,
S2MPS15_REG_LDODSCH2,
S2MPS15_REG_LDODSCH3,
S2MPS15_REG_LDODSCH4,
};
/* S2MPS15 regulator ids */
enum s2mps15_regulators {
S2MPS15_LDO1,
S2MPS15_LDO2,
S2MPS15_LDO3,
S2MPS15_LDO4,
S2MPS15_LDO5,
S2MPS15_LDO6,
S2MPS15_LDO7,
S2MPS15_LDO8,
S2MPS15_LDO9,
S2MPS15_LDO10,
S2MPS15_LDO11,
S2MPS15_LDO12,
S2MPS15_LDO13,
S2MPS15_LDO14,
S2MPS15_LDO15,
S2MPS15_LDO16,
S2MPS15_LDO17,
S2MPS15_LDO18,
S2MPS15_LDO19,
S2MPS15_LDO20,
S2MPS15_LDO21,
S2MPS15_LDO22,
S2MPS15_LDO23,
S2MPS15_LDO24,
S2MPS15_LDO25,
S2MPS15_LDO26,
S2MPS15_LDO27,
S2MPS15_BUCK1,
S2MPS15_BUCK2,
S2MPS15_BUCK3,
S2MPS15_BUCK4,
S2MPS15_BUCK5,
S2MPS15_BUCK6,
S2MPS15_BUCK7,
S2MPS15_BUCK8,
S2MPS15_BUCK9,
S2MPS15_BUCK10,
S2MPS15_BUCK11,
S2MPS15_REGULATOR_MAX,
};
#define S2MPS15_LDO_VSEL_MASK (0x3F)
#define S2MPS15_BUCK_VSEL_MASK (0xFF)
#define S2MPS15_ENABLE_SHIFT (0x06)
#define S2MPS15_ENABLE_MASK (0x03 << S2MPS15_ENABLE_SHIFT)
#define S2MPS15_LDO_N_VOLTAGES (S2MPS15_LDO_VSEL_MASK + 1)
#define S2MPS15_BUCK_N_VOLTAGES (S2MPS15_BUCK_VSEL_MASK + 1)
#endif /* __LINUX_MFD_S2MPS15_H */