mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
MFD for v7.4
- New Support & Features
- Cirrus Logic CS42L43: Add support for the CS42L44 variant
- Khadas MCU: Add support for the VIM4 MCU variant along with per-variant fan duty-cycle
levels and optional fan supply regulator support
- Maxim MAX77705: Add support for the PASS2 hardware revision
- MediaTek MT6397: Add AUXADC sub-device support for MT6397
- Motorola CPCAP: Support per-board sub-device compositions and add the Tegra20 Mot
composition
- ROHM BD73800: Add support for the BD73800 PMIC core, regulator, RTC, clock gate, and
GPIO sub-devices
- TI LM3533: Add VIN regulator supply support, configure initial backlight mapping mode
from Device Tree, and implement the `backlight_scale` property
- X-Powers AC200: Add support for the AC200 I2C mixed-signal companion IC
- Improvements & Fixes
- Cirrus Logic CS42L43: Synchronize SoundWire enumeration work in `remove()` before
devres cleanup begins
- Dialog DA903x: Manage IRQ work cancellation and sub-device removal via devres to
prevent use-after-free during teardown
- Dialog DA9150: Balance `enable_irq_wake()` with `disable_irq_wake()` during probe
failure and driver removal
- Intel LPSS: Add DMI quirks for Dell Latitude 5285 and 7275 to ignore ACPI resource
conflicts on the I2C4 controller
- Intel Quark I2C/GPIO: Manage the fixed-rate clock and its clkdev lookup with devres to
fix a resource leak on unbind
- Maxim MAX77705: Select `REGMAP_I2C` and `REGMAP_IRQ` in Kconfig to fix build errors
- Qualcomm WCD934x: Initialize the parent DMA mask to suppress "DMA mask not set"
warnings on child devices
- Qualcomm WCD934x: Pass the valid device pointer to `dev_err_probe()` on IRQ lookup
failure to avoid a NULL pointer dereference
- Rockchip RK8xx: Register the poweroff handler in the atomic `SYS_OFF_MODE_POWER_OFF`
phase so polling I2C transfers complete during shutdown
- ST-Ericsson AB8500: Use `devm_mfd_add_devices()` to prevent leaking child devices on
probe failure
- TI BQ257xx: Mark self-modifying BQ25792 configuration registers as volatile
- TI LM3533: Set `coherent_dma_mask` to zero to suppress "DMA mask not set" warnings
- TI TPS65217: Check for errors during IRQ initialization and masking, and manage IRQ
domain and wake teardown with devres
- TI TWL: Unregister the auxiliary platform device via a devres action on probe failure
and driver unbind
- Cleanups & Refactoring
- Core: Convert drivers from deprecated `SIMPLE_DEV_PM_OPS()` to
`DEFINE_SIMPLE_DEV_PM_OPS()` and `pm_sleep_ptr()`
- Core: Fix spelling mistakes in comments across various MFD drivers and headers
- Maintainers: Add ROHM BD73800 PMIC files under the ROHM PMIC entry
- Maintainers: Specify the `for-mfd-next` branch for the MFD and Syscon git trees
- Dialog DA9062: Use `DEFINE_RES_IRQ_NAMED()` for IRQ resource definitions
- Intel LPSS: Simplify DebugFS handling by dropping redundant error checks and
intermediate dentry variables, using octal permissions, and switching to
`debugfs_remove()`
- Khadas MCU: Convert MFD cell arrays to `const` and use `MFD_CELL_NAME()`
- ST-Ericsson AB8500: Fix a spelling typo in a comment
- TI LM3533: Convert from platform data to Device Tree bindings and pass only regmap and
light sensor presence to child devices
- TI LM3533: Remove driver-specific regmap wrappers, redundant pdata helpers, and
unnecessary `extern` qualifiers, and use `dev_groups` for sysfs attributes
- Wolfson WM831x: Fix a spelling typo in a comment
- Device Tree Binding Updates
- HiSilicon Hi6421 SPMI: Fix the compatible string to match `hisilicon,hi6421-spmi`
- MediaTek MT6357: Allow an `adc` child node
- MediaTek MT6360: Allow two-cell interrupt specifiers with trigger flags
- MediaTek MT6397: Document the `#sound-dai-cells` property
- MediaTek MT6397: Document the battery-backed NVMEM layout under the RTC child node
- MediaTek MT6397: Document the MT6323 PMIC EFUSE child node
- Motorola CPCAP: Convert MFD and power button bindings to DT schema and document the
Mapphone and Mot compositions
- Qualcomm SPMI PMIC: Document the PM4125 audio codec compatible
- Qualcomm SPMI PMIC: Document the PMAU0102 PMIC compatible
- Qualcomm TCSR: Document the MSM8952 TCSR compatible
- Rockchip RK805: Fold the pin controller binding into the RK805 PMIC DT schema
- ROHM BD73800: Document the BD73800 PMIC and its regulators
- ROHM PMIC: Factor out common pin properties into `rohm,pmic-pins.yaml` and reference
them across BD71815, BD71828, and BD72720 bindings
- ST-Ericsson AB8500: Document AB8500 and AB8505 buck converter regulators
- ST-Ericsson AB8500: Document codec audio graph ports, sound DAI cells, and analog
microphone wiring properties
- ST-Ericsson DB8500 PRCMU: Deprecate the `db8500-prcmu-regulators` child node and make
it optional
- Syscon: Document the Ambarella CV75 secure scratchpad compatible
- TI BQ25703A: Add the BQ25798 compatible with fallback to BQ25792
- TI Keystone: Convert Device State Control bindings to DT schema
- TI LM3533: Document the LM3533 LED controller, backlight, and indicator LED bindings
- TI LP3943: Convert MFD and PWM bindings to DT schema
- TI TPS61050: Convert bindings to DT schema
- TI TPS65086: Make the `regulators` child node optional
- TI TPS65910: Document `wakeup-source` and GPIO hog child nodes
- TI TWL6040: Convert bindings to DT schema and align property names with the driver
- X-Powers AC200: Document the AC200 mixed-signal companion IC
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmrfbfQACgkQUa+KL4f8
d2FqyxAAsju3PmhlmAdSaHEYXu3PQwzV4j9ZJ4jynWeMyVcKGPePiWfaaSqpyQ36
gn95B6ZoFlVl9aRAKu0kaLCSx2oGTtD9BoQ6jjfvVW6yU4LzmhvdCw+Zr7Img61H
rv+kYmZiqzwt1LGaGBbbDNtP1q+B+QFKvgdDGvaiRKGEvOtuKuASLnD4t8jtWuLT
5VIMFcCFqySeYUwLMnLQk8C2Fqysx1dPvOe0doe90vPF5tpKI8ZNIrbk0OruQzlN
tfQahrfUnmkZGdjO+lalbkwSvlSrs+6KTckr53fyrIYHILPJcbfnFPimLhDzBVG4
Ko/WnjGWwt2XkfIkGJJALUZptyz5YpfKfwxl+Xi3NAyWkpVcKfI0nASLd6T8QO4h
mJQsg2SQer3/HCY2z8Hs8IW1XBhzLPtZN+e5qPOIPBNW3D11y92KodvjMxfSRmdz
lCeIJohs5md75f3aFUqFSi0iDv4tgTZ2BCUSz9BzqYgkA7cQYlmQrYEqFrhHQFjo
sYAAFBlg4SLJ5J5N1cEp8DFrjompbqDCenm2csntvJhWQ6hmxHbm5zEKMKeXUYLw
le+E+jpvg7EXoEsoy+3dVY89gdMpnVN68A7wRCH8EVIrIzq1pRpFpX2V9kd85sro
SV1LOuEnnnyjEdJ3wSQGEKkPXdy/YZguMBDqoFKw3ODV0cez/cE=
=Is2H
-----END PGP SIGNATURE-----
Merge tag 'mfd-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones:
"New Support & Features:
- Cirrus Logic CS42L43: Add support for the CS42L44 variant
- Khadas MCU: Add support for the VIM4 MCU variant along with
per-variant fan duty-cycle levels and optional fan supply regulator
support
- Maxim MAX77705: Add support for the PASS2 hardware revision
- MediaTek MT6397: Add AUXADC sub-device support for MT6397
- Motorola CPCAP: Support per-board sub-device compositions and add
the Tegra20 Mot composition
- ROHM BD73800: Add support for the BD73800 PMIC core, regulator,
RTC, clock gate, and GPIO sub-devices
- TI LM3533: Add VIN regulator supply support, configure initial
backlight mapping mode from Device Tree, and implement the
`backlight_scale` property
- X-Powers AC200: Add support for the AC200 I2C mixed-signal companion IC
Improvements & Fixes:
- Cirrus Logic CS42L43: Synchronize SoundWire enumeration work in
`remove()` before devres cleanup begins
- Dialog DA903x: Manage IRQ work cancellation and sub-device removal
via devres to prevent use-after-free during teardown
- Dialog DA9150: Balance `enable_irq_wake()` with
`disable_irq_wake()` during probe failure and driver removal
- Intel LPSS: Add DMI quirks for Dell Latitude 5285 and 7275 to
ignore ACPI resource conflicts on the I2C4 controller
- Intel Quark I2C/GPIO: Manage the fixed-rate clock and its clkdev
lookup with devres to fix a resource leak on unbind
- Maxim MAX77705: Select `REGMAP_I2C` and `REGMAP_IRQ` in Kconfig to
fix build errors
- Qualcomm WCD934x: Initialize the parent DMA mask to suppress "DMA
mask not set" warnings on child devices
- Qualcomm WCD934x: Pass the valid device pointer to
`dev_err_probe()` on IRQ lookup failure to avoid a NULL pointer
dereference
- Rockchip RK8xx: Register the poweroff handler in the atomic
`SYS_OFF_MODE_POWER_OFF` phase so polling I2C transfers complete
during shutdown
- ST-Ericsson AB8500: Use `devm_mfd_add_devices()` to prevent leaking
child devices on probe failure
- TI BQ257xx: Mark self-modifying BQ25792 configuration registers as
volatile
- TI LM3533: Set `coherent_dma_mask` to zero to suppress "DMA mask
not set" warnings
- TI TPS65217: Check for errors during IRQ initialization and
masking, and manage IRQ domain and wake teardown with devres
- TI TWL: Unregister the auxiliary platform device via a devres
action on probe failure and driver unbind
Cleanups & Refactoring
- Core: Convert drivers from deprecated `SIMPLE_DEV_PM_OPS()` to
`DEFINE_SIMPLE_DEV_PM_OPS()` and `pm_sleep_ptr()`
- Core: Fix spelling mistakes in comments across various MFD drivers
and headers
- Maintainers: Add ROHM BD73800 PMIC files under the ROHM PMIC entry
- Maintainers: Specify the `for-mfd-next` branch for the MFD and
Syscon git trees
- Dialog DA9062: Use `DEFINE_RES_IRQ_NAMED()` for IRQ resource
definitions
- Intel LPSS: Simplify DebugFS handling by dropping redundant error
checks and intermediate dentry variables, using octal permissions,
and switching to
`debugfs_remove()`
- Khadas MCU: Convert MFD cell arrays to `const` and use
`MFD_CELL_NAME()`
- ST-Ericsson AB8500: Fix a spelling typo in a comment
- TI LM3533: Convert from platform data to Device Tree bindings and
pass only regmap and light sensor presence to child devices
- TI LM3533: Remove driver-specific regmap wrappers, redundant pdata
helpers, and unnecessary `extern` qualifiers, and use `dev_groups`
for sysfs attributes
- Wolfson WM831x: Fix a spelling typo in a comment
Device Tree Binding Updates
- HiSilicon Hi6421 SPMI: Fix the compatible string to match
`hisilicon,hi6421-spmi`
- MediaTek MT6357: Allow an `adc` child node
- MediaTek MT6360: Allow two-cell interrupt specifiers with trigger
flags
- MediaTek MT6397: Document the `#sound-dai-cells` property
- MediaTek MT6397: Document the battery-backed NVMEM layout under the
RTC child node
- MediaTek MT6397: Document the MT6323 PMIC EFUSE child node
- Motorola CPCAP: Convert MFD and power button bindings to DT schema
and document the Mapphone and Mot compositions
- Qualcomm SPMI PMIC: Document the PM4125 audio codec compatible
- Qualcomm SPMI PMIC: Document the PMAU0102 PMIC compatible
- Qualcomm TCSR: Document the MSM8952 TCSR compatible
- Rockchip RK805: Fold the pin controller binding into the RK805 PMIC
DT schema
- ROHM BD73800: Document the BD73800 PMIC and its regulators
- ROHM PMIC: Factor out common pin properties into
`rohm,pmic-pins.yaml` and reference them across BD71815, BD71828,
and BD72720 bindings
- ST-Ericsson AB8500: Document AB8500 and AB8505 buck converter
regulators
- ST-Ericsson AB8500: Document codec audio graph ports, sound DAI
cells, and analog microphone wiring properties
- ST-Ericsson DB8500 PRCMU: Deprecate the `db8500-prcmu-regulators`
child node and make it optional
- Syscon: Document the Ambarella CV75 secure scratchpad compatible
- TI BQ25703A: Add the BQ25798 compatible with fallback to BQ25792
- TI Keystone: Convert Device State Control bindings to DT schema
- TI LM3533: Document the LM3533 LED controller, backlight, and
indicator LED bindings
- TI LP3943: Convert MFD and PWM bindings to DT schema
- TI TPS61050: Convert bindings to DT schema
- TI TPS65086: Make the `regulators` child node optional
- TI TPS65910: Document `wakeup-source` and GPIO hog child nodes
- TI TWL6040: Convert bindings to DT schema and align property names
with the driver
- X-Powers AC200: Document the AC200 mixed-signal companion IC"
* tag 'mfd-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (74 commits)
dt-bindings: mfd: db8500-prcmu: Deprecate EPOD regulators
dt-bindings: mfd: syscon: Add Ambarella CV75 secure scratchpad
dt-bindings: mfd: rockchip,rk805: Convert pinctrl to DT schema
mfd: intel-lpss: Add Dell Latitude 7275 to the resource conflict quirk
mfd: intel-lpss: Add resource conflict quirk for Dell Latitude 5285
mfd: tps65217: Use devres for IRQ domain and wake teardown
mfd: tps65217: Check return value when masking interrupt sources
mfd: tps65217: Fix NULL pointer dereference on IRQ init failure
dt-bindings: mfd: qcom,spmi-pmic: Add compatibles for pm4125-codec
mfd: bq257xx: Mark self-modifying BQ25792 registers volatile
dt-bindings: mfd: mediatek: mt6397: describe the RTC's nvmem layout
mfd: mt6397-core: Add mt6397 AUXADC support
mfd: max77705: Mark PASS2 revision as supported
mfd: ab8500: Fix child device leaks on probe failure
dt-bindings: mfd: Add MT6397 sound DAI cells
dt-bindings: mfd: mediatek: mt6397: Add mt6323 PMIC EFUSE
dt-bindings: mfd: hisilicon: Fix Hi6421 SPMI compatible
dt-bindings: mfd: ti,bq25703a: Expand to include BQ25798
dt-bindings: mfd: Allow MT6360 interrupt flags
dt-bindings: mfd: mediatek: Allow MT6357 ADC
...
This commit is contained in:
commit
d857e1f3fa
|
|
@ -1,20 +0,0 @@
|
|||
Motorola CPCAP on key
|
||||
|
||||
This module is part of the CPCAP. For more details about the whole
|
||||
chip see Documentation/devicetree/bindings/mfd/motorola-cpcap.txt.
|
||||
|
||||
This module provides a simple power button event via an Interrupt.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be one of the following
|
||||
- "motorola,cpcap-pwrbutton"
|
||||
- interrupts: irq specifier for CPCAP's ON IRQ
|
||||
|
||||
Example:
|
||||
|
||||
&cpcap {
|
||||
cpcap_pwrbutton: pwrbutton {
|
||||
compatible = "motorola,cpcap-pwrbutton";
|
||||
interrupts = <23 IRQ_TYPE_NONE>;
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/input/motorola,cpcap-pwrbutton.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Motorola CPCAP PMIC power key
|
||||
|
||||
maintainers:
|
||||
- Svyatoslav Ryhel <clamor95@gmail.com>
|
||||
|
||||
description:
|
||||
This module is part of the Motorola CPCAP MFD device. For more details
|
||||
see Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml. The
|
||||
power key is represented as a sub-node of the PMIC node on the device
|
||||
tree.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: motorola,cpcap-pwrbutton
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: CPCAP's ON interrupt
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- interrupts
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
...
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/backlight/ti,lm3533-backlight.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI LM3533 high voltage series LED strings
|
||||
|
||||
description:
|
||||
This is part of the TI LM3533 MFD device. It represents two high voltage series
|
||||
LED strings for display backlight controlled by the TI LM3533.
|
||||
|
||||
maintainers:
|
||||
- Svyatoslav Ryhel <clamor95@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/leds/backlight/common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,lm3533-backlight
|
||||
|
||||
reg:
|
||||
description: Control bank selection (0 = bank A, 1 = bank B).
|
||||
maximum: 1
|
||||
|
||||
led-max-microamp:
|
||||
description: maximum current in uA with a 800 uA step.
|
||||
minimum: 5000
|
||||
maximum: 29800
|
||||
default: 5000
|
||||
|
||||
led-sources:
|
||||
description: |
|
||||
HVLED strings associated with this control bank:
|
||||
0 - HVLED1
|
||||
1 - HVLED2
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
maximum: 1
|
||||
|
||||
ti,pwm-config-mask:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Control Bank PWM Configuration Register mask that allows to configure
|
||||
PWM input in Zones 0-4
|
||||
BIT(0) - PWM Input is enabled
|
||||
BIT(1) - PWM Input is enabled in Zone 0
|
||||
BIT(2) - PWM Input is enabled in Zone 1
|
||||
BIT(3) - PWM Input is enabled in Zone 2
|
||||
BIT(4) - PWM Input is enabled in Zone 3
|
||||
BIT(5) - PWM Input is enabled in Zone 4
|
||||
default: 0
|
||||
|
||||
ti,linear-mapping-mode:
|
||||
description:
|
||||
Enable linear mapping mode. If disabled, then it will use exponential
|
||||
mapping mode in which the ramp up/down appears to have a more uniform
|
||||
transition to the human eye.
|
||||
type: boolean
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
# see ti,lm3533.yaml for an example
|
||||
67
Documentation/devicetree/bindings/leds/ti,lm3533-leds.yaml
Normal file
67
Documentation/devicetree/bindings/leds/ti,lm3533-leds.yaml
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/ti,lm3533-leds.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI LM3533 low voltage control banks for individual LEDs
|
||||
|
||||
description:
|
||||
This is part of the TI LM3533 MFD device. It represents four low voltage
|
||||
control banks for individual LEDs provided by the TI LM3533.
|
||||
|
||||
maintainers:
|
||||
- Svyatoslav Ryhel <clamor95@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/leds/common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,lm3533-leds
|
||||
|
||||
reg:
|
||||
description:
|
||||
Control bank selection (2 = bank C, 3 = bank D, 4 = bank E, 5 = bank F).
|
||||
minimum: 2
|
||||
maximum: 5
|
||||
|
||||
led-max-microamp:
|
||||
description: maximum current in uA with a 800 uA step.
|
||||
minimum: 5000
|
||||
maximum: 29800
|
||||
default: 5000
|
||||
|
||||
led-sources:
|
||||
description: |
|
||||
LVLED associated with this control bank. May be more than 1 source per bank.
|
||||
0 - LVLED1
|
||||
1 - LVLED2
|
||||
2 - LVLED3
|
||||
3 - LVLED4
|
||||
4 - LVLED5
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
items:
|
||||
maximum: 4
|
||||
|
||||
ti,pwm-config-mask:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: |
|
||||
Control Bank PWM Configuration Register mask that allows to configure
|
||||
PWM input in Zones 0-4
|
||||
BIT(0) - PWM Input is enabled
|
||||
BIT(1) - PWM Input is enabled in Zone 0
|
||||
BIT(2) - PWM Input is enabled in Zone 1
|
||||
BIT(3) - PWM Input is enabled in Zone 2
|
||||
BIT(4) - PWM Input is enabled in Zone 3
|
||||
BIT(5) - PWM Input is enabled in Zone 4
|
||||
default: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
# see ti,lm3533.yaml for an example
|
||||
169
Documentation/devicetree/bindings/leds/ti,lm3533.yaml
Normal file
169
Documentation/devicetree/bindings/leds/ti,lm3533.yaml
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/leds/ti,lm3533.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI LM3533 Complete Lighting Power Solution
|
||||
|
||||
description: >
|
||||
The LM3533 is a complete power source for backlight, keypad, and indicator LEDs
|
||||
in smartphone handsets. The high-voltage inductive boost converter provides the
|
||||
power for two high voltage series LED strings for display backlight and four low
|
||||
voltage control banks for individual LEDs. Additionally, LM3533 features an
|
||||
interface for an external light sensor.
|
||||
|
||||
https://www.ti.com/product/LM3533
|
||||
|
||||
maintainers:
|
||||
- Svyatoslav Ryhel <clamor95@gmail.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,lm3533
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
enable-gpios:
|
||||
description: GPIO connected to the HWEN pin.
|
||||
maxItems: 1
|
||||
|
||||
vin-supply:
|
||||
description: Supply connected to the IN line (2.7 V to 5.5 V).
|
||||
|
||||
'#address-cells':
|
||||
const: 1
|
||||
|
||||
'#size-cells':
|
||||
const: 0
|
||||
|
||||
ti,boost-ovp-microvolt:
|
||||
description: boost OVP select (16V, 24V, 32V, 40V)
|
||||
enum: [ 16000000, 24000000, 32000000, 40000000 ]
|
||||
default: 16000000
|
||||
|
||||
ti,boost-freq-hz:
|
||||
description: boost frequency select (500KHz or 1MHz)
|
||||
enum: [ 500000, 1000000 ]
|
||||
default: 500000
|
||||
|
||||
light-sensor:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,lm3533-als
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
ti,resistor-ohms:
|
||||
description:
|
||||
Internal configuration resistor value when light sensor is in
|
||||
Analog Sensor mode and PWM mode is disabled. The expectation is
|
||||
the input is a current from the external analog light sensor and
|
||||
this is used to convert it to a voltage within the target range.
|
||||
minimum: 1575
|
||||
maximum: 200000
|
||||
|
||||
ti,pwm-mode:
|
||||
type: boolean
|
||||
description:
|
||||
Switch for mode in which light sensor interface is running. If
|
||||
this property is set then the light sensor interface is running
|
||||
in PWM mode, internal resistor value is set to high-impedance (0)
|
||||
and ti,resistor-ohms property is ignored.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
oneOf:
|
||||
- required:
|
||||
- ti,resistor-ohms
|
||||
- required:
|
||||
- ti,pwm-mode
|
||||
|
||||
patternProperties:
|
||||
"^backlight@[01]$":
|
||||
$ref: /schemas/leds/backlight/ti,lm3533-backlight.yaml#
|
||||
|
||||
"^led@[2-5]$":
|
||||
$ref: /schemas/leds/ti,lm3533-leds.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#address-cells'
|
||||
- '#size-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
led-controller@36 {
|
||||
compatible = "ti,lm3533";
|
||||
reg = <0x36>;
|
||||
|
||||
enable-gpios = <&gpio 110 GPIO_ACTIVE_HIGH>;
|
||||
vin-supply = <&vdd_3v3_bat>;
|
||||
|
||||
ti,boost-ovp-microvolt = <24000000>;
|
||||
ti,boost-freq-hz = <500000>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
backlight@0 {
|
||||
compatible = "ti,lm3533-backlight";
|
||||
reg = <0>;
|
||||
|
||||
default-brightness = <113>;
|
||||
|
||||
led-max-microamp = <23400>;
|
||||
led-sources = <0 1>;
|
||||
};
|
||||
|
||||
led@2 {
|
||||
compatible = "ti,lm3533-leds";
|
||||
reg = <2>;
|
||||
|
||||
led-max-microamp = <23400>;
|
||||
led-sources = <0 1>;
|
||||
};
|
||||
|
||||
led@4 {
|
||||
compatible = "ti,lm3533-leds";
|
||||
reg = <4>;
|
||||
|
||||
led-max-microamp = <23400>;
|
||||
led-sources = <2>;
|
||||
};
|
||||
|
||||
led@5 {
|
||||
compatible = "ti,lm3533-leds";
|
||||
reg = <5>;
|
||||
|
||||
led-max-microamp = <23400>;
|
||||
led-sources = <3 4>;
|
||||
};
|
||||
|
||||
light-sensor {
|
||||
compatible = "ti,lm3533-als";
|
||||
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <80 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
ti,pwm-mode;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -24,7 +24,7 @@ properties:
|
|||
pattern: "pmic@[0-9a-f]"
|
||||
|
||||
compatible:
|
||||
const: hisilicon,hi6421v600-spmi
|
||||
const: hisilicon,hi6421-spmi
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
@ -66,7 +66,7 @@ examples:
|
|||
#size-cells = <0>;
|
||||
|
||||
pmic@0 {
|
||||
compatible = "hisilicon,hi6421v600-spmi";
|
||||
compatible = "hisilicon,hi6421-spmi";
|
||||
reg = <0 SPMI_USID>;
|
||||
|
||||
#interrupt-cells = <2>;
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
TI/National Semiconductor LP3943 MFD driver
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,lp3943"
|
||||
- reg: I2C slave address. From 0x60 to 0x67.
|
||||
|
||||
LP3943 consists of two sub-devices, lp3943-gpio and lp3943-pwm.
|
||||
|
||||
For the LP3943 GPIO properties please refer to:
|
||||
Documentation/devicetree/bindings/gpio/trivial-gpio.yaml
|
||||
|
||||
For the LP3943 PWM properties please refer to:
|
||||
Documentation/devicetree/bindings/pwm/pwm-lp3943.txt
|
||||
|
||||
Example:
|
||||
|
||||
lp3943@60 {
|
||||
compatible = "ti,lp3943";
|
||||
reg = <0x60>;
|
||||
|
||||
gpioex: gpio {
|
||||
compatible = "ti,lp3943-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
pwm3943: pwm {
|
||||
compatible = "ti,lp3943-pwm";
|
||||
#pwm-cells = <2>;
|
||||
ti,pwm0 = <8 9 10>;
|
||||
ti,pwm1 = <15>;
|
||||
};
|
||||
};
|
||||
|
|
@ -62,6 +62,13 @@ properties:
|
|||
description:
|
||||
List of MT6357 BUCKs and LDOs regulators.
|
||||
|
||||
adc:
|
||||
type: object
|
||||
$ref: /schemas/iio/adc/mediatek,mt6359-auxadc.yaml#
|
||||
unevaluatedProperties: false
|
||||
description:
|
||||
MT6357 auxiliary ADC.
|
||||
|
||||
rtc:
|
||||
type: object
|
||||
$ref: /schemas/rtc/rtc.yaml#
|
||||
|
|
|
|||
|
|
@ -33,9 +33,10 @@ properties:
|
|||
interrupt-controller: true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 1
|
||||
enum: [1, 2]
|
||||
description:
|
||||
The first cell is the IRQ number.
|
||||
The first cell is the IRQ number. The optional second cell is the IRQ
|
||||
trigger type.
|
||||
|
||||
regulators:
|
||||
$ref: /schemas/regulator/mt6360-regulator.yaml#
|
||||
|
|
|
|||
|
|
@ -57,6 +57,9 @@ properties:
|
|||
"#interrupt-cells":
|
||||
const: 2
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 1
|
||||
|
||||
rtc:
|
||||
type: object
|
||||
$ref: /schemas/rtc/rtc.yaml#
|
||||
|
|
@ -81,6 +84,15 @@ properties:
|
|||
|
||||
start-year: true
|
||||
|
||||
nvmem-layout:
|
||||
$ref: /schemas/nvmem/layouts/nvmem-layout.yaml
|
||||
description:
|
||||
The RTC carries four bytes of storage that neither the clock nor the
|
||||
alarm uses, in the high half of four of the alarm registers, and
|
||||
offers them as a battery-backed nvmem provider. MediaTek's
|
||||
documentation names them RTC_NEW_SPARE0 to RTC_NEW_SPARE3 and gives
|
||||
the first to a fuel gauge.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
|
|
|
|||
408
Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
Normal file
408
Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/motorola,cpcap.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Motorola CPCAP PMIC MFD
|
||||
|
||||
maintainers:
|
||||
- Svyatoslav Ryhel <clamor95@gmail.com>
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/spi/spi-peripheral-props.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- motorola,mapphone-cpcap
|
||||
- motorola,mot-cpcap
|
||||
|
||||
- items:
|
||||
- const: motorola,cpcap
|
||||
- const: st,6556002
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
interrupt-controller: true
|
||||
|
||||
"#interrupt-cells":
|
||||
const: 2
|
||||
|
||||
spi-max-frequency:
|
||||
maximum: 9600000
|
||||
|
||||
spi-cs-high: true
|
||||
spi-cpol: true
|
||||
spi-cpha: true
|
||||
|
||||
adc:
|
||||
$ref: /schemas/iio/adc/motorola,cpcap-adc.yaml#
|
||||
|
||||
audio-codec:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
interrupts:
|
||||
items:
|
||||
- description: headset detect interrupt
|
||||
- description: microphone bias 2 detect interrupt
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: hs
|
||||
- const: mb2
|
||||
|
||||
"#sound-dai-cells":
|
||||
const: 1
|
||||
|
||||
VAUDIO-supply:
|
||||
description:
|
||||
Codec power supply, usually VAUDIO regulator of CPCAP.
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: port connected to the Stereo HiFi DAC
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: port connected to the Voice DAC
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- "#sound-dai-cells"
|
||||
|
||||
battery:
|
||||
$ref: /schemas/power/supply/cpcap-battery.yaml#
|
||||
|
||||
charger:
|
||||
$ref: /schemas/power/supply/cpcap-charger.yaml#
|
||||
|
||||
key-power:
|
||||
$ref: /schemas/input/motorola,cpcap-pwrbutton.yaml#
|
||||
|
||||
phy:
|
||||
$ref: /schemas/phy/motorola,cpcap-usb-phy.yaml#
|
||||
|
||||
regulator:
|
||||
$ref: /schemas/regulator/motorola,cpcap-regulator.yaml#
|
||||
|
||||
rtc:
|
||||
$ref: /schemas/rtc/motorola,cpcap-rtc.yaml#
|
||||
|
||||
patternProperties:
|
||||
"^led(-[a-z]+)?$":
|
||||
$ref: /schemas/leds/motorola,cpcap-leds.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-controller
|
||||
- "#interrupt-cells"
|
||||
- spi-max-frequency
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/input/linux-event-codes.h>
|
||||
|
||||
spi {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpcap: pmic@0 {
|
||||
compatible = "motorola,cpcap", "st,6556002";
|
||||
reg = <0>; /* cs0 */
|
||||
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
|
||||
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
spi-max-frequency = <3000000>;
|
||||
spi-cs-high;
|
||||
|
||||
spi-cpol;
|
||||
spi-cpha;
|
||||
|
||||
cpcap_adc: adc {
|
||||
compatible = "motorola,cpcap-adc";
|
||||
|
||||
interrupt-parent = <&cpcap>;
|
||||
interrupts = <8 IRQ_TYPE_NONE>;
|
||||
interrupt-names = "adcdone";
|
||||
|
||||
#io-channel-cells = <1>;
|
||||
};
|
||||
|
||||
cpcap_audio: audio-codec {
|
||||
interrupt-parent = <&cpcap>;
|
||||
interrupts = <9 IRQ_TYPE_NONE>, <10 IRQ_TYPE_NONE>;
|
||||
interrupt-names = "hs", "mb2";
|
||||
|
||||
VAUDIO-supply = <&vdd_audio>;
|
||||
|
||||
#sound-dai-cells = <1>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* HiFi */
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
cpcap_audio_codec0: endpoint {
|
||||
};
|
||||
};
|
||||
|
||||
/* Voice */
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
cpcap_audio_codec1: endpoint {
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cpcap_battery: battery {
|
||||
compatible = "motorola,cpcap-battery";
|
||||
|
||||
interrupt-parent = <&cpcap>;
|
||||
interrupts = <6 IRQ_TYPE_NONE>, <5 IRQ_TYPE_NONE>,
|
||||
<3 IRQ_TYPE_NONE>, <20 IRQ_TYPE_NONE>,
|
||||
<54 IRQ_TYPE_NONE>, <57 IRQ_TYPE_NONE>;
|
||||
interrupt-names = "eol", "lowbph", "lowbpl",
|
||||
"chrgcurr1", "battdetb", "cccal";
|
||||
|
||||
io-channels = <&cpcap_adc 0>, <&cpcap_adc 1>,
|
||||
<&cpcap_adc 5>, <&cpcap_adc 6>;
|
||||
io-channel-names = "battdetb", "battp",
|
||||
"chg_isense", "batti";
|
||||
power-supplies = <&cpcap_charger>;
|
||||
};
|
||||
|
||||
cpcap_charger: charger {
|
||||
compatible = "motorola,mapphone-cpcap-charger";
|
||||
|
||||
interrupt-parent = <&cpcap>;
|
||||
interrupts = <13 IRQ_TYPE_NONE>, <12 IRQ_TYPE_NONE>,
|
||||
<29 IRQ_TYPE_NONE>, <28 IRQ_TYPE_NONE>,
|
||||
<22 IRQ_TYPE_NONE>, <21 IRQ_TYPE_NONE>,
|
||||
<20 IRQ_TYPE_NONE>, <19 IRQ_TYPE_NONE>,
|
||||
<54 IRQ_TYPE_NONE>;
|
||||
interrupt-names = "chrg_det", "rvrs_chrg", "chrg_se1b",
|
||||
"se0conn", "rvrs_mode", "chrgcurr2",
|
||||
"chrgcurr1", "vbusvld", "battdetb";
|
||||
|
||||
mode-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>,
|
||||
<&gpio3 23 GPIO_ACTIVE_LOW>;
|
||||
|
||||
io-channels = <&cpcap_adc 0>, <&cpcap_adc 1>,
|
||||
<&cpcap_adc 2>, <&cpcap_adc 5>,
|
||||
<&cpcap_adc 6>;
|
||||
io-channel-names = "battdetb", "battp",
|
||||
"vbus", "chg_isense",
|
||||
"batti";
|
||||
};
|
||||
|
||||
key-power {
|
||||
compatible = "motorola,cpcap-pwrbutton";
|
||||
|
||||
interrupt-parent = <&cpcap>;
|
||||
interrupts = <23 IRQ_TYPE_NONE>;
|
||||
};
|
||||
|
||||
led-red {
|
||||
compatible = "motorola,cpcap-led-red";
|
||||
vdd-supply = <&vdd_led>;
|
||||
label = "status-led::red";
|
||||
};
|
||||
|
||||
led-green {
|
||||
compatible = "motorola,cpcap-led-green";
|
||||
vdd-supply = <&vdd_led>;
|
||||
label = "status-led::green";
|
||||
};
|
||||
|
||||
led-blue {
|
||||
compatible = "motorola,cpcap-led-blue";
|
||||
vdd-supply = <&vdd_led>;
|
||||
label = "status-led::blue";
|
||||
};
|
||||
|
||||
cpcap_usb2_phy: phy {
|
||||
compatible = "motorola,cpcap-usb-phy";
|
||||
|
||||
pinctrl-0 = <&usb_gpio_mux_sel1>, <&usb_gpio_mux_sel2>;
|
||||
pinctrl-1 = <&usb_ulpi_pins>;
|
||||
pinctrl-2 = <&usb_utmi_pins>;
|
||||
pinctrl-3 = <&uart3_pins>;
|
||||
pinctrl-names = "default", "ulpi", "utmi", "uart";
|
||||
#phy-cells = <0>;
|
||||
|
||||
interrupts-extended =
|
||||
<&cpcap 15 IRQ_TYPE_NONE>, <&cpcap 14 IRQ_TYPE_NONE>,
|
||||
<&cpcap 28 IRQ_TYPE_NONE>, <&cpcap 19 IRQ_TYPE_NONE>,
|
||||
<&cpcap 18 IRQ_TYPE_NONE>, <&cpcap 17 IRQ_TYPE_NONE>,
|
||||
<&cpcap 16 IRQ_TYPE_NONE>, <&cpcap 49 IRQ_TYPE_NONE>,
|
||||
<&cpcap 48 IRQ_TYPE_NONE>;
|
||||
interrupt-names = "id_ground", "id_float", "se0conn",
|
||||
"vbusvld", "sessvld", "sessend",
|
||||
"se1", "dm", "dp";
|
||||
|
||||
mode-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>,
|
||||
<&gpio1 0 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
|
||||
io-channel-names = "vbus", "id";
|
||||
|
||||
vusb-supply = <&avdd_usb>;
|
||||
};
|
||||
|
||||
regulator {
|
||||
compatible = "motorola,cpcap-regulator";
|
||||
|
||||
regulators {
|
||||
vdd_cpu: SW1 {
|
||||
regulator-name = "vdd_cpu";
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <1125000>;
|
||||
regulator-enable-ramp-delay = <1500>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vdd_core: SW2 {
|
||||
regulator-name = "vdd_core";
|
||||
regulator-min-microvolt = <950000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-enable-ramp-delay = <1500>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vdd_1v8_vio: SW3 {
|
||||
regulator-name = "vdd_1v8_vio";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
regulator-enable-ramp-delay = <0>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vdd_aon: SW4 {
|
||||
regulator-name = "vdd_aon";
|
||||
regulator-min-microvolt = <950000>;
|
||||
regulator-max-microvolt = <1300000>;
|
||||
regulator-enable-ramp-delay = <1500>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vdd_led: SW5 {
|
||||
regulator-name = "vdd_led";
|
||||
regulator-min-microvolt = <5050000>;
|
||||
regulator-max-microvolt = <5050000>;
|
||||
regulator-enable-ramp-delay = <1500>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vdd_hvio: VHVIO {
|
||||
regulator-name = "vdd_hvio";
|
||||
regulator-min-microvolt = <2775000>;
|
||||
regulator-max-microvolt = <2775000>;
|
||||
regulator-enable-ramp-delay = <1000>;
|
||||
};
|
||||
|
||||
vcore_emmc: VSDIO {
|
||||
regulator-name = "vcore_emmc";
|
||||
regulator-min-microvolt = <1500000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-enable-ramp-delay = <1000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
avdd_dsi_csi: VCSI {
|
||||
regulator-name = "avdd_dsi_csi";
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-enable-ramp-delay = <1000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
avdd_3v3_periph: VWLAN2 {
|
||||
regulator-name = "avdd_3v3_periph";
|
||||
regulator-min-microvolt = <2775000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-enable-ramp-delay = <1000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vddio_usd: VSIMCARD {
|
||||
regulator-name = "vddio_usd";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <2900000>;
|
||||
regulator-enable-ramp-delay = <1000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vdd_haptic: VVIB {
|
||||
regulator-name = "vdd_haptic";
|
||||
regulator-min-microvolt = <1300000>;
|
||||
regulator-max-microvolt = <3000000>;
|
||||
regulator-enable-ramp-delay = <1000>;
|
||||
};
|
||||
|
||||
avdd_usb: VUSB {
|
||||
regulator-name = "avdd_usb";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-enable-ramp-delay = <1000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
vdd_audio: VAUDIO {
|
||||
regulator-name = "vdd_audio";
|
||||
regulator-min-microvolt = <2775000>;
|
||||
regulator-max-microvolt = <2775000>;
|
||||
regulator-enable-ramp-delay = <1000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cpcap_rtc: rtc {
|
||||
compatible = "motorola,cpcap-rtc";
|
||||
|
||||
interrupt-parent = <&cpcap>;
|
||||
interrupts = <39 IRQ_TYPE_NONE>, <26 IRQ_TYPE_NONE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
Motorola CPCAP PMIC device tree binding
|
||||
|
||||
Required properties:
|
||||
- compatible : One or both of "motorola,cpcap" or "ste,6556002"
|
||||
- reg : SPI chip select
|
||||
- interrupts : The interrupt line the device is connected to
|
||||
- interrupt-controller : Marks the device node as an interrupt controller
|
||||
- #interrupt-cells : The number of cells to describe an IRQ, should be 2
|
||||
- #address-cells : Child device offset number of cells, should be 1
|
||||
- #size-cells : Child device size number of cells, should be 0
|
||||
- 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:
|
||||
|
||||
- Documentation/devicetree/bindings/power/supply/cpcap-battery.yaml
|
||||
- Documentation/devicetree/bindings/power/supply/cpcap-charger.yaml
|
||||
- Documentation/devicetree/bindings/regulator/cpcap-regulator.txt
|
||||
- Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
|
||||
- Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt
|
||||
- Documentation/devicetree/bindings/rtc/cpcap-rtc.txt
|
||||
- Documentation/devicetree/bindings/leds/leds-cpcap.txt
|
||||
- Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml
|
||||
|
||||
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>;
|
||||
- interrupts : should contain jack detection interrupts, with headset
|
||||
detect interrupt matching "hs" and microphone bias 2
|
||||
detect interrupt matching "mb2" in interrupt-names.
|
||||
- interrupt-names : Contains "hs", "mb2"
|
||||
|
||||
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 {
|
||||
cpcap: pmic@0 {
|
||||
compatible = "motorola,cpcap", "ste,6556002";
|
||||
reg = <0>; /* cs0 */
|
||||
interrupt-parent = <&gpio1>;
|
||||
interrupts = <7 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
spi-max-frequency = <3000000>;
|
||||
spi-cs-high;
|
||||
|
||||
audio-codec {
|
||||
#sound-dai-cells = <1>;
|
||||
interrupts-extended = <&cpcap 9 0>, <&cpcap 10 0>;
|
||||
interrupt-names = "hs", "mb2";
|
||||
|
||||
/* HiFi */
|
||||
port@0 {
|
||||
endpoint {
|
||||
remote-endpoint = <&cpu_dai1>;
|
||||
};
|
||||
};
|
||||
|
||||
/* Voice */
|
||||
port@1 {
|
||||
endpoint {
|
||||
remote-endpoint = <&cpu_dai2>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -74,6 +74,7 @@ properties:
|
|||
- qcom,pm8994
|
||||
- qcom,pm8998
|
||||
- qcom,pma8084
|
||||
- qcom,pmau0102
|
||||
- qcom,pmc8180
|
||||
- qcom,pmc8180c
|
||||
- qcom,pmc8380
|
||||
|
|
@ -147,7 +148,9 @@ patternProperties:
|
|||
|
||||
"^audio-codec@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/sound/qcom,pm8916-wcd-analog-codec.yaml#
|
||||
oneOf:
|
||||
- $ref: /schemas/sound/qcom,pm4125-codec.yaml#
|
||||
- $ref: /schemas/sound/qcom,pm8916-wcd-analog-codec.yaml#
|
||||
|
||||
"^battery@[0-9a-f]+$":
|
||||
type: object
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ properties:
|
|||
- qcom,tcsr-msm8916
|
||||
- qcom,tcsr-msm8917
|
||||
- qcom,tcsr-msm8937
|
||||
- qcom,tcsr-msm8952
|
||||
- qcom,tcsr-msm8953
|
||||
- qcom,tcsr-msm8960
|
||||
- qcom,tcsr-msm8974
|
||||
|
|
|
|||
|
|
@ -77,6 +77,16 @@ properties:
|
|||
description:
|
||||
The input supply for LDO_REG3.
|
||||
|
||||
# pinctrl-bindings.txt allows the pin configuration nodes to be grandchildren
|
||||
# of the pin controller, and the text binding this replaces used that layout:
|
||||
# a "pinmux" node holding the nodes that carry "pins". The driver reaches both
|
||||
# layouts, because pinconf_generic_dt_node_to_map() parses the referenced node
|
||||
# and then walks its children.
|
||||
pinmux:
|
||||
type: object
|
||||
additionalProperties:
|
||||
$ref: '#/$defs/rk805-pin-config'
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
patternProperties:
|
||||
|
|
@ -86,6 +96,38 @@ properties:
|
|||
unevaluatedProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
$defs:
|
||||
rk805-pin-config:
|
||||
type: object
|
||||
description:
|
||||
The RK805 has two output-only GPIOs which can be muxed to the GPIO
|
||||
function and driven low or high at boot.
|
||||
additionalProperties: false
|
||||
|
||||
properties:
|
||||
pins:
|
||||
description:
|
||||
List of GPIO pins to configure.
|
||||
items:
|
||||
enum: [gpio0, gpio1]
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
function:
|
||||
description:
|
||||
The RK805 only supports the GPIO function.
|
||||
enum: [gpio]
|
||||
|
||||
output-low: true
|
||||
output-high: true
|
||||
|
||||
required:
|
||||
- pins
|
||||
|
||||
patternProperties:
|
||||
'-pins$':
|
||||
$ref: '#/$defs/rk805-pin-config'
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
|
|
@ -125,9 +167,11 @@ examples:
|
|||
interrupt-parent = <&gpio2>;
|
||||
interrupts = <RK_PA6 IRQ_TYPE_LEVEL_LOW>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pmic_int_l>;
|
||||
pinctrl-0 = <&pmic_int_l>, <&rk805_default>, <&rk805_grouped>;
|
||||
rockchip,system-power-controller;
|
||||
wakeup-source;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
#clock-cells = <0>;
|
||||
|
||||
vcc1-supply = <&vcc_sys>;
|
||||
|
|
@ -137,6 +181,20 @@ examples:
|
|||
vcc5-supply = <&vcc_io>;
|
||||
vcc6-supply = <&vcc_io>;
|
||||
|
||||
rk805_default: rk805-default-pins {
|
||||
pins = "gpio0";
|
||||
function = "gpio";
|
||||
output-high;
|
||||
};
|
||||
|
||||
rk805_grouped: pinmux {
|
||||
gpio01 {
|
||||
pins = "gpio1";
|
||||
function = "gpio";
|
||||
output-low;
|
||||
};
|
||||
};
|
||||
|
||||
regulators {
|
||||
vdd_logic: DCDC_REG1 {
|
||||
regulator-name = "vdd_logic";
|
||||
|
|
|
|||
|
|
@ -312,6 +312,33 @@ properties:
|
|||
items:
|
||||
- const: audioclk
|
||||
|
||||
'#sound-dai-cells':
|
||||
description: Selects one of the two digital audio interfaces
|
||||
const: 1
|
||||
|
||||
ports:
|
||||
$ref: /schemas/sound/audio-graph-port.yaml#/definitions/ports
|
||||
|
||||
stericsson,amic1-type-single-ended:
|
||||
description: Configure analog microphone 1 as single-ended
|
||||
type: boolean
|
||||
|
||||
stericsson,amic2-type-single-ended:
|
||||
description: Configure analog microphone 2 as single-ended
|
||||
type: boolean
|
||||
|
||||
stericsson,amic1a-bias-vamic2:
|
||||
description: Supply analog microphone 1A from VAMIC2 instead of VAMIC1
|
||||
type: boolean
|
||||
|
||||
stericsson,amic1b-bias-vamic2:
|
||||
description: Supply analog microphone 1B from VAMIC2 instead of VAMIC1
|
||||
type: boolean
|
||||
|
||||
stericsson,amic2-bias-vamic1:
|
||||
description: Supply analog microphone 2 from VAMIC1 instead of VAMIC2
|
||||
type: boolean
|
||||
|
||||
stericsson,earpeice-cmv:
|
||||
description: Earpiece voltage
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
|
|
@ -319,11 +346,14 @@ properties:
|
|||
|
||||
required:
|
||||
- compatible
|
||||
- '#sound-dai-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
regulator:
|
||||
description: Node describing the AB8500 internal regulators.
|
||||
LDO means low-dropout regulator. SMPS means switched-mode power
|
||||
supply; the SMPS regulators described here are buck converters.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
|
|
@ -439,16 +469,117 @@ properties:
|
|||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: stericsson,ab8500-regulator
|
||||
then:
|
||||
properties:
|
||||
ab8500_buck_smps1:
|
||||
description: Analog buck converter for the VSMPS1 1.2V I/O
|
||||
and memory supply.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8500_buck_smps2:
|
||||
description: Analog buck converter for the VSMPS2 1.8V I/O
|
||||
and memory supply.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8500_buck_smps3:
|
||||
description: Analog buck converter for VSMPS3, which supplies
|
||||
the VSAFE power domain.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8500_buck_arm:
|
||||
description: Analog buck converter for the VARM processor
|
||||
supply.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8500_buck_ape:
|
||||
description: Analog buck converter for the VAPE application
|
||||
processor supply.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8500_buck_mod:
|
||||
description: Analog buck converter for the VMOD modem supply.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: stericsson,ab8505-regulator
|
||||
then:
|
||||
properties:
|
||||
ab8505_buck_smpsa:
|
||||
description: Analog buck converter for the VSMPSA 1.2V I/O
|
||||
and memory supply. The selector range depends on OTP
|
||||
configuration.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8505_buck_smpsb:
|
||||
description: Analog buck converter for the VSMPSB 1.8V I/O
|
||||
and memory supply. The selector range depends on OTP
|
||||
configuration.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8505_buck_safe:
|
||||
description: Analog buck converter for the VSAFE permanent
|
||||
logic and DDR supply. The selector range depends on OTP
|
||||
configuration.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8505_buck_arm:
|
||||
description: Analog buck converter for the VARM processor
|
||||
supply, with a 0.6V to 1.39375V selector range.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8505_buck_smpsc:
|
||||
description: Analog buck converter for the VSMPSC multimedia
|
||||
and graphics supply. The selector range depends on OTP
|
||||
configuration.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8505_buck_smpsm:
|
||||
description: Analog buck converter for the VSMPSM modem
|
||||
supply. The selector range depends on OTP configuration.
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
additionalProperties: false
|
||||
unevaluatedProperties: false
|
||||
|
||||
regulator-external:
|
||||
description: Node describing the AB8500 external regulators. This
|
||||
concerns the autonomous regulators VSMPS1, VSMPS2 and VSMPS3
|
||||
that are normally controlled by external electronics but also
|
||||
sometimes need to be explicitly controlled by software.
|
||||
description: Node describing AB8500 control interfaces for external
|
||||
regulators. AB8500 controls these external devices through the
|
||||
ExtSupply1Ena, ExtSupply2Ena and ExtSupply3Ena signals and associated
|
||||
low-power-mode signals. They are distinct from the VSMPS1, VSMPS2 and
|
||||
VSMPS3 buck converters integrated into AB8500.
|
||||
type: object
|
||||
|
||||
properties:
|
||||
|
|
@ -456,19 +587,22 @@ properties:
|
|||
const: stericsson,ab8500-ext-regulator
|
||||
|
||||
ab8500_ext1:
|
||||
description: The voltage for the VSMPS1 external regulator
|
||||
description: External regulator controlled through ExtSupply1Ena and
|
||||
ExtSupply12LPn
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8500_ext2:
|
||||
description: The voltage for the VSMPS2 external regulator
|
||||
description: External regulator controlled through ExtSupply2Ena and
|
||||
ExtSupply12LPn
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
||||
ab8500_ext3:
|
||||
description: The voltage for the VSMPS3 external regulator
|
||||
description: External regulator controlled through ExtSupply3Ena and
|
||||
ExtSupply3LPn
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
unevaluatedProperties: false
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ properties:
|
|||
const: 2
|
||||
|
||||
db8500-prcmu-regulators:
|
||||
deprecated: true
|
||||
description: Node describing the DB8500 regulators. These are mainly
|
||||
power rails inside the silicon but some of those are also routed
|
||||
out to external pins.
|
||||
|
|
@ -207,26 +208,6 @@ properties:
|
|||
|
||||
required:
|
||||
- compatible
|
||||
- db8500_vape
|
||||
- db8500_varm
|
||||
- db8500_vmodem
|
||||
- db8500_vpll
|
||||
- db8500_vsmps1
|
||||
- db8500_vsmps2
|
||||
- db8500_vsmps3
|
||||
- db8500_vrf1
|
||||
- db8500_sva_mmdsp
|
||||
- db8500_sva_mmdsp_ret
|
||||
- db8500_sva_pipe
|
||||
- db8500_sia_mmdsp
|
||||
- db8500_sia_mmdsp_ret
|
||||
- db8500_sia_pipe
|
||||
- db8500_sga
|
||||
- db8500_b2r2_mcde
|
||||
- db8500_esram12
|
||||
- db8500_esram12_ret
|
||||
- db8500_esram34
|
||||
- db8500_esram34_ret
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
|
|
@ -294,6 +275,5 @@ required:
|
|||
- interrupts
|
||||
- interrupt-controller
|
||||
- '#interrupt-cells'
|
||||
- db8500-prcmu-regulators
|
||||
|
||||
additionalProperties: false
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ properties:
|
|||
- allwinner,sun50i-a64-system-controller
|
||||
- altr,l3regs
|
||||
- altr,sdr-ctl
|
||||
- ambarella,cv75-sec-scratchpad
|
||||
- amd,pensando-elba-syscon
|
||||
- amlogic,meson-mx-assist
|
||||
- amlogic,meson-mx-bootrom
|
||||
|
|
|
|||
|
|
@ -11,9 +11,14 @@ maintainers:
|
|||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,bq25703a
|
||||
- ti,bq25792
|
||||
oneOf:
|
||||
- enum:
|
||||
- ti,bq25703a
|
||||
- ti,bq25792
|
||||
- items:
|
||||
- enum:
|
||||
- ti,bq25798
|
||||
- const: ti,bq25792
|
||||
|
||||
reg:
|
||||
const: 0x6b
|
||||
|
|
@ -103,7 +108,8 @@ allOf:
|
|||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,bq25792
|
||||
contains:
|
||||
const: ti,bq25792
|
||||
then:
|
||||
properties:
|
||||
input-current-limit-microamp:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/ti,keystone-devctrl.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments Keystone Device State Control
|
||||
|
||||
maintainers:
|
||||
- Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
|
||||
|
||||
description:
|
||||
The Keystone II devices have a set of registers that are used to control the
|
||||
status of its peripherals. This node is intended to allow access to this
|
||||
functionality.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: ti,keystone-devctrl
|
||||
- const: syscon
|
||||
- const: simple-mfd
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 1
|
||||
|
||||
ranges: true
|
||||
|
||||
patternProperties:
|
||||
"^gpio@[0-9a-f]+$":
|
||||
type: object
|
||||
description: Keystone DSP GPIO controller
|
||||
required:
|
||||
- compatible
|
||||
|
||||
"^interrupt-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
description: Keystone DSP to ARM interrupt controller
|
||||
required:
|
||||
- compatible
|
||||
|
||||
"^reset-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
description: Keystone reset controller
|
||||
required:
|
||||
- compatible
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#address-cells"
|
||||
- "#size-cells"
|
||||
- ranges
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
device-state-control@2620000 {
|
||||
compatible = "ti,keystone-devctrl", "syscon", "simple-mfd";
|
||||
reg = <0x02620000 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges = <0x0 0x02620000 0x1000>;
|
||||
|
||||
interrupt-controller@2a0 {
|
||||
compatible = "ti,keystone-irq";
|
||||
reg = <0x2a0 0x4>;
|
||||
interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
ti,syscon-dev = <&devctrl 0x2a0>;
|
||||
};
|
||||
|
||||
reset-controller@328 {
|
||||
compatible = "ti,keystone-reset";
|
||||
reg = <0x328 0x10>;
|
||||
ti,syscon-pll = <&pllctrl 0xe4>;
|
||||
ti,syscon-dev = <&devctrl 0x328>;
|
||||
ti,wdt-list = <0>;
|
||||
};
|
||||
};
|
||||
64
Documentation/devicetree/bindings/mfd/ti,lp3943.yaml
Normal file
64
Documentation/devicetree/bindings/mfd/ti,lp3943.yaml
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/ti,lp3943.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI/National Semiconductor LP3943 MFD driver
|
||||
|
||||
maintainers:
|
||||
- Chaosheng Qu <quchaosheng000406@163.com>
|
||||
|
||||
description:
|
||||
LP3943 is an integrated device capable of driving LEDs. It contains two
|
||||
sub-devices, lp3943-gpio and lp3943-pwm, which are instantiated by the MFD
|
||||
core from the child nodes described below.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,lp3943
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
description: I2C slave address, from 0x60 to 0x67
|
||||
|
||||
patternProperties:
|
||||
"^gpio":
|
||||
type: object
|
||||
$ref: /schemas/gpio/trivial-gpio.yaml#
|
||||
|
||||
"^pwm":
|
||||
type: object
|
||||
$ref: /schemas/pwm/pwm-lp3943.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
lp3943: gpio@60 {
|
||||
compatible = "ti,lp3943";
|
||||
reg = <0x60>;
|
||||
|
||||
gpio {
|
||||
compatible = "ti,lp3943-gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
pwm {
|
||||
compatible = "ti,lp3943-pwm";
|
||||
#pwm-cells = <2>;
|
||||
ti,pwm0 = <8 9 10>;
|
||||
ti,pwm1 = <15>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
92
Documentation/devicetree/bindings/mfd/ti,tps61050.yaml
Normal file
92
Documentation/devicetree/bindings/mfd/ti,tps61050.yaml
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/ti,tps61050.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments TPS61050/TPS61052 Boost Converter
|
||||
|
||||
maintainers:
|
||||
- Eduard Bostina <egbostina@gmail.com>
|
||||
|
||||
description:
|
||||
The TP61050/TPS61052 is a high-power "white LED driver". The device
|
||||
provides LED, GPIO and regulator functionalities.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,tps61050
|
||||
- ti,tps61052
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
regulator:
|
||||
type: object
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
description: Puts the chip in regulator mode.
|
||||
unevaluatedProperties: false
|
||||
|
||||
led:
|
||||
type: object
|
||||
$ref: /schemas/leds/common.yaml#
|
||||
description: Puts the chip in LED mode.
|
||||
unevaluatedProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
allOf:
|
||||
- not:
|
||||
required:
|
||||
- regulator
|
||||
- led
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
tps61052@33 {
|
||||
compatible = "ti,tps61052";
|
||||
reg = <0x33>;
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
tps61052@33 {
|
||||
compatible = "ti,tps61052";
|
||||
reg = <0x33>;
|
||||
|
||||
regulator {
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
#include <dt-bindings/leds/common.h>
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
tps61052@33 {
|
||||
compatible = "ti,tps61052";
|
||||
reg = <0x33>;
|
||||
|
||||
led {
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -90,7 +90,6 @@ required:
|
|||
- reg
|
||||
- gpio-controller
|
||||
- '#gpio-cells'
|
||||
- regulators
|
||||
|
||||
examples:
|
||||
- |
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ properties:
|
|||
|
||||
interrupt-controller: true
|
||||
|
||||
wakeup-source: true
|
||||
|
||||
'#interrupt-cells':
|
||||
description: Specifies the IRQ number and flags
|
||||
const: 2
|
||||
|
|
@ -169,6 +171,12 @@ patternProperties:
|
|||
vcc7-supply: VRTC input.
|
||||
vccio-supply: VIO input.
|
||||
|
||||
"^.+-hog$":
|
||||
type: object
|
||||
|
||||
required:
|
||||
- gpio-hog
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
|
|
|||
156
Documentation/devicetree/bindings/mfd/ti,twl6040.yaml
Normal file
156
Documentation/devicetree/bindings/mfd/ti,twl6040.yaml
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/ti,twl6040.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Texas Instruments TWL6040 family audio codec
|
||||
|
||||
maintainers:
|
||||
- Eduard Bostina <egbostina@gmail.com>
|
||||
|
||||
description:
|
||||
The TWL6040s are 8-channel high quality low-power audio codecs providing
|
||||
audio, vibra and GPO functionality on OMAP4+ platforms. They are connected
|
||||
to the host processor via i2c for commands, McPDM for audio data and
|
||||
commands.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- ti,twl6040
|
||||
- ti,twl6041
|
||||
|
||||
reg:
|
||||
const: 0x4b
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
gpio-controller: true
|
||||
|
||||
"#gpio-cells":
|
||||
const: 1
|
||||
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
ti,audpwron-gpio:
|
||||
maxItems: 1
|
||||
description: Power on GPIO line for the twl6040
|
||||
|
||||
vio-supply:
|
||||
description: Regulator for the twl6040 VIO supply
|
||||
|
||||
v2v1-supply:
|
||||
description: Regulator for the twl6040 V2V1 supply
|
||||
|
||||
enable-active-high:
|
||||
type: boolean
|
||||
description: To power on the twl6040 during boot.
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 2
|
||||
items:
|
||||
enum:
|
||||
- clk32k
|
||||
- mclk
|
||||
|
||||
vddvibl-supply:
|
||||
description: Regulator for the left vibra motor
|
||||
|
||||
vddvibr-supply:
|
||||
description: Regulator for the right vibra motor
|
||||
|
||||
vibra:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
properties:
|
||||
ti,vibldrv-res:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Resistance parameter for left driver
|
||||
|
||||
ti,vibrdrv-res:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Resistance parameter for right driver
|
||||
|
||||
ti,viblmotor-res:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Resistance parameter for left motor
|
||||
|
||||
ti,vibrmotor-res:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: Resistance parameter for right motor
|
||||
|
||||
ti,vddvibl-uV:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: vddvibl default voltage if it needs to be changed
|
||||
|
||||
ti,vddvibr-uV:
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
description: vddvibr default voltage if it needs to be changed
|
||||
|
||||
required:
|
||||
- ti,vibldrv-res
|
||||
- ti,vibrdrv-res
|
||||
- ti,viblmotor-res
|
||||
- ti,vibrmotor-res
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- "#clock-cells"
|
||||
- vio-supply
|
||||
- v2v1-supply
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
required:
|
||||
- vibra
|
||||
then:
|
||||
required:
|
||||
- vddvibl-supply
|
||||
- vddvibr-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
audio-codec@4b {
|
||||
compatible = "ti,twl6040";
|
||||
reg = <0x4b>;
|
||||
interrupts = <0 119 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-parent = <&gic>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <1>;
|
||||
#clock-cells = <0>;
|
||||
ti,audpwron-gpio = <&gpio4 31 0>;
|
||||
|
||||
vio-supply = <&v1v8>;
|
||||
v2v1-supply = <&v2v1>;
|
||||
enable-active-high;
|
||||
|
||||
/* regulators for vibra motor */
|
||||
vddvibl-supply = <&vbat>;
|
||||
vddvibr-supply = <&vbat>;
|
||||
|
||||
vibra {
|
||||
ti,vibldrv-res = <8>;
|
||||
ti,vibrdrv-res = <3>;
|
||||
ti,viblmotor-res = <10>;
|
||||
ti,vibrmotor-res = <10>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
* Device tree bindings for Texas Instruments keystone device state control
|
||||
|
||||
The Keystone II devices have a set of registers that are used to control
|
||||
the status of its peripherals. This node is intended to allow access to
|
||||
this functionality.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: "ti,keystone-devctrl", "syscon"
|
||||
|
||||
- reg: contains offset/length value for device state control
|
||||
registers space.
|
||||
|
||||
Example:
|
||||
|
||||
devctrl: device-state-control@02620000 {
|
||||
compatible = "ti,keystone-devctrl", "syscon";
|
||||
reg = <0x02620000 0x1000>;
|
||||
};
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
* Device tree bindings for TI TPS61050/61052 Boost Converters
|
||||
|
||||
The TP61050/TPS61052 is a high-power "white LED driver". The
|
||||
device provides LED, GPIO and regulator functionalities.
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,tps61050" or "ti,tps61052"
|
||||
- reg: Specifies the I2C slave address
|
||||
|
||||
Optional sub-node:
|
||||
|
||||
This subnode selects the chip's operational mode.
|
||||
There can be at most one single available subnode.
|
||||
|
||||
- regulator: presence of this sub-node puts the chip in regulator mode.
|
||||
see ../regulator/regulator.yaml
|
||||
|
||||
- led: presence of this sub-node puts the chip in led mode.
|
||||
Optional properties:
|
||||
- function : see ../leds/common.txt
|
||||
- color : see ../leds/common.txt
|
||||
- label : see ../leds/common.txt
|
||||
(deprecated)
|
||||
|
||||
Example (GPIO operation only):
|
||||
|
||||
i2c0 {
|
||||
tps61052@33 {
|
||||
compatible = "ti,tps61052";
|
||||
reg = <0x33>;
|
||||
};
|
||||
};
|
||||
|
||||
Example (GPIO + regulator operation):
|
||||
|
||||
i2c0 {
|
||||
tps61052@33 {
|
||||
compatible = "ti,tps61052";
|
||||
reg = <0x33>;
|
||||
|
||||
regulator {
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
Example (GPIO + led operation):
|
||||
|
||||
#include <dt-bindings/leds/common.h>
|
||||
|
||||
i2c0 {
|
||||
tps61052@33 {
|
||||
compatible = "ti,tps61052";
|
||||
reg = <0x33>;
|
||||
|
||||
led {
|
||||
color = <LED_COLOR_ID_WHITE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
Texas Instruments TWL6040 family
|
||||
|
||||
The TWL6040s are 8-channel high quality low-power audio codecs providing audio,
|
||||
vibra and GPO functionality on OMAP4+ platforms.
|
||||
They are connected to the host processor via i2c for commands, McPDM for audio
|
||||
data and commands.
|
||||
|
||||
Required properties:
|
||||
- compatible : "ti,twl6040" for twl6040, "ti,twl6041" for twl6041
|
||||
- reg: must be 0x4b for i2c address
|
||||
- interrupts: twl6040 has one interrupt line connecteded to the main SoC
|
||||
- gpio-controller:
|
||||
- #gpio-cells = <1>: twl6040 provides GPO lines.
|
||||
- #clock-cells = <0>; twl6040 is a provider of pdmclk which is used by McPDM
|
||||
- twl6040,audpwron-gpio: Power on GPIO line for the twl6040
|
||||
|
||||
- vio-supply: Regulator for the twl6040 VIO supply
|
||||
- v2v1-supply: Regulator for the twl6040 V2V1 supply
|
||||
|
||||
Optional properties, nodes:
|
||||
- enable-active-high: To power on the twl6040 during boot.
|
||||
- clocks: phandle to the clk32k and/or to mclk clock provider
|
||||
- clock-names: Must be "clk32k" for the 32K clock and "mclk" for the MCLK.
|
||||
|
||||
Vibra functionality
|
||||
Required properties:
|
||||
- vddvibl-supply: Regulator for the left vibra motor
|
||||
- vddvibr-supply: Regulator for the right vibra motor
|
||||
- vibra { }: Configuration section for vibra parameters containing the following
|
||||
properties:
|
||||
- ti,vibldrv-res: Resistance parameter for left driver
|
||||
- ti,vibrdrv-res: Resistance parameter for right driver
|
||||
- ti,viblmotor-res: Resistance parameter for left motor
|
||||
- ti,viblmotor-res: Resistance parameter for right motor
|
||||
|
||||
Optional properties within vibra { } section:
|
||||
- vddvibl_uV: If the vddvibl default voltage need to be changed
|
||||
- vddvibr_uV: If the vddvibr default voltage need to be changed
|
||||
|
||||
Example:
|
||||
&i2c1 {
|
||||
twl6040: twl@4b {
|
||||
compatible = "ti,twl6040";
|
||||
|
||||
interrupts = <0 119 4>;
|
||||
interrupt-parent = <&gic>;
|
||||
twl6040,audpwron-gpio = <&gpio4 31 0>;
|
||||
|
||||
vio-supply = <&v1v8>;
|
||||
v2v1-supply = <&v2v1>;
|
||||
enable-active-high;
|
||||
|
||||
/* regulators for vibra motor */
|
||||
vddvibl-supply = <&vbat>;
|
||||
vddvibr-supply = <&vbat>;
|
||||
|
||||
vibra {
|
||||
/* Vibra driver, motor resistance parameters */
|
||||
ti,vibldrv-res = <8>;
|
||||
ti,vibrdrv-res = <3>;
|
||||
ti,viblmotor-res = <10>;
|
||||
ti,vibrmotor-res = <10>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/include/ "twl6040.dtsi"
|
||||
168
Documentation/devicetree/bindings/mfd/x-powers,ac200.yaml
Normal file
168
Documentation/devicetree/bindings/mfd/x-powers,ac200.yaml
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/x-powers,ac200.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: X-Powers AC200 mixed-signal IC
|
||||
|
||||
maintainers:
|
||||
- James Hilliard <james.hilliard1@gmail.com>
|
||||
- Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
|
||||
description:
|
||||
The AC200 is a mixed-signal companion IC containing audio, video, RTC and
|
||||
Fast Ethernet PHY functions. Its control registers are accessed over I2C.
|
||||
The audio codec and TV encoder are described by properties of this node.
|
||||
The Ethernet PHY is described separately on its MDIO bus.
|
||||
|
||||
allOf:
|
||||
- $ref: /schemas/sound/dai-common.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: x-powers,ac200
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
description:
|
||||
AC200 input clock. When using the Ethernet PHY, its configured rate must
|
||||
be 24 or 27 MHz, matching the rates encoded by the documented EPHY clock
|
||||
selector.
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
description:
|
||||
The shared, level-triggered, open-drain INTB output for the TV encoder,
|
||||
Ethernet PHY and RTC interrupts. Omit when INTB is not connected. TV
|
||||
encoder cable detection status can also be read over I2C without an
|
||||
interrupt.
|
||||
|
||||
'#sound-dai-cells':
|
||||
const: 0
|
||||
|
||||
ac-ldoin-supply:
|
||||
description:
|
||||
The 3.3 V supply connected to the AC_LDOIN pin for the audio codec LDO
|
||||
input. This may be the same regulator as tv-vcc-supply.
|
||||
|
||||
tv-vcc-supply:
|
||||
description:
|
||||
The 3.3 V supply connected to the TV_VCC pin for the composite-video
|
||||
DAC. This may be the same regulator as ac-ldoin-supply.
|
||||
|
||||
nvmem-cells:
|
||||
maxItems: 1
|
||||
description: TV encoder bandgap calibration.
|
||||
|
||||
nvmem-cell-names:
|
||||
items:
|
||||
- const: bandgap
|
||||
|
||||
ports:
|
||||
$ref: /schemas/graph.yaml#/properties/ports
|
||||
|
||||
properties:
|
||||
port@0:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Input to the TV encoder, carrying CCIR656.
|
||||
|
||||
port@1:
|
||||
$ref: /schemas/graph.yaml#/properties/port
|
||||
description: Output to the composite-video connector.
|
||||
|
||||
required:
|
||||
- port@0
|
||||
- port@1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
|
||||
dependencies:
|
||||
'#sound-dai-cells': [ ac-ldoin-supply ]
|
||||
ports: [ tv-vcc-supply ]
|
||||
nvmem-cells: [ nvmem-cell-names ]
|
||||
nvmem-cell-names: [ nvmem-cells ]
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mixed-signal@10 {
|
||||
compatible = "x-powers,ac200";
|
||||
reg = <0x10>;
|
||||
clocks = <&pwm 5>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <1 20 IRQ_TYPE_LEVEL_LOW>;
|
||||
#sound-dai-cells = <0>;
|
||||
ac-ldoin-supply = <®_aldo2>;
|
||||
tv-vcc-supply = <®_aldo2>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
tve_in: endpoint {
|
||||
remote-endpoint = <&tcon_out_tve>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
tve_out: endpoint {
|
||||
remote-endpoint = <&composite_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
mixed-signal@10 {
|
||||
compatible = "x-powers,ac200";
|
||||
reg = <0x10>;
|
||||
clocks = <&pwm 5>;
|
||||
/* INTB is not connected. */
|
||||
tv-vcc-supply = <®_aldo2>;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&tcon_out_tve>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
endpoint {
|
||||
remote-endpoint = <&composite_in>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
Pincontrol driver for RK805 Power management IC.
|
||||
|
||||
RK805 has 2 pins which can be configured as GPIO output only.
|
||||
|
||||
Please refer file <devicetree/bindings/pinctrl/pinctrl-bindings.txt>
|
||||
for details of the common pinctrl bindings used by client devices,
|
||||
including the meaning of the phrase "pin configuration node".
|
||||
|
||||
Optional Pinmux properties:
|
||||
--------------------------
|
||||
Following properties are required if default setting of pins are required
|
||||
at boot.
|
||||
- pinctrl-names: A pinctrl state named per <pinctrl-bindings.txt>.
|
||||
- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per
|
||||
<pinctrl-bindings.txt>.
|
||||
|
||||
The pin configurations are defined as child of the pinctrl states node. Each
|
||||
sub-node have following properties:
|
||||
|
||||
Required properties:
|
||||
------------------
|
||||
- #gpio-cells: Should be two. The first cell is the pin number and the
|
||||
second is the GPIO flags.
|
||||
|
||||
- gpio-controller: Marks the device node as a GPIO controller.
|
||||
|
||||
- pins: List of pins. Valid values of pins properties are: gpio0, gpio1.
|
||||
|
||||
First 2 properties must be added in the RK805 PMIC node, documented in
|
||||
Documentation/devicetree/bindings/mfd/rockchip,rk808.yaml
|
||||
|
||||
Optional properties:
|
||||
-------------------
|
||||
Following are optional properties defined as pinmux DT binding document
|
||||
<pinctrl-bindings.txt>. Absence of properties will leave the configuration
|
||||
on default.
|
||||
function,
|
||||
output-low,
|
||||
output-high.
|
||||
|
||||
Valid values for function properties are: gpio.
|
||||
|
||||
There are also not customised properties for any GPIO.
|
||||
|
||||
Example:
|
||||
--------
|
||||
rk805: rk805@18 {
|
||||
compatible = "rockchip,rk805";
|
||||
...
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pmic_int_l>, <&rk805_default>;
|
||||
|
||||
rk805_default: pinmux {
|
||||
gpio01 {
|
||||
pins = "gpio0", "gpio1";
|
||||
function = "gpio";
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
TI/National Semiconductor LP3943 PWM controller
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,lp3943-pwm"
|
||||
- #pwm-cells: Should be 2. See pwm.yaml in this directory for a
|
||||
description of the cells format.
|
||||
Note that this hardware limits the period length to the
|
||||
range 6250~1600000.
|
||||
- ti,pwm0 or ti,pwm1: Output pin number(s) for PWM channel 0 or 1.
|
||||
0 = output 0
|
||||
1 = output 1
|
||||
.
|
||||
.
|
||||
15 = output 15
|
||||
|
||||
Example:
|
||||
PWM 0 is for RGB LED brightness control
|
||||
PWM 1 is for brightness control of LP8557 backlight device
|
||||
|
||||
&i2c3 {
|
||||
lp3943@60 {
|
||||
compatible = "ti,lp3943";
|
||||
reg = <0x60>;
|
||||
|
||||
/*
|
||||
* PWM 0 : output 8, 9 and 10
|
||||
* PWM 1 : output 15
|
||||
*/
|
||||
pwm3943: pwm {
|
||||
compatible = "ti,lp3943-pwm";
|
||||
#pwm-cells = <2>;
|
||||
ti,pwm0 = <8 9 10>;
|
||||
ti,pwm1 = <15>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/* LEDs control with PWM 0 of LP3943 */
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
rgb {
|
||||
label = "indi::rgb";
|
||||
pwms = <&pwm3943 0 10000>;
|
||||
max-brightness = <255>;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c4 {
|
||||
/* Backlight control with PWM 1 of LP3943 */
|
||||
backlight@2c {
|
||||
compatible = "ti,lp8557";
|
||||
reg = <0x2c>;
|
||||
|
||||
pwms = <&pwm3943 1 10000>;
|
||||
pwm-names = "lp8557";
|
||||
};
|
||||
};
|
||||
80
Documentation/devicetree/bindings/pwm/pwm-lp3943.yaml
Normal file
80
Documentation/devicetree/bindings/pwm/pwm-lp3943.yaml
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/pwm/pwm-lp3943.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI/National Semiconductor LP3943 PWM controller
|
||||
|
||||
maintainers:
|
||||
- Chaosheng Qu <quchaosheng000406@163.com>
|
||||
|
||||
description:
|
||||
LP3943 has two internal PWM channels. Each channel can be routed to one or
|
||||
more of the 16 outputs of the device.
|
||||
|
||||
Note that the hardware limits the period length to the range 6250~1600000.
|
||||
|
||||
allOf:
|
||||
- $ref: pwm.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: ti,lp3943-pwm
|
||||
|
||||
"#pwm-cells":
|
||||
const: 2
|
||||
|
||||
ti,pwm0:
|
||||
description: Output pin number(s) for PWM channel 0.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 16
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
|
||||
ti,pwm1:
|
||||
description: Output pin number(s) for PWM channel 1.
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 16
|
||||
items:
|
||||
minimum: 0
|
||||
maximum: 15
|
||||
|
||||
anyOf:
|
||||
- required:
|
||||
- ti,pwm0
|
||||
- required:
|
||||
- ti,pwm1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#pwm-cells"
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
gpio@60 {
|
||||
compatible = "ti,lp3943";
|
||||
reg = <0x60>;
|
||||
|
||||
/*
|
||||
* PWM 0 : output 8, 9 and 10
|
||||
* PWM 1 : output 15
|
||||
*/
|
||||
pwm {
|
||||
compatible = "ti,lp3943-pwm";
|
||||
#pwm-cells = <2>;
|
||||
ti,pwm0 = <8 9 10>;
|
||||
ti,pwm1 = <15>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
12
MAINTAINERS
12
MAINTAINERS
|
|
@ -19007,7 +19007,7 @@ MULTIFUNCTION DEVICES (MFD)
|
|||
M: Lee Jones <lee@kernel.org>
|
||||
L: mfd@lists.linux.dev
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
|
||||
F: Documentation/devicetree/bindings/mfd/
|
||||
F: drivers/mfd/
|
||||
F: include/dt-bindings/mfd/
|
||||
|
|
@ -27145,7 +27145,7 @@ SYSTEM CONFIGURATION (SYSCON)
|
|||
M: Lee Jones <lee@kernel.org>
|
||||
M: Arnd Bergmann <arnd@arndb.de>
|
||||
S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
|
||||
F: drivers/mfd/syscon.c
|
||||
|
||||
SYSTEM CONTROL & POWER/MANAGEMENT INTERFACE (SCPI/SCMI) Message Protocol drivers
|
||||
|
|
@ -30133,6 +30133,14 @@ F: drivers/net/wwan/
|
|||
F: include/linux/wwan.h
|
||||
F: include/uapi/linux/wwan.h
|
||||
|
||||
X-POWERS AC200 DRIVERS
|
||||
M: Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
M: James Hilliard <james.hilliard1@gmail.com>
|
||||
L: linux-sunxi@lists.linux.dev
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/mfd/x-powers,ac200.yaml
|
||||
F: drivers/mfd/ac200.c
|
||||
|
||||
X-POWERS AXP288 PMIC DRIVERS
|
||||
M: Hans de Goede <hansg@kernel.org>
|
||||
S: Maintained
|
||||
|
|
|
|||
|
|
@ -18,14 +18,17 @@
|
|||
#include <linux/mutex.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include <linux/mfd/lm3533.h>
|
||||
|
||||
|
||||
#define LM3533_ALS_RESISTOR_MIN 1
|
||||
#define LM3533_ALS_RESISTOR_MAX 127
|
||||
#define LM3533_ALS_RESISTOR_MIN_OHMS 1575
|
||||
#define LM3533_ALS_RESISTOR_MAX_OHMS 200000
|
||||
#define LM3533_ALS_CHANNEL_CURRENT_MAX 2
|
||||
#define LM3533_ALS_THRESH_MAX 3
|
||||
#define LM3533_ALS_ZONE_MAX 4
|
||||
|
|
@ -49,7 +52,7 @@
|
|||
|
||||
|
||||
struct lm3533_als {
|
||||
struct lm3533 *lm3533;
|
||||
struct regmap *regmap;
|
||||
struct platform_device *pdev;
|
||||
|
||||
unsigned long flags;
|
||||
|
|
@ -57,6 +60,9 @@ struct lm3533_als {
|
|||
|
||||
atomic_t zone;
|
||||
struct mutex thresh_mutex;
|
||||
|
||||
u32 r_select;
|
||||
bool pwm_mode;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -65,7 +71,7 @@ static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average,
|
|||
{
|
||||
struct lm3533_als *als = iio_priv(indio_dev);
|
||||
u8 reg;
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (average)
|
||||
|
|
@ -73,7 +79,7 @@ static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average,
|
|||
else
|
||||
reg = LM3533_REG_ALS_READ_ADC_RAW;
|
||||
|
||||
ret = lm3533_read(als->lm3533, reg, &val);
|
||||
ret = regmap_read(als->regmap, reg, &val);
|
||||
if (ret) {
|
||||
dev_err(&indio_dev->dev, "failed to read adc\n");
|
||||
return ret;
|
||||
|
|
@ -87,10 +93,10 @@ static int lm3533_als_get_adc(struct iio_dev *indio_dev, bool average,
|
|||
static int _lm3533_als_get_zone(struct iio_dev *indio_dev, u8 *zone)
|
||||
{
|
||||
struct lm3533_als *als = iio_priv(indio_dev);
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val);
|
||||
ret = regmap_read(als->regmap, LM3533_REG_ALS_ZONE_INFO, &val);
|
||||
if (ret) {
|
||||
dev_err(&indio_dev->dev, "failed to read zone\n");
|
||||
return ret;
|
||||
|
|
@ -128,7 +134,7 @@ static inline u8 lm3533_als_get_target_reg(unsigned channel, unsigned zone)
|
|||
}
|
||||
|
||||
static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel,
|
||||
unsigned zone, u8 *val)
|
||||
unsigned zone, u32 *val)
|
||||
{
|
||||
struct lm3533_als *als = iio_priv(indio_dev);
|
||||
u8 reg;
|
||||
|
|
@ -141,7 +147,7 @@ static int lm3533_als_get_target(struct iio_dev *indio_dev, unsigned channel,
|
|||
return -EINVAL;
|
||||
|
||||
reg = lm3533_als_get_target_reg(channel, zone);
|
||||
ret = lm3533_read(als->lm3533, reg, val);
|
||||
ret = regmap_read(als->regmap, reg, val);
|
||||
if (ret)
|
||||
dev_err(&indio_dev->dev, "failed to get target current\n");
|
||||
|
||||
|
|
@ -162,7 +168,7 @@ static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel,
|
|||
return -EINVAL;
|
||||
|
||||
reg = lm3533_als_get_target_reg(channel, zone);
|
||||
ret = lm3533_write(als->lm3533, reg, val);
|
||||
ret = regmap_write(als->regmap, reg, val);
|
||||
if (ret)
|
||||
dev_err(&indio_dev->dev, "failed to set target current\n");
|
||||
|
||||
|
|
@ -172,8 +178,8 @@ static int lm3533_als_set_target(struct iio_dev *indio_dev, unsigned channel,
|
|||
static int lm3533_als_get_current(struct iio_dev *indio_dev, unsigned channel,
|
||||
int *val)
|
||||
{
|
||||
u32 target;
|
||||
u8 zone;
|
||||
u8 target;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_als_get_zone(indio_dev, &zone);
|
||||
|
|
@ -272,16 +278,10 @@ static irqreturn_t lm3533_als_isr(int irq, void *dev_id)
|
|||
static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable)
|
||||
{
|
||||
struct lm3533_als *als = iio_priv(indio_dev);
|
||||
u8 mask = LM3533_ALS_INT_ENABLE_MASK;
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
if (enable)
|
||||
val = mask;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, val, mask);
|
||||
ret = regmap_assign_bits(als->regmap, LM3533_REG_ALS_ZONE_INFO,
|
||||
LM3533_ALS_INT_ENABLE_MASK, enable);
|
||||
if (ret) {
|
||||
dev_err(&indio_dev->dev, "failed to set int mode %d\n",
|
||||
enable);
|
||||
|
|
@ -294,17 +294,16 @@ static int lm3533_als_set_int_mode(struct iio_dev *indio_dev, int enable)
|
|||
static int lm3533_als_get_int_mode(struct iio_dev *indio_dev, int *enable)
|
||||
{
|
||||
struct lm3533_als *als = iio_priv(indio_dev);
|
||||
u8 mask = LM3533_ALS_INT_ENABLE_MASK;
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_read(als->lm3533, LM3533_REG_ALS_ZONE_INFO, &val);
|
||||
if (ret) {
|
||||
ret = regmap_test_bits(als->regmap, LM3533_REG_ALS_ZONE_INFO,
|
||||
LM3533_ALS_INT_ENABLE_MASK);
|
||||
if (ret < 0) {
|
||||
dev_err(&indio_dev->dev, "failed to get int mode\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
*enable = !!(val & mask);
|
||||
*enable = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -317,7 +316,7 @@ static inline u8 lm3533_als_get_threshold_reg(unsigned nr, bool raising)
|
|||
}
|
||||
|
||||
static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr,
|
||||
bool raising, u8 *val)
|
||||
bool raising, u32 *val)
|
||||
{
|
||||
struct lm3533_als *als = iio_priv(indio_dev);
|
||||
u8 reg;
|
||||
|
|
@ -327,7 +326,7 @@ static int lm3533_als_get_threshold(struct iio_dev *indio_dev, unsigned nr,
|
|||
return -EINVAL;
|
||||
|
||||
reg = lm3533_als_get_threshold_reg(nr, raising);
|
||||
ret = lm3533_read(als->lm3533, reg, val);
|
||||
ret = regmap_read(als->regmap, reg, val);
|
||||
if (ret)
|
||||
dev_err(&indio_dev->dev, "failed to get threshold\n");
|
||||
|
||||
|
|
@ -338,8 +337,8 @@ static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr,
|
|||
bool raising, u8 val)
|
||||
{
|
||||
struct lm3533_als *als = iio_priv(indio_dev);
|
||||
u8 val2;
|
||||
u8 reg, reg2;
|
||||
u32 val2;
|
||||
int ret;
|
||||
|
||||
if (nr > LM3533_ALS_THRESH_MAX)
|
||||
|
|
@ -349,7 +348,7 @@ static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr,
|
|||
reg2 = lm3533_als_get_threshold_reg(nr, !raising);
|
||||
|
||||
mutex_lock(&als->thresh_mutex);
|
||||
ret = lm3533_read(als->lm3533, reg2, &val2);
|
||||
ret = regmap_read(als->regmap, reg2, &val2);
|
||||
if (ret) {
|
||||
dev_err(&indio_dev->dev, "failed to get threshold\n");
|
||||
goto out;
|
||||
|
|
@ -364,7 +363,7 @@ static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = lm3533_write(als->lm3533, reg, val);
|
||||
ret = regmap_write(als->regmap, reg, val);
|
||||
if (ret) {
|
||||
dev_err(&indio_dev->dev, "failed to set threshold\n");
|
||||
goto out;
|
||||
|
|
@ -376,11 +375,11 @@ static int lm3533_als_set_threshold(struct iio_dev *indio_dev, unsigned nr,
|
|||
}
|
||||
|
||||
static int lm3533_als_get_hysteresis(struct iio_dev *indio_dev, unsigned nr,
|
||||
u8 *val)
|
||||
u32 *val)
|
||||
{
|
||||
struct lm3533_als *als = iio_priv(indio_dev);
|
||||
u8 falling;
|
||||
u8 raising;
|
||||
u32 falling;
|
||||
u32 raising;
|
||||
int ret;
|
||||
|
||||
if (nr > LM3533_ALS_THRESH_MAX)
|
||||
|
|
@ -410,7 +409,7 @@ static ssize_t show_thresh_either_en(struct device *dev,
|
|||
int enable;
|
||||
int ret;
|
||||
|
||||
if (als->irq) {
|
||||
if (als->irq > 0) {
|
||||
ret = lm3533_als_get_int_mode(indio_dev, &enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -432,7 +431,7 @@ static ssize_t store_thresh_either_en(struct device *dev,
|
|||
u8 zone;
|
||||
int ret;
|
||||
|
||||
if (!als->irq)
|
||||
if (als->irq <= 0)
|
||||
return -EBUSY;
|
||||
|
||||
ret = kstrtoul(buf, 0, &enable);
|
||||
|
|
@ -505,7 +504,7 @@ static ssize_t show_als_attr(struct device *dev,
|
|||
{
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct lm3533_als_attribute *als_attr = to_lm3533_als_attr(attr);
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
switch (als_attr->type) {
|
||||
|
|
@ -717,71 +716,51 @@ static const struct attribute_group lm3533_als_attribute_group = {
|
|||
.attrs = lm3533_als_attributes
|
||||
};
|
||||
|
||||
static int lm3533_als_set_input_mode(struct lm3533_als *als, bool pwm_mode)
|
||||
static int lm3533_als_setup(struct lm3533_als *als)
|
||||
{
|
||||
u8 mask = LM3533_ALS_INPUT_MODE_MASK;
|
||||
u8 val;
|
||||
struct device *dev = &als->pdev->dev;
|
||||
int ret;
|
||||
|
||||
if (pwm_mode)
|
||||
val = mask; /* pwm input */
|
||||
else
|
||||
val = 0; /* analog input */
|
||||
als->pwm_mode = device_property_read_bool(dev, "ti,pwm-mode");
|
||||
|
||||
ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, val, mask);
|
||||
if (ret) {
|
||||
dev_err(&als->pdev->dev, "failed to set input mode %d\n",
|
||||
pwm_mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm3533_als_set_resistor(struct lm3533_als *als, u8 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (val < LM3533_ALS_RESISTOR_MIN || val > LM3533_ALS_RESISTOR_MAX) {
|
||||
dev_err(&als->pdev->dev, "invalid resistor value\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = lm3533_write(als->lm3533, LM3533_REG_ALS_RESISTOR_SELECT, val);
|
||||
if (ret) {
|
||||
dev_err(&als->pdev->dev, "failed to set resistor\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm3533_als_setup(struct lm3533_als *als,
|
||||
const struct lm3533_als_platform_data *pdata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lm3533_als_set_input_mode(als, pdata->pwm_mode);
|
||||
ret = regmap_assign_bits(als->regmap, LM3533_REG_ALS_CONF,
|
||||
LM3533_ALS_INPUT_MODE_MASK, als->pwm_mode);
|
||||
if (ret)
|
||||
return ret;
|
||||
return dev_err_probe(dev, ret, "failed to set input mode %d\n",
|
||||
als->pwm_mode);
|
||||
|
||||
/* ALS input is always high impedance in PWM-mode. */
|
||||
if (!pdata->pwm_mode) {
|
||||
ret = lm3533_als_set_resistor(als, pdata->r_select);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (als->pwm_mode)
|
||||
return 0;
|
||||
|
||||
ret = device_property_read_u32(dev, "ti,resistor-ohms",
|
||||
&als->r_select);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"failed to ger resistor value\n");
|
||||
|
||||
if (als->r_select < LM3533_ALS_RESISTOR_MIN_OHMS ||
|
||||
als->r_select > LM3533_ALS_RESISTOR_MAX_OHMS)
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"invalid resistor value\n");
|
||||
|
||||
als->r_select = DIV_ROUND_UP(2 * MICRO, 10 * als->r_select);
|
||||
|
||||
ret = regmap_write(als->regmap, LM3533_REG_ALS_RESISTOR_SELECT,
|
||||
als->r_select);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to set resistor\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm3533_als_setup_irq(struct lm3533_als *als, void *dev)
|
||||
{
|
||||
u8 mask = LM3533_ALS_INT_ENABLE_MASK;
|
||||
int ret;
|
||||
|
||||
/* Make sure interrupts are disabled. */
|
||||
ret = lm3533_update(als->lm3533, LM3533_REG_ALS_ZONE_INFO, 0, mask);
|
||||
ret = regmap_clear_bits(als->regmap, LM3533_REG_ALS_ZONE_INFO,
|
||||
LM3533_ALS_INT_ENABLE_MASK);
|
||||
if (ret) {
|
||||
dev_err(&als->pdev->dev, "failed to disable interrupts\n");
|
||||
return ret;
|
||||
|
|
@ -801,10 +780,10 @@ static int lm3533_als_setup_irq(struct lm3533_als *als, void *dev)
|
|||
|
||||
static int lm3533_als_enable(struct lm3533_als *als)
|
||||
{
|
||||
u8 mask = LM3533_ALS_ENABLE_MASK;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, mask, mask);
|
||||
ret = regmap_set_bits(als->regmap, LM3533_REG_ALS_CONF,
|
||||
LM3533_ALS_ENABLE_MASK);
|
||||
if (ret)
|
||||
dev_err(&als->pdev->dev, "failed to enable ALS\n");
|
||||
|
||||
|
|
@ -813,10 +792,10 @@ static int lm3533_als_enable(struct lm3533_als *als)
|
|||
|
||||
static int lm3533_als_disable(struct lm3533_als *als)
|
||||
{
|
||||
u8 mask = LM3533_ALS_ENABLE_MASK;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_update(als->lm3533, LM3533_REG_ALS_CONF, 0, mask);
|
||||
ret = regmap_clear_bits(als->regmap, LM3533_REG_ALS_CONF,
|
||||
LM3533_ALS_ENABLE_MASK);
|
||||
if (ret)
|
||||
dev_err(&als->pdev->dev, "failed to disable ALS\n");
|
||||
|
||||
|
|
@ -831,7 +810,6 @@ static const struct iio_info lm3533_als_info = {
|
|||
|
||||
static int lm3533_als_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct lm3533_als_platform_data *pdata;
|
||||
struct lm3533 *lm3533;
|
||||
struct lm3533_als *als;
|
||||
struct iio_dev *indio_dev;
|
||||
|
|
@ -841,12 +819,6 @@ static int lm3533_als_probe(struct platform_device *pdev)
|
|||
if (!lm3533)
|
||||
return -EINVAL;
|
||||
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*als));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
|
|
@ -855,25 +827,27 @@ static int lm3533_als_probe(struct platform_device *pdev)
|
|||
indio_dev->channels = lm3533_als_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(lm3533_als_channels);
|
||||
indio_dev->name = dev_name(&pdev->dev);
|
||||
iio_device_set_parent(indio_dev, pdev->dev.parent);
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
als = iio_priv(indio_dev);
|
||||
als->lm3533 = lm3533;
|
||||
als->regmap = lm3533->regmap;
|
||||
als->pdev = pdev;
|
||||
als->irq = lm3533->irq;
|
||||
als->irq = platform_get_irq_optional(pdev, 0);
|
||||
if (als->irq == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
atomic_set(&als->zone, 0);
|
||||
mutex_init(&als->thresh_mutex);
|
||||
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
if (als->irq) {
|
||||
if (als->irq > 0) {
|
||||
ret = lm3533_als_setup_irq(als, indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = lm3533_als_setup(als, pdata);
|
||||
ret = lm3533_als_setup(als);
|
||||
if (ret)
|
||||
goto err_free_irq;
|
||||
|
||||
|
|
@ -892,7 +866,7 @@ static int lm3533_als_probe(struct platform_device *pdev)
|
|||
err_disable:
|
||||
lm3533_als_disable(als);
|
||||
err_free_irq:
|
||||
if (als->irq)
|
||||
if (als->irq > 0)
|
||||
free_irq(als->irq, indio_dev);
|
||||
|
||||
return ret;
|
||||
|
|
@ -906,13 +880,20 @@ static void lm3533_als_remove(struct platform_device *pdev)
|
|||
lm3533_als_set_int_mode(indio_dev, false);
|
||||
iio_device_unregister(indio_dev);
|
||||
lm3533_als_disable(als);
|
||||
if (als->irq)
|
||||
if (als->irq > 0)
|
||||
free_irq(als->irq, indio_dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id lm3533_als_match_table[] = {
|
||||
{ .compatible = "ti,lm3533-als" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lm3533_als_match_table);
|
||||
|
||||
static struct platform_driver lm3533_als_driver = {
|
||||
.driver = {
|
||||
.name = "lm3533-als",
|
||||
.of_match_table = lm3533_als_match_table,
|
||||
},
|
||||
.probe = lm3533_als_probe,
|
||||
.remove = lm3533_als_remove,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include <linux/mfd/core.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/mfd/lm3533.h>
|
||||
|
|
@ -41,13 +43,18 @@
|
|||
|
||||
|
||||
struct lm3533_led {
|
||||
struct lm3533 *lm3533;
|
||||
struct regmap *regmap;
|
||||
struct lm3533_ctrlbank cb;
|
||||
struct led_classdev cdev;
|
||||
int id;
|
||||
|
||||
struct mutex mutex;
|
||||
unsigned long flags;
|
||||
|
||||
u32 max_current;
|
||||
u32 pwm;
|
||||
|
||||
bool have_als;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -80,7 +87,6 @@ static inline u8 lm3533_led_get_pattern_reg(struct lm3533_led *led,
|
|||
static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable)
|
||||
{
|
||||
u8 mask;
|
||||
u8 val;
|
||||
int pattern;
|
||||
int state;
|
||||
int ret = 0;
|
||||
|
|
@ -96,12 +102,8 @@ static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable)
|
|||
pattern = lm3533_led_get_pattern(led);
|
||||
mask = 1 << (2 * pattern);
|
||||
|
||||
if (enable)
|
||||
val = mask;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
ret = lm3533_update(led->lm3533, LM3533_REG_PATTERN_ENABLE, val, mask);
|
||||
ret = regmap_assign_bits(led->regmap,
|
||||
LM3533_REG_PATTERN_ENABLE, mask, enable);
|
||||
if (ret) {
|
||||
dev_err(led->cdev.dev, "failed to enable pattern %d (%d)\n",
|
||||
pattern, enable);
|
||||
|
|
@ -131,7 +133,7 @@ static int lm3533_led_set(struct led_classdev *cdev,
|
|||
static enum led_brightness lm3533_led_get(struct led_classdev *cdev)
|
||||
{
|
||||
struct lm3533_led *led = to_lm3533_led(cdev);
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_ctrlbank_get_brightness(&led->cb, &val);
|
||||
|
|
@ -259,7 +261,7 @@ static u8 lm3533_led_delay_set(struct lm3533_led *led, u8 base,
|
|||
dev_dbg(led->cdev.dev, "%s - %lu: %u (0x%02x)\n", __func__,
|
||||
*delay, t, val);
|
||||
reg = lm3533_led_get_pattern_reg(led, base);
|
||||
ret = lm3533_write(led->lm3533, reg, val);
|
||||
ret = regmap_write(led->regmap, reg, val);
|
||||
if (ret)
|
||||
dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg);
|
||||
|
||||
|
|
@ -337,10 +339,10 @@ static ssize_t show_risefalltime(struct device *dev,
|
|||
struct lm3533_led *led = to_lm3533_led(led_cdev);
|
||||
ssize_t ret;
|
||||
u8 reg;
|
||||
u8 val;
|
||||
u32 val;
|
||||
|
||||
reg = lm3533_led_get_pattern_reg(led, base);
|
||||
ret = lm3533_read(led->lm3533, reg, &val);
|
||||
ret = regmap_read(led->regmap, reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -375,7 +377,7 @@ static ssize_t store_risefalltime(struct device *dev,
|
|||
return -EINVAL;
|
||||
|
||||
reg = lm3533_led_get_pattern_reg(led, base);
|
||||
ret = lm3533_write(led->lm3533, reg, val);
|
||||
ret = regmap_write(led->regmap, reg, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -405,11 +407,11 @@ static ssize_t show_als_channel(struct device *dev,
|
|||
struct lm3533_led *led = to_lm3533_led(led_cdev);
|
||||
unsigned channel;
|
||||
u8 reg;
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
|
||||
ret = lm3533_read(led->lm3533, reg, &val);
|
||||
ret = regmap_read(led->regmap, reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -441,7 +443,7 @@ static ssize_t store_als_channel(struct device *dev,
|
|||
mask = LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK;
|
||||
val = channel - 1;
|
||||
|
||||
ret = lm3533_update(led->lm3533, reg, val, mask);
|
||||
ret = regmap_update_bits(led->regmap, reg, mask, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -455,11 +457,11 @@ static ssize_t show_als_en(struct device *dev,
|
|||
struct lm3533_led *led = to_lm3533_led(led_cdev);
|
||||
bool enable;
|
||||
u8 reg;
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
|
||||
ret = lm3533_read(led->lm3533, reg, &val);
|
||||
ret = regmap_read(led->regmap, reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -476,22 +478,15 @@ static ssize_t store_als_en(struct device *dev,
|
|||
struct lm3533_led *led = to_lm3533_led(led_cdev);
|
||||
unsigned enable;
|
||||
u8 reg;
|
||||
u8 mask;
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
if (kstrtouint(buf, 0, &enable))
|
||||
return -EINVAL;
|
||||
|
||||
reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
|
||||
mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
|
||||
|
||||
if (enable)
|
||||
val = mask;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
ret = lm3533_update(led->lm3533, reg, val, mask);
|
||||
ret = regmap_assign_bits(led->regmap, reg,
|
||||
LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK, enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -504,12 +499,12 @@ static ssize_t show_linear(struct device *dev,
|
|||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
struct lm3533_led *led = to_lm3533_led(led_cdev);
|
||||
u8 reg;
|
||||
u8 val;
|
||||
u32 val;
|
||||
int linear;
|
||||
int ret;
|
||||
|
||||
reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
|
||||
ret = lm3533_read(led->lm3533, reg, &val);
|
||||
ret = regmap_read(led->regmap, reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -529,22 +524,15 @@ static ssize_t store_linear(struct device *dev,
|
|||
struct lm3533_led *led = to_lm3533_led(led_cdev);
|
||||
unsigned long linear;
|
||||
u8 reg;
|
||||
u8 mask;
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
if (kstrtoul(buf, 0, &linear))
|
||||
return -EINVAL;
|
||||
|
||||
reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
|
||||
mask = LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK;
|
||||
|
||||
if (linear)
|
||||
val = mask;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
ret = lm3533_update(led->lm3533, reg, val, mask);
|
||||
ret = regmap_assign_bits(led->regmap, reg,
|
||||
LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK, linear);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -557,7 +545,7 @@ static ssize_t show_pwm(struct device *dev,
|
|||
{
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
struct lm3533_led *led = to_lm3533_led(led_cdev);
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_ctrlbank_get_pwm(&led->cb, &val);
|
||||
|
|
@ -573,10 +561,10 @@ static ssize_t store_pwm(struct device *dev,
|
|||
{
|
||||
struct led_classdev *led_cdev = dev_get_drvdata(dev);
|
||||
struct lm3533_led *led = to_lm3533_led(led_cdev);
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (kstrtou8(buf, 0, &val))
|
||||
if (kstrtou32(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
ret = lm3533_ctrlbank_set_pwm(&led->cb, val);
|
||||
|
|
@ -615,7 +603,7 @@ static umode_t lm3533_led_attr_is_visible(struct kobject *kobj,
|
|||
|
||||
if (attr == &dev_attr_als_channel.attr ||
|
||||
attr == &dev_attr_als_en.attr) {
|
||||
if (!led->lm3533->have_als)
|
||||
if (!led->have_als)
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
|
|
@ -632,22 +620,20 @@ static const struct attribute_group *lm3533_led_attribute_groups[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static int lm3533_led_setup(struct lm3533_led *led,
|
||||
struct lm3533_led_platform_data *pdata)
|
||||
static int lm3533_led_setup(struct lm3533_led *led)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current);
|
||||
ret = lm3533_ctrlbank_set_max_current(&led->cb, led->max_current);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm);
|
||||
return lm3533_ctrlbank_set_pwm(&led->cb, led->pwm);
|
||||
}
|
||||
|
||||
static int lm3533_led_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct lm3533 *lm3533;
|
||||
struct lm3533_led_platform_data *pdata;
|
||||
struct lm3533_led *led;
|
||||
int ret;
|
||||
|
||||
|
|
@ -657,12 +643,6 @@ static int lm3533_led_probe(struct platform_device *pdev)
|
|||
if (!lm3533)
|
||||
return -EINVAL;
|
||||
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) {
|
||||
dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id);
|
||||
return -EINVAL;
|
||||
|
|
@ -672,9 +652,9 @@ static int lm3533_led_probe(struct platform_device *pdev)
|
|||
if (!led)
|
||||
return -ENOMEM;
|
||||
|
||||
led->lm3533 = lm3533;
|
||||
led->cdev.name = pdata->name;
|
||||
led->cdev.default_trigger = pdata->default_trigger;
|
||||
led->regmap = lm3533->regmap;
|
||||
led->have_als = lm3533->have_als;
|
||||
|
||||
led->cdev.brightness_set_blocking = lm3533_led_set;
|
||||
led->cdev.brightness_get = lm3533_led_get;
|
||||
led->cdev.blink_set = lm3533_led_blink_set;
|
||||
|
|
@ -682,19 +662,28 @@ static int lm3533_led_probe(struct platform_device *pdev)
|
|||
led->cdev.groups = lm3533_led_attribute_groups;
|
||||
led->id = pdev->id;
|
||||
|
||||
led->cdev.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s-%d",
|
||||
pdev->name, led->id);
|
||||
if (!led->cdev.name)
|
||||
return -ENOMEM;
|
||||
|
||||
led->cdev.default_trigger = "none";
|
||||
device_property_read_string(&pdev->dev, "linux,default-trigger",
|
||||
&led->cdev.default_trigger);
|
||||
|
||||
mutex_init(&led->mutex);
|
||||
|
||||
/* The class framework makes a callback to get brightness during
|
||||
* registration so use parent device (for error reporting) until
|
||||
* registered.
|
||||
*/
|
||||
led->cb.lm3533 = lm3533;
|
||||
led->cb.regmap = lm3533->regmap;
|
||||
led->cb.id = lm3533_led_get_ctrlbank_id(led);
|
||||
led->cb.dev = lm3533->dev;
|
||||
|
||||
platform_set_drvdata(pdev, led);
|
||||
|
||||
ret = led_classdev_register(pdev->dev.parent, &led->cdev);
|
||||
ret = led_classdev_register(&pdev->dev, &led->cdev);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id);
|
||||
return ret;
|
||||
|
|
@ -702,7 +691,14 @@ static int lm3533_led_probe(struct platform_device *pdev)
|
|||
|
||||
led->cb.dev = led->cdev.dev;
|
||||
|
||||
ret = lm3533_led_setup(led, pdata);
|
||||
device_property_read_u32(&pdev->dev, "led-max-microamp",
|
||||
&led->max_current);
|
||||
led->max_current = clamp(led->max_current, LM3533_MAX_CURRENT_MIN,
|
||||
LM3533_MAX_CURRENT_MAX);
|
||||
|
||||
device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &led->pwm);
|
||||
|
||||
ret = lm3533_led_setup(led);
|
||||
if (ret)
|
||||
goto err_deregister;
|
||||
|
||||
|
|
@ -739,9 +735,16 @@ static void lm3533_led_shutdown(struct platform_device *pdev)
|
|||
lm3533_led_set(&led->cdev, LED_OFF); /* disable blink */
|
||||
}
|
||||
|
||||
static const struct of_device_id lm3533_led_match_table[] = {
|
||||
{ .compatible = "ti,lm3533-leds" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lm3533_led_match_table);
|
||||
|
||||
static struct platform_driver lm3533_led_driver = {
|
||||
.driver = {
|
||||
.name = "lm3533-leds",
|
||||
.of_match_table = lm3533_led_match_table,
|
||||
},
|
||||
.probe = lm3533_led_probe,
|
||||
.remove = lm3533_led_remove,
|
||||
|
|
|
|||
|
|
@ -275,10 +275,10 @@ static int device_gpadc_init(struct pm80x_chip *chip,
|
|||
goto out;
|
||||
|
||||
/*
|
||||
* the defult of PM800 is GPADC operates at 100Ks/s rate
|
||||
* the default of PM800 is GPADC operates at 100Ks/s rate
|
||||
* and Number of GPADC slots with active current bias prior
|
||||
* to GPADC sampling = 1 slot for all GPADCs set for
|
||||
* Temprature mesurmants
|
||||
* Temperature measurements
|
||||
*/
|
||||
mask = (PM800_GPADC_GP_BIAS_EN0 | PM800_GPADC_GP_BIAS_EN1 |
|
||||
PM800_GPADC_GP_BIAS_EN2 | PM800_GPADC_GP_BIAS_EN3);
|
||||
|
|
|
|||
|
|
@ -205,6 +205,20 @@ config MFD_AC100
|
|||
This driver include only the core APIs. You have to select individual
|
||||
components like codecs or RTC under the corresponding menus.
|
||||
|
||||
config MFD_AC200
|
||||
tristate "X-Powers AC200"
|
||||
depends on COMMON_CLK
|
||||
depends on I2C
|
||||
depends on OF
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Support for the X-Powers AC200 mixed-signal companion IC. The AC200
|
||||
contains audio, video, RTC and Fast Ethernet PHY functions and is
|
||||
co-packaged with some Allwinner H6 and H616 SoCs. This driver provides
|
||||
the shared register access and instantiates the individual function
|
||||
devices.
|
||||
|
||||
config MFD_AXP20X
|
||||
tristate
|
||||
select MFD_CORE
|
||||
|
|
@ -1006,6 +1020,8 @@ config MFD_MAX77705
|
|||
depends on I2C
|
||||
select MFD_CORE
|
||||
select MFD_SIMPLE_MFD_I2C
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
help
|
||||
Say yes here to add support for Maxim Integrated MAX77705 PMIC.
|
||||
This is a Power Management IC with Charger, safe LDOs, Flash, Haptic
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
|
|||
obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
|
||||
|
||||
obj-$(CONFIG_MFD_AC100) += ac100.o
|
||||
obj-$(CONFIG_MFD_AC200) += ac200.o
|
||||
obj-$(CONFIG_MFD_AXP20X) += axp20x.o
|
||||
obj-$(CONFIG_MFD_AXP20X_I2C) += axp20x-i2c.o
|
||||
obj-$(CONFIG_MFD_AXP20X_RSB) += axp20x-rsb.o
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ static u8 turn_on_stat_set;
|
|||
|
||||
/*
|
||||
* Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
|
||||
* numbers are indexed into this array with (num / 8). The interupts are
|
||||
* numbers are indexed into this array with (num / 8). The interrupts are
|
||||
* defined in linux/mfd/ab8500.h
|
||||
*
|
||||
* This is one off from the register names, i.e. AB8500_IT_MASK1_REG is at
|
||||
|
|
@ -1194,39 +1194,41 @@ static int ab8500_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
|
||||
if (is_ab9540(ab8500))
|
||||
ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
|
||||
ARRAY_SIZE(ab9540_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
ret = devm_mfd_add_devices(ab8500->dev, 0, ab9540_devs,
|
||||
ARRAY_SIZE(ab9540_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
else if (is_ab8540(ab8500)) {
|
||||
ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs,
|
||||
ARRAY_SIZE(ab8540_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
ret = devm_mfd_add_devices(ab8500->dev, 0, ab8540_devs,
|
||||
ARRAY_SIZE(ab8540_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (is_ab8540_1p2_or_earlier(ab8500))
|
||||
ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut1_devs,
|
||||
ARRAY_SIZE(ab8540_cut1_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
ret = devm_mfd_add_devices(ab8500->dev, 0,
|
||||
ab8540_cut1_devs,
|
||||
ARRAY_SIZE(ab8540_cut1_devs),
|
||||
NULL, 0, ab8500->domain);
|
||||
else /* ab8540 >= cut2 */
|
||||
ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut2_devs,
|
||||
ARRAY_SIZE(ab8540_cut2_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
ret = devm_mfd_add_devices(ab8500->dev, 0,
|
||||
ab8540_cut2_devs,
|
||||
ARRAY_SIZE(ab8540_cut2_devs),
|
||||
NULL, 0, ab8500->domain);
|
||||
} else if (is_ab8505(ab8500))
|
||||
ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs,
|
||||
ARRAY_SIZE(ab8505_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
ret = devm_mfd_add_devices(ab8500->dev, 0, ab8505_devs,
|
||||
ARRAY_SIZE(ab8505_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
else
|
||||
ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
|
||||
ARRAY_SIZE(ab8500_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
ret = devm_mfd_add_devices(ab8500->dev, 0, ab8500_devs,
|
||||
ARRAY_SIZE(ab8500_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Add battery management devices */
|
||||
ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
|
||||
ARRAY_SIZE(ab8500_bm_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
ret = devm_mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
|
||||
ARRAY_SIZE(ab8500_bm_devs), NULL,
|
||||
0, ab8500->domain);
|
||||
if (ret)
|
||||
dev_err(ab8500->dev, "error adding bm devices\n");
|
||||
|
||||
|
|
|
|||
222
drivers/mfd/ac200.c
Normal file
222
drivers/mfd/ac200.c
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* X-Powers AC200 Core driver
|
||||
*
|
||||
* Copyright (C) 2019 Jernej Skrabec <jernej.skrabec@gmail.com>
|
||||
* Copyright (C) 2026 James Hilliard <james.hilliard1@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define AC200_SYS_CONTROL_REG 0x0002
|
||||
#define AC200_SYS_CONTROL_CHIP_RESET_DEASSERT BIT(0)
|
||||
#define AC200_SYS_IRQ_ENABLE_REG 0x0004
|
||||
#define AC200_SYS_IRQ_INTB_ENABLE BIT(15)
|
||||
#define AC200_SYS_IRQ_INTB_ACTIVE_HIGH BIT(14)
|
||||
#define AC200_SYS_IRQ_RTC BIT(12)
|
||||
#define AC200_SYS_IRQ_EPHY BIT(8)
|
||||
#define AC200_SYS_IRQ_TVE BIT(4)
|
||||
|
||||
/* Interface register accessible from every register page. */
|
||||
#define AC200_TWI_REG_ADDR_H 0x00fe
|
||||
#define AC200_MAX_REG 0xa1f2
|
||||
|
||||
static const struct regmap_range_cfg ac200_range_cfg[] = {
|
||||
{
|
||||
.range_max = AC200_MAX_REG,
|
||||
.selector_reg = AC200_TWI_REG_ADDR_H,
|
||||
.selector_mask = 0xff,
|
||||
.window_len = 256,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Each AC200 sub-block can reset independently, invalidating its register
|
||||
* contents without regmap's knowledge. Cache only the common page selector;
|
||||
* this avoids a selector read-modify-write for every access on the same page
|
||||
* without ever returning stale functional-register values.
|
||||
*/
|
||||
static bool ac200_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return reg != AC200_TWI_REG_ADDR_H;
|
||||
}
|
||||
|
||||
static const struct regmap_config ac200_regmap_config = {
|
||||
.name = "ac200",
|
||||
.reg_bits = 8,
|
||||
.reg_stride = 2,
|
||||
.val_bits = 16,
|
||||
.ranges = ac200_range_cfg,
|
||||
.num_ranges = ARRAY_SIZE(ac200_range_cfg),
|
||||
.max_register = AC200_MAX_REG,
|
||||
.volatile_reg = ac200_volatile_reg,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
static const char * const ac200_codec_supplies[] = {
|
||||
"ac-ldoin",
|
||||
};
|
||||
|
||||
static const char * const ac200_tve_supplies[] = {
|
||||
"tv-vcc",
|
||||
};
|
||||
|
||||
static const struct resource ac200_tve_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(0, "intb"),
|
||||
};
|
||||
|
||||
#define AC200_CELL(_name, _supplies, _resources) \
|
||||
{ \
|
||||
.name = (_name), \
|
||||
.parent_supplies = (_supplies), \
|
||||
.num_parent_supplies = ARRAY_SIZE(_supplies), \
|
||||
.resources = (_resources), \
|
||||
.num_resources = MFD_RES_SIZE(_resources), \
|
||||
}
|
||||
|
||||
static const struct mfd_cell ac200_cells[] = {
|
||||
AC200_CELL("ac200-codec", ac200_codec_supplies, NULL),
|
||||
AC200_CELL("ac200-tve", ac200_tve_supplies, ac200_tve_resources),
|
||||
};
|
||||
|
||||
static const struct mfd_cell ac200_noirq_cells[] = {
|
||||
AC200_CELL("ac200-codec", ac200_codec_supplies, NULL),
|
||||
AC200_CELL("ac200-tve", ac200_tve_supplies, NULL),
|
||||
};
|
||||
|
||||
static void ac200_disable_intb(void *data)
|
||||
{
|
||||
struct regmap *regmap = data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_clear_bits(regmap, AC200_SYS_IRQ_ENABLE_REG, AC200_SYS_IRQ_INTB_ENABLE);
|
||||
if (ret)
|
||||
dev_err(regmap_get_device(regmap), "failed to disable INTB: %d\n", ret);
|
||||
}
|
||||
|
||||
static int ac200_init_irq(struct device *dev, struct regmap *regmap, int irq)
|
||||
{
|
||||
unsigned int trigger;
|
||||
u16 value = 0;
|
||||
int ret;
|
||||
|
||||
trigger = irq_get_trigger_type(irq);
|
||||
switch (trigger) {
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
value |= AC200_SYS_IRQ_INTB_ACTIVE_HIGH;
|
||||
break;
|
||||
case IRQ_TYPE_NONE:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
break;
|
||||
default:
|
||||
return dev_err_probe(dev, -EINVAL,
|
||||
"INTB is level triggered, not type %u\n", trigger);
|
||||
}
|
||||
|
||||
/* Mask every source before enabling the shared output. */
|
||||
ret = regmap_update_bits(regmap, AC200_SYS_IRQ_ENABLE_REG,
|
||||
AC200_SYS_IRQ_INTB_ENABLE | AC200_SYS_IRQ_INTB_ACTIVE_HIGH |
|
||||
AC200_SYS_IRQ_RTC | AC200_SYS_IRQ_EPHY | AC200_SYS_IRQ_TVE, value);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Children are removed before INTB is disabled and the regmap released. */
|
||||
ret = devm_add_action_or_reset(dev, ac200_disable_intb, regmap);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (trigger == IRQ_TYPE_NONE) {
|
||||
ret = irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to set INTB trigger\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Function drivers request INTB with IRQF_SHARED | IRQF_ONESHOT before
|
||||
* enabling their own source. They check and clear their own status and
|
||||
* mask their source before freeing the IRQ. No IRQ domain is needed.
|
||||
*/
|
||||
return regmap_set_bits(regmap, AC200_SYS_IRQ_ENABLE_REG, AC200_SYS_IRQ_INTB_ENABLE);
|
||||
}
|
||||
|
||||
static int ac200_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct mfd_cell *cells = ac200_noirq_cells;
|
||||
unsigned int num_cells = ARRAY_SIZE(ac200_noirq_cells);
|
||||
struct device *dev = &client->dev;
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
int ret;
|
||||
|
||||
clk = devm_clk_get_enabled(dev, NULL);
|
||||
if (IS_ERR(clk))
|
||||
return dev_err_probe(dev, PTR_ERR(clk), "failed to enable input clock\n");
|
||||
|
||||
ret = devm_clk_rate_exclusive_get(dev, clk);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to lock clock rate\n");
|
||||
|
||||
/*
|
||||
* No minimum delay is documented. Retain the vendor resume path's 40 ms
|
||||
* wait after enabling the input clock and before register access.
|
||||
*/
|
||||
msleep(40);
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, &ac200_regmap_config);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap), "failed to initialize regmap\n");
|
||||
|
||||
ret = regmap_set_bits(regmap, AC200_SYS_CONTROL_REG, AC200_SYS_CONTROL_CHIP_RESET_DEASSERT);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (client->irq > 0) {
|
||||
ret = ac200_init_irq(dev, regmap, client->irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
cells = ac200_cells;
|
||||
num_cells = ARRAY_SIZE(ac200_cells);
|
||||
}
|
||||
|
||||
/* Function drivers read their firmware properties from the parent. */
|
||||
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, num_cells,
|
||||
NULL, client->irq, NULL);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to add function devices\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id ac200_of_match[] = {
|
||||
{ .compatible = "x-powers,ac200" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ac200_of_match);
|
||||
|
||||
static const struct i2c_device_id ac200_i2c_ids[] = {
|
||||
{ .name = "ac200" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ac200_i2c_ids);
|
||||
|
||||
static struct i2c_driver ac200_driver = {
|
||||
.driver = {
|
||||
.name = "ac200",
|
||||
.of_match_table = ac200_of_match,
|
||||
},
|
||||
.probe = ac200_probe,
|
||||
.id_table = ac200_i2c_ids,
|
||||
};
|
||||
module_i2c_driver(ac200_driver);
|
||||
|
||||
MODULE_AUTHOR("Jernej Skrabec <jernej.skrabec@gmail.com>");
|
||||
MODULE_AUTHOR("James Hilliard <james.hilliard1@gmail.com>");
|
||||
MODULE_DESCRIPTION("X-Powers AC200 Core driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -52,8 +52,18 @@ static const struct regmap_access_table bq25792_writeable_regs = {
|
|||
};
|
||||
|
||||
static const struct regmap_range bq25792_volatile_reg_ranges[] = {
|
||||
regmap_reg_range(BQ25792_REG05_INPUT_VOLTAGE_LIMIT,
|
||||
BQ25792_REG06_INPUT_CURRENT_LIMIT + 1),
|
||||
regmap_reg_range(BQ25792_REG0F_CHARGER_CONTROL_0,
|
||||
BQ25792_REG0F_CHARGER_CONTROL_0),
|
||||
regmap_reg_range(BQ25792_REG11_CHARGER_CONTROL_2,
|
||||
BQ25792_REG11_CHARGER_CONTROL_2),
|
||||
regmap_reg_range(BQ25792_REG13_CHARGER_CONTROL_4,
|
||||
BQ25792_REG13_CHARGER_CONTROL_4),
|
||||
regmap_reg_range(BQ25792_REG19_ICO_CURRENT_LIMIT,
|
||||
BQ25792_REG27_FAULT_FLAG_1),
|
||||
regmap_reg_range(BQ25792_REG2E_ADC_CONTROL,
|
||||
BQ25792_REG2E_ADC_CONTROL),
|
||||
regmap_reg_range(BQ25792_REG31_IBUS_ADC,
|
||||
BQ25792_REG47_DPDM_DRIVER),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -54,10 +54,18 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c)
|
|||
return cs42l43_dev_probe(cs42l43);
|
||||
}
|
||||
|
||||
static void cs42l43_i2c_remove(struct i2c_client *i2c)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = dev_get_drvdata(&i2c->dev);
|
||||
|
||||
cs42l43_dev_remove(cs42l43);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_OF)
|
||||
static const struct of_device_id cs42l43_of_match[] = {
|
||||
{ .compatible = "cirrus,cs42l43", .data = (void *)CS42L43_DEVID_VAL },
|
||||
{ .compatible = "cirrus,cs42l43b", .data = (void *)CS42L43B_DEVID_VAL },
|
||||
{ .compatible = "cirrus,cs42l44", .data = (void *)CS42L43B_DEVID_VAL },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cs42l43_of_match);
|
||||
|
|
@ -67,6 +75,7 @@ MODULE_DEVICE_TABLE(of, cs42l43_of_match);
|
|||
static const struct acpi_device_id cs42l43_acpi_match[] = {
|
||||
{ "CSC4243", CS42L43_DEVID_VAL },
|
||||
{ "CSC2A3B", CS42L43B_DEVID_VAL },
|
||||
{ "CSC4244", CS42L43B_DEVID_VAL },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, cs42l43_acpi_match);
|
||||
|
|
@ -81,6 +90,7 @@ static struct i2c_driver cs42l43_i2c_driver = {
|
|||
},
|
||||
|
||||
.probe = cs42l43_i2c_probe,
|
||||
.remove = cs42l43_i2c_remove,
|
||||
};
|
||||
module_i2c_driver(cs42l43_i2c_driver);
|
||||
|
||||
|
|
|
|||
|
|
@ -180,9 +180,17 @@ static int cs42l43_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *
|
|||
return cs42l43_dev_probe(cs42l43);
|
||||
}
|
||||
|
||||
static void cs42l43_sdw_remove(struct sdw_slave *sdw)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = dev_get_drvdata(&sdw->dev);
|
||||
|
||||
cs42l43_dev_remove(cs42l43);
|
||||
}
|
||||
|
||||
static const struct sdw_device_id cs42l43_sdw_id[] = {
|
||||
SDW_SLAVE_ENTRY(0x01FA, 0x4243, (void *)CS42L43_DEVID_VAL),
|
||||
SDW_SLAVE_ENTRY(0x01FA, 0x2A3B, (void *)CS42L43B_DEVID_VAL),
|
||||
SDW_SLAVE_ENTRY(0x01FA, 0x4244, (void *)CS42L43B_DEVID_VAL),
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdw, cs42l43_sdw_id);
|
||||
|
|
@ -194,6 +202,7 @@ static struct sdw_driver cs42l43_sdw_driver = {
|
|||
},
|
||||
|
||||
.probe = cs42l43_sdw_probe,
|
||||
.remove = cs42l43_sdw_remove,
|
||||
.id_table = cs42l43_sdw_id,
|
||||
.ops = &cs42l43_sdw_ops,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -959,6 +959,7 @@ static void cs42l43_boot_work(struct work_struct *work)
|
|||
{
|
||||
struct cs42l43 *cs42l43 = container_of(work, struct cs42l43, boot_work);
|
||||
unsigned int devid, revid, otp;
|
||||
bool valid_id;
|
||||
int ret;
|
||||
|
||||
ret = cs42l43_wait_for_attach(cs42l43);
|
||||
|
|
@ -973,19 +974,24 @@ static void cs42l43_boot_work(struct work_struct *work)
|
|||
|
||||
switch (devid) {
|
||||
case CS42L43_DEVID_VAL:
|
||||
valid_id = (cs42l43->variant_id == CS42L43_DEVID_VAL);
|
||||
break;
|
||||
case CS42L43B_DEVID_VAL:
|
||||
if (devid != cs42l43->variant_id) {
|
||||
dev_err(cs42l43->dev,
|
||||
"Device ID (0x%06x) does not match variant ID (0x%06lx)\n",
|
||||
devid, cs42l43->variant_id);
|
||||
goto err;
|
||||
}
|
||||
case CS42L44_DEVID_VAL:
|
||||
valid_id = (cs42l43->variant_id == CS42L43B_DEVID_VAL);
|
||||
break;
|
||||
default:
|
||||
dev_err(cs42l43->dev, "Unrecognised devid: 0x%06x\n", devid);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!valid_id) {
|
||||
dev_err(cs42l43->dev,
|
||||
"Device ID (0x%06x) does not match variant ID (0x%06lx)\n",
|
||||
devid, cs42l43->variant_id);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = regmap_read(cs42l43->regmap, CS42L43_REVID, &revid);
|
||||
if (ret) {
|
||||
dev_err(cs42l43->dev, "Failed to read rev: %d\n", ret);
|
||||
|
|
@ -1099,15 +1105,19 @@ static int cs42l43_power_down(struct cs42l43 *cs42l43)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void cs42l43_dev_remove(void *data)
|
||||
static void cs42l43_dev_power_down(void *data)
|
||||
{
|
||||
struct cs42l43 *cs42l43 = data;
|
||||
|
||||
cancel_work_sync(&cs42l43->boot_work);
|
||||
|
||||
cs42l43_power_down(cs42l43);
|
||||
}
|
||||
|
||||
void cs42l43_dev_remove(struct cs42l43 *cs42l43)
|
||||
{
|
||||
flush_work(&cs42l43->boot_work);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(cs42l43_dev_remove, "MFD_CS42L43");
|
||||
|
||||
int cs42l43_dev_probe(struct cs42l43 *cs42l43)
|
||||
{
|
||||
int i, ret;
|
||||
|
|
@ -1153,7 +1163,7 @@ int cs42l43_dev_probe(struct cs42l43 *cs42l43)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_add_action_or_reset(cs42l43->dev, cs42l43_dev_remove, cs42l43);
|
||||
ret = devm_add_action_or_reset(cs42l43->dev, cs42l43_dev_power_down, cs42l43);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,5 +25,6 @@ bool cs42l43_precious_register(struct device *dev, unsigned int reg);
|
|||
bool cs42l43_volatile_register(struct device *dev, unsigned int reg);
|
||||
|
||||
int cs42l43_dev_probe(struct cs42l43 *cs42l43);
|
||||
void cs42l43_dev_remove(struct cs42l43 *cs42l43);
|
||||
|
||||
#endif /* CS42L43_CORE_INT_H */
|
||||
|
|
|
|||
|
|
@ -421,6 +421,14 @@ static irqreturn_t da903x_irq_handler(int irq, void *data)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void da903x_cancel_irq_work(void *data)
|
||||
{
|
||||
struct da903x_chip *chip = data;
|
||||
|
||||
disable_irq(chip->client->irq);
|
||||
cancel_work_sync(&chip->irq_work);
|
||||
}
|
||||
|
||||
static const struct da903x_chip_ops da903x_ops[] = {
|
||||
[0] = {
|
||||
.init_chip = da9030_init_chip,
|
||||
|
|
@ -456,6 +464,13 @@ static int da903x_remove_subdevs(struct da903x_chip *chip)
|
|||
return device_for_each_child(chip->dev, NULL, __remove_subdev);
|
||||
}
|
||||
|
||||
static void da903x_remove_subdevs_action(void *data)
|
||||
{
|
||||
struct da903x_chip *chip = data;
|
||||
|
||||
da903x_remove_subdevs(chip);
|
||||
}
|
||||
|
||||
static int da903x_add_subdevs(struct da903x_chip *chip,
|
||||
struct da903x_platform_data *pdata)
|
||||
{
|
||||
|
|
@ -484,7 +499,6 @@ static int da903x_add_subdevs(struct da903x_chip *chip,
|
|||
return 0;
|
||||
|
||||
failed:
|
||||
da903x_remove_subdevs(chip);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -520,6 +534,11 @@ static int da903x_probe(struct i2c_client *client)
|
|||
chip->ops->mask_events(chip, chip->events_mask);
|
||||
chip->ops->read_events(chip, &tmp);
|
||||
|
||||
ret = devm_add_action_or_reset(&client->dev,
|
||||
da903x_remove_subdevs_action, chip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_request_irq(&client->dev, client->irq, da903x_irq_handler,
|
||||
IRQF_TRIGGER_FALLING,
|
||||
"da903x", chip);
|
||||
|
|
@ -529,22 +548,19 @@ static int da903x_probe(struct i2c_client *client)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(&client->dev, da903x_cancel_irq_work,
|
||||
chip);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return da903x_add_subdevs(chip, pdata);
|
||||
}
|
||||
|
||||
static void da903x_remove(struct i2c_client *client)
|
||||
{
|
||||
struct da903x_chip *chip = i2c_get_clientdata(client);
|
||||
|
||||
da903x_remove_subdevs(chip);
|
||||
}
|
||||
|
||||
static struct i2c_driver da903x_driver = {
|
||||
.driver = {
|
||||
.name = "da903x",
|
||||
},
|
||||
.probe = da903x_probe,
|
||||
.remove = da903x_remove,
|
||||
.id_table = da903x_id_table,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -203,36 +203,36 @@ static const struct mfd_cell da9061_devs_noirq[] = {
|
|||
};
|
||||
|
||||
static const struct resource da9062_core_resources[] = {
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN, 1, "VDD_WARN", IORESOURCE_IRQ),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_VDD_WARN, "VDD_WARN"),
|
||||
};
|
||||
|
||||
static const struct resource da9062_regulators_resources[] = {
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_LDO_LIM, 1, "LDO_LIM", IORESOURCE_IRQ),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_LDO_LIM, "LDO_LIM"),
|
||||
};
|
||||
|
||||
static const struct resource da9062_thermal_resources[] = {
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_TEMP, 1, "THERMAL", IORESOURCE_IRQ),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_TEMP, "THERMAL"),
|
||||
};
|
||||
|
||||
static const struct resource da9062_wdt_resources[] = {
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_WDG_WARN, 1, "WD_WARN", IORESOURCE_IRQ),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_WDG_WARN, "WD_WARN"),
|
||||
};
|
||||
|
||||
static const struct resource da9062_rtc_resources[] = {
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_ALARM, 1, "ALARM", IORESOURCE_IRQ),
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_TICK, 1, "TICK", IORESOURCE_IRQ),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_ALARM, "ALARM"),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_TICK, "TICK"),
|
||||
};
|
||||
|
||||
static const struct resource da9062_onkey_resources[] = {
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_ONKEY, 1, "ONKEY", IORESOURCE_IRQ),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_ONKEY, "ONKEY"),
|
||||
};
|
||||
|
||||
static const struct resource da9062_gpio_resources[] = {
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_GPI0, 1, "GPI0", IORESOURCE_IRQ),
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_GPI1, 1, "GPI1", IORESOURCE_IRQ),
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_GPI2, 1, "GPI2", IORESOURCE_IRQ),
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_GPI3, 1, "GPI3", IORESOURCE_IRQ),
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_GPI4, 1, "GPI4", IORESOURCE_IRQ),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI0, "GPI0"),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI1, "GPI1"),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI2, "GPI2"),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI3, "GPI3"),
|
||||
DEFINE_RES_IRQ_NAMED(DA9062_IRQ_GPI4, "GPI4"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell da9062_devs_irq[] = {
|
||||
|
|
|
|||
|
|
@ -450,7 +450,7 @@ static int da9150_probe(struct i2c_client *client)
|
|||
|
||||
da9150->irq_base = regmap_irq_chip_get_base(da9150->regmap_irq_data);
|
||||
|
||||
enable_irq_wake(da9150->irq);
|
||||
da9150->irq_wake_enabled = !enable_irq_wake(da9150->irq);
|
||||
|
||||
ret = mfd_add_devices(da9150->dev, -1, da9150_devs,
|
||||
ARRAY_SIZE(da9150_devs), NULL,
|
||||
|
|
@ -463,6 +463,8 @@ static int da9150_probe(struct i2c_client *client)
|
|||
return 0;
|
||||
|
||||
mfd_fail:
|
||||
if (da9150->irq_wake_enabled)
|
||||
disable_irq_wake(da9150->irq);
|
||||
regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
|
||||
regmap_irq_fail:
|
||||
i2c_unregister_device(da9150->core_qif);
|
||||
|
|
@ -474,8 +476,10 @@ static void da9150_remove(struct i2c_client *client)
|
|||
{
|
||||
struct da9150 *da9150 = i2c_get_clientdata(client);
|
||||
|
||||
regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
|
||||
mfd_remove_devices(da9150->dev);
|
||||
if (da9150->irq_wake_enabled)
|
||||
disable_irq_wake(da9150->irq);
|
||||
regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
|
||||
i2c_unregister_device(da9150->core_qif);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@
|
|||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/gfp_types.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/module.h>
|
||||
|
|
@ -171,6 +173,33 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = {
|
|||
};
|
||||
MODULE_DEVICE_TABLE(acpi, intel_lpss_acpi_ids);
|
||||
|
||||
/*
|
||||
* Devices that need a quirk applied only on the machines matched by
|
||||
* intel_lpss_quirk_dmi[] below. The quirk to apply is carried in the
|
||||
* matching entry's driver_data.
|
||||
*/
|
||||
static const struct acpi_device_id intel_lpss_acpi_quirk_ids[] = {
|
||||
/* Dell Latitude 5285: ACPI GEXP device conflicts with I2C4 (INT3446) */
|
||||
{ .id = "INT3446", .driver_data = QUIRK_IGNORE_RESOURCE_CONFLICTS },
|
||||
{ }
|
||||
};
|
||||
|
||||
static const struct dmi_system_id intel_lpss_quirk_dmi[] = {
|
||||
{
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 5285"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Latitude 7275"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static int intel_lpss_acpi_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct intel_lpss_platform_info *data;
|
||||
|
|
@ -185,6 +214,15 @@ static int intel_lpss_acpi_probe(struct platform_device *pdev)
|
|||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Apply per-device quirks that are only needed on certain machines */
|
||||
if (dmi_check_system(intel_lpss_quirk_dmi)) {
|
||||
const struct acpi_device_id *id;
|
||||
|
||||
id = acpi_match_device(intel_lpss_acpi_quirk_ids, &pdev->dev);
|
||||
if (id)
|
||||
info->quirks |= id->driver_data;
|
||||
}
|
||||
|
||||
/* No need to check mem and irq here as intel_lpss_probe() does it for us */
|
||||
info->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
info->irq = platform_get_irq(pdev, 0);
|
||||
|
|
|
|||
|
|
@ -142,28 +142,21 @@ static void intel_lpss_cache_ltr(struct intel_lpss *lpss)
|
|||
lpss->idle_ltr = readl(lpss->priv + LPSS_PRIV_IDLELTR);
|
||||
}
|
||||
|
||||
static int intel_lpss_debugfs_add(struct intel_lpss *lpss)
|
||||
static void intel_lpss_debugfs_add(struct intel_lpss *lpss)
|
||||
{
|
||||
struct dentry *dir;
|
||||
|
||||
dir = debugfs_create_dir(dev_name(lpss->dev), intel_lpss_debugfs);
|
||||
if (IS_ERR(dir))
|
||||
return PTR_ERR(dir);
|
||||
lpss->debugfs = debugfs_create_dir(dev_name(lpss->dev), intel_lpss_debugfs);
|
||||
|
||||
/* Cache the values into lpss structure */
|
||||
intel_lpss_cache_ltr(lpss);
|
||||
|
||||
debugfs_create_x32("capabilities", S_IRUGO, dir, &lpss->caps);
|
||||
debugfs_create_x32("active_ltr", S_IRUGO, dir, &lpss->active_ltr);
|
||||
debugfs_create_x32("idle_ltr", S_IRUGO, dir, &lpss->idle_ltr);
|
||||
|
||||
lpss->debugfs = dir;
|
||||
return 0;
|
||||
debugfs_create_x32("capabilities", 0444, lpss->debugfs, &lpss->caps);
|
||||
debugfs_create_x32("active_ltr", 0444, lpss->debugfs, &lpss->active_ltr);
|
||||
debugfs_create_x32("idle_ltr", 0444, lpss->debugfs, &lpss->idle_ltr);
|
||||
}
|
||||
|
||||
static void intel_lpss_debugfs_remove(struct intel_lpss *lpss)
|
||||
{
|
||||
debugfs_remove_recursive(lpss->debugfs);
|
||||
debugfs_remove(lpss->debugfs);
|
||||
}
|
||||
|
||||
static void intel_lpss_ltr_set(struct device *dev, s32 val)
|
||||
|
|
@ -432,10 +425,7 @@ int intel_lpss_probe(struct device *dev,
|
|||
goto err_clk_register;
|
||||
|
||||
intel_lpss_ltr_expose(lpss);
|
||||
|
||||
ret = intel_lpss_debugfs_add(lpss);
|
||||
if (ret)
|
||||
dev_warn(dev, "Failed to create debugfs entries\n");
|
||||
intel_lpss_debugfs_add(lpss);
|
||||
|
||||
if (intel_lpss_has_idma(lpss)) {
|
||||
ret = mfd_add_devices(dev, lpss->devid, &intel_lpss_idma64_cell,
|
||||
|
|
|
|||
|
|
@ -35,11 +35,6 @@
|
|||
/* The Quark I2C controller source clock */
|
||||
#define INTEL_QUARK_I2C_CLK_HZ 33000000
|
||||
|
||||
struct intel_quark_mfd {
|
||||
struct clk *i2c_clk;
|
||||
struct clk_lookup *i2c_clk_lookup;
|
||||
};
|
||||
|
||||
static const struct property_entry intel_quark_i2c_controller_standard_properties[] = {
|
||||
PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_STANDARD_MODE_FREQ),
|
||||
{ }
|
||||
|
|
@ -160,37 +155,12 @@ MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
|
|||
|
||||
static int intel_quark_register_i2c_clk(struct device *dev)
|
||||
{
|
||||
struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev);
|
||||
struct clk *i2c_clk;
|
||||
struct clk_hw *hw;
|
||||
|
||||
i2c_clk = clk_register_fixed_rate(dev,
|
||||
INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
|
||||
0, INTEL_QUARK_I2C_CLK_HZ);
|
||||
if (IS_ERR(i2c_clk))
|
||||
return PTR_ERR(i2c_clk);
|
||||
|
||||
quark_mfd->i2c_clk = i2c_clk;
|
||||
quark_mfd->i2c_clk_lookup = clkdev_create(i2c_clk, NULL,
|
||||
INTEL_QUARK_I2C_CONTROLLER_CLK);
|
||||
|
||||
if (!quark_mfd->i2c_clk_lookup) {
|
||||
clk_unregister(quark_mfd->i2c_clk);
|
||||
dev_err(dev, "Fixed clk register failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void intel_quark_unregister_i2c_clk(struct device *dev)
|
||||
{
|
||||
struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev);
|
||||
|
||||
if (!quark_mfd->i2c_clk_lookup)
|
||||
return;
|
||||
|
||||
clkdev_drop(quark_mfd->i2c_clk_lookup);
|
||||
clk_unregister(quark_mfd->i2c_clk);
|
||||
hw = devm_clk_hw_register_fixed_rate(dev, INTEL_QUARK_I2C_CONTROLLER_CLK,
|
||||
NULL, 0, INTEL_QUARK_I2C_CLK_HZ);
|
||||
return devm_clk_hw_register_clkdev(dev, hw, NULL,
|
||||
INTEL_QUARK_I2C_CONTROLLER_CLK);
|
||||
}
|
||||
|
||||
static int intel_quark_i2c_setup(struct pci_dev *pdev)
|
||||
|
|
@ -238,19 +208,12 @@ static int intel_quark_gpio_setup(struct pci_dev *pdev)
|
|||
static int intel_quark_mfd_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct intel_quark_mfd *quark_mfd;
|
||||
int ret;
|
||||
|
||||
ret = pcim_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL);
|
||||
if (!quark_mfd)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, quark_mfd);
|
||||
|
||||
ret = intel_quark_register_i2c_clk(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
@ -260,7 +223,7 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
|
|||
/* This driver only requires 1 IRQ vector */
|
||||
ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
|
||||
if (ret < 0)
|
||||
goto err_unregister_i2c_clk;
|
||||
return ret;
|
||||
|
||||
ret = intel_quark_i2c_setup(pdev);
|
||||
if (ret)
|
||||
|
|
@ -282,8 +245,6 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
|
|||
software_node_unregister_node_group(intel_quark_gpio_node_group);
|
||||
err_free_irq_vectors:
|
||||
pci_free_irq_vectors(pdev);
|
||||
err_unregister_i2c_clk:
|
||||
intel_quark_unregister_i2c_clk(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -292,7 +253,6 @@ static void intel_quark_mfd_remove(struct pci_dev *pdev)
|
|||
mfd_remove_devices(&pdev->dev);
|
||||
software_node_unregister_node_group(intel_quark_gpio_node_group);
|
||||
pci_free_irq_vectors(pdev);
|
||||
intel_quark_unregister_i2c_clk(&pdev->dev);
|
||||
}
|
||||
|
||||
static struct pci_driver intel_quark_mfd_driver = {
|
||||
|
|
|
|||
|
|
@ -1015,7 +1015,7 @@ static void iqs62x_remove(struct i2c_client *client)
|
|||
wait_for_completion(&iqs62x->fw_done);
|
||||
}
|
||||
|
||||
static int __maybe_unused iqs62x_suspend(struct device *dev)
|
||||
static int iqs62x_suspend(struct device *dev)
|
||||
{
|
||||
struct iqs62x_core *iqs62x = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
|
@ -1036,7 +1036,7 @@ static int __maybe_unused iqs62x_suspend(struct device *dev)
|
|||
IQS62X_PWR_SETTINGS_PWR_MODE_HALT);
|
||||
}
|
||||
|
||||
static int __maybe_unused iqs62x_resume(struct device *dev)
|
||||
static int iqs62x_resume(struct device *dev)
|
||||
{
|
||||
struct iqs62x_core *iqs62x = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
|
@ -1051,7 +1051,7 @@ static int __maybe_unused iqs62x_resume(struct device *dev)
|
|||
IQS62X_PWR_SETTINGS_DIS_AUTO, 0);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(iqs62x_pm, iqs62x_suspend, iqs62x_resume);
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(iqs62x_pm, iqs62x_suspend, iqs62x_resume);
|
||||
|
||||
static const struct of_device_id iqs62x_of_match[] = {
|
||||
{ .compatible = "azoteq,iqs620a" },
|
||||
|
|
@ -1067,7 +1067,7 @@ static struct i2c_driver iqs62x_i2c_driver = {
|
|||
.driver = {
|
||||
.name = "iqs62x",
|
||||
.of_match_table = iqs62x_of_match,
|
||||
.pm = &iqs62x_pm,
|
||||
.pm = pm_sleep_ptr(&iqs62x_pm),
|
||||
},
|
||||
.probe = iqs62x_probe,
|
||||
.remove = iqs62x_remove,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ static void kempld_get_hardware_mutex(struct kempld_device_data *pld)
|
|||
|
||||
static void kempld_release_hardware_mutex(struct kempld_device_data *pld)
|
||||
{
|
||||
/* The harware mutex is released when 1 is written to the mutex bit. */
|
||||
/* The hardware mutex is released when 1 is written to the mutex bit. */
|
||||
iowrite8(KEMPLD_MUTEX_KEY, pld->io_index);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,47 +75,116 @@ static const struct regmap_config khadas_mcu_regmap_config = {
|
|||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
static struct mfd_cell khadas_mcu_fan_cells[] = {
|
||||
static const struct mfd_cell khadas_mcu_fan_cells[] = {
|
||||
/* VIM1/2 Rev13+ and VIM3 only */
|
||||
{ .name = "khadas-mcu-fan-ctrl", },
|
||||
MFD_CELL_NAME("khadas-mcu-fan-ctrl"),
|
||||
};
|
||||
|
||||
static struct mfd_cell khadas_mcu_cells[] = {
|
||||
{ .name = "khadas-mcu-user-mem", },
|
||||
static const struct mfd_cell khadas_mcu_cells[] = {
|
||||
MFD_CELL_NAME("khadas-mcu-user-mem"),
|
||||
};
|
||||
|
||||
static bool khadas_mcu_vim4_reg_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case KHADAS_MCU_PWR_OFF_CMD_REG:
|
||||
case KHADAS_MCU_VIM4_REST_CONF_REG:
|
||||
case KHADAS_MCU_WOL_INIT_START_REG:
|
||||
case KHADAS_MCU_VIM4_LED_ON_RAM_REG:
|
||||
case KHADAS_MCU_VIM4_FAN_CTRL_REG:
|
||||
case KHADAS_MCU_VIM4_WDT_EN_REG:
|
||||
case KHADAS_MCU_VIM4_SYS_RST_REG:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool khadas_mcu_vim4_reg_writeable(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case KHADAS_MCU_VERSION_0_REG:
|
||||
case KHADAS_MCU_VERSION_1_REG:
|
||||
case KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config khadas_mcu_vim4_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.reg_stride = 1,
|
||||
.val_bits = 8,
|
||||
.max_register = KHADAS_MCU_VIM4_SYS_RST_REG,
|
||||
.volatile_reg = khadas_mcu_vim4_reg_volatile,
|
||||
.writeable_reg = khadas_mcu_vim4_reg_writeable,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
static const struct mfd_cell khadas_mcu_vim4_fan_cells[] = {
|
||||
MFD_CELL_NAME("khadas-mcu-vim4-fan"),
|
||||
};
|
||||
|
||||
static int khadas_mcu_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct mfd_cell *cells, *fan_cells;
|
||||
const struct regmap_config *regmap_cfg;
|
||||
struct device *dev = &client->dev;
|
||||
int ncells, nfan_cells, ret;
|
||||
struct khadas_mcu *ddata;
|
||||
int ret;
|
||||
const void *mcu_variant;
|
||||
|
||||
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
|
||||
if (!ddata)
|
||||
return -ENOMEM;
|
||||
|
||||
mcu_variant = i2c_get_match_data(client);
|
||||
if (!mcu_variant)
|
||||
return -ENODEV;
|
||||
|
||||
switch ((uintptr_t)mcu_variant) {
|
||||
case KHADAS_MCU_GENERIC:
|
||||
regmap_cfg = &khadas_mcu_regmap_config;
|
||||
cells = khadas_mcu_cells;
|
||||
ncells = ARRAY_SIZE(khadas_mcu_cells);
|
||||
fan_cells = khadas_mcu_fan_cells;
|
||||
nfan_cells = ARRAY_SIZE(khadas_mcu_fan_cells);
|
||||
break;
|
||||
case KHADAS_MCU_VIM4:
|
||||
regmap_cfg = &khadas_mcu_vim4_regmap_config;
|
||||
cells = NULL;
|
||||
ncells = 0;
|
||||
fan_cells = khadas_mcu_vim4_fan_cells;
|
||||
nfan_cells = ARRAY_SIZE(khadas_mcu_vim4_fan_cells);
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, ddata);
|
||||
|
||||
ddata->dev = dev;
|
||||
|
||||
ddata->regmap = devm_regmap_init_i2c(client, &khadas_mcu_regmap_config);
|
||||
ddata->regmap = devm_regmap_init_i2c(client, regmap_cfg);
|
||||
if (IS_ERR(ddata->regmap)) {
|
||||
ret = PTR_ERR(ddata->regmap);
|
||||
dev_err(dev, "Failed to allocate register map: %d\n", ret);
|
||||
return ret;
|
||||
return dev_err_probe(dev, ret, "Failed to allocate register map\n");
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
|
||||
khadas_mcu_cells,
|
||||
ARRAY_SIZE(khadas_mcu_cells),
|
||||
NULL, 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (cells && ncells) {
|
||||
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
|
||||
cells,
|
||||
ncells,
|
||||
NULL, 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (of_property_present(dev->of_node, "#cooling-cells"))
|
||||
return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
|
||||
khadas_mcu_fan_cells,
|
||||
ARRAY_SIZE(khadas_mcu_fan_cells),
|
||||
fan_cells,
|
||||
nfan_cells,
|
||||
NULL, 0, NULL);
|
||||
|
||||
return 0;
|
||||
|
|
@ -123,7 +192,8 @@ static int khadas_mcu_probe(struct i2c_client *client)
|
|||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id khadas_mcu_of_match[] = {
|
||||
{ .compatible = "khadas,mcu", },
|
||||
{ .compatible = "khadas,mcu", .data = (void *)KHADAS_MCU_GENERIC },
|
||||
{ .compatible = "khadas,vim4-mcu", .data = (void *)KHADAS_MCU_VIM4 },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, khadas_mcu_of_match);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
* Author: Johan Hovold <jhovold@gmail.com>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
|
|
@ -14,19 +15,24 @@
|
|||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include <linux/mfd/lm3533.h>
|
||||
|
||||
|
||||
#define LM3533_BOOST_OVP_MASK 0x06
|
||||
#define LM3533_BOOST_OVP_SHIFT 1
|
||||
#define LM3533_BOOST_OVP_MIN (16 * MICRO)
|
||||
#define LM3533_BOOST_OVP_MAX (40 * MICRO)
|
||||
|
||||
#define LM3533_BOOST_FREQ_MASK 0x01
|
||||
#define LM3533_BOOST_FREQ_SHIFT 0
|
||||
#define LM3533_BOOST_FREQ_MIN (500 * HZ_PER_KHZ)
|
||||
#define LM3533_BOOST_FREQ_MAX (1000 * HZ_PER_KHZ)
|
||||
|
||||
#define LM3533_BL_ID_MASK 1
|
||||
#define LM3533_LED_ID_MASK 3
|
||||
|
|
@ -35,6 +41,7 @@
|
|||
|
||||
#define LM3533_HVLED_ID_MAX 2
|
||||
#define LM3533_LVLED_ID_MAX 5
|
||||
#define LM3533_CELLS_MAX 7
|
||||
|
||||
#define LM3533_REG_OUTPUT_CONF1 0x10
|
||||
#define LM3533_REG_OUTPUT_CONF2 0x11
|
||||
|
|
@ -42,125 +49,6 @@
|
|||
|
||||
#define LM3533_REG_MAX 0xb2
|
||||
|
||||
|
||||
static struct mfd_cell lm3533_als_devs[] = {
|
||||
{
|
||||
.name = "lm3533-als",
|
||||
.id = -1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell lm3533_bl_devs[] = {
|
||||
{
|
||||
.name = "lm3533-backlight",
|
||||
.id = 0,
|
||||
},
|
||||
{
|
||||
.name = "lm3533-backlight",
|
||||
.id = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell lm3533_led_devs[] = {
|
||||
{
|
||||
.name = "lm3533-leds",
|
||||
.id = 0,
|
||||
},
|
||||
{
|
||||
.name = "lm3533-leds",
|
||||
.id = 1,
|
||||
},
|
||||
{
|
||||
.name = "lm3533-leds",
|
||||
.id = 2,
|
||||
},
|
||||
{
|
||||
.name = "lm3533-leds",
|
||||
.id = 3,
|
||||
},
|
||||
};
|
||||
|
||||
int lm3533_read(struct lm3533 *lm3533, u8 reg, u8 *val)
|
||||
{
|
||||
int tmp;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(lm3533->regmap, reg, &tmp);
|
||||
if (ret < 0) {
|
||||
dev_err(lm3533->dev, "failed to read register %02x: %d\n",
|
||||
reg, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*val = tmp;
|
||||
|
||||
dev_dbg(lm3533->dev, "read [%02x]: %02x\n", reg, *val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lm3533_read);
|
||||
|
||||
int lm3533_write(struct lm3533 *lm3533, u8 reg, u8 val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dev_dbg(lm3533->dev, "write [%02x]: %02x\n", reg, val);
|
||||
|
||||
ret = regmap_write(lm3533->regmap, reg, val);
|
||||
if (ret < 0) {
|
||||
dev_err(lm3533->dev, "failed to write register %02x: %d\n",
|
||||
reg, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lm3533_write);
|
||||
|
||||
int lm3533_update(struct lm3533 *lm3533, u8 reg, u8 val, u8 mask)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dev_dbg(lm3533->dev, "update [%02x]: %02x/%02x\n", reg, val, mask);
|
||||
|
||||
ret = regmap_update_bits(lm3533->regmap, reg, mask, val);
|
||||
if (ret < 0) {
|
||||
dev_err(lm3533->dev, "failed to update register %02x: %d\n",
|
||||
reg, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lm3533_update);
|
||||
|
||||
static int lm3533_set_boost_freq(struct lm3533 *lm3533,
|
||||
enum lm3533_boost_freq freq)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM,
|
||||
freq << LM3533_BOOST_FREQ_SHIFT,
|
||||
LM3533_BOOST_FREQ_MASK);
|
||||
if (ret)
|
||||
dev_err(lm3533->dev, "failed to set boost frequency\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int lm3533_set_boost_ovp(struct lm3533 *lm3533,
|
||||
enum lm3533_boost_ovp ovp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM,
|
||||
ovp << LM3533_BOOST_OVP_SHIFT,
|
||||
LM3533_BOOST_OVP_MASK);
|
||||
if (ret)
|
||||
dev_err(lm3533->dev, "failed to set boost ovp\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* HVLED output config -- output hvled controlled by backlight bl
|
||||
*/
|
||||
|
|
@ -181,7 +69,8 @@ static int lm3533_set_hvled_config(struct lm3533 *lm3533, u8 hvled, u8 bl)
|
|||
mask = LM3533_BL_ID_MASK << shift;
|
||||
val = bl << shift;
|
||||
|
||||
ret = lm3533_update(lm3533, LM3533_REG_OUTPUT_CONF1, val, mask);
|
||||
ret = regmap_update_bits(lm3533->regmap, LM3533_REG_OUTPUT_CONF1,
|
||||
mask, val);
|
||||
if (ret)
|
||||
dev_err(lm3533->dev, "failed to set hvled config\n");
|
||||
|
||||
|
|
@ -216,21 +105,32 @@ static int lm3533_set_lvled_config(struct lm3533 *lm3533, u8 lvled, u8 led)
|
|||
mask = LM3533_LED_ID_MASK << shift;
|
||||
val = led << shift;
|
||||
|
||||
ret = lm3533_update(lm3533, reg, val, mask);
|
||||
ret = regmap_update_bits(lm3533->regmap, reg, mask, val);
|
||||
if (ret)
|
||||
dev_err(lm3533->dev, "failed to set lvled config\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lm3533_enable(struct lm3533 *lm3533)
|
||||
static int lm3533_enable(struct lm3533 *lm3533)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regulator_enable(lm3533->vin_supply);
|
||||
if (ret) {
|
||||
dev_err(lm3533->dev, "failed to enable vin power supply\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
gpiod_set_value(lm3533->hwen, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lm3533_disable(struct lm3533 *lm3533)
|
||||
{
|
||||
gpiod_set_value(lm3533->hwen, 0);
|
||||
regulator_disable(lm3533->vin_supply);
|
||||
}
|
||||
|
||||
enum lm3533_attribute_type {
|
||||
|
|
@ -258,7 +158,7 @@ static ssize_t show_output(struct device *dev,
|
|||
struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(attr);
|
||||
int id = lattr->u.output.id;
|
||||
u8 reg;
|
||||
u8 val;
|
||||
u32 val;
|
||||
u8 mask;
|
||||
int shift;
|
||||
int ret;
|
||||
|
|
@ -278,7 +178,7 @@ static ssize_t show_output(struct device *dev,
|
|||
mask = LM3533_LED_ID_MASK << shift;
|
||||
}
|
||||
|
||||
ret = lm3533_read(lm3533, reg, &val);
|
||||
ret = regmap_read(lm3533->regmap, reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -376,136 +276,102 @@ static struct attribute_group lm3533_attribute_group = {
|
|||
.attrs = lm3533_attributes
|
||||
};
|
||||
|
||||
static int lm3533_device_als_init(struct lm3533 *lm3533)
|
||||
{
|
||||
struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
|
||||
int ret;
|
||||
|
||||
if (!pdata->als)
|
||||
return 0;
|
||||
|
||||
lm3533_als_devs[0].platform_data = pdata->als;
|
||||
lm3533_als_devs[0].pdata_size = sizeof(*pdata->als);
|
||||
|
||||
ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL,
|
||||
0, NULL);
|
||||
if (ret) {
|
||||
dev_err(lm3533->dev, "failed to add ALS device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
lm3533->have_als = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm3533_device_bl_init(struct lm3533 *lm3533)
|
||||
{
|
||||
struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (!pdata->backlights || pdata->num_backlights == 0)
|
||||
return 0;
|
||||
|
||||
if (pdata->num_backlights > ARRAY_SIZE(lm3533_bl_devs))
|
||||
pdata->num_backlights = ARRAY_SIZE(lm3533_bl_devs);
|
||||
|
||||
for (i = 0; i < pdata->num_backlights; ++i) {
|
||||
lm3533_bl_devs[i].platform_data = &pdata->backlights[i];
|
||||
lm3533_bl_devs[i].pdata_size = sizeof(pdata->backlights[i]);
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs,
|
||||
pdata->num_backlights, NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(lm3533->dev, "failed to add backlight devices\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
lm3533->have_backlights = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm3533_device_led_init(struct lm3533 *lm3533)
|
||||
{
|
||||
struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (!pdata->leds || pdata->num_leds == 0)
|
||||
return 0;
|
||||
|
||||
if (pdata->num_leds > ARRAY_SIZE(lm3533_led_devs))
|
||||
pdata->num_leds = ARRAY_SIZE(lm3533_led_devs);
|
||||
|
||||
for (i = 0; i < pdata->num_leds; ++i) {
|
||||
lm3533_led_devs[i].platform_data = &pdata->leds[i];
|
||||
lm3533_led_devs[i].pdata_size = sizeof(pdata->leds[i]);
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs,
|
||||
pdata->num_leds, NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(lm3533->dev, "failed to add LED devices\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
lm3533->have_leds = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lm3533_device_setup(struct lm3533 *lm3533,
|
||||
struct lm3533_platform_data *pdata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lm3533_set_boost_freq(lm3533, pdata->boost_freq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return lm3533_set_boost_ovp(lm3533, pdata->boost_ovp);
|
||||
}
|
||||
static const struct attribute_group *lm3533_attribute_groups[] = {
|
||||
&lm3533_attribute_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int lm3533_device_init(struct lm3533 *lm3533)
|
||||
{
|
||||
struct lm3533_platform_data *pdata = dev_get_platdata(lm3533->dev);
|
||||
struct device *dev = lm3533->dev;
|
||||
struct mfd_cell *lm3533_devices;
|
||||
u32 reg, nchilds;
|
||||
u32 count = 0;
|
||||
int ret;
|
||||
|
||||
dev_dbg(lm3533->dev, "%s\n", __func__);
|
||||
nchilds = device_get_child_node_count(dev);
|
||||
if (!nchilds || nchilds > LM3533_CELLS_MAX)
|
||||
return dev_err_probe(dev, -ENODEV,
|
||||
"num of child nodes is not supported\n");
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(lm3533->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
lm3533_devices = devm_kcalloc(dev, nchilds, sizeof(*lm3533_devices),
|
||||
GFP_KERNEL);
|
||||
if (!lm3533_devices)
|
||||
return -ENOMEM;
|
||||
|
||||
device_for_each_child_node_scoped(dev, child) {
|
||||
if (count >= nchilds)
|
||||
break;
|
||||
|
||||
if (fwnode_device_is_compatible(child, "ti,lm3533-als")) {
|
||||
lm3533_devices[count].name = "lm3533-als";
|
||||
lm3533_devices[count].of_compatible = "ti,lm3533-als";
|
||||
lm3533_devices[count].id = PLATFORM_DEVID_NONE;
|
||||
|
||||
lm3533->have_als = true;
|
||||
count++;
|
||||
} else if (fwnode_device_is_compatible(child, "ti,lm3533-backlight")) {
|
||||
ret = fwnode_property_read_u32(child, "reg", ®);
|
||||
if (ret || reg >= LM3533_HVLED_ID_MAX) {
|
||||
dev_err(dev, "invalid backlight node %pfw\n", child);
|
||||
continue;
|
||||
}
|
||||
|
||||
lm3533_devices[count].name = "lm3533-backlight";
|
||||
lm3533_devices[count].of_compatible = "ti,lm3533-backlight";
|
||||
lm3533_devices[count].id = reg;
|
||||
lm3533_devices[count].of_reg = reg;
|
||||
lm3533_devices[count].use_of_reg = true;
|
||||
|
||||
lm3533->have_backlights = true;
|
||||
count++;
|
||||
} else if (fwnode_device_is_compatible(child, "ti,lm3533-leds")) {
|
||||
ret = fwnode_property_read_u32(child, "reg", ®);
|
||||
if (ret || reg < LM3533_HVLED_ID_MAX ||
|
||||
reg > LM3533_LVLED_ID_MAX) {
|
||||
dev_err(dev, "invalid LED node %pfw\n", child);
|
||||
continue;
|
||||
}
|
||||
|
||||
lm3533_devices[count].name = "lm3533-leds";
|
||||
lm3533_devices[count].of_compatible = "ti,lm3533-leds";
|
||||
lm3533_devices[count].id = reg - LM3533_HVLED_ID_MAX;
|
||||
lm3533_devices[count].of_reg = reg;
|
||||
lm3533_devices[count].use_of_reg = true;
|
||||
|
||||
lm3533->have_leds = true;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
lm3533->hwen = devm_gpiod_get(lm3533->dev, NULL, GPIOD_OUT_LOW);
|
||||
if (IS_ERR(lm3533->hwen))
|
||||
return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->hwen), "failed to request HWEN GPIO\n");
|
||||
gpiod_set_consumer_name(lm3533->hwen, "lm3533-hwen");
|
||||
|
||||
lm3533_enable(lm3533);
|
||||
|
||||
ret = lm3533_device_setup(lm3533, pdata);
|
||||
ret = lm3533_enable(lm3533);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(lm3533->regmap, LM3533_REG_BOOST_PWM,
|
||||
LM3533_BOOST_FREQ_MASK,
|
||||
FIELD_PREP(LM3533_BOOST_FREQ_MASK, lm3533->boost_freq));
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to set boost frequency\n");
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
lm3533_device_als_init(lm3533);
|
||||
lm3533_device_bl_init(lm3533);
|
||||
lm3533_device_led_init(lm3533);
|
||||
ret = regmap_update_bits(lm3533->regmap, LM3533_REG_BOOST_PWM,
|
||||
LM3533_BOOST_OVP_MASK,
|
||||
FIELD_PREP(LM3533_BOOST_OVP_MASK, lm3533->boost_ovp));
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to set boost ovp\n");
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
ret = sysfs_create_group(&lm3533->dev->kobj, &lm3533_attribute_group);
|
||||
if (ret < 0) {
|
||||
dev_err(lm3533->dev, "failed to create sysfs attributes\n");
|
||||
goto err_unregister;
|
||||
ret = mfd_add_devices(dev, 0, lm3533_devices, count, NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to add MFD devices: %d\n", ret);
|
||||
goto err_disable;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister:
|
||||
mfd_remove_devices(lm3533->dev);
|
||||
err_disable:
|
||||
lm3533_disable(lm3533);
|
||||
|
||||
|
|
@ -516,8 +382,6 @@ static void lm3533_device_exit(struct lm3533 *lm3533)
|
|||
{
|
||||
dev_dbg(lm3533->dev, "%s\n", __func__);
|
||||
|
||||
sysfs_remove_group(&lm3533->dev->kobj, &lm3533_attribute_group);
|
||||
|
||||
mfd_remove_devices(lm3533->dev);
|
||||
lm3533_disable(lm3533);
|
||||
}
|
||||
|
|
@ -589,7 +453,35 @@ static int lm3533_i2c_probe(struct i2c_client *i2c)
|
|||
return PTR_ERR(lm3533->regmap);
|
||||
|
||||
lm3533->dev = &i2c->dev;
|
||||
lm3533->irq = i2c->irq;
|
||||
|
||||
lm3533->hwen = devm_gpiod_get_optional(lm3533->dev, "enable",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(lm3533->hwen))
|
||||
return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->hwen),
|
||||
"failed to get HWEN GPIO\n");
|
||||
|
||||
lm3533->vin_supply = devm_regulator_get(lm3533->dev, "vin");
|
||||
if (IS_ERR(lm3533->vin_supply))
|
||||
return dev_err_probe(lm3533->dev, PTR_ERR(lm3533->vin_supply),
|
||||
"failed to get vin-supply\n");
|
||||
|
||||
device_property_read_u32(lm3533->dev, "ti,boost-ovp-microvolt",
|
||||
&lm3533->boost_ovp);
|
||||
|
||||
lm3533->boost_ovp = clamp(lm3533->boost_ovp, LM3533_BOOST_OVP_MIN,
|
||||
LM3533_BOOST_OVP_MAX);
|
||||
lm3533->boost_ovp = lm3533->boost_ovp / (8 * MICRO) - 2;
|
||||
|
||||
device_property_read_u32(lm3533->dev, "ti,boost-freq-hz",
|
||||
&lm3533->boost_freq);
|
||||
|
||||
lm3533->boost_freq = clamp(lm3533->boost_freq, LM3533_BOOST_FREQ_MIN,
|
||||
LM3533_BOOST_FREQ_MAX);
|
||||
lm3533->boost_freq = lm3533->boost_freq / (500 * KILO) - 1;
|
||||
|
||||
/* LM3533 and child devices do not use DMA */
|
||||
i2c->dev.coherent_dma_mask = 0;
|
||||
i2c->dev.dma_mask = &i2c->dev.coherent_dma_mask;
|
||||
|
||||
return lm3533_device_init(lm3533);
|
||||
}
|
||||
|
|
@ -603,6 +495,12 @@ static void lm3533_i2c_remove(struct i2c_client *i2c)
|
|||
lm3533_device_exit(lm3533);
|
||||
}
|
||||
|
||||
static const struct of_device_id lm3533_match_table[] = {
|
||||
{ .compatible = "ti,lm3533" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lm3533_match_table);
|
||||
|
||||
static const struct i2c_device_id lm3533_i2c_ids[] = {
|
||||
{ "lm3533" },
|
||||
{ }
|
||||
|
|
@ -612,6 +510,8 @@ MODULE_DEVICE_TABLE(i2c, lm3533_i2c_ids);
|
|||
static struct i2c_driver lm3533_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "lm3533",
|
||||
.dev_groups = lm3533_attribute_groups,
|
||||
.of_match_table = lm3533_match_table,
|
||||
},
|
||||
.id_table = lm3533_i2c_ids,
|
||||
.probe = lm3533_i2c_probe,
|
||||
|
|
|
|||
|
|
@ -9,14 +9,10 @@
|
|||
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <linux/mfd/lm3533.h>
|
||||
|
||||
|
||||
#define LM3533_MAX_CURRENT_MIN 5000
|
||||
#define LM3533_MAX_CURRENT_MAX 29800
|
||||
#define LM3533_MAX_CURRENT_STEP 800
|
||||
|
||||
#define LM3533_PWM_MAX 0x3f
|
||||
|
||||
#define LM3533_REG_PWM_BASE 0x14
|
||||
|
|
@ -38,8 +34,8 @@ int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb)
|
|||
dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
|
||||
|
||||
mask = 1 << cb->id;
|
||||
ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE,
|
||||
mask, mask);
|
||||
ret = regmap_set_bits(cb->regmap, LM3533_REG_CTRLBANK_ENABLE,
|
||||
mask);
|
||||
if (ret)
|
||||
dev_err(cb->dev, "failed to enable ctrlbank %d\n", cb->id);
|
||||
|
||||
|
|
@ -55,7 +51,8 @@ int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb)
|
|||
dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
|
||||
|
||||
mask = 1 << cb->id;
|
||||
ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, 0, mask);
|
||||
ret = regmap_clear_bits(cb->regmap, LM3533_REG_CTRLBANK_ENABLE,
|
||||
mask);
|
||||
if (ret)
|
||||
dev_err(cb->dev, "failed to disable ctrlbank %d\n", cb->id);
|
||||
|
||||
|
|
@ -68,7 +65,7 @@ EXPORT_SYMBOL_GPL(lm3533_ctrlbank_disable);
|
|||
*
|
||||
* imax 5000 - 29800 uA (800 uA step)
|
||||
*/
|
||||
int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax)
|
||||
int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u32 imax)
|
||||
{
|
||||
u8 reg;
|
||||
u8 val;
|
||||
|
|
@ -80,7 +77,7 @@ int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax)
|
|||
val = (imax - LM3533_MAX_CURRENT_MIN) / LM3533_MAX_CURRENT_STEP;
|
||||
|
||||
reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_MAX_CURRENT_BASE);
|
||||
ret = lm3533_write(cb->lm3533, reg, val);
|
||||
ret = regmap_write(cb->regmap, reg, val);
|
||||
if (ret)
|
||||
dev_err(cb->dev, "failed to set max current\n");
|
||||
|
||||
|
|
@ -88,13 +85,13 @@ int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current);
|
||||
|
||||
int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val)
|
||||
int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u32 val)
|
||||
{
|
||||
u8 reg;
|
||||
int ret;
|
||||
|
||||
reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE);
|
||||
ret = lm3533_write(cb->lm3533, reg, val);
|
||||
ret = regmap_write(cb->regmap, reg, val);
|
||||
if (ret)
|
||||
dev_err(cb->dev, "failed to set brightness\n");
|
||||
|
||||
|
|
@ -102,13 +99,13 @@ int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_brightness);
|
||||
|
||||
int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val)
|
||||
int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u32 *val)
|
||||
{
|
||||
u8 reg;
|
||||
int ret;
|
||||
|
||||
reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE);
|
||||
ret = lm3533_read(cb->lm3533, reg, val);
|
||||
ret = regmap_read(cb->regmap, reg, val);
|
||||
if (ret)
|
||||
dev_err(cb->dev, "failed to get brightness\n");
|
||||
|
||||
|
|
@ -126,7 +123,7 @@ EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_brightness);
|
|||
* bit 1 - PWM-input enabled in Zone 0
|
||||
* bit 0 - PWM-input enabled
|
||||
*/
|
||||
int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val)
|
||||
int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u32 val)
|
||||
{
|
||||
u8 reg;
|
||||
int ret;
|
||||
|
|
@ -135,7 +132,7 @@ int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val)
|
|||
return -EINVAL;
|
||||
|
||||
reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE);
|
||||
ret = lm3533_write(cb->lm3533, reg, val);
|
||||
ret = regmap_write(cb->regmap, reg, val);
|
||||
if (ret)
|
||||
dev_err(cb->dev, "failed to set PWM mask\n");
|
||||
|
||||
|
|
@ -143,13 +140,13 @@ int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_pwm);
|
||||
|
||||
int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val)
|
||||
int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u32 *val)
|
||||
{
|
||||
u8 reg;
|
||||
int ret;
|
||||
|
||||
reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE);
|
||||
ret = lm3533_read(cb->lm3533, reg, val);
|
||||
ret = regmap_read(cb->regmap, reg, val);
|
||||
if (ret)
|
||||
dev_err(cb->dev, "failed to get PWM mask\n");
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ static int max77705_i2c_probe(struct i2c_client *i2c)
|
|||
return -ENODEV;
|
||||
|
||||
pmic_rev = pmic_rev_value & MAX77705_REVISION_MASK;
|
||||
if (pmic_rev != MAX77705_PASS3)
|
||||
if (pmic_rev != MAX77705_PASS2 && pmic_rev != MAX77705_PASS3)
|
||||
return dev_err_probe(dev, -ENODEV, "Rev.0x%x is not tested\n", pmic_rev);
|
||||
|
||||
/* Active Discharge Enable */
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ static const struct i2c_device_id max77843_id[] = {
|
|||
{ },
|
||||
};
|
||||
|
||||
static int __maybe_unused max77843_suspend(struct device *dev)
|
||||
static int max77843_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
|
||||
|
|
@ -185,7 +185,7 @@ static int __maybe_unused max77843_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused max77843_resume(struct device *dev)
|
||||
static int max77843_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
|
||||
|
|
@ -197,12 +197,12 @@ static int __maybe_unused max77843_resume(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(max77843_pm, max77843_suspend, max77843_resume);
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(max77843_pm, max77843_suspend, max77843_resume);
|
||||
|
||||
static struct i2c_driver max77843_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "max77843",
|
||||
.pm = &max77843_pm,
|
||||
.pm = pm_sleep_ptr(&max77843_pm),
|
||||
.of_match_table = max77843_dt_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ static struct max8998_platform_data *max8998_i2c_parse_dt_pdata(
|
|||
|
||||
/*
|
||||
* ToDo: the 'wakeup' member in the platform data is more of a linux
|
||||
* specfic information. Hence, there is no binding for that yet and
|
||||
* specific information. Hence, there is no binding for that yet and
|
||||
* not parsed here.
|
||||
*/
|
||||
return pd;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
|
|
@ -29,6 +30,7 @@ struct cpcap_ddata {
|
|||
struct regmap_irq_chip_data *irqdata[CPCAP_NR_IRQ_CHIPS];
|
||||
const struct regmap_config *regmap_conf;
|
||||
struct regmap *regmap;
|
||||
enum cpcap_variant variant;
|
||||
};
|
||||
|
||||
static int cpcap_sense_irq(struct regmap *regmap, int irq)
|
||||
|
|
@ -194,20 +196,6 @@ static int cpcap_init_irq(struct cpcap_ddata *cpcap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id cpcap_of_match[] = {
|
||||
{ .compatible = "motorola,cpcap", },
|
||||
{ .compatible = "st,6556002", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cpcap_of_match);
|
||||
|
||||
static const struct spi_device_id cpcap_spi_ids[] = {
|
||||
{ .name = "cpcap" },
|
||||
{ .name = "6556002" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, cpcap_spi_ids);
|
||||
|
||||
static const struct regmap_config cpcap_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.reg_stride = 4,
|
||||
|
|
@ -240,62 +228,74 @@ static int cpcap_resume(struct device *dev)
|
|||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(cpcap_pm, cpcap_suspend, cpcap_resume);
|
||||
|
||||
static const struct mfd_cell cpcap_mfd_devices[] = {
|
||||
{
|
||||
.name = "cpcap_adc",
|
||||
.of_compatible = "motorola,mapphone-cpcap-adc",
|
||||
}, {
|
||||
.name = "cpcap_battery",
|
||||
.of_compatible = "motorola,cpcap-battery",
|
||||
}, {
|
||||
.name = "cpcap-charger",
|
||||
.of_compatible = "motorola,mapphone-cpcap-charger",
|
||||
}, {
|
||||
.name = "cpcap-regulator",
|
||||
.of_compatible = "motorola,mapphone-cpcap-regulator",
|
||||
}, {
|
||||
.name = "cpcap-rtc",
|
||||
.of_compatible = "motorola,cpcap-rtc",
|
||||
}, {
|
||||
.name = "cpcap-pwrbutton",
|
||||
.of_compatible = "motorola,cpcap-pwrbutton",
|
||||
}, {
|
||||
.name = "cpcap-usb-phy",
|
||||
.of_compatible = "motorola,mapphone-cpcap-usb-phy",
|
||||
}, {
|
||||
.name = "cpcap-led",
|
||||
.id = 0,
|
||||
.of_compatible = "motorola,cpcap-led-red",
|
||||
}, {
|
||||
.name = "cpcap-led",
|
||||
.id = 1,
|
||||
.of_compatible = "motorola,cpcap-led-green",
|
||||
}, {
|
||||
.name = "cpcap-led",
|
||||
.id = 2,
|
||||
.of_compatible = "motorola,cpcap-led-blue",
|
||||
}, {
|
||||
.name = "cpcap-led",
|
||||
.id = 3,
|
||||
.of_compatible = "motorola,cpcap-led-adl",
|
||||
}, {
|
||||
.name = "cpcap-led",
|
||||
.id = 4,
|
||||
.of_compatible = "motorola,cpcap-led-cp",
|
||||
}, {
|
||||
.name = "cpcap-codec",
|
||||
}
|
||||
static const struct mfd_cell cpcap_common_devices[] = {
|
||||
MFD_CELL_OF("cpcap_battery", NULL, NULL, 0, 0, "motorola,cpcap-battery"),
|
||||
MFD_CELL_OF("cpcap-rtc", NULL, NULL, 0, 0, "motorola,cpcap-rtc"),
|
||||
MFD_CELL_OF("cpcap-pwrbutton", NULL, NULL, 0, 0, "motorola,cpcap-pwrbutton"),
|
||||
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 0, "motorola,cpcap-led-red"),
|
||||
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 1, "motorola,cpcap-led-green"),
|
||||
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 2, "motorola,cpcap-led-blue"),
|
||||
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 3, "motorola,cpcap-led-adl"),
|
||||
MFD_CELL_NAME("cpcap-codec"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell cpcap_default_devices[] = {
|
||||
MFD_CELL_OF("cpcap_adc", NULL, NULL, 0, 0, "motorola,cpcap-adc"),
|
||||
MFD_CELL_OF("cpcap-regulator", NULL, NULL, 0, 0, "motorola,cpcap-regulator"),
|
||||
MFD_CELL_OF("cpcap-usb-phy", NULL, NULL, 0, 0, "motorola,cpcap-usb-phy"),
|
||||
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 4, "motorola,cpcap-led-cp"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell cpcap_mapphone_devices[] = {
|
||||
MFD_CELL_OF("cpcap_adc", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-adc"),
|
||||
MFD_CELL_OF("cpcap-charger", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-charger"),
|
||||
MFD_CELL_OF("cpcap-regulator", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-regulator"),
|
||||
MFD_CELL_OF("cpcap-usb-phy", NULL, NULL, 0, 0, "motorola,mapphone-cpcap-usb-phy"),
|
||||
MFD_CELL_OF("cpcap-led", NULL, NULL, 0, 4, "motorola,cpcap-led-cp"),
|
||||
};
|
||||
|
||||
/*
|
||||
* The Mot board features a USB-PHY and charger similar to the ones in
|
||||
* Mapphone; however, because Mot is based on Tegra20, it is incompatible
|
||||
* with the existing implementation, which is tightly interconnected with
|
||||
* the OMAP USB PHY.
|
||||
*/
|
||||
static const struct mfd_cell cpcap_mot_devices[] = {
|
||||
MFD_CELL_OF("cpcap_adc", NULL, NULL, 0, 0, "motorola,mot-cpcap-adc"),
|
||||
MFD_CELL_OF("cpcap-regulator", NULL, NULL, 0, 0, "motorola,mot-cpcap-regulator"),
|
||||
};
|
||||
|
||||
static int cpcap_probe(struct spi_device *spi)
|
||||
{
|
||||
struct cpcap_ddata *cpcap;
|
||||
const struct mfd_cell *cells;
|
||||
unsigned int num_cells;
|
||||
int ret;
|
||||
|
||||
cpcap = devm_kzalloc(&spi->dev, sizeof(*cpcap), GFP_KERNEL);
|
||||
if (!cpcap)
|
||||
return -ENOMEM;
|
||||
|
||||
cpcap->variant = (enum cpcap_variant)spi_get_device_match_data(spi);
|
||||
|
||||
switch (cpcap->variant) {
|
||||
case CPCAP_DEFAULT:
|
||||
cells = cpcap_default_devices;
|
||||
num_cells = ARRAY_SIZE(cpcap_default_devices);
|
||||
break;
|
||||
case CPCAP_MAPPHONE:
|
||||
cells = cpcap_mapphone_devices;
|
||||
num_cells = ARRAY_SIZE(cpcap_mapphone_devices);
|
||||
break;
|
||||
case CPCAP_MOT:
|
||||
cells = cpcap_mot_devices;
|
||||
num_cells = ARRAY_SIZE(cpcap_mot_devices);
|
||||
break;
|
||||
default:
|
||||
return dev_err_probe(&spi->dev, -ENODEV,
|
||||
"Unknown device %d\n", cpcap->variant);
|
||||
}
|
||||
|
||||
cpcap->spi = spi;
|
||||
spi_set_drvdata(spi, cpcap);
|
||||
|
||||
|
|
@ -330,10 +330,31 @@ static int cpcap_probe(struct spi_device *spi)
|
|||
spi->dev.coherent_dma_mask = 0;
|
||||
spi->dev.dma_mask = &spi->dev.coherent_dma_mask;
|
||||
|
||||
return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices,
|
||||
ARRAY_SIZE(cpcap_mfd_devices), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(&spi->dev, 0, cpcap_common_devices,
|
||||
ARRAY_SIZE(cpcap_common_devices), NULL, 0, NULL);
|
||||
if (ret)
|
||||
return dev_err_probe(&spi->dev, ret,
|
||||
"Failed to add common child devices\n");
|
||||
|
||||
return devm_mfd_add_devices(&spi->dev, 0, cells, num_cells, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static const struct of_device_id cpcap_of_match[] = {
|
||||
{ .compatible = "motorola,cpcap", .data = (void *)CPCAP_DEFAULT },
|
||||
{ .compatible = "motorola,mapphone-cpcap", .data = (void *)CPCAP_MAPPHONE },
|
||||
{ .compatible = "motorola,mot-cpcap", .data = (void *)CPCAP_MOT },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cpcap_of_match);
|
||||
|
||||
static const struct spi_device_id cpcap_spi_ids[] = {
|
||||
{ .name = "cpcap", .driver_data = CPCAP_DEFAULT },
|
||||
{ .name = "mapphone-cpcap", .driver_data = CPCAP_MAPPHONE },
|
||||
{ .name = "mot-cpcap", .driver_data = CPCAP_MOT },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, cpcap_spi_ids);
|
||||
|
||||
static struct spi_driver cpcap_driver = {
|
||||
.driver = {
|
||||
.name = "cpcap-core",
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ static int mt6360_probe(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused mt6360_suspend(struct device *dev)
|
||||
static int mt6360_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
|
||||
|
|
@ -593,7 +593,7 @@ static int __maybe_unused mt6360_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused mt6360_resume(struct device *dev)
|
||||
static int mt6360_resume(struct device *dev)
|
||||
{
|
||||
|
||||
struct i2c_client *i2c = to_i2c_client(dev);
|
||||
|
|
@ -604,7 +604,7 @@ static int __maybe_unused mt6360_resume(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(mt6360_pm_ops, mt6360_suspend, mt6360_resume);
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(mt6360_pm_ops, mt6360_suspend, mt6360_resume);
|
||||
|
||||
static const struct of_device_id __maybe_unused mt6360_of_id[] = {
|
||||
{ .compatible = "mediatek,mt6360", },
|
||||
|
|
@ -615,7 +615,7 @@ MODULE_DEVICE_TABLE(of, mt6360_of_id);
|
|||
static struct i2c_driver mt6360_driver = {
|
||||
.driver = {
|
||||
.name = "mt6360",
|
||||
.pm = &mt6360_pm_ops,
|
||||
.pm = pm_sleep_ptr(&mt6360_pm_ops),
|
||||
.of_match_table = of_match_ptr(mt6360_of_id),
|
||||
},
|
||||
.probe = mt6360_probe,
|
||||
|
|
|
|||
|
|
@ -261,6 +261,9 @@ static const struct mfd_cell mt6359_devs[] = {
|
|||
|
||||
static const struct mfd_cell mt6397_devs[] = {
|
||||
{
|
||||
.name = "mt6397-auxadc",
|
||||
.of_compatible = "mediatek,mt6397-auxadc",
|
||||
}, {
|
||||
.name = "mt6397-rtc",
|
||||
.num_resources = ARRAY_SIZE(mt6397_rtc_resources),
|
||||
.resources = mt6397_rtc_resources,
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ static u8 rave_sp_reply_code(u8 command)
|
|||
return command + 0x20;
|
||||
case 0xE0 ... 0xEF:
|
||||
/*
|
||||
* Events emitted by all versions of the firmare use
|
||||
* Events emitted by all versions of the firmware use
|
||||
* least significant bit to get an ACK code
|
||||
*/
|
||||
return command | 0x01;
|
||||
|
|
@ -544,7 +544,7 @@ static size_t rave_sp_receive_buf(struct serdev_device *serdev,
|
|||
* NOTE: The above means that only the
|
||||
* frame started by third SOF, sent
|
||||
* after this one will have a chance
|
||||
* to get throught.
|
||||
* to get through.
|
||||
*/
|
||||
goto reset_framer;
|
||||
case RAVE_SP_DLE:
|
||||
|
|
@ -595,7 +595,7 @@ static size_t rave_sp_receive_buf(struct serdev_device *serdev,
|
|||
|
||||
/*
|
||||
* The only way to get out of the above loop and end up here
|
||||
* is throught consuming all of the supplied data, so here we
|
||||
* is through consuming all of the supplied data, so here we
|
||||
* report that we processed it all.
|
||||
*/
|
||||
return size;
|
||||
|
|
|
|||
|
|
@ -875,7 +875,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
|
|||
if (device_property_read_bool(dev, "system-power-controller") ||
|
||||
device_property_read_bool(dev, "rockchip,system-power-controller")) {
|
||||
ret = devm_register_sys_off_handler(dev,
|
||||
SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_PRIO_HIGH,
|
||||
SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_HIGH,
|
||||
&rk808_power_off, rk808);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ static void rk8xx_i2c_shutdown(struct i2c_client *client)
|
|||
rk8xx_shutdown(&client->dev);
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume);
|
||||
|
||||
static const struct of_device_id rk8xx_i2c_of_match[] = {
|
||||
{ .compatible = "rockchip,rk801", .data = &rk801_data },
|
||||
|
|
@ -270,7 +270,7 @@ static struct i2c_driver rk8xx_i2c_driver = {
|
|||
.driver = {
|
||||
.name = "rk8xx-i2c",
|
||||
.of_match_table = rk8xx_i2c_of_match,
|
||||
.pm = &rk8xx_i2c_pm_ops,
|
||||
.pm = pm_sleep_ptr(&rk8xx_i2c_pm_ops),
|
||||
},
|
||||
.probe = rk8xx_i2c_probe,
|
||||
.shutdown = rk8xx_i2c_shutdown,
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ static void rn5t618_i2c_remove(struct i2c_client *i2c)
|
|||
unregister_restart_handler(&rn5t618_restart_handler);
|
||||
}
|
||||
|
||||
static int __maybe_unused rn5t618_i2c_suspend(struct device *dev)
|
||||
static int rn5t618_i2c_suspend(struct device *dev)
|
||||
{
|
||||
struct rn5t618 *priv = dev_get_drvdata(dev);
|
||||
|
||||
|
|
@ -253,7 +253,7 @@ static int __maybe_unused rn5t618_i2c_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused rn5t618_i2c_resume(struct device *dev)
|
||||
static int rn5t618_i2c_resume(struct device *dev)
|
||||
{
|
||||
struct rn5t618 *priv = dev_get_drvdata(dev);
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ static int __maybe_unused rn5t618_i2c_resume(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(rn5t618_i2c_dev_pm_ops,
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(rn5t618_i2c_dev_pm_ops,
|
||||
rn5t618_i2c_suspend,
|
||||
rn5t618_i2c_resume);
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ static struct i2c_driver rn5t618_i2c_driver = {
|
|||
.driver = {
|
||||
.name = "rn5t618",
|
||||
.of_match_table = rn5t618_of_match,
|
||||
.pm = &rn5t618_i2c_dev_pm_ops,
|
||||
.pm = pm_sleep_ptr(&rn5t618_i2c_dev_pm_ops),
|
||||
},
|
||||
.probe = rn5t618_i2c_probe,
|
||||
.remove = rn5t618_i2c_remove,
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ int si476x_core_stop(struct si476x_core *core, bool soft)
|
|||
atomic_set(&core->is_alive, 0);
|
||||
|
||||
if (soft) {
|
||||
/* TODO: This probably shoud be a configurable option,
|
||||
/* TODO: This probably should be a configurable option,
|
||||
* so it is possible to have the chips keep their
|
||||
* oscillators running
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ static int __maybe_unused ti_tscadc_can_wakeup(struct device *dev, void *data)
|
|||
return device_may_wakeup(dev);
|
||||
}
|
||||
|
||||
static int __maybe_unused tscadc_suspend(struct device *dev)
|
||||
static int tscadc_suspend(struct device *dev)
|
||||
{
|
||||
struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev);
|
||||
|
||||
|
|
@ -331,7 +331,7 @@ static int __maybe_unused tscadc_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused tscadc_resume(struct device *dev)
|
||||
static int tscadc_resume(struct device *dev)
|
||||
{
|
||||
struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev);
|
||||
|
||||
|
|
@ -345,7 +345,7 @@ static int __maybe_unused tscadc_resume(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(tscadc_pm_ops, tscadc_suspend, tscadc_resume);
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(tscadc_pm_ops, tscadc_suspend, tscadc_resume);
|
||||
|
||||
static const struct ti_tscadc_data tscdata = {
|
||||
.adc_feature_name = "TI-am335x-adc",
|
||||
|
|
@ -373,7 +373,7 @@ MODULE_DEVICE_TABLE(of, ti_tscadc_dt_ids);
|
|||
static struct platform_driver ti_tscadc_driver = {
|
||||
.driver = {
|
||||
.name = "ti_am3359-tscadc",
|
||||
.pm = &tscadc_pm_ops,
|
||||
.pm = pm_sleep_ptr(&tscadc_pm_ops),
|
||||
.of_match_table = ti_tscadc_dt_ids,
|
||||
},
|
||||
.probe = ti_tscadc_probe,
|
||||
|
|
|
|||
|
|
@ -146,6 +146,31 @@ static const struct irq_domain_ops tps65217_irq_domain_ops = {
|
|||
.map = tps65217_irq_map,
|
||||
};
|
||||
|
||||
static void tps65217_irq_cleanup(void *data)
|
||||
{
|
||||
struct tps65217 *tps = data;
|
||||
unsigned int virq;
|
||||
|
||||
if (!tps->irq_domain)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < TPS65217_NUM_IRQ; i++) {
|
||||
virq = irq_find_mapping(tps->irq_domain, i);
|
||||
if (virq)
|
||||
irq_dispose_mapping(virq);
|
||||
}
|
||||
|
||||
irq_domain_remove(tps->irq_domain);
|
||||
tps->irq_domain = NULL;
|
||||
}
|
||||
|
||||
static void tps65217_irq_wake_disable(void *data)
|
||||
{
|
||||
unsigned long irq = (unsigned long)data;
|
||||
|
||||
disable_irq_wake(irq);
|
||||
}
|
||||
|
||||
static int tps65217_irq_init(struct tps65217 *tps, int irq)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -155,8 +180,12 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq)
|
|||
|
||||
/* Mask all interrupt sources */
|
||||
tps->irq_mask = TPS65217_INT_MASK;
|
||||
tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
|
||||
TPS65217_INT_MASK, TPS65217_PROTECT_NONE);
|
||||
ret = tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
|
||||
TPS65217_INT_MASK, TPS65217_PROTECT_NONE);
|
||||
if (ret) {
|
||||
dev_err(tps->dev, "Failed to mask interrupt sources: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tps->irq_domain = irq_domain_create_linear(dev_fwnode(tps->dev), TPS65217_NUM_IRQ,
|
||||
&tps65217_irq_domain_ops, tps);
|
||||
|
|
@ -165,6 +194,10 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(tps->dev, tps65217_irq_cleanup, tps);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_request_threaded_irq(tps->dev, irq, NULL,
|
||||
tps65217_irq_thread, IRQF_ONESHOT,
|
||||
"tps65217-irq", tps);
|
||||
|
|
@ -174,7 +207,16 @@ static int tps65217_irq_init(struct tps65217 *tps, int irq)
|
|||
return ret;
|
||||
}
|
||||
|
||||
enable_irq_wake(irq);
|
||||
ret = enable_irq_wake(irq);
|
||||
if (ret) {
|
||||
dev_warn(tps->dev, "failed to enable IRQ wake: %d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(tps->dev, tps65217_irq_wake_disable,
|
||||
(void *)(unsigned long)irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -333,7 +375,9 @@ static int tps65217_probe(struct i2c_client *client)
|
|||
}
|
||||
|
||||
if (client->irq) {
|
||||
tps65217_irq_init(tps, client->irq);
|
||||
ret = tps65217_irq_init(tps, client->irq);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
|
|
@ -373,22 +417,6 @@ static int tps65217_probe(struct i2c_client *client)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void tps65217_remove(struct i2c_client *client)
|
||||
{
|
||||
struct tps65217 *tps = i2c_get_clientdata(client);
|
||||
unsigned int virq;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < TPS65217_NUM_IRQ; i++) {
|
||||
virq = irq_find_mapping(tps->irq_domain, i);
|
||||
if (virq)
|
||||
irq_dispose_mapping(virq);
|
||||
}
|
||||
|
||||
irq_domain_remove(tps->irq_domain);
|
||||
tps->irq_domain = NULL;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tps65217_id_table[] = {
|
||||
{"tps65217", TPS65217},
|
||||
{ /* sentinel */ }
|
||||
|
|
@ -402,7 +430,6 @@ static struct i2c_driver tps65217_driver = {
|
|||
},
|
||||
.id_table = tps65217_id_table,
|
||||
.probe = tps65217_probe,
|
||||
.remove = tps65217_remove,
|
||||
};
|
||||
|
||||
static int __init tps65217_init(void)
|
||||
|
|
|
|||
|
|
@ -618,7 +618,7 @@ static void tps6586x_i2c_remove(struct i2c_client *client)
|
|||
free_irq(client->irq, tps6586x);
|
||||
}
|
||||
|
||||
static int __maybe_unused tps6586x_i2c_suspend(struct device *dev)
|
||||
static int tps6586x_i2c_suspend(struct device *dev)
|
||||
{
|
||||
struct tps6586x *tps6586x = dev_get_drvdata(dev);
|
||||
|
||||
|
|
@ -628,7 +628,7 @@ static int __maybe_unused tps6586x_i2c_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused tps6586x_i2c_resume(struct device *dev)
|
||||
static int tps6586x_i2c_resume(struct device *dev)
|
||||
{
|
||||
struct tps6586x *tps6586x = dev_get_drvdata(dev);
|
||||
|
||||
|
|
@ -638,7 +638,7 @@ static int __maybe_unused tps6586x_i2c_resume(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_i2c_suspend,
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(tps6586x_pm_ops, tps6586x_i2c_suspend,
|
||||
tps6586x_i2c_resume);
|
||||
|
||||
static const struct i2c_device_id tps6586x_id_table[] = {
|
||||
|
|
@ -651,7 +651,7 @@ static struct i2c_driver tps6586x_driver = {
|
|||
.driver = {
|
||||
.name = "tps6586x",
|
||||
.of_match_table = of_match_ptr(tps6586x_of_match),
|
||||
.pm = &tps6586x_pm_ops,
|
||||
.pm = pm_sleep_ptr(&tps6586x_pm_ops),
|
||||
},
|
||||
.probe = tps6586x_i2c_probe,
|
||||
.remove = tps6586x_i2c_remove,
|
||||
|
|
|
|||
|
|
@ -719,6 +719,11 @@ static const struct mfd_cell twl6032_cells[] = {
|
|||
{ .name = "twl6032-clk" },
|
||||
};
|
||||
|
||||
static void twl_unregister_device(void *data)
|
||||
{
|
||||
platform_device_unregister(data);
|
||||
}
|
||||
|
||||
/* NOTE: This driver only handles a single twl4030/tps659x0 chip */
|
||||
static int
|
||||
twl_probe(struct i2c_client *client)
|
||||
|
|
@ -754,17 +759,22 @@ twl_probe(struct i2c_client *client)
|
|||
return status;
|
||||
}
|
||||
|
||||
status = devm_add_action_or_reset(&client->dev, twl_unregister_device,
|
||||
pdev);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
dev_dbg(&client->dev, "can't talk I2C?\n");
|
||||
status = -EIO;
|
||||
goto free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
twl_priv = devm_kzalloc(&client->dev, sizeof(struct twl_private),
|
||||
GFP_KERNEL);
|
||||
if (!twl_priv) {
|
||||
status = -ENOMEM;
|
||||
goto free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((id->driver_data) & TWL6030_CLASS) {
|
||||
|
|
@ -784,7 +794,7 @@ twl_probe(struct i2c_client *client)
|
|||
GFP_KERNEL);
|
||||
if (!twl_priv->twl_modules) {
|
||||
status = -ENOMEM;
|
||||
goto free;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_slaves; i++) {
|
||||
|
|
@ -880,7 +890,7 @@ twl_probe(struct i2c_client *client)
|
|||
status = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
|
||||
cells, num_cells, NULL, 0, NULL);
|
||||
if (status < 0)
|
||||
goto free;
|
||||
goto out;
|
||||
|
||||
if (of_device_is_system_power_controller(node)) {
|
||||
if (!pm_power_off)
|
||||
|
|
@ -896,14 +906,11 @@ twl_probe(struct i2c_client *client)
|
|||
fail:
|
||||
if (status < 0)
|
||||
twl_remove(client);
|
||||
free:
|
||||
if (status < 0)
|
||||
platform_device_unregister(pdev);
|
||||
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int __maybe_unused twl_suspend(struct device *dev)
|
||||
static int twl_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
|
|
@ -913,7 +920,7 @@ static int __maybe_unused twl_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused twl_resume(struct device *dev)
|
||||
static int twl_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
|
|
@ -923,7 +930,7 @@ static int __maybe_unused twl_resume(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(twl_dev_pm_ops, twl_suspend, twl_resume);
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(twl_dev_pm_ops, twl_suspend, twl_resume);
|
||||
|
||||
static const struct i2c_device_id twl_ids[] = {
|
||||
{ "twl4030", TWL4030_VAUX2 }, /* "Triton 2" */
|
||||
|
|
@ -942,7 +949,7 @@ static const struct i2c_device_id twl_ids[] = {
|
|||
/* One Client Driver , 4 Clients */
|
||||
static struct i2c_driver twl_driver = {
|
||||
.driver.name = DRIVER_NAME,
|
||||
.driver.pm = &twl_dev_pm_ops,
|
||||
.driver.pm = pm_sleep_ptr(&twl_dev_pm_ops),
|
||||
.id_table = twl_ids,
|
||||
.probe = twl_probe,
|
||||
.remove = twl_remove,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Copyright (c) 2019, Linaro Limited
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
|
|
@ -217,13 +218,18 @@ static int wcd934x_slim_probe(struct slim_device *sdev)
|
|||
struct gpio_desc *reset_gpio;
|
||||
int ret;
|
||||
|
||||
ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to set DMA mask\n");
|
||||
|
||||
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
|
||||
if (!ddata)
|
||||
return -ENOMEM;
|
||||
|
||||
ddata->irq = of_irq_get(np, 0);
|
||||
if (ddata->irq < 0)
|
||||
return dev_err_probe(ddata->dev, ddata->irq,
|
||||
return dev_err_probe(dev, ddata->irq,
|
||||
"Failed to get IRQ\n");
|
||||
|
||||
ddata->extclk = devm_clk_get(dev, "extclk");
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data)
|
|||
1 << input, 0);
|
||||
wm831x->auxadc_active &= ~(1 << input);
|
||||
|
||||
/* Turn off the entire convertor if idle */
|
||||
/* Turn off the entire converter if idle */
|
||||
if (!wm831x->auxadc_active)
|
||||
wm831x_reg_write(wm831x, WM831X_AUXADC_CONTROL, 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -13,34 +13,33 @@
|
|||
#include <linux/regmap.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/minmax.h>
|
||||
|
||||
#define MAX_LEVEL 3
|
||||
#define MAX_LEVEL 5
|
||||
|
||||
struct khadas_mcu_fan_ctx {
|
||||
struct khadas_mcu *mcu;
|
||||
unsigned int fan_reg;
|
||||
unsigned int level;
|
||||
const unsigned int *levels;
|
||||
unsigned int nlevels;
|
||||
struct thermal_cooling_device *cdev;
|
||||
struct regulator *power;
|
||||
};
|
||||
|
||||
static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
|
||||
unsigned int level)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_write(ctx->mcu->regmap, KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
|
||||
level);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctx->level = level;
|
||||
|
||||
return 0;
|
||||
return regmap_write(ctx->mcu->regmap, ctx->fan_reg, level);
|
||||
}
|
||||
|
||||
static int khadas_mcu_fan_get_max_state(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
*state = MAX_LEVEL;
|
||||
struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
|
||||
|
||||
*state = min_t(unsigned int, MAX_LEVEL, ctx->nlevels - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -60,14 +59,21 @@ khadas_mcu_fan_set_cur_state(struct thermal_cooling_device *cdev,
|
|||
unsigned long state)
|
||||
{
|
||||
struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
|
||||
int ret;
|
||||
|
||||
if (state > MAX_LEVEL)
|
||||
if (state > MAX_LEVEL || state >= ctx->nlevels)
|
||||
return -EINVAL;
|
||||
|
||||
if (state == ctx->level)
|
||||
return 0;
|
||||
|
||||
return khadas_mcu_fan_set_level(ctx, state);
|
||||
ret = khadas_mcu_fan_set_level(ctx, ctx->levels[state]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctx->level = state;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct thermal_cooling_device_ops khadas_mcu_fan_cooling_ops = {
|
||||
|
|
@ -76,22 +82,71 @@ static const struct thermal_cooling_device_ops khadas_mcu_fan_cooling_ops = {
|
|||
.set_cur_state = khadas_mcu_fan_set_cur_state,
|
||||
};
|
||||
|
||||
static void khadas_mcu_fan_regulator_disable(void *data)
|
||||
{
|
||||
struct regulator *power = data;
|
||||
|
||||
regulator_disable(power);
|
||||
}
|
||||
|
||||
static const unsigned int khadas_mcu_fan_levels[] = { 0, 1, 2, 3 };
|
||||
|
||||
static const unsigned int khadas_mcu_vim4_fan_levels[] = { 0, 30, 40, 55, 75, 100 };
|
||||
|
||||
static int khadas_mcu_fan_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct platform_device_id *id = platform_get_device_id(pdev);
|
||||
struct khadas_mcu *mcu = dev_get_drvdata(pdev->dev.parent);
|
||||
struct thermal_cooling_device *cdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct khadas_mcu_fan_ctx *ctx;
|
||||
int ret;
|
||||
|
||||
|
||||
if (!dev->of_node)
|
||||
dev->of_node = of_node_get(dev->parent->of_node);
|
||||
|
||||
if (!id)
|
||||
return -EINVAL;
|
||||
|
||||
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->mcu = mcu;
|
||||
switch (id->driver_data) {
|
||||
case KHADAS_MCU_GENERIC:
|
||||
ctx->fan_reg = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG;
|
||||
ctx->levels = khadas_mcu_fan_levels;
|
||||
ctx->nlevels = ARRAY_SIZE(khadas_mcu_fan_levels);
|
||||
break;
|
||||
case KHADAS_MCU_VIM4:
|
||||
ctx->fan_reg = KHADAS_MCU_VIM4_FAN_CTRL_REG;
|
||||
ctx->levels = khadas_mcu_vim4_fan_levels;
|
||||
ctx->nlevels = ARRAY_SIZE(khadas_mcu_vim4_fan_levels);
|
||||
break;
|
||||
default:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ctx->power = devm_regulator_get(dev, "fan");
|
||||
if (IS_ERR(ctx->power))
|
||||
return PTR_ERR(ctx->power);
|
||||
|
||||
ret = regulator_enable(ctx->power);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to enable fan power supply: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_add_action_or_reset(dev, khadas_mcu_fan_regulator_disable, ctx->power);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, ctx);
|
||||
|
||||
cdev = devm_thermal_of_child_cooling_device_register(dev->parent,
|
||||
dev->parent->of_node,
|
||||
cdev = devm_thermal_of_child_cooling_device_register(dev,
|
||||
dev->of_node,
|
||||
"khadas-mcu-fan", ctx,
|
||||
&khadas_mcu_fan_cooling_ops);
|
||||
if (IS_ERR(cdev)) {
|
||||
|
|
@ -109,21 +164,24 @@ static void khadas_mcu_fan_shutdown(struct platform_device *pdev)
|
|||
{
|
||||
struct khadas_mcu_fan_ctx *ctx = platform_get_drvdata(pdev);
|
||||
|
||||
khadas_mcu_fan_set_level(ctx, 0);
|
||||
khadas_mcu_fan_set_level(ctx, ctx->levels[0]);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int khadas_mcu_fan_suspend(struct device *dev)
|
||||
{
|
||||
struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev);
|
||||
unsigned int level_save = ctx->level;
|
||||
int ret;
|
||||
|
||||
ret = khadas_mcu_fan_set_level(ctx, 0);
|
||||
ret = khadas_mcu_fan_set_level(ctx, ctx->levels[0]);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctx->level = level_save;
|
||||
ret = regulator_disable(ctx->power);
|
||||
if (ret) {
|
||||
khadas_mcu_fan_set_level(ctx, ctx->levels[ctx->level]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -131,8 +189,13 @@ static int khadas_mcu_fan_suspend(struct device *dev)
|
|||
static int khadas_mcu_fan_resume(struct device *dev)
|
||||
{
|
||||
struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
return khadas_mcu_fan_set_level(ctx, ctx->level);
|
||||
ret = regulator_enable(ctx->power);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return khadas_mcu_fan_set_level(ctx, ctx->levels[ctx->level]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -140,7 +203,8 @@ static SIMPLE_DEV_PM_OPS(khadas_mcu_fan_pm, khadas_mcu_fan_suspend,
|
|||
khadas_mcu_fan_resume);
|
||||
|
||||
static const struct platform_device_id khadas_mcu_fan_id_table[] = {
|
||||
{ .name = "khadas-mcu-fan-ctrl", },
|
||||
{ .name = "khadas-mcu-fan-ctrl", .driver_data = KHADAS_MCU_GENERIC },
|
||||
{ .name = "khadas-mcu-vim4-fan", .driver_data = KHADAS_MCU_VIM4 },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, khadas_mcu_fan_id_table);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,9 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/mfd/lm3533.h>
|
||||
|
|
@ -20,13 +22,21 @@
|
|||
#define LM3533_BL_MAX_BRIGHTNESS 255
|
||||
|
||||
#define LM3533_REG_CTRLBANK_AB_BCONF 0x1a
|
||||
#define CTRLBANK_AB_BCONF_ALS(n) BIT(2 * (n))
|
||||
#define CTRLBANK_AB_BCONF_MODE(n) BIT(2 * (n) + 1)
|
||||
|
||||
|
||||
struct lm3533_bl {
|
||||
struct lm3533 *lm3533;
|
||||
struct regmap *regmap;
|
||||
struct lm3533_ctrlbank cb;
|
||||
struct backlight_device *bd;
|
||||
int id;
|
||||
|
||||
u32 max_current;
|
||||
u32 pwm;
|
||||
|
||||
bool have_als;
|
||||
bool linear;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -45,7 +55,7 @@ static int lm3533_bl_update_status(struct backlight_device *bd)
|
|||
static int lm3533_bl_get_brightness(struct backlight_device *bd)
|
||||
{
|
||||
struct lm3533_bl *bl = bl_get_data(bd);
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_ctrlbank_get_brightness(&bl->cb, &val);
|
||||
|
|
@ -77,103 +87,75 @@ static ssize_t show_als_channel(struct device *dev,
|
|||
return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
|
||||
}
|
||||
|
||||
static ssize_t show_als_en(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t show_als_en(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct lm3533_bl *bl = dev_get_drvdata(dev);
|
||||
int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
|
||||
u8 val;
|
||||
u8 mask;
|
||||
bool enable;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_read(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, &val);
|
||||
if (ret)
|
||||
ret = regmap_test_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
|
||||
CTRLBANK_AB_BCONF_ALS(ctrlbank));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mask = 1 << (2 * ctrlbank);
|
||||
enable = val & mask;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
|
||||
return scnprintf(buf, PAGE_SIZE, "%d\n", ret);
|
||||
}
|
||||
|
||||
static ssize_t store_als_en(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
static ssize_t store_als_en(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
struct lm3533_bl *bl = dev_get_drvdata(dev);
|
||||
int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
|
||||
int enable;
|
||||
u8 val;
|
||||
u8 mask;
|
||||
int ret;
|
||||
|
||||
if (kstrtoint(buf, 0, &enable))
|
||||
return -EINVAL;
|
||||
|
||||
mask = 1 << (2 * ctrlbank);
|
||||
|
||||
if (enable)
|
||||
val = mask;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
ret = lm3533_update(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, val,
|
||||
mask);
|
||||
ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
|
||||
CTRLBANK_AB_BCONF_ALS(ctrlbank), enable);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t show_linear(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
static ssize_t show_linear(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct lm3533_bl *bl = dev_get_drvdata(dev);
|
||||
u8 val;
|
||||
u8 mask;
|
||||
int linear;
|
||||
int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
|
||||
int ret;
|
||||
|
||||
ret = lm3533_read(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, &val);
|
||||
if (ret)
|
||||
ret = regmap_test_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
|
||||
CTRLBANK_AB_BCONF_MODE(ctrlbank));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
mask = 1 << (2 * lm3533_bl_get_ctrlbank_id(bl) + 1);
|
||||
|
||||
if (val & mask)
|
||||
linear = 1;
|
||||
else
|
||||
linear = 0;
|
||||
|
||||
return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
|
||||
return scnprintf(buf, PAGE_SIZE, "%x\n", ret);
|
||||
}
|
||||
|
||||
static ssize_t store_linear(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
static ssize_t store_linear(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
struct lm3533_bl *bl = dev_get_drvdata(dev);
|
||||
int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
|
||||
struct backlight_device *bd = bl->bd;
|
||||
unsigned long linear;
|
||||
u8 mask;
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
if (kstrtoul(buf, 0, &linear))
|
||||
return -EINVAL;
|
||||
|
||||
mask = 1 << (2 * lm3533_bl_get_ctrlbank_id(bl) + 1);
|
||||
|
||||
if (linear)
|
||||
val = mask;
|
||||
else
|
||||
val = 0;
|
||||
|
||||
ret = lm3533_update(bl->lm3533, LM3533_REG_CTRLBANK_AB_BCONF, val,
|
||||
mask);
|
||||
ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
|
||||
CTRLBANK_AB_BCONF_MODE(ctrlbank), linear);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bd->props.scale = linear ? BACKLIGHT_SCALE_LINEAR :
|
||||
BACKLIGHT_SCALE_NON_LINEAR;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +164,7 @@ static ssize_t show_pwm(struct device *dev,
|
|||
char *buf)
|
||||
{
|
||||
struct lm3533_bl *bl = dev_get_drvdata(dev);
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = lm3533_ctrlbank_get_pwm(&bl->cb, &val);
|
||||
|
|
@ -197,10 +179,10 @@ static ssize_t store_pwm(struct device *dev,
|
|||
const char *buf, size_t len)
|
||||
{
|
||||
struct lm3533_bl *bl = dev_get_drvdata(dev);
|
||||
u8 val;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (kstrtou8(buf, 0, &val))
|
||||
if (kstrtou32(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
ret = lm3533_ctrlbank_set_pwm(&bl->cb, val);
|
||||
|
|
@ -234,7 +216,7 @@ static umode_t lm3533_bl_attr_is_visible(struct kobject *kobj,
|
|||
|
||||
if (attr == &dev_attr_als_channel.attr ||
|
||||
attr == &dev_attr_als_en.attr) {
|
||||
if (!bl->lm3533->have_als)
|
||||
if (!bl->have_als)
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
|
|
@ -246,25 +228,36 @@ static struct attribute_group lm3533_bl_attribute_group = {
|
|||
.attrs = lm3533_bl_attributes
|
||||
};
|
||||
|
||||
static int lm3533_bl_setup(struct lm3533_bl *bl,
|
||||
struct lm3533_bl_platform_data *pdata)
|
||||
static const struct attribute_group *lm3533_bl_attribute_groups[] = {
|
||||
&lm3533_bl_attribute_group,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int lm3533_bl_setup(struct lm3533_bl *bl)
|
||||
{
|
||||
int ctrlbank = lm3533_bl_get_ctrlbank_id(bl);
|
||||
int ret;
|
||||
|
||||
ret = lm3533_ctrlbank_set_max_current(&bl->cb, pdata->max_current);
|
||||
ret = regmap_assign_bits(bl->regmap, LM3533_REG_CTRLBANK_AB_BCONF,
|
||||
CTRLBANK_AB_BCONF_MODE(ctrlbank), bl->linear);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return lm3533_ctrlbank_set_pwm(&bl->cb, pdata->pwm);
|
||||
ret = lm3533_ctrlbank_set_max_current(&bl->cb, bl->max_current);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return lm3533_ctrlbank_set_pwm(&bl->cb, bl->pwm);
|
||||
}
|
||||
|
||||
static int lm3533_bl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct lm3533 *lm3533;
|
||||
struct lm3533_bl_platform_data *pdata;
|
||||
struct lm3533_bl *bl;
|
||||
struct backlight_device *bd;
|
||||
struct backlight_properties props;
|
||||
char *name = NULL;
|
||||
u32 default_brightness = LM3533_BL_MAX_BRIGHTNESS;
|
||||
int ret;
|
||||
|
||||
dev_dbg(&pdev->dev, "%s\n", __func__);
|
||||
|
|
@ -273,12 +266,6 @@ static int lm3533_bl_probe(struct platform_device *pdev)
|
|||
if (!lm3533)
|
||||
return -EINVAL;
|
||||
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pdev->id < 0 || pdev->id >= LM3533_HVCTRLBANK_COUNT) {
|
||||
dev_err(&pdev->dev, "illegal backlight id %d\n", pdev->id);
|
||||
return -EINVAL;
|
||||
|
|
@ -288,20 +275,34 @@ static int lm3533_bl_probe(struct platform_device *pdev)
|
|||
if (!bl)
|
||||
return -ENOMEM;
|
||||
|
||||
bl->lm3533 = lm3533;
|
||||
bl->regmap = lm3533->regmap;
|
||||
bl->have_als = lm3533->have_als;
|
||||
bl->id = pdev->id;
|
||||
|
||||
bl->cb.lm3533 = lm3533;
|
||||
bl->cb.regmap = lm3533->regmap;
|
||||
bl->cb.id = lm3533_bl_get_ctrlbank_id(bl);
|
||||
bl->cb.dev = NULL; /* until registered */
|
||||
|
||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s-%d",
|
||||
pdev->name, pdev->id);
|
||||
if (!name)
|
||||
return -ENOMEM;
|
||||
|
||||
device_property_read_u32(&pdev->dev, "default-brightness",
|
||||
&default_brightness);
|
||||
|
||||
memset(&props, 0, sizeof(props));
|
||||
props.type = BACKLIGHT_RAW;
|
||||
props.max_brightness = LM3533_BL_MAX_BRIGHTNESS;
|
||||
props.brightness = pdata->default_brightness;
|
||||
bd = devm_backlight_device_register(&pdev->dev, pdata->name,
|
||||
pdev->dev.parent, bl, &lm3533_bl_ops,
|
||||
&props);
|
||||
props.brightness = default_brightness;
|
||||
|
||||
bl->linear = device_property_read_bool(&pdev->dev,
|
||||
"ti,linear-mapping-mode");
|
||||
props.scale = bl->linear ? BACKLIGHT_SCALE_LINEAR :
|
||||
BACKLIGHT_SCALE_NON_LINEAR;
|
||||
|
||||
bd = devm_backlight_device_register(&pdev->dev, name, &pdev->dev,
|
||||
bl, &lm3533_bl_ops, &props);
|
||||
if (IS_ERR(bd)) {
|
||||
dev_err(&pdev->dev, "failed to register backlight device\n");
|
||||
return PTR_ERR(bd);
|
||||
|
|
@ -312,28 +313,24 @@ static int lm3533_bl_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, bl);
|
||||
|
||||
ret = sysfs_create_group(&bd->dev.kobj, &lm3533_bl_attribute_group);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to create sysfs attributes\n");
|
||||
device_property_read_u32(&pdev->dev, "led-max-microamp",
|
||||
&bl->max_current);
|
||||
bl->max_current = clamp(bl->max_current, LM3533_MAX_CURRENT_MIN,
|
||||
LM3533_MAX_CURRENT_MAX);
|
||||
|
||||
device_property_read_u32(&pdev->dev, "ti,pwm-config-mask", &bl->pwm);
|
||||
|
||||
ret = lm3533_bl_setup(bl);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
backlight_update_status(bd);
|
||||
|
||||
ret = lm3533_bl_setup(bl, pdata);
|
||||
if (ret)
|
||||
goto err_sysfs_remove;
|
||||
|
||||
ret = lm3533_ctrlbank_enable(&bl->cb);
|
||||
if (ret)
|
||||
goto err_sysfs_remove;
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
||||
err_sysfs_remove:
|
||||
sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lm3533_bl_remove(struct platform_device *pdev)
|
||||
|
|
@ -347,7 +344,6 @@ static void lm3533_bl_remove(struct platform_device *pdev)
|
|||
bd->props.brightness = 0;
|
||||
|
||||
lm3533_ctrlbank_disable(&bl->cb);
|
||||
sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
|
@ -381,10 +377,18 @@ static void lm3533_bl_shutdown(struct platform_device *pdev)
|
|||
lm3533_ctrlbank_disable(&bl->cb);
|
||||
}
|
||||
|
||||
static const struct of_device_id lm3533_bl_match_table[] = {
|
||||
{ .compatible = "ti,lm3533-backlight" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lm3533_bl_match_table);
|
||||
|
||||
static struct platform_driver lm3533_bl_driver = {
|
||||
.driver = {
|
||||
.name = "lm3533-backlight",
|
||||
.pm = &lm3533_bl_pm_ops,
|
||||
.dev_groups = lm3533_bl_attribute_groups,
|
||||
.of_match_table = lm3533_bl_match_table,
|
||||
},
|
||||
.probe = lm3533_bl_probe,
|
||||
.remove = lm3533_bl_remove,
|
||||
|
|
|
|||
|
|
@ -1183,6 +1183,7 @@
|
|||
|
||||
/* CS42L43B VARIANT REGISTERS */
|
||||
#define CS42L43B_DEVID_VAL 0x0042A43B
|
||||
#define CS42L44_DEVID_VAL 0x00042A44
|
||||
|
||||
#define CS42L43B_DECIM_VOL_CTRL_CH1_CH2 0x00008280
|
||||
#define CS42L43B_DECIM_VOL_CTRL_CH3_CH4 0x00008284
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#define DA9063_I2C_PAGE_SEL_SHIFT 1
|
||||
#define DA9063_EVENT_REG_NUM 4
|
||||
|
||||
/* Page selection I2C or SPI always in the begining of any page. */
|
||||
/* Page selection I2C or SPI always in the beginning of any page. */
|
||||
/* Page 0 : I2C access 0x000 - 0x0FF SPI access 0x000 - 0x07F */
|
||||
/* Page 1 : SPI access 0x080 - 0x0FF */
|
||||
/* Page 2 : I2C access 0x100 - 0x1FF SPI access 0x100 - 0x17F */
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ struct da9150 {
|
|||
struct regmap_irq_chip_data *regmap_irq_data;
|
||||
int irq;
|
||||
int irq_base;
|
||||
bool irq_wake_enabled;
|
||||
};
|
||||
|
||||
/* Device I/O - Query Interface for FG and standard register access */
|
||||
|
|
|
|||
|
|
@ -337,31 +337,31 @@ enum sia_mmdsp_stat {
|
|||
* @SYSCLKOK_ERR: The SYSCLK is not available in the given time
|
||||
* @BOOT_ERR: Romcode has not validated the XP70 self reset in the given time
|
||||
* @ROMCODESAVECONTEXT: The Romcode didn.t correctly save it secure context
|
||||
* @VARMHIGHSPEEDVALTO_ERR: The ARM high speed supply value transfered
|
||||
* @VARMHIGHSPEEDVALTO_ERR: The ARM high speed supply value transferred
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @VARMHIGHSPEEDACCESS_ERR: The command value of VarmHighSpeedVal transfered
|
||||
* @VARMHIGHSPEEDACCESS_ERR: The command value of VarmHighSpeedVal transferred
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @VARMLOWSPEEDVALTO_ERR:The ARM low speed supply value transfered through
|
||||
* @VARMLOWSPEEDVALTO_ERR:The ARM low speed supply value transferred through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VARMLOWSPEEDACCESS_ERR: The command value of VarmLowSpeedVal transfered
|
||||
* @VARMLOWSPEEDACCESS_ERR: The command value of VarmLowSpeedVal transferred
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @VARMRETENTIONVALTO_ERR: The ARM retention supply value transfered through
|
||||
* @VARMRETENTIONVALTO_ERR: The ARM retention supply value transferred through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VARMRETENTIONACCESS_ERR: The command value of VarmRetentionVal transfered
|
||||
* @VARMRETENTIONACCESS_ERR: The command value of VarmRetentionVal transferred
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @VAPEHIGHSPEEDVALTO_ERR: The APE highspeed supply value transfered through
|
||||
* @VAPEHIGHSPEEDVALTO_ERR: The APE highspeed supply value transferred through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VSAFEHPVALTO_ERR: The SAFE high power supply value transfered through I2C
|
||||
* @VSAFEHPVALTO_ERR: The SAFE high power supply value transferred through I2C
|
||||
* has not been correctly executed in the given time
|
||||
* @VMODSEL1VALTO_ERR: The MODEM sel1 supply value transfered through I2C has
|
||||
* @VMODSEL1VALTO_ERR: The MODEM sel1 supply value transferred through I2C has
|
||||
* not been correctly executed in the given time
|
||||
* @VMODSEL2VALTO_ERR: The MODEM sel2 supply value transfered through I2C has
|
||||
* @VMODSEL2VALTO_ERR: The MODEM sel2 supply value transferred through I2C has
|
||||
* not been correctly executed in the given time
|
||||
* @VARMOFFACCESS_ERR: The command value of Varm ON/OFF transfered through
|
||||
* @VARMOFFACCESS_ERR: The command value of Varm ON/OFF transferred through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VAPEOFFACCESS_ERR: The command value of Vape ON/OFF transfered through
|
||||
* @VAPEOFFACCESS_ERR: The command value of Vape ON/OFF transferred through
|
||||
* I2C has not been correctly executed in the given time
|
||||
* @VARMRETACCES_ERR: The command value of Varm retention ON/OFF transfered
|
||||
* @VARMRETACCES_ERR: The command value of Varm retention ON/OFF transferred
|
||||
* through I2C has not been correctly executed in the given time
|
||||
* @CURAPPWRSTISNOTBOOT:Generated when Arm want to do power state transition
|
||||
* ApBoot to ApExecute but the power current state is not Apboot
|
||||
|
|
@ -376,11 +376,11 @@ enum sia_mmdsp_stat {
|
|||
* been correctly executed in the given time
|
||||
* @ARMREGU2VALTO_ERR: The ArmRegu2 value transferred through I2C has not
|
||||
* been correctly executed in the given time
|
||||
* @VAPEREGUVALTO_ERR: The VApeRegu value transfered through I2C has not
|
||||
* @VAPEREGUVALTO_ERR: The VApeRegu value transferred through I2C has not
|
||||
* been correctly executed in the given time
|
||||
* @VSMPS3REGUVALTO_ERR: The VSmps3Regu value transfered through I2C has not
|
||||
* @VSMPS3REGUVALTO_ERR: The VSmps3Regu value transferred through I2C has not
|
||||
* been correctly executed in the given time
|
||||
* @VMODREGUVALTO_ERR: The VModemRegu value transfered through I2C has not
|
||||
* @VMODREGUVALTO_ERR: The VModemRegu value transferred through I2C has not
|
||||
* been correctly executed in the given time
|
||||
*/
|
||||
enum mbox_to_arm_err {
|
||||
|
|
|
|||
|
|
@ -70,6 +70,13 @@
|
|||
#define KHADAS_MCU_WOL_INIT_START_REG 0x87 /* WO */
|
||||
#define KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG 0x88 /* WO */
|
||||
|
||||
/* VIM4 specific registers */
|
||||
#define KHADAS_MCU_VIM4_REST_CONF_REG 0x2c /* WO - reset EEPROM */
|
||||
#define KHADAS_MCU_VIM4_LED_ON_RAM_REG 0x89 /* WO - LED volatile */
|
||||
#define KHADAS_MCU_VIM4_FAN_CTRL_REG 0x8a /* WO */
|
||||
#define KHADAS_MCU_VIM4_WDT_EN_REG 0x8b /* WO */
|
||||
#define KHADAS_MCU_VIM4_SYS_RST_REG 0x91 /* WO */
|
||||
|
||||
enum {
|
||||
KHADAS_BOARD_VIM1 = 0x1,
|
||||
KHADAS_BOARD_VIM2,
|
||||
|
|
@ -80,7 +87,7 @@ enum {
|
|||
|
||||
/**
|
||||
* struct khadas_mcu - Khadas MCU structure
|
||||
* @device: device reference used for logs
|
||||
* @dev: device reference used for logs
|
||||
* @regmap: register map
|
||||
*/
|
||||
struct khadas_mcu {
|
||||
|
|
@ -88,4 +95,14 @@ struct khadas_mcu {
|
|||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
/**
|
||||
* enum khadas_mcu_type - Khadas MCU hardware variant
|
||||
* @KHADAS_MCU_GENERIC: VIM1, VIM2, VIM3, Edge, Edge-V (shared register map)
|
||||
* @KHADAS_MCU_VIM4: VIM4 (extended register map, distinct fan/LED/WDT regs)
|
||||
*/
|
||||
enum khadas_mcu_type {
|
||||
KHADAS_MCU_GENERIC = 1,
|
||||
KHADAS_MCU_VIM4,
|
||||
};
|
||||
|
||||
#endif /* MFD_KHADAS_MCU_H */
|
||||
|
|
|
|||
|
|
@ -15,9 +15,14 @@
|
|||
#define LM3533_ATTR_RW(_name) \
|
||||
DEVICE_ATTR(_name, S_IRUGO | S_IWUSR , show_##_name, store_##_name)
|
||||
|
||||
#define LM3533_MAX_CURRENT_MIN 5000
|
||||
#define LM3533_MAX_CURRENT_MAX 29800
|
||||
#define LM3533_MAX_CURRENT_STEP 800
|
||||
|
||||
struct device;
|
||||
struct gpio_desc;
|
||||
struct regmap;
|
||||
struct regulator;
|
||||
|
||||
struct lm3533 {
|
||||
struct device *dev;
|
||||
|
|
@ -25,7 +30,10 @@ struct lm3533 {
|
|||
struct regmap *regmap;
|
||||
|
||||
struct gpio_desc *hwen;
|
||||
int irq;
|
||||
struct regulator *vin_supply;
|
||||
|
||||
u32 boost_ovp;
|
||||
u32 boost_freq;
|
||||
|
||||
unsigned have_als:1;
|
||||
unsigned have_backlights:1;
|
||||
|
|
@ -33,67 +41,18 @@ struct lm3533 {
|
|||
};
|
||||
|
||||
struct lm3533_ctrlbank {
|
||||
struct lm3533 *lm3533;
|
||||
struct regmap *regmap;
|
||||
struct device *dev;
|
||||
int id;
|
||||
};
|
||||
|
||||
struct lm3533_als_platform_data {
|
||||
unsigned pwm_mode:1; /* PWM input mode (default analog) */
|
||||
u8 r_select; /* 1 - 127 (ignored in PWM-mode) */
|
||||
};
|
||||
int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb);
|
||||
int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb);
|
||||
|
||||
struct lm3533_bl_platform_data {
|
||||
char *name;
|
||||
u16 max_current; /* 5000 - 29800 uA (800 uA step) */
|
||||
u8 default_brightness; /* 0 - 255 */
|
||||
u8 pwm; /* 0 - 0x3f */
|
||||
};
|
||||
|
||||
struct lm3533_led_platform_data {
|
||||
char *name;
|
||||
const char *default_trigger;
|
||||
u16 max_current; /* 5000 - 29800 uA (800 uA step) */
|
||||
u8 pwm; /* 0 - 0x3f */
|
||||
};
|
||||
|
||||
enum lm3533_boost_freq {
|
||||
LM3533_BOOST_FREQ_500KHZ,
|
||||
LM3533_BOOST_FREQ_1000KHZ,
|
||||
};
|
||||
|
||||
enum lm3533_boost_ovp {
|
||||
LM3533_BOOST_OVP_16V,
|
||||
LM3533_BOOST_OVP_24V,
|
||||
LM3533_BOOST_OVP_32V,
|
||||
LM3533_BOOST_OVP_40V,
|
||||
};
|
||||
|
||||
struct lm3533_platform_data {
|
||||
enum lm3533_boost_ovp boost_ovp;
|
||||
enum lm3533_boost_freq boost_freq;
|
||||
|
||||
struct lm3533_als_platform_data *als;
|
||||
|
||||
struct lm3533_bl_platform_data *backlights;
|
||||
int num_backlights;
|
||||
|
||||
struct lm3533_led_platform_data *leds;
|
||||
int num_leds;
|
||||
};
|
||||
|
||||
extern int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb);
|
||||
extern int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb);
|
||||
|
||||
extern int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val);
|
||||
extern int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val);
|
||||
extern int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb,
|
||||
u16 imax);
|
||||
extern int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val);
|
||||
extern int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val);
|
||||
|
||||
extern int lm3533_read(struct lm3533 *lm3533, u8 reg, u8 *val);
|
||||
extern int lm3533_write(struct lm3533 *lm3533, u8 reg, u8 val);
|
||||
extern int lm3533_update(struct lm3533 *lm3533, u8 reg, u8 val, u8 mask);
|
||||
int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u32 val);
|
||||
int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u32 *val);
|
||||
int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u32 imax);
|
||||
int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u32 val);
|
||||
int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u32 *val);
|
||||
|
||||
#endif /* __LINUX_MFD_LM3533_H */
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#define LP8788_ALM_IRQ "ALARM_IRQ"
|
||||
|
||||
enum lp8788_int_id {
|
||||
/* interrup register 1 : Addr 00h */
|
||||
/* interrupt register 1 : Addr 00h */
|
||||
LP8788_INT_TSDL,
|
||||
LP8788_INT_TSDH,
|
||||
LP8788_INT_UVLO,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ enum {
|
|||
/**
|
||||
* max8998_regulator_data - regulator data
|
||||
* @id: regulator id
|
||||
* @initdata: regulator init data (contraints, supplies, ...)
|
||||
* @initdata: regulator init data (constraints, supplies, ...)
|
||||
* @reg_node: DT node of regulator (unused on non-DT platforms)
|
||||
*/
|
||||
struct max8998_regulator_data {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,13 @@
|
|||
#define CPCAP_REVISION_2_0 0x10
|
||||
#define CPCAP_REVISION_2_1 0x11
|
||||
|
||||
enum cpcap_variant {
|
||||
CPCAP_DEFAULT = 1,
|
||||
CPCAP_MAPPHONE,
|
||||
CPCAP_MOT,
|
||||
CPCAP_MAX
|
||||
};
|
||||
|
||||
/* CPCAP registers */
|
||||
#define CPCAP_REG_INT1 0x0000 /* Interrupt 1 */
|
||||
#define CPCAP_REG_INT2 0x0004 /* Interrupt 2 */
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ enum tps65917_regulators {
|
|||
TPS65917_NUM_REGS,
|
||||
};
|
||||
|
||||
/* External controll signal name */
|
||||
/* External control signal name */
|
||||
enum {
|
||||
PALMAS_EXT_CONTROL_ENABLE1 = 0x1,
|
||||
PALMAS_EXT_CONTROL_ENABLE2 = 0x2,
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ enum {
|
|||
#define BD71828_REG_RTC_ALM2 0x63
|
||||
#define BD71828_REG_RTC_START BD71828_REG_RTC_SEC
|
||||
|
||||
/* Charger/Battey */
|
||||
/* Charger/Battery */
|
||||
#define BD71828_REG_CHG_STATE 0x65
|
||||
#define BD71828_REG_CHG_FULL 0xd2
|
||||
#define BD71828_REG_CHG_EN 0x6F
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ struct sec_platform_data {
|
|||
/**
|
||||
* sec_regulator_data - regulator data
|
||||
* @id: regulator id
|
||||
* @initdata: regulator init data (contraints, supplies, ...)
|
||||
* @initdata: regulator init data (constraints, supplies, ...)
|
||||
*/
|
||||
struct sec_regulator_data {
|
||||
int id;
|
||||
|
|
|
|||
|
|
@ -94,10 +94,10 @@ enum si476x_power_state {
|
|||
* of the @rds_fifo_drainer.
|
||||
* @rds_drainer_status_lock: Lock used to guard access to the
|
||||
* @rds_drainer_is_working variable.
|
||||
* @command: Wait queue for wainting on the command comapletion.
|
||||
* @command: Wait queue for waiting on the command completion.
|
||||
* @cts: Clear To Send flag set upon receiving first status with CTS
|
||||
* set.
|
||||
* @tuning: Wait queue used for wainting for tune/seek comand
|
||||
* @tuning: Wait queue used for waiting for tune/seek command
|
||||
* completion.
|
||||
* @stc: Similar to @cts, but for the STC bit of the status value.
|
||||
* @power_up_parameters: Parameters used as argument for POWER_UP
|
||||
|
|
|
|||
|
|
@ -739,7 +739,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base);
|
|||
#define TWL4030_REG_VUSB3V1 19
|
||||
|
||||
/* TWL6030 SMPS/LDO's */
|
||||
/* EXTERNAL dc-to-dc buck convertor controllable via SR */
|
||||
/* EXTERNAL dc-to-dc buck converter controllable via SR */
|
||||
#define TWL6030_REG_VDD1 30
|
||||
#define TWL6030_REG_VDD2 31
|
||||
#define TWL6030_REG_VDD3 32
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user