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

Pull MFD updates from Lee Jones:
 "Core framework:
   - Add the MFD bindings doc to MAINTAINERS

  New drivers:
   - X-Powers AC100 Audio CODEC and RTC
   - TI LP873x PMIC
   - Rockchip RK808 PMIC
   - Samsung Exynos Low Power Audio

  New device support:
   - Add support for STMPE1600 variant to stmpe
   - Add support for PM8018 PMIC to pm8921-core
   - Add support for AXP806 PMIC in axp20x
   - Add support for AXP209 GPIO in axp20x

  New functionality:
   - Add support for Reset to all STMPE variants
   - Add support for MKBP event support to cros_ec
   - Add support for USB to intel_soc_pmic_bxtwc
   - Add support for IRQs and Power Button to tps65217

  Fix-ups:
   - Clean-up defunct author emails (da9063, max14577)
   - Kconfig fixups (wm8350-i2c, as37220
   - Constify (altera-a10sr, sm501)
   - Supply PCI IDs (intel-lpss-pci)
   - Improve clocking (qcom_rpm)
   - Fix IRQ probing (ucb1x00-core)
   - Ensure fault log is cleared (da9052)
   - Remove NO_IRQ check (ucb1x00-core)
   - Supply I2C properties (intel-lpss-acpi, intel-lpss-pci)
   - Non standard declaration (tps65217, max8997-irq)
   - Remove unused code (lp873x, db8500-prcmu, ab8500-debugfs,
     cros_ec_spi)
   - Make non-modular (altera-a10sr, intel_msic, smsc-ece1099,
     sun6i-prcm, twl-core)
   - OF bindings (ac100, stmpe, qcom-pm8xxx, qcom-rpm, rk808, axp20x,
     lp873x, exynos5433-lpass, act8945a, aspeed-scu, twl6040, arizona)

  Bugfixes:
   - Release OF pointer (qcom_rpm)
   - Avoid double shifting in suspend/resume (88pm80x)
   - Fix 'defined but not used' error (exynos-lpass)
   - Fix 'sleeping whilst attomic' (atmel-hlcdc)"

* tag 'mfd-for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (69 commits)
  mfd: arizona: Handle probe deferral for reset GPIO
  mfd: arizona: Remove arizona_of_get_named_gpio helper function
  mfd: arizona: Add DT options for max_channels_clocked and PDM speaker config
  mfd: twl6040: Register child device for twl6040-pdmclk
  mfd: cros_ec_spi: Remove unused variable 'request'
  mfd: omap-usb-host: Return value is not 'const int'
  mfd: ab8500-debugfs: Remove 'weak' function suspend_test_wake_cause_interrupt_is_mine()
  mfd: ab8500-debugfs: Remove ab8500_dump_all_banks_to_mem()
  mfd: db8500-prcmu: Remove unused *prcmu_set_ddr_opp() calls
  mfd: ab8500-debugfs: Prevent initialised field from being over-written
  mfd: max8997-irq: 'inline' should be at the beginning of the declaration
  mfd: rk808: Fix RK818_IRQ_DISCHG_ILIM initializer
  mfd: tps65217: Fix nonstandard declaration
  mfd: lp873x: Remove unused mutex lock from struct lp873x
  mfd: atmel-hlcdc: Do not sleep in atomic context
  mfd: exynos-lpass: Mark PM functions as __maybe_unused
  mfd: intel-lpss: Add default I2C device properties for Apollo Lake
  mfd: twl-core: Make it explicitly non-modular
  mfd: sun6i-prcm: Make it explicitly non-modular
  mfd: smsc-ece1099: Make it explicitly non-modular
  ...
This commit is contained in:
Linus Torvalds
2016-10-07 08:35:35 -07:00
80 changed files with 3123 additions and 457 deletions
@@ -0,0 +1,54 @@
X-Powers AC100 Codec/RTC IC Device Tree bindings
AC100 is a audio codec and RTC subsystem combo IC. The 2 parts are
separated, including power supplies and interrupt lines, but share
a common register address space and host interface.
Required properties:
- compatible: "x-powers,ac100"
- reg: The I2C slave address or RSB hardware address for the chip
- sub-nodes:
- codec
- compatible: "x-powers,ac100-codec"
- interrupt-parent: The parent interrupt controller
- interrupts: SoC NMI / GPIO interrupt connected to the
IRQ_AUDIO pin
- #clock-cells: Shall be 0
- clock-output-names: "4M_adda"
- see clock/clock-bindings.txt for common clock bindings
- rtc
- compatible: "x-powers,ac100-rtc"
- interrupt-parent: The parent interrupt controller
- interrupts: SoC NMI / GPIO interrupt connected to the
IRQ_RTC pin
- clocks: A phandle to the codec's "4M_adda" clock
- #clock-cells: Shall be 1
- clock-output-names: "cko1_rtc", "cko2_rtc", "cko3_rtc"
- see clock/clock-bindings.txt for common clock bindings
Example:
ac100: codec@e89 {
compatible = "x-powers,ac100";
reg = <0xe89>;
ac100_codec: codec {
compatible = "x-powers,ac100-codec";
interrupt-parent = <&r_pio>;
interrupts = <0 9 IRQ_TYPE_LEVEL_LOW>; /* PL9 */
#clock-cells = <0>;
clock-output-names = "4M_adda";
};
ac100_rtc: rtc {
compatible = "x-powers,ac100-rtc";
interrupt-parent = <&nmi_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
clocks = <&ac100_codec>;
#clock-cells = <1>;
clock-output-names = "cko1_rtc", "cko2_rtc", "cko3_rtc";
};
};
@@ -14,13 +14,6 @@ Example:
reg = <0x5b>;
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_charger_chglev>;
active-semi,chglev-gpio = <&pioA 12 GPIO_ACTIVE_HIGH>;
active-semi,input-voltage-threshold-microvolt = <6600>;
active-semi,precondition-timeout = <40>;
active-semi,total-timeout = <3>;
active-semi,vsel-high;
regulators {
@@ -73,4 +66,19 @@ Example:
regulator-always-on;
};
};
charger {
compatible = "active-semi,act8945a-charger";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_charger_chglev &pinctrl_charger_lbo &pinctrl_charger_irq>;
interrupt-parent = <&pioA>;
interrupts = <45 GPIO_ACTIVE_LOW>;
active-semi,chglev-gpios = <&pioA 12 GPIO_ACTIVE_HIGH>;
active-semi,lbo-gpios = <&pioA 72 GPIO_ACTIVE_LOW>;
active-semi,input-voltage-threshold-microvolt = <6600>;
active-semi,precondition-timeout = <40>;
active-semi,total-timeout = <3>;
status = "okay";
};
};
@@ -85,6 +85,24 @@ Optional properties:
present, the number of values should be less than or equal to the
number of inputs, unspecified inputs will use the chip default.
- wlf,max-channels-clocked : The maximum number of channels to be clocked on
each AIF, useful for I2S systems with multiple data lines being mastered.
Specify one cell for each AIF to be configured, specify zero for AIFs that
should be handled normally.
If present, number of cells must be less than or equal to the number of
AIFs. If less than the number of AIFs, for cells that have not been
specified the corresponding AIFs will be treated as default setting.
- wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and OUT6).
See the datasheet for values.
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
wm8998, wm1814)
- wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 and OUT6).
See the datasheet for values.
The second cell is ignored for codecs that do not have OUT6 (wm5102, wm8997,
wm8998, wm1814)
- 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
@@ -0,0 +1,18 @@
The Aspeed System Control Unit manages the global behaviour of the SoC,
configuring elements such as clocks, pinmux, and reset.
Required properties:
- compatible: One of:
"aspeed,ast2400-scu", "syscon", "simple-mfd"
"aspeed,g4-scu", "syscon", "simple-mfd"
"aspeed,ast2500-scu", "syscon", "simple-mfd"
"aspeed,g5-scu", "syscon", "simple-mfd"
- reg: contains the offset and length of the SCU memory region
Example:
syscon: syscon@1e6e2000 {
compatible = "aspeed,ast2400-scu", "syscon", "simple-mfd";
reg = <0x1e6e2000 0x1a8>;
};
@@ -10,7 +10,8 @@ axp809 (X-Powers)
Required properties:
- compatible: "x-powers,axp152", "x-powers,axp202", "x-powers,axp209",
"x-powers,axp221", "x-powers,axp223", "x-powers,axp809"
"x-powers,axp221", "x-powers,axp223", "x-powers,axp806",
"x-powers,axp809"
- reg: The I2C slave address or RSB hardware address for the AXP chip
- interrupt-parent: The parent interrupt controller
- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
@@ -47,7 +48,6 @@ Optional properties for DCDC regulators:
probably makes sense for HiFi audio related
applications that aren't battery constrained.
AXP202/AXP209 regulators, type, and corresponding input supply names:
Regulator Type Supply Name Notes
@@ -86,6 +86,30 @@ LDO_IO1 : LDO : ips-supply : GPIO 1
RTC_LDO : LDO : ips-supply : always on
DRIVEVBUS : Enable output : drivevbus-supply : external regulator
AXP806 regulators, type, and corresponding input supply names:
Regulator Type Supply Name Notes
--------- ---- ----------- -----
DCDCA : DC-DC buck : vina-supply : poly-phase capable
DCDCB : DC-DC buck : vinb-supply : poly-phase capable
DCDCC : DC-DC buck : vinc-supply : poly-phase capable
DCDCD : DC-DC buck : vind-supply : poly-phase capable
DCDCE : DC-DC buck : vine-supply : poly-phase capable
ALDO1 : LDO : aldoin-supply : shared supply
ALDO2 : LDO : aldoin-supply : shared supply
ALDO3 : LDO : aldoin-supply : shared supply
BLDO1 : LDO : bldoin-supply : shared supply
BLDO2 : LDO : bldoin-supply : shared supply
BLDO3 : LDO : bldoin-supply : shared supply
BLDO4 : LDO : bldoin-supply : shared supply
CLDO1 : LDO : cldoin-supply : shared supply
CLDO2 : LDO : cldoin-supply : shared supply
CLDO3 : LDO : cldoin-supply : shared supply
SW : On/Off Switch : swin-supply
Additionally, the AXP806 DC-DC regulators support poly-phase arrangements
for higher output current. The possible groupings are: A+B, A+B+C, D+E.
AXP809 regulators, type, and corresponding input supply names:
Regulator Type Supply Name Notes
@@ -0,0 +1,59 @@
TI LP873X PMIC MFD driver
Required properties:
- compatible: "ti,lp8732", "ti,lp8733"
- reg: I2C slave address.
- gpio-controller: Marks the device node as a GPIO Controller.
- #gpio-cells: Should be two. The first cell is the pin number and
the second cell is used to specify flags.
See ../gpio/gpio.txt for more information.
- regulators: List of child nodes that specify the regulator
initialization data.
Example:
pmic: lp8733@60 {
compatible = "ti,lp8733";
reg = <0x60>;
gpio-controller;
#gpio-cells = <2>;
regulators {
lp8733_buck0: buck0 {
regulator-name = "lp8733-buck0";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>;
regulator-min-microamp = <1500000>;
regulator-max-microamp = <4000000>;
regulator-ramp-delay = <10000>;
regulator-always-on;
regulator-boot-on;
};
lp8733_buck1: buck1 {
regulator-name = "lp8733-buck1";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1400000>;
regulator-min-microamp = <1500000>;
regulator-max-microamp = <4000000>;
regulator-ramp-delay = <10000>;
regulator-boot-on;
regulator-always-on;
};
lp8733_ldo0: ldo0 {
regulator-name = "lp8733-ldo0";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3000000>;
regulator-boot-on;
regulator-always-on;
};
lp8733_ldo1: ldo1 {
regulator-name = "lp8733-ldo1";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
regulator-boot-on;
};
};
};
@@ -62,6 +62,7 @@ The below bindings specify the set of valid subnodes.
"qcom,pm8058-rtc"
"qcom,pm8921-rtc"
"qcom,pm8941-rtc"
"qcom,pm8018-rtc"
- reg:
Usage: required
@@ -13,6 +13,7 @@ frequencies.
"qcom,rpm-msm8660"
"qcom,rpm-msm8960"
"qcom,rpm-ipq8064"
"qcom,rpm-mdm9615"
- reg:
Usage: required
@@ -59,6 +60,7 @@ Regulator nodes are identified by their compatible:
"qcom,rpm-pm8058-regulators"
"qcom,rpm-pm8901-regulators"
"qcom,rpm-pm8921-regulators"
"qcom,rpm-pm8018-regulators"
- vdd_l0_l1_lvs-supply:
- vdd_l2_l11_l12-supply:
@@ -137,6 +139,15 @@ Regulator nodes are identified by their compatible:
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vin_lvs1-supply:
- vdd_l7-supply:
- vdd_l8-supply:
- vdd_l9_l10_l11_l12-supply:
Usage: optional (pm8018 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
The regulator node houses sub-nodes for each regulator within the device. Each
sub-node is identified using the node's name, with valid values listed for each
of the pmics below.
@@ -156,6 +167,10 @@ pm8921:
l29, lvs1, lvs2, lvs3, lvs4, lvs5, lvs6, lvs7, usb-switch, hdmi-switch,
ncp
pm8018:
s1, s2, s3, s4, s5, , l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
l12, l14, lvs1
The content of each sub-node is defined by the standard binding for regulators -
see regulator.txt - with additional custom properties described below:
@@ -1,7 +1,11 @@
RK808 Power Management Integrated Circuit
RK8XX Power Management Integrated Circuit
The rk8xx family current members:
rk808
rk818
Required properties:
- compatible: "rockchip,rk808"
- compatible: "rockchip,rk808", "rockchip,rk818"
- reg: I2C slave address
- interrupt-parent: The parent interrupt controller.
- interrupts: the interrupt outputs of the controller.
@@ -13,6 +17,8 @@ Optional properties:
default output clock name
- rockchip,system-power-controller: Telling whether or not this pmic is controlling
the system power.
Optional RK808 properties:
- vcc1-supply: The input supply for DCDC_REG1
- vcc2-supply: The input supply for DCDC_REG2
- vcc3-supply: The input supply for DCDC_REG3
@@ -29,7 +35,20 @@ Optional properties:
the gpio controller. If DVS GPIOs aren't present, voltage changes will happen
very quickly with no slow ramp time.
Regulators: All the regulators of RK808 to be instantiated shall be
Optional RK818 properties:
- vcc1-supply: The input supply for DCDC_REG1
- vcc2-supply: The input supply for DCDC_REG2
- vcc3-supply: The input supply for DCDC_REG3
- vcc4-supply: The input supply for DCDC_REG4
- boost-supply: The input supply for DCDC_BOOST
- vcc6-supply: The input supply for LDO_REG1 and LDO_REG2
- vcc7-supply: The input supply for LDO_REG3, LDO_REG5 and LDO_REG7
- vcc8-supply: The input supply for LDO_REG4, LDO_REG6 and LDO_REG8
- vcc9-supply: The input supply for LDO_REG9 and SWITCH_REG
- h_5v-supply: The input supply for HDMI_SWITCH
- usb-supply: The input supply for OTG_SWITCH
Regulators: All the regulators of RK8XX to be instantiated shall be
listed in a child node named 'regulators'. Each regulator is represented
by a child node of the 'regulators' node.
@@ -48,6 +67,18 @@ number as described in RK808 datasheet.
- SWITCH_REGn
- valid values for n are 1 to 2
Following regulators of the RK818 PMIC block are supported. Note that
the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
number as described in RK818 datasheet.
- DCDC_REGn
- valid values for n are 1 to 4.
- LDO_REGn
- valid values for n are 1 to 9.
- SWITCH_REG
- HDMI_SWITCH
- OTG_SWITCH
Standard regulator bindings are used inside regulator subnodes. Check
Documentation/devicetree/bindings/regulator/regulator.txt
for more details
@@ -0,0 +1,70 @@
Samsung Exynos SoC Low Power Audio Subsystem (LPASS)
Required properties:
- compatible : "samsung,exynos5433-lpass"
- reg : should contain the LPASS top SFR region location
and size
- samsung,pmu-syscon : the phandle to the Power Management Unit node
- #address-cells : should be 1
- #size-cells : should be 1
- ranges : must be present
Each IP block of the Low Power Audio Subsystem should be specified as
an optional sub-node. For "samsung,exynos5433-lpass" compatible this includes:
UART, SLIMBUS, PCM, I2S, DMAC, Timers 0...4, VIC, WDT 0...1 devices.
Bindings of the sub-nodes are described in:
../serial/samsung_uart.txt
../sound/samsung-i2s.txt
../dma/arm-pl330.txt
Example:
audio-subsystem {
compatible = "samsung,exynos5433-lpass";
reg = <0x11400000 0x100>, <0x11500000 0x08>;
samsung,pmu-syscon = <&pmu_system_controller>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
adma: adma@11420000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0x11420000 0x1000>;
interrupts = <0 73 0>;
clocks = <&cmu_aud CLK_ACLK_DMAC>;
clock-names = "apb_pclk";
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
};
i2s0: i2s0@11440000 {
compatible = "samsung,exynos7-i2s";
reg = <0x11440000 0x100>;
dmas = <&adma 0 &adma 2>;
dma-names = "tx", "rx";
interrupts = <0 70 0>;
clocks = <&cmu_aud CLK_PCLK_AUD_I2S>,
<&cmu_aud CLK_SCLK_AUD_I2S>,
<&cmu_aud CLK_SCLK_I2S_BCLK>;
clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
pinctrl-names = "default";
pinctrl-0 = <&i2s0_bus>;
status = "disabled";
};
serial_3: serial@11460000 {
compatible = "samsung,exynos5433-uart";
reg = <0x11460000 0x100>;
interrupts = <0 67 0>;
clocks = <&cmu_aud CLK_PCLK_AUD_UART>,
<&cmu_aud CLK_SCLK_AUD_UART>;
clock-names = "uart", "clk_uart_baud0";
pinctrl-names = "default";
pinctrl-0 = <&uart_aud_bus>;
status = "disabled";
};
};
@@ -12,6 +12,7 @@ Required properties:
- interrupt-parent: The parent interrupt controller
- gpio-controller:
- #gpio-cells = <1>: twl6040 provides GPO lines.
- #clock-cells = <0>; twl6040 is a provider of pdmclk which is used by McPDM
- twl6040,audpwron-gpio: Power on GPIO line for the twl6040
- vio-supply: Regulator for the twl6040 VIO supply
+1
View File
@@ -8098,6 +8098,7 @@ MULTIFUNCTION DEVICES (MFD)
M: Lee Jones <lee.jones@linaro.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
S: Supported
F: Documentation/devicetree/bindings/mfd/
F: drivers/mfd/
F: include/linux/mfd/
+32 -105
View File
@@ -27,6 +27,7 @@
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/input/matrix_keypad.h>
@@ -44,6 +45,7 @@
* @dev: Device pointer
* @idev: Input device
* @ec: Top level ChromeOS device to use to talk to EC
* @notifier: interrupt event notifier for transport devices
*/
struct cros_ec_keyb {
unsigned int rows;
@@ -57,6 +59,7 @@ struct cros_ec_keyb {
struct device *dev;
struct input_dev *idev;
struct cros_ec_device *ec;
struct notifier_block notifier;
};
@@ -146,67 +149,44 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev,
input_sync(ckdev->idev);
}
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state)
{
int ret = 0;
struct cros_ec_command *msg;
msg = kmalloc(sizeof(*msg) + ckdev->cols, GFP_KERNEL);
if (!msg)
return -ENOMEM;
msg->version = 0;
msg->command = EC_CMD_MKBP_STATE;
msg->insize = ckdev->cols;
msg->outsize = 0;
ret = cros_ec_cmd_xfer(ckdev->ec, msg);
if (ret < 0) {
dev_err(ckdev->dev, "Error transferring EC message %d\n", ret);
goto exit;
}
memcpy(kb_state, msg->data, ckdev->cols);
exit:
kfree(msg);
return ret;
}
static irqreturn_t cros_ec_keyb_irq(int irq, void *data)
{
struct cros_ec_keyb *ckdev = data;
struct cros_ec_device *ec = ckdev->ec;
int ret;
uint8_t kb_state[ckdev->cols];
if (device_may_wakeup(ec->dev))
pm_wakeup_event(ec->dev, 0);
ret = cros_ec_keyb_get_state(ckdev, kb_state);
if (ret >= 0)
cros_ec_keyb_process(ckdev, kb_state, ret);
else
dev_err(ckdev->dev, "failed to get keyboard state: %d\n", ret);
return IRQ_HANDLED;
}
static int cros_ec_keyb_open(struct input_dev *dev)
{
struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
struct cros_ec_device *ec = ckdev->ec;
return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"cros_ec_keyb", ckdev);
return blocking_notifier_chain_register(&ckdev->ec->event_notifier,
&ckdev->notifier);
}
static void cros_ec_keyb_close(struct input_dev *dev)
{
struct cros_ec_keyb *ckdev = input_get_drvdata(dev);
struct cros_ec_device *ec = ckdev->ec;
free_irq(ec->irq, ckdev);
blocking_notifier_chain_unregister(&ckdev->ec->event_notifier,
&ckdev->notifier);
}
static int cros_ec_keyb_work(struct notifier_block *nb,
unsigned long queued_during_suspend, void *_notify)
{
struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb,
notifier);
if (ckdev->ec->event_data.event_type != EC_MKBP_EVENT_KEY_MATRIX)
return NOTIFY_DONE;
/*
* If EC is not the wake source, discard key state changes during
* suspend.
*/
if (queued_during_suspend)
return NOTIFY_OK;
if (ckdev->ec->event_size != ckdev->cols) {
dev_err(ckdev->dev,
"Discarded incomplete key matrix event.\n");
return NOTIFY_OK;
}
cros_ec_keyb_process(ckdev, ckdev->ec->event_data.data.key_matrix,
ckdev->ec->event_size);
return NOTIFY_OK;
}
/*
@@ -265,12 +245,8 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
if (!idev)
return -ENOMEM;
if (!ec->irq) {
dev_err(dev, "no EC IRQ specified\n");
return -EINVAL;
}
ckdev->ec = ec;
ckdev->notifier.notifier_call = cros_ec_keyb_work;
ckdev->dev = dev;
dev_set_drvdata(dev, ckdev);
@@ -311,54 +287,6 @@ static int cros_ec_keyb_probe(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM_SLEEP
/* Clear any keys in the buffer */
static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev)
{
uint8_t old_state[ckdev->cols];
uint8_t new_state[ckdev->cols];
unsigned long duration;
int i, ret;
/*
* Keep reading until we see that the scan state does not change.
* That indicates that we are done.
*
* Assume that the EC keyscan buffer is at most 32 deep.
*/
duration = jiffies;
ret = cros_ec_keyb_get_state(ckdev, new_state);
for (i = 1; !ret && i < 32; i++) {
memcpy(old_state, new_state, sizeof(old_state));
ret = cros_ec_keyb_get_state(ckdev, new_state);
if (0 == memcmp(old_state, new_state, sizeof(old_state)))
break;
}
duration = jiffies - duration;
dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i,
jiffies_to_usecs(duration));
}
static int cros_ec_keyb_resume(struct device *dev)
{
struct cros_ec_keyb *ckdev = dev_get_drvdata(dev);
/*
* When the EC is not a wake source, then it could not have caused the
* resume, so we clear the EC's key scan buffer. If the EC was a
* wake source (e.g. the lid is open and the user might press a key to
* wake) then the key scan buffer should be preserved.
*/
if (!ckdev->ec->was_wake_device)
cros_ec_keyb_clear_keyboard(ckdev);
return 0;
}
#endif
static SIMPLE_DEV_PM_OPS(cros_ec_keyb_pm_ops, NULL, cros_ec_keyb_resume);
#ifdef CONFIG_OF
static const struct of_device_id cros_ec_keyb_of_match[] = {
{ .compatible = "google,cros-ec-keyb" },
@@ -372,7 +300,6 @@ static struct platform_driver cros_ec_keyb_driver = {
.driver = {
.name = "cros-ec-keyb",
.of_match_table = of_match_ptr(cros_ec_keyb_of_match),
.pm = &cros_ec_keyb_pm_ops,
},
};
+23 -3
View File
@@ -50,7 +50,7 @@ config MFD_AS3711
Support for the AS3711 PMIC from AMS
config MFD_AS3722
bool "ams AS3722 Power Management IC"
tristate "ams AS3722 Power Management IC"
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -112,6 +112,16 @@ config MFD_BCM590XX
help
Support for the BCM590xx PMUs from Broadcom
config MFD_AC100
tristate "X-Powers AC100"
select MFD_CORE
depends on SUNXI_RSB
help
If you say Y here you get support for the X-Powers AC100 audio codec
IC.
This driver include only the core APIs. You have to select individual
components like codecs or RTC under the corresponding menus.
config MFD_AXP20X
tristate
select MFD_CORE
@@ -281,6 +291,14 @@ config MFD_DLN2
etc. must be enabled in order to use the functionality of
the device.
config MFD_EXYNOS_LPASS
tristate "Samsung Exynos SoC Low Power Audio Subsystem"
select MFD_CORE
select REGMAP_MMIO
help
Select this option to enable support for Samsung Exynos Low Power
Audio Subsystem.
config MFD_MC13XXX
tristate
depends on (SPI_MASTER || I2C)
@@ -844,13 +862,13 @@ config MFD_RC5T583
different functionality of the device.
config MFD_RK808
tristate "Rockchip RK808 Power Management chip"
tristate "Rockchip RK808/RK818 Power Management Chip"
depends on I2C && OF
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
help
If you say yes here you get support for the RK808
If you say yes here you get support for the RK808 and RK818
Power Management chips.
This driver provides common support for accessing the device
through I2C interface. The device supports multiple sub-devices
@@ -1206,6 +1224,7 @@ config MFD_TPS65217
depends on I2C
select MFD_CORE
select REGMAP_I2C
select IRQ_DOMAIN
help
If you say yes here you get support for the TPS65217 series of
Power Management / White LED chips.
@@ -1555,6 +1574,7 @@ config MFD_WM8350
config MFD_WM8350_I2C
bool "Wolfson Microelectronics WM8350 with I2C"
select MFD_WM8350
select REGMAP_I2C
depends on I2C=y
help
The WM8350 is an integrated audio and power management
+3
View File
@@ -13,6 +13,7 @@ obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o
obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o
obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
obj-$(CONFIG_MFD_EXYNOS_LPASS) += exynos-lpass.o
rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
@@ -114,6 +115,8 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-irq.o
obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
obj-$(CONFIG_MFD_AC100) += ac100.o
obj-$(CONFIG_MFD_AXP20X) += axp20x.o
obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o
obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o
+24 -94
View File
@@ -153,14 +153,14 @@ static struct hwreg_cfg hwreg_cfg = {
#define AB8500_NAME_STRING "ab8500"
#define AB8500_ADC_NAME_STRING "gpadc"
#define AB8500_NUM_BANKS 24
#define AB8500_NUM_BANKS AB8500_DEBUG_FIELD_LAST
#define AB8500_REV_REG 0x80
static struct ab8500_prcmu_ranges *debug_ranges;
static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
[0x0] = {
[AB8500_M_FSM_RANK] = {
.num_ranges = 0,
.range = NULL,
},
@@ -315,7 +315,7 @@ static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
},
},
},
[0x9] = {
[AB8500_RESERVED] = {
.num_ranges = 0,
.range = NULL,
},
@@ -386,24 +386,6 @@ static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
},
},
},
[AB8500_DEVELOPMENT] = {
.num_ranges = 1,
.range = (struct ab8500_reg_range[]) {
{
.first = 0x00,
.last = 0x00,
},
},
},
[AB8500_DEBUG] = {
.num_ranges = 1,
.range = (struct ab8500_reg_range[]) {
{
.first = 0x05,
.last = 0x07,
},
},
},
[AB8500_AUDIO] = {
.num_ranges = 1,
.range = (struct ab8500_reg_range[]) {
@@ -463,19 +445,29 @@ static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = {
},
},
},
[0x11] = {
[AB8500_DEVELOPMENT] = {
.num_ranges = 1,
.range = (struct ab8500_reg_range[]) {
{
.first = 0x00,
.last = 0x00,
},
},
},
[AB8500_DEBUG] = {
.num_ranges = 1,
.range = (struct ab8500_reg_range[]) {
{
.first = 0x05,
.last = 0x07,
},
},
},
[AB8500_PROD_TEST] = {
.num_ranges = 0,
.range = NULL,
},
[0x12] = {
.num_ranges = 0,
.range = NULL,
},
[0x13] = {
.num_ranges = 0,
.range = NULL,
},
[0x14] = {
[AB8500_STE_TEST] = {
.num_ranges = 0,
.range = NULL,
},
@@ -1382,60 +1374,6 @@ void ab8500_dump_all_banks(struct device *dev)
}
}
/* Space for 500 registers. */
#define DUMP_MAX_REGS 700
static struct ab8500_register_dump
{
u8 bank;
u8 reg;
u8 value;
} ab8500_complete_register_dump[DUMP_MAX_REGS];
/* This shall only be called upon kernel panic! */
void ab8500_dump_all_banks_to_mem(void)
{
int i, r = 0;
u8 bank;
int err = 0;
pr_info("Saving all ABB registers for crash analysis.\n");
for (bank = 0; bank < AB8500_NUM_BANKS; bank++) {
for (i = 0; i < debug_ranges[bank].num_ranges; i++) {
u8 reg;
for (reg = debug_ranges[bank].range[i].first;
reg <= debug_ranges[bank].range[i].last;
reg++) {
u8 value;
err = prcmu_abb_read(bank, reg, &value, 1);
if (err < 0)
goto out;
ab8500_complete_register_dump[r].bank = bank;
ab8500_complete_register_dump[r].reg = reg;
ab8500_complete_register_dump[r].value = value;
r++;
if (r >= DUMP_MAX_REGS) {
pr_err("%s: too many register to dump!\n",
__func__);
err = -EINVAL;
goto out;
}
}
}
}
out:
if (err >= 0)
pr_info("Saved all ABB registers.\n");
else
pr_info("Failed to save all ABB registers.\n");
}
static int ab8500_all_banks_open(struct inode *inode, struct file *file)
{
struct seq_file *s;
@@ -1584,18 +1522,10 @@ static u32 num_interrupts[AB8500_MAX_NR_IRQS];
static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS];
static int num_interrupt_lines;
bool __attribute__((weak)) suspend_test_wake_cause_interrupt_is_mine(u32 my_int)
{
return false;
}
void ab8500_debug_register_interrupt(int line)
{
if (line < num_interrupt_lines) {
if (line < num_interrupt_lines)
num_interrupts[line]++;
if (suspend_test_wake_cause_interrupt_is_mine(irq_ab8500))
num_wake_interrupts[line]++;
}
}
static int ab8500_interrupts_print(struct seq_file *s, void *p)
+137
View File
@@ -0,0 +1,137 @@
/*
* MFD core driver for X-Powers' AC100 Audio Codec IC
*
* The AC100 is a highly integrated audio codec and RTC subsystem designed
* for mobile applications. It has 3 I2S/PCM interfaces, a 2 channel DAC,
* a 2 channel ADC with 5 inputs and a builtin mixer. The RTC subsystem has
* 3 clock outputs.
*
* The audio codec and RTC parts are completely separate, sharing only the
* host interface for access to its registers.
*
* Copyright (2016) Chen-Yu Tsai
*
* Author: Chen-Yu Tsai <wens@csie.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mfd/ac100.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/sunxi-rsb.h>
static const struct regmap_range ac100_writeable_ranges[] = {
regmap_reg_range(AC100_CHIP_AUDIO_RST, AC100_I2S_SR_CTRL),
regmap_reg_range(AC100_I2S1_CLK_CTRL, AC100_I2S1_MXR_GAIN),
regmap_reg_range(AC100_I2S2_CLK_CTRL, AC100_I2S2_MXR_GAIN),
regmap_reg_range(AC100_I2S3_CLK_CTRL, AC100_I2S3_SIG_PATH_CTRL),
regmap_reg_range(AC100_ADC_DIG_CTRL, AC100_ADC_VOL_CTRL),
regmap_reg_range(AC100_HMIC_CTRL1, AC100_HMIC_STATUS),
regmap_reg_range(AC100_DAC_DIG_CTRL, AC100_DAC_MXR_GAIN),
regmap_reg_range(AC100_ADC_APC_CTRL, AC100_LINEOUT_CTRL),
regmap_reg_range(AC100_ADC_DAP_L_CTRL, AC100_ADC_DAP_OPT),
regmap_reg_range(AC100_DAC_DAP_CTRL, AC100_DAC_DAP_OPT),
regmap_reg_range(AC100_ADC_DAP_ENA, AC100_DAC_DAP_ENA),
regmap_reg_range(AC100_SRC1_CTRL1, AC100_SRC1_CTRL2),
regmap_reg_range(AC100_SRC2_CTRL1, AC100_SRC2_CTRL2),
regmap_reg_range(AC100_CLK32K_ANALOG_CTRL, AC100_CLKOUT_CTRL3),
regmap_reg_range(AC100_RTC_RST, AC100_RTC_UPD),
regmap_reg_range(AC100_ALM_INT_ENA, AC100_ALM_INT_STA),
regmap_reg_range(AC100_ALM_SEC, AC100_RTC_GP(15)),
};
static const struct regmap_range ac100_volatile_ranges[] = {
regmap_reg_range(AC100_CHIP_AUDIO_RST, AC100_PLL_CTRL2),
regmap_reg_range(AC100_HMIC_STATUS, AC100_HMIC_STATUS),
regmap_reg_range(AC100_ADC_DAP_L_STA, AC100_ADC_DAP_L_STA),
regmap_reg_range(AC100_SRC1_CTRL1, AC100_SRC1_CTRL1),
regmap_reg_range(AC100_SRC1_CTRL3, AC100_SRC2_CTRL1),
regmap_reg_range(AC100_SRC2_CTRL3, AC100_SRC2_CTRL4),
regmap_reg_range(AC100_RTC_RST, AC100_RTC_RST),
regmap_reg_range(AC100_RTC_SEC, AC100_ALM_INT_STA),
regmap_reg_range(AC100_ALM_SEC, AC100_ALM_UPD),
};
static const struct regmap_access_table ac100_writeable_table = {
.yes_ranges = ac100_writeable_ranges,
.n_yes_ranges = ARRAY_SIZE(ac100_writeable_ranges),
};
static const struct regmap_access_table ac100_volatile_table = {
.yes_ranges = ac100_volatile_ranges,
.n_yes_ranges = ARRAY_SIZE(ac100_volatile_ranges),
};
static const struct regmap_config ac100_regmap_config = {
.reg_bits = 8,
.val_bits = 16,
.wr_table = &ac100_writeable_table,
.volatile_table = &ac100_volatile_table,
.max_register = AC100_RTC_GP(15),
.cache_type = REGCACHE_RBTREE,
};
static struct mfd_cell ac100_cells[] = {
{
.name = "ac100-codec",
.of_compatible = "x-powers,ac100-codec",
}, {
.name = "ac100-rtc",
.of_compatible = "x-powers,ac100-rtc",
},
};
static int ac100_rsb_probe(struct sunxi_rsb_device *rdev)
{
struct ac100_dev *ac100;
int ret;
ac100 = devm_kzalloc(&rdev->dev, sizeof(*ac100), GFP_KERNEL);
if (!ac100)
return -ENOMEM;
ac100->dev = &rdev->dev;
sunxi_rsb_device_set_drvdata(rdev, ac100);
ac100->regmap = devm_regmap_init_sunxi_rsb(rdev, &ac100_regmap_config);
if (IS_ERR(ac100->regmap)) {
ret = PTR_ERR(ac100->regmap);
dev_err(ac100->dev, "regmap init failed: %d\n", ret);
return ret;
}
ret = devm_mfd_add_devices(ac100->dev, PLATFORM_DEVID_NONE, ac100_cells,
ARRAY_SIZE(ac100_cells), NULL, 0, NULL);
if (ret) {
dev_err(ac100->dev, "failed to add MFD devices: %d\n", ret);
return ret;
}
return 0;
}
static const struct of_device_id ac100_of_match[] = {
{ .compatible = "x-powers,ac100" },
{ },
};
MODULE_DEVICE_TABLE(of, ac100_of_match);
static struct sunxi_rsb_driver ac100_rsb_driver = {
.driver = {
.name = "ac100",
.of_match_table = of_match_ptr(ac100_of_match),
},
.probe = ac100_rsb_probe,
};
module_sunxi_rsb_driver(ac100_rsb_driver);
MODULE_DESCRIPTION("Audio codec MFD core driver for AC100");
MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>");
MODULE_LICENSE("GPL v2");
+1
View File
@@ -23,6 +23,7 @@ static const struct mfd_cell act8945a_devs[] = {
},
{
.name = "act8945a-charger",
.of_compatible = "active-semi,act8945a-charger",
},
};
+7 -9
View File
@@ -1,4 +1,8 @@
/*
* Altera Arria10 DevKit System Resource MFD Driver
*
* Author: Thor Thayer <tthayer@opensource.altera.com>
*
* Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,7 +24,7 @@
#include <linux/mfd/altera-a10sr.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/spi/spi.h>
@@ -94,7 +98,7 @@ static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)
}
}
const struct regmap_config altr_a10sr_regmap_config = {
static const struct regmap_config altr_a10sr_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
@@ -152,7 +156,6 @@ static const struct of_device_id altr_a10sr_spi_of_match[] = {
{ .compatible = "altr,a10sr" },
{ },
};
MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match);
static struct spi_driver altr_a10sr_spi_driver = {
.probe = altr_a10sr_spi_probe,
@@ -161,9 +164,4 @@ static struct spi_driver altr_a10sr_spi_driver = {
.of_match_table = of_match_ptr(altr_a10sr_spi_of_match),
},
};
module_spi_driver(altr_a10sr_spi_driver);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>");
MODULE_DESCRIPTION("Altera Arria10 DevKit System Resource MFD Driver");
builtin_driver(altr_a10sr_spi_driver, spi_register_driver)
+81 -32
View File
@@ -10,6 +10,7 @@
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
@@ -49,7 +50,15 @@ int arizona_clk32k_enable(struct arizona *arizona)
case ARIZONA_32KZ_MCLK1:
ret = pm_runtime_get_sync(arizona->dev);
if (ret != 0)
goto out;
goto err_ref;
ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]);
if (ret != 0)
goto err_pm;
break;
case ARIZONA_32KZ_MCLK2:
ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK2]);
if (ret != 0)
goto err_ref;
break;
}
@@ -58,7 +67,9 @@ int arizona_clk32k_enable(struct arizona *arizona)
ARIZONA_CLK_32K_ENA);
}
out:
err_pm:
pm_runtime_put_sync(arizona->dev);
err_ref:
if (ret != 0)
arizona->clk32k_ref--;
@@ -83,6 +94,10 @@ int arizona_clk32k_disable(struct arizona *arizona)
switch (arizona->pdata.clk32k_src) {
case ARIZONA_32KZ_MCLK1:
pm_runtime_put_sync(arizona->dev);
clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK1]);
break;
case ARIZONA_32KZ_MCLK2:
clk_disable_unprepare(arizona->mclk[ARIZONA_MCLK2]);
break;
}
}
@@ -735,7 +750,7 @@ static int arizona_suspend(struct device *dev)
return 0;
}
static int arizona_suspend_late(struct device *dev)
static int arizona_suspend_noirq(struct device *dev)
{
struct arizona *arizona = dev_get_drvdata(dev);
@@ -759,7 +774,7 @@ static int arizona_resume(struct device *dev)
{
struct arizona *arizona = dev_get_drvdata(dev);
dev_dbg(arizona->dev, "Late resume, reenabling IRQ\n");
dev_dbg(arizona->dev, "Resume, reenabling IRQ\n");
enable_irq(arizona->irq);
return 0;
@@ -771,10 +786,8 @@ const struct dev_pm_ops arizona_pm_ops = {
arizona_runtime_resume,
NULL)
SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
#ifdef CONFIG_PM_SLEEP
.suspend_late = arizona_suspend_late,
.resume_noirq = arizona_resume_noirq,
#endif
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(arizona_suspend_noirq,
arizona_resume_noirq)
};
EXPORT_SYMBOL_GPL(arizona_pm_ops);
@@ -790,35 +803,25 @@ unsigned long arizona_of_get_type(struct device *dev)
}
EXPORT_SYMBOL_GPL(arizona_of_get_type);
int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
bool mandatory)
{
int gpio;
gpio = of_get_named_gpio(arizona->dev->of_node, prop, 0);
if (gpio < 0) {
if (mandatory)
dev_err(arizona->dev,
"Mandatory DT gpio %s missing/malformed: %d\n",
prop, gpio);
gpio = 0;
}
return gpio;
}
EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio);
static int arizona_of_get_core_pdata(struct arizona *arizona)
{
struct arizona_pdata *pdata = &arizona->pdata;
struct property *prop;
const __be32 *cur;
u32 val;
u32 pdm_val[ARIZONA_MAX_PDM_SPK];
int ret, i;
int count = 0;
pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true);
pdata->reset = of_get_named_gpio(arizona->dev->of_node, "wlf,reset", 0);
if (pdata->reset == -EPROBE_DEFER) {
return pdata->reset;
} else if (pdata->reset < 0) {
dev_err(arizona->dev, "Reset GPIO missing/malformed: %d\n",
pdata->reset);
pdata->reset = 0;
}
ret = of_property_read_u32_array(arizona->dev->of_node,
"wlf,gpio-defaults",
@@ -871,6 +874,35 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
count++;
}
count = 0;
of_property_for_each_u32(arizona->dev->of_node,
"wlf,max-channels-clocked",
prop, cur, val) {
if (count == ARRAY_SIZE(pdata->max_channels_clocked))
break;
pdata->max_channels_clocked[count] = val;
count++;
}
ret = of_property_read_u32_array(arizona->dev->of_node,
"wlf,spk-fmt",
pdm_val,
ARRAY_SIZE(pdm_val));
if (ret >= 0)
for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
pdata->spk_fmt[count] = pdm_val[count];
ret = of_property_read_u32_array(arizona->dev->of_node,
"wlf,spk-mute",
pdm_val,
ARRAY_SIZE(pdm_val));
if (ret >= 0)
for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
pdata->spk_mute[count] = pdm_val[count];
return 0;
}
@@ -1000,6 +1032,7 @@ static const struct mfd_cell wm8998_devs[] = {
int arizona_dev_init(struct arizona *arizona)
{
const char * const mclk_name[] = { "mclk1", "mclk2" };
struct device *dev = arizona->dev;
const char *type_name = NULL;
unsigned int reg, val, mask;
@@ -1010,11 +1043,24 @@ int arizona_dev_init(struct arizona *arizona)
dev_set_drvdata(arizona->dev, arizona);
mutex_init(&arizona->clk_lock);
if (dev_get_platdata(arizona->dev))
if (dev_get_platdata(arizona->dev)) {
memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
sizeof(arizona->pdata));
else
arizona_of_get_core_pdata(arizona);
} else {
ret = arizona_of_get_core_pdata(arizona);
if (ret < 0)
return ret;
}
BUILD_BUG_ON(ARRAY_SIZE(arizona->mclk) != ARRAY_SIZE(mclk_name));
for (i = 0; i < ARRAY_SIZE(arizona->mclk); i++) {
arizona->mclk[i] = devm_clk_get(arizona->dev, mclk_name[i]);
if (IS_ERR(arizona->mclk[i])) {
dev_info(arizona->dev, "Failed to get %s: %ld\n",
mclk_name[i], PTR_ERR(arizona->mclk[i]));
arizona->mclk[i] = NULL;
}
}
regcache_cache_only(arizona->regmap, true);
@@ -1035,7 +1081,7 @@ int arizona_dev_init(struct arizona *arizona)
default:
dev_err(arizona->dev, "Unknown device type %d\n",
arizona->type);
return -EINVAL;
return -ENODEV;
}
/* Mark DCVDD as external, LDO1 driver will clear if internal */
@@ -1121,6 +1167,7 @@ int arizona_dev_init(struct arizona *arizona)
break;
default:
dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
ret = -ENODEV;
goto err_reset;
}
@@ -1280,12 +1327,14 @@ int arizona_dev_init(struct arizona *arizona)
break;
default:
dev_err(arizona->dev, "Unknown device ID %x\n", reg);
ret = -ENODEV;
goto err_reset;
}
if (!subdevs) {
dev_err(arizona->dev,
"No kernel support for device ID %x\n", reg);
ret = -ENODEV;
goto err_reset;
}

Some files were not shown because too many files have changed in this diff Show More