- New Device Support
- Add support for AXP813 ADC to AXP20x - Add support for PM8005, PM8998 and PMI8998 - New Functionality - Add support for Battery Power Supply to AXP813 - Add support for SYSCON to SPARD SC27XX SPI - Add support for RTC to ChromeOS Embedded-Controller - Fix-ups - Remove unused code; exynos{4,5}-pmu, cros_ec, cros_ec_acpi_gpe - Remove duplicate error messages (-ENOMEM, etc); htc-i2cpld, janz-cmodio, max8997, rc5t583, sm501, smsc-ece1099, abx500-core, si476x-i2c, ti_am335x_tscadc, tps65090, tps6586x, tps65910, tps80031, twl6030-irq, viperboard - Succinctly use ptr to struct in sizeof(); rc5t583, abx500-core, sm501, smsc-ece1099 - Simplify syntax for NULL ptr checking; abx500-core, sm501 - No not unnecessarily initialise variables; tps65910, tps65910 - Reorganise and simplify driver data; omap-usb-tll - Move to SPDX license statement; tps68470 - Probe ADCs via DT; axp20x - Use new GPIOD API; arizona-core - Constify things; axp20x - Reduce code-size (use MACROS, etc); axp20x, omap-usb-host - Add DT support/docs; motorola-cpcap - Remove VLAs; rave-sp - Use devm_* managed resources; cros_ec - Interrogate HW for firmware version; rave-sp - Provide ACPI support for ChromeOS Embedded-Controller - Bug Fixes - Reorder ordered (enum) device list; tps65218 - Only accept valid data from the offset; rave-sp - Refrain from copying junk from failed SPI read; cros_ec_dev - Fix potential memory leaks; pcf50633-core - Fix clock initialisation; twl-core - Fix build-issue; tps65911 - Fix off-by-one error; tps65911 - Fix code ordering issues; intel-lpss - Fix COMPILE_TEST related issues; pwm-stm32 - Fix broken MMC card detection; asic3 - Fix clocking related issues; intel-lpss-pci -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAlsea+sACgkQUa+KL4f8 d2Fc+A//aaFlfHfJh337tvmJ6wC8w13jjXn0f2M2NrCvRS1CoMF/WqSmJbFGguET gwv4v8Yf5mWe9crJfSLR4b6hlNWfvzK9Rxwy1WJ8sfnN7a71SIS6LlapxQwZ0S5o 3tQ8n2YKdIyy6feATKnxzRi6IvTjTsIe6BRYev2+m23cEqxoI7b6xo0H1CApVXez vEnPaT08421qZ2vuPx3UW3JgwWMTYe4iazq1BRkveZZBdyQC+GLpdpoJIO5/OziF Wgn01Hluu11YuAPidxtmLCAI23RcqLNcPB0zu6//CG5+ut71qnQRs6ua4R352nME G6aMRVCTR1b0XY48MK+IOLb7mPCCUByHdvdaonzBd48dIrX6k//kVzYxNKY1vlmk //l/cYhnHBZxGvJAvCmtyi+4AjGz0aLcabY6S7qHMvpNMQ7oNU9FDomJXxynjXg9 ulDkA4EJy6jlWDS6h0u99xycyLuQ4wKo997/Sl5SU+9FBFrdOor2q7R4KfIXQsG9 VGZXi2kWBO9V9oFbbo1oyZ52hDiCy2TKz6fk0rdRltOpVMd4PYluETc4nmnWDo5W hvjP3rIJSSSIcpggOoQMp5L03cONPGP4MdiuCXOREc6q476CFtpEgJMWApgaEUjw e1SE8HMKounqw0JYLVz3Lf0RbcHPuR1PN5HDbrchDb8LaAAyCcA= =NF/E -----END PGP SIGNATURE----- Merge tag 'mfd-next-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "New Device Support: - Add support for AXP813 ADC to AXP20x - Add support for PM8005, PM8998 and PMI8998 New Functionality: - Add support for Battery Power Supply to AXP813 - Add support for SYSCON to SPARD SC27XX SPI - Add support for RTC to ChromeOS Embedded-Controller Fix-ups: - Remove unused code; exynos{4,5}-pmu, cros_ec, cros_ec_acpi_gpe - Remove duplicate error messages (-ENOMEM, etc); htc-i2cpld, janz-cmodio, max8997, rc5t583, sm501, smsc-ece1099, abx500-core, si476x-i2c, ti_am335x_tscadc, tps65090, tps6586x, tps65910, tps80031, twl6030-irq, viperboard - Succinctly use ptr to struct in sizeof(); rc5t583, abx500-core, sm501, smsc-ece1099 - Simplify syntax for NULL ptr checking; abx500-core, sm501 - No not unnecessarily initialise variables; tps65910, tps65910 - Reorganise and simplify driver data; omap-usb-tll - Move to SPDX license statement; tps68470 - Probe ADCs via DT; axp20x - Use new GPIOD API; arizona-core - Constify things; axp20x - Reduce code-size (use MACROS, etc); axp20x, omap-usb-host - Add DT support/docs; motorola-cpcap - Remove VLAs; rave-sp - Use devm_* managed resources; cros_ec - Interrogate HW for firmware version; rave-sp - Provide ACPI support for ChromeOS Embedded-Controller Bug Fixes: - Reorder ordered (enum) device list; tps65218 - Only accept valid data from the offset; rave-sp - Refrain from copying junk from failed SPI read; cros_ec_dev - Fix potential memory leaks; pcf50633-core - Fix clock initialisation; twl-core - Fix build-issue; tps65911 - Fix off-by-one error; tps65911 - Fix code ordering issues; intel-lpss - Fix COMPILE_TEST related issues; pwm-stm32 - Fix broken MMC card detection; asic3 - Fix clocking related issues; intel-lpss-pci" * tag 'mfd-next-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (84 commits) mfd: cros_ec: Remove unused __remove function mfd: wm97xx-core: Platform data can be NULL mfd: cros_ec_dev: Don't advertise junk features on failure mfd: cros_ec: Use devm_kzalloc for private data mfd: intel-lpss: Fix Intel Cannon Lake LPSS I2C input clock mfd: asic3: Fix broken MMC card detection mfd: timberdale: Fix spelling mistake "Uknown" -> "Unknown" mfd: omap-usb-host: Use match_string() helper mfd: stm32-timers: Fix pwm-stm32 linker issue with COMPILE_TEST pwm: stm32: Initialize raw local variables mfd: arizona: Update DT doc to support more standard Reset binding dt-bindings: mfd: Add bindings for DA9063L mfd: intel-lpss: Correct names of RESETS register bits mfd: qcom-spmi-pmic: Add support for pm8005, pm8998 and pmi8998 mfd: intel-lpss: Program REMAP register in PIO mode mfd: cros_ec_i2c: Moving the system sleep pm ops to late mfd: cros_ec_i2c: Add ACPI module device table mfd: cros_ec_dev: Register shutdown function for debugfs mfd: cros_ec_dev: Register cros-ec-rtc driver as a subdevice mfd: cros_ec: Don't try to grab log when suspended ...
This commit is contained in:
commit
883cad5ba8
|
@ -0,0 +1,43 @@
|
|||
MediaTek MT6397/MT6323 PMIC Keys Device Driver
|
||||
|
||||
There are two key functions provided by MT6397/MT6323 PMIC, pwrkey
|
||||
and homekey. The key functions are defined as the subnode of the function
|
||||
node provided by MT6397/MT6323 PMIC that is being defined as one kind
|
||||
of Muti-Function Device (MFD)
|
||||
|
||||
For MT6397/MT6323 MFD bindings see:
|
||||
Documentation/devicetree/bindings/mfd/mt6397.txt
|
||||
|
||||
Required properties:
|
||||
- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
|
||||
- linux,keycodes: See Documentation/devicetree/bindings/input/keys.txt
|
||||
|
||||
Optional Properties:
|
||||
- wakeup-source: See Documentation/devicetree/bindings/power/wakeup-source.txt
|
||||
- mediatek,long-press-mode: Long press key shutdown setting, 1 for
|
||||
pwrkey only, 2 for pwrkey/homekey together, others for disabled.
|
||||
- power-off-time-sec: See Documentation/devicetree/bindings/input/keys.txt
|
||||
|
||||
Example:
|
||||
|
||||
pmic: mt6397 {
|
||||
compatible = "mediatek,mt6397";
|
||||
|
||||
...
|
||||
|
||||
mt6397keys: mt6397keys {
|
||||
compatible = "mediatek,mt6397-keys";
|
||||
mediatek,long-press-mode = <1>;
|
||||
power-off-time-sec = <0>;
|
||||
|
||||
power {
|
||||
linux,keycodes = <116>;
|
||||
wakeup-source;
|
||||
};
|
||||
|
||||
home {
|
||||
linux,keycodes = <114>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
|
@ -50,7 +50,7 @@ Required properties:
|
|||
|
||||
Optional properties:
|
||||
|
||||
- wlf,reset : GPIO specifier for the GPIO controlling /RESET
|
||||
- reset-gpios : GPIO specifier for the GPIO controlling /RESET
|
||||
|
||||
- clocks: Should reference the clocks supplied on MCLK1 and MCLK2
|
||||
- clock-names: Should contains two strings:
|
||||
|
@ -70,6 +70,10 @@ Optional properties:
|
|||
Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
(wm5102, wm5110, wm8280, wm8997, wm8998, wm1814)
|
||||
|
||||
Deprecated properties:
|
||||
|
||||
- wlf,reset : GPIO specifier for the GPIO controlling /RESET
|
||||
|
||||
Also see child specific device properties:
|
||||
Regulator - ../regulator/arizona-regulator.txt
|
||||
Extcon - ../extcon/extcon-arizona.txt
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
* Dialog DA9063 Power Management Integrated Circuit (PMIC)
|
||||
* Dialog DA9063/DA9063L Power Management Integrated Circuit (PMIC)
|
||||
|
||||
DA9093 consists of a large and varied group of sub-devices (I2C Only):
|
||||
|
||||
|
@ -6,14 +6,14 @@ Device Supply Names Description
|
|||
------ ------------ -----------
|
||||
da9063-regulator : : LDOs & BUCKs
|
||||
da9063-onkey : : On Key
|
||||
da9063-rtc : : Real-Time Clock
|
||||
da9063-rtc : : Real-Time Clock (DA9063 only)
|
||||
da9063-watchdog : : Watchdog
|
||||
|
||||
======
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : Should be "dlg,da9063"
|
||||
- compatible : Should be "dlg,da9063" or "dlg,da9063l"
|
||||
- reg : Specifies the I2C slave address (this defaults to 0x58 but it can be
|
||||
modified to match the chip's OTP settings).
|
||||
- interrupt-parent : Specifies the reference to the interrupt controller for
|
||||
|
@ -23,8 +23,8 @@ Required properties:
|
|||
|
||||
Sub-nodes:
|
||||
|
||||
- regulators : This node defines the settings for the LDOs and BUCKs. The
|
||||
DA9063 regulators are bound using their names listed below:
|
||||
- regulators : This node defines the settings for the LDOs and BUCKs.
|
||||
The DA9063(L) regulators are bound using their names listed below:
|
||||
|
||||
bcore1 : BUCK CORE1
|
||||
bcore2 : BUCK CORE2
|
||||
|
@ -32,16 +32,16 @@ Sub-nodes:
|
|||
bmem : BUCK MEM
|
||||
bio : BUCK IO
|
||||
bperi : BUCK PERI
|
||||
ldo1 : LDO_1
|
||||
ldo2 : LDO_2
|
||||
ldo1 : LDO_1 (DA9063 only)
|
||||
ldo2 : LDO_2 (DA9063 only)
|
||||
ldo3 : LDO_3
|
||||
ldo4 : LDO_4
|
||||
ldo5 : LDO_5
|
||||
ldo6 : LDO_6
|
||||
ldo4 : LDO_4 (DA9063 only)
|
||||
ldo5 : LDO_5 (DA9063 only)
|
||||
ldo6 : LDO_6 (DA9063 only)
|
||||
ldo7 : LDO_7
|
||||
ldo8 : LDO_8
|
||||
ldo9 : LDO_9
|
||||
ldo10 : LDO_10
|
||||
ldo10 : LDO_10 (DA9063 only)
|
||||
ldo11 : LDO_11
|
||||
|
||||
The component follows the standard regulator framework and the bindings
|
||||
|
@ -49,8 +49,9 @@ Sub-nodes:
|
|||
Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
- rtc : This node defines settings for the Real-Time Clock associated with
|
||||
the DA9063. There are currently no entries in this binding, however
|
||||
compatible = "dlg,da9063-rtc" should be added if a node is created.
|
||||
the DA9063 only. The RTC is not present in DA9063L. There are currently
|
||||
no entries in this binding, however compatible = "dlg,da9063-rtc" should
|
||||
be added if a node is created.
|
||||
|
||||
- onkey : This node defines the OnKey settings for controlling the key
|
||||
functionality of the device. The node should contain the compatible property
|
||||
|
@ -65,8 +66,9 @@ Sub-nodes:
|
|||
and KEY_SLEEP.
|
||||
|
||||
- watchdog : This node defines settings for the Watchdog timer associated
|
||||
with the DA9063. There are currently no entries in this binding, however
|
||||
compatible = "dlg,da9063-watchdog" should be added if a node is created.
|
||||
with the DA9063 and DA9063L. There are currently no entries in this
|
||||
binding, however compatible = "dlg,da9063-watchdog" should be added
|
||||
if a node is created.
|
||||
|
||||
|
||||
Example:
|
||||
|
|
|
@ -12,6 +12,30 @@ Required properties:
|
|||
- spi-max-frequency : Typically set to 3000000
|
||||
- spi-cs-high : SPI chip select direction
|
||||
|
||||
Optional subnodes:
|
||||
|
||||
The sub-functions of CPCAP get their own node with their own compatible values,
|
||||
which are described in the following files:
|
||||
|
||||
- ../power/supply/cpcap-battery.txt
|
||||
- ../power/supply/cpcap-charger.txt
|
||||
- ../regulator/cpcap-regulator.txt
|
||||
- ../phy/phy-cpcap-usb.txt
|
||||
- ../input/cpcap-pwrbutton.txt
|
||||
- ../rtc/cpcap-rtc.txt
|
||||
- ../leds/leds-cpcap.txt
|
||||
- ../iio/adc/cpcap-adc.txt
|
||||
|
||||
The only exception is the audio codec. Instead of a compatible value its
|
||||
node must be named "audio-codec".
|
||||
|
||||
Required properties for the audio-codec subnode:
|
||||
|
||||
- #sound-dai-cells = <1>;
|
||||
|
||||
The audio-codec provides two DAIs. The first one is connected to the
|
||||
Stereo HiFi DAC and the second one is connected to the Voice DAC.
|
||||
|
||||
Example:
|
||||
|
||||
&mcspi1 {
|
||||
|
@ -26,6 +50,24 @@ Example:
|
|||
#size-cells = <0>;
|
||||
spi-max-frequency = <3000000>;
|
||||
spi-cs-high;
|
||||
|
||||
audio-codec {
|
||||
#sound-dai-cells = <1>;
|
||||
|
||||
/* HiFi */
|
||||
port@0 {
|
||||
endpoint {
|
||||
remote-endpoint = <&cpu_dai1>;
|
||||
};
|
||||
};
|
||||
|
||||
/* Voice */
|
||||
port@1 {
|
||||
endpoint {
|
||||
remote-endpoint = <&cpu_dai2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ MT6397/MT6323 is a multifunction device with the following sub modules:
|
|||
- GPIO
|
||||
- Clock
|
||||
- LED
|
||||
- Keys
|
||||
|
||||
It is interfaced to host controller using SPI interface by a proprietary hardware
|
||||
called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
|
||||
|
@ -40,6 +41,11 @@ Optional subnodes:
|
|||
- compatible: "mediatek,mt6323-led"
|
||||
see Documentation/devicetree/bindings/leds/leds-mt6323.txt
|
||||
|
||||
- keys
|
||||
Required properties:
|
||||
- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
|
||||
see Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
|
||||
|
||||
Example:
|
||||
pwrap: pwrap@1000f000 {
|
||||
compatible = "mediatek,mt8135-pwrap";
|
||||
|
|
|
@ -29,6 +29,9 @@ Required properties:
|
|||
"qcom,pm8916",
|
||||
"qcom,pm8004",
|
||||
"qcom,pm8909",
|
||||
"qcom,pm8998",
|
||||
"qcom,pmi8998",
|
||||
"qcom,pm8005",
|
||||
or generalized "qcom,spmi-pmic".
|
||||
- reg: Specifies the SPMI USID slave address for this device.
|
||||
For more information see:
|
||||
|
|
10
MAINTAINERS
10
MAINTAINERS
|
@ -13562,6 +13562,16 @@ T: git git://linuxtv.org/media_tree.git
|
|||
S: Maintained
|
||||
F: drivers/media/usb/stk1160/
|
||||
|
||||
STM32 TIMER/LPTIMER DRIVERS
|
||||
M: Fabrice Gasnier <fabrice.gasnier@st.com>
|
||||
S: Maintained
|
||||
F: drivers/*/stm32-*timer*
|
||||
F: drivers/pwm/pwm-stm32*
|
||||
F: include/linux/*/stm32-*tim*
|
||||
F: Documentation/ABI/testing/*timer-stm32
|
||||
F: Documentation/devicetree/bindings/*/stm32-*timer
|
||||
F: Documentation/devicetree/bindings/pwm/pwm-stm32*
|
||||
|
||||
STMMAC ETHERNET DRIVER
|
||||
M: Giuseppe Cavallaro <peppe.cavallaro@st.com>
|
||||
M: Alexandre Torgue <alexandre.torgue@st.com>
|
||||
|
|
|
@ -747,4 +747,13 @@ config KEYBOARD_BCM
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called bcm-keypad.
|
||||
|
||||
config KEYBOARD_MTK_PMIC
|
||||
tristate "MediaTek PMIC keys support"
|
||||
depends on MFD_MT6397
|
||||
help
|
||||
Say Y here if you want to use the pmic keys (powerkey/homekey).
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called pmic-keys.
|
||||
|
||||
endif
|
||||
|
|
|
@ -40,6 +40,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o
|
|||
obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o
|
||||
obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o
|
||||
obj-$(CONFIG_KEYBOARD_MTK_PMIC) += mtk-pmic-keys.o
|
||||
obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o
|
||||
obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o
|
||||
obj-$(CONFIG_KEYBOARD_NSPIRE) += nspire-keypad.o
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* Copyright (C) 2017 MediaTek, Inc.
|
||||
*
|
||||
* Author: Chen Zhong <chen.zhong@mediatek.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/mt6323/registers.h>
|
||||
#include <linux/mfd/mt6397/registers.h>
|
||||
#include <linux/mfd/mt6397/core.h>
|
||||
|
||||
#define MTK_PMIC_PWRKEY_RST_EN_MASK 0x1
|
||||
#define MTK_PMIC_PWRKEY_RST_EN_SHIFT 6
|
||||
#define MTK_PMIC_HOMEKEY_RST_EN_MASK 0x1
|
||||
#define MTK_PMIC_HOMEKEY_RST_EN_SHIFT 5
|
||||
#define MTK_PMIC_RST_DU_MASK 0x3
|
||||
#define MTK_PMIC_RST_DU_SHIFT 8
|
||||
|
||||
#define MTK_PMIC_PWRKEY_RST \
|
||||
(MTK_PMIC_PWRKEY_RST_EN_MASK << MTK_PMIC_PWRKEY_RST_EN_SHIFT)
|
||||
#define MTK_PMIC_HOMEKEY_RST \
|
||||
(MTK_PMIC_HOMEKEY_RST_EN_MASK << MTK_PMIC_HOMEKEY_RST_EN_SHIFT)
|
||||
|
||||
#define MTK_PMIC_PWRKEY_INDEX 0
|
||||
#define MTK_PMIC_HOMEKEY_INDEX 1
|
||||
#define MTK_PMIC_MAX_KEY_COUNT 2
|
||||
|
||||
struct mtk_pmic_keys_regs {
|
||||
u32 deb_reg;
|
||||
u32 deb_mask;
|
||||
u32 intsel_reg;
|
||||
u32 intsel_mask;
|
||||
};
|
||||
|
||||
#define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_mask, \
|
||||
_intsel_reg, _intsel_mask) \
|
||||
{ \
|
||||
.deb_reg = _deb_reg, \
|
||||
.deb_mask = _deb_mask, \
|
||||
.intsel_reg = _intsel_reg, \
|
||||
.intsel_mask = _intsel_mask, \
|
||||
}
|
||||
|
||||
struct mtk_pmic_regs {
|
||||
const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT];
|
||||
u32 pmic_rst_reg;
|
||||
};
|
||||
|
||||
static const struct mtk_pmic_regs mt6397_regs = {
|
||||
.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS,
|
||||
0x8, MT6397_INT_RSV, 0x10),
|
||||
.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2,
|
||||
0x10, MT6397_INT_RSV, 0x8),
|
||||
.pmic_rst_reg = MT6397_TOP_RST_MISC,
|
||||
};
|
||||
|
||||
static const struct mtk_pmic_regs mt6323_regs = {
|
||||
.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
|
||||
0x2, MT6323_INT_MISC_CON, 0x10),
|
||||
.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
|
||||
MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS,
|
||||
0x4, MT6323_INT_MISC_CON, 0x8),
|
||||
.pmic_rst_reg = MT6323_TOP_RST_MISC,
|
||||
};
|
||||
|
||||
struct mtk_pmic_keys_info {
|
||||
struct mtk_pmic_keys *keys;
|
||||
const struct mtk_pmic_keys_regs *regs;
|
||||
unsigned int keycode;
|
||||
int irq;
|
||||
bool wakeup:1;
|
||||
};
|
||||
|
||||
struct mtk_pmic_keys {
|
||||
struct input_dev *input_dev;
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct mtk_pmic_keys_info keys[MTK_PMIC_MAX_KEY_COUNT];
|
||||
};
|
||||
|
||||
enum mtk_pmic_keys_lp_mode {
|
||||
LP_DISABLE,
|
||||
LP_ONEKEY,
|
||||
LP_TWOKEY,
|
||||
};
|
||||
|
||||
static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys,
|
||||
u32 pmic_rst_reg)
|
||||
{
|
||||
int ret;
|
||||
u32 long_press_mode, long_press_debounce;
|
||||
|
||||
ret = of_property_read_u32(keys->dev->of_node,
|
||||
"power-off-time-sec", &long_press_debounce);
|
||||
if (ret)
|
||||
long_press_debounce = 0;
|
||||
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT,
|
||||
long_press_debounce << MTK_PMIC_RST_DU_SHIFT);
|
||||
|
||||
ret = of_property_read_u32(keys->dev->of_node,
|
||||
"mediatek,long-press-mode", &long_press_mode);
|
||||
if (ret)
|
||||
long_press_mode = LP_DISABLE;
|
||||
|
||||
switch (long_press_mode) {
|
||||
case LP_ONEKEY:
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_PWRKEY_RST,
|
||||
MTK_PMIC_PWRKEY_RST);
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_HOMEKEY_RST,
|
||||
0);
|
||||
break;
|
||||
case LP_TWOKEY:
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_PWRKEY_RST,
|
||||
MTK_PMIC_PWRKEY_RST);
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_HOMEKEY_RST,
|
||||
MTK_PMIC_HOMEKEY_RST);
|
||||
break;
|
||||
case LP_DISABLE:
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_PWRKEY_RST,
|
||||
0);
|
||||
regmap_update_bits(keys->regmap, pmic_rst_reg,
|
||||
MTK_PMIC_HOMEKEY_RST,
|
||||
0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t mtk_pmic_keys_irq_handler_thread(int irq, void *data)
|
||||
{
|
||||
struct mtk_pmic_keys_info *info = data;
|
||||
u32 key_deb, pressed;
|
||||
|
||||
regmap_read(info->keys->regmap, info->regs->deb_reg, &key_deb);
|
||||
|
||||
key_deb &= info->regs->deb_mask;
|
||||
|
||||
pressed = !key_deb;
|
||||
|
||||
input_report_key(info->keys->input_dev, info->keycode, pressed);
|
||||
input_sync(info->keys->input_dev);
|
||||
|
||||
dev_dbg(info->keys->dev, "(%s) key =%d using PMIC\n",
|
||||
pressed ? "pressed" : "released", info->keycode);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys,
|
||||
struct mtk_pmic_keys_info *info)
|
||||
{
|
||||
int ret;
|
||||
|
||||
info->keys = keys;
|
||||
|
||||
ret = regmap_update_bits(keys->regmap, info->regs->intsel_reg,
|
||||
info->regs->intsel_mask,
|
||||
info->regs->intsel_mask);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = devm_request_threaded_irq(keys->dev, info->irq, NULL,
|
||||
mtk_pmic_keys_irq_handler_thread,
|
||||
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
|
||||
"mtk-pmic-keys", info);
|
||||
if (ret) {
|
||||
dev_err(keys->dev, "Failed to request IRQ: %d: %d\n",
|
||||
info->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
input_set_capability(keys->input_dev, EV_KEY, info->keycode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev)
|
||||
{
|
||||
struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
|
||||
int index;
|
||||
|
||||
for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
|
||||
if (keys->keys[index].wakeup)
|
||||
enable_irq_wake(keys->keys[index].irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused mtk_pmic_keys_resume(struct device *dev)
|
||||
{
|
||||
struct mtk_pmic_keys *keys = dev_get_drvdata(dev);
|
||||
int index;
|
||||
|
||||
for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
|
||||
if (keys->keys[index].wakeup)
|
||||
disable_irq_wake(keys->keys[index].irq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(mtk_pmic_keys_pm_ops, mtk_pmic_keys_suspend,
|
||||
mtk_pmic_keys_resume);
|
||||
|
||||
static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt6397-keys",
|
||||
.data = &mt6397_regs,
|
||||
}, {
|
||||
.compatible = "mediatek,mt6323-keys",
|
||||
.data = &mt6323_regs,
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_mtk_pmic_keys_match_tbl);
|
||||
|
||||
static int mtk_pmic_keys_probe(struct platform_device *pdev)
|
||||
{
|
||||
int error, index = 0;
|
||||
unsigned int keycount;
|
||||
struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent);
|
||||
struct device_node *node = pdev->dev.of_node, *child;
|
||||
struct mtk_pmic_keys *keys;
|
||||
const struct mtk_pmic_regs *mtk_pmic_regs;
|
||||
struct input_dev *input_dev;
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(of_mtk_pmic_keys_match_tbl, &pdev->dev);
|
||||
|
||||
keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL);
|
||||
if (!keys)
|
||||
return -ENOMEM;
|
||||
|
||||
keys->dev = &pdev->dev;
|
||||
keys->regmap = pmic_chip->regmap;
|
||||
mtk_pmic_regs = of_id->data;
|
||||
|
||||
keys->input_dev = input_dev = devm_input_allocate_device(keys->dev);
|
||||
if (!input_dev) {
|
||||
dev_err(keys->dev, "input allocate device fail.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
input_dev->name = "mtk-pmic-keys";
|
||||
input_dev->id.bustype = BUS_HOST;
|
||||
input_dev->id.vendor = 0x0001;
|
||||
input_dev->id.product = 0x0001;
|
||||
input_dev->id.version = 0x0001;
|
||||
|
||||
keycount = of_get_available_child_count(node);
|
||||
if (keycount > MTK_PMIC_MAX_KEY_COUNT) {
|
||||
dev_err(keys->dev, "too many keys defined (%d)\n", keycount);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for_each_child_of_node(node, child) {
|
||||
keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];
|
||||
|
||||
keys->keys[index].irq = platform_get_irq(pdev, index);
|
||||
if (keys->keys[index].irq < 0)
|
||||
return keys->keys[index].irq;
|
||||
|
||||
error = of_property_read_u32(child,
|
||||
"linux,keycodes", &keys->keys[index].keycode);
|
||||
if (error) {
|
||||
dev_err(keys->dev,
|
||||
"failed to read key:%d linux,keycode property: %d\n",
|
||||
index, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (of_property_read_bool(child, "wakeup-source"))
|
||||
keys->keys[index].wakeup = true;
|
||||
|
||||
error = mtk_pmic_key_setup(keys, &keys->keys[index]);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
error = input_register_device(input_dev);
|
||||
if (error) {
|
||||
dev_err(&pdev->dev,
|
||||
"register input device failed (%d)\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs->pmic_rst_reg);
|
||||
|
||||
platform_set_drvdata(pdev, keys);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver pmic_keys_pdrv = {
|
||||
.probe = mtk_pmic_keys_probe,
|
||||
.driver = {
|
||||
.name = "mtk-pmic-keys",
|
||||
.of_match_table = of_mtk_pmic_keys_match_tbl,
|
||||
.pm = &mtk_pmic_keys_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(pmic_keys_pdrv);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Chen Zhong <chen.zhong@mediatek.com>");
|
||||
MODULE_DESCRIPTION("MTK pmic-keys driver v0.1");
|
|
@ -13,7 +13,6 @@ obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
|
|||
obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
|
||||
obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o
|
||||
cros_ec_core-objs := cros_ec.o
|
||||
cros_ec_core-$(CONFIG_ACPI) += cros_ec_acpi_gpe.o
|
||||
obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o
|
||||
obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o
|
||||
obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
|
||||
|
|
|
@ -2519,11 +2519,10 @@ static ssize_t ab8500_subscribe_write(struct file *file,
|
|||
if (!dev_attr[irq_index])
|
||||
return -ENOMEM;
|
||||
|
||||
event_name[irq_index] = kmalloc(count, GFP_KERNEL);
|
||||
event_name[irq_index] = kasprintf(GFP_KERNEL, "%lu", user_val);
|
||||
if (!event_name[irq_index])
|
||||
return -ENOMEM;
|
||||
|
||||
sprintf(event_name[irq_index], "%lu", user_val);
|
||||
dev_attr[irq_index]->show = show_irq;
|
||||
dev_attr[irq_index]->store = NULL;
|
||||
dev_attr[irq_index]->attr.name = event_name[irq_index];
|
||||
|
|
|
@ -37,15 +37,12 @@ int abx500_register_ops(struct device *dev, struct abx500_ops *ops)
|
|||
{
|
||||
struct abx500_device_entry *dev_entry;
|
||||
|
||||
dev_entry = devm_kzalloc(dev,
|
||||
sizeof(struct abx500_device_entry),
|
||||
GFP_KERNEL);
|
||||
if (!dev_entry) {
|
||||
dev_err(dev, "register_ops kzalloc failed");
|
||||
dev_entry = devm_kzalloc(dev, sizeof(*dev_entry), GFP_KERNEL);
|
||||
if (!dev_entry)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev_entry->dev = dev;
|
||||
memcpy(&dev_entry->ops, ops, sizeof(struct abx500_ops));
|
||||
memcpy(&dev_entry->ops, ops, sizeof(*ops));
|
||||
|
||||
list_add_tail(&dev_entry->list, &abx500_list);
|
||||
return 0;
|
||||
|
@ -68,7 +65,7 @@ int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
|
|||
struct abx500_ops *ops;
|
||||
|
||||
lookup_ops(dev->parent, &ops);
|
||||
if ((ops != NULL) && (ops->set_register != NULL))
|
||||
if (ops && ops->set_register)
|
||||
return ops->set_register(dev, bank, reg, value);
|
||||
else
|
||||
return -ENOTSUPP;
|
||||
|
@ -81,7 +78,7 @@ int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg,
|
|||
struct abx500_ops *ops;
|
||||
|
||||
lookup_ops(dev->parent, &ops);
|
||||
if ((ops != NULL) && (ops->get_register != NULL))
|
||||
if (ops && ops->get_register)
|
||||
return ops->get_register(dev, bank, reg, value);
|
||||
else
|
||||
return -ENOTSUPP;
|
||||
|
@ -94,7 +91,7 @@ int abx500_get_register_page_interruptible(struct device *dev, u8 bank,
|
|||
struct abx500_ops *ops;
|
||||
|
||||
lookup_ops(dev->parent, &ops);
|
||||
if ((ops != NULL) && (ops->get_register_page != NULL))
|
||||
if (ops && ops->get_register_page)
|
||||
return ops->get_register_page(dev, bank,
|
||||
first_reg, regvals, numregs);
|
||||
else
|
||||
|
@ -108,7 +105,7 @@ int abx500_mask_and_set_register_interruptible(struct device *dev, u8 bank,
|
|||
struct abx500_ops *ops;
|
||||
|
||||
lookup_ops(dev->parent, &ops);
|
||||
if ((ops != NULL) && (ops->mask_and_set_register != NULL))
|
||||
if (ops && ops->mask_and_set_register)
|
||||
return ops->mask_and_set_register(dev, bank,
|
||||
reg, bitmask, bitvalues);
|
||||
else
|
||||
|
@ -121,7 +118,7 @@ int abx500_get_chip_id(struct device *dev)
|
|||
struct abx500_ops *ops;
|
||||
|
||||
lookup_ops(dev->parent, &ops);
|
||||
if ((ops != NULL) && (ops->get_chip_id != NULL))
|
||||
if (ops && ops->get_chip_id)
|
||||
return ops->get_chip_id(dev);
|
||||
else
|
||||
return -ENOTSUPP;
|
||||
|
@ -133,7 +130,7 @@ int abx500_event_registers_startup_state_get(struct device *dev, u8 *event)
|
|||
struct abx500_ops *ops;
|
||||
|
||||
lookup_ops(dev->parent, &ops);
|
||||
if ((ops != NULL) && (ops->event_registers_startup_state_get != NULL))
|
||||
if (ops && ops->event_registers_startup_state_get)
|
||||
return ops->event_registers_startup_state_get(dev, event);
|
||||
else
|
||||
return -ENOTSUPP;
|
||||
|
@ -145,7 +142,7 @@ int abx500_startup_irq_enabled(struct device *dev, unsigned int irq)
|
|||
struct abx500_ops *ops;
|
||||
|
||||
lookup_ops(dev->parent, &ops);
|
||||
if ((ops != NULL) && (ops->startup_irq_enabled != NULL))
|
||||
if (ops && ops->startup_irq_enabled)
|
||||
return ops->startup_irq_enabled(dev, irq);
|
||||
else
|
||||
return -ENOTSUPP;
|
||||
|
|
|
@ -13,13 +13,12 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
@ -279,7 +278,7 @@ static int arizona_wait_for_boot(struct arizona *arizona)
|
|||
static inline void arizona_enable_reset(struct arizona *arizona)
|
||||
{
|
||||
if (arizona->pdata.reset)
|
||||
gpio_set_value_cansleep(arizona->pdata.reset, 0);
|
||||
gpiod_set_raw_value_cansleep(arizona->pdata.reset, 0);
|
||||
}
|
||||
|
||||
static void arizona_disable_reset(struct arizona *arizona)
|
||||
|
@ -295,7 +294,7 @@ static void arizona_disable_reset(struct arizona *arizona)
|
|||
break;
|
||||
}
|
||||
|
||||
gpio_set_value_cansleep(arizona->pdata.reset, 1);
|
||||
gpiod_set_raw_value_cansleep(arizona->pdata.reset, 1);
|
||||
usleep_range(1000, 5000);
|
||||
}
|
||||
}
|
||||
|
@ -799,14 +798,27 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
|
|||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
int ret, i;
|
||||
|
||||
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);
|
||||
/* Handle old non-standard DT binding */
|
||||
pdata->reset = devm_gpiod_get_from_of_node(arizona->dev,
|
||||
arizona->dev->of_node,
|
||||
"wlf,reset", 0,
|
||||
GPIOD_OUT_LOW,
|
||||
"arizona /RESET");
|
||||
if (IS_ERR(pdata->reset)) {
|
||||
ret = PTR_ERR(pdata->reset);
|
||||
|
||||
pdata->reset = 0;
|
||||
/*
|
||||
* Reset missing will be caught when other binding is read
|
||||
* but all other errors imply this binding is in use but has
|
||||
* encountered a problem so should be handled.
|
||||
*/
|
||||
if (ret == -EPROBE_DEFER)
|
||||
return ret;
|
||||
else if (ret != -ENOENT && ret != -ENOSYS)
|
||||
dev_err(arizona->dev, "Reset GPIO malformed: %d\n",
|
||||
ret);
|
||||
|
||||
pdata->reset = NULL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32_array(arizona->dev->of_node,
|
||||
|
@ -1050,14 +1062,19 @@ int arizona_dev_init(struct arizona *arizona)
|
|||
goto err_early;
|
||||
}
|
||||
|
||||
if (arizona->pdata.reset) {
|
||||
if (!arizona->pdata.reset) {
|
||||
/* Start out with /RESET low to put the chip into reset */
|
||||
ret = devm_gpio_request_one(arizona->dev, arizona->pdata.reset,
|
||||
GPIOF_DIR_OUT | GPIOF_INIT_LOW,
|
||||
"arizona /RESET");
|
||||
if (ret != 0) {
|
||||
dev_err(dev, "Failed to request /RESET: %d\n", ret);
|
||||
goto err_dcvdd;
|
||||
arizona->pdata.reset = devm_gpiod_get(arizona->dev, "reset",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(arizona->pdata.reset)) {
|
||||
ret = PTR_ERR(arizona->pdata.reset);
|
||||
if (ret == -EPROBE_DEFER)
|
||||
goto err_dcvdd;
|
||||
|
||||
dev_err(arizona->dev,
|
||||
"Reset GPIO missing/malformed: %d\n", ret);
|
||||
|
||||
arizona->pdata.reset = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include <linux/mfd/ds1wm.h>
|
||||
#include <linux/mfd/tmio.h>
|
||||
|
||||
#include <linux/mmc/host.h>
|
||||
|
||||
enum {
|
||||
ASIC3_CLOCK_SPI,
|
||||
ASIC3_CLOCK_OWM,
|
||||
|
@ -719,6 +721,7 @@ static void asic3_mmc_clk_div(struct platform_device *pdev, int state)
|
|||
|
||||
static struct tmio_mmc_data asic3_mmc_data = {
|
||||
.hclk = 24576000,
|
||||
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
|
||||
.set_pwr = asic3_mmc_pwr,
|
||||
.set_clk_div = asic3_mmc_clk_div,
|
||||
};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/mfd/syscon/atmel-smc.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
/**
|
||||
* atmel_smc_cs_conf_init - initialize a SMC CS conf
|
||||
|
|
|
@ -169,131 +169,61 @@ static const struct regmap_access_table axp806_volatile_table = {
|
|||
.n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges),
|
||||
};
|
||||
|
||||
static struct resource axp152_pek_resources[] = {
|
||||
static const struct resource axp152_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static struct resource axp20x_ac_power_supply_resources[] = {
|
||||
static const struct resource axp20x_ac_power_supply_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"),
|
||||
};
|
||||
|
||||
static struct resource axp20x_pek_resources[] = {
|
||||
{
|
||||
.name = "PEK_DBR",
|
||||
.start = AXP20X_IRQ_PEK_RIS_EDGE,
|
||||
.end = AXP20X_IRQ_PEK_RIS_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}, {
|
||||
.name = "PEK_DBF",
|
||||
.start = AXP20X_IRQ_PEK_FAL_EDGE,
|
||||
.end = AXP20X_IRQ_PEK_FAL_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static const struct resource axp20x_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static struct resource axp20x_usb_power_supply_resources[] = {
|
||||
static const struct resource axp20x_usb_power_supply_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
|
||||
};
|
||||
|
||||
static struct resource axp22x_usb_power_supply_resources[] = {
|
||||
static const struct resource axp22x_usb_power_supply_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
|
||||
};
|
||||
|
||||
static struct resource axp22x_pek_resources[] = {
|
||||
{
|
||||
.name = "PEK_DBR",
|
||||
.start = AXP22X_IRQ_PEK_RIS_EDGE,
|
||||
.end = AXP22X_IRQ_PEK_RIS_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}, {
|
||||
.name = "PEK_DBF",
|
||||
.start = AXP22X_IRQ_PEK_FAL_EDGE,
|
||||
.end = AXP22X_IRQ_PEK_FAL_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static const struct resource axp22x_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static struct resource axp288_power_button_resources[] = {
|
||||
{
|
||||
.name = "PEK_DBR",
|
||||
.start = AXP288_IRQ_POKP,
|
||||
.end = AXP288_IRQ_POKP,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.name = "PEK_DBF",
|
||||
.start = AXP288_IRQ_POKN,
|
||||
.end = AXP288_IRQ_POKN,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static const struct resource axp288_power_button_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKP, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKN, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static struct resource axp288_fuel_gauge_resources[] = {
|
||||
{
|
||||
.start = AXP288_IRQ_QWBTU,
|
||||
.end = AXP288_IRQ_QWBTU,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_WBTU,
|
||||
.end = AXP288_IRQ_WBTU,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_QWBTO,
|
||||
.end = AXP288_IRQ_QWBTO,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_WBTO,
|
||||
.end = AXP288_IRQ_WBTO,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_WL2,
|
||||
.end = AXP288_IRQ_WL2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_WL1,
|
||||
.end = AXP288_IRQ_WL1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static const struct resource axp288_fuel_gauge_resources[] = {
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_QWBTU),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_WBTU),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_QWBTO),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_WBTO),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_WL2),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_WL1),
|
||||
};
|
||||
|
||||
static struct resource axp803_pek_resources[] = {
|
||||
{
|
||||
.name = "PEK_DBR",
|
||||
.start = AXP803_IRQ_PEK_RIS_EDGE,
|
||||
.end = AXP803_IRQ_PEK_RIS_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}, {
|
||||
.name = "PEK_DBF",
|
||||
.start = AXP803_IRQ_PEK_FAL_EDGE,
|
||||
.end = AXP803_IRQ_PEK_FAL_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static const struct resource axp803_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static struct resource axp809_pek_resources[] = {
|
||||
{
|
||||
.name = "PEK_DBR",
|
||||
.start = AXP809_IRQ_PEK_RIS_EDGE,
|
||||
.end = AXP809_IRQ_PEK_RIS_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}, {
|
||||
.name = "PEK_DBF",
|
||||
.start = AXP809_IRQ_PEK_FAL_EDGE,
|
||||
.end = AXP809_IRQ_PEK_FAL_EDGE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static const struct resource axp809_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static const struct regmap_config axp152_regmap_config = {
|
||||
|
@ -520,11 +450,11 @@ static const struct regmap_irq axp806_regmap_irqs[] = {
|
|||
INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW, 0, 5),
|
||||
INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW, 0, 6),
|
||||
INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW, 0, 7),
|
||||
INIT_REGMAP_IRQ(AXP806, PWROK_LONG, 1, 0),
|
||||
INIT_REGMAP_IRQ(AXP806, PWROK_SHORT, 1, 1),
|
||||
INIT_REGMAP_IRQ(AXP806, POK_LONG, 1, 0),
|
||||
INIT_REGMAP_IRQ(AXP806, POK_SHORT, 1, 1),
|
||||
INIT_REGMAP_IRQ(AXP806, WAKEUP, 1, 4),
|
||||
INIT_REGMAP_IRQ(AXP806, PWROK_FALL, 1, 5),
|
||||
INIT_REGMAP_IRQ(AXP806, PWROK_RISE, 1, 6),
|
||||
INIT_REGMAP_IRQ(AXP806, POK_FALL, 1, 5),
|
||||
INIT_REGMAP_IRQ(AXP806, POK_RISE, 1, 6),
|
||||
};
|
||||
|
||||
static const struct regmap_irq axp809_regmap_irqs[] = {
|
||||
|
@ -648,7 +578,7 @@ static const struct regmap_irq_chip axp809_regmap_irq_chip = {
|
|||
.num_regs = 5,
|
||||
};
|
||||
|
||||
static struct mfd_cell axp20x_cells[] = {
|
||||
static const struct mfd_cell axp20x_cells[] = {
|
||||
{
|
||||
.name = "axp20x-gpio",
|
||||
.of_compatible = "x-powers,axp209-gpio",
|
||||
|
@ -660,6 +590,7 @@ static struct mfd_cell axp20x_cells[] = {
|
|||
.name = "axp20x-regulator",
|
||||
}, {
|
||||
.name = "axp20x-adc",
|
||||
.of_compatible = "x-powers,axp209-adc",
|
||||
}, {
|
||||
.name = "axp20x-battery-power-supply",
|
||||
.of_compatible = "x-powers,axp209-battery-power-supply",
|
||||
|
@ -676,7 +607,7 @@ static struct mfd_cell axp20x_cells[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp221_cells[] = {
|
||||
static const struct mfd_cell axp221_cells[] = {
|
||||
{
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp22x_pek_resources),
|
||||
|
@ -684,7 +615,8 @@ static struct mfd_cell axp221_cells[] = {
|
|||
}, {
|
||||
.name = "axp20x-regulator",
|
||||
}, {
|
||||
.name = "axp22x-adc"
|
||||
.name = "axp22x-adc",
|
||||
.of_compatible = "x-powers,axp221-adc",
|
||||
}, {
|
||||
.name = "axp20x-ac-power-supply",
|
||||
.of_compatible = "x-powers,axp221-ac-power-supply",
|
||||
|
@ -701,13 +633,14 @@ static struct mfd_cell axp221_cells[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp223_cells[] = {
|
||||
static const struct mfd_cell axp223_cells[] = {
|
||||
{
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp22x_pek_resources),
|
||||
.resources = axp22x_pek_resources,
|
||||
}, {
|
||||
.name = "axp22x-adc",
|
||||
.of_compatible = "x-powers,axp221-adc",
|
||||
}, {
|
||||
.name = "axp20x-battery-power-supply",
|
||||
.of_compatible = "x-powers,axp221-battery-power-supply",
|
||||
|
@ -726,7 +659,7 @@ static struct mfd_cell axp223_cells[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp152_cells[] = {
|
||||
static const struct mfd_cell axp152_cells[] = {
|
||||
{
|
||||
.name = "axp20x-pek",
|
||||
.num_resources = ARRAY_SIZE(axp152_pek_resources),
|
||||
|
@ -734,87 +667,30 @@ static struct mfd_cell axp152_cells[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct resource axp288_adc_resources[] = {
|
||||
{
|
||||
.name = "GPADC",
|
||||
.start = AXP288_IRQ_GPADC,
|
||||
.end = AXP288_IRQ_GPADC,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static const struct resource axp288_adc_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"),
|
||||
};
|
||||
|
||||
static struct resource axp288_extcon_resources[] = {
|
||||
{
|
||||
.start = AXP288_IRQ_VBUS_FALL,
|
||||
.end = AXP288_IRQ_VBUS_FALL,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_VBUS_RISE,
|
||||
.end = AXP288_IRQ_VBUS_RISE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_MV_CHNG,
|
||||
.end = AXP288_IRQ_MV_CHNG,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_BC_USB_CHNG,
|
||||
.end = AXP288_IRQ_BC_USB_CHNG,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static const struct resource axp288_extcon_resources[] = {
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_VBUS_FALL),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_VBUS_RISE),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_MV_CHNG),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_BC_USB_CHNG),
|
||||
};
|
||||
|
||||
static struct resource axp288_charger_resources[] = {
|
||||
{
|
||||
.start = AXP288_IRQ_OV,
|
||||
.end = AXP288_IRQ_OV,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_DONE,
|
||||
.end = AXP288_IRQ_DONE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_CHARGING,
|
||||
.end = AXP288_IRQ_CHARGING,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_SAFE_QUIT,
|
||||
.end = AXP288_IRQ_SAFE_QUIT,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_SAFE_ENTER,
|
||||
.end = AXP288_IRQ_SAFE_ENTER,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_QCBTU,
|
||||
.end = AXP288_IRQ_QCBTU,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_CBTU,
|
||||
.end = AXP288_IRQ_CBTU,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_QCBTO,
|
||||
.end = AXP288_IRQ_QCBTO,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = AXP288_IRQ_CBTO,
|
||||
.end = AXP288_IRQ_CBTO,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
static const struct resource axp288_charger_resources[] = {
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_OV),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_DONE),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_CHARGING),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_SAFE_QUIT),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_SAFE_ENTER),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_QCBTU),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_CBTU),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_QCBTO),
|
||||
DEFINE_RES_IRQ(AXP288_IRQ_CBTO),
|
||||
};
|
||||
|
||||
static struct mfd_cell axp288_cells[] = {
|
||||
static const struct mfd_cell axp288_cells[] = {
|
||||
{
|
||||
.name = "axp288_adc",
|
||||
.num_resources = ARRAY_SIZE(axp288_adc_resources),
|
||||
|
@ -845,7 +721,7 @@ static struct mfd_cell axp288_cells[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp803_cells[] = {
|
||||
static const struct mfd_cell axp803_cells[] = {
|
||||
{
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp803_pek_resources),
|
||||
|
@ -854,14 +730,14 @@ static struct mfd_cell axp803_cells[] = {
|
|||
{ .name = "axp20x-regulator" },
|
||||
};
|
||||
|
||||
static struct mfd_cell axp806_cells[] = {
|
||||
static const struct mfd_cell axp806_cells[] = {
|
||||
{
|
||||
.id = 2,
|
||||
.name = "axp20x-regulator",
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp809_cells[] = {
|
||||
static const struct mfd_cell axp809_cells[] = {
|
||||
{
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp809_pek_resources),
|
||||
|
@ -872,7 +748,7 @@ static struct mfd_cell axp809_cells[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp813_cells[] = {
|
||||
static const struct mfd_cell axp813_cells[] = {
|
||||
{
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp803_pek_resources),
|
||||
|
@ -882,7 +758,13 @@ static struct mfd_cell axp813_cells[] = {
|
|||
}, {
|
||||
.name = "axp20x-gpio",
|
||||
.of_compatible = "x-powers,axp813-gpio",
|
||||
}
|
||||
}, {
|
||||
.name = "axp813-adc",
|
||||
.of_compatible = "x-powers,axp813-adc",
|
||||
}, {
|
||||
.name = "axp20x-battery-power-supply",
|
||||
.of_compatible = "x-powers,axp813-battery-power-supply",
|
||||
},
|
||||
};
|
||||
|
||||
static struct axp20x_dev *axp20x_pm_power_off;
|
||||
|
|
|
@ -112,12 +112,16 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
|
|||
|
||||
mutex_init(&ec_dev->lock);
|
||||
|
||||
cros_ec_query_all(ec_dev);
|
||||
err = cros_ec_query_all(ec_dev);
|
||||
if (err) {
|
||||
dev_err(dev, "Cannot identify the EC: error %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (ec_dev->irq) {
|
||||
err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread,
|
||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
"chromeos-ec", ec_dev);
|
||||
err = devm_request_threaded_irq(dev, ec_dev->irq, NULL,
|
||||
ec_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||
"chromeos-ec", ec_dev);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to request IRQ %d: %d",
|
||||
ec_dev->irq, err);
|
||||
|
@ -131,7 +135,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
|
|||
dev_err(dev,
|
||||
"Failed to register Embedded Controller subdevice %d\n",
|
||||
err);
|
||||
goto fail_mfd;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (ec_dev->max_passthru) {
|
||||
|
@ -149,7 +153,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
|
|||
dev_err(dev,
|
||||
"Failed to register Power Delivery subdevice %d\n",
|
||||
err);
|
||||
goto fail_mfd;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +162,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
|
|||
if (err) {
|
||||
mfd_remove_devices(dev);
|
||||
dev_err(dev, "Failed to register sub-devices\n");
|
||||
goto fail_mfd;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,14 +177,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev)
|
|||
|
||||
dev_info(dev, "Chrome EC device registered\n");
|
||||
|
||||
cros_ec_acpi_install_gpe_handler(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_mfd:
|
||||
if (ec_dev->irq)
|
||||
free_irq(ec_dev->irq, ec_dev);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(cros_ec_register);
|
||||
|
||||
|
@ -188,11 +185,6 @@ int cros_ec_remove(struct cros_ec_device *ec_dev)
|
|||
{
|
||||
mfd_remove_devices(ec_dev->dev);
|
||||
|
||||
cros_ec_acpi_remove_gpe_handler();
|
||||
|
||||
if (ec_dev->irq)
|
||||
free_irq(ec_dev->irq, ec_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cros_ec_remove);
|
||||
|
@ -204,14 +196,9 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)
|
|||
int ret;
|
||||
u8 sleep_event;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_ACPI) || pm_suspend_via_firmware()) {
|
||||
sleep_event = HOST_SLEEP_EVENT_S3_SUSPEND;
|
||||
} else {
|
||||
sleep_event = HOST_SLEEP_EVENT_S0IX_SUSPEND;
|
||||
|
||||
/* Clearing the GPE status for any pending event */
|
||||
cros_ec_acpi_clear_gpe();
|
||||
}
|
||||
sleep_event = (!IS_ENABLED(CONFIG_ACPI) || pm_suspend_via_firmware()) ?
|
||||
HOST_SLEEP_EVENT_S3_SUSPEND :
|
||||
HOST_SLEEP_EVENT_S0IX_SUSPEND;
|
||||
|
||||
ret = cros_ec_sleep_event(ec_dev, sleep_event);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* ChromeOS EC multi-function device
|
||||
*
|
||||
* Copyright (C) 2017 Google, Inc
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The ChromeOS EC multi function device is used to mux all the requests
|
||||
* to the EC device for its multiple features: keyboard controller,
|
||||
* battery charging and regulator control, firmware update.
|
||||
*/
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#define ACPI_LID_DEVICE "LID0"
|
||||
|
||||
static int ec_wake_gpe = -EINVAL;
|
||||
|
||||
/*
|
||||
* This handler indicates to ACPI core that this GPE should stay enabled for
|
||||
* lid to work in suspend to idle path.
|
||||
*/
|
||||
static u32 cros_ec_gpe_handler(acpi_handle gpe_device, u32 gpe_number,
|
||||
void *data)
|
||||
{
|
||||
return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get ACPI GPE for LID0 device.
|
||||
*/
|
||||
static int cros_ec_get_ec_wake_gpe(struct device *dev)
|
||||
{
|
||||
struct acpi_device *cros_acpi_dev;
|
||||
struct acpi_device *adev;
|
||||
acpi_handle handle;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
cros_acpi_dev = ACPI_COMPANION(dev);
|
||||
|
||||
if (!cros_acpi_dev || !cros_acpi_dev->parent ||
|
||||
!cros_acpi_dev->parent->handle)
|
||||
return -EINVAL;
|
||||
|
||||
status = acpi_get_handle(cros_acpi_dev->parent->handle, ACPI_LID_DEVICE,
|
||||
&handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -EINVAL;
|
||||
|
||||
ret = acpi_bus_get_device(handle, &adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return adev->wakeup.gpe_number;
|
||||
}
|
||||
|
||||
int cros_ec_acpi_install_gpe_handler(struct device *dev)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
ec_wake_gpe = cros_ec_get_ec_wake_gpe(dev);
|
||||
|
||||
if (ec_wake_gpe < 0)
|
||||
return ec_wake_gpe;
|
||||
|
||||
status = acpi_install_gpe_handler(NULL, ec_wake_gpe,
|
||||
ACPI_GPE_EDGE_TRIGGERED,
|
||||
&cros_ec_gpe_handler, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
return -ENODEV;
|
||||
|
||||
dev_info(dev, "Initialized, GPE = 0x%x\n", ec_wake_gpe);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cros_ec_acpi_remove_gpe_handler(void)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
if (ec_wake_gpe < 0)
|
||||
return;
|
||||
|
||||
status = acpi_remove_gpe_handler(NULL, ec_wake_gpe,
|
||||
&cros_ec_gpe_handler);
|
||||
if (ACPI_FAILURE(status))
|
||||
pr_err("failed to remove gpe handler\n");
|
||||
}
|
||||
|
||||
void cros_ec_acpi_clear_gpe(void)
|
||||
{
|
||||
if (ec_wake_gpe < 0)
|
||||
return;
|
||||
|
||||
acpi_clear_gpe(NULL, ec_wake_gpe);
|
||||
}
|
|
@ -113,10 +113,10 @@ static int cros_ec_check_features(struct cros_ec_dev *ec, int feature)
|
|||
dev_warn(ec->dev, "cannot get EC features: %d/%d\n",
|
||||
ret, msg->result);
|
||||
memset(ec->features, 0, sizeof(ec->features));
|
||||
} else {
|
||||
memcpy(ec->features, msg->data, sizeof(ec->features));
|
||||
}
|
||||
|
||||
memcpy(ec->features, msg->data, sizeof(ec->features));
|
||||
|
||||
dev_dbg(ec->dev, "EC features %08x %08x\n",
|
||||
ec->features[0], ec->features[1]);
|
||||
|
||||
|
@ -262,13 +262,6 @@ static const struct file_operations fops = {
|
|||
#endif
|
||||
};
|
||||
|
||||
static void __remove(struct device *dev)
|
||||
{
|
||||
struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev,
|
||||
class_dev);
|
||||
kfree(ec);
|
||||
}
|
||||
|
||||
static void cros_ec_sensors_register(struct cros_ec_dev *ec)
|
||||
{
|
||||
/*
|
||||
|
@ -383,12 +376,16 @@ error:
|
|||
kfree(msg);
|
||||
}
|
||||
|
||||
static const struct mfd_cell cros_ec_rtc_cells[] = {
|
||||
{ .name = "cros-ec-rtc" }
|
||||
};
|
||||
|
||||
static int ec_device_probe(struct platform_device *pdev)
|
||||
{
|
||||
int retval = -ENOMEM;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct cros_ec_platform *ec_platform = dev_get_platdata(dev);
|
||||
struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL);
|
||||
struct cros_ec_dev *ec = devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL);
|
||||
|
||||
if (!ec)
|
||||
return retval;
|
||||
|
@ -410,7 +407,6 @@ static int ec_device_probe(struct platform_device *pdev)
|
|||
ec->class_dev.devt = MKDEV(ec_major, pdev->id);
|
||||
ec->class_dev.class = &cros_class;
|
||||
ec->class_dev.parent = dev;
|
||||
ec->class_dev.release = __remove;
|
||||
|
||||
retval = dev_set_name(&ec->class_dev, "%s", ec_platform->ec_name);
|
||||
if (retval) {
|
||||
|
@ -422,6 +418,18 @@ static int ec_device_probe(struct platform_device *pdev)
|
|||
if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE))
|
||||
cros_ec_sensors_register(ec);
|
||||
|
||||
/* Check whether this EC instance has RTC host command support */
|
||||
if (cros_ec_check_features(ec, EC_FEATURE_RTC)) {
|
||||
retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO,
|
||||
cros_ec_rtc_cells,
|
||||
ARRAY_SIZE(cros_ec_rtc_cells),
|
||||
NULL, 0, NULL);
|
||||
if (retval)
|
||||
dev_err(ec->dev,
|
||||
"failed to add cros-ec-rtc device: %d\n",
|
||||
retval);
|
||||
}
|
||||
|
||||
/* Take control of the lightbar from the EC. */
|
||||
lb_manual_suspend_ctrl(ec, 1);
|
||||
|
||||
|
@ -456,9 +464,17 @@ static int ec_device_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ec_device_shutdown(struct platform_device *pdev)
|
||||
{
|
||||
struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
/* Be sure to clear up debugfs delayed works */
|
||||
cros_ec_debugfs_remove(ec);
|
||||
}
|
||||
|
||||
static const struct platform_device_id cros_ec_id[] = {
|
||||
{ DRV_NAME, 0 },
|
||||
{ /* sentinel */ },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, cros_ec_id);
|
||||
|
||||
|
@ -466,6 +482,8 @@ static __maybe_unused int ec_device_suspend(struct device *dev)
|
|||
{
|
||||
struct cros_ec_dev *ec = dev_get_drvdata(dev);
|
||||
|
||||
cros_ec_debugfs_suspend(ec);
|
||||
|
||||
lb_suspend(ec);
|
||||
|
||||
return 0;
|
||||
|
@ -475,6 +493,8 @@ static __maybe_unused int ec_device_resume(struct device *dev)
|
|||
{
|
||||
struct cros_ec_dev *ec = dev_get_drvdata(dev);
|
||||
|
||||
cros_ec_debugfs_resume(ec);
|
||||
|
||||
lb_resume(ec);
|
||||
|
||||
return 0;
|
||||
|
@ -494,6 +514,7 @@ static struct platform_driver cros_ec_dev_driver = {
|
|||
},
|
||||
.probe = ec_device_probe,
|
||||
.remove = ec_device_remove,
|
||||
.shutdown = ec_device_shutdown,
|
||||
};
|
||||
|
||||
static int __init cros_ec_dev_init(void)
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -341,14 +342,17 @@ static int cros_ec_i2c_resume(struct device *dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(cros_ec_i2c_pm_ops, cros_ec_i2c_suspend,
|
||||
cros_ec_i2c_resume);
|
||||
static const struct dev_pm_ops cros_ec_i2c_pm_ops = {
|
||||
SET_LATE_SYSTEM_SLEEP_PM_OPS(cros_ec_i2c_suspend, cros_ec_i2c_resume)
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id cros_ec_i2c_of_match[] = {
|
||||
{ .compatible = "google,cros-ec-i2c", },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id cros_ec_i2c_id[] = {
|
||||
{ "cros-ec-i2c", 0 },
|
||||
|
@ -356,9 +360,18 @@ static const struct i2c_device_id cros_ec_i2c_id[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(i2c, cros_ec_i2c_id);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static const struct acpi_device_id cros_ec_i2c_acpi_id[] = {
|
||||
{ "GOOG0008", 0 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_acpi_id);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver cros_ec_driver = {
|
||||
.driver = {
|
||||
.name = "cros-ec-i2c",
|
||||
.acpi_match_table = ACPI_PTR(cros_ec_i2c_acpi_id),
|
||||
.of_match_table = of_match_ptr(cros_ec_i2c_of_match),
|
||||
.pm = &cros_ec_i2c_pm_ops,
|
||||
},
|
||||
|
|
|
@ -365,186 +365,69 @@ static int da9062_get_device_type(struct da9062 *chip)
|
|||
}
|
||||
|
||||
static const struct regmap_range da9061_aa_readable_ranges[] = {
|
||||
{
|
||||
.range_min = DA9062AA_PAGE_CON,
|
||||
.range_max = DA9062AA_STATUS_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_STATUS_D,
|
||||
.range_max = DA9062AA_EVENT_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_IRQ_MASK_A,
|
||||
.range_max = DA9062AA_IRQ_MASK_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_A,
|
||||
.range_max = DA9062AA_GPIO_4,
|
||||
}, {
|
||||
.range_min = DA9062AA_GPIO_WKUP_MODE,
|
||||
.range_max = DA9062AA_GPIO_OUT3_4,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK1_CONT,
|
||||
.range_max = DA9062AA_BUCK4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK3_CONT,
|
||||
.range_max = DA9062AA_BUCK3_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_LDO1_CONT,
|
||||
.range_max = DA9062AA_LDO4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_DVC_1,
|
||||
.range_max = DA9062AA_DVC_1,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ,
|
||||
.range_max = DA9062AA_ID_4_3,
|
||||
}, {
|
||||
.range_min = DA9062AA_ID_12_11,
|
||||
.range_max = DA9062AA_ID_16_15,
|
||||
}, {
|
||||
.range_min = DA9062AA_ID_22_21,
|
||||
.range_max = DA9062AA_ID_32_31,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ_A,
|
||||
.range_max = DA9062AA_WAIT,
|
||||
}, {
|
||||
.range_min = DA9062AA_RESET,
|
||||
.range_max = DA9062AA_BUCK_ILIM_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK1_CFG,
|
||||
.range_max = DA9062AA_BUCK3_CFG,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK1_A,
|
||||
.range_max = DA9062AA_VBUCK4_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK3_A,
|
||||
.range_max = DA9062AA_VBUCK3_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_A,
|
||||
.range_max = DA9062AA_VLDO4_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK1_B,
|
||||
.range_max = DA9062AA_VBUCK4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK3_B,
|
||||
.range_max = DA9062AA_VBUCK3_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_B,
|
||||
.range_max = DA9062AA_VLDO4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_INTERFACE,
|
||||
.range_max = DA9062AA_CONFIG_E,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONFIG_G,
|
||||
.range_max = DA9062AA_CONFIG_K,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONFIG_M,
|
||||
.range_max = DA9062AA_CONFIG_M,
|
||||
}, {
|
||||
.range_min = DA9062AA_GP_ID_0,
|
||||
.range_max = DA9062AA_GP_ID_19,
|
||||
}, {
|
||||
.range_min = DA9062AA_DEVICE_ID,
|
||||
.range_max = DA9062AA_CONFIG_ID,
|
||||
},
|
||||
regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
|
||||
regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
|
||||
regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
|
||||
regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
|
||||
regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4),
|
||||
regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT),
|
||||
regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
|
||||
regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
|
||||
regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
|
||||
regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
|
||||
regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
|
||||
regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
|
||||
regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT),
|
||||
regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C),
|
||||
regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG),
|
||||
regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A),
|
||||
regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
|
||||
regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
|
||||
regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B),
|
||||
regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
|
||||
regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
|
||||
regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E),
|
||||
regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K),
|
||||
regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M),
|
||||
regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
|
||||
regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID),
|
||||
};
|
||||
|
||||
static const struct regmap_range da9061_aa_writeable_ranges[] = {
|
||||
{
|
||||
.range_min = DA9062AA_PAGE_CON,
|
||||
.range_max = DA9062AA_PAGE_CON,
|
||||
}, {
|
||||
.range_min = DA9062AA_FAULT_LOG,
|
||||
.range_max = DA9062AA_EVENT_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_IRQ_MASK_A,
|
||||
.range_max = DA9062AA_IRQ_MASK_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_A,
|
||||
.range_max = DA9062AA_GPIO_4,
|
||||
}, {
|
||||
.range_min = DA9062AA_GPIO_WKUP_MODE,
|
||||
.range_max = DA9062AA_GPIO_OUT3_4,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK1_CONT,
|
||||
.range_max = DA9062AA_BUCK4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK3_CONT,
|
||||
.range_max = DA9062AA_BUCK3_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_LDO1_CONT,
|
||||
.range_max = DA9062AA_LDO4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_DVC_1,
|
||||
.range_max = DA9062AA_DVC_1,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ,
|
||||
.range_max = DA9062AA_ID_4_3,
|
||||
}, {
|
||||
.range_min = DA9062AA_ID_12_11,
|
||||
.range_max = DA9062AA_ID_16_15,
|
||||
}, {
|
||||
.range_min = DA9062AA_ID_22_21,
|
||||
.range_max = DA9062AA_ID_32_31,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ_A,
|
||||
.range_max = DA9062AA_WAIT,
|
||||
}, {
|
||||
.range_min = DA9062AA_RESET,
|
||||
.range_max = DA9062AA_BUCK_ILIM_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK1_CFG,
|
||||
.range_max = DA9062AA_BUCK3_CFG,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK1_A,
|
||||
.range_max = DA9062AA_VBUCK4_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK3_A,
|
||||
.range_max = DA9062AA_VBUCK3_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_A,
|
||||
.range_max = DA9062AA_VLDO4_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK1_B,
|
||||
.range_max = DA9062AA_VBUCK4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK3_B,
|
||||
.range_max = DA9062AA_VBUCK3_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_B,
|
||||
.range_max = DA9062AA_VLDO4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_GP_ID_0,
|
||||
.range_max = DA9062AA_GP_ID_19,
|
||||
},
|
||||
regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON),
|
||||
regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C),
|
||||
regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
|
||||
regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
|
||||
regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4),
|
||||
regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT),
|
||||
regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
|
||||
regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
|
||||
regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
|
||||
regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
|
||||
regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
|
||||
regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
|
||||
regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT),
|
||||
regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C),
|
||||
regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG),
|
||||
regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A),
|
||||
regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
|
||||
regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
|
||||
regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B),
|
||||
regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
|
||||
regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
|
||||
regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
|
||||
};
|
||||
|
||||
static const struct regmap_range da9061_aa_volatile_ranges[] = {
|
||||
{
|
||||
.range_min = DA9062AA_PAGE_CON,
|
||||
.range_max = DA9062AA_STATUS_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_STATUS_D,
|
||||
.range_max = DA9062AA_EVENT_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_A,
|
||||
.range_max = DA9062AA_CONTROL_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_E,
|
||||
.range_max = DA9062AA_CONTROL_F,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK1_CONT,
|
||||
.range_max = DA9062AA_BUCK4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK3_CONT,
|
||||
.range_max = DA9062AA_BUCK3_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_LDO1_CONT,
|
||||
.range_max = DA9062AA_LDO4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_DVC_1,
|
||||
.range_max = DA9062AA_DVC_1,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ,
|
||||
.range_max = DA9062AA_SEQ,
|
||||
},
|
||||
regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
|
||||
regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
|
||||
regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B),
|
||||
regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F),
|
||||
regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT),
|
||||
regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
|
||||
regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
|
||||
regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
|
||||
regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table da9061_aa_readable_table = {
|
||||
|
@ -587,186 +470,69 @@ static struct regmap_config da9061_regmap_config = {
|
|||
};
|
||||
|
||||
static const struct regmap_range da9062_aa_readable_ranges[] = {
|
||||
{
|
||||
.range_min = DA9062AA_PAGE_CON,
|
||||
.range_max = DA9062AA_STATUS_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_STATUS_D,
|
||||
.range_max = DA9062AA_EVENT_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_IRQ_MASK_A,
|
||||
.range_max = DA9062AA_IRQ_MASK_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_A,
|
||||
.range_max = DA9062AA_GPIO_4,
|
||||
}, {
|
||||
.range_min = DA9062AA_GPIO_WKUP_MODE,
|
||||
.range_max = DA9062AA_BUCK4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK3_CONT,
|
||||
.range_max = DA9062AA_BUCK3_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_LDO1_CONT,
|
||||
.range_max = DA9062AA_LDO4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_DVC_1,
|
||||
.range_max = DA9062AA_DVC_1,
|
||||
}, {
|
||||
.range_min = DA9062AA_COUNT_S,
|
||||
.range_max = DA9062AA_SECOND_D,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ,
|
||||
.range_max = DA9062AA_ID_4_3,
|
||||
}, {
|
||||
.range_min = DA9062AA_ID_12_11,
|
||||
.range_max = DA9062AA_ID_16_15,
|
||||
}, {
|
||||
.range_min = DA9062AA_ID_22_21,
|
||||
.range_max = DA9062AA_ID_32_31,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ_A,
|
||||
.range_max = DA9062AA_BUCK3_CFG,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK2_A,
|
||||
.range_max = DA9062AA_VBUCK4_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK3_A,
|
||||
.range_max = DA9062AA_VBUCK3_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_A,
|
||||
.range_max = DA9062AA_VLDO4_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK2_B,
|
||||
.range_max = DA9062AA_VBUCK4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK3_B,
|
||||
.range_max = DA9062AA_VBUCK3_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_B,
|
||||
.range_max = DA9062AA_VLDO4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_BBAT_CONT,
|
||||
.range_max = DA9062AA_BBAT_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_INTERFACE,
|
||||
.range_max = DA9062AA_CONFIG_E,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONFIG_G,
|
||||
.range_max = DA9062AA_CONFIG_K,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONFIG_M,
|
||||
.range_max = DA9062AA_CONFIG_M,
|
||||
}, {
|
||||
.range_min = DA9062AA_TRIM_CLDR,
|
||||
.range_max = DA9062AA_GP_ID_19,
|
||||
}, {
|
||||
.range_min = DA9062AA_DEVICE_ID,
|
||||
.range_max = DA9062AA_CONFIG_ID,
|
||||
},
|
||||
regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
|
||||
regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
|
||||
regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
|
||||
regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
|
||||
regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT),
|
||||
regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
|
||||
regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
|
||||
regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
|
||||
regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D),
|
||||
regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
|
||||
regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
|
||||
regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
|
||||
regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG),
|
||||
regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A),
|
||||
regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
|
||||
regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
|
||||
regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B),
|
||||
regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
|
||||
regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
|
||||
regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT),
|
||||
regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E),
|
||||
regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K),
|
||||
regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M),
|
||||
regmap_reg_range(DA9062AA_TRIM_CLDR, DA9062AA_GP_ID_19),
|
||||
regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID),
|
||||
};
|
||||
|
||||
static const struct regmap_range da9062_aa_writeable_ranges[] = {
|
||||
{
|
||||
.range_min = DA9062AA_PAGE_CON,
|
||||
.range_max = DA9062AA_PAGE_CON,
|
||||
}, {
|
||||
.range_min = DA9062AA_FAULT_LOG,
|
||||
.range_max = DA9062AA_EVENT_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_IRQ_MASK_A,
|
||||
.range_max = DA9062AA_IRQ_MASK_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_A,
|
||||
.range_max = DA9062AA_GPIO_4,
|
||||
}, {
|
||||
.range_min = DA9062AA_GPIO_WKUP_MODE,
|
||||
.range_max = DA9062AA_BUCK4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK3_CONT,
|
||||
.range_max = DA9062AA_BUCK3_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_LDO1_CONT,
|
||||
.range_max = DA9062AA_LDO4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_DVC_1,
|
||||
.range_max = DA9062AA_DVC_1,
|
||||
}, {
|
||||
.range_min = DA9062AA_COUNT_S,
|
||||
.range_max = DA9062AA_ALARM_Y,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ,
|
||||
.range_max = DA9062AA_ID_4_3,
|
||||
}, {
|
||||
.range_min = DA9062AA_ID_12_11,
|
||||
.range_max = DA9062AA_ID_16_15,
|
||||
}, {
|
||||
.range_min = DA9062AA_ID_22_21,
|
||||
.range_max = DA9062AA_ID_32_31,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ_A,
|
||||
.range_max = DA9062AA_BUCK3_CFG,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK2_A,
|
||||
.range_max = DA9062AA_VBUCK4_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK3_A,
|
||||
.range_max = DA9062AA_VBUCK3_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_A,
|
||||
.range_max = DA9062AA_VLDO4_A,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK2_B,
|
||||
.range_max = DA9062AA_VBUCK4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_VBUCK3_B,
|
||||
.range_max = DA9062AA_VBUCK3_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_VLDO1_B,
|
||||
.range_max = DA9062AA_VLDO4_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_BBAT_CONT,
|
||||
.range_max = DA9062AA_BBAT_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_GP_ID_0,
|
||||
.range_max = DA9062AA_GP_ID_19,
|
||||
},
|
||||
regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON),
|
||||
regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C),
|
||||
regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C),
|
||||
regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4),
|
||||
regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT),
|
||||
regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
|
||||
regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
|
||||
regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
|
||||
regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_ALARM_Y),
|
||||
regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3),
|
||||
regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15),
|
||||
regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31),
|
||||
regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG),
|
||||
regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A),
|
||||
regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A),
|
||||
regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A),
|
||||
regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B),
|
||||
regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B),
|
||||
regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B),
|
||||
regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT),
|
||||
regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19),
|
||||
};
|
||||
|
||||
static const struct regmap_range da9062_aa_volatile_ranges[] = {
|
||||
{
|
||||
.range_min = DA9062AA_PAGE_CON,
|
||||
.range_max = DA9062AA_STATUS_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_STATUS_D,
|
||||
.range_max = DA9062AA_EVENT_C,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_A,
|
||||
.range_max = DA9062AA_CONTROL_B,
|
||||
}, {
|
||||
.range_min = DA9062AA_CONTROL_E,
|
||||
.range_max = DA9062AA_CONTROL_F,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK2_CONT,
|
||||
.range_max = DA9062AA_BUCK4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_BUCK3_CONT,
|
||||
.range_max = DA9062AA_BUCK3_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_LDO1_CONT,
|
||||
.range_max = DA9062AA_LDO4_CONT,
|
||||
}, {
|
||||
.range_min = DA9062AA_DVC_1,
|
||||
.range_max = DA9062AA_DVC_1,
|
||||
}, {
|
||||
.range_min = DA9062AA_COUNT_S,
|
||||
.range_max = DA9062AA_SECOND_D,
|
||||
}, {
|
||||
.range_min = DA9062AA_SEQ,
|
||||
.range_max = DA9062AA_SEQ,
|
||||
}, {
|
||||
.range_min = DA9062AA_EN_32K,
|
||||
.range_max = DA9062AA_EN_32K,
|
||||
},
|
||||
regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B),
|
||||
regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C),
|
||||
regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B),
|
||||
regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F),
|
||||
regmap_reg_range(DA9062AA_BUCK2_CONT, DA9062AA_BUCK4_CONT),
|
||||
regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT),
|
||||
regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT),
|
||||
regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1),
|
||||
regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D),
|
||||
regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ),
|
||||
regmap_reg_range(DA9062AA_EN_32K, DA9062AA_EN_32K),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table da9062_aa_readable_table = {
|
||||
|
|
|
@ -479,10 +479,8 @@ static int htcpld_setup_chips(struct platform_device *pdev)
|
|||
htcpld->nchips = pdata->num_chip;
|
||||
htcpld->chip = devm_kzalloc(dev, sizeof(struct htcpld_chip) * htcpld->nchips,
|
||||
GFP_KERNEL);
|
||||
if (!htcpld->chip) {
|
||||
dev_warn(dev, "Unable to allocate memory for chips\n");
|
||||
if (!htcpld->chip)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Add the chips as best we can */
|
||||
for (i = 0; i < htcpld->nchips; i++) {
|
||||
|
|
|
@ -124,6 +124,11 @@ static const struct intel_lpss_platform_info apl_i2c_info = {
|
|||
.properties = apl_i2c_properties,
|
||||
};
|
||||
|
||||
static const struct intel_lpss_platform_info cnl_i2c_info = {
|
||||
.clk_rate = 216000000,
|
||||
.properties = spt_i2c_properties,
|
||||
};
|
||||
|
||||
static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||
/* BXT A-Step */
|
||||
{ PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
|
||||
|
@ -207,13 +212,13 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
|||
{ PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&cnl_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&cnl_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dc7), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9de8), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9de8), (kernel_ulong_t)&cnl_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&cnl_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&cnl_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&cnl_i2c_info },
|
||||
/* SPT-H */
|
||||
{ PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info },
|
||||
|
@ -240,10 +245,10 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
|||
{ PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa347), (kernel_ulong_t)&spt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&cnl_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&cnl_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&cnl_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&cnl_i2c_info },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
|
||||
/* Offsets from lpss->priv */
|
||||
#define LPSS_PRIV_RESETS 0x04
|
||||
#define LPSS_PRIV_RESETS_FUNC BIT(2)
|
||||
#define LPSS_PRIV_RESETS_IDMA 0x3
|
||||
#define LPSS_PRIV_RESETS_IDMA BIT(2)
|
||||
#define LPSS_PRIV_RESETS_FUNC 0x3
|
||||
|
||||
#define LPSS_PRIV_ACTIVELTR 0x10
|
||||
#define LPSS_PRIV_IDLELTR 0x14
|
||||
|
@ -275,11 +275,11 @@ static void intel_lpss_init_dev(const struct intel_lpss *lpss)
|
|||
|
||||
intel_lpss_deassert_reset(lpss);
|
||||
|
||||
intel_lpss_set_remap_addr(lpss);
|
||||
|
||||
if (!intel_lpss_has_idma(lpss))
|
||||
return;
|
||||
|
||||
intel_lpss_set_remap_addr(lpss);
|
||||
|
||||
/* Make sure that SPI multiblock DMA transfers are re-enabled */
|
||||
if (lpss->type == LPSS_DEV_SPI)
|
||||
writel(value, lpss->priv + LPSS_PRIV_SSP_REG);
|
||||
|
|
|
@ -183,10 +183,8 @@ static int cmodio_pci_probe(struct pci_dev *dev,
|
|||
int ret;
|
||||
|
||||
priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
dev_err(&dev->dev, "unable to allocate private data\n");
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pci_set_drvdata(dev, priv);
|
||||
priv->pdev = dev;
|
||||
|
|
|
@ -212,10 +212,8 @@ static int jz4740_adc_probe(struct platform_device *pdev)
|
|||
int irq_base;
|
||||
|
||||
adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL);
|
||||
if (!adc) {
|
||||
dev_err(&pdev->dev, "Failed to allocate driver structure\n");
|
||||
if (!adc)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
adc->irq = platform_get_irq(pdev, 0);
|
||||
if (adc->irq < 0) {
|
||||
|
|
|
@ -148,10 +148,8 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata(
|
|||
struct max8997_platform_data *pd;
|
||||
|
||||
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
|
||||
if (!pd) {
|
||||
dev_err(dev, "could not allocate memory for pdata\n");
|
||||
if (!pd)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
pd->ono = irq_of_parse_and_map(dev->of_node, 1);
|
||||
|
||||
|
|
|
@ -43,6 +43,16 @@ static const struct resource mt6397_rtc_resources[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct resource mt6323_keys_resources[] = {
|
||||
DEFINE_RES_IRQ(MT6323_IRQ_STATUS_PWRKEY),
|
||||
DEFINE_RES_IRQ(MT6323_IRQ_STATUS_FCHRKEY),
|
||||
};
|
||||
|
||||
static const struct resource mt6397_keys_resources[] = {
|
||||
DEFINE_RES_IRQ(MT6397_IRQ_PWRKEY),
|
||||
DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY),
|
||||
};
|
||||
|
||||
static const struct mfd_cell mt6323_devs[] = {
|
||||
{
|
||||
.name = "mt6323-regulator",
|
||||
|
@ -50,6 +60,11 @@ static const struct mfd_cell mt6323_devs[] = {
|
|||
}, {
|
||||
.name = "mt6323-led",
|
||||
.of_compatible = "mediatek,mt6323-led"
|
||||
}, {
|
||||
.name = "mtk-pmic-keys",
|
||||
.num_resources = ARRAY_SIZE(mt6323_keys_resources),
|
||||
.resources = mt6323_keys_resources,
|
||||
.of_compatible = "mediatek,mt6323-keys"
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -71,7 +86,12 @@ static const struct mfd_cell mt6397_devs[] = {
|
|||
}, {
|
||||
.name = "mt6397-pinctrl",
|
||||
.of_compatible = "mediatek,mt6397-pinctrl",
|
||||
},
|
||||
}, {
|
||||
.name = "mtk-pmic-keys",
|
||||
.num_resources = ARRAY_SIZE(mt6397_keys_resources),
|
||||
.resources = mt6397_keys_resources,
|
||||
.of_compatible = "mediatek,mt6397-keys"
|
||||
}
|
||||
};
|
||||
|
||||
static void mt6397_irq_lock(struct irq_data *data)
|
||||
|
@ -289,7 +309,7 @@ static int mt6397_probe(struct platform_device *pdev)
|
|||
|
||||
ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs,
|
||||
ARRAY_SIZE(mt6323_devs), NULL,
|
||||
0, NULL);
|
||||
0, pmic->irq_domain);
|
||||
break;
|
||||
|
||||
case MT6397_CID_CODE:
|
||||
|
@ -304,7 +324,7 @@ static int mt6397_probe(struct platform_device *pdev)
|
|||
|
||||
ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs,
|
||||
ARRAY_SIZE(mt6397_devs), NULL,
|
||||
0, NULL);
|
||||
0, pmic->irq_domain);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -153,27 +153,6 @@ static const char * const port_modes[] = {
|
|||
[OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM] = "ohci-tll-2pin-dpdm",
|
||||
};
|
||||
|
||||
/**
|
||||
* omap_usbhs_get_dt_port_mode - Get the 'enum usbhs_omap_port_mode'
|
||||
* from the port mode string.
|
||||
* @mode: The port mode string, usually obtained from device tree.
|
||||
*
|
||||
* The function returns the 'enum usbhs_omap_port_mode' that matches the
|
||||
* provided port mode string as per the port_modes table.
|
||||
* If no match is found it returns -ENODEV
|
||||
*/
|
||||
static int omap_usbhs_get_dt_port_mode(const char *mode)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(port_modes); i++) {
|
||||
if (!strcmp(mode, port_modes[i]))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static struct platform_device *omap_usbhs_alloc_child(const char *name,
|
||||
struct resource *res, int num_resources, void *pdata,
|
||||
size_t pdata_size, struct device *dev)
|
||||
|
@ -529,7 +508,8 @@ static int usbhs_omap_get_dt_pdata(struct device *dev,
|
|||
if (ret < 0)
|
||||
continue;
|
||||
|
||||
ret = omap_usbhs_get_dt_port_mode(mode);
|
||||
/* get 'enum usbhs_omap_port_mode' from port mode string */
|
||||
ret = match_string(port_modes, ARRAY_SIZE(port_modes), mode);
|
||||
if (ret < 0) {
|
||||
dev_warn(dev, "Invalid port%d-mode \"%s\" in device tree\n",
|
||||
i, mode);
|
||||
|
|
|
@ -108,9 +108,9 @@
|
|||
(x) != OMAP_EHCI_PORT_MODE_PHY)
|
||||
|
||||
struct usbtll_omap {
|
||||
int nch; /* num. of channels */
|
||||
struct clk **ch_clk;
|
||||
void __iomem *base;
|
||||
void __iomem *base;
|
||||
int nch; /* num. of channels */
|
||||
struct clk *ch_clk[0]; /* must be the last member */
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
@ -216,53 +216,49 @@ static int usbtll_omap_probe(struct platform_device *pdev)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
struct usbtll_omap *tll;
|
||||
int ret = 0;
|
||||
int i, ver;
|
||||
void __iomem *base;
|
||||
int i, nch, ver;
|
||||
|
||||
dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
|
||||
|
||||
tll = devm_kzalloc(dev, sizeof(struct usbtll_omap), GFP_KERNEL);
|
||||
if (!tll) {
|
||||
dev_err(dev, "Memory allocation failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
tll->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(tll->base))
|
||||
return PTR_ERR(tll->base);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
platform_set_drvdata(pdev, tll);
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
ver = usbtll_read(tll->base, OMAP_USBTLL_REVISION);
|
||||
ver = usbtll_read(base, OMAP_USBTLL_REVISION);
|
||||
switch (ver) {
|
||||
case OMAP_USBTLL_REV1:
|
||||
case OMAP_USBTLL_REV4:
|
||||
tll->nch = OMAP_TLL_CHANNEL_COUNT;
|
||||
nch = OMAP_TLL_CHANNEL_COUNT;
|
||||
break;
|
||||
case OMAP_USBTLL_REV2:
|
||||
case OMAP_USBTLL_REV3:
|
||||
tll->nch = OMAP_REV2_TLL_CHANNEL_COUNT;
|
||||
nch = OMAP_REV2_TLL_CHANNEL_COUNT;
|
||||
break;
|
||||
default:
|
||||
tll->nch = OMAP_TLL_CHANNEL_COUNT;
|
||||
dev_dbg(dev,
|
||||
"USB TLL Rev : 0x%x not recognized, assuming %d channels\n",
|
||||
ver, tll->nch);
|
||||
nch = OMAP_TLL_CHANNEL_COUNT;
|
||||
dev_dbg(dev, "rev 0x%x not recognized, assuming %d channels\n",
|
||||
ver, nch);
|
||||
break;
|
||||
}
|
||||
|
||||
tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk *) * tll->nch,
|
||||
GFP_KERNEL);
|
||||
if (!tll->ch_clk) {
|
||||
ret = -ENOMEM;
|
||||
dev_err(dev, "Couldn't allocate memory for channel clocks\n");
|
||||
goto err_clk_alloc;
|
||||
tll = devm_kzalloc(dev, sizeof(*tll) + sizeof(tll->ch_clk[nch]),
|
||||
GFP_KERNEL);
|
||||
if (!tll) {
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < tll->nch; i++) {
|
||||
tll->base = base;
|
||||
tll->nch = nch;
|
||||
platform_set_drvdata(pdev, tll);
|
||||
|
||||
for (i = 0; i < nch; i++) {
|
||||
char clkname[] = "usb_tll_hs_usb_chx_clk";
|
||||
|
||||
snprintf(clkname, sizeof(clkname),
|
||||
|
@ -282,12 +278,6 @@ static int usbtll_omap_probe(struct platform_device *pdev)
|
|||
spin_unlock(&tll_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_alloc:
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -242,8 +242,10 @@ static int pcf50633_probe(struct i2c_client *client,
|
|||
|
||||
for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
|
||||
pdev = platform_device_alloc("pcf50633-regulator", i);
|
||||
if (!pdev)
|
||||
return -ENOMEM;
|
||||
if (!pdev) {
|
||||
ret = -ENOMEM;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
pdev->dev.parent = pcf->dev;
|
||||
ret = platform_device_add_data(pdev, &pdata->reg_init_data[i],
|
||||
|
@ -269,6 +271,7 @@ static int pcf50633_probe(struct i2c_client *client,
|
|||
|
||||
err:
|
||||
platform_device_put(pdev);
|
||||
err2:
|
||||
for (j = 0; j < i; j++)
|
||||
platform_device_put(pcf->regulator_pdev[j]);
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#define PM8916_SUBTYPE 0x0b
|
||||
#define PM8004_SUBTYPE 0x0c
|
||||
#define PM8909_SUBTYPE 0x0d
|
||||
#define PM8998_SUBTYPE 0x14
|
||||
#define PMI8998_SUBTYPE 0x15
|
||||
#define PM8005_SUBTYPE 0x18
|
||||
|
||||
static const struct of_device_id pmic_spmi_id_table[] = {
|
||||
{ .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE },
|
||||
|
@ -55,6 +58,9 @@ static const struct of_device_id pmic_spmi_id_table[] = {
|
|||
{ .compatible = "qcom,pm8916", .data = (void *)PM8916_SUBTYPE },
|
||||
{ .compatible = "qcom,pm8004", .data = (void *)PM8004_SUBTYPE },
|
||||
{ .compatible = "qcom,pm8909", .data = (void *)PM8909_SUBTYPE },
|
||||
{ .compatible = "qcom,pm8998", .data = (void *)PM8998_SUBTYPE },
|
||||
{ .compatible = "qcom,pmi8998", .data = (void *)PMI8998_SUBTYPE },
|
||||
{ .compatible = "qcom,pm8005", .data = (void *)PM8005_SUBTYPE },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -45,7 +45,9 @@
|
|||
#define RAVE_SP_DLE 0x10
|
||||
|
||||
#define RAVE_SP_MAX_DATA_SIZE 64
|
||||
#define RAVE_SP_CHECKSUM_SIZE 2 /* Worst case scenario on RDU2 */
|
||||
#define RAVE_SP_CHECKSUM_8B2C 1
|
||||
#define RAVE_SP_CHECKSUM_CCITT 2
|
||||
#define RAVE_SP_CHECKSUM_SIZE RAVE_SP_CHECKSUM_CCITT
|
||||
/*
|
||||
* We don't store STX, ETX and unescaped bytes, so Rx is only
|
||||
* DATA + CSUM
|
||||
|
@ -160,6 +162,8 @@ struct rave_sp_variant {
|
|||
* @variant: Device variant specific information
|
||||
* @event_notifier_list: Input event notification chain
|
||||
*
|
||||
* @part_number_firmware: Firmware version
|
||||
* @part_number_bootloader: Bootloader version
|
||||
*/
|
||||
struct rave_sp {
|
||||
struct serdev_device *serdev;
|
||||
|
@ -171,8 +175,40 @@ struct rave_sp {
|
|||
|
||||
const struct rave_sp_variant *variant;
|
||||
struct blocking_notifier_head event_notifier_list;
|
||||
|
||||
const char *part_number_firmware;
|
||||
const char *part_number_bootloader;
|
||||
};
|
||||
|
||||
struct rave_sp_version {
|
||||
u8 hardware;
|
||||
__le16 major;
|
||||
u8 minor;
|
||||
u8 letter[2];
|
||||
} __packed;
|
||||
|
||||
struct rave_sp_status {
|
||||
struct rave_sp_version bootloader_version;
|
||||
struct rave_sp_version firmware_version;
|
||||
u16 rdu_eeprom_flag;
|
||||
u16 dds_eeprom_flag;
|
||||
u8 pic_flag;
|
||||
u8 orientation;
|
||||
u32 etc;
|
||||
s16 temp[2];
|
||||
u8 backlight_current[3];
|
||||
u8 dip_switch;
|
||||
u8 host_interrupt;
|
||||
u16 voltage_28;
|
||||
u8 i2c_device_status;
|
||||
u8 power_status;
|
||||
u8 general_status;
|
||||
u8 deprecated1;
|
||||
u8 power_led_status;
|
||||
u8 deprecated2;
|
||||
u8 periph_power_shutoff;
|
||||
} __packed;
|
||||
|
||||
static bool rave_sp_id_is_event(u8 code)
|
||||
{
|
||||
return (code & 0xF0) == RAVE_SP_EVNT_BASE;
|
||||
|
@ -275,8 +311,8 @@ static int rave_sp_write(struct rave_sp *sp, const u8 *data, u8 data_size)
|
|||
|
||||
length = dest - frame;
|
||||
|
||||
print_hex_dump(KERN_DEBUG, "rave-sp tx: ", DUMP_PREFIX_NONE,
|
||||
16, 1, frame, length, false);
|
||||
print_hex_dump_debug("rave-sp tx: ", DUMP_PREFIX_NONE,
|
||||
16, 1, frame, length, false);
|
||||
|
||||
return serdev_device_write(sp->serdev, frame, length, HZ);
|
||||
}
|
||||
|
@ -415,10 +451,15 @@ static void rave_sp_receive_frame(struct rave_sp *sp,
|
|||
const size_t payload_length = length - checksum_length;
|
||||
const u8 *crc_reported = &data[payload_length];
|
||||
struct device *dev = &sp->serdev->dev;
|
||||
u8 crc_calculated[checksum_length];
|
||||
u8 crc_calculated[RAVE_SP_CHECKSUM_SIZE];
|
||||
|
||||
print_hex_dump(KERN_DEBUG, "rave-sp rx: ", DUMP_PREFIX_NONE,
|
||||
16, 1, data, length, false);
|
||||
if (unlikely(checksum_length > sizeof(crc_calculated))) {
|
||||
dev_warn(dev, "Checksum too long, dropping\n");
|
||||
return;
|
||||
}
|
||||
|
||||
print_hex_dump_debug("rave-sp rx: ", DUMP_PREFIX_NONE,
|
||||
16, 1, data, length, false);
|
||||
|
||||
if (unlikely(length <= checksum_length)) {
|
||||
dev_warn(dev, "Dropping short frame\n");
|
||||
|
@ -512,8 +553,6 @@ static int rave_sp_receive_buf(struct serdev_device *serdev,
|
|||
/* FALLTHROUGH */
|
||||
|
||||
case RAVE_SP_EXPECT_ESCAPED_DATA:
|
||||
deframer->data[deframer->length++] = byte;
|
||||
|
||||
if (deframer->length == sizeof(deframer->data)) {
|
||||
dev_warn(dev, "Bad frame: Too long\n");
|
||||
/*
|
||||
|
@ -528,6 +567,8 @@ static int rave_sp_receive_buf(struct serdev_device *serdev,
|
|||
goto reset_framer;
|
||||
}
|
||||
|
||||
deframer->data[deframer->length++] = byte;
|
||||
|
||||
/*
|
||||
* We've extracted out special byte, now we
|
||||
* can go back to regular data collecting
|
||||
|
@ -609,6 +650,52 @@ static int rave_sp_default_cmd_translate(enum rave_sp_command command)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *devm_rave_sp_version(struct device *dev,
|
||||
struct rave_sp_version *version)
|
||||
{
|
||||
/*
|
||||
* NOTE: The format string below uses %02d to display u16
|
||||
* intentionally for the sake of backwards compatibility with
|
||||
* legacy software.
|
||||
*/
|
||||
return devm_kasprintf(dev, GFP_KERNEL, "%02d%02d%02d.%c%c\n",
|
||||
version->hardware,
|
||||
le16_to_cpu(version->major),
|
||||
version->minor,
|
||||
version->letter[0],
|
||||
version->letter[1]);
|
||||
}
|
||||
|
||||
static int rave_sp_get_status(struct rave_sp *sp)
|
||||
{
|
||||
struct device *dev = &sp->serdev->dev;
|
||||
u8 cmd[] = {
|
||||
[0] = RAVE_SP_CMD_STATUS,
|
||||
[1] = 0
|
||||
};
|
||||
struct rave_sp_status status;
|
||||
const char *version;
|
||||
int ret;
|
||||
|
||||
ret = rave_sp_exec(sp, cmd, sizeof(cmd), &status, sizeof(status));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
version = devm_rave_sp_version(dev, &status.firmware_version);
|
||||
if (!version)
|
||||
return -ENOMEM;
|
||||
|
||||
sp->part_number_firmware = version;
|
||||
|
||||
version = devm_rave_sp_version(dev, &status.bootloader_version);
|
||||
if (!version)
|
||||
return -ENOMEM;
|
||||
|
||||
sp->part_number_bootloader = version;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rave_sp_checksum rave_sp_checksum_8b2c = {
|
||||
.length = 1,
|
||||
.subroutine = csum_8b2c,
|
||||
|
@ -657,6 +744,7 @@ static const struct serdev_device_ops rave_sp_serdev_device_ops = {
|
|||
static int rave_sp_probe(struct serdev_device *serdev)
|
||||
{
|
||||
struct device *dev = &serdev->dev;
|
||||
const char *unknown = "unknown\n";
|
||||
struct rave_sp *sp;
|
||||
u32 baud;
|
||||
int ret;
|
||||
|
@ -689,6 +777,20 @@ static int rave_sp_probe(struct serdev_device *serdev)
|
|||
|
||||
serdev_device_set_baudrate(serdev, baud);
|
||||
|
||||
ret = rave_sp_get_status(sp);
|
||||
if (ret) {
|
||||
dev_warn(dev, "Failed to get firmware status: %d\n", ret);
|
||||
sp->part_number_firmware = unknown;
|
||||
sp->part_number_bootloader = unknown;
|
||||
}
|
||||
|
||||
/*
|
||||
* Those strings already have a \n embedded, so there's no
|
||||
* need to have one in format string.
|
||||
*/
|
||||
dev_info(dev, "Firmware version: %s", sp->part_number_firmware);
|
||||
dev_info(dev, "Bootloader version: %s", sp->part_number_bootloader);
|
||||
|
||||
return devm_of_platform_populate(dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -258,11 +258,9 @@ static int rc5t583_i2c_probe(struct i2c_client *i2c,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc5t583 = devm_kzalloc(&i2c->dev, sizeof(struct rc5t583), GFP_KERNEL);
|
||||
if (!rc5t583) {
|
||||
dev_err(&i2c->dev, "Memory allocation failed\n");
|
||||
rc5t583 = devm_kzalloc(&i2c->dev, sizeof(*rc5t583), GFP_KERNEL);
|
||||
if (!rc5t583)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc5t583->dev = &i2c->dev;
|
||||
i2c_set_clientdata(i2c, rc5t583);
|
||||
|
|
|
@ -697,11 +697,9 @@ static int si476x_core_probe(struct i2c_client *client,
|
|||
int cell_num;
|
||||
|
||||
core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
|
||||
if (!core) {
|
||||
dev_err(&client->dev,
|
||||
"failed to allocate 'struct si476x_core'\n");
|
||||
if (!core)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
core->client = client;
|
||||
|
||||
core->regmap = devm_regmap_init_si476x(core);
|
||||
|
|
|
@ -1050,13 +1050,13 @@ static int sm501_register_gpio(struct sm501_devdata *sm)
|
|||
spin_lock_init(&gpio->lock);
|
||||
|
||||
gpio->regs_res = request_mem_region(iobase, 0x20, "sm501-gpio");
|
||||
if (gpio->regs_res == NULL) {
|
||||
if (!gpio->regs_res) {
|
||||
dev_err(sm->dev, "gpio: failed to request region\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
gpio->regs = ioremap(iobase, 0x20);
|
||||
if (gpio->regs == NULL) {
|
||||
if (!gpio->regs) {
|
||||
dev_err(sm->dev, "gpio: failed to remap registers\n");
|
||||
ret = -ENXIO;
|
||||
goto err_claimed;
|
||||
|
@ -1358,7 +1358,7 @@ static int sm501_init_dev(struct sm501_devdata *sm)
|
|||
sm501_register_gpio(sm);
|
||||
}
|
||||
|
||||
if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) {
|
||||
if (pdata && pdata->gpio_i2c && pdata->gpio_i2c_nr > 0) {
|
||||
if (!sm501_gpio_isregistered(sm))
|
||||
dev_err(sm->dev, "no gpio available for i2c gpio.\n");
|
||||
else
|
||||
|
@ -1383,9 +1383,8 @@ static int sm501_plat_probe(struct platform_device *dev)
|
|||
struct sm501_devdata *sm;
|
||||
int ret;
|
||||
|
||||
sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL);
|
||||
if (sm == NULL) {
|
||||
dev_err(&dev->dev, "no memory for device data\n");
|
||||
sm = kzalloc(sizeof(*sm), GFP_KERNEL);
|
||||
if (!sm) {
|
||||
ret = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
|
@ -1403,8 +1402,7 @@ static int sm501_plat_probe(struct platform_device *dev)
|
|||
|
||||
sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
|
||||
sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
|
||||
|
||||
if (sm->io_res == NULL || sm->mem_res == NULL) {
|
||||
if (!sm->io_res || !sm->mem_res) {
|
||||
dev_err(&dev->dev, "failed to get IO resource\n");
|
||||
ret = -ENOENT;
|
||||
goto err_res;
|
||||
|
@ -1412,8 +1410,7 @@ static int sm501_plat_probe(struct platform_device *dev)
|
|||
|
||||
sm->regs_claim = request_mem_region(sm->io_res->start,
|
||||
0x100, "sm501");
|
||||
|
||||
if (sm->regs_claim == NULL) {
|
||||
if (!sm->regs_claim) {
|
||||
dev_err(&dev->dev, "cannot claim registers\n");
|
||||
ret = -EBUSY;
|
||||
goto err_res;
|
||||
|
@ -1422,8 +1419,7 @@ static int sm501_plat_probe(struct platform_device *dev)
|
|||
platform_set_drvdata(dev, sm);
|
||||
|
||||
sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res));
|
||||
|
||||
if (sm->regs == NULL) {
|
||||
if (!sm->regs) {
|
||||
dev_err(&dev->dev, "cannot remap registers\n");
|
||||
ret = -EIO;
|
||||
goto err_claim;
|
||||
|
@ -1449,7 +1445,7 @@ static void sm501_set_power(struct sm501_devdata *sm, int on)
|
|||
{
|
||||
struct sm501_platdata *pd = sm->platdata;
|
||||
|
||||
if (pd == NULL)
|
||||
if (!pd)
|
||||
return;
|
||||
|
||||
if (pd->get_power) {
|
||||
|
@ -1573,9 +1569,8 @@ static int sm501_pci_probe(struct pci_dev *dev,
|
|||
struct sm501_devdata *sm;
|
||||
int err;
|
||||
|
||||
sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL);
|
||||
if (sm == NULL) {
|
||||
dev_err(&dev->dev, "no memory for device data\n");
|
||||
sm = kzalloc(sizeof(*sm), GFP_KERNEL);
|
||||
if (!sm) {
|
||||
err = -ENOMEM;
|
||||
goto err1;
|
||||
}
|
||||
|
@ -1626,15 +1621,14 @@ static int sm501_pci_probe(struct pci_dev *dev,
|
|||
|
||||
sm->regs_claim = request_mem_region(sm->io_res->start,
|
||||
0x100, "sm501");
|
||||
if (sm->regs_claim == NULL) {
|
||||
if (!sm->regs_claim) {
|
||||
dev_err(&dev->dev, "cannot claim registers\n");
|
||||
err= -EBUSY;
|
||||
goto err3;
|
||||
}
|
||||
|
||||
sm->regs = pci_ioremap_bar(dev, 1);
|
||||
|
||||
if (sm->regs == NULL) {
|
||||
if (!sm->regs) {
|
||||
dev_err(&dev->dev, "cannot remap registers\n");
|
||||
err = -EIO;
|
||||
goto err4;
|
||||
|
|
|
@ -37,12 +37,9 @@ static int smsc_i2c_probe(struct i2c_client *i2c,
|
|||
int devid, rev, venid_l, venid_h;
|
||||
int ret;
|
||||
|
||||
smsc = devm_kzalloc(&i2c->dev, sizeof(struct smsc),
|
||||
GFP_KERNEL);
|
||||
if (!smsc) {
|
||||
dev_err(&i2c->dev, "smsc mfd driver memory allocation failed\n");
|
||||
smsc = devm_kzalloc(&i2c->dev, sizeof(*smsc), GFP_KERNEL);
|
||||
if (!smsc)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config);
|
||||
if (IS_ERR(smsc->regmap))
|
||||
|
|
|
@ -111,6 +111,9 @@ static const struct mfd_cell sprd_pmic_devs[] = {
|
|||
}, {
|
||||
.name = "sc27xx-poweroff",
|
||||
.of_compatible = "sprd,sc27xx-poweroff",
|
||||
}, {
|
||||
.name = "sc27xx-syscon",
|
||||
.of_compatible = "sprd,sc27xx-syscon",
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -4,16 +4,156 @@
|
|||
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/mfd/stm32-timers.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#define STM32_TIMERS_MAX_REGISTERS 0x3fc
|
||||
|
||||
/* DIER register DMA enable bits */
|
||||
static const u32 stm32_timers_dier_dmaen[STM32_TIMERS_MAX_DMAS] = {
|
||||
TIM_DIER_CC1DE,
|
||||
TIM_DIER_CC2DE,
|
||||
TIM_DIER_CC3DE,
|
||||
TIM_DIER_CC4DE,
|
||||
TIM_DIER_UIE,
|
||||
TIM_DIER_TDE,
|
||||
TIM_DIER_COMDE
|
||||
};
|
||||
|
||||
static void stm32_timers_dma_done(void *p)
|
||||
{
|
||||
struct stm32_timers_dma *dma = p;
|
||||
struct dma_tx_state state;
|
||||
enum dma_status status;
|
||||
|
||||
status = dmaengine_tx_status(dma->chan, dma->chan->cookie, &state);
|
||||
if (status == DMA_COMPLETE)
|
||||
complete(&dma->completion);
|
||||
}
|
||||
|
||||
/**
|
||||
* stm32_timers_dma_burst_read - Read from timers registers using DMA.
|
||||
*
|
||||
* Read from STM32 timers registers using DMA on a single event.
|
||||
* @dev: reference to stm32_timers MFD device
|
||||
* @buf: DMA'able destination buffer
|
||||
* @id: stm32_timers_dmas event identifier (ch[1..4], up, trig or com)
|
||||
* @reg: registers start offset for DMA to read from (like CCRx for capture)
|
||||
* @num_reg: number of registers to read upon each DMA request, starting @reg.
|
||||
* @bursts: number of bursts to read (e.g. like two for pwm period capture)
|
||||
* @tmo_ms: timeout (milliseconds)
|
||||
*/
|
||||
int stm32_timers_dma_burst_read(struct device *dev, u32 *buf,
|
||||
enum stm32_timers_dmas id, u32 reg,
|
||||
unsigned int num_reg, unsigned int bursts,
|
||||
unsigned long tmo_ms)
|
||||
{
|
||||
struct stm32_timers *ddata = dev_get_drvdata(dev);
|
||||
unsigned long timeout = msecs_to_jiffies(tmo_ms);
|
||||
struct regmap *regmap = ddata->regmap;
|
||||
struct stm32_timers_dma *dma = &ddata->dma;
|
||||
size_t len = num_reg * bursts * sizeof(u32);
|
||||
struct dma_async_tx_descriptor *desc;
|
||||
struct dma_slave_config config;
|
||||
dma_cookie_t cookie;
|
||||
dma_addr_t dma_buf;
|
||||
u32 dbl, dba;
|
||||
long err;
|
||||
int ret;
|
||||
|
||||
/* Sanity check */
|
||||
if (id < STM32_TIMERS_DMA_CH1 || id >= STM32_TIMERS_MAX_DMAS)
|
||||
return -EINVAL;
|
||||
|
||||
if (!num_reg || !bursts || reg > STM32_TIMERS_MAX_REGISTERS ||
|
||||
(reg + num_reg * sizeof(u32)) > STM32_TIMERS_MAX_REGISTERS)
|
||||
return -EINVAL;
|
||||
|
||||
if (!dma->chans[id])
|
||||
return -ENODEV;
|
||||
mutex_lock(&dma->lock);
|
||||
|
||||
/* Select DMA channel in use */
|
||||
dma->chan = dma->chans[id];
|
||||
dma_buf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(dev, dma_buf)) {
|
||||
ret = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
/* Prepare DMA read from timer registers, using DMA burst mode */
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.src_addr = (dma_addr_t)dma->phys_base + TIM_DMAR;
|
||||
config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
ret = dmaengine_slave_config(dma->chan, &config);
|
||||
if (ret)
|
||||
goto unmap;
|
||||
|
||||
desc = dmaengine_prep_slave_single(dma->chan, dma_buf, len,
|
||||
DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
|
||||
if (!desc) {
|
||||
ret = -EBUSY;
|
||||
goto unmap;
|
||||
}
|
||||
|
||||
desc->callback = stm32_timers_dma_done;
|
||||
desc->callback_param = dma;
|
||||
cookie = dmaengine_submit(desc);
|
||||
ret = dma_submit_error(cookie);
|
||||
if (ret)
|
||||
goto dma_term;
|
||||
|
||||
reinit_completion(&dma->completion);
|
||||
dma_async_issue_pending(dma->chan);
|
||||
|
||||
/* Setup and enable timer DMA burst mode */
|
||||
dbl = FIELD_PREP(TIM_DCR_DBL, bursts - 1);
|
||||
dba = FIELD_PREP(TIM_DCR_DBA, reg >> 2);
|
||||
ret = regmap_write(regmap, TIM_DCR, dbl | dba);
|
||||
if (ret)
|
||||
goto dma_term;
|
||||
|
||||
/* Clear pending flags before enabling DMA request */
|
||||
ret = regmap_write(regmap, TIM_SR, 0);
|
||||
if (ret)
|
||||
goto dcr_clr;
|
||||
|
||||
ret = regmap_update_bits(regmap, TIM_DIER, stm32_timers_dier_dmaen[id],
|
||||
stm32_timers_dier_dmaen[id]);
|
||||
if (ret)
|
||||
goto dcr_clr;
|
||||
|
||||
err = wait_for_completion_interruptible_timeout(&dma->completion,
|
||||
timeout);
|
||||
if (err == 0)
|
||||
ret = -ETIMEDOUT;
|
||||
else if (err < 0)
|
||||
ret = err;
|
||||
|
||||
regmap_update_bits(regmap, TIM_DIER, stm32_timers_dier_dmaen[id], 0);
|
||||
regmap_write(regmap, TIM_SR, 0);
|
||||
dcr_clr:
|
||||
regmap_write(regmap, TIM_DCR, 0);
|
||||
dma_term:
|
||||
dmaengine_terminate_all(dma->chan);
|
||||
unmap:
|
||||
dma_unmap_single(dev, dma_buf, len, DMA_FROM_DEVICE);
|
||||
unlock:
|
||||
dma->chan = NULL;
|
||||
mutex_unlock(&dma->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(stm32_timers_dma_burst_read);
|
||||
|
||||
static const struct regmap_config stm32_timers_regmap_cfg = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = sizeof(u32),
|
||||
.max_register = 0x3fc,
|
||||
.max_register = STM32_TIMERS_MAX_REGISTERS,
|
||||
};
|
||||
|
||||
static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
|
||||
|
@ -27,12 +167,45 @@ static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
|
|||
regmap_write(ddata->regmap, TIM_ARR, 0x0);
|
||||
}
|
||||
|
||||
static void stm32_timers_dma_probe(struct device *dev,
|
||||
struct stm32_timers *ddata)
|
||||
{
|
||||
int i;
|
||||
char name[4];
|
||||
|
||||
init_completion(&ddata->dma.completion);
|
||||
mutex_init(&ddata->dma.lock);
|
||||
|
||||
/* Optional DMA support: get valid DMA channel(s) or NULL */
|
||||
for (i = STM32_TIMERS_DMA_CH1; i <= STM32_TIMERS_DMA_CH4; i++) {
|
||||
snprintf(name, ARRAY_SIZE(name), "ch%1d", i + 1);
|
||||
ddata->dma.chans[i] = dma_request_slave_channel(dev, name);
|
||||
}
|
||||
ddata->dma.chans[STM32_TIMERS_DMA_UP] =
|
||||
dma_request_slave_channel(dev, "up");
|
||||
ddata->dma.chans[STM32_TIMERS_DMA_TRIG] =
|
||||
dma_request_slave_channel(dev, "trig");
|
||||
ddata->dma.chans[STM32_TIMERS_DMA_COM] =
|
||||
dma_request_slave_channel(dev, "com");
|
||||
}
|
||||
|
||||
static void stm32_timers_dma_remove(struct device *dev,
|
||||
struct stm32_timers *ddata)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = STM32_TIMERS_DMA_CH1; i < STM32_TIMERS_MAX_DMAS; i++)
|
||||
if (ddata->dma.chans[i])
|
||||
dma_release_channel(ddata->dma.chans[i]);
|
||||
}
|
||||
|
||||
static int stm32_timers_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct stm32_timers *ddata;
|
||||
struct resource *res;
|
||||
void __iomem *mmio;
|
||||
int ret;
|
||||
|
||||
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
|
||||
if (!ddata)
|
||||
|
@ -43,6 +216,9 @@ static int stm32_timers_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(mmio))
|
||||
return PTR_ERR(mmio);
|
||||
|
||||
/* Timer physical addr for DMA */
|
||||
ddata->dma.phys_base = res->start;
|
||||
|
||||
ddata->regmap = devm_regmap_init_mmio_clk(dev, "int", mmio,
|
||||
&stm32_timers_regmap_cfg);
|
||||
if (IS_ERR(ddata->regmap))
|
||||
|
@ -54,9 +230,29 @@ static int stm32_timers_probe(struct platform_device *pdev)
|
|||
|
||||
stm32_timers_get_arr_size(ddata);
|
||||
|
||||
stm32_timers_dma_probe(dev, ddata);
|
||||
|
||||
platform_set_drvdata(pdev, ddata);
|
||||
|
||||
return devm_of_platform_populate(&pdev->dev);
|
||||
ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
|
||||
if (ret)
|
||||
stm32_timers_dma_remove(dev, ddata);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_timers_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct stm32_timers *ddata = platform_get_drvdata(pdev);
|
||||
|
||||
/*
|
||||
* Don't use devm_ here: enfore of_platform_depopulate() happens before
|
||||
* DMA are released, to avoid race on DMA.
|
||||
*/
|
||||
of_platform_depopulate(&pdev->dev);
|
||||
stm32_timers_dma_remove(&pdev->dev, ddata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id stm32_timers_of_match[] = {
|
||||
|
@ -67,6 +263,7 @@ MODULE_DEVICE_TABLE(of, stm32_timers_of_match);
|
|||
|
||||
static struct platform_driver stm32_timers_driver = {
|
||||
.probe = stm32_timers_probe,
|
||||
.remove = stm32_timers_remove,
|
||||
.driver = {
|
||||
.name = "stm32-timers",
|
||||
.of_match_table = stm32_timers_of_match,
|
||||
|
|
|
@ -106,9 +106,11 @@ static struct syscon *of_syscon_register(struct device_node *np)
|
|||
}
|
||||
}
|
||||
|
||||
syscon_config.name = of_node_full_name(np);
|
||||
syscon_config.reg_stride = reg_io_width;
|
||||
syscon_config.val_bits = reg_io_width * 8;
|
||||
syscon_config.max_register = resource_size(&res) - reg_io_width;
|
||||
syscon_config.name = of_node_full_name(np);
|
||||
|
||||
regmap = regmap_init_mmio(NULL, base, &syscon_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
|
|
|
@ -169,10 +169,9 @@ static int ti_tscadc_probe(struct platform_device *pdev)
|
|||
|
||||
/* Allocate memory for device */
|
||||
tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL);
|
||||
if (!tscadc) {
|
||||
dev_err(&pdev->dev, "failed to allocate memory.\n");
|
||||
if (!tscadc)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tscadc->dev = &pdev->dev;
|
||||
|
||||
err = platform_get_irq(pdev, 0);
|
||||
|
|
|
@ -777,7 +777,7 @@ static int timb_probe(struct pci_dev *dev,
|
|||
&dev->resource[0], msix_entries[0].vector, NULL);
|
||||
break;
|
||||
default:
|
||||
dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n",
|
||||
dev_err(&dev->dev, "Unknown IP setup: %d.%d.%d\n",
|
||||
priv->fw.major, priv->fw.minor, ip_setup);
|
||||
err = -ENODEV;
|
||||
goto err_mfd;
|
||||
|
|
|
@ -192,10 +192,8 @@ static int tps65090_i2c_probe(struct i2c_client *client,
|
|||
irq_base = pdata->irq_base;
|
||||
|
||||
tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL);
|
||||
if (!tps65090) {
|
||||
dev_err(&client->dev, "mem alloc for tps65090 failed\n");
|
||||
if (!tps65090)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tps65090->dev = &client->dev;
|
||||
i2c_set_clientdata(client, tps65090);
|
||||
|
|
|
@ -423,10 +423,8 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
|
|||
struct tps6586x_platform_data *pdata;
|
||||
|
||||
pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata) {
|
||||
dev_err(&client->dev, "Memory allocation failed\n");
|
||||
if (!pdata)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pdata->num_subdevs = 0;
|
||||
pdata->subdevs = NULL;
|
||||
|
|
|
@ -229,7 +229,7 @@ static struct regmap_irq_chip tps65910_irq_chip = {
|
|||
static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
|
||||
struct tps65910_platform_data *pdata)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret;
|
||||
static struct regmap_irq_chip *tps6591x_irqs_chip;
|
||||
|
||||
if (!irq) {
|
||||
|
@ -312,14 +312,14 @@ static int tps65910_ck32k_init(struct tps65910 *tps65910,
|
|||
static int tps65910_sleepinit(struct tps65910 *tps65910,
|
||||
struct tps65910_board *pmic_pdata)
|
||||
{
|
||||
struct device *dev = NULL;
|
||||
int ret = 0;
|
||||
|
||||
dev = tps65910->dev;
|
||||
struct device *dev;
|
||||
int ret;
|
||||
|
||||
if (!pmic_pdata->en_dev_slp)
|
||||
return 0;
|
||||
|
||||
dev = tps65910->dev;
|
||||
|
||||
/* enabling SLEEP device state */
|
||||
ret = tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL,
|
||||
DEVCTRL_DEV_SLP_MASK);
|
||||
|
@ -383,7 +383,7 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
|
|||
struct tps65910_board *board_info;
|
||||
unsigned int prop;
|
||||
const struct of_device_id *match;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
match = of_match_device(tps65910_of_match, &client->dev);
|
||||
if (!match) {
|
||||
|
@ -395,10 +395,8 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
|
|||
|
||||
board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
|
||||
GFP_KERNEL);
|
||||
if (!board_info) {
|
||||
dev_err(&client->dev, "Failed to allocate pdata\n");
|
||||
if (!board_info)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "ti,vmbch-threshold", &prop);
|
||||
if (!ret)
|
||||
|
@ -462,7 +460,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
|
|||
struct tps65910_board *of_pmic_plat_data = NULL;
|
||||
struct tps65910_platform_data *init_data;
|
||||
unsigned long chip_id = id->driver_data;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
pmic_plat_data = dev_get_platdata(&i2c->dev);
|
||||
|
||||
|
|
|
@ -22,9 +22,8 @@
|
|||
#include <linux/gpio.h>
|
||||
#include <linux/mfd/tps65910.h>
|
||||
|
||||
#define COMP 0
|
||||
#define COMP1 1
|
||||
#define COMP2 2
|
||||
#define COMP1 0
|
||||
#define COMP2 1
|
||||
|
||||
/* Comparator 1 voltage selection table in millivolts */
|
||||
static const u16 COMP_VSEL_TABLE[] = {
|
||||
|
@ -63,9 +62,6 @@ static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage)
|
|||
int ret;
|
||||
u8 index = 0, val;
|
||||
|
||||
if (id == COMP)
|
||||
return 0;
|
||||
|
||||
while (curr_voltage < tps_comp.uV_max) {
|
||||
curr_voltage = tps_comp.vsel_table[index];
|
||||
if (curr_voltage >= voltage)
|
||||
|
@ -78,7 +74,7 @@ static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage)
|
|||
return -EINVAL;
|
||||
|
||||
val = index << 1;
|
||||
ret = tps65910->write(tps65910, tps_comp.reg, 1, &val);
|
||||
ret = tps65910_reg_write(tps65910, tps_comp.reg, val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -86,13 +82,10 @@ static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage)
|
|||
static int comp_threshold_get(struct tps65910 *tps65910, int id)
|
||||
{
|
||||
struct comparator tps_comp = tps_comparators[id];
|
||||
unsigned int val;
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
if (id == COMP)
|
||||
return 0;
|
||||
|
||||
ret = tps65910->read(tps65910, tps_comp.reg, 1, &val);
|
||||
ret = tps65910_reg_read(tps65910, tps_comp.reg, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* TPS68470 chip Parent driver
|
||||
*
|
||||
|
@ -8,15 +9,6 @@
|
|||
* Tianshu Qiu <tian.shu.qiu@intel.com>
|
||||
* Jian Xu Zheng <jian.xu.zheng@intel.com>
|
||||
* Yuning Pu <yuning.pu@intel.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 version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
|
|
|
@ -431,10 +431,8 @@ static int tps80031_probe(struct i2c_client *client,
|
|||
}
|
||||
|
||||
tps80031 = devm_kzalloc(&client->dev, sizeof(*tps80031), GFP_KERNEL);
|
||||
if (!tps80031) {
|
||||
dev_err(&client->dev, "Malloc failed for tps80031\n");
|
||||
if (!tps80031)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < TPS80031_NUM_SLAVES; i++) {
|
||||
if (tps80031_slave_address[i] == client->addr)
|
||||
|
|
|
@ -1177,7 +1177,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||
twl_priv->ready = true;
|
||||
|
||||
/* setup clock framework */
|
||||
clocks_init(&pdev->dev, pdata ? pdata->clock : NULL);
|
||||
clocks_init(&client->dev, pdata ? pdata->clock : NULL);
|
||||
|
||||
/* read TWL IDCODE Register */
|
||||
if (twl_class_is_4030()) {
|
||||
|
|
|
@ -392,10 +392,8 @@ int twl6030_init_irq(struct device *dev, int irq_num)
|
|||
nr_irqs = TWL6030_NR_IRQS;
|
||||
|
||||
twl6030_irq = devm_kzalloc(dev, sizeof(*twl6030_irq), GFP_KERNEL);
|
||||
if (!twl6030_irq) {
|
||||
dev_err(dev, "twl6030_irq: Memory allocation failed\n");
|
||||
if (!twl6030_irq)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mask[0] = 0xFF;
|
||||
mask[1] = 0xFF;
|
||||
|
|
|
@ -59,10 +59,8 @@ static int vprbrd_probe(struct usb_interface *interface,
|
|||
|
||||
/* allocate memory for our device state and initialize it */
|
||||
vb = kzalloc(sizeof(*vb), GFP_KERNEL);
|
||||
if (vb == NULL) {
|
||||
dev_err(&interface->dev, "Out of memory\n");
|
||||
if (!vb)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mutex_init(&vb->lock);
|
||||
|
||||
|
|
|
@ -278,7 +278,7 @@ static int wm97xx_ac97_probe(struct ac97_codec_device *adev)
|
|||
|
||||
codec_pdata = &wm97xx->codec_pdata;
|
||||
codec_pdata->ac97 = wm97xx->ac97;
|
||||
codec_pdata->batt_pdata = pdata->batt_pdata;
|
||||
codec_pdata->batt_pdata = pdata ? pdata->batt_pdata : NULL;
|
||||
|
||||
switch (adev->vendor_id) {
|
||||
case WM9705_VENDOR_ID:
|
||||
|
|
|
@ -470,3 +470,23 @@ void cros_ec_debugfs_remove(struct cros_ec_dev *ec)
|
|||
cros_ec_cleanup_console_log(ec->debug_info);
|
||||
}
|
||||
EXPORT_SYMBOL(cros_ec_debugfs_remove);
|
||||
|
||||
void cros_ec_debugfs_suspend(struct cros_ec_dev *ec)
|
||||
{
|
||||
/*
|
||||
* cros_ec_debugfs_init() failures are non-fatal; it's also possible
|
||||
* that we initted things but decided that console log wasn't supported.
|
||||
* We'll use the same set of checks that cros_ec_debugfs_remove() +
|
||||
* cros_ec_cleanup_console_log() end up using to handle those cases.
|
||||
*/
|
||||
if (ec->debug_info && ec->debug_info->log_buffer.buf)
|
||||
cancel_delayed_work_sync(&ec->debug_info->log_poll_work);
|
||||
}
|
||||
EXPORT_SYMBOL(cros_ec_debugfs_suspend);
|
||||
|
||||
void cros_ec_debugfs_resume(struct cros_ec_dev *ec)
|
||||
{
|
||||
if (ec->debug_info && ec->debug_info->log_buffer.buf)
|
||||
schedule_delayed_work(&ec->debug_info->log_poll_work, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(cros_ec_debugfs_resume);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* pwm-atmel.c from Bo Shen
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/mfd/stm32-timers.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -25,6 +26,7 @@ struct stm32_pwm {
|
|||
struct regmap *regmap;
|
||||
u32 max_arr;
|
||||
bool have_complementary_output;
|
||||
u32 capture[4] ____cacheline_aligned; /* DMA'able buffer */
|
||||
};
|
||||
|
||||
struct stm32_breakinput {
|
||||
|
@ -62,6 +64,258 @@ static int write_ccrx(struct stm32_pwm *dev, int ch, u32 value)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#define TIM_CCER_CC12P (TIM_CCER_CC1P | TIM_CCER_CC2P)
|
||||
#define TIM_CCER_CC12E (TIM_CCER_CC1E | TIM_CCER_CC2E)
|
||||
#define TIM_CCER_CC34P (TIM_CCER_CC3P | TIM_CCER_CC4P)
|
||||
#define TIM_CCER_CC34E (TIM_CCER_CC3E | TIM_CCER_CC4E)
|
||||
|
||||
/*
|
||||
* Capture using PWM input mode:
|
||||
* ___ ___
|
||||
* TI[1, 2, 3 or 4]: ........._| |________|
|
||||
* ^0 ^1 ^2
|
||||
* . . .
|
||||
* . . XXXXX
|
||||
* . . XXXXX |
|
||||
* . XXXXX . |
|
||||
* XXXXX . . |
|
||||
* COUNTER: ______XXXXX . . . |_XXX
|
||||
* start^ . . . ^stop
|
||||
* . . . .
|
||||
* v v . v
|
||||
* v
|
||||
* CCR1/CCR3: tx..........t0...........t2
|
||||
* CCR2/CCR4: tx..............t1.........
|
||||
*
|
||||
* DMA burst transfer: | |
|
||||
* v v
|
||||
* DMA buffer: { t0, tx } { t2, t1 }
|
||||
* DMA done: ^
|
||||
*
|
||||
* 0: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
|
||||
* + DMA transfer CCR[1/3] & CCR[2/4] values (t0, tx: doesn't care)
|
||||
* 1: IC2/4 snapchot on falling edge: counter value -> CCR2/CCR4
|
||||
* 2: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3
|
||||
* + DMA transfer CCR[1/3] & CCR[2/4] values (t2, t1)
|
||||
*
|
||||
* DMA done, compute:
|
||||
* - Period = t2 - t0
|
||||
* - Duty cycle = t1 - t0
|
||||
*/
|
||||
static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm,
|
||||
unsigned long tmo_ms, u32 *raw_prd,
|
||||
u32 *raw_dty)
|
||||
{
|
||||
struct device *parent = priv->chip.dev->parent;
|
||||
enum stm32_timers_dmas dma_id;
|
||||
u32 ccen, ccr;
|
||||
int ret;
|
||||
|
||||
/* Ensure registers have been updated, enable counter and capture */
|
||||
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
|
||||
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
|
||||
|
||||
/* Use cc1 or cc3 DMA resp for PWM input channels 1 & 2 or 3 & 4 */
|
||||
dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3;
|
||||
ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E;
|
||||
ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3;
|
||||
regmap_update_bits(priv->regmap, TIM_CCER, ccen, ccen);
|
||||
|
||||
/*
|
||||
* Timer DMA burst mode. Request 2 registers, 2 bursts, to get both
|
||||
* CCR1 & CCR2 (or CCR3 & CCR4) on each capture event.
|
||||
* We'll get two capture snapchots: { CCR1, CCR2 }, { CCR1, CCR2 }
|
||||
* or { CCR3, CCR4 }, { CCR3, CCR4 }
|
||||
*/
|
||||
ret = stm32_timers_dma_burst_read(parent, priv->capture, dma_id, ccr, 2,
|
||||
2, tmo_ms);
|
||||
if (ret)
|
||||
goto stop;
|
||||
|
||||
/* Period: t2 - t0 (take care of counter overflow) */
|
||||
if (priv->capture[0] <= priv->capture[2])
|
||||
*raw_prd = priv->capture[2] - priv->capture[0];
|
||||
else
|
||||
*raw_prd = priv->max_arr - priv->capture[0] + priv->capture[2];
|
||||
|
||||
/* Duty cycle capture requires at least two capture units */
|
||||
if (pwm->chip->npwm < 2)
|
||||
*raw_dty = 0;
|
||||
else if (priv->capture[0] <= priv->capture[3])
|
||||
*raw_dty = priv->capture[3] - priv->capture[0];
|
||||
else
|
||||
*raw_dty = priv->max_arr - priv->capture[0] + priv->capture[3];
|
||||
|
||||
if (*raw_dty > *raw_prd) {
|
||||
/*
|
||||
* Race beetween PWM input and DMA: it may happen
|
||||
* falling edge triggers new capture on TI2/4 before DMA
|
||||
* had a chance to read CCR2/4. It means capture[1]
|
||||
* contains period + duty_cycle. So, subtract period.
|
||||
*/
|
||||
*raw_dty -= *raw_prd;
|
||||
}
|
||||
|
||||
stop:
|
||||
regmap_update_bits(priv->regmap, TIM_CCER, ccen, 0);
|
||||
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_capture *result, unsigned long tmo_ms)
|
||||
{
|
||||
struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
|
||||
unsigned long long prd, div, dty;
|
||||
unsigned long rate;
|
||||
unsigned int psc = 0, icpsc, scale;
|
||||
u32 raw_prd = 0, raw_dty = 0;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
if (active_channels(priv)) {
|
||||
ret = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ret = clk_enable(priv->clk);
|
||||
if (ret) {
|
||||
dev_err(priv->chip.dev, "failed to enable counter clock\n");
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
rate = clk_get_rate(priv->clk);
|
||||
if (!rate) {
|
||||
ret = -EINVAL;
|
||||
goto clk_dis;
|
||||
}
|
||||
|
||||
/* prescaler: fit timeout window provided by upper layer */
|
||||
div = (unsigned long long)rate * (unsigned long long)tmo_ms;
|
||||
do_div(div, MSEC_PER_SEC);
|
||||
prd = div;
|
||||
while ((div > priv->max_arr) && (psc < MAX_TIM_PSC)) {
|
||||
psc++;
|
||||
div = prd;
|
||||
do_div(div, psc + 1);
|
||||
}
|
||||
regmap_write(priv->regmap, TIM_ARR, priv->max_arr);
|
||||
regmap_write(priv->regmap, TIM_PSC, psc);
|
||||
|
||||
/* Map TI1 or TI2 PWM input to IC1 & IC2 (or TI3/4 to IC3 & IC4) */
|
||||
regmap_update_bits(priv->regmap,
|
||||
pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2,
|
||||
TIM_CCMR_CC1S | TIM_CCMR_CC2S, pwm->hwpwm & 0x1 ?
|
||||
TIM_CCMR_CC1S_TI2 | TIM_CCMR_CC2S_TI2 :
|
||||
TIM_CCMR_CC1S_TI1 | TIM_CCMR_CC2S_TI1);
|
||||
|
||||
/* Capture period on IC1/3 rising edge, duty cycle on IC2/4 falling. */
|
||||
regmap_update_bits(priv->regmap, TIM_CCER, pwm->hwpwm < 2 ?
|
||||
TIM_CCER_CC12P : TIM_CCER_CC34P, pwm->hwpwm < 2 ?
|
||||
TIM_CCER_CC2P : TIM_CCER_CC4P);
|
||||
|
||||
ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty);
|
||||
if (ret)
|
||||
goto stop;
|
||||
|
||||
/*
|
||||
* Got a capture. Try to improve accuracy at high rates:
|
||||
* - decrease counter clock prescaler, scale up to max rate.
|
||||
* - use input prescaler, capture once every /2 /4 or /8 edges.
|
||||
*/
|
||||
if (raw_prd) {
|
||||
u32 max_arr = priv->max_arr - 0x1000; /* arbitrary margin */
|
||||
|
||||
scale = max_arr / min(max_arr, raw_prd);
|
||||
} else {
|
||||
scale = priv->max_arr; /* bellow resolution, use max scale */
|
||||
}
|
||||
|
||||
if (psc && scale > 1) {
|
||||
/* 2nd measure with new scale */
|
||||
psc /= scale;
|
||||
regmap_write(priv->regmap, TIM_PSC, psc);
|
||||
ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd,
|
||||
&raw_dty);
|
||||
if (ret)
|
||||
goto stop;
|
||||
}
|
||||
|
||||
/* Compute intermediate period not to exceed timeout at low rates */
|
||||
prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC;
|
||||
do_div(prd, rate);
|
||||
|
||||
for (icpsc = 0; icpsc < MAX_TIM_ICPSC ; icpsc++) {
|
||||
/* input prescaler: also keep arbitrary margin */
|
||||
if (raw_prd >= (priv->max_arr - 0x1000) >> (icpsc + 1))
|
||||
break;
|
||||
if (prd >= (tmo_ms * NSEC_PER_MSEC) >> (icpsc + 2))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!icpsc)
|
||||
goto done;
|
||||
|
||||
/* Last chance to improve period accuracy, using input prescaler */
|
||||
regmap_update_bits(priv->regmap,
|
||||
pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2,
|
||||
TIM_CCMR_IC1PSC | TIM_CCMR_IC2PSC,
|
||||
FIELD_PREP(TIM_CCMR_IC1PSC, icpsc) |
|
||||
FIELD_PREP(TIM_CCMR_IC2PSC, icpsc));
|
||||
|
||||
ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty);
|
||||
if (ret)
|
||||
goto stop;
|
||||
|
||||
if (raw_dty >= (raw_prd >> icpsc)) {
|
||||
/*
|
||||
* We may fall here using input prescaler, when input
|
||||
* capture starts on high side (before falling edge).
|
||||
* Example with icpsc to capture on each 4 events:
|
||||
*
|
||||
* start 1st capture 2nd capture
|
||||
* v v v
|
||||
* ___ _____ _____ _____ _____ ____
|
||||
* TI1..4 |__| |__| |__| |__| |__|
|
||||
* v v . . . . . v v
|
||||
* icpsc1/3: . 0 . 1 . 2 . 3 . 0
|
||||
* icpsc2/4: 0 1 2 3 0
|
||||
* v v v v
|
||||
* CCR1/3 ......t0..............................t2
|
||||
* CCR2/4 ..t1..............................t1'...
|
||||
* . . .
|
||||
* Capture0: .<----------------------------->.
|
||||
* Capture1: .<-------------------------->. .
|
||||
* . . .
|
||||
* Period: .<------> . .
|
||||
* Low side: .<>.
|
||||
*
|
||||
* Result:
|
||||
* - Period = Capture0 / icpsc
|
||||
* - Duty = Period - Low side = Period - (Capture0 - Capture1)
|
||||
*/
|
||||
raw_dty = (raw_prd >> icpsc) - (raw_prd - raw_dty);
|
||||
}
|
||||
|
||||
done:
|
||||
prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC;
|
||||
result->period = DIV_ROUND_UP_ULL(prd, rate << icpsc);
|
||||
dty = (unsigned long long)raw_dty * (psc + 1) * NSEC_PER_SEC;
|
||||
result->duty_cycle = DIV_ROUND_UP_ULL(dty, rate);
|
||||
stop:
|
||||
regmap_write(priv->regmap, TIM_CCER, 0);
|
||||
regmap_write(priv->regmap, pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, 0);
|
||||
regmap_write(priv->regmap, TIM_PSC, 0);
|
||||
clk_dis:
|
||||
clk_disable(priv->clk);
|
||||
unlock:
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stm32_pwm_config(struct stm32_pwm *priv, int ch,
|
||||
int duty_ns, int period_ns)
|
||||
{
|
||||
|
@ -230,6 +484,9 @@ static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm,
|
|||
static const struct pwm_ops stm32pwm_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.apply = stm32_pwm_apply_locked,
|
||||
#if IS_ENABLED(CONFIG_DMA_ENGINE)
|
||||
.capture = stm32_pwm_capture,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,
|
||||
|
|
|
@ -322,10 +322,9 @@ static int mtk_rtc_probe(struct platform_device *pdev)
|
|||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
rtc->addr_base = res->start;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
rtc->irq = irq_create_mapping(mt6397_chip->irq_domain, res->start);
|
||||
if (rtc->irq <= 0)
|
||||
return -EINVAL;
|
||||
rtc->irq = platform_get_irq(pdev, 0);
|
||||
if (rtc->irq < 0)
|
||||
return rtc->irq;
|
||||
|
||||
rtc->regmap = mt6397_chip->regmap;
|
||||
rtc->dev = &pdev->dev;
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#define ARIZONA_MAX_PDM_SPK 2
|
||||
|
||||
struct regulator_init_data;
|
||||
struct gpio_desc;
|
||||
|
||||
struct arizona_micbias {
|
||||
int mV; /** Regulated voltage */
|
||||
|
@ -77,7 +78,7 @@ struct arizona_micd_range {
|
|||
};
|
||||
|
||||
struct arizona_pdata {
|
||||
int reset; /** GPIO controlling /RESET, if any */
|
||||
struct gpio_desc *reset; /** GPIO controlling /RESET, if any */
|
||||
|
||||
/** Regulator configuration for MICVDD */
|
||||
struct arizona_micsupp_pdata micvdd;
|
||||
|
|
|
@ -592,11 +592,11 @@ enum axp806_irqs {
|
|||
AXP806_IRQ_DCDCC_V_LOW,
|
||||
AXP806_IRQ_DCDCD_V_LOW,
|
||||
AXP806_IRQ_DCDCE_V_LOW,
|
||||
AXP806_IRQ_PWROK_LONG,
|
||||
AXP806_IRQ_PWROK_SHORT,
|
||||
AXP806_IRQ_POK_LONG,
|
||||
AXP806_IRQ_POK_SHORT,
|
||||
AXP806_IRQ_WAKEUP,
|
||||
AXP806_IRQ_PWROK_FALL,
|
||||
AXP806_IRQ_PWROK_RISE,
|
||||
AXP806_IRQ_POK_FALL,
|
||||
AXP806_IRQ_POK_RISE,
|
||||
};
|
||||
|
||||
enum axp809_irqs {
|
||||
|
@ -642,7 +642,7 @@ struct axp20x_dev {
|
|||
struct regmap_irq_chip_data *regmap_irqc;
|
||||
long variant;
|
||||
int nr_cells;
|
||||
struct mfd_cell *cells;
|
||||
const struct mfd_cell *cells;
|
||||
const struct regmap_config *regmap_cfg;
|
||||
const struct regmap_irq_chip *regmap_irq_chip;
|
||||
};
|
||||
|
|
|
@ -329,23 +329,7 @@ extern struct attribute_group cros_ec_vbc_attr_group;
|
|||
/* debugfs stuff */
|
||||
int cros_ec_debugfs_init(struct cros_ec_dev *ec);
|
||||
void cros_ec_debugfs_remove(struct cros_ec_dev *ec);
|
||||
|
||||
/* ACPI GPE handler */
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
int cros_ec_acpi_install_gpe_handler(struct device *dev);
|
||||
void cros_ec_acpi_remove_gpe_handler(void);
|
||||
void cros_ec_acpi_clear_gpe(void);
|
||||
|
||||
#else /* CONFIG_ACPI */
|
||||
|
||||
static inline int cros_ec_acpi_install_gpe_handler(struct device *dev)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline void cros_ec_acpi_remove_gpe_handler(void) {}
|
||||
static inline void cros_ec_acpi_clear_gpe(void) {}
|
||||
|
||||
#endif /* CONFIG_ACPI */
|
||||
void cros_ec_debugfs_suspend(struct cros_ec_dev *ec);
|
||||
void cros_ec_debugfs_resume(struct cros_ec_dev *ec);
|
||||
|
||||
#endif /* __LINUX_MFD_CROS_EC_H */
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#define _LINUX_STM32_GPTIMER_H_
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define TIM_CR1 0x00 /* Control Register 1 */
|
||||
|
@ -27,6 +29,8 @@
|
|||
#define TIM_CCR3 0x3C /* Capt/Comp Register 3 */
|
||||
#define TIM_CCR4 0x40 /* Capt/Comp Register 4 */
|
||||
#define TIM_BDTR 0x44 /* Break and Dead-Time Reg */
|
||||
#define TIM_DCR 0x48 /* DMA control register */
|
||||
#define TIM_DMAR 0x4C /* DMA register for transfer */
|
||||
|
||||
#define TIM_CR1_CEN BIT(0) /* Counter Enable */
|
||||
#define TIM_CR1_DIR BIT(4) /* Counter Direction */
|
||||
|
@ -36,17 +40,35 @@
|
|||
#define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
|
||||
#define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
|
||||
#define TIM_DIER_UIE BIT(0) /* Update interrupt */
|
||||
#define TIM_DIER_UDE BIT(8) /* Update DMA request Enable */
|
||||
#define TIM_DIER_CC1DE BIT(9) /* CC1 DMA request Enable */
|
||||
#define TIM_DIER_CC2DE BIT(10) /* CC2 DMA request Enable */
|
||||
#define TIM_DIER_CC3DE BIT(11) /* CC3 DMA request Enable */
|
||||
#define TIM_DIER_CC4DE BIT(12) /* CC4 DMA request Enable */
|
||||
#define TIM_DIER_COMDE BIT(13) /* COM DMA request Enable */
|
||||
#define TIM_DIER_TDE BIT(14) /* Trigger DMA request Enable */
|
||||
#define TIM_SR_UIF BIT(0) /* Update interrupt flag */
|
||||
#define TIM_EGR_UG BIT(0) /* Update Generation */
|
||||
#define TIM_CCMR_PE BIT(3) /* Channel Preload Enable */
|
||||
#define TIM_CCMR_M1 (BIT(6) | BIT(5)) /* Channel PWM Mode 1 */
|
||||
#define TIM_CCMR_CC1S (BIT(0) | BIT(1)) /* Capture/compare 1 sel */
|
||||
#define TIM_CCMR_IC1PSC GENMASK(3, 2) /* Input capture 1 prescaler */
|
||||
#define TIM_CCMR_CC2S (BIT(8) | BIT(9)) /* Capture/compare 2 sel */
|
||||
#define TIM_CCMR_IC2PSC GENMASK(11, 10) /* Input capture 2 prescaler */
|
||||
#define TIM_CCMR_CC1S_TI1 BIT(0) /* IC1/IC3 selects TI1/TI3 */
|
||||
#define TIM_CCMR_CC1S_TI2 BIT(1) /* IC1/IC3 selects TI2/TI4 */
|
||||
#define TIM_CCMR_CC2S_TI2 BIT(8) /* IC2/IC4 selects TI2/TI4 */
|
||||
#define TIM_CCMR_CC2S_TI1 BIT(9) /* IC2/IC4 selects TI1/TI3 */
|
||||
#define TIM_CCER_CC1E BIT(0) /* Capt/Comp 1 out Ena */
|
||||
#define TIM_CCER_CC1P BIT(1) /* Capt/Comp 1 Polarity */
|
||||
#define TIM_CCER_CC1NE BIT(2) /* Capt/Comp 1N out Ena */
|
||||
#define TIM_CCER_CC1NP BIT(3) /* Capt/Comp 1N Polarity */
|
||||
#define TIM_CCER_CC2E BIT(4) /* Capt/Comp 2 out Ena */
|
||||
#define TIM_CCER_CC2P BIT(5) /* Capt/Comp 2 Polarity */
|
||||
#define TIM_CCER_CC3E BIT(8) /* Capt/Comp 3 out Ena */
|
||||
#define TIM_CCER_CC3P BIT(9) /* Capt/Comp 3 Polarity */
|
||||
#define TIM_CCER_CC4E BIT(12) /* Capt/Comp 4 out Ena */
|
||||
#define TIM_CCER_CC4P BIT(13) /* Capt/Comp 4 Polarity */
|
||||
#define TIM_CCER_CCXE (BIT(0) | BIT(4) | BIT(8) | BIT(12))
|
||||
#define TIM_BDTR_BKE BIT(12) /* Break input enable */
|
||||
#define TIM_BDTR_BKP BIT(13) /* Break input polarity */
|
||||
|
@ -56,8 +78,11 @@
|
|||
#define TIM_BDTR_BK2F (BIT(20) | BIT(21) | BIT(22) | BIT(23))
|
||||
#define TIM_BDTR_BK2E BIT(24) /* Break 2 input enable */
|
||||
#define TIM_BDTR_BK2P BIT(25) /* Break 2 input polarity */
|
||||
#define TIM_DCR_DBA GENMASK(4, 0) /* DMA base addr */
|
||||
#define TIM_DCR_DBL GENMASK(12, 8) /* DMA burst len */
|
||||
|
||||
#define MAX_TIM_PSC 0xFFFF
|
||||
#define MAX_TIM_ICPSC 0x3
|
||||
#define TIM_CR2_MMS_SHIFT 4
|
||||
#define TIM_CR2_MMS2_SHIFT 20
|
||||
#define TIM_SMCR_TS_SHIFT 4
|
||||
|
@ -65,9 +90,54 @@
|
|||
#define TIM_BDTR_BKF_SHIFT 16
|
||||
#define TIM_BDTR_BK2F_SHIFT 20
|
||||
|
||||
enum stm32_timers_dmas {
|
||||
STM32_TIMERS_DMA_CH1,
|
||||
STM32_TIMERS_DMA_CH2,
|
||||
STM32_TIMERS_DMA_CH3,
|
||||
STM32_TIMERS_DMA_CH4,
|
||||
STM32_TIMERS_DMA_UP,
|
||||
STM32_TIMERS_DMA_TRIG,
|
||||
STM32_TIMERS_DMA_COM,
|
||||
STM32_TIMERS_MAX_DMAS,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct stm32_timers_dma - STM32 timer DMA handling.
|
||||
* @completion: end of DMA transfer completion
|
||||
* @phys_base: control registers physical base address
|
||||
* @lock: protect DMA access
|
||||
* @chan: DMA channel in use
|
||||
* @chans: DMA channels available for this timer instance
|
||||
*/
|
||||
struct stm32_timers_dma {
|
||||
struct completion completion;
|
||||
phys_addr_t phys_base;
|
||||
struct mutex lock;
|
||||
struct dma_chan *chan;
|
||||
struct dma_chan *chans[STM32_TIMERS_MAX_DMAS];
|
||||
};
|
||||
|
||||
struct stm32_timers {
|
||||
struct clk *clk;
|
||||
struct regmap *regmap;
|
||||
u32 max_arr;
|
||||
struct stm32_timers_dma dma; /* Only to be used by the parent */
|
||||
};
|
||||
|
||||
#if IS_REACHABLE(CONFIG_MFD_STM32_TIMERS)
|
||||
int stm32_timers_dma_burst_read(struct device *dev, u32 *buf,
|
||||
enum stm32_timers_dmas id, u32 reg,
|
||||
unsigned int num_reg, unsigned int bursts,
|
||||
unsigned long tmo_ms);
|
||||
#else
|
||||
static inline int stm32_timers_dma_burst_read(struct device *dev, u32 *buf,
|
||||
enum stm32_timers_dmas id,
|
||||
u32 reg,
|
||||
unsigned int num_reg,
|
||||
unsigned int bursts,
|
||||
unsigned long tmo_ms)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2015 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_
|
||||
#define _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_
|
||||
|
||||
/* Exynos4 PMU register definitions */
|
||||
|
||||
/* MIPI_PHYn_CONTROL register offset: n = 0..1 */
|
||||
#define EXYNOS4_MIPI_PHY_CONTROL(n) (0x710 + (n) * 4)
|
||||
#define EXYNOS4_MIPI_PHY_ENABLE (1 << 0)
|
||||
#define EXYNOS4_MIPI_PHY_SRESETN (1 << 1)
|
||||
#define EXYNOS4_MIPI_PHY_MRESETN (1 << 2)
|
||||
#define EXYNOS4_MIPI_PHY_RESET_MASK (3 << 1)
|
||||
|
||||
#endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ */
|
|
@ -1,19 +0,0 @@
|
|||
/*
|
||||
* Exynos5 SoC series Power Management Unit (PMU) register offsets
|
||||
* and bit definitions.
|
||||
*
|
||||
* Copyright (C) 2014 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_
|
||||
#define _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_
|
||||
|
||||
#define EXYNOS5_PHY_ENABLE BIT(0)
|
||||
#define EXYNOS5_MIPI_PHY_S_RESETN BIT(1)
|
||||
#define EXYNOS5_MIPI_PHY_M_RESETN BIT(2)
|
||||
|
||||
#endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ */
|
|
@ -205,10 +205,10 @@ enum tps65218_regulator_id {
|
|||
TPS65218_DCDC_4,
|
||||
TPS65218_DCDC_5,
|
||||
TPS65218_DCDC_6,
|
||||
/* LS's */
|
||||
TPS65218_LS_3,
|
||||
/* LDOs */
|
||||
TPS65218_LDO_1,
|
||||
/* LS's */
|
||||
TPS65218_LS_3,
|
||||
};
|
||||
|
||||
#define TPS65218_MAX_REG_ID TPS65218_LDO_1
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Intel Corporation
|
||||
*
|
||||
* Functions to access TPS68470 power management chip.
|
||||
*
|
||||
* 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 version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (C) 2017 Intel Corporation */
|
||||
/* Functions to access TPS68470 power management chip. */
|
||||
|
||||
#ifndef __LINUX_MFD_TPS68470_H
|
||||
#define __LINUX_MFD_TPS68470_H
|
||||
|
|
Loading…
Reference in New Issue