mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
- New Drivers
- Add support for Renesas RZ/G2L MTU3 - New Device Support - Add support for Lenovo Yoga Book X90F to Intel CHT WC - Add support for MAX5970 and MAX5978 to Simple MFD (I2C) - Add support for Meteor Lake PCH-S LPSS PCI to Intel LPSS PCI - Add support for AXP15060 PMIC to X-Powers PMIC collection - Remove Device Support - Remove support for Samsung 5M8751 and S5M8763 PMIC devices - New Functionality - Convert deprecated QCOM IRQ Chip to config registers - Add support for 32-bit address spaces to Renesas SMUs - Fix-ups - Make use of APIs / MACROs designed to simplify and demystify - Add / improve Device Tree bindings - Memory saving struct layout optimisations - Remove old / deprecated functionality - Factor out unassigned register addresses from ranges - Trivial: Spelling fixes, renames and coding style fixes - Rid 'defined but not used' warnings - Remove ineffective casts and pointer stubs - Bug Fixes - Fix incorrectly non-inverted mask/unmask IRQs on QCOM platforms - Remove MODULE_*() helpers from non-tristate drivers - Do not attempt to use out-of-range memory addresses associated with io_base - Provide missing export helpers - Fix remap bulk read optimisation fallout - Fix memory leak issues in error paths -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmRROFAACgkQUa+KL4f8 d2E9OxAAtG4Ac/I8Cp/VsTGGn5/pxxMnY/AWmdfkexp8bDQSvavKKQZ2wEwgFaTW GVaOIuWpG82fdoIAm1SkLs/gjPbXLnDJlxv8UcYa3kMQik/iiwrWl4zN2KBZqIIX qdg7fZNVAhi/qjue1YCHxKjMB80kK2LBTfwly+mbOXWMOBmoDh957oFuNBAa9W/A QxN9ckU/yVMjpeZQ1M97g/nUu+lKMypcCNHm1hklzqbchqgUiefdYS6t+g7zBgff zvwrlo+Tt0oIef95+TVmiVQBWJ+Cf8ssZphyL9I5dUH1Ft16BsNZYVvD1Eur1WGf N7szGDBZoqK5I6uUJ2t4+xiE4Mh1r+TIoCZuSwpDWS5IRKiWxTTZ9aDTXTKbnVKK Ov5SA3cdC2McXa0NCXB/47HzDTXhffH0SQ9x3JKlba2crSKt7LicVhjeflMOcHw+ HuTzg3imeMQriLVrVcvgce+YOcF3G/bFX9jvxnp8WFY+MLKuTYCGqoUfY6EF6r4i F0Y6DmYDBGX3rND+zvXDVMjS+RymYTSMtY9PKOXEdY1WU9E8GAHSKhrOCyCO3aIm PZRC2GAzGQ5fRCkyXusk0kxJqBBxu1My/wUQ9xRjdMKszFxEgVVFIY7KLwanY5vW 2akDnwOtu+37G9Qm4h2TpQdNLGTldZbbFcWrYGKzbNrVOjYw824= =EBtX -----END PGP SIGNATURE----- Merge tag 'mfd-next-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "New Drivers: - Add support for Renesas RZ/G2L MTU3 New Device Support: - Add support for Lenovo Yoga Book X90F to Intel CHT WC - Add support for MAX5970 and MAX5978 to Simple MFD (I2C) - Add support for Meteor Lake PCH-S LPSS PCI to Intel LPSS PCI - Add support for AXP15060 PMIC to X-Powers PMIC collection Remove Device Support: - Remove support for Samsung 5M8751 and S5M8763 PMIC devices New Functionality: - Convert deprecated QCOM IRQ Chip to config registers - Add support for 32-bit address spaces to Renesas SMUs Fix-ups: - Make use of APIs / MACROs designed to simplify and demystify - Add / improve Device Tree bindings - Memory saving struct layout optimisations - Remove old / deprecated functionality - Factor out unassigned register addresses from ranges - Trivial: Spelling fixes, renames and coding style fixes - Rid 'defined but not used' warnings - Remove ineffective casts and pointer stubs Bug Fixes: - Fix incorrectly non-inverted mask/unmask IRQs on QCOM platforms - Remove MODULE_*() helpers from non-tristate drivers - Do not attempt to use out-of-range memory addresses associated with io_base - Provide missing export helpers - Fix remap bulk read optimisation fallout - Fix memory leak issues in error paths" * tag 'mfd-next-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (88 commits) dt-bindings: mfd: ti,j721e-system-controller: Add SoC chip ID leds: bd2606mvv: Driver for the Rohm 6 Channel i2c LED driver dt-bindings: mfd: qcom,spmi-pmic: Document flash LED controller dt-bindings: mfd: x-powers,axp152: Document the AXP15060 variant mfd: axp20x: Add support for AXP15060 PMIC dt-bindings: mfd: x-powers,axp152: Document the AXP313a variant counter: rz-mtu3-cnt: Unlock on error in rz_mtu3_count_ceiling_write() dt-bindings: mfd: dlg,da9063: Document voltage monitoring dt-bindings: mfd: stm32: Remove unnecessary blank lines dt-bindings: mfd: qcom,spmi-pmic: Use generic ADC node name in examples dt-bindings: mfd: syscon: Add nuvoton,ma35d1-sys compatible MAINTAINERS: Add entries for Renesas RZ/G2L MTU3a counter driver counter: Add Renesas RZ/G2L MTU3a counter driver Documentation: ABI: sysfs-bus-counter: add cascade_counts_enable and external_input_phase_clock_select mfd: Add Renesas RZ/G2L MTU3a core driver dt-bindings: timer: Document RZ/G2L MTU3a bindings mfd: rsmu_i2c: Convert to i2c's .probe_new() again mfd: intel-lpss: Add Intel Meteor Lake PCH-S LPSS PCI IDs mfd: dln2: Fix memory leak in dln2_probe() mfd: axp20x: Fix axp288 writable-ranges ...
This commit is contained in:
commit
3af49062b0
@ -1,3 +1,33 @@
|
||||
What: /sys/bus/counter/devices/counterX/cascade_counts_enable
|
||||
KernelVersion: 6.4
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Indicates the cascading of Counts on Counter X.
|
||||
|
||||
Valid attribute values are boolean.
|
||||
|
||||
What: /sys/bus/counter/devices/counterX/external_input_phase_clock_select
|
||||
KernelVersion: 6.4
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Selects the external clock pin for phase counting mode of
|
||||
Counter X.
|
||||
|
||||
MTCLKA-MTCLKB:
|
||||
MTCLKA and MTCLKB pins are selected for the external
|
||||
phase clock.
|
||||
|
||||
MTCLKC-MTCLKD:
|
||||
MTCLKC and MTCLKD pins are selected for the external
|
||||
phase clock.
|
||||
|
||||
What: /sys/bus/counter/devices/counterX/external_input_phase_clock_select_available
|
||||
KernelVersion: 6.4
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
Discrete set of available values for the respective device
|
||||
configuration are listed in this file.
|
||||
|
||||
What: /sys/bus/counter/devices/counterX/countY/count
|
||||
KernelVersion: 5.2
|
||||
Contact: linux-iio@vger.kernel.org
|
||||
@ -215,6 +245,8 @@ Contact: linux-iio@vger.kernel.org
|
||||
Description:
|
||||
This attribute indicates the number of overflows of count Y.
|
||||
|
||||
What: /sys/bus/counter/devices/counterX/cascade_counts_enable_component_id
|
||||
What: /sys/bus/counter/devices/counterX/external_input_phase_clock_select_component_id
|
||||
What: /sys/bus/counter/devices/counterX/countY/capture_component_id
|
||||
What: /sys/bus/counter/devices/counterX/countY/ceiling_component_id
|
||||
What: /sys/bus/counter/devices/counterX/countY/floor_component_id
|
||||
|
@ -36,7 +36,7 @@ properties:
|
||||
clock-controller:
|
||||
# Child node
|
||||
type: object
|
||||
$ref: "../clock/canaan,k210-clk.yaml"
|
||||
$ref: ../clock/canaan,k210-clk.yaml
|
||||
description:
|
||||
Clock controller for the SoC clocks. This child node definition
|
||||
should follow the bindings specified in
|
||||
@ -45,7 +45,7 @@ properties:
|
||||
reset-controller:
|
||||
# Child node
|
||||
type: object
|
||||
$ref: "../reset/canaan,k210-rst.yaml"
|
||||
$ref: ../reset/canaan,k210-rst.yaml
|
||||
description:
|
||||
Reset controller for the SoC. This child node definition
|
||||
should follow the bindings specified in
|
||||
@ -54,7 +54,7 @@ properties:
|
||||
syscon-reboot:
|
||||
# Child node
|
||||
type: object
|
||||
$ref: "../power/reset/syscon-reboot.yaml"
|
||||
$ref: ../power/reset/syscon-reboot.yaml
|
||||
description:
|
||||
Reboot method for the SoC. This child node definition
|
||||
should follow the bindings specified in
|
||||
|
@ -65,7 +65,7 @@ properties:
|
||||
ARM Cortex M4 Co-processor. Contains the name of the rpmsg
|
||||
device. Used to match the subnode to the rpmsg device announced by
|
||||
the SCP.
|
||||
$ref: "/schemas/types.yaml#/definitions/string"
|
||||
$ref: /schemas/types.yaml#/definitions/string
|
||||
|
||||
spi-max-frequency: true
|
||||
|
||||
@ -94,23 +94,23 @@ properties:
|
||||
const: 0
|
||||
|
||||
typec:
|
||||
$ref: "/schemas/chrome/google,cros-ec-typec.yaml#"
|
||||
$ref: /schemas/chrome/google,cros-ec-typec.yaml#
|
||||
|
||||
ec-pwm:
|
||||
$ref: "/schemas/pwm/google,cros-ec-pwm.yaml#"
|
||||
$ref: /schemas/pwm/google,cros-ec-pwm.yaml#
|
||||
deprecated: true
|
||||
|
||||
pwm:
|
||||
$ref: "/schemas/pwm/google,cros-ec-pwm.yaml#"
|
||||
$ref: /schemas/pwm/google,cros-ec-pwm.yaml#
|
||||
|
||||
kbd-led-backlight:
|
||||
$ref: "/schemas/chrome/google,cros-kbd-led-backlight.yaml#"
|
||||
$ref: /schemas/chrome/google,cros-kbd-led-backlight.yaml#
|
||||
|
||||
keyboard-controller:
|
||||
$ref: "/schemas/input/google,cros-ec-keyb.yaml#"
|
||||
$ref: /schemas/input/google,cros-ec-keyb.yaml#
|
||||
|
||||
proximity:
|
||||
$ref: "/schemas/iio/proximity/google,cros-ec-mkbp-proximity.yaml#"
|
||||
$ref: /schemas/iio/proximity/google,cros-ec-mkbp-proximity.yaml#
|
||||
|
||||
codecs:
|
||||
type: object
|
||||
@ -126,7 +126,7 @@ properties:
|
||||
patternProperties:
|
||||
"^ec-codec@[a-f0-9]+$":
|
||||
type: object
|
||||
$ref: "/schemas/sound/google,cros-ec-codec.yaml#"
|
||||
$ref: /schemas/sound/google,cros-ec-codec.yaml#
|
||||
|
||||
required:
|
||||
- "#address-cells"
|
||||
@ -151,15 +151,15 @@ properties:
|
||||
patternProperties:
|
||||
"^i2c-tunnel[0-9]*$":
|
||||
type: object
|
||||
$ref: "/schemas/i2c/google,cros-ec-i2c-tunnel.yaml#"
|
||||
$ref: /schemas/i2c/google,cros-ec-i2c-tunnel.yaml#
|
||||
|
||||
"^regulator@[0-9]+$":
|
||||
type: object
|
||||
$ref: "/schemas/regulator/google,cros-ec-regulator.yaml#"
|
||||
$ref: /schemas/regulator/google,cros-ec-regulator.yaml#
|
||||
|
||||
"^extcon[0-9]*$":
|
||||
type: object
|
||||
$ref: "/schemas/extcon/extcon-usbc-cros-ec.yaml#"
|
||||
$ref: /schemas/extcon/extcon-usbc-cros-ec.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -53,7 +53,7 @@ properties:
|
||||
'^ldo[0-9]+$':
|
||||
type: object
|
||||
|
||||
$ref: "/schemas/regulator/regulator.yaml#"
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
|
151
Documentation/devicetree/bindings/mfd/maxim,max5970.yaml
Normal file
151
Documentation/devicetree/bindings/mfd/maxim,max5970.yaml
Normal file
@ -0,0 +1,151 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/maxim,max5970.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Regulator for MAX5970 Smart Switch from Maxim Integrated
|
||||
|
||||
maintainers:
|
||||
- Patrick Rudolph <patrick.rudolph@9elements.com>
|
||||
|
||||
description: |
|
||||
The smart switch provides no output regulation, but independent fault protection
|
||||
and voltage and current sensing.
|
||||
Programming is done through I2C bus.
|
||||
|
||||
Datasheets:
|
||||
https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf
|
||||
https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- maxim,max5970
|
||||
- maxim,max5978
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
leds:
|
||||
type: object
|
||||
description:
|
||||
Properties for four LEDS.
|
||||
|
||||
properties:
|
||||
"#address-cells":
|
||||
const: 1
|
||||
|
||||
"#size-cells":
|
||||
const: 0
|
||||
|
||||
patternProperties:
|
||||
"^led@[0-3]$":
|
||||
$ref: /schemas/leds/common.yaml#
|
||||
type: object
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
vss1-supply:
|
||||
description: Supply of the first channel.
|
||||
|
||||
vss2-supply:
|
||||
description: Supply of the second channel.
|
||||
|
||||
regulators:
|
||||
type: object
|
||||
description:
|
||||
Properties for both hot swap control/switch.
|
||||
|
||||
patternProperties:
|
||||
"^sw[0-1]$":
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
type: object
|
||||
properties:
|
||||
shunt-resistor-micro-ohms:
|
||||
description: |
|
||||
The value of current sense resistor in microohms.
|
||||
|
||||
required:
|
||||
- shunt-resistor-micro-ohms
|
||||
|
||||
unevaluatedProperties: false
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- regulators
|
||||
- vss1-supply
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- maxim,max5970
|
||||
then:
|
||||
required:
|
||||
- vss2-supply
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
regulator@3a {
|
||||
compatible = "maxim,max5978";
|
||||
reg = <0x3a>;
|
||||
vss1-supply = <&p3v3>;
|
||||
|
||||
regulators {
|
||||
sw0_ref_0: sw0 {
|
||||
shunt-resistor-micro-ohms = <12000>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
led@0 {
|
||||
reg = <0>;
|
||||
label = "led0";
|
||||
default-state = "on";
|
||||
};
|
||||
led@1 {
|
||||
reg = <1>;
|
||||
label = "led1";
|
||||
default-state = "on";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
- |
|
||||
i2c {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
regulator@3a {
|
||||
compatible = "maxim,max5970";
|
||||
reg = <0x3a>;
|
||||
vss1-supply = <&p3v3>;
|
||||
vss2-supply = <&p5v>;
|
||||
|
||||
regulators {
|
||||
sw0_ref_1: sw0 {
|
||||
shunt-resistor-micro-ohms = <12000>;
|
||||
};
|
||||
sw1_ref_1: sw1 {
|
||||
shunt-resistor-micro-ohms = <10000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
@ -33,6 +33,7 @@ properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- qcom,pm2250
|
||||
- qcom,pm6125
|
||||
- qcom,pm6150
|
||||
- qcom,pm6150l
|
||||
@ -78,6 +79,7 @@ properties:
|
||||
- qcom,pmk8350
|
||||
- qcom,pmk8550
|
||||
- qcom,pmm8155au
|
||||
- qcom,pmm8654au
|
||||
- qcom,pmp8074
|
||||
- qcom,pmr735a
|
||||
- qcom,pmr735b
|
||||
@ -115,6 +117,7 @@ patternProperties:
|
||||
type: object
|
||||
oneOf:
|
||||
- $ref: /schemas/iio/adc/qcom,spmi-iadc.yaml#
|
||||
- $ref: /schemas/iio/adc/qcom,spmi-rradc.yaml#
|
||||
- $ref: /schemas/iio/adc/qcom,spmi-vadc.yaml#
|
||||
|
||||
"^adc-tm@[0-9a-f]+$":
|
||||
@ -135,6 +138,14 @@ patternProperties:
|
||||
type: object
|
||||
$ref: /schemas/pinctrl/qcom,pmic-gpio.yaml#
|
||||
|
||||
"^led-controller@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/leds/qcom,spmi-flash-led.yaml#
|
||||
|
||||
"^nvram@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/nvmem/qcom,spmi-sdam.yaml#
|
||||
|
||||
"pon@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/power/reset/qcom,pon.yaml#
|
||||
@ -276,12 +287,12 @@ examples:
|
||||
#size-cells = <0>;
|
||||
#io-channel-cells = <1>;
|
||||
|
||||
adc-chan@6 {
|
||||
channel@6 {
|
||||
reg = <ADC5_DIE_TEMP>;
|
||||
label = "die_temp";
|
||||
};
|
||||
|
||||
adc-chan@4f {
|
||||
channel@4f {
|
||||
reg = <ADC5_AMUX_THM3_100K_PU>;
|
||||
qcom,ratiometric;
|
||||
qcom,hw-settle-time = <200>;
|
||||
|
@ -25,12 +25,16 @@ properties:
|
||||
- qcom,sc8280xp-tcsr
|
||||
- qcom,sdm630-tcsr
|
||||
- qcom,sdm845-tcsr
|
||||
- qcom,sdx55-tcsr
|
||||
- qcom,sdx65-tcsr
|
||||
- qcom,sm8150-tcsr
|
||||
- qcom,sm8450-tcsr
|
||||
- qcom,tcsr-apq8064
|
||||
- qcom,tcsr-apq8084
|
||||
- qcom,tcsr-ipq5332
|
||||
- qcom,tcsr-ipq6018
|
||||
- qcom,tcsr-ipq8064
|
||||
- qcom,tcsr-ipq9574
|
||||
- qcom,tcsr-mdm9615
|
||||
- qcom,tcsr-msm8226
|
||||
- qcom,tcsr-msm8660
|
||||
|
@ -49,7 +49,7 @@ patternProperties:
|
||||
|
||||
"rtc@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: "../rtc/qcom-pm8xxx-rtc.yaml"
|
||||
$ref: ../rtc/qcom-pm8xxx-rtc.yaml
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
@ -46,7 +46,7 @@ properties:
|
||||
|
||||
rohm,clkout-open-drain:
|
||||
description: clk32kout mode. Set to 1 for "open-drain" or 0 for "cmos".
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
|
||||
|
@ -46,7 +46,7 @@ properties:
|
||||
|
||||
rohm,clkout-open-drain:
|
||||
description: clk32kout mode. Set to 1 for "open-drain" or 0 for "cmos".
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32
|
||||
minimum: 0
|
||||
maximum: 1
|
||||
|
||||
|
@ -56,6 +56,7 @@ properties:
|
||||
- microchip,lan966x-cpu-syscon
|
||||
- microchip,sparx5-cpu-syscon
|
||||
- mstar,msc313-pmsleep
|
||||
- nuvoton,ma35d1-sys
|
||||
- nuvoton,wpcm450-shm
|
||||
- rockchip,px30-qos
|
||||
- rockchip,rk3036-qos
|
||||
@ -67,6 +68,7 @@ properties:
|
||||
- rockchip,rk3568-qos
|
||||
- rockchip,rk3588-qos
|
||||
- rockchip,rv1126-qos
|
||||
- starfive,jh7100-sysmain
|
||||
|
||||
- const: syscon
|
||||
|
||||
|
@ -62,6 +62,12 @@ patternProperties:
|
||||
description:
|
||||
The phy node corresponding to the ethernet MAC.
|
||||
|
||||
"^chipid@[0-9a-f]+$":
|
||||
type: object
|
||||
$ref: /schemas/hwinfo/ti,k3-socinfo.yaml#
|
||||
description:
|
||||
The node corresponding to SoC chip identification.
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
@ -99,5 +105,10 @@ examples:
|
||||
reg = <0x4140 0x18>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
chipid@14 {
|
||||
compatible = "ti,am654-chipid";
|
||||
reg = <0x14 0x4>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
51
Documentation/devicetree/bindings/mfd/ti,nspire-misc.yaml
Normal file
51
Documentation/devicetree/bindings/mfd/ti,nspire-misc.yaml
Normal file
@ -0,0 +1,51 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
# Copyright (C) 2022-2023 Texas Instruments Incorporated - https://www.ti.com/
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/mfd/ti,nspire-misc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI Nspire MISC hardware block
|
||||
|
||||
maintainers:
|
||||
- Andrew Davis <afd@ti.com>
|
||||
|
||||
description:
|
||||
System controller node represents a register region containing a set
|
||||
of miscellaneous registers. The registers are not cohesive enough to
|
||||
represent as any specific type of device. Currently there is a reset
|
||||
controller.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- ti,nspire-misc
|
||||
- const: syscon
|
||||
- const: simple-mfd
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
reboot:
|
||||
$ref: /schemas/power/reset/syscon-reboot.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reboot
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
misc: misc@900a0000 {
|
||||
compatible = "ti,nspire-misc", "syscon", "simple-mfd";
|
||||
reg = <0x900a0000 0x1000>;
|
||||
|
||||
reboot {
|
||||
compatible = "syscon-reboot";
|
||||
offset = <0x08>;
|
||||
value = <0x02>;
|
||||
};
|
||||
};
|
@ -156,7 +156,7 @@ properties:
|
||||
entry has a value that is out of range for a 16 bit register then the
|
||||
chip default will be used. If present exactly five values must be
|
||||
specified.
|
||||
$ref: "/schemas/types.yaml#/definitions/uint32-array"
|
||||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/mfd/x-powers,ac100.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
$id: http://devicetree.org/schemas/mfd/x-powers,ac100.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: X-Powers AC100
|
||||
|
||||
|
@ -47,9 +47,8 @@ allOf:
|
||||
- x-powers,axp209
|
||||
|
||||
then:
|
||||
not:
|
||||
required:
|
||||
- x-powers,drive-vbus-en
|
||||
properties:
|
||||
x-powers,drive-vbus-en: false
|
||||
|
||||
- if:
|
||||
not:
|
||||
@ -59,14 +58,9 @@ allOf:
|
||||
const: x-powers,axp806
|
||||
|
||||
then:
|
||||
allOf:
|
||||
- not:
|
||||
required:
|
||||
- x-powers,self-working-mode
|
||||
|
||||
- not:
|
||||
required:
|
||||
- x-powers,master-mode
|
||||
properties:
|
||||
x-powers,self-working-mode: false
|
||||
x-powers,master-mode: false
|
||||
|
||||
- if:
|
||||
not:
|
||||
@ -79,6 +73,18 @@ allOf:
|
||||
required:
|
||||
- interrupts
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- x-powers,axp313a
|
||||
- x-powers,axp15060
|
||||
|
||||
then:
|
||||
properties:
|
||||
x-powers,dcdc-freq: false
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
@ -88,10 +94,12 @@ properties:
|
||||
- x-powers,axp209
|
||||
- x-powers,axp221
|
||||
- x-powers,axp223
|
||||
- x-powers,axp313a
|
||||
- x-powers,axp803
|
||||
- x-powers,axp806
|
||||
- x-powers,axp809
|
||||
- x-powers,axp813
|
||||
- x-powers,axp15060
|
||||
- items:
|
||||
- const: x-powers,axp228
|
||||
- const: x-powers,axp221
|
||||
@ -260,7 +268,7 @@ properties:
|
||||
Defines the work frequency of DC-DC in kHz.
|
||||
|
||||
patternProperties:
|
||||
"^(([a-f])?ldo[0-9]|dcdc[0-7a-e]|ldo(_|-)io(0|1)|(dc1)?sw|rtc(_|-)ldo|drivevbus|dc5ldo)$":
|
||||
"^(([a-f])?ldo[0-9]|dcdc[0-7a-e]|ldo(_|-)io(0|1)|(dc1)?sw|rtc(_|-)ldo|cpusldo|drivevbus|dc5ldo)$":
|
||||
$ref: /schemas/regulator/regulator.yaml#
|
||||
type: object
|
||||
unevaluatedProperties: false
|
||||
|
@ -2,8 +2,8 @@
|
||||
# Copyright 2019 Bootlin
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/mfd/xylon,logicvc.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
$id: http://devicetree.org/schemas/mfd/xylon,logicvc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Xylon LogiCVC multi-function device
|
||||
|
||||
|
302
Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml
Normal file
302
Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml
Normal file
@ -0,0 +1,302 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/timer/renesas,rz-mtu3.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Renesas RZ/G2L Multi-Function Timer Pulse Unit 3 (MTU3a)
|
||||
|
||||
maintainers:
|
||||
- Biju Das <biju.das.jz@bp.renesas.com>
|
||||
|
||||
description: |
|
||||
This hardware block consists of eight 16-bit timer channels and one
|
||||
32- bit timer channel. It supports the following specifications:
|
||||
- Pulse input/output: 28 lines max.
|
||||
- Pulse input 3 lines
|
||||
- Count clock 11 clocks for each channel (14 clocks for MTU0, 12 clocks
|
||||
for MTU2, and 10 clocks for MTU5, four clocks for MTU1-MTU2 combination
|
||||
(when LWA = 1))
|
||||
- Operating frequency Up to 100 MHz
|
||||
- Available operations [MTU0 to MTU4, MTU6, MTU7, and MTU8]
|
||||
- Waveform output on compare match
|
||||
- Input capture function (noise filter setting available)
|
||||
- Counter-clearing operation
|
||||
- Simultaneous writing to multiple timer counters (TCNT)
|
||||
(excluding MTU8).
|
||||
- Simultaneous clearing on compare match or input capture
|
||||
(excluding MTU8).
|
||||
- Simultaneous input and output to registers in synchronization with
|
||||
counter operations (excluding MTU8).
|
||||
- Up to 12-phase PWM output in combination with synchronous operation
|
||||
(excluding MTU8)
|
||||
- [MTU0 MTU3, MTU4, MTU6, MTU7, and MTU8]
|
||||
- Buffer operation specifiable
|
||||
- [MTU1, MTU2]
|
||||
- Phase counting mode can be specified independently
|
||||
- 32-bit phase counting mode can be specified for interlocked operation
|
||||
of MTU1 and MTU2 (when TMDR3.LWA = 1)
|
||||
- Cascade connection operation available
|
||||
- [MTU3, MTU4, MTU6, and MTU7]
|
||||
- Through interlocked operation of MTU3/4 and MTU6/7, the positive and
|
||||
negative signals in six phases (12 phases in total) can be output in
|
||||
complementary PWM and reset-synchronized PWM operation.
|
||||
- In complementary PWM mode, values can be transferred from buffer
|
||||
registers to temporary registers at crests and troughs of the timer-
|
||||
counter values or when the buffer registers (TGRD registers in MTU4
|
||||
and MTU7) are written to.
|
||||
- Double-buffering selectable in complementary PWM mode.
|
||||
- [MTU3 and MTU4]
|
||||
- Through interlocking with MTU0, a mode for driving AC synchronous
|
||||
motors (brushless DC motors) by using complementary PWM output and
|
||||
reset-synchronized PWM output is settable and allows the selection
|
||||
of two types of waveform output (chopping or level).
|
||||
- [MTU5]
|
||||
- Capable of operation as a dead-time compensation counter.
|
||||
- [MTU0/MTU5, MTU1, MTU2, and MTU8]
|
||||
- 32-bit phase counting mode specifiable by combining MTU1 and MTU2 and
|
||||
through interlocked operation with MTU0/MTU5 and MTU8.
|
||||
- Interrupt-skipping function
|
||||
- In complementary PWM mode, interrupts on crests and troughs of counter
|
||||
values and triggers to start conversion by the A/D converter can be
|
||||
skipped.
|
||||
- Interrupt sources: 43 sources.
|
||||
- Buffer operation:
|
||||
- Automatic transfer of register data (transfer from the buffer
|
||||
register to the timer register).
|
||||
- Trigger generation
|
||||
- A/D converter start triggers can be generated
|
||||
- A/D converter start request delaying function enables A/D converter
|
||||
to be started with any desired timing and to be synchronized with
|
||||
PWM output.
|
||||
- Low power consumption function
|
||||
- The MTU3a can be placed in the module-stop state.
|
||||
|
||||
There are two phase counting modes. 16-bit phase counting mode in which
|
||||
MTU1 and MTU2 operate independently, and cascade connection 32-bit phase
|
||||
counting mode in which MTU1 and MTU2 are cascaded.
|
||||
|
||||
In phase counting mode, the phase difference between two external input
|
||||
clocks is detected and the corresponding TCNT is incremented or
|
||||
decremented.
|
||||
The below counters are supported
|
||||
count0 - MTU1 16-bit phase counting
|
||||
count1 - MTU2 16-bit phase counting
|
||||
count2 - MTU1+ MTU2 32-bit phase counting
|
||||
|
||||
The module supports PWM mode{1,2}, Reset-synchronized PWM mode and
|
||||
complementary PWM mode{1,2,3}.
|
||||
|
||||
In complementary PWM mode, six positive-phase and six negative-phase PWM
|
||||
waveforms (12 phases in total) with dead time can be output by
|
||||
combining MTU{3,4} and MTU{6,7}.
|
||||
|
||||
The below pwm channels are supported in pwm mode 1.
|
||||
pwm0 - MTU0.MTIOC0A PWM mode 1
|
||||
pwm1 - MTU0.MTIOC0C PWM mode 1
|
||||
pwm2 - MTU1.MTIOC1A PWM mode 1
|
||||
pwm3 - MTU2.MTIOC2A PWM mode 1
|
||||
pwm4 - MTU3.MTIOC3A PWM mode 1
|
||||
pwm5 - MTU3.MTIOC3C PWM mode 1
|
||||
pwm6 - MTU4.MTIOC4A PWM mode 1
|
||||
pwm7 - MTU4.MTIOC4C PWM mode 1
|
||||
pwm8 - MTU6.MTIOC6A PWM mode 1
|
||||
pwm9 - MTU6.MTIOC6C PWM mode 1
|
||||
pwm10 - MTU7.MTIOC7A PWM mode 1
|
||||
pwm11 - MTU7.MTIOC7C PWM mode 1
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- renesas,r9a07g044-mtu3 # RZ/G2{L,LC}
|
||||
- renesas,r9a07g054-mtu3 # RZ/V2L
|
||||
- const: renesas,rz-mtu3
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: MTU0.TGRA input capture/compare match
|
||||
- description: MTU0.TGRB input capture/compare match
|
||||
- description: MTU0.TGRC input capture/compare match
|
||||
- description: MTU0.TGRD input capture/compare match
|
||||
- description: MTU0.TCNT overflow
|
||||
- description: MTU0.TGRE compare match
|
||||
- description: MTU0.TGRF compare match
|
||||
- description: MTU1.TGRA input capture/compare match
|
||||
- description: MTU1.TGRB input capture/compare match
|
||||
- description: MTU1.TCNT overflow
|
||||
- description: MTU1.TCNT underflow
|
||||
- description: MTU2.TGRA input capture/compare match
|
||||
- description: MTU2.TGRB input capture/compare match
|
||||
- description: MTU2.TCNT overflow
|
||||
- description: MTU2.TCNT underflow
|
||||
- description: MTU3.TGRA input capture/compare match
|
||||
- description: MTU3.TGRB input capture/compare match
|
||||
- description: MTU3.TGRC input capture/compare match
|
||||
- description: MTU3.TGRD input capture/compare match
|
||||
- description: MTU3.TCNT overflow
|
||||
- description: MTU4.TGRA input capture/compare match
|
||||
- description: MTU4.TGRB input capture/compare match
|
||||
- description: MTU4.TGRC input capture/compare match
|
||||
- description: MTU4.TGRD input capture/compare match
|
||||
- description: MTU4.TCNT overflow/underflow
|
||||
- description: MTU5.TGRU input capture/compare match
|
||||
- description: MTU5.TGRV input capture/compare match
|
||||
- description: MTU5.TGRW input capture/compare match
|
||||
- description: MTU6.TGRA input capture/compare match
|
||||
- description: MTU6.TGRB input capture/compare match
|
||||
- description: MTU6.TGRC input capture/compare match
|
||||
- description: MTU6.TGRD input capture/compare match
|
||||
- description: MTU6.TCNT overflow
|
||||
- description: MTU7.TGRA input capture/compare match
|
||||
- description: MTU7.TGRB input capture/compare match
|
||||
- description: MTU7.TGRC input capture/compare match
|
||||
- description: MTU7.TGRD input capture/compare match
|
||||
- description: MTU7.TCNT overflow/underflow
|
||||
- description: MTU8.TGRA input capture/compare match
|
||||
- description: MTU8.TGRB input capture/compare match
|
||||
- description: MTU8.TGRC input capture/compare match
|
||||
- description: MTU8.TGRD input capture/compare match
|
||||
- description: MTU8.TCNT overflow
|
||||
- description: MTU8.TCNT underflow
|
||||
|
||||
interrupt-names:
|
||||
items:
|
||||
- const: tgia0
|
||||
- const: tgib0
|
||||
- const: tgic0
|
||||
- const: tgid0
|
||||
- const: tgiv0
|
||||
- const: tgie0
|
||||
- const: tgif0
|
||||
- const: tgia1
|
||||
- const: tgib1
|
||||
- const: tgiv1
|
||||
- const: tgiu1
|
||||
- const: tgia2
|
||||
- const: tgib2
|
||||
- const: tgiv2
|
||||
- const: tgiu2
|
||||
- const: tgia3
|
||||
- const: tgib3
|
||||
- const: tgic3
|
||||
- const: tgid3
|
||||
- const: tgiv3
|
||||
- const: tgia4
|
||||
- const: tgib4
|
||||
- const: tgic4
|
||||
- const: tgid4
|
||||
- const: tgiv4
|
||||
- const: tgiu5
|
||||
- const: tgiv5
|
||||
- const: tgiw5
|
||||
- const: tgia6
|
||||
- const: tgib6
|
||||
- const: tgic6
|
||||
- const: tgid6
|
||||
- const: tgiv6
|
||||
- const: tgia7
|
||||
- const: tgib7
|
||||
- const: tgic7
|
||||
- const: tgid7
|
||||
- const: tgiv7
|
||||
- const: tgia8
|
||||
- const: tgib8
|
||||
- const: tgic8
|
||||
- const: tgid8
|
||||
- const: tgiv8
|
||||
- const: tgiu8
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
"#pwm-cells":
|
||||
const: 2
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- interrupt-names
|
||||
- clocks
|
||||
- power-domains
|
||||
- resets
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r9a07g044-cpg.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
mtu3: timer@10001200 {
|
||||
compatible = "renesas,r9a07g044-mtu3", "renesas,rz-mtu3";
|
||||
reg = <0x10001200 0xb00>;
|
||||
interrupts = <GIC_SPI 170 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 171 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 172 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 173 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 174 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 175 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 176 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 177 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 178 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 179 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 180 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 181 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 182 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 183 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 184 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 185 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 186 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 187 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 188 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 189 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 190 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 191 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 192 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 193 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 194 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 195 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 196 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 197 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 198 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 199 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 200 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 201 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 202 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 203 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 204 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 205 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 206 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 207 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 208 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 210 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 211 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 212 IRQ_TYPE_EDGE_RISING>,
|
||||
<GIC_SPI 213 IRQ_TYPE_EDGE_RISING>;
|
||||
interrupt-names = "tgia0", "tgib0", "tgic0", "tgid0", "tgiv0", "tgie0",
|
||||
"tgif0",
|
||||
"tgia1", "tgib1", "tgiv1", "tgiu1",
|
||||
"tgia2", "tgib2", "tgiv2", "tgiu2",
|
||||
"tgia3", "tgib3", "tgic3", "tgid3", "tgiv3",
|
||||
"tgia4", "tgib4", "tgic4", "tgid4", "tgiv4",
|
||||
"tgiu5", "tgiv5", "tgiw5",
|
||||
"tgia6", "tgib6", "tgic6", "tgid6", "tgiv6",
|
||||
"tgia7", "tgib7", "tgic7", "tgid7", "tgiv7",
|
||||
"tgia8", "tgib8", "tgic8", "tgid8", "tgiv8", "tgiu8";
|
||||
clocks = <&cpg CPG_MOD R9A07G044_MTU_X_MCK_MTU3>;
|
||||
power-domains = <&cpg>;
|
||||
resets = <&cpg R9A07G044_MTU_X_PRESET_MTU3>;
|
||||
#pwm-cells = <2>;
|
||||
};
|
@ -17972,6 +17972,14 @@ S: Supported
|
||||
F: Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml
|
||||
F: drivers/iio/adc/rzg2l_adc.c
|
||||
|
||||
RENESAS RZ/G2L MTU3a COUNTER DRIVER
|
||||
M: Biju Das <biju.das.jz@bp.renesas.com>
|
||||
L: linux-iio@vger.kernel.org
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml
|
||||
F: drivers/counter/rz-mtu3-cnt.c
|
||||
|
||||
RENESAS RZ/N1 A5PSW SWITCH DRIVER
|
||||
M: Clément Léger <clement.leger@bootlin.com>
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
|
@ -73,6 +73,17 @@ config MICROCHIP_TCB_CAPTURE
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called microchip-tcb-capture.
|
||||
|
||||
config RZ_MTU3_CNT
|
||||
tristate "Renesas RZ/G2L MTU3a counter driver"
|
||||
depends on RZ_MTU3 || COMPILE_TEST
|
||||
help
|
||||
Enable support for MTU3a counter driver found on Renesas RZ/G2L alike
|
||||
SoCs. This IP supports both 16-bit and 32-bit phase counting mode
|
||||
support.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called rz-mtu3-cnt.
|
||||
|
||||
config STM32_LPTIMER_CNT
|
||||
tristate "STM32 LP Timer encoder counter driver"
|
||||
depends on MFD_STM32_LPTIMER || COMPILE_TEST
|
||||
|
@ -8,6 +8,7 @@ counter-y := counter-core.o counter-sysfs.o counter-chrdev.o
|
||||
|
||||
obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o
|
||||
obj-$(CONFIG_INTERRUPT_CNT) += interrupt-cnt.o
|
||||
obj-$(CONFIG_RZ_MTU3_CNT) += rz-mtu3-cnt.o
|
||||
obj-$(CONFIG_STM32_TIMER_CNT) += stm32-timer-cnt.o
|
||||
obj-$(CONFIG_STM32_LPTIMER_CNT) += stm32-lptimer-cnt.o
|
||||
obj-$(CONFIG_TI_EQEP) += ti-eqep.o
|
||||
|
906
drivers/counter/rz-mtu3-cnt.c
Normal file
906
drivers/counter/rz-mtu3-cnt.c
Normal file
@ -0,0 +1,906 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Renesas RZ/G2L MTU3a Counter driver
|
||||
*
|
||||
* Copyright (C) 2022 Renesas Electronics Corporation
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/counter.h>
|
||||
#include <linux/mfd/rz-mtu3.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* Register descriptions
|
||||
* TSR: Timer Status Register
|
||||
* TMDR1: Timer Mode Register 1
|
||||
* TMDR3: Timer Mode Register 3
|
||||
* TIOR: Timer I/O Control Register
|
||||
* TCR: Timer Control Register
|
||||
* TCNT: Timer Counter
|
||||
* TGRA: Timer general register A
|
||||
* TCNTLW: Timer Longword Counter
|
||||
* TGRALW: Timer longword general register A
|
||||
*/
|
||||
|
||||
#define RZ_MTU3_TSR_TCFD BIT(7) /* Count Direction Flag */
|
||||
|
||||
#define RZ_MTU3_TMDR1_PH_CNT_MODE_1 (4) /* Phase counting mode 1 */
|
||||
#define RZ_MTU3_TMDR1_PH_CNT_MODE_2 (5) /* Phase counting mode 2 */
|
||||
#define RZ_MTU3_TMDR1_PH_CNT_MODE_3 (6) /* Phase counting mode 3 */
|
||||
#define RZ_MTU3_TMDR1_PH_CNT_MODE_4 (7) /* Phase counting mode 4 */
|
||||
#define RZ_MTU3_TMDR1_PH_CNT_MODE_5 (9) /* Phase counting mode 5 */
|
||||
#define RZ_MTU3_TMDR1_PH_CNT_MODE_MASK (0xf)
|
||||
|
||||
/*
|
||||
* LWA: MTU1/MTU2 Combination Longword Access Control
|
||||
* 0: 16-bit, 1: 32-bit
|
||||
*/
|
||||
#define RZ_MTU3_TMDR3_LWA (0)
|
||||
|
||||
/*
|
||||
* PHCKSEL: External Input Phase Clock Select
|
||||
* 0: MTCLKA and MTCLKB, 1: MTCLKC and MTCLKD
|
||||
*/
|
||||
#define RZ_MTU3_TMDR3_PHCKSEL (1)
|
||||
|
||||
#define RZ_MTU3_16_BIT_MTU1_CH (0)
|
||||
#define RZ_MTU3_16_BIT_MTU2_CH (1)
|
||||
#define RZ_MTU3_32_BIT_CH (2)
|
||||
|
||||
#define RZ_MTU3_TIOR_NO_OUTPUT (0) /* Output prohibited */
|
||||
#define RZ_MTU3_TIOR_IC_BOTH (10) /* Input capture at both edges */
|
||||
|
||||
#define SIGNAL_A_ID (0)
|
||||
#define SIGNAL_B_ID (1)
|
||||
#define SIGNAL_C_ID (2)
|
||||
#define SIGNAL_D_ID (3)
|
||||
|
||||
#define RZ_MTU3_MAX_HW_CNTR_CHANNELS (2)
|
||||
#define RZ_MTU3_MAX_LOGICAL_CNTR_CHANNELS (3)
|
||||
|
||||
/**
|
||||
* struct rz_mtu3_cnt - MTU3 counter private data
|
||||
*
|
||||
* @clk: MTU3 module clock
|
||||
* @lock: Lock to prevent concurrent access for ceiling and count
|
||||
* @ch: HW channels for the counters
|
||||
* @count_is_enabled: Enabled state of Counter value channel
|
||||
* @mtu_16bit_max: Cache for 16-bit counters
|
||||
* @mtu_32bit_max: Cache for 32-bit counters
|
||||
*/
|
||||
struct rz_mtu3_cnt {
|
||||
struct clk *clk;
|
||||
struct mutex lock;
|
||||
struct rz_mtu3_channel *ch;
|
||||
bool count_is_enabled[RZ_MTU3_MAX_LOGICAL_CNTR_CHANNELS];
|
||||
union {
|
||||
u16 mtu_16bit_max[RZ_MTU3_MAX_HW_CNTR_CHANNELS];
|
||||
u32 mtu_32bit_max;
|
||||
};
|
||||
};
|
||||
|
||||
static const enum counter_function rz_mtu3_count_functions[] = {
|
||||
COUNTER_FUNCTION_QUADRATURE_X4,
|
||||
COUNTER_FUNCTION_PULSE_DIRECTION,
|
||||
COUNTER_FUNCTION_QUADRATURE_X2_B,
|
||||
};
|
||||
|
||||
static inline size_t rz_mtu3_get_hw_ch(const size_t id)
|
||||
{
|
||||
return (id == RZ_MTU3_32_BIT_CH) ? 0 : id;
|
||||
}
|
||||
|
||||
static inline struct rz_mtu3_channel *rz_mtu3_get_ch(struct counter_device *counter, int id)
|
||||
{
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
const size_t ch_id = rz_mtu3_get_hw_ch(id);
|
||||
|
||||
return &priv->ch[ch_id];
|
||||
}
|
||||
|
||||
static bool rz_mtu3_is_counter_invalid(struct counter_device *counter, int id)
|
||||
{
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
unsigned long tmdr;
|
||||
|
||||
pm_runtime_get_sync(priv->ch->dev);
|
||||
tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
|
||||
pm_runtime_put(priv->ch->dev);
|
||||
|
||||
if (id == RZ_MTU3_32_BIT_CH && test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
|
||||
return false;
|
||||
|
||||
if (id != RZ_MTU3_32_BIT_CH && !test_bit(RZ_MTU3_TMDR3_LWA, &tmdr))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int rz_mtu3_lock_if_counter_is_valid(struct counter_device *counter,
|
||||
struct rz_mtu3_channel *const ch,
|
||||
struct rz_mtu3_cnt *const priv,
|
||||
int id)
|
||||
{
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
if (ch->is_busy && !priv->count_is_enabled[id]) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rz_mtu3_is_counter_invalid(counter, id)) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_lock_if_count_is_enabled(struct rz_mtu3_channel *const ch,
|
||||
struct rz_mtu3_cnt *const priv,
|
||||
int id)
|
||||
{
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
if (ch->is_busy && !priv->count_is_enabled[id]) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_read(struct counter_device *counter,
|
||||
struct counter_count *count, u64 *val)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, count->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_get_sync(ch->dev);
|
||||
if (count->id == RZ_MTU3_32_BIT_CH)
|
||||
*val = rz_mtu3_32bit_ch_read(ch, RZ_MTU3_TCNTLW);
|
||||
else
|
||||
*val = rz_mtu3_16bit_ch_read(ch, RZ_MTU3_TCNT);
|
||||
pm_runtime_put(ch->dev);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_write(struct counter_device *counter,
|
||||
struct counter_count *count, const u64 val)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, count->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_get_sync(ch->dev);
|
||||
if (count->id == RZ_MTU3_32_BIT_CH)
|
||||
rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TCNTLW, val);
|
||||
else
|
||||
rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TCNT, val);
|
||||
pm_runtime_put(ch->dev);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_function_read_helper(struct rz_mtu3_channel *const ch,
|
||||
struct rz_mtu3_cnt *const priv,
|
||||
enum counter_function *function)
|
||||
{
|
||||
u8 timer_mode;
|
||||
|
||||
pm_runtime_get_sync(ch->dev);
|
||||
timer_mode = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TMDR1);
|
||||
pm_runtime_put(ch->dev);
|
||||
|
||||
switch (timer_mode & RZ_MTU3_TMDR1_PH_CNT_MODE_MASK) {
|
||||
case RZ_MTU3_TMDR1_PH_CNT_MODE_1:
|
||||
*function = COUNTER_FUNCTION_QUADRATURE_X4;
|
||||
return 0;
|
||||
case RZ_MTU3_TMDR1_PH_CNT_MODE_2:
|
||||
*function = COUNTER_FUNCTION_PULSE_DIRECTION;
|
||||
return 0;
|
||||
case RZ_MTU3_TMDR1_PH_CNT_MODE_4:
|
||||
*function = COUNTER_FUNCTION_QUADRATURE_X2_B;
|
||||
return 0;
|
||||
default:
|
||||
/*
|
||||
* TODO:
|
||||
* - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_3
|
||||
* - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_5
|
||||
*/
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_function_read(struct counter_device *counter,
|
||||
struct counter_count *count,
|
||||
enum counter_function *function)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rz_mtu3_count_function_read_helper(ch, priv, function);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_function_write(struct counter_device *counter,
|
||||
struct counter_count *count,
|
||||
enum counter_function function)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
u8 timer_mode;
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (function) {
|
||||
case COUNTER_FUNCTION_QUADRATURE_X4:
|
||||
timer_mode = RZ_MTU3_TMDR1_PH_CNT_MODE_1;
|
||||
break;
|
||||
case COUNTER_FUNCTION_PULSE_DIRECTION:
|
||||
timer_mode = RZ_MTU3_TMDR1_PH_CNT_MODE_2;
|
||||
break;
|
||||
case COUNTER_FUNCTION_QUADRATURE_X2_B:
|
||||
timer_mode = RZ_MTU3_TMDR1_PH_CNT_MODE_4;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* TODO:
|
||||
* - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_3
|
||||
* - need to add RZ_MTU3_TMDR1_PH_CNT_MODE_5
|
||||
*/
|
||||
mutex_unlock(&priv->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pm_runtime_get_sync(ch->dev);
|
||||
rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, timer_mode);
|
||||
pm_runtime_put(ch->dev);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_direction_read(struct counter_device *counter,
|
||||
struct counter_count *count,
|
||||
enum counter_count_direction *direction)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
int ret;
|
||||
u8 tsr;
|
||||
|
||||
ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_get_sync(ch->dev);
|
||||
tsr = rz_mtu3_8bit_ch_read(ch, RZ_MTU3_TSR);
|
||||
pm_runtime_put(ch->dev);
|
||||
|
||||
*direction = (tsr & RZ_MTU3_TSR_TCFD) ?
|
||||
COUNTER_COUNT_DIRECTION_FORWARD : COUNTER_COUNT_DIRECTION_BACKWARD;
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_ceiling_read(struct counter_device *counter,
|
||||
struct counter_count *count,
|
||||
u64 *ceiling)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
const size_t ch_id = rz_mtu3_get_hw_ch(count->id);
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, count->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (count->id) {
|
||||
case RZ_MTU3_16_BIT_MTU1_CH:
|
||||
case RZ_MTU3_16_BIT_MTU2_CH:
|
||||
*ceiling = priv->mtu_16bit_max[ch_id];
|
||||
break;
|
||||
case RZ_MTU3_32_BIT_CH:
|
||||
*ceiling = priv->mtu_32bit_max;
|
||||
break;
|
||||
default:
|
||||
/* should never reach this path */
|
||||
mutex_unlock(&priv->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_ceiling_write(struct counter_device *counter,
|
||||
struct counter_count *count,
|
||||
u64 ceiling)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
const size_t ch_id = rz_mtu3_get_hw_ch(count->id);
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_counter_is_valid(counter, ch, priv, count->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (count->id) {
|
||||
case RZ_MTU3_16_BIT_MTU1_CH:
|
||||
case RZ_MTU3_16_BIT_MTU2_CH:
|
||||
if (ceiling > U16_MAX) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return -ERANGE;
|
||||
}
|
||||
priv->mtu_16bit_max[ch_id] = ceiling;
|
||||
break;
|
||||
case RZ_MTU3_32_BIT_CH:
|
||||
if (ceiling > U32_MAX) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return -ERANGE;
|
||||
}
|
||||
priv->mtu_32bit_max = ceiling;
|
||||
break;
|
||||
default:
|
||||
/* should never reach this path */
|
||||
mutex_unlock(&priv->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pm_runtime_get_sync(ch->dev);
|
||||
if (count->id == RZ_MTU3_32_BIT_CH)
|
||||
rz_mtu3_32bit_ch_write(ch, RZ_MTU3_TGRALW, ceiling);
|
||||
else
|
||||
rz_mtu3_16bit_ch_write(ch, RZ_MTU3_TGRA, ceiling);
|
||||
|
||||
rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA);
|
||||
pm_runtime_put(ch->dev);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rz_mtu3_32bit_cnt_setting(struct counter_device *counter)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, 0);
|
||||
struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, 1);
|
||||
|
||||
/* Phase counting mode 1 is used as default in initialization. */
|
||||
rz_mtu3_8bit_ch_write(ch1, RZ_MTU3_TMDR1, RZ_MTU3_TMDR1_PH_CNT_MODE_1);
|
||||
|
||||
rz_mtu3_8bit_ch_write(ch1, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA);
|
||||
rz_mtu3_8bit_ch_write(ch1, RZ_MTU3_TIOR, RZ_MTU3_TIOR_IC_BOTH);
|
||||
|
||||
rz_mtu3_enable(ch1);
|
||||
rz_mtu3_enable(ch2);
|
||||
}
|
||||
|
||||
static void rz_mtu3_16bit_cnt_setting(struct counter_device *counter, int id)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id);
|
||||
|
||||
/* Phase counting mode 1 is used as default in initialization. */
|
||||
rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TMDR1, RZ_MTU3_TMDR1_PH_CNT_MODE_1);
|
||||
|
||||
rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TCR, RZ_MTU3_TCR_CCLR_TGRA);
|
||||
rz_mtu3_8bit_ch_write(ch, RZ_MTU3_TIOR, RZ_MTU3_TIOR_NO_OUTPUT);
|
||||
rz_mtu3_enable(ch);
|
||||
}
|
||||
|
||||
static int rz_mtu3_initialize_counter(struct counter_device *counter, int id)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id);
|
||||
struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, 0);
|
||||
struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, 1);
|
||||
|
||||
switch (id) {
|
||||
case RZ_MTU3_16_BIT_MTU1_CH:
|
||||
case RZ_MTU3_16_BIT_MTU2_CH:
|
||||
if (!rz_mtu3_request_channel(ch))
|
||||
return -EBUSY;
|
||||
|
||||
rz_mtu3_16bit_cnt_setting(counter, id);
|
||||
return 0;
|
||||
case RZ_MTU3_32_BIT_CH:
|
||||
/*
|
||||
* 32-bit phase counting need MTU1 and MTU2 to create 32-bit
|
||||
* cascade counter.
|
||||
*/
|
||||
if (!rz_mtu3_request_channel(ch1))
|
||||
return -EBUSY;
|
||||
|
||||
if (!rz_mtu3_request_channel(ch2)) {
|
||||
rz_mtu3_release_channel(ch1);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
rz_mtu3_32bit_cnt_setting(counter);
|
||||
return 0;
|
||||
default:
|
||||
/* should never reach this path */
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void rz_mtu3_terminate_counter(struct counter_device *counter, int id)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, id);
|
||||
struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, 0);
|
||||
struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, 1);
|
||||
|
||||
if (id == RZ_MTU3_32_BIT_CH) {
|
||||
rz_mtu3_release_channel(ch2);
|
||||
rz_mtu3_release_channel(ch1);
|
||||
rz_mtu3_disable(ch2);
|
||||
rz_mtu3_disable(ch1);
|
||||
} else {
|
||||
rz_mtu3_release_channel(ch);
|
||||
rz_mtu3_disable(ch);
|
||||
}
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_enable_read(struct counter_device *counter,
|
||||
struct counter_count *count, u8 *enable)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_channel *const ch1 = rz_mtu3_get_ch(counter, 0);
|
||||
struct rz_mtu3_channel *const ch2 = rz_mtu3_get_ch(counter, 1);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (count->id == RZ_MTU3_32_BIT_CH)
|
||||
*enable = rz_mtu3_is_enabled(ch1) && rz_mtu3_is_enabled(ch2);
|
||||
else
|
||||
*enable = rz_mtu3_is_enabled(ch);
|
||||
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_count_enable_write(struct counter_device *counter,
|
||||
struct counter_count *count, u8 enable)
|
||||
{
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
int ret = 0;
|
||||
|
||||
if (enable) {
|
||||
pm_runtime_get_sync(ch->dev);
|
||||
mutex_lock(&priv->lock);
|
||||
ret = rz_mtu3_initialize_counter(counter, count->id);
|
||||
if (ret == 0)
|
||||
priv->count_is_enabled[count->id] = true;
|
||||
mutex_unlock(&priv->lock);
|
||||
} else {
|
||||
mutex_lock(&priv->lock);
|
||||
rz_mtu3_terminate_counter(counter, count->id);
|
||||
priv->count_is_enabled[count->id] = false;
|
||||
mutex_unlock(&priv->lock);
|
||||
pm_runtime_put(ch->dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rz_mtu3_lock_if_ch0_is_enabled(struct rz_mtu3_cnt *const priv)
|
||||
{
|
||||
mutex_lock(&priv->lock);
|
||||
if (priv->ch->is_busy && !(priv->count_is_enabled[RZ_MTU3_16_BIT_MTU1_CH] ||
|
||||
priv->count_is_enabled[RZ_MTU3_32_BIT_CH])) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_cascade_counts_enable_get(struct counter_device *counter,
|
||||
u8 *cascade_enable)
|
||||
{
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
unsigned long tmdr;
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_ch0_is_enabled(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_get_sync(priv->ch->dev);
|
||||
tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
|
||||
pm_runtime_put(priv->ch->dev);
|
||||
*cascade_enable = test_bit(RZ_MTU3_TMDR3_LWA, &tmdr);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_cascade_counts_enable_set(struct counter_device *counter,
|
||||
u8 cascade_enable)
|
||||
{
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_ch0_is_enabled(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_get_sync(priv->ch->dev);
|
||||
rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
|
||||
RZ_MTU3_TMDR3_LWA, cascade_enable);
|
||||
pm_runtime_put(priv->ch->dev);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_ext_input_phase_clock_select_get(struct counter_device *counter,
|
||||
u32 *ext_input_phase_clock_select)
|
||||
{
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
unsigned long tmdr;
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_ch0_is_enabled(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_get_sync(priv->ch->dev);
|
||||
tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
|
||||
pm_runtime_put(priv->ch->dev);
|
||||
*ext_input_phase_clock_select = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_ext_input_phase_clock_select_set(struct counter_device *counter,
|
||||
u32 ext_input_phase_clock_select)
|
||||
{
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_ch0_is_enabled(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pm_runtime_get_sync(priv->ch->dev);
|
||||
rz_mtu3_shared_reg_update_bit(priv->ch, RZ_MTU3_TMDR3,
|
||||
RZ_MTU3_TMDR3_PHCKSEL,
|
||||
ext_input_phase_clock_select);
|
||||
pm_runtime_put(priv->ch->dev);
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct counter_comp rz_mtu3_count_ext[] = {
|
||||
COUNTER_COMP_DIRECTION(rz_mtu3_count_direction_read),
|
||||
COUNTER_COMP_ENABLE(rz_mtu3_count_enable_read,
|
||||
rz_mtu3_count_enable_write),
|
||||
COUNTER_COMP_CEILING(rz_mtu3_count_ceiling_read,
|
||||
rz_mtu3_count_ceiling_write),
|
||||
};
|
||||
|
||||
static const enum counter_synapse_action rz_mtu3_synapse_actions[] = {
|
||||
COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
|
||||
COUNTER_SYNAPSE_ACTION_RISING_EDGE,
|
||||
COUNTER_SYNAPSE_ACTION_NONE,
|
||||
};
|
||||
|
||||
static int rz_mtu3_action_read(struct counter_device *counter,
|
||||
struct counter_count *count,
|
||||
struct counter_synapse *synapse,
|
||||
enum counter_synapse_action *action)
|
||||
{
|
||||
const bool is_signal_ab = (synapse->signal->id == SIGNAL_A_ID) ||
|
||||
(synapse->signal->id == SIGNAL_B_ID);
|
||||
struct rz_mtu3_channel *const ch = rz_mtu3_get_ch(counter, count->id);
|
||||
struct rz_mtu3_cnt *const priv = counter_priv(counter);
|
||||
enum counter_function function;
|
||||
bool mtclkc_mtclkd;
|
||||
unsigned long tmdr;
|
||||
int ret;
|
||||
|
||||
ret = rz_mtu3_lock_if_count_is_enabled(ch, priv, count->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rz_mtu3_count_function_read_helper(ch, priv, &function);
|
||||
if (ret) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Default action mode */
|
||||
*action = COUNTER_SYNAPSE_ACTION_NONE;
|
||||
|
||||
if (count->id != RZ_MTU3_16_BIT_MTU1_CH) {
|
||||
tmdr = rz_mtu3_shared_reg_read(priv->ch, RZ_MTU3_TMDR3);
|
||||
mtclkc_mtclkd = test_bit(RZ_MTU3_TMDR3_PHCKSEL, &tmdr);
|
||||
if ((mtclkc_mtclkd && is_signal_ab) ||
|
||||
(!mtclkc_mtclkd && !is_signal_ab)) {
|
||||
mutex_unlock(&priv->lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (function) {
|
||||
case COUNTER_FUNCTION_PULSE_DIRECTION:
|
||||
/*
|
||||
* Rising edges on signal A (signal C) updates the respective
|
||||
* count. The input level of signal B (signal D) determines
|
||||
* direction.
|
||||
*/
|
||||
if (synapse->signal->id == SIGNAL_A_ID ||
|
||||
synapse->signal->id == SIGNAL_C_ID)
|
||||
*action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
|
||||
break;
|
||||
case COUNTER_FUNCTION_QUADRATURE_X2_B:
|
||||
/*
|
||||
* Any state transition on quadrature pair signal B (signal D)
|
||||
* updates the respective count.
|
||||
*/
|
||||
if (synapse->signal->id == SIGNAL_B_ID ||
|
||||
synapse->signal->id == SIGNAL_D_ID)
|
||||
*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
|
||||
break;
|
||||
case COUNTER_FUNCTION_QUADRATURE_X4:
|
||||
/* counts up/down on both edges of A (C) and B (D) signal */
|
||||
*action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
|
||||
break;
|
||||
default:
|
||||
/* should never reach this path */
|
||||
mutex_unlock(&priv->lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct counter_ops rz_mtu3_cnt_ops = {
|
||||
.count_read = rz_mtu3_count_read,
|
||||
.count_write = rz_mtu3_count_write,
|
||||
.function_read = rz_mtu3_count_function_read,
|
||||
.function_write = rz_mtu3_count_function_write,
|
||||
.action_read = rz_mtu3_action_read,
|
||||
};
|
||||
|
||||
#define RZ_MTU3_PHASE_SIGNAL(_id, _name) { \
|
||||
.id = (_id), \
|
||||
.name = (_name), \
|
||||
}
|
||||
|
||||
static struct counter_signal rz_mtu3_signals[] = {
|
||||
RZ_MTU3_PHASE_SIGNAL(SIGNAL_A_ID, "MTU1 MTCLKA"),
|
||||
RZ_MTU3_PHASE_SIGNAL(SIGNAL_B_ID, "MTU1 MTCLKB"),
|
||||
RZ_MTU3_PHASE_SIGNAL(SIGNAL_C_ID, "MTU2 MTCLKC"),
|
||||
RZ_MTU3_PHASE_SIGNAL(SIGNAL_D_ID, "MTU2 MTCLKD"),
|
||||
};
|
||||
|
||||
static struct counter_synapse rz_mtu3_mtu1_count_synapses[] = {
|
||||
{
|
||||
.actions_list = rz_mtu3_synapse_actions,
|
||||
.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
|
||||
.signal = rz_mtu3_signals,
|
||||
},
|
||||
{
|
||||
.actions_list = rz_mtu3_synapse_actions,
|
||||
.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
|
||||
.signal = rz_mtu3_signals + 1,
|
||||
}
|
||||
};
|
||||
|
||||
static struct counter_synapse rz_mtu3_mtu2_count_synapses[] = {
|
||||
{
|
||||
.actions_list = rz_mtu3_synapse_actions,
|
||||
.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
|
||||
.signal = rz_mtu3_signals,
|
||||
},
|
||||
{
|
||||
.actions_list = rz_mtu3_synapse_actions,
|
||||
.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
|
||||
.signal = rz_mtu3_signals + 1,
|
||||
},
|
||||
{
|
||||
.actions_list = rz_mtu3_synapse_actions,
|
||||
.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
|
||||
.signal = rz_mtu3_signals + 2,
|
||||
},
|
||||
{
|
||||
.actions_list = rz_mtu3_synapse_actions,
|
||||
.num_actions = ARRAY_SIZE(rz_mtu3_synapse_actions),
|
||||
.signal = rz_mtu3_signals + 3,
|
||||
}
|
||||
};
|
||||
|
||||
static struct counter_count rz_mtu3_counts[] = {
|
||||
{
|
||||
.id = RZ_MTU3_16_BIT_MTU1_CH,
|
||||
.name = "Channel 1 Count",
|
||||
.functions_list = rz_mtu3_count_functions,
|
||||
.num_functions = ARRAY_SIZE(rz_mtu3_count_functions),
|
||||
.synapses = rz_mtu3_mtu1_count_synapses,
|
||||
.num_synapses = ARRAY_SIZE(rz_mtu3_mtu1_count_synapses),
|
||||
.ext = rz_mtu3_count_ext,
|
||||
.num_ext = ARRAY_SIZE(rz_mtu3_count_ext),
|
||||
},
|
||||
{
|
||||
.id = RZ_MTU3_16_BIT_MTU2_CH,
|
||||
.name = "Channel 2 Count",
|
||||
.functions_list = rz_mtu3_count_functions,
|
||||
.num_functions = ARRAY_SIZE(rz_mtu3_count_functions),
|
||||
.synapses = rz_mtu3_mtu2_count_synapses,
|
||||
.num_synapses = ARRAY_SIZE(rz_mtu3_mtu2_count_synapses),
|
||||
.ext = rz_mtu3_count_ext,
|
||||
.num_ext = ARRAY_SIZE(rz_mtu3_count_ext),
|
||||
},
|
||||
{
|
||||
.id = RZ_MTU3_32_BIT_CH,
|
||||
.name = "Channel 1 and 2 (cascaded) Count",
|
||||
.functions_list = rz_mtu3_count_functions,
|
||||
.num_functions = ARRAY_SIZE(rz_mtu3_count_functions),
|
||||
.synapses = rz_mtu3_mtu2_count_synapses,
|
||||
.num_synapses = ARRAY_SIZE(rz_mtu3_mtu2_count_synapses),
|
||||
.ext = rz_mtu3_count_ext,
|
||||
.num_ext = ARRAY_SIZE(rz_mtu3_count_ext),
|
||||
}
|
||||
};
|
||||
|
||||
static const char *const rz_mtu3_ext_input_phase_clock_select[] = {
|
||||
"MTCLKA-MTCLKB",
|
||||
"MTCLKC-MTCLKD",
|
||||
};
|
||||
|
||||
static DEFINE_COUNTER_ENUM(rz_mtu3_ext_input_phase_clock_select_enum,
|
||||
rz_mtu3_ext_input_phase_clock_select);
|
||||
|
||||
static struct counter_comp rz_mtu3_device_ext[] = {
|
||||
COUNTER_COMP_DEVICE_BOOL("cascade_counts_enable",
|
||||
rz_mtu3_cascade_counts_enable_get,
|
||||
rz_mtu3_cascade_counts_enable_set),
|
||||
COUNTER_COMP_DEVICE_ENUM("external_input_phase_clock_select",
|
||||
rz_mtu3_ext_input_phase_clock_select_get,
|
||||
rz_mtu3_ext_input_phase_clock_select_set,
|
||||
rz_mtu3_ext_input_phase_clock_select_enum),
|
||||
};
|
||||
|
||||
static int rz_mtu3_cnt_pm_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct clk *const clk = dev_get_drvdata(dev);
|
||||
|
||||
clk_disable_unprepare(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rz_mtu3_cnt_pm_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct clk *const clk = dev_get_drvdata(dev);
|
||||
|
||||
clk_prepare_enable(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEFINE_RUNTIME_DEV_PM_OPS(rz_mtu3_cnt_pm_ops,
|
||||
rz_mtu3_cnt_pm_runtime_suspend,
|
||||
rz_mtu3_cnt_pm_runtime_resume, NULL);
|
||||
|
||||
static void rz_mtu3_cnt_pm_disable(void *data)
|
||||
{
|
||||
struct device *dev = data;
|
||||
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_suspended(dev);
|
||||
}
|
||||
|
||||
static int rz_mtu3_cnt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rz_mtu3 *ddata = dev_get_drvdata(pdev->dev.parent);
|
||||
struct device *dev = &pdev->dev;
|
||||
struct counter_device *counter;
|
||||
struct rz_mtu3_channel *ch;
|
||||
struct rz_mtu3_cnt *priv;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
counter = devm_counter_alloc(dev, sizeof(*priv));
|
||||
if (!counter)
|
||||
return -ENOMEM;
|
||||
|
||||
priv = counter_priv(counter);
|
||||
priv->clk = ddata->clk;
|
||||
priv->mtu_32bit_max = U32_MAX;
|
||||
priv->ch = &ddata->channels[RZ_MTU3_CHAN_1];
|
||||
ch = &priv->ch[0];
|
||||
for (i = 0; i < RZ_MTU3_MAX_HW_CNTR_CHANNELS; i++) {
|
||||
ch->dev = dev;
|
||||
priv->mtu_16bit_max[i] = U16_MAX;
|
||||
ch++;
|
||||
}
|
||||
|
||||
mutex_init(&priv->lock);
|
||||
platform_set_drvdata(pdev, priv->clk);
|
||||
clk_prepare_enable(priv->clk);
|
||||
pm_runtime_set_active(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
ret = devm_add_action_or_reset(&pdev->dev, rz_mtu3_cnt_pm_disable, dev);
|
||||
if (ret < 0)
|
||||
goto disable_clock;
|
||||
|
||||
counter->name = dev_name(dev);
|
||||
counter->parent = dev;
|
||||
counter->ops = &rz_mtu3_cnt_ops;
|
||||
counter->counts = rz_mtu3_counts;
|
||||
counter->num_counts = ARRAY_SIZE(rz_mtu3_counts);
|
||||
counter->signals = rz_mtu3_signals;
|
||||
counter->num_signals = ARRAY_SIZE(rz_mtu3_signals);
|
||||
counter->ext = rz_mtu3_device_ext;
|
||||
counter->num_ext = ARRAY_SIZE(rz_mtu3_device_ext);
|
||||
|
||||
/* Register Counter device */
|
||||
ret = devm_counter_add(dev, counter);
|
||||
if (ret < 0) {
|
||||
dev_err_probe(dev, ret, "Failed to add counter\n");
|
||||
goto disable_clock;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
disable_clock:
|
||||
clk_disable_unprepare(priv->clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver rz_mtu3_cnt_driver = {
|
||||
.probe = rz_mtu3_cnt_probe,
|
||||
.driver = {
|
||||
.name = "rz-mtu3-counter",
|
||||
.pm = pm_ptr(&rz_mtu3_cnt_pm_ops),
|
||||
},
|
||||
};
|
||||
module_platform_driver(rz_mtu3_cnt_driver);
|
||||
|
||||
MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
|
||||
MODULE_ALIAS("platform:rz-mtu3-counter");
|
||||
MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a counter driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(COUNTER);
|
@ -1292,6 +1292,18 @@ config GPIO_KEMPLD
|
||||
This driver can also be built as a module. If so, the module will be
|
||||
called gpio-kempld.
|
||||
|
||||
config GPIO_LJCA
|
||||
tristate "INTEL La Jolla Cove Adapter GPIO support"
|
||||
depends on MFD_LJCA
|
||||
select GPIOLIB_IRQCHIP
|
||||
default MFD_LJCA
|
||||
help
|
||||
Select this option to enable GPIO driver for the INTEL
|
||||
La Jolla Cove Adapter (LJCA) board.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called gpio-ljca.
|
||||
|
||||
config GPIO_LP3943
|
||||
tristate "TI/National Semiconductor LP3943 GPIO expander"
|
||||
depends on MFD_LP3943
|
||||
|
@ -79,6 +79,7 @@ obj-$(CONFIG_GPIO_IXP4XX) += gpio-ixp4xx.o
|
||||
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
|
||||
obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
|
||||
obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o
|
||||
obj-$(CONFIG_GPIO_LJCA) += gpio-ljca.o
|
||||
obj-$(CONFIG_GPIO_LOGICVC) += gpio-logicvc.o
|
||||
obj-$(CONFIG_GPIO_LOONGSON1) += gpio-loongson1.o
|
||||
obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o
|
||||
|
454
drivers/gpio/gpio-ljca.c
Normal file
454
drivers/gpio/gpio-ljca.c
Normal file
@ -0,0 +1,454 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Intel La Jolla Cove Adapter USB-GPIO driver
|
||||
*
|
||||
* Copyright (c) 2023, Intel Corporation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/dev_printk.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kref.h>
|
||||
#include <linux/mfd/ljca.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
/* GPIO commands */
|
||||
#define LJCA_GPIO_CONFIG 1
|
||||
#define LJCA_GPIO_READ 2
|
||||
#define LJCA_GPIO_WRITE 3
|
||||
#define LJCA_GPIO_INT_EVENT 4
|
||||
#define LJCA_GPIO_INT_MASK 5
|
||||
#define LJCA_GPIO_INT_UNMASK 6
|
||||
|
||||
#define LJCA_GPIO_CONF_DISABLE BIT(0)
|
||||
#define LJCA_GPIO_CONF_INPUT BIT(1)
|
||||
#define LJCA_GPIO_CONF_OUTPUT BIT(2)
|
||||
#define LJCA_GPIO_CONF_PULLUP BIT(3)
|
||||
#define LJCA_GPIO_CONF_PULLDOWN BIT(4)
|
||||
#define LJCA_GPIO_CONF_DEFAULT BIT(5)
|
||||
#define LJCA_GPIO_CONF_INTERRUPT BIT(6)
|
||||
#define LJCA_GPIO_INT_TYPE BIT(7)
|
||||
|
||||
#define LJCA_GPIO_CONF_EDGE FIELD_PREP(LJCA_GPIO_INT_TYPE, 1)
|
||||
#define LJCA_GPIO_CONF_LEVEL FIELD_PREP(LJCA_GPIO_INT_TYPE, 0)
|
||||
|
||||
/* Intentional overlap with PULLUP / PULLDOWN */
|
||||
#define LJCA_GPIO_CONF_SET BIT(3)
|
||||
#define LJCA_GPIO_CONF_CLR BIT(4)
|
||||
|
||||
struct gpio_op {
|
||||
u8 index;
|
||||
u8 value;
|
||||
} __packed;
|
||||
|
||||
struct gpio_packet {
|
||||
u8 num;
|
||||
struct gpio_op item[];
|
||||
} __packed;
|
||||
|
||||
#define LJCA_GPIO_BUF_SIZE 60
|
||||
struct ljca_gpio_dev {
|
||||
struct platform_device *pdev;
|
||||
struct gpio_chip gc;
|
||||
struct ljca_gpio_info *gpio_info;
|
||||
DECLARE_BITMAP(unmasked_irqs, LJCA_MAX_GPIO_NUM);
|
||||
DECLARE_BITMAP(enabled_irqs, LJCA_MAX_GPIO_NUM);
|
||||
DECLARE_BITMAP(reenable_irqs, LJCA_MAX_GPIO_NUM);
|
||||
u8 *connect_mode;
|
||||
/* mutex to protect irq bus */
|
||||
struct mutex irq_lock;
|
||||
struct work_struct work;
|
||||
/* lock to protect package transfer to Hardware */
|
||||
struct mutex trans_lock;
|
||||
|
||||
u8 obuf[LJCA_GPIO_BUF_SIZE];
|
||||
u8 ibuf[LJCA_GPIO_BUF_SIZE];
|
||||
};
|
||||
|
||||
static int gpio_config(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id, u8 config)
|
||||
{
|
||||
struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ljca_gpio->trans_lock);
|
||||
packet->item[0].index = gpio_id;
|
||||
packet->item[0].value = config | ljca_gpio->connect_mode[gpio_id];
|
||||
packet->num = 1;
|
||||
|
||||
ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_CONFIG, packet,
|
||||
struct_size(packet, item, packet->num), NULL, NULL);
|
||||
mutex_unlock(&ljca_gpio->trans_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ljca_gpio_read(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id)
|
||||
{
|
||||
struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf;
|
||||
struct gpio_packet *ack_packet = (struct gpio_packet *)ljca_gpio->ibuf;
|
||||
unsigned int ibuf_len = LJCA_GPIO_BUF_SIZE;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ljca_gpio->trans_lock);
|
||||
packet->num = 1;
|
||||
packet->item[0].index = gpio_id;
|
||||
ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_READ, packet,
|
||||
struct_size(packet, item, packet->num), ljca_gpio->ibuf, &ibuf_len);
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
if (!ibuf_len || ack_packet->num != packet->num) {
|
||||
dev_err(&ljca_gpio->pdev->dev, "failed gpio_id:%u %u", gpio_id, ack_packet->num);
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&ljca_gpio->trans_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
return ack_packet->item[0].value > 0;
|
||||
}
|
||||
|
||||
static int ljca_gpio_write(struct ljca_gpio_dev *ljca_gpio, u8 gpio_id,
|
||||
int value)
|
||||
{
|
||||
struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ljca_gpio->trans_lock);
|
||||
packet->num = 1;
|
||||
packet->item[0].index = gpio_id;
|
||||
packet->item[0].value = value & 1;
|
||||
|
||||
ret = ljca_transfer(ljca_gpio->gpio_info->ljca, LJCA_GPIO_WRITE, packet,
|
||||
struct_size(packet, item, packet->num), NULL, NULL);
|
||||
mutex_unlock(&ljca_gpio->trans_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ljca_gpio_get_value(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip);
|
||||
|
||||
return ljca_gpio_read(ljca_gpio, offset);
|
||||
}
|
||||
|
||||
static void ljca_gpio_set_value(struct gpio_chip *chip, unsigned int offset,
|
||||
int val)
|
||||
{
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip);
|
||||
int ret;
|
||||
|
||||
ret = ljca_gpio_write(ljca_gpio, offset, val);
|
||||
if (ret)
|
||||
dev_err(chip->parent, "offset:%u val:%d set value failed %d\n", offset, val, ret);
|
||||
}
|
||||
|
||||
static int ljca_gpio_direction_input(struct gpio_chip *chip,
|
||||
unsigned int offset)
|
||||
{
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip);
|
||||
u8 config = LJCA_GPIO_CONF_INPUT | LJCA_GPIO_CONF_CLR;
|
||||
|
||||
return gpio_config(ljca_gpio, offset, config);
|
||||
}
|
||||
|
||||
static int ljca_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned int offset, int val)
|
||||
{
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip);
|
||||
u8 config = LJCA_GPIO_CONF_OUTPUT | LJCA_GPIO_CONF_CLR;
|
||||
int ret;
|
||||
|
||||
ret = gpio_config(ljca_gpio, offset, config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ljca_gpio_set_value(chip, offset, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ljca_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
|
||||
unsigned long config)
|
||||
{
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip);
|
||||
|
||||
ljca_gpio->connect_mode[offset] = 0;
|
||||
switch (pinconf_to_config_param(config)) {
|
||||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
ljca_gpio->connect_mode[offset] |= LJCA_GPIO_CONF_PULLUP;
|
||||
break;
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
ljca_gpio->connect_mode[offset] |= LJCA_GPIO_CONF_PULLDOWN;
|
||||
break;
|
||||
case PIN_CONFIG_DRIVE_PUSH_PULL:
|
||||
case PIN_CONFIG_PERSIST_STATE:
|
||||
break;
|
||||
default:
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ljca_gpio_init_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask,
|
||||
unsigned int ngpios)
|
||||
{
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(chip);
|
||||
|
||||
WARN_ON_ONCE(ngpios != ljca_gpio->gpio_info->num);
|
||||
bitmap_copy(valid_mask, ljca_gpio->gpio_info->valid_pin_map, ngpios);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ljca_gpio_irq_init_valid_mask(struct gpio_chip *chip, unsigned long *valid_mask,
|
||||
unsigned int ngpios)
|
||||
{
|
||||
ljca_gpio_init_valid_mask(chip, valid_mask, ngpios);
|
||||
}
|
||||
|
||||
static int ljca_enable_irq(struct ljca_gpio_dev *ljca_gpio, int gpio_id, bool enable)
|
||||
{
|
||||
struct gpio_packet *packet = (struct gpio_packet *)ljca_gpio->obuf;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ljca_gpio->trans_lock);
|
||||
packet->num = 1;
|
||||
packet->item[0].index = gpio_id;
|
||||
packet->item[0].value = 0;
|
||||
|
||||
ret = ljca_transfer(ljca_gpio->gpio_info->ljca,
|
||||
enable ? LJCA_GPIO_INT_UNMASK : LJCA_GPIO_INT_MASK, packet,
|
||||
struct_size(packet, item, packet->num), NULL, NULL);
|
||||
mutex_unlock(&ljca_gpio->trans_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ljca_gpio_async(struct work_struct *work)
|
||||
{
|
||||
struct ljca_gpio_dev *ljca_gpio = container_of(work, struct ljca_gpio_dev, work);
|
||||
int gpio_id;
|
||||
int unmasked;
|
||||
|
||||
for_each_set_bit(gpio_id, ljca_gpio->reenable_irqs, ljca_gpio->gc.ngpio) {
|
||||
clear_bit(gpio_id, ljca_gpio->reenable_irqs);
|
||||
unmasked = test_bit(gpio_id, ljca_gpio->unmasked_irqs);
|
||||
if (unmasked)
|
||||
ljca_enable_irq(ljca_gpio, gpio_id, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void ljca_gpio_event_cb(void *context, u8 cmd, const void *evt_data, int len)
|
||||
{
|
||||
const struct gpio_packet *packet = evt_data;
|
||||
struct ljca_gpio_dev *ljca_gpio = context;
|
||||
int i;
|
||||
int irq;
|
||||
|
||||
if (cmd != LJCA_GPIO_INT_EVENT)
|
||||
return;
|
||||
|
||||
for (i = 0; i < packet->num; i++) {
|
||||
irq = irq_find_mapping(ljca_gpio->gc.irq.domain, packet->item[i].index);
|
||||
if (!irq) {
|
||||
dev_err(ljca_gpio->gc.parent, "gpio_id %u does not mapped to IRQ yet\n",
|
||||
packet->item[i].index);
|
||||
return;
|
||||
}
|
||||
|
||||
generic_handle_domain_irq(ljca_gpio->gc.irq.domain, irq);
|
||||
set_bit(packet->item[i].index, ljca_gpio->reenable_irqs);
|
||||
}
|
||||
|
||||
schedule_work(&ljca_gpio->work);
|
||||
}
|
||||
|
||||
static void ljca_irq_unmask(struct irq_data *irqd)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(gc);
|
||||
int gpio_id = irqd_to_hwirq(irqd);
|
||||
|
||||
gpiochip_enable_irq(gc, gpio_id);
|
||||
set_bit(gpio_id, ljca_gpio->unmasked_irqs);
|
||||
}
|
||||
|
||||
static void ljca_irq_mask(struct irq_data *irqd)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(gc);
|
||||
int gpio_id = irqd_to_hwirq(irqd);
|
||||
|
||||
clear_bit(gpio_id, ljca_gpio->unmasked_irqs);
|
||||
gpiochip_disable_irq(gc, gpio_id);
|
||||
}
|
||||
|
||||
static int ljca_irq_set_type(struct irq_data *irqd, unsigned int type)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(gc);
|
||||
int gpio_id = irqd_to_hwirq(irqd);
|
||||
|
||||
ljca_gpio->connect_mode[gpio_id] = LJCA_GPIO_CONF_INTERRUPT;
|
||||
switch (type) {
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLUP);
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_LEVEL | LJCA_GPIO_CONF_PULLDOWN);
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLUP);
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
ljca_gpio->connect_mode[gpio_id] |= (LJCA_GPIO_CONF_EDGE | LJCA_GPIO_CONF_PULLDOWN);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ljca_irq_bus_lock(struct irq_data *irqd)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(gc);
|
||||
|
||||
mutex_lock(&ljca_gpio->irq_lock);
|
||||
}
|
||||
|
||||
static void ljca_irq_bus_unlock(struct irq_data *irqd)
|
||||
{
|
||||
struct gpio_chip *gc = irq_data_get_irq_chip_data(irqd);
|
||||
struct ljca_gpio_dev *ljca_gpio = gpiochip_get_data(gc);
|
||||
int gpio_id = irqd_to_hwirq(irqd);
|
||||
int enabled;
|
||||
int unmasked;
|
||||
|
||||
enabled = test_bit(gpio_id, ljca_gpio->enabled_irqs);
|
||||
unmasked = test_bit(gpio_id, ljca_gpio->unmasked_irqs);
|
||||
|
||||
if (enabled != unmasked) {
|
||||
if (unmasked) {
|
||||
gpio_config(ljca_gpio, gpio_id, 0);
|
||||
ljca_enable_irq(ljca_gpio, gpio_id, true);
|
||||
set_bit(gpio_id, ljca_gpio->enabled_irqs);
|
||||
} else {
|
||||
ljca_enable_irq(ljca_gpio, gpio_id, false);
|
||||
clear_bit(gpio_id, ljca_gpio->enabled_irqs);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&ljca_gpio->irq_lock);
|
||||
}
|
||||
|
||||
static const struct irq_chip ljca_gpio_irqchip = {
|
||||
.name = "ljca-irq",
|
||||
.irq_mask = ljca_irq_mask,
|
||||
.irq_unmask = ljca_irq_unmask,
|
||||
.irq_set_type = ljca_irq_set_type,
|
||||
.irq_bus_lock = ljca_irq_bus_lock,
|
||||
.irq_bus_sync_unlock = ljca_irq_bus_unlock,
|
||||
.flags = IRQCHIP_IMMUTABLE,
|
||||
GPIOCHIP_IRQ_RESOURCE_HELPERS,
|
||||
};
|
||||
|
||||
static int ljca_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ljca_gpio_dev *ljca_gpio;
|
||||
struct gpio_irq_chip *girq;
|
||||
int ret;
|
||||
|
||||
ljca_gpio = devm_kzalloc(&pdev->dev, sizeof(*ljca_gpio), GFP_KERNEL);
|
||||
if (!ljca_gpio)
|
||||
return -ENOMEM;
|
||||
|
||||
ljca_gpio->gpio_info = dev_get_platdata(&pdev->dev);
|
||||
ljca_gpio->connect_mode = devm_kcalloc(&pdev->dev, ljca_gpio->gpio_info->num,
|
||||
sizeof(*ljca_gpio->connect_mode), GFP_KERNEL);
|
||||
if (!ljca_gpio->connect_mode)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&ljca_gpio->irq_lock);
|
||||
mutex_init(&ljca_gpio->trans_lock);
|
||||
ljca_gpio->pdev = pdev;
|
||||
ljca_gpio->gc.direction_input = ljca_gpio_direction_input;
|
||||
ljca_gpio->gc.direction_output = ljca_gpio_direction_output;
|
||||
ljca_gpio->gc.get = ljca_gpio_get_value;
|
||||
ljca_gpio->gc.set = ljca_gpio_set_value;
|
||||
ljca_gpio->gc.set_config = ljca_gpio_set_config;
|
||||
ljca_gpio->gc.init_valid_mask = ljca_gpio_init_valid_mask;
|
||||
ljca_gpio->gc.can_sleep = true;
|
||||
ljca_gpio->gc.parent = &pdev->dev;
|
||||
|
||||
ljca_gpio->gc.base = -1;
|
||||
ljca_gpio->gc.ngpio = ljca_gpio->gpio_info->num;
|
||||
ljca_gpio->gc.label = ACPI_COMPANION(&pdev->dev) ?
|
||||
acpi_dev_name(ACPI_COMPANION(&pdev->dev)) :
|
||||
dev_name(&pdev->dev);
|
||||
ljca_gpio->gc.owner = THIS_MODULE;
|
||||
|
||||
platform_set_drvdata(pdev, ljca_gpio);
|
||||
ljca_register_event_cb(ljca_gpio->gpio_info->ljca, ljca_gpio_event_cb, ljca_gpio);
|
||||
|
||||
girq = &ljca_gpio->gc.irq;
|
||||
gpio_irq_chip_set_chip(girq, &ljca_gpio_irqchip);
|
||||
girq->parent_handler = NULL;
|
||||
girq->num_parents = 0;
|
||||
girq->parents = NULL;
|
||||
girq->default_type = IRQ_TYPE_NONE;
|
||||
girq->handler = handle_simple_irq;
|
||||
girq->init_valid_mask = ljca_gpio_irq_init_valid_mask;
|
||||
|
||||
INIT_WORK(&ljca_gpio->work, ljca_gpio_async);
|
||||
ret = gpiochip_add_data(&ljca_gpio->gc, ljca_gpio);
|
||||
if (ret) {
|
||||
ljca_unregister_event_cb(ljca_gpio->gpio_info->ljca);
|
||||
mutex_destroy(&ljca_gpio->irq_lock);
|
||||
mutex_destroy(&ljca_gpio->trans_lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ljca_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ljca_gpio_dev *ljca_gpio = platform_get_drvdata(pdev);
|
||||
|
||||
gpiochip_remove(&ljca_gpio->gc);
|
||||
ljca_unregister_event_cb(ljca_gpio->gpio_info->ljca);
|
||||
mutex_destroy(&ljca_gpio->irq_lock);
|
||||
mutex_destroy(&ljca_gpio->trans_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LJCA_GPIO_DRV_NAME "ljca-gpio"
|
||||
static const struct platform_device_id ljca_gpio_id[] = {
|
||||
{ LJCA_GPIO_DRV_NAME, 0 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, ljca_gpio_id);
|
||||
|
||||
static struct platform_driver ljca_gpio_driver = {
|
||||
.driver.name = LJCA_GPIO_DRV_NAME,
|
||||
.probe = ljca_gpio_probe,
|
||||
.remove = ljca_gpio_remove,
|
||||
};
|
||||
module_platform_driver(ljca_gpio_driver);
|
||||
|
||||
MODULE_AUTHOR("Ye Xiang <xiang.ye@intel.com>");
|
||||
MODULE_AUTHOR("Wang Zhifeng <zhifeng.wang@intel.com>");
|
||||
MODULE_AUTHOR("Zhang Lixu <lixu.zhang@intel.com>");
|
||||
MODULE_DESCRIPTION("Intel La Jolla Cove Adapter USB-GPIO driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(LJCA);
|
@ -1117,8 +1117,7 @@ static int pm860x_dt_init(struct device_node *np,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL))
|
||||
pdata->irq_mode = 1;
|
||||
pdata->irq_mode = of_property_read_bool(np, "marvell,88pm860x-irq-read-clr");
|
||||
ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr",
|
||||
&pdata->companion_addr);
|
||||
if (ret) {
|
||||
@ -1276,4 +1275,3 @@ module_exit(pm860x_i2c_exit);
|
||||
|
||||
MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
|
||||
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -266,6 +266,16 @@ config MFD_MADERA_SPI
|
||||
Support for the Cirrus Logic Madera platform audio SoC
|
||||
core functionality controlled via SPI.
|
||||
|
||||
config MFD_MAX597X
|
||||
tristate "Maxim 597x power switch and monitor"
|
||||
depends on (I2C && OF)
|
||||
select MFD_SIMPLE_MFD_I2C
|
||||
help
|
||||
This driver controls a Maxim 5970/5978 switch via I2C bus.
|
||||
The MAX5970/5978 is a smart switch with no output regulation, but
|
||||
fault protection and voltage and current monitoring capabilities.
|
||||
Also it supports upto 4 indication leds.
|
||||
|
||||
config MFD_CS47L15
|
||||
bool "Cirrus Logic CS47L15"
|
||||
select PINCTRL_CS47L15
|
||||
@ -353,9 +363,6 @@ config MFD_DA9055
|
||||
Additional drivers must be enabled in order to use the functionality
|
||||
of the device.
|
||||
|
||||
This driver can be built as a module. If built as a module it will be
|
||||
called "da9055"
|
||||
|
||||
config MFD_DA9062
|
||||
tristate "Dialog Semiconductor DA9062/61 PMIC Support"
|
||||
select MFD_CORE
|
||||
@ -1308,6 +1315,16 @@ config MFD_SC27XX_PMIC
|
||||
This driver provides common support for accessing the SC27xx PMICs,
|
||||
and it also adds the irq_chip parts for handling the PMIC chip events.
|
||||
|
||||
config RZ_MTU3
|
||||
bool "Renesas RZ/G2L MTU3a core driver"
|
||||
depends on (ARCH_RZG2L && OF) || COMPILE_TEST
|
||||
help
|
||||
Select this option to enable Renesas RZ/G2L MTU3a core driver for
|
||||
the Multi-Function Timer Pulse Unit 3 (MTU3a) hardware available
|
||||
on SoCs from Renesas. The core driver shares the clk and channel
|
||||
register access for the other child devices like Counter, PWM,
|
||||
Clock Source, and Clock event.
|
||||
|
||||
config ABX500_CORE
|
||||
bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
|
||||
depends on ARCH_U8500 || COMPILE_TEST
|
||||
|
@ -174,6 +174,7 @@ pcf50633-objs := pcf50633-core.o pcf50633-irq.o
|
||||
obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
|
||||
obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
|
||||
obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
|
||||
obj-$(CONFIG_RZ_MTU3) += rz-mtu3.o
|
||||
obj-$(CONFIG_ABX500_CORE) += abx500-core.o
|
||||
obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
|
||||
# ab8500-core need to come after db8500-prcmu (which provides the channel)
|
||||
|
@ -112,6 +112,7 @@ static const struct of_device_id arizona_i2c_of_match[] = {
|
||||
{ .compatible = "wlf,wm1814", .data = (void *)WM1814 },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, arizona_i2c_of_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver arizona_i2c_driver = {
|
||||
|
@ -277,6 +277,7 @@ static const struct of_device_id arizona_spi_of_match[] = {
|
||||
{ .compatible = "cirrus,cs47l24", .data = (void *)CS47L24 },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, arizona_spi_of_match);
|
||||
#endif
|
||||
|
||||
static struct spi_driver arizona_spi_driver = {
|
||||
|
@ -51,7 +51,7 @@ MODULE_DEVICE_TABLE(of, atc260x_i2c_of_match);
|
||||
static struct i2c_driver atc260x_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "atc260x",
|
||||
.of_match_table = of_match_ptr(atc260x_i2c_of_match),
|
||||
.of_match_table = atc260x_i2c_of_match,
|
||||
},
|
||||
.probe_new = atc260x_i2c_probe,
|
||||
};
|
||||
|
@ -37,7 +37,6 @@ struct atmel_flexcom {
|
||||
static int atmel_flexcom_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct resource *res;
|
||||
struct atmel_flexcom *ddata;
|
||||
int err;
|
||||
|
||||
@ -55,8 +54,7 @@ static int atmel_flexcom_probe(struct platform_device *pdev)
|
||||
ddata->opmode > ATMEL_FLEXCOM_MODE_TWI)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ddata->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
ddata->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(ddata->base))
|
||||
return PTR_ERR(ddata->base);
|
||||
|
||||
|
@ -323,7 +323,7 @@ static const struct atmel_hsmc_reg_layout sama5d2_reg_layout = {
|
||||
.timing_regs_offset = 0x700,
|
||||
};
|
||||
|
||||
static const struct of_device_id atmel_smc_ids[] = {
|
||||
static const struct of_device_id atmel_smc_ids[] __maybe_unused = {
|
||||
{ .compatible = "atmel,at91sam9260-smc", .data = NULL },
|
||||
{ .compatible = "atmel,sama5d3-smc", .data = &sama5d3_reg_layout },
|
||||
{ .compatible = "atmel,sama5d2-smc", .data = &sama5d2_reg_layout },
|
||||
|
@ -65,6 +65,7 @@ static const struct of_device_id axp20x_i2c_of_match[] = {
|
||||
{ .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
|
||||
{ .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
|
||||
{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
|
||||
{ .compatible = "x-powers,axp15060", .data = (void *)AXP15060_ID },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axp20x_i2c_of_match);
|
||||
@ -78,6 +79,7 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
|
||||
{ "axp223", 0 },
|
||||
{ "axp803", 0 },
|
||||
{ "axp806", 0 },
|
||||
{ "axp15060", 0 },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
|
||||
|
@ -43,6 +43,7 @@ static const char * const axp20x_model_names[] = {
|
||||
"AXP806",
|
||||
"AXP809",
|
||||
"AXP813",
|
||||
"AXP15060",
|
||||
};
|
||||
|
||||
static const struct regmap_range axp152_writeable_ranges[] = {
|
||||
@ -119,6 +120,7 @@ static const struct regmap_access_table axp22x_volatile_table = {
|
||||
|
||||
/* AXP288 ranges are shared with the AXP803, as they cover the same range */
|
||||
static const struct regmap_range axp288_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP288_POWER_REASON, AXP288_POWER_REASON),
|
||||
regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ6_STATE),
|
||||
regmap_reg_range(AXP20X_DCDC_MODE, AXP288_FG_TUNE5),
|
||||
};
|
||||
@ -168,6 +170,31 @@ static const struct regmap_access_table axp806_volatile_table = {
|
||||
.n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp15060_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP15060_PWR_OUT_CTRL1, AXP15060_DCDC_MODE_CTRL2),
|
||||
regmap_reg_range(AXP15060_OUTPUT_MONITOR_DISCHARGE, AXP15060_CPUSLDO_V_CTRL),
|
||||
regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
|
||||
regmap_reg_range(AXP15060_PEK_KEY, AXP15060_PEK_KEY),
|
||||
regmap_reg_range(AXP15060_IRQ1_EN, AXP15060_IRQ2_EN),
|
||||
regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp15060_volatile_ranges[] = {
|
||||
regmap_reg_range(AXP15060_STARTUP_SRC, AXP15060_STARTUP_SRC),
|
||||
regmap_reg_range(AXP15060_PWR_WAKEUP_CTRL, AXP15060_PWR_DISABLE_DOWN_SEQ),
|
||||
regmap_reg_range(AXP15060_IRQ1_STATE, AXP15060_IRQ2_STATE),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table axp15060_writeable_table = {
|
||||
.yes_ranges = axp15060_writeable_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(axp15060_writeable_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table axp15060_volatile_table = {
|
||||
.yes_ranges = axp15060_volatile_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(axp15060_volatile_ranges),
|
||||
};
|
||||
|
||||
static const struct resource axp152_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
@ -236,6 +263,11 @@ static const struct resource axp809_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static const struct resource axp15060_pek_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_RIS_EDGE, "PEK_DBR"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP15060_IRQ_PEK_FAL_EDGE, "PEK_DBF"),
|
||||
};
|
||||
|
||||
static const struct regmap_config axp152_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@ -281,6 +313,15 @@ static const struct regmap_config axp806_regmap_config = {
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct regmap_config axp15060_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.wr_table = &axp15060_writeable_table,
|
||||
.volatile_table = &axp15060_volatile_table,
|
||||
.max_register = AXP15060_IRQ2_STATE,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
#define INIT_REGMAP_IRQ(_variant, _irq, _off, _mask) \
|
||||
[_variant##_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) }
|
||||
|
||||
@ -502,6 +543,23 @@ static const struct regmap_irq axp809_regmap_irqs[] = {
|
||||
INIT_REGMAP_IRQ(AXP809, GPIO0_INPUT, 4, 0),
|
||||
};
|
||||
|
||||
static const struct regmap_irq axp15060_regmap_irqs[] = {
|
||||
INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV1, 0, 0),
|
||||
INIT_REGMAP_IRQ(AXP15060, DIE_TEMP_HIGH_LV2, 0, 1),
|
||||
INIT_REGMAP_IRQ(AXP15060, DCDC1_V_LOW, 0, 2),
|
||||
INIT_REGMAP_IRQ(AXP15060, DCDC2_V_LOW, 0, 3),
|
||||
INIT_REGMAP_IRQ(AXP15060, DCDC3_V_LOW, 0, 4),
|
||||
INIT_REGMAP_IRQ(AXP15060, DCDC4_V_LOW, 0, 5),
|
||||
INIT_REGMAP_IRQ(AXP15060, DCDC5_V_LOW, 0, 6),
|
||||
INIT_REGMAP_IRQ(AXP15060, DCDC6_V_LOW, 0, 7),
|
||||
INIT_REGMAP_IRQ(AXP15060, PEK_LONG, 1, 0),
|
||||
INIT_REGMAP_IRQ(AXP15060, PEK_SHORT, 1, 1),
|
||||
INIT_REGMAP_IRQ(AXP15060, GPIO1_INPUT, 1, 2),
|
||||
INIT_REGMAP_IRQ(AXP15060, PEK_FAL_EDGE, 1, 3),
|
||||
INIT_REGMAP_IRQ(AXP15060, PEK_RIS_EDGE, 1, 4),
|
||||
INIT_REGMAP_IRQ(AXP15060, GPIO2_INPUT, 1, 5),
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip axp152_regmap_irq_chip = {
|
||||
.name = "axp152_irq_chip",
|
||||
.status_base = AXP152_IRQ1_STATE,
|
||||
@ -581,6 +639,17 @@ static const struct regmap_irq_chip axp809_regmap_irq_chip = {
|
||||
.num_regs = 5,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip axp15060_regmap_irq_chip = {
|
||||
.name = "axp15060",
|
||||
.status_base = AXP15060_IRQ1_STATE,
|
||||
.ack_base = AXP15060_IRQ1_STATE,
|
||||
.unmask_base = AXP15060_IRQ1_EN,
|
||||
.init_ack_masked = true,
|
||||
.irqs = axp15060_regmap_irqs,
|
||||
.num_irqs = ARRAY_SIZE(axp15060_regmap_irqs),
|
||||
.num_regs = 2,
|
||||
};
|
||||
|
||||
static const struct mfd_cell axp20x_cells[] = {
|
||||
{
|
||||
.name = "axp20x-gpio",
|
||||
@ -825,6 +894,23 @@ static const struct mfd_cell axp813_cells[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell axp15060_cells[] = {
|
||||
{
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp15060_pek_resources),
|
||||
.resources = axp15060_pek_resources,
|
||||
}, {
|
||||
.name = "axp20x-regulator",
|
||||
},
|
||||
};
|
||||
|
||||
/* For boards that don't have IRQ line connected to SOC. */
|
||||
static const struct mfd_cell axp_regulator_only_cells[] = {
|
||||
{
|
||||
.name = "axp20x-regulator",
|
||||
},
|
||||
};
|
||||
|
||||
static int axp20x_power_off(struct sys_off_data *data)
|
||||
{
|
||||
struct axp20x_dev *axp20x = data->cb_data;
|
||||
@ -934,6 +1020,28 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
|
||||
*/
|
||||
axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
|
||||
break;
|
||||
case AXP15060_ID:
|
||||
/*
|
||||
* Don't register the power key part if there is no interrupt
|
||||
* line.
|
||||
*
|
||||
* Since most use cases of AXP PMICs are Allwinner SOCs, board
|
||||
* designers follow Allwinner's reference design and connects
|
||||
* IRQ line to SOC, there's no need for those variants to deal
|
||||
* with cases that IRQ isn't connected. However, AXP15660 is
|
||||
* used by some other vendors' SOCs that didn't connect IRQ
|
||||
* line, we need to deal with this case.
|
||||
*/
|
||||
if (axp20x->irq > 0) {
|
||||
axp20x->nr_cells = ARRAY_SIZE(axp15060_cells);
|
||||
axp20x->cells = axp15060_cells;
|
||||
} else {
|
||||
axp20x->nr_cells = ARRAY_SIZE(axp_regulator_only_cells);
|
||||
axp20x->cells = axp_regulator_only_cells;
|
||||
}
|
||||
axp20x->regmap_cfg = &axp15060_regmap_config;
|
||||
axp20x->regmap_irq_chip = &axp15060_regmap_irq_chip;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
|
||||
return -EINVAL;
|
||||
|
@ -28,7 +28,7 @@ static const struct mfd_cell bcm2835_power_devs[] = {
|
||||
static int bcm2835_pm_get_pdata(struct platform_device *pdev,
|
||||
struct bcm2835_pm *pm)
|
||||
{
|
||||
if (of_find_property(pm->dev->of_node, "reg-names", NULL)) {
|
||||
if (of_property_present(pm->dev->of_node, "reg-names")) {
|
||||
struct resource *res;
|
||||
|
||||
pm->base = devm_platform_ioremap_resource_byname(pdev, "pm");
|
||||
@ -123,4 +123,3 @@ module_platform_driver(bcm2835_pm_driver);
|
||||
|
||||
MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
|
||||
MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM MFD");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -563,4 +563,3 @@ module_exit(da903x_exit);
|
||||
MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034");
|
||||
MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
|
||||
MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -653,4 +653,3 @@ void da9052_device_exit(struct da9052 *da9052)
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
|
||||
MODULE_DESCRIPTION("DA9052 MFD Core");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -209,4 +209,3 @@ module_exit(da9052_i2c_exit);
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
|
||||
MODULE_DESCRIPTION("I2C driver for Dialog DA9052 PMIC");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -102,4 +102,3 @@ module_exit(da9052_spi_exit);
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
|
||||
MODULE_DESCRIPTION("SPI driver for Dialog DA9052 PMIC");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -398,5 +398,4 @@ void da9055_device_exit(struct da9055 *da9055)
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
|
||||
|
@ -97,4 +97,3 @@ module_exit(da9055_i2c_exit);
|
||||
|
||||
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
|
||||
MODULE_DESCRIPTION("I2C driver for Dialog DA9055 PMIC");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -181,35 +181,25 @@ static const struct resource da9061_onkey_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY, "ONKEY"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell da9061_devs[] = {
|
||||
{
|
||||
.name = "da9061-core",
|
||||
.num_resources = ARRAY_SIZE(da9061_core_resources),
|
||||
.resources = da9061_core_resources,
|
||||
},
|
||||
{
|
||||
.name = "da9062-regulators",
|
||||
.num_resources = ARRAY_SIZE(da9061_regulators_resources),
|
||||
.resources = da9061_regulators_resources,
|
||||
},
|
||||
{
|
||||
.name = "da9061-watchdog",
|
||||
.num_resources = ARRAY_SIZE(da9061_wdt_resources),
|
||||
.resources = da9061_wdt_resources,
|
||||
.of_compatible = "dlg,da9061-watchdog",
|
||||
},
|
||||
{
|
||||
.name = "da9061-thermal",
|
||||
.num_resources = ARRAY_SIZE(da9061_thermal_resources),
|
||||
.resources = da9061_thermal_resources,
|
||||
.of_compatible = "dlg,da9061-thermal",
|
||||
},
|
||||
{
|
||||
.name = "da9061-onkey",
|
||||
.num_resources = ARRAY_SIZE(da9061_onkey_resources),
|
||||
.resources = da9061_onkey_resources,
|
||||
.of_compatible = "dlg,da9061-onkey",
|
||||
},
|
||||
static const struct mfd_cell da9061_devs_irq[] = {
|
||||
MFD_CELL_OF("da9061-core", da9061_core_resources, NULL, 0, 0,
|
||||
NULL),
|
||||
MFD_CELL_OF("da9062-regulators", da9061_regulators_resources, NULL, 0, 0,
|
||||
NULL),
|
||||
MFD_CELL_OF("da9061-watchdog", da9061_wdt_resources, NULL, 0, 0,
|
||||
"dlg,da9061-watchdog"),
|
||||
MFD_CELL_OF("da9061-thermal", da9061_thermal_resources, NULL, 0, 0,
|
||||
"dlg,da9061-thermal"),
|
||||
MFD_CELL_OF("da9061-onkey", da9061_onkey_resources, NULL, 0, 0,
|
||||
"dlg,da9061-onkey"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell da9061_devs_noirq[] = {
|
||||
MFD_CELL_OF("da9061-core", NULL, NULL, 0, 0, NULL),
|
||||
MFD_CELL_OF("da9062-regulators", NULL, NULL, 0, 0, NULL),
|
||||
MFD_CELL_OF("da9061-watchdog", NULL, NULL, 0, 0, "dlg,da9061-watchdog"),
|
||||
MFD_CELL_OF("da9061-thermal", NULL, NULL, 0, 0, "dlg,da9061-thermal"),
|
||||
MFD_CELL_OF("da9061-onkey", NULL, NULL, 0, 0, "dlg,da9061-onkey"),
|
||||
};
|
||||
|
||||
static const struct resource da9062_core_resources[] = {
|
||||
@ -245,47 +235,31 @@ static const struct resource da9062_gpio_resources[] = {
|
||||
DEFINE_RES_NAMED(DA9062_IRQ_GPI4, 1, "GPI4", IORESOURCE_IRQ),
|
||||
};
|
||||
|
||||
static const struct mfd_cell da9062_devs[] = {
|
||||
{
|
||||
.name = "da9062-core",
|
||||
.num_resources = ARRAY_SIZE(da9062_core_resources),
|
||||
.resources = da9062_core_resources,
|
||||
},
|
||||
{
|
||||
.name = "da9062-regulators",
|
||||
.num_resources = ARRAY_SIZE(da9062_regulators_resources),
|
||||
.resources = da9062_regulators_resources,
|
||||
},
|
||||
{
|
||||
.name = "da9062-watchdog",
|
||||
.num_resources = ARRAY_SIZE(da9062_wdt_resources),
|
||||
.resources = da9062_wdt_resources,
|
||||
.of_compatible = "dlg,da9062-watchdog",
|
||||
},
|
||||
{
|
||||
.name = "da9062-thermal",
|
||||
.num_resources = ARRAY_SIZE(da9062_thermal_resources),
|
||||
.resources = da9062_thermal_resources,
|
||||
.of_compatible = "dlg,da9062-thermal",
|
||||
},
|
||||
{
|
||||
.name = "da9062-rtc",
|
||||
.num_resources = ARRAY_SIZE(da9062_rtc_resources),
|
||||
.resources = da9062_rtc_resources,
|
||||
.of_compatible = "dlg,da9062-rtc",
|
||||
},
|
||||
{
|
||||
.name = "da9062-onkey",
|
||||
.num_resources = ARRAY_SIZE(da9062_onkey_resources),
|
||||
.resources = da9062_onkey_resources,
|
||||
.of_compatible = "dlg,da9062-onkey",
|
||||
},
|
||||
{
|
||||
.name = "da9062-gpio",
|
||||
.num_resources = ARRAY_SIZE(da9062_gpio_resources),
|
||||
.resources = da9062_gpio_resources,
|
||||
.of_compatible = "dlg,da9062-gpio",
|
||||
},
|
||||
static const struct mfd_cell da9062_devs_irq[] = {
|
||||
MFD_CELL_OF("da9062-core", da9062_core_resources, NULL, 0, 0,
|
||||
NULL),
|
||||
MFD_CELL_OF("da9062-regulators", da9062_regulators_resources, NULL, 0, 0,
|
||||
NULL),
|
||||
MFD_CELL_OF("da9062-watchdog", da9062_wdt_resources, NULL, 0, 0,
|
||||
"dlg,da9062-watchdog"),
|
||||
MFD_CELL_OF("da9062-thermal", da9062_thermal_resources, NULL, 0, 0,
|
||||
"dlg,da9062-thermal"),
|
||||
MFD_CELL_OF("da9062-rtc", da9062_rtc_resources, NULL, 0, 0,
|
||||
"dlg,da9062-rtc"),
|
||||
MFD_CELL_OF("da9062-onkey", da9062_onkey_resources, NULL, 0, 0,
|
||||
"dlg,da9062-onkey"),
|
||||
MFD_CELL_OF("da9062-gpio", da9062_gpio_resources, NULL, 0, 0,
|
||||
"dlg,da9062-gpio"),
|
||||
};
|
||||
|
||||
static const struct mfd_cell da9062_devs_noirq[] = {
|
||||
MFD_CELL_OF("da9062-core", NULL, NULL, 0, 0, NULL),
|
||||
MFD_CELL_OF("da9062-regulators", NULL, NULL, 0, 0, NULL),
|
||||
MFD_CELL_OF("da9062-watchdog", NULL, NULL, 0, 0, "dlg,da9062-watchdog"),
|
||||
MFD_CELL_OF("da9062-thermal", NULL, NULL, 0, 0, "dlg,da9062-thermal"),
|
||||
MFD_CELL_OF("da9062-rtc", NULL, NULL, 0, 0, "dlg,da9062-rtc"),
|
||||
MFD_CELL_OF("da9062-onkey", NULL, NULL, 0, 0, "dlg,da9062-onkey"),
|
||||
MFD_CELL_OF("da9062-gpio", NULL, NULL, 0, 0, "dlg,da9062-gpio"),
|
||||
};
|
||||
|
||||
static int da9062_clear_fault_log(struct da9062 *chip)
|
||||
@ -625,7 +599,7 @@ static int da9062_i2c_probe(struct i2c_client *i2c)
|
||||
{
|
||||
const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
|
||||
struct da9062 *chip;
|
||||
unsigned int irq_base;
|
||||
unsigned int irq_base = 0;
|
||||
const struct mfd_cell *cell;
|
||||
const struct regmap_irq_chip *irq_chip;
|
||||
const struct regmap_config *config;
|
||||
@ -645,22 +619,16 @@ static int da9062_i2c_probe(struct i2c_client *i2c)
|
||||
i2c_set_clientdata(i2c, chip);
|
||||
chip->dev = &i2c->dev;
|
||||
|
||||
if (!i2c->irq) {
|
||||
dev_err(chip->dev, "No IRQ configured\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Start with a base configuration without IRQ */
|
||||
switch (chip->chip_type) {
|
||||
case COMPAT_TYPE_DA9061:
|
||||
cell = da9061_devs;
|
||||
cell_num = ARRAY_SIZE(da9061_devs);
|
||||
irq_chip = &da9061_irq_chip;
|
||||
cell = da9061_devs_noirq;
|
||||
cell_num = ARRAY_SIZE(da9061_devs_noirq);
|
||||
config = &da9061_regmap_config;
|
||||
break;
|
||||
case COMPAT_TYPE_DA9062:
|
||||
cell = da9062_devs;
|
||||
cell_num = ARRAY_SIZE(da9062_devs);
|
||||
irq_chip = &da9062_irq_chip;
|
||||
cell = da9062_devs_noirq;
|
||||
cell_num = ARRAY_SIZE(da9062_devs_noirq);
|
||||
config = &da9062_regmap_config;
|
||||
break;
|
||||
default:
|
||||
@ -695,29 +663,43 @@ static int da9062_i2c_probe(struct i2c_client *i2c)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = da9062_configure_irq_type(chip, i2c->irq, &trigger_type);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "Failed to configure IRQ type\n");
|
||||
return ret;
|
||||
}
|
||||
/* If IRQ is available, reconfigure it accordingly */
|
||||
if (i2c->irq) {
|
||||
if (chip->chip_type == COMPAT_TYPE_DA9061) {
|
||||
cell = da9061_devs_irq;
|
||||
cell_num = ARRAY_SIZE(da9061_devs_irq);
|
||||
irq_chip = &da9061_irq_chip;
|
||||
} else {
|
||||
cell = da9062_devs_irq;
|
||||
cell_num = ARRAY_SIZE(da9062_devs_irq);
|
||||
irq_chip = &da9062_irq_chip;
|
||||
}
|
||||
|
||||
ret = regmap_add_irq_chip(chip->regmap, i2c->irq,
|
||||
trigger_type | IRQF_SHARED | IRQF_ONESHOT,
|
||||
-1, irq_chip, &chip->regmap_irq);
|
||||
if (ret) {
|
||||
dev_err(chip->dev, "Failed to request IRQ %d: %d\n",
|
||||
i2c->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
ret = da9062_configure_irq_type(chip, i2c->irq, &trigger_type);
|
||||
if (ret < 0) {
|
||||
dev_err(chip->dev, "Failed to configure IRQ type\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
irq_base = regmap_irq_chip_get_base(chip->regmap_irq);
|
||||
ret = regmap_add_irq_chip(chip->regmap, i2c->irq,
|
||||
trigger_type | IRQF_SHARED | IRQF_ONESHOT,
|
||||
-1, irq_chip, &chip->regmap_irq);
|
||||
if (ret) {
|
||||
dev_err(chip->dev, "Failed to request IRQ %d: %d\n",
|
||||
i2c->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
irq_base = regmap_irq_chip_get_base(chip->regmap_irq);
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, cell,
|
||||
cell_num, NULL, irq_base,
|
||||
NULL);
|
||||
if (ret) {
|
||||
dev_err(chip->dev, "Cannot register child devices\n");
|
||||
regmap_del_irq_chip(i2c->irq, chip->regmap_irq);
|
||||
if (i2c->irq)
|
||||
regmap_del_irq_chip(i2c->irq, chip->regmap_irq);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -827,6 +827,7 @@ out_stop_rx:
|
||||
dln2_stop_rx_urbs(dln2);
|
||||
|
||||
out_free:
|
||||
usb_put_dev(dln2->usb_dev);
|
||||
dln2_free(dln2);
|
||||
|
||||
return ret;
|
||||
|
@ -528,7 +528,6 @@ static void __exit ezx_pcap_exit(void)
|
||||
subsys_initcall(ezx_pcap_init);
|
||||
module_exit(ezx_pcap_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Daniel Ribeiro / Harald Welte");
|
||||
MODULE_DESCRIPTION("Motorola PCAP2 ASIC Driver");
|
||||
MODULE_ALIAS("spi:ezx-pcap");
|
||||
|
@ -50,7 +50,6 @@ MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match);
|
||||
static int hi6421_pmic_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct hi6421_pmic *pmic;
|
||||
struct resource *res;
|
||||
const struct of_device_id *id;
|
||||
const struct mfd_cell *subdevs;
|
||||
enum hi6421_type type;
|
||||
@ -66,8 +65,7 @@ static int hi6421_pmic_probe(struct platform_device *pdev)
|
||||
if (!pmic)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(&pdev->dev, res);
|
||||
base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
|
@ -447,6 +447,21 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0x7e79), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7e7a), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7e7b), (kernel_ulong_t)&bxt_i2c_info },
|
||||
/* MTP-S */
|
||||
{ PCI_VDEVICE(INTEL, 0x7f28), (kernel_ulong_t)&bxt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f29), (kernel_ulong_t)&bxt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f2a), (kernel_ulong_t)&tgl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f2b), (kernel_ulong_t)&tgl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f4c), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f4d), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f4e), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f4f), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f5c), (kernel_ulong_t)&bxt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f5d), (kernel_ulong_t)&bxt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f5e), (kernel_ulong_t)&tgl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f5f), (kernel_ulong_t)&tgl_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f7a), (kernel_ulong_t)&bxt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x7f7b), (kernel_ulong_t)&bxt_i2c_info },
|
||||
/* LKF */
|
||||
{ PCI_VDEVICE(INTEL, 0x98a8), (kernel_ulong_t)&bxt_uart_info },
|
||||
{ PCI_VDEVICE(INTEL, 0x98a9), (kernel_ulong_t)&bxt_uart_info },
|
||||
|
@ -159,11 +159,19 @@ static const struct dmi_system_id cht_wc_model_dmi_ids[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
|
||||
},
|
||||
}, {
|
||||
/* Lenovo Yoga Book X90F / X91F / X91L */
|
||||
/* Lenovo Yoga Book X90F / X90L */
|
||||
.driver_data = (void *)(long)INTEL_CHT_WC_LENOVO_YOGABOOK1,
|
||||
.matches = {
|
||||
/* Non exact match to match all versions */
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"),
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
|
||||
},
|
||||
}, {
|
||||
/* Lenovo Yoga Book X91F / X91L */
|
||||
.driver_data = (void *)(long)INTEL_CHT_WC_LENOVO_YOGABOOK1,
|
||||
.matches = {
|
||||
/* Non exact match to match F + L versions */
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X91"),
|
||||
},
|
||||
}, {
|
||||
/* Lenovo Yoga Tab 3 Pro YT3-X90F */
|
||||
|
@ -271,6 +271,5 @@ static struct i2c_driver crystal_cove_i2c_driver = {
|
||||
module_i2c_driver(crystal_cove_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("I2C driver for Intel SoC PMIC");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Yang, Bin <bin.yang@intel.com>");
|
||||
MODULE_AUTHOR("Zhu, Lejun <lejun.zhu@linux.intel.com>");
|
||||
|
@ -381,7 +381,6 @@ static int __maybe_unused micro_resume(struct device *dev)
|
||||
static int __init micro_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ipaq_micro *micro;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
int irq;
|
||||
|
||||
@ -391,8 +390,7 @@ static int __init micro_probe(struct platform_device *pdev)
|
||||
|
||||
micro->dev = &pdev->dev;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
micro->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
micro->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(micro->base))
|
||||
return PTR_ERR(micro->base);
|
||||
|
||||
|
@ -112,7 +112,7 @@ static int khadas_mcu_probe(struct i2c_client *client)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (of_find_property(dev->of_node, "#cooling-cells", NULL))
|
||||
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),
|
||||
|
@ -244,4 +244,3 @@ module_exit(lp8788_exit);
|
||||
|
||||
MODULE_DESCRIPTION("TI LP8788 MFD Driver");
|
||||
MODULE_AUTHOR("Milo Kim");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -33,32 +33,6 @@ static struct device_type mfd_dev_type = {
|
||||
.name = "mfd_device",
|
||||
};
|
||||
|
||||
int mfd_cell_enable(struct platform_device *pdev)
|
||||
{
|
||||
const struct mfd_cell *cell = mfd_get_cell(pdev);
|
||||
|
||||
if (!cell->enable) {
|
||||
dev_dbg(&pdev->dev, "No .enable() call-back registered\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cell->enable(pdev);
|
||||
}
|
||||
EXPORT_SYMBOL(mfd_cell_enable);
|
||||
|
||||
int mfd_cell_disable(struct platform_device *pdev)
|
||||
{
|
||||
const struct mfd_cell *cell = mfd_get_cell(pdev);
|
||||
|
||||
if (!cell->disable) {
|
||||
dev_dbg(&pdev->dev, "No .disable() call-back registered\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cell->disable(pdev);
|
||||
}
|
||||
EXPORT_SYMBOL(mfd_cell_disable);
|
||||
|
||||
#if IS_ENABLED(CONFIG_ACPI)
|
||||
struct match_ids_walk_data {
|
||||
struct acpi_device_id *ids;
|
||||
|
@ -130,6 +130,7 @@ static const struct regmap_config ocelot_spi_regmap_config = {
|
||||
|
||||
.write_flag_mask = 0x80,
|
||||
|
||||
.use_single_read = true,
|
||||
.use_single_write = true,
|
||||
.can_multi_write = false,
|
||||
|
||||
|
@ -853,7 +853,6 @@ static struct platform_driver usbhs_omap_driver = {
|
||||
MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
|
||||
MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
|
||||
MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("usb host common core driver for omap EHCI and OHCI");
|
||||
|
||||
static int omap_usbhs_drvinit(void)
|
||||
|
@ -125,11 +125,6 @@ static inline void usbtll_writeb(void __iomem *base, u32 reg, u8 val)
|
||||
writeb_relaxed(val, base + reg);
|
||||
}
|
||||
|
||||
static inline u8 usbtll_readb(void __iomem *base, u32 reg)
|
||||
{
|
||||
return readb_relaxed(base + reg);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
|
||||
@ -450,7 +445,6 @@ EXPORT_SYMBOL_GPL(omap_tll_disable);
|
||||
|
||||
MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
|
||||
MODULE_AUTHOR("Roger Quadros <rogerq@ti.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("usb tll driver for TI OMAP EHCI and OHCI controllers");
|
||||
|
||||
static int __init omap_usbtll_drvinit(void)
|
||||
|
@ -44,37 +44,16 @@ enum {
|
||||
#define PM8008_GPIO1_ADDR PM8008_PERIPH_2_BASE
|
||||
#define PM8008_GPIO2_ADDR PM8008_PERIPH_3_BASE
|
||||
|
||||
#define PM8008_STATUS_BASE (PM8008_PERIPH_0_BASE | INT_LATCHED_STS_OFFSET)
|
||||
#define PM8008_MASK_BASE (PM8008_PERIPH_0_BASE | INT_EN_SET_OFFSET)
|
||||
#define PM8008_UNMASK_BASE (PM8008_PERIPH_0_BASE | INT_EN_CLR_OFFSET)
|
||||
#define PM8008_TYPE_BASE (PM8008_PERIPH_0_BASE | INT_SET_TYPE_OFFSET)
|
||||
#define PM8008_ACK_BASE (PM8008_PERIPH_0_BASE | INT_LATCHED_CLR_OFFSET)
|
||||
#define PM8008_POLARITY_HI_BASE (PM8008_PERIPH_0_BASE | INT_POL_HIGH_OFFSET)
|
||||
#define PM8008_POLARITY_LO_BASE (PM8008_PERIPH_0_BASE | INT_POL_LOW_OFFSET)
|
||||
|
||||
#define PM8008_PERIPH_OFFSET(paddr) (paddr - PM8008_PERIPH_0_BASE)
|
||||
|
||||
static unsigned int p0_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_0_BASE)};
|
||||
static unsigned int p1_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_1_BASE)};
|
||||
static unsigned int p2_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_2_BASE)};
|
||||
static unsigned int p3_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_3_BASE)};
|
||||
|
||||
static struct regmap_irq_sub_irq_map pm8008_sub_reg_offsets[] = {
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(p0_offs),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(p1_offs),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(p2_offs),
|
||||
REGMAP_IRQ_MAIN_REG_OFFSET(p3_offs),
|
||||
};
|
||||
|
||||
static unsigned int pm8008_virt_regs[] = {
|
||||
PM8008_POLARITY_HI_BASE,
|
||||
PM8008_POLARITY_LO_BASE,
|
||||
};
|
||||
|
||||
enum {
|
||||
SET_TYPE_INDEX,
|
||||
POLARITY_HI_INDEX,
|
||||
POLARITY_LO_INDEX,
|
||||
PM8008_NUM_VIRT_REGS,
|
||||
};
|
||||
|
||||
static unsigned int pm8008_config_regs[] = {
|
||||
INT_SET_TYPE_OFFSET,
|
||||
INT_POL_HIGH_OFFSET,
|
||||
INT_POL_LOW_OFFSET,
|
||||
};
|
||||
|
||||
static struct regmap_irq pm8008_irqs[] = {
|
||||
@ -88,32 +67,54 @@ static struct regmap_irq pm8008_irqs[] = {
|
||||
REGMAP_IRQ_REG(PM8008_IRQ_GPIO2, PM8008_GPIO2, BIT(0)),
|
||||
};
|
||||
|
||||
static int pm8008_set_type_virt(unsigned int **virt_buf,
|
||||
unsigned int type, unsigned long hwirq,
|
||||
int reg)
|
||||
static const unsigned int pm8008_periph_base[] = {
|
||||
PM8008_PERIPH_0_BASE,
|
||||
PM8008_PERIPH_1_BASE,
|
||||
PM8008_PERIPH_2_BASE,
|
||||
PM8008_PERIPH_3_BASE,
|
||||
};
|
||||
|
||||
static unsigned int pm8008_get_irq_reg(struct regmap_irq_chip_data *data,
|
||||
unsigned int base, int index)
|
||||
{
|
||||
/* Simple linear addressing for the main status register */
|
||||
if (base == I2C_INTR_STATUS_BASE)
|
||||
return base + index;
|
||||
|
||||
return pm8008_periph_base[index] + base;
|
||||
}
|
||||
|
||||
static int pm8008_set_type_config(unsigned int **buf, unsigned int type,
|
||||
const struct regmap_irq *irq_data, int idx,
|
||||
void *irq_drv_data)
|
||||
{
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
virt_buf[POLARITY_HI_INDEX][reg] &= ~pm8008_irqs[hwirq].mask;
|
||||
virt_buf[POLARITY_LO_INDEX][reg] |= pm8008_irqs[hwirq].mask;
|
||||
buf[POLARITY_HI_INDEX][idx] &= ~irq_data->mask;
|
||||
buf[POLARITY_LO_INDEX][idx] |= irq_data->mask;
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
virt_buf[POLARITY_HI_INDEX][reg] |= pm8008_irqs[hwirq].mask;
|
||||
virt_buf[POLARITY_LO_INDEX][reg] &= ~pm8008_irqs[hwirq].mask;
|
||||
buf[POLARITY_HI_INDEX][idx] |= irq_data->mask;
|
||||
buf[POLARITY_LO_INDEX][idx] &= ~irq_data->mask;
|
||||
break;
|
||||
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
virt_buf[POLARITY_HI_INDEX][reg] |= pm8008_irqs[hwirq].mask;
|
||||
virt_buf[POLARITY_LO_INDEX][reg] |= pm8008_irqs[hwirq].mask;
|
||||
buf[POLARITY_HI_INDEX][idx] |= irq_data->mask;
|
||||
buf[POLARITY_LO_INDEX][idx] |= irq_data->mask;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type & IRQ_TYPE_EDGE_BOTH)
|
||||
buf[SET_TYPE_INDEX][idx] |= irq_data->mask;
|
||||
else
|
||||
buf[SET_TYPE_INDEX][idx] &= ~irq_data->mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -121,20 +122,19 @@ static struct regmap_irq_chip pm8008_irq_chip = {
|
||||
.name = "pm8008_irq",
|
||||
.main_status = I2C_INTR_STATUS_BASE,
|
||||
.num_main_regs = 1,
|
||||
.num_virt_regs = PM8008_NUM_VIRT_REGS,
|
||||
.irqs = pm8008_irqs,
|
||||
.num_irqs = ARRAY_SIZE(pm8008_irqs),
|
||||
.num_regs = PM8008_NUM_PERIPHS,
|
||||
.not_fixed_stride = true,
|
||||
.sub_reg_offsets = pm8008_sub_reg_offsets,
|
||||
.set_type_virt = pm8008_set_type_virt,
|
||||
.status_base = PM8008_STATUS_BASE,
|
||||
.mask_base = PM8008_MASK_BASE,
|
||||
.unmask_base = PM8008_UNMASK_BASE,
|
||||
.type_base = PM8008_TYPE_BASE,
|
||||
.ack_base = PM8008_ACK_BASE,
|
||||
.virt_reg_base = pm8008_virt_regs,
|
||||
.num_type_reg = PM8008_NUM_PERIPHS,
|
||||
.status_base = INT_LATCHED_STS_OFFSET,
|
||||
.mask_base = INT_EN_CLR_OFFSET,
|
||||
.unmask_base = INT_EN_SET_OFFSET,
|
||||
.mask_unmask_non_inverted = true,
|
||||
.ack_base = INT_LATCHED_CLR_OFFSET,
|
||||
.config_base = pm8008_config_regs,
|
||||
.num_config_bases = ARRAY_SIZE(pm8008_config_regs),
|
||||
.num_config_regs = PM8008_NUM_PERIPHS,
|
||||
.set_type_config = pm8008_set_type_config,
|
||||
.get_irq_reg = pm8008_get_irq_reg,
|
||||
};
|
||||
|
||||
static struct regmap_config qcom_mfd_regmap_cfg = {
|
||||
@ -143,30 +143,6 @@ static struct regmap_config qcom_mfd_regmap_cfg = {
|
||||
.max_register = 0xFFFF,
|
||||
};
|
||||
|
||||
static int pm8008_init(struct regmap *regmap)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Set TEMP_ALARM peripheral's TYPE so that the regmap-irq framework
|
||||
* reads this as the default value instead of zero, the HW default.
|
||||
* This is required to enable the writing of TYPE registers in
|
||||
* regmap_irq_sync_unlock().
|
||||
*/
|
||||
rc = regmap_write(regmap, (PM8008_TEMP_ALARM_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Do the same for GPIO1 and GPIO2 peripherals */
|
||||
rc = regmap_write(regmap, (PM8008_GPIO1_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = regmap_write(regmap, (PM8008_GPIO2_ADDR | INT_SET_TYPE_OFFSET), BIT(0));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int pm8008_probe_irq_peripherals(struct device *dev,
|
||||
struct regmap *regmap,
|
||||
int client_irq)
|
||||
@ -175,20 +151,10 @@ static int pm8008_probe_irq_peripherals(struct device *dev,
|
||||
struct regmap_irq_type *type;
|
||||
struct regmap_irq_chip_data *irq_data;
|
||||
|
||||
rc = pm8008_init(regmap);
|
||||
if (rc) {
|
||||
dev_err(dev, "Init failed: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(pm8008_irqs); i++) {
|
||||
type = &pm8008_irqs[i].type;
|
||||
|
||||
type->type_reg_offset = pm8008_irqs[i].reg_offset;
|
||||
type->type_rising_val = pm8008_irqs[i].mask;
|
||||
type->type_falling_val = pm8008_irqs[i].mask;
|
||||
type->type_level_high_val = 0;
|
||||
type->type_level_low_val = 0;
|
||||
type->type_reg_offset = pm8008_irqs[i].reg_offset;
|
||||
|
||||
if (type->type_reg_offset == PM8008_MISC)
|
||||
type->types_supported = IRQ_TYPE_EDGE_RISING;
|
||||
|
@ -530,7 +530,6 @@ static int qcom_rpm_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
struct device_node *syscon_np;
|
||||
struct resource *res;
|
||||
struct qcom_rpm *rpm;
|
||||
u32 fw_version[3];
|
||||
int irq_wakeup;
|
||||
@ -576,8 +575,7 @@ static int qcom_rpm_probe(struct platform_device *pdev)
|
||||
return -ENODEV;
|
||||
rpm->data = match->data;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
rpm->status_regs = devm_ioremap_resource(&pdev->dev, res);
|
||||
rpm->status_regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(rpm->status_regs))
|
||||
return PTR_ERR(rpm->status_regs);
|
||||
rpm->ctrl_regs = rpm->status_regs + 0x400;
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include <linux/mfd/rsmu.h>
|
||||
|
||||
#define RSMU_CM_SCSR_BASE 0x20100000
|
||||
|
||||
int rsmu_core_init(struct rsmu_ddata *rsmu);
|
||||
void rsmu_core_exit(struct rsmu_ddata *rsmu);
|
||||
|
||||
|
@ -18,11 +18,12 @@
|
||||
#include "rsmu.h"
|
||||
|
||||
/*
|
||||
* 16-bit register address: the lower 8 bits of the register address come
|
||||
* from the offset addr byte and the upper 8 bits come from the page register.
|
||||
* 32-bit register address: the lower 8 bits of the register address come
|
||||
* from the offset addr byte and the upper 24 bits come from the page register.
|
||||
*/
|
||||
#define RSMU_CM_PAGE_ADDR 0xFD
|
||||
#define RSMU_CM_PAGE_WINDOW 256
|
||||
#define RSMU_CM_PAGE_ADDR 0xFC
|
||||
#define RSMU_CM_PAGE_MASK 0xFFFFFF00
|
||||
#define RSMU_CM_ADDRESS_MASK 0x000000FF
|
||||
|
||||
/*
|
||||
* 15-bit register address: the lower 7 bits of the register address come
|
||||
@ -31,18 +32,6 @@
|
||||
#define RSMU_SABRE_PAGE_ADDR 0x7F
|
||||
#define RSMU_SABRE_PAGE_WINDOW 128
|
||||
|
||||
static const struct regmap_range_cfg rsmu_cm_range_cfg[] = {
|
||||
{
|
||||
.range_min = 0,
|
||||
.range_max = 0xD000,
|
||||
.selector_reg = RSMU_CM_PAGE_ADDR,
|
||||
.selector_mask = 0xFF,
|
||||
.selector_shift = 0,
|
||||
.window_start = 0,
|
||||
.window_len = RSMU_CM_PAGE_WINDOW,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct regmap_range_cfg rsmu_sabre_range_cfg[] = {
|
||||
{
|
||||
.range_min = 0,
|
||||
@ -55,16 +44,6 @@ static const struct regmap_range_cfg rsmu_sabre_range_cfg[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static bool rsmu_cm_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case RSMU_CM_PAGE_ADDR:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rsmu_sabre_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
@ -75,15 +54,131 @@ static bool rsmu_sabre_volatile_reg(struct device *dev, unsigned int reg)
|
||||
}
|
||||
}
|
||||
|
||||
static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(rsmu->dev);
|
||||
struct i2c_msg msg[2];
|
||||
int cnt;
|
||||
|
||||
msg[0].addr = client->addr;
|
||||
msg[0].flags = 0;
|
||||
msg[0].len = 1;
|
||||
msg[0].buf = ®
|
||||
|
||||
msg[1].addr = client->addr;
|
||||
msg[1].flags = I2C_M_RD;
|
||||
msg[1].len = bytes;
|
||||
msg[1].buf = buf;
|
||||
|
||||
cnt = i2c_transfer(client->adapter, msg, 2);
|
||||
|
||||
if (cnt < 0) {
|
||||
dev_err(rsmu->dev, "i2c_transfer failed at addr: %04x!", reg);
|
||||
return cnt;
|
||||
} else if (cnt != 2) {
|
||||
dev_err(rsmu->dev,
|
||||
"i2c_transfer sent only %d of 2 messages", cnt);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(rsmu->dev);
|
||||
u8 msg[RSMU_MAX_WRITE_COUNT + 1]; /* 1 Byte added for the device register */
|
||||
int cnt;
|
||||
|
||||
if (bytes > RSMU_MAX_WRITE_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
msg[0] = reg;
|
||||
memcpy(&msg[1], buf, bytes);
|
||||
|
||||
cnt = i2c_master_send(client, msg, bytes + 1);
|
||||
|
||||
if (cnt < 0) {
|
||||
dev_err(&client->dev,
|
||||
"i2c_master_send failed at addr: %04x!", reg);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg)
|
||||
{
|
||||
u32 page = reg & RSMU_CM_PAGE_MASK;
|
||||
u8 buf[4];
|
||||
int err;
|
||||
|
||||
/* Do not modify offset register for none-scsr registers */
|
||||
if (reg < RSMU_CM_SCSR_BASE)
|
||||
return 0;
|
||||
|
||||
/* Simply return if we are on the same page */
|
||||
if (rsmu->page == page)
|
||||
return 0;
|
||||
|
||||
buf[0] = 0x0;
|
||||
buf[1] = (u8)((page >> 8) & 0xFF);
|
||||
buf[2] = (u8)((page >> 16) & 0xFF);
|
||||
buf[3] = (u8)((page >> 24) & 0xFF);
|
||||
|
||||
err = rsmu_write_device(rsmu, RSMU_CM_PAGE_ADDR, buf, sizeof(buf));
|
||||
if (err)
|
||||
dev_err(rsmu->dev, "Failed to set page offset 0x%x\n", page);
|
||||
else
|
||||
/* Remember the last page */
|
||||
rsmu->page = page;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context);
|
||||
u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK);
|
||||
int err;
|
||||
|
||||
err = rsmu_write_page_register(rsmu, reg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = rsmu_read_device(rsmu, addr, (u8 *)val, 1);
|
||||
if (err)
|
||||
dev_err(rsmu->dev, "Failed to read offset address 0x%x\n", addr);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val)
|
||||
{
|
||||
struct rsmu_ddata *rsmu = i2c_get_clientdata((struct i2c_client *)context);
|
||||
u8 addr = (u8)(reg & RSMU_CM_ADDRESS_MASK);
|
||||
u8 data = (u8)val;
|
||||
int err;
|
||||
|
||||
err = rsmu_write_page_register(rsmu, reg);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = rsmu_write_device(rsmu, addr, &data, 1);
|
||||
if (err)
|
||||
dev_err(rsmu->dev,
|
||||
"Failed to write offset address 0x%x\n", addr);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct regmap_config rsmu_cm_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.reg_bits = 32,
|
||||
.val_bits = 8,
|
||||
.max_register = 0xD000,
|
||||
.ranges = rsmu_cm_range_cfg,
|
||||
.num_ranges = ARRAY_SIZE(rsmu_cm_range_cfg),
|
||||
.volatile_reg = rsmu_cm_volatile_reg,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.can_multi_write = true,
|
||||
.max_register = 0x20120000,
|
||||
.reg_read = rsmu_reg_read,
|
||||
.reg_write = rsmu_reg_write,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
};
|
||||
|
||||
static const struct regmap_config rsmu_sabre_regmap_config = {
|
||||
@ -101,7 +196,7 @@ static const struct regmap_config rsmu_sl_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.val_bits = 8,
|
||||
.reg_format_endian = REGMAP_ENDIAN_BIG,
|
||||
.max_register = 0x339,
|
||||
.max_register = 0x340,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
.can_multi_write = true,
|
||||
};
|
||||
@ -136,7 +231,11 @@ static int rsmu_i2c_probe(struct i2c_client *client)
|
||||
dev_err(rsmu->dev, "Unsupported RSMU device type: %d\n", rsmu->type);
|
||||
return -ENODEV;
|
||||
}
|
||||
rsmu->regmap = devm_regmap_init_i2c(client, cfg);
|
||||
|
||||
if (rsmu->type == RSMU_CM)
|
||||
rsmu->regmap = devm_regmap_init(&client->dev, NULL, client, cfg);
|
||||
else
|
||||
rsmu->regmap = devm_regmap_init_i2c(client, cfg);
|
||||
if (IS_ERR(rsmu->regmap)) {
|
||||
ret = PTR_ERR(rsmu->regmap);
|
||||
dev_err(rsmu->dev, "Failed to allocate register map: %d\n", ret);
|
||||
|
@ -19,19 +19,21 @@
|
||||
|
||||
#define RSMU_CM_PAGE_ADDR 0x7C
|
||||
#define RSMU_SABRE_PAGE_ADDR 0x7F
|
||||
#define RSMU_HIGHER_ADDR_MASK 0xFF80
|
||||
#define RSMU_HIGHER_ADDR_SHIFT 7
|
||||
#define RSMU_LOWER_ADDR_MASK 0x7F
|
||||
#define RSMU_PAGE_MASK 0xFFFFFF80
|
||||
#define RSMU_ADDR_MASK 0x7F
|
||||
|
||||
static int rsmu_read_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes)
|
||||
{
|
||||
struct spi_device *client = to_spi_device(rsmu->dev);
|
||||
struct spi_transfer xfer = {0};
|
||||
struct spi_message msg;
|
||||
u8 cmd[256] = {0};
|
||||
u8 rsp[256] = {0};
|
||||
u8 cmd[RSMU_MAX_READ_COUNT + 1] = {0};
|
||||
u8 rsp[RSMU_MAX_READ_COUNT + 1] = {0};
|
||||
int ret;
|
||||
|
||||
if (bytes > RSMU_MAX_READ_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
cmd[0] = reg | 0x80;
|
||||
xfer.rx_buf = rsp;
|
||||
xfer.len = bytes + 1;
|
||||
@ -66,7 +68,10 @@ static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes
|
||||
struct spi_device *client = to_spi_device(rsmu->dev);
|
||||
struct spi_transfer xfer = {0};
|
||||
struct spi_message msg;
|
||||
u8 cmd[256] = {0};
|
||||
u8 cmd[RSMU_MAX_WRITE_COUNT + 1] = {0};
|
||||
|
||||
if (bytes > RSMU_MAX_WRITE_COUNT)
|
||||
return -EINVAL;
|
||||
|
||||
cmd[0] = reg;
|
||||
memcpy(&cmd[1], buf, bytes);
|
||||
@ -86,26 +91,35 @@ static int rsmu_write_device(struct rsmu_ddata *rsmu, u8 reg, u8 *buf, u16 bytes
|
||||
* 16-bit register address: the lower 7 bits of the register address come
|
||||
* from the offset addr byte and the upper 9 bits come from the page register.
|
||||
*/
|
||||
static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u16 reg)
|
||||
static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u32 reg)
|
||||
{
|
||||
u8 page_reg;
|
||||
u8 buf[2];
|
||||
u8 buf[4];
|
||||
u16 bytes;
|
||||
u16 page;
|
||||
u32 page;
|
||||
int err;
|
||||
|
||||
switch (rsmu->type) {
|
||||
case RSMU_CM:
|
||||
/* Do not modify page register for none-scsr registers */
|
||||
if (reg < RSMU_CM_SCSR_BASE)
|
||||
return 0;
|
||||
page_reg = RSMU_CM_PAGE_ADDR;
|
||||
page = reg & RSMU_HIGHER_ADDR_MASK;
|
||||
page = reg & RSMU_PAGE_MASK;
|
||||
buf[0] = (u8)(page & 0xff);
|
||||
buf[1] = (u8)((page >> 8) & 0xff);
|
||||
bytes = 2;
|
||||
buf[2] = (u8)((page >> 16) & 0xff);
|
||||
buf[3] = (u8)((page >> 24) & 0xff);
|
||||
bytes = 4;
|
||||
break;
|
||||
case RSMU_SABRE:
|
||||
/* Do not modify page register if reg is page register itself */
|
||||
if ((reg & RSMU_ADDR_MASK) == RSMU_ADDR_MASK)
|
||||
return 0;
|
||||
page_reg = RSMU_SABRE_PAGE_ADDR;
|
||||
page = reg >> RSMU_HIGHER_ADDR_SHIFT;
|
||||
buf[0] = (u8)(page & 0xff);
|
||||
page = reg & RSMU_PAGE_MASK;
|
||||
/* The three page bits are located in the single Page Register */
|
||||
buf[0] = (u8)((page >> 7) & 0x7);
|
||||
bytes = 1;
|
||||
break;
|
||||
default:
|
||||
@ -130,7 +144,7 @@ static int rsmu_write_page_register(struct rsmu_ddata *rsmu, u16 reg)
|
||||
static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context);
|
||||
u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK);
|
||||
u8 addr = (u8)(reg & RSMU_ADDR_MASK);
|
||||
int err;
|
||||
|
||||
err = rsmu_write_page_register(rsmu, reg);
|
||||
@ -147,7 +161,7 @@ static int rsmu_reg_read(void *context, unsigned int reg, unsigned int *val)
|
||||
static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val)
|
||||
{
|
||||
struct rsmu_ddata *rsmu = spi_get_drvdata((struct spi_device *)context);
|
||||
u8 addr = (u8)(reg & RSMU_LOWER_ADDR_MASK);
|
||||
u8 addr = (u8)(reg & RSMU_ADDR_MASK);
|
||||
u8 data = (u8)val;
|
||||
int err;
|
||||
|
||||
@ -164,9 +178,9 @@ static int rsmu_reg_write(void *context, unsigned int reg, unsigned int val)
|
||||
}
|
||||
|
||||
static const struct regmap_config rsmu_cm_regmap_config = {
|
||||
.reg_bits = 16,
|
||||
.reg_bits = 32,
|
||||
.val_bits = 8,
|
||||
.max_register = 0xD000,
|
||||
.max_register = 0x20120000,
|
||||
.reg_read = rsmu_reg_read,
|
||||
.reg_write = rsmu_reg_write,
|
||||
.cache_type = REGCACHE_NONE,
|
||||
|
391
drivers/mfd/rz-mtu3.c
Normal file
391
drivers/mfd/rz-mtu3.c
Normal file
@ -0,0 +1,391 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Renesas RZ/G2L Multi-Function Timer Pulse Unit 3(MTU3a) Core driver
|
||||
*
|
||||
* Copyright (C) 2023 Renesas Electronics Corporation
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/rz-mtu3.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "rz-mtu3.h"
|
||||
|
||||
struct rz_mtu3_priv {
|
||||
void __iomem *mmio;
|
||||
struct reset_control *rstc;
|
||||
raw_spinlock_t lock;
|
||||
};
|
||||
|
||||
/******* MTU3 registers (original offset is +0x1200) *******/
|
||||
static const unsigned long rz_mtu3_8bit_ch_reg_offs[][13] = {
|
||||
[RZ_MTU3_CHAN_0] = MTU_8BIT_CH_0(0x104, 0x090, 0x100, 0x128, 0x101, 0x102, 0x103, 0x126),
|
||||
[RZ_MTU3_CHAN_1] = MTU_8BIT_CH_1_2(0x184, 0x091, 0x185, 0x180, 0x194, 0x181, 0x182),
|
||||
[RZ_MTU3_CHAN_2] = MTU_8BIT_CH_1_2(0x204, 0x092, 0x205, 0x200, 0x20c, 0x201, 0x202),
|
||||
[RZ_MTU3_CHAN_3] = MTU_8BIT_CH_3_4_6_7(0x008, 0x093, 0x02c, 0x000, 0x04c, 0x002, 0x004, 0x005, 0x038),
|
||||
[RZ_MTU3_CHAN_4] = MTU_8BIT_CH_3_4_6_7(0x009, 0x094, 0x02d, 0x001, 0x04d, 0x003, 0x006, 0x007, 0x039),
|
||||
[RZ_MTU3_CHAN_5] = MTU_8BIT_CH_5(0xab2, 0x1eb, 0xab4, 0xab6, 0xa84, 0xa85, 0xa86, 0xa94, 0xa95, 0xa96, 0xaa4, 0xaa5, 0xaa6),
|
||||
[RZ_MTU3_CHAN_6] = MTU_8BIT_CH_3_4_6_7(0x808, 0x893, 0x82c, 0x800, 0x84c, 0x802, 0x804, 0x805, 0x838),
|
||||
[RZ_MTU3_CHAN_7] = MTU_8BIT_CH_3_4_6_7(0x809, 0x894, 0x82d, 0x801, 0x84d, 0x803, 0x806, 0x807, 0x839),
|
||||
[RZ_MTU3_CHAN_8] = MTU_8BIT_CH_8(0x404, 0x098, 0x400, 0x406, 0x401, 0x402, 0x403)
|
||||
};
|
||||
|
||||
static const unsigned long rz_mtu3_16bit_ch_reg_offs[][12] = {
|
||||
[RZ_MTU3_CHAN_0] = MTU_16BIT_CH_0(0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x120, 0x122),
|
||||
[RZ_MTU3_CHAN_1] = MTU_16BIT_CH_1_2(0x186, 0x188, 0x18a),
|
||||
[RZ_MTU3_CHAN_2] = MTU_16BIT_CH_1_2(0x206, 0x208, 0x20a),
|
||||
[RZ_MTU3_CHAN_3] = MTU_16BIT_CH_3_6(0x010, 0x018, 0x01a, 0x024, 0x026, 0x072),
|
||||
[RZ_MTU3_CHAN_4] = MTU_16BIT_CH_4_7(0x012, 0x01c, 0x01e, 0x028, 0x2a, 0x074, 0x076, 0x040, 0x044, 0x046, 0x048, 0x04a),
|
||||
[RZ_MTU3_CHAN_5] = MTU_16BIT_CH_5(0xa80, 0xa82, 0xa90, 0xa92, 0xaa0, 0xaa2),
|
||||
[RZ_MTU3_CHAN_6] = MTU_16BIT_CH_3_6(0x810, 0x818, 0x81a, 0x824, 0x826, 0x872),
|
||||
[RZ_MTU3_CHAN_7] = MTU_16BIT_CH_4_7(0x812, 0x81c, 0x81e, 0x828, 0x82a, 0x874, 0x876, 0x840, 0x844, 0x846, 0x848, 0x84a)
|
||||
};
|
||||
|
||||
static const unsigned long rz_mtu3_32bit_ch_reg_offs[][5] = {
|
||||
[RZ_MTU3_CHAN_1] = MTU_32BIT_CH_1(0x1a0, 0x1a4, 0x1a8),
|
||||
[RZ_MTU3_CHAN_8] = MTU_32BIT_CH_8(0x408, 0x40c, 0x410, 0x414, 0x418)
|
||||
};
|
||||
|
||||
static bool rz_mtu3_is_16bit_shared_reg(u16 offset)
|
||||
{
|
||||
return (offset == RZ_MTU3_TDDRA || offset == RZ_MTU3_TDDRB ||
|
||||
offset == RZ_MTU3_TCDRA || offset == RZ_MTU3_TCDRB ||
|
||||
offset == RZ_MTU3_TCBRA || offset == RZ_MTU3_TCBRB ||
|
||||
offset == RZ_MTU3_TCNTSA || offset == RZ_MTU3_TCNTSB);
|
||||
}
|
||||
|
||||
u16 rz_mtu3_shared_reg_read(struct rz_mtu3_channel *ch, u16 offset)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
|
||||
if (rz_mtu3_is_16bit_shared_reg(offset))
|
||||
return readw(priv->mmio + offset);
|
||||
else
|
||||
return readb(priv->mmio + offset);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_read);
|
||||
|
||||
u8 rz_mtu3_8bit_ch_read(struct rz_mtu3_channel *ch, u16 offset)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
u16 ch_offs;
|
||||
|
||||
ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset];
|
||||
|
||||
return readb(priv->mmio + ch_offs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_read);
|
||||
|
||||
u16 rz_mtu3_16bit_ch_read(struct rz_mtu3_channel *ch, u16 offset)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
u16 ch_offs;
|
||||
|
||||
/* MTU8 doesn't have 16-bit registers */
|
||||
if (ch->channel_number == RZ_MTU3_CHAN_8)
|
||||
return 0;
|
||||
|
||||
ch_offs = rz_mtu3_16bit_ch_reg_offs[ch->channel_number][offset];
|
||||
|
||||
return readw(priv->mmio + ch_offs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_read);
|
||||
|
||||
u32 rz_mtu3_32bit_ch_read(struct rz_mtu3_channel *ch, u16 offset)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
u16 ch_offs;
|
||||
|
||||
if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8)
|
||||
return 0;
|
||||
|
||||
ch_offs = rz_mtu3_32bit_ch_reg_offs[ch->channel_number][offset];
|
||||
|
||||
return readl(priv->mmio + ch_offs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_read);
|
||||
|
||||
void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u8 val)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
u16 ch_offs;
|
||||
|
||||
ch_offs = rz_mtu3_8bit_ch_reg_offs[ch->channel_number][offset];
|
||||
writeb(val, priv->mmio + ch_offs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_8bit_ch_write);
|
||||
|
||||
void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u16 val)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
u16 ch_offs;
|
||||
|
||||
/* MTU8 doesn't have 16-bit registers */
|
||||
if (ch->channel_number == RZ_MTU3_CHAN_8)
|
||||
return;
|
||||
|
||||
ch_offs = rz_mtu3_16bit_ch_reg_offs[ch->channel_number][offset];
|
||||
writew(val, priv->mmio + ch_offs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_16bit_ch_write);
|
||||
|
||||
void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel *ch, u16 offset, u32 val)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
u16 ch_offs;
|
||||
|
||||
if (ch->channel_number != RZ_MTU3_CHAN_1 && ch->channel_number != RZ_MTU3_CHAN_8)
|
||||
return;
|
||||
|
||||
ch_offs = rz_mtu3_32bit_ch_reg_offs[ch->channel_number][offset];
|
||||
writel(val, priv->mmio + ch_offs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_32bit_ch_write);
|
||||
|
||||
void rz_mtu3_shared_reg_write(struct rz_mtu3_channel *ch, u16 offset, u16 value)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
|
||||
if (rz_mtu3_is_16bit_shared_reg(offset))
|
||||
writew(value, priv->mmio + offset);
|
||||
else
|
||||
writeb((u8)value, priv->mmio + offset);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_write);
|
||||
|
||||
void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch, u16 offset,
|
||||
u16 pos, u8 val)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
unsigned long tmdr, flags;
|
||||
|
||||
raw_spin_lock_irqsave(&priv->lock, flags);
|
||||
tmdr = rz_mtu3_shared_reg_read(ch, offset);
|
||||
__assign_bit(pos, &tmdr, !!val);
|
||||
rz_mtu3_shared_reg_write(ch, offset, tmdr);
|
||||
raw_spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_shared_reg_update_bit);
|
||||
|
||||
static u16 rz_mtu3_get_tstr_offset(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
u16 offset;
|
||||
|
||||
switch (ch->channel_number) {
|
||||
case RZ_MTU3_CHAN_0:
|
||||
case RZ_MTU3_CHAN_1:
|
||||
case RZ_MTU3_CHAN_2:
|
||||
case RZ_MTU3_CHAN_3:
|
||||
case RZ_MTU3_CHAN_4:
|
||||
case RZ_MTU3_CHAN_8:
|
||||
offset = RZ_MTU3_TSTRA;
|
||||
break;
|
||||
case RZ_MTU3_CHAN_5:
|
||||
offset = RZ_MTU3_TSTR;
|
||||
break;
|
||||
case RZ_MTU3_CHAN_6:
|
||||
case RZ_MTU3_CHAN_7:
|
||||
offset = RZ_MTU3_TSTRB;
|
||||
break;
|
||||
default:
|
||||
offset = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static u8 rz_mtu3_get_tstr_bit_pos(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
u8 bitpos;
|
||||
|
||||
switch (ch->channel_number) {
|
||||
case RZ_MTU3_CHAN_0:
|
||||
case RZ_MTU3_CHAN_1:
|
||||
case RZ_MTU3_CHAN_2:
|
||||
case RZ_MTU3_CHAN_6:
|
||||
case RZ_MTU3_CHAN_7:
|
||||
bitpos = ch->channel_number;
|
||||
break;
|
||||
case RZ_MTU3_CHAN_3:
|
||||
bitpos = 6;
|
||||
break;
|
||||
case RZ_MTU3_CHAN_4:
|
||||
bitpos = 7;
|
||||
break;
|
||||
case RZ_MTU3_CHAN_5:
|
||||
bitpos = 2;
|
||||
break;
|
||||
case RZ_MTU3_CHAN_8:
|
||||
bitpos = 3;
|
||||
break;
|
||||
default:
|
||||
bitpos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return bitpos;
|
||||
}
|
||||
|
||||
static void rz_mtu3_start_stop_ch(struct rz_mtu3_channel *ch, bool start)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
unsigned long flags, tstr;
|
||||
u16 offset;
|
||||
u8 bitpos;
|
||||
|
||||
/* start stop register shared by multiple timer channels */
|
||||
raw_spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
offset = rz_mtu3_get_tstr_offset(ch);
|
||||
bitpos = rz_mtu3_get_tstr_bit_pos(ch);
|
||||
tstr = rz_mtu3_shared_reg_read(ch, offset);
|
||||
__assign_bit(bitpos, &tstr, start);
|
||||
rz_mtu3_shared_reg_write(ch, offset, tstr);
|
||||
|
||||
raw_spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(ch->dev->parent);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
unsigned long flags, tstr;
|
||||
bool ret = false;
|
||||
u16 offset;
|
||||
u8 bitpos;
|
||||
|
||||
/* start stop register shared by multiple timer channels */
|
||||
raw_spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
offset = rz_mtu3_get_tstr_offset(ch);
|
||||
bitpos = rz_mtu3_get_tstr_bit_pos(ch);
|
||||
tstr = rz_mtu3_shared_reg_read(ch, offset);
|
||||
ret = tstr & BIT(bitpos);
|
||||
|
||||
raw_spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_is_enabled);
|
||||
|
||||
int rz_mtu3_enable(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
/* enable channel */
|
||||
rz_mtu3_start_stop_ch(ch, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_enable);
|
||||
|
||||
void rz_mtu3_disable(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
/* disable channel */
|
||||
rz_mtu3_start_stop_ch(ch, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rz_mtu3_disable);
|
||||
|
||||
static void rz_mtu3_reset_assert(void *data)
|
||||
{
|
||||
struct rz_mtu3 *mtu = dev_get_drvdata(data);
|
||||
struct rz_mtu3_priv *priv = mtu->priv_data;
|
||||
|
||||
mfd_remove_devices(data);
|
||||
reset_control_assert(priv->rstc);
|
||||
}
|
||||
|
||||
static const struct mfd_cell rz_mtu3_devs[] = {
|
||||
{
|
||||
.name = "rz-mtu3-counter",
|
||||
},
|
||||
{
|
||||
.name = "pwm-rz-mtu3",
|
||||
},
|
||||
};
|
||||
|
||||
static int rz_mtu3_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rz_mtu3_priv *priv;
|
||||
struct rz_mtu3 *ddata;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
|
||||
if (!ddata)
|
||||
return -ENOMEM;
|
||||
|
||||
ddata->priv_data = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!ddata->priv_data)
|
||||
return -ENOMEM;
|
||||
|
||||
priv = ddata->priv_data;
|
||||
|
||||
priv->mmio = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(priv->mmio))
|
||||
return PTR_ERR(priv->mmio);
|
||||
|
||||
priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
|
||||
if (IS_ERR(priv->rstc))
|
||||
return PTR_ERR(priv->rstc);
|
||||
|
||||
ddata->clk = devm_clk_get(&pdev->dev, NULL);
|
||||
if (IS_ERR(ddata->clk))
|
||||
return PTR_ERR(ddata->clk);
|
||||
|
||||
reset_control_deassert(priv->rstc);
|
||||
raw_spin_lock_init(&priv->lock);
|
||||
platform_set_drvdata(pdev, ddata);
|
||||
|
||||
for (i = 0; i < RZ_MTU_NUM_CHANNELS; i++) {
|
||||
ddata->channels[i].channel_number = i;
|
||||
ddata->channels[i].is_busy = false;
|
||||
mutex_init(&ddata->channels[i].lock);
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&pdev->dev, 0, rz_mtu3_devs,
|
||||
ARRAY_SIZE(rz_mtu3_devs), NULL, 0, NULL);
|
||||
if (ret < 0)
|
||||
goto err_assert;
|
||||
|
||||
return devm_add_action_or_reset(&pdev->dev, rz_mtu3_reset_assert,
|
||||
&pdev->dev);
|
||||
|
||||
err_assert:
|
||||
reset_control_assert(priv->rstc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id rz_mtu3_of_match[] = {
|
||||
{ .compatible = "renesas,rz-mtu3", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rz_mtu3_of_match);
|
||||
|
||||
static struct platform_driver rz_mtu3_driver = {
|
||||
.probe = rz_mtu3_probe,
|
||||
.driver = {
|
||||
.name = "rz-mtu3",
|
||||
.of_match_table = rz_mtu3_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(rz_mtu3_driver);
|
||||
|
||||
MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>");
|
||||
MODULE_DESCRIPTION("Renesas RZ/G2L MTU3a Core Driver");
|
||||
MODULE_LICENSE("GPL");
|
147
drivers/mfd/rz-mtu3.h
Normal file
147
drivers/mfd/rz-mtu3.h
Normal file
@ -0,0 +1,147 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* MFD internals for Renesas RZ/G2L MTU3 Core driver
|
||||
*
|
||||
* Copyright (C) 2023 Renesas Electronics Corporation
|
||||
*/
|
||||
|
||||
#ifndef RZ_MTU3_MFD_H
|
||||
#define RZ_MTU3_MFD_H
|
||||
|
||||
#define MTU_8BIT_CH_0(_tier, _nfcr, _tcr, _tcr2, _tmdr1, _tiorh, _tiorl, _tbtm) \
|
||||
{ \
|
||||
[RZ_MTU3_TIER] = _tier, \
|
||||
[RZ_MTU3_NFCR] = _nfcr, \
|
||||
[RZ_MTU3_TCR] = _tcr, \
|
||||
[RZ_MTU3_TCR2] = _tcr2, \
|
||||
[RZ_MTU3_TMDR1] = _tmdr1, \
|
||||
[RZ_MTU3_TIORH] = _tiorh, \
|
||||
[RZ_MTU3_TIORL] = _tiorl, \
|
||||
[RZ_MTU3_TBTM] = _tbtm \
|
||||
}
|
||||
|
||||
#define MTU_8BIT_CH_1_2(_tier, _nfcr, _tsr, _tcr, _tcr2, _tmdr1, _tior) \
|
||||
{ \
|
||||
[RZ_MTU3_TIER] = _tier, \
|
||||
[RZ_MTU3_NFCR] = _nfcr, \
|
||||
[RZ_MTU3_TSR] = _tsr, \
|
||||
[RZ_MTU3_TCR] = _tcr, \
|
||||
[RZ_MTU3_TCR2] = _tcr2, \
|
||||
[RZ_MTU3_TMDR1] = _tmdr1, \
|
||||
[RZ_MTU3_TIOR] = _tior \
|
||||
} \
|
||||
|
||||
#define MTU_8BIT_CH_3_4_6_7(_tier, _nfcr, _tsr, _tcr, _tcr2, _tmdr1, _tiorh, _tiorl, _tbtm) \
|
||||
{ \
|
||||
[RZ_MTU3_TIER] = _tier, \
|
||||
[RZ_MTU3_NFCR] = _nfcr, \
|
||||
[RZ_MTU3_TSR] = _tsr, \
|
||||
[RZ_MTU3_TCR] = _tcr, \
|
||||
[RZ_MTU3_TCR2] = _tcr2, \
|
||||
[RZ_MTU3_TMDR1] = _tmdr1, \
|
||||
[RZ_MTU3_TIORH] = _tiorh, \
|
||||
[RZ_MTU3_TIORL] = _tiorl, \
|
||||
[RZ_MTU3_TBTM] = _tbtm \
|
||||
} \
|
||||
|
||||
#define MTU_8BIT_CH_5(_tier, _nfcr, _tstr, _tcntcmpclr, _tcru, _tcr2u, _tioru, \
|
||||
_tcrv, _tcr2v, _tiorv, _tcrw, _tcr2w, _tiorw) \
|
||||
{ \
|
||||
[RZ_MTU3_TIER] = _tier, \
|
||||
[RZ_MTU3_NFCR] = _nfcr, \
|
||||
[RZ_MTU3_TSTR] = _tstr, \
|
||||
[RZ_MTU3_TCNTCMPCLR] = _tcntcmpclr, \
|
||||
[RZ_MTU3_TCRU] = _tcru, \
|
||||
[RZ_MTU3_TCR2U] = _tcr2u, \
|
||||
[RZ_MTU3_TIORU] = _tioru, \
|
||||
[RZ_MTU3_TCRV] = _tcrv, \
|
||||
[RZ_MTU3_TCR2V] = _tcr2v, \
|
||||
[RZ_MTU3_TIORV] = _tiorv, \
|
||||
[RZ_MTU3_TCRW] = _tcrw, \
|
||||
[RZ_MTU3_TCR2W] = _tcr2w, \
|
||||
[RZ_MTU3_TIORW] = _tiorw \
|
||||
} \
|
||||
|
||||
#define MTU_8BIT_CH_8(_tier, _nfcr, _tcr, _tcr2, _tmdr1, _tiorh, _tiorl) \
|
||||
{ \
|
||||
[RZ_MTU3_TIER] = _tier, \
|
||||
[RZ_MTU3_NFCR] = _nfcr, \
|
||||
[RZ_MTU3_TCR] = _tcr, \
|
||||
[RZ_MTU3_TCR2] = _tcr2, \
|
||||
[RZ_MTU3_TMDR1] = _tmdr1, \
|
||||
[RZ_MTU3_TIORH] = _tiorh, \
|
||||
[RZ_MTU3_TIORL] = _tiorl \
|
||||
} \
|
||||
|
||||
#define MTU_16BIT_CH_0(_tcnt, _tgra, _tgrb, _tgrc, _tgrd, _tgre, _tgrf) \
|
||||
{ \
|
||||
[RZ_MTU3_TCNT] = _tcnt, \
|
||||
[RZ_MTU3_TGRA] = _tgra, \
|
||||
[RZ_MTU3_TGRB] = _tgrb, \
|
||||
[RZ_MTU3_TGRC] = _tgrc, \
|
||||
[RZ_MTU3_TGRD] = _tgrd, \
|
||||
[RZ_MTU3_TGRE] = _tgre, \
|
||||
[RZ_MTU3_TGRF] = _tgrf \
|
||||
}
|
||||
|
||||
#define MTU_16BIT_CH_1_2(_tcnt, _tgra, _tgrb) \
|
||||
{ \
|
||||
[RZ_MTU3_TCNT] = _tcnt, \
|
||||
[RZ_MTU3_TGRA] = _tgra, \
|
||||
[RZ_MTU3_TGRB] = _tgrb \
|
||||
}
|
||||
|
||||
#define MTU_16BIT_CH_3_6(_tcnt, _tgra, _tgrb, _tgrc, _tgrd, _tgre) \
|
||||
{ \
|
||||
[RZ_MTU3_TCNT] = _tcnt, \
|
||||
[RZ_MTU3_TGRA] = _tgra, \
|
||||
[RZ_MTU3_TGRB] = _tgrb, \
|
||||
[RZ_MTU3_TGRC] = _tgrc, \
|
||||
[RZ_MTU3_TGRD] = _tgrd, \
|
||||
[RZ_MTU3_TGRE] = _tgre \
|
||||
}
|
||||
|
||||
#define MTU_16BIT_CH_4_7(_tcnt, _tgra, _tgrb, _tgrc, _tgrd, _tgre, _tgrf, \
|
||||
_tadcr, _tadcora, _tadcorb, _tadcobra, _tadcobrb) \
|
||||
{ \
|
||||
[RZ_MTU3_TCNT] = _tcnt, \
|
||||
[RZ_MTU3_TGRA] = _tgra, \
|
||||
[RZ_MTU3_TGRB] = _tgrb, \
|
||||
[RZ_MTU3_TGRC] = _tgrc, \
|
||||
[RZ_MTU3_TGRD] = _tgrd, \
|
||||
[RZ_MTU3_TGRE] = _tgre, \
|
||||
[RZ_MTU3_TGRF] = _tgrf, \
|
||||
[RZ_MTU3_TADCR] = _tadcr, \
|
||||
[RZ_MTU3_TADCORA] = _tadcora, \
|
||||
[RZ_MTU3_TADCORB] = _tadcorb, \
|
||||
[RZ_MTU3_TADCOBRA] = _tadcobra, \
|
||||
[RZ_MTU3_TADCOBRB] = _tadcobrb \
|
||||
}
|
||||
|
||||
#define MTU_16BIT_CH_5(_tcntu, _tgru, _tcntv, _tgrv, _tcntw, _tgrw) \
|
||||
{ \
|
||||
[RZ_MTU3_TCNTU] = _tcntu, \
|
||||
[RZ_MTU3_TGRU] = _tgru, \
|
||||
[RZ_MTU3_TCNTV] = _tcntv, \
|
||||
[RZ_MTU3_TGRV] = _tgrv, \
|
||||
[RZ_MTU3_TCNTW] = _tcntw, \
|
||||
[RZ_MTU3_TGRW] = _tgrw \
|
||||
}
|
||||
|
||||
#define MTU_32BIT_CH_1(_tcntlw, _tgralw, _tgrblw) \
|
||||
{ \
|
||||
[RZ_MTU3_TCNTLW] = _tcntlw, \
|
||||
[RZ_MTU3_TGRALW] = _tgralw, \
|
||||
[RZ_MTU3_TGRBLW] = _tgrblw \
|
||||
}
|
||||
|
||||
#define MTU_32BIT_CH_8(_tcnt, _tgra, _tgrb, _tgrc, _tgrd) \
|
||||
{ \
|
||||
[RZ_MTU3_TCNT] = _tcnt, \
|
||||
[RZ_MTU3_TGRA] = _tgra, \
|
||||
[RZ_MTU3_TGRB] = _tgrb, \
|
||||
[RZ_MTU3_TGRC] = _tgrc, \
|
||||
[RZ_MTU3_TGRD] = _tgrd \
|
||||
}
|
||||
|
||||
#endif
|
@ -24,22 +24,9 @@
|
||||
#include <linux/mfd/samsung/s2mps14.h>
|
||||
#include <linux/mfd/samsung/s2mps15.h>
|
||||
#include <linux/mfd/samsung/s2mpu02.h>
|
||||
#include <linux/mfd/samsung/s5m8763.h>
|
||||
#include <linux/mfd/samsung/s5m8767.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const struct mfd_cell s5m8751_devs[] = {
|
||||
{ .name = "s5m8751-pmic", },
|
||||
{ .name = "s5m-charger", },
|
||||
{ .name = "s5m8751-codec", },
|
||||
};
|
||||
|
||||
static const struct mfd_cell s5m8763_devs[] = {
|
||||
{ .name = "s5m8763-pmic", },
|
||||
{ .name = "s5m-rtc", },
|
||||
{ .name = "s5m-charger", },
|
||||
};
|
||||
|
||||
static const struct mfd_cell s5m8767_devs[] = {
|
||||
{ .name = "s5m8767-pmic", },
|
||||
{ .name = "s5m-rtc", },
|
||||
@ -158,19 +145,6 @@ static bool s2mpu02_volatile(struct device *dev, unsigned int reg)
|
||||
}
|
||||
}
|
||||
|
||||
static bool s5m8763_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case S5M8763_REG_IRQM1:
|
||||
case S5M8763_REG_IRQM2:
|
||||
case S5M8763_REG_IRQM3:
|
||||
case S5M8763_REG_IRQM4:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct regmap_config sec_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@ -230,15 +204,6 @@ static const struct regmap_config s2mpu02_regmap_config = {
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s5m8763_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
|
||||
.max_register = S5M8763_REG_LBCNFG2,
|
||||
.volatile_reg = s5m8763_volatile,
|
||||
.cache_type = REGCACHE_FLAT,
|
||||
};
|
||||
|
||||
static const struct regmap_config s5m8767_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@ -348,9 +313,6 @@ static int sec_pmic_probe(struct i2c_client *i2c)
|
||||
case S2MPS15X:
|
||||
regmap = &s2mps15_regmap_config;
|
||||
break;
|
||||
case S5M8763X:
|
||||
regmap = &s5m8763_regmap_config;
|
||||
break;
|
||||
case S5M8767X:
|
||||
regmap = &s5m8767_regmap_config;
|
||||
break;
|
||||
@ -375,14 +337,6 @@ static int sec_pmic_probe(struct i2c_client *i2c)
|
||||
pm_runtime_set_active(sec_pmic->dev);
|
||||
|
||||
switch (sec_pmic->device_type) {
|
||||
case S5M8751X:
|
||||
sec_devs = s5m8751_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s5m8751_devs);
|
||||
break;
|
||||
case S5M8763X:
|
||||
sec_devs = s5m8763_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s5m8763_devs);
|
||||
break;
|
||||
case S5M8767X:
|
||||
sec_devs = s5m8767_devs;
|
||||
num_sec_devs = ARRAY_SIZE(s5m8767_devs);
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/mfd/samsung/s2mps11.h>
|
||||
#include <linux/mfd/samsung/s2mps14.h>
|
||||
#include <linux/mfd/samsung/s2mpu02.h>
|
||||
#include <linux/mfd/samsung/s5m8763.h>
|
||||
#include <linux/mfd/samsung/s5m8767.h>
|
||||
|
||||
static const struct regmap_irq s2mps11_irqs[] = {
|
||||
@ -297,81 +296,6 @@ static const struct regmap_irq s5m8767_irqs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_irq s5m8763_irqs[] = {
|
||||
[S5M8763_IRQ_DCINF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8763_IRQ_DCINF_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_DCINR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8763_IRQ_DCINR_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_JIGF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8763_IRQ_JIGF_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_JIGR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8763_IRQ_JIGR_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_PWRONF] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8763_IRQ_PWRONF_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_PWRONR] = {
|
||||
.reg_offset = 0,
|
||||
.mask = S5M8763_IRQ_PWRONR_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_WTSREVNT] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S5M8763_IRQ_WTSREVNT_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_SMPLEVNT] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S5M8763_IRQ_SMPLEVNT_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_ALARM1] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S5M8763_IRQ_ALARM1_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_ALARM0] = {
|
||||
.reg_offset = 1,
|
||||
.mask = S5M8763_IRQ_ALARM0_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_ONKEY1S] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8763_IRQ_ONKEY1S_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_TOPOFFR] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8763_IRQ_TOPOFFR_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_DCINOVPR] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8763_IRQ_DCINOVPR_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_CHGRSTF] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8763_IRQ_CHGRSTF_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_DONER] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8763_IRQ_DONER_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_CHGFAULT] = {
|
||||
.reg_offset = 2,
|
||||
.mask = S5M8763_IRQ_CHGFAULT_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_LOBAT1] = {
|
||||
.reg_offset = 3,
|
||||
.mask = S5M8763_IRQ_LOBAT1_MASK,
|
||||
},
|
||||
[S5M8763_IRQ_LOBAT2] = {
|
||||
.reg_offset = 3,
|
||||
.mask = S5M8763_IRQ_LOBAT2_MASK,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip s2mps11_irq_chip = {
|
||||
.name = "s2mps11",
|
||||
.irqs = s2mps11_irqs,
|
||||
@ -425,16 +349,6 @@ static const struct regmap_irq_chip s5m8767_irq_chip = {
|
||||
.ack_base = S5M8767_REG_INT1,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip s5m8763_irq_chip = {
|
||||
.name = "s5m8763",
|
||||
.irqs = s5m8763_irqs,
|
||||
.num_irqs = ARRAY_SIZE(s5m8763_irqs),
|
||||
.num_regs = 4,
|
||||
.status_base = S5M8763_REG_IRQ1,
|
||||
.mask_base = S5M8763_REG_IRQM1,
|
||||
.ack_base = S5M8763_REG_IRQ1,
|
||||
};
|
||||
|
||||
int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -448,9 +362,6 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case S5M8763X:
|
||||
sec_irq_chip = &s5m8763_irq_chip;
|
||||
break;
|
||||
case S5M8767X:
|
||||
sec_irq_chip = &s5m8767_irq_chip;
|
||||
break;
|
||||
|
@ -251,7 +251,7 @@ static int si476x_core_parse_and_nag_about_error(struct si476x_core *core)
|
||||
* @usecs: amount of time to wait before reading the response (in
|
||||
* usecs)
|
||||
*
|
||||
* Function returns 0 on succsess and negative error code on
|
||||
* Function returns 0 on success and negative error code on
|
||||
* failure
|
||||
*/
|
||||
static int si476x_core_send_command(struct si476x_core *core,
|
||||
@ -398,7 +398,7 @@ static int si476x_cmd_tune_seek_freq(struct si476x_core *core,
|
||||
* The command requests the firmware and patch version for currently
|
||||
* loaded firmware (dependent on the function of the device FM/AM/WB)
|
||||
*
|
||||
* Function returns 0 on succsess and negative error code on
|
||||
* Function returns 0 on success and negative error code on
|
||||
* failure
|
||||
*/
|
||||
int si476x_core_cmd_func_info(struct si476x_core *core,
|
||||
@ -429,7 +429,7 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_func_info);
|
||||
* @property: property address
|
||||
* @value: property value
|
||||
*
|
||||
* Function returns 0 on succsess and negative error code on
|
||||
* Function returns 0 on success and negative error code on
|
||||
* failure
|
||||
*/
|
||||
int si476x_core_cmd_set_property(struct si476x_core *core,
|
||||
@ -545,13 +545,13 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_dig_audio_pin_cfg);
|
||||
* SI476X_IQCLK_NOOP - do not modify the behaviour
|
||||
* SI476X_IQCLK_TRISTATE - put the pin in tristate condition,
|
||||
* enable 1MOhm pulldown
|
||||
* SI476X_IQCLK_IQ - set pin to be a part of I/Q interace
|
||||
* SI476X_IQCLK_IQ - set pin to be a part of I/Q interface
|
||||
* in master mode
|
||||
* @iqfs: - IQFS pin function configuration:
|
||||
* SI476X_IQFS_NOOP - do not modify the behaviour
|
||||
* SI476X_IQFS_TRISTATE - put the pin in tristate condition,
|
||||
* enable 1MOhm pulldown
|
||||
* SI476X_IQFS_IQ - set pin to be a part of I/Q interace
|
||||
* SI476X_IQFS_IQ - set pin to be a part of I/Q interface
|
||||
* in master mode
|
||||
* @iout: - IOUT pin function configuration:
|
||||
* SI476X_IOUT_NOOP - do not modify the behaviour
|
||||
@ -589,7 +589,7 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_zif_pin_cfg);
|
||||
|
||||
/**
|
||||
* si476x_core_cmd_ic_link_gpo_ctl_pin_cfg - send
|
||||
* 'IC_LINK_GPIO_CTL_PIN_CFG' comand to the device
|
||||
* 'IC_LINK_GPIO_CTL_PIN_CFG' command to the device
|
||||
* @core: - device to send the command to
|
||||
* @icin: - ICIN pin function configuration:
|
||||
* SI476X_ICIN_NOOP - do not modify the behaviour
|
||||
@ -1014,7 +1014,7 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_phase_diversity);
|
||||
* NOTE caller must hold core lock
|
||||
*
|
||||
* Function returns the value of the status bit in case of success and
|
||||
* negative error code in case of failre.
|
||||
* negative error code in case of failure.
|
||||
*/
|
||||
int si476x_core_cmd_fm_phase_div_status(struct si476x_core *core)
|
||||
{
|
||||
|
@ -72,9 +72,22 @@ static const struct simple_mfd_data silergy_sy7636a = {
|
||||
.mfd_cell_size = ARRAY_SIZE(sy7636a_cells),
|
||||
};
|
||||
|
||||
static const struct mfd_cell max597x_cells[] = {
|
||||
{ .name = "max597x-regulator", },
|
||||
{ .name = "max597x-iio", },
|
||||
{ .name = "max597x-led", },
|
||||
};
|
||||
|
||||
static const struct simple_mfd_data maxim_max597x = {
|
||||
.mfd_cell = max597x_cells,
|
||||
.mfd_cell_size = ARRAY_SIZE(max597x_cells),
|
||||
};
|
||||
|
||||
static const struct of_device_id simple_mfd_i2c_of_match[] = {
|
||||
{ .compatible = "kontron,sl28cpld" },
|
||||
{ .compatible = "silergy,sy7636a", .data = &silergy_sy7636a},
|
||||
{ .compatible = "maxim,max5970", .data = &maxim_max597x},
|
||||
{ .compatible = "maxim,max5978", .data = &maxim_max597x},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);
|
||||
|
@ -262,7 +262,6 @@ EXPORT_SYMBOL_GPL(ssbi_write);
|
||||
static int ssbi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct resource *mem_res;
|
||||
struct ssbi *ssbi;
|
||||
const char *type;
|
||||
|
||||
@ -270,8 +269,7 @@ static int ssbi_probe(struct platform_device *pdev)
|
||||
if (!ssbi)
|
||||
return -ENOMEM;
|
||||
|
||||
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
ssbi->base = devm_ioremap_resource(&pdev->dev, mem_res);
|
||||
ssbi->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(ssbi->base))
|
||||
return PTR_ERR(ssbi->base);
|
||||
|
||||
|
@ -135,6 +135,5 @@ static void __exit stmpe_exit(void)
|
||||
}
|
||||
module_exit(stmpe_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver");
|
||||
MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>");
|
||||
|
@ -154,6 +154,5 @@ static void __exit stmpe_exit(void)
|
||||
}
|
||||
module_exit(stmpe_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver");
|
||||
MODULE_AUTHOR("Viresh Kumar <vireshk@kernel.org>");
|
||||
|
@ -1378,7 +1378,7 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum)
|
||||
|
||||
stmpe_of_probe(pdata, np);
|
||||
|
||||
if (of_find_property(np, "interrupts", NULL) == NULL)
|
||||
if (!of_property_present(np, "interrupts"))
|
||||
ci->irq = -1;
|
||||
|
||||
stmpe = devm_kzalloc(ci->dev, sizeof(struct stmpe), GFP_KERNEL);
|
||||
|
@ -93,7 +93,6 @@ MODULE_DEVICE_TABLE(of, sun4i_gpadc_of_match);
|
||||
static int sun4i_gpadc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sun4i_gpadc_dev *dev;
|
||||
struct resource *mem;
|
||||
const struct of_device_id *of_id;
|
||||
const struct mfd_cell *cells;
|
||||
unsigned int irq, size;
|
||||
@ -124,8 +123,7 @@ static int sun4i_gpadc_probe(struct platform_device *pdev)
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
dev->base = devm_ioremap_resource(&pdev->dev, mem);
|
||||
dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
|
||||
if (IS_ERR(dev->base))
|
||||
return PTR_ERR(dev->base);
|
||||
|
||||
|
@ -502,6 +502,5 @@ static void __exit tc3589x_exit(void)
|
||||
}
|
||||
module_exit(tc3589x_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("TC3589x MFD core driver");
|
||||
MODULE_AUTHOR("Hanumath Prasad, Rabin Vincent");
|
||||
|
@ -638,4 +638,3 @@ module_exit(tps6586x_exit);
|
||||
|
||||
MODULE_DESCRIPTION("TPS6586X core driver");
|
||||
MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include <linux/platform_data/i2c-ocores.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#define TQMX86_IOBASE 0x160
|
||||
#define TQMX86_IOSIZE 0x3f
|
||||
#define TQMX86_IOBASE 0x180
|
||||
#define TQMX86_IOSIZE 0x20
|
||||
#define TQMX86_IOBASE_I2C 0x1a0
|
||||
#define TQMX86_IOSIZE_I2C 0xa
|
||||
#define TQMX86_IOBASE_WATCHDOG 0x18b
|
||||
@ -25,14 +25,14 @@
|
||||
#define TQMX86_IOBASE_GPIO 0x18d
|
||||
#define TQMX86_IOSIZE_GPIO 0x4
|
||||
|
||||
#define TQMX86_REG_BOARD_ID 0x20
|
||||
#define TQMX86_REG_BOARD_ID 0x00
|
||||
#define TQMX86_REG_BOARD_ID_E38M 1
|
||||
#define TQMX86_REG_BOARD_ID_50UC 2
|
||||
#define TQMX86_REG_BOARD_ID_E38C 3
|
||||
#define TQMX86_REG_BOARD_ID_60EB 4
|
||||
#define TQMX86_REG_BOARD_ID_E39M 5
|
||||
#define TQMX86_REG_BOARD_ID_E39C 6
|
||||
#define TQMX86_REG_BOARD_ID_E39x 7
|
||||
#define TQMX86_REG_BOARD_ID_E39MS 5
|
||||
#define TQMX86_REG_BOARD_ID_E39C1 6
|
||||
#define TQMX86_REG_BOARD_ID_E39C2 7
|
||||
#define TQMX86_REG_BOARD_ID_70EB 8
|
||||
#define TQMX86_REG_BOARD_ID_80UC 9
|
||||
#define TQMX86_REG_BOARD_ID_110EB 11
|
||||
@ -40,18 +40,18 @@
|
||||
#define TQMX86_REG_BOARD_ID_E40S 13
|
||||
#define TQMX86_REG_BOARD_ID_E40C1 14
|
||||
#define TQMX86_REG_BOARD_ID_E40C2 15
|
||||
#define TQMX86_REG_BOARD_REV 0x21
|
||||
#define TQMX86_REG_IO_EXT_INT 0x26
|
||||
#define TQMX86_REG_BOARD_REV 0x01
|
||||
#define TQMX86_REG_IO_EXT_INT 0x06
|
||||
#define TQMX86_REG_IO_EXT_INT_NONE 0
|
||||
#define TQMX86_REG_IO_EXT_INT_7 1
|
||||
#define TQMX86_REG_IO_EXT_INT_9 2
|
||||
#define TQMX86_REG_IO_EXT_INT_12 3
|
||||
#define TQMX86_REG_IO_EXT_INT_MASK 0x3
|
||||
#define TQMX86_REG_IO_EXT_INT_GPIO_SHIFT 4
|
||||
#define TQMX86_REG_SAUC 0x17
|
||||
|
||||
#define TQMX86_REG_I2C_DETECT 0x47
|
||||
#define TQMX86_REG_I2C_DETECT 0x1a7
|
||||
#define TQMX86_REG_I2C_DETECT_SOFT 0xa5
|
||||
#define TQMX86_REG_I2C_INT_EN 0x49
|
||||
|
||||
static uint gpio_irq;
|
||||
module_param(gpio_irq, uint, 0);
|
||||
@ -111,7 +111,7 @@ static const struct mfd_cell tqmx86_devs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const char *tqmx86_board_id_to_name(u8 board_id)
|
||||
static const char *tqmx86_board_id_to_name(u8 board_id, u8 sauc)
|
||||
{
|
||||
switch (board_id) {
|
||||
case TQMX86_REG_BOARD_ID_E38M:
|
||||
@ -122,12 +122,12 @@ static const char *tqmx86_board_id_to_name(u8 board_id)
|
||||
return "TQMxE38C";
|
||||
case TQMX86_REG_BOARD_ID_60EB:
|
||||
return "TQMx60EB";
|
||||
case TQMX86_REG_BOARD_ID_E39M:
|
||||
return "TQMxE39M";
|
||||
case TQMX86_REG_BOARD_ID_E39C:
|
||||
return "TQMxE39C";
|
||||
case TQMX86_REG_BOARD_ID_E39x:
|
||||
return "TQMxE39x";
|
||||
case TQMX86_REG_BOARD_ID_E39MS:
|
||||
return (sauc == 0xff) ? "TQMxE39M" : "TQMxE39S";
|
||||
case TQMX86_REG_BOARD_ID_E39C1:
|
||||
return "TQMxE39C1";
|
||||
case TQMX86_REG_BOARD_ID_E39C2:
|
||||
return "TQMxE39C2";
|
||||
case TQMX86_REG_BOARD_ID_70EB:
|
||||
return "TQMx70EB";
|
||||
case TQMX86_REG_BOARD_ID_80UC:
|
||||
@ -160,9 +160,9 @@ static int tqmx86_board_id_to_clk_rate(struct device *dev, u8 board_id)
|
||||
case TQMX86_REG_BOARD_ID_E40C1:
|
||||
case TQMX86_REG_BOARD_ID_E40C2:
|
||||
return 24000;
|
||||
case TQMX86_REG_BOARD_ID_E39M:
|
||||
case TQMX86_REG_BOARD_ID_E39C:
|
||||
case TQMX86_REG_BOARD_ID_E39x:
|
||||
case TQMX86_REG_BOARD_ID_E39MS:
|
||||
case TQMX86_REG_BOARD_ID_E39C1:
|
||||
case TQMX86_REG_BOARD_ID_E39C2:
|
||||
return 25000;
|
||||
case TQMX86_REG_BOARD_ID_E38M:
|
||||
case TQMX86_REG_BOARD_ID_E38C:
|
||||
@ -176,7 +176,7 @@ static int tqmx86_board_id_to_clk_rate(struct device *dev, u8 board_id)
|
||||
|
||||
static int tqmx86_probe(struct platform_device *pdev)
|
||||
{
|
||||
u8 board_id, rev, i2c_det, io_ext_int_val;
|
||||
u8 board_id, sauc, rev, i2c_det, io_ext_int_val;
|
||||
struct device *dev = &pdev->dev;
|
||||
u8 gpio_irq_cfg, readback;
|
||||
const char *board_name;
|
||||
@ -206,14 +206,20 @@ static int tqmx86_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
board_id = ioread8(io_base + TQMX86_REG_BOARD_ID);
|
||||
board_name = tqmx86_board_id_to_name(board_id);
|
||||
sauc = ioread8(io_base + TQMX86_REG_SAUC);
|
||||
board_name = tqmx86_board_id_to_name(board_id, sauc);
|
||||
rev = ioread8(io_base + TQMX86_REG_BOARD_REV);
|
||||
|
||||
dev_info(dev,
|
||||
"Found %s - Board ID %d, PCB Revision %d, PLD Revision %d\n",
|
||||
board_name, board_id, rev >> 4, rev & 0xf);
|
||||
|
||||
i2c_det = ioread8(io_base + TQMX86_REG_I2C_DETECT);
|
||||
/*
|
||||
* The I2C_DETECT register is in the range assigned to the I2C driver
|
||||
* later, so we don't extend TQMX86_IOSIZE. Use inb() for this one-off
|
||||
* access instead of ioport_map + unmap.
|
||||
*/
|
||||
i2c_det = inb(TQMX86_REG_I2C_DETECT);
|
||||
|
||||
if (gpio_irq_cfg) {
|
||||
io_ext_int_val =
|
||||
|
@ -594,71 +594,6 @@ int twl_get_hfclk_rate(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(twl_get_hfclk_rate);
|
||||
|
||||
static struct device *
|
||||
add_numbered_child(unsigned mod_no, const char *name, int num,
|
||||
void *pdata, unsigned pdata_len,
|
||||
bool can_wakeup, int irq0, int irq1)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct twl_client *twl;
|
||||
int status, sid;
|
||||
|
||||
if (unlikely(mod_no >= twl_get_last_module())) {
|
||||
pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
|
||||
return ERR_PTR(-EPERM);
|
||||
}
|
||||
sid = twl_priv->twl_map[mod_no].sid;
|
||||
twl = &twl_priv->twl_modules[sid];
|
||||
|
||||
pdev = platform_device_alloc(name, num);
|
||||
if (!pdev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pdev->dev.parent = &twl->client->dev;
|
||||
|
||||
if (pdata) {
|
||||
status = platform_device_add_data(pdev, pdata, pdata_len);
|
||||
if (status < 0) {
|
||||
dev_dbg(&pdev->dev, "can't add platform_data\n");
|
||||
goto put_device;
|
||||
}
|
||||
}
|
||||
|
||||
if (irq0) {
|
||||
struct resource r[2] = {
|
||||
{ .start = irq0, .flags = IORESOURCE_IRQ, },
|
||||
{ .start = irq1, .flags = IORESOURCE_IRQ, },
|
||||
};
|
||||
|
||||
status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1);
|
||||
if (status < 0) {
|
||||
dev_dbg(&pdev->dev, "can't add irqs\n");
|
||||
goto put_device;
|
||||
}
|
||||
}
|
||||
|
||||
status = platform_device_add(pdev);
|
||||
if (status)
|
||||
goto put_device;
|
||||
|
||||
device_init_wakeup(&pdev->dev, can_wakeup);
|
||||
|
||||
return &pdev->dev;
|
||||
|
||||
put_device:
|
||||
platform_device_put(pdev);
|
||||
dev_err(&twl->client->dev, "failed to add device %s\n", name);
|
||||
return ERR_PTR(status);
|
||||
}
|
||||
|
||||
static inline struct device *add_child(unsigned mod_no, const char *name,
|
||||
void *pdata, unsigned pdata_len,
|
||||
bool can_wakeup, int irq0, int irq1)
|
||||
{
|
||||
return add_numbered_child(mod_no, name, -1, pdata, pdata_len,
|
||||
can_wakeup, irq0, irq1);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
|
@ -285,5 +285,4 @@ module_platform_driver(twl4030_audio_driver);
|
||||
|
||||
MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
|
||||
MODULE_DESCRIPTION("TWL4030 audio block MFD driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS("platform:twl4030-audio");
|
||||
|
@ -839,4 +839,3 @@ module_i2c_driver(twl6040_driver);
|
||||
MODULE_DESCRIPTION("TWL6040 MFD");
|
||||
MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
|
||||
MODULE_AUTHOR("Jorge Eduardo Candelaria <jorge.candelaria@ti.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -279,20 +279,11 @@ static int wm8994_set_pdata_from_of(struct wm8994 *wm8994)
|
||||
of_property_read_u32_array(np, "wlf,micbias-cfg", pdata->micbias,
|
||||
ARRAY_SIZE(pdata->micbias));
|
||||
|
||||
pdata->lineout1_diff = true;
|
||||
pdata->lineout2_diff = true;
|
||||
if (of_find_property(np, "wlf,lineout1-se", NULL))
|
||||
pdata->lineout1_diff = false;
|
||||
if (of_find_property(np, "wlf,lineout2-se", NULL))
|
||||
pdata->lineout2_diff = false;
|
||||
|
||||
if (of_find_property(np, "wlf,lineout1-feedback", NULL))
|
||||
pdata->lineout1fb = true;
|
||||
if (of_find_property(np, "wlf,lineout2-feedback", NULL))
|
||||
pdata->lineout2fb = true;
|
||||
|
||||
if (of_find_property(np, "wlf,ldoena-always-driven", NULL))
|
||||
pdata->lineout2fb = true;
|
||||
pdata->lineout1_diff = !of_property_read_bool(np, "wlf,lineout1-se");
|
||||
pdata->lineout2_diff = !of_property_read_bool(np, "wlf,lineout2-se");
|
||||
pdata->lineout1fb = of_property_read_bool(np, "wlf,lineout1-feedback");
|
||||
pdata->lineout2fb = of_property_read_bool(np, "wlf,lineout2-feedback") ||
|
||||
of_property_read_bool(np, "wlf,ldoena-always-driven");
|
||||
|
||||
pdata->spkmode_pu = of_property_read_bool(np, "wlf,spkmode-pu");
|
||||
|
||||
|
@ -85,7 +85,7 @@ struct s5m_rtc_reg_config {
|
||||
unsigned int write_alarm_udr_mask;
|
||||
};
|
||||
|
||||
/* Register map for S5M8763 and S5M8767 */
|
||||
/* Register map for S5M8767 */
|
||||
static const struct s5m_rtc_reg_config s5m_rtc_regs = {
|
||||
.regs_count = 8,
|
||||
.time = S5M_RTC_SEC,
|
||||
@ -236,7 +236,6 @@ static int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info,
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8767X:
|
||||
case S5M8763X:
|
||||
ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val);
|
||||
val &= S5M_ALARM0_STATUS;
|
||||
break;
|
||||
@ -299,7 +298,6 @@ static int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
|
||||
|
||||
data |= info->regs->write_alarm_udr_mask;
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
case S5M8767X:
|
||||
data &= ~S5M_RTC_TIME_EN_MASK;
|
||||
break;
|
||||
@ -329,38 +327,6 @@ static int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void s5m8763_data_to_tm(u8 *data, struct rtc_time *tm)
|
||||
{
|
||||
tm->tm_sec = bcd2bin(data[RTC_SEC]);
|
||||
tm->tm_min = bcd2bin(data[RTC_MIN]);
|
||||
|
||||
if (data[RTC_HOUR] & HOUR_12) {
|
||||
tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f);
|
||||
if (data[RTC_HOUR] & HOUR_PM)
|
||||
tm->tm_hour += 12;
|
||||
} else {
|
||||
tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
|
||||
}
|
||||
|
||||
tm->tm_wday = data[RTC_WEEKDAY] & 0x07;
|
||||
tm->tm_mday = bcd2bin(data[RTC_DATE]);
|
||||
tm->tm_mon = bcd2bin(data[RTC_MONTH]);
|
||||
tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100;
|
||||
tm->tm_year -= 1900;
|
||||
}
|
||||
|
||||
static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data)
|
||||
{
|
||||
data[RTC_SEC] = bin2bcd(tm->tm_sec);
|
||||
data[RTC_MIN] = bin2bcd(tm->tm_min);
|
||||
data[RTC_HOUR] = bin2bcd(tm->tm_hour);
|
||||
data[RTC_WEEKDAY] = tm->tm_wday;
|
||||
data[RTC_DATE] = bin2bcd(tm->tm_mday);
|
||||
data[RTC_MONTH] = bin2bcd(tm->tm_mon);
|
||||
data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100);
|
||||
data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100);
|
||||
}
|
||||
|
||||
static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
{
|
||||
struct s5m_rtc_info *info = dev_get_drvdata(dev);
|
||||
@ -385,10 +351,6 @@ static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||
return ret;
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
s5m8763_data_to_tm(data, tm);
|
||||
break;
|
||||
|
||||
case S5M8767X:
|
||||
case S2MPS15X:
|
||||
case S2MPS14X:
|
||||
@ -412,9 +374,6 @@ static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||
int ret = 0;
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
s5m8763_tm_to_data(tm, data);
|
||||
break;
|
||||
case S5M8767X:
|
||||
case S2MPS15X:
|
||||
case S2MPS14X:
|
||||
@ -444,7 +403,6 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
{
|
||||
struct s5m_rtc_info *info = dev_get_drvdata(dev);
|
||||
u8 data[RTC_MAX_NUM_TIME_REGS];
|
||||
unsigned int val;
|
||||
int ret, i;
|
||||
|
||||
ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
|
||||
@ -453,15 +411,6 @@ static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
return ret;
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
s5m8763_data_to_tm(data, &alrm->time);
|
||||
ret = regmap_read(info->regmap, S5M_ALARM0_CONF, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
alrm->enabled = !!val;
|
||||
break;
|
||||
|
||||
case S5M8767X:
|
||||
case S2MPS15X:
|
||||
case S2MPS14X:
|
||||
@ -500,10 +449,6 @@ static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
|
||||
dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday);
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
ret = regmap_write(info->regmap, S5M_ALARM0_CONF, 0);
|
||||
break;
|
||||
|
||||
case S5M8767X:
|
||||
case S2MPS15X:
|
||||
case S2MPS14X:
|
||||
@ -531,7 +476,6 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
|
||||
{
|
||||
int ret;
|
||||
u8 data[RTC_MAX_NUM_TIME_REGS];
|
||||
u8 alarm0_conf;
|
||||
struct rtc_time tm;
|
||||
|
||||
ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
|
||||
@ -543,11 +487,6 @@ static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
|
||||
dev_dbg(info->dev, "%s: %ptR(%d)\n", __func__, &tm, tm.tm_wday);
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
alarm0_conf = 0x77;
|
||||
ret = regmap_write(info->regmap, S5M_ALARM0_CONF, alarm0_conf);
|
||||
break;
|
||||
|
||||
case S5M8767X:
|
||||
case S2MPS15X:
|
||||
case S2MPS14X:
|
||||
@ -585,10 +524,6 @@ static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
|
||||
int ret;
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
s5m8763_tm_to_data(&alrm->time, data);
|
||||
break;
|
||||
|
||||
case S5M8767X:
|
||||
case S2MPS15X:
|
||||
case S2MPS14X:
|
||||
@ -655,7 +590,6 @@ static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
|
||||
int ret;
|
||||
|
||||
switch (info->device_type) {
|
||||
case S5M8763X:
|
||||
case S5M8767X:
|
||||
/* UDR update time. Default of 7.32 ms is too long. */
|
||||
ret = regmap_update_bits(info->regmap, S5M_RTC_UDR_CON,
|
||||
@ -729,11 +663,6 @@ static int s5m_rtc_probe(struct platform_device *pdev)
|
||||
info->regs = &s2mps13_rtc_regs;
|
||||
alarm_irq = S2MPS14_IRQ_RTCA0;
|
||||
break;
|
||||
case S5M8763X:
|
||||
regmap_cfg = &s5m_rtc_regmap_config;
|
||||
info->regs = &s5m_rtc_regs;
|
||||
alarm_irq = S5M8763_IRQ_ALARM0;
|
||||
break;
|
||||
case S5M8767X:
|
||||
regmap_cfg = &s5m_rtc_regmap_config;
|
||||
info->regs = &s5m_rtc_regs;
|
||||
@ -786,13 +715,8 @@ static int s5m_rtc_probe(struct platform_device *pdev)
|
||||
|
||||
info->rtc_dev->ops = &s5m_rtc_ops;
|
||||
|
||||
if (info->device_type == S5M8763X) {
|
||||
info->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_0000;
|
||||
info->rtc_dev->range_max = RTC_TIMESTAMP_END_9999;
|
||||
} else {
|
||||
info->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000;
|
||||
info->rtc_dev->range_max = RTC_TIMESTAMP_END_2099;
|
||||
}
|
||||
info->rtc_dev->range_min = RTC_TIMESTAMP_BEGIN_2000;
|
||||
info->rtc_dev->range_max = RTC_TIMESTAMP_END_2099;
|
||||
|
||||
if (!info->irq) {
|
||||
clear_bit(RTC_FEATURE_ALARM, info->rtc_dev->features);
|
||||
|
@ -34,7 +34,6 @@
|
||||
#define STM32F4_AHB1_RESET(bit) (STM32F4_RCC_AHB1_##bit + (0x10 * 8))
|
||||
#define STM32F4_AHB1_CLOCK(bit) (STM32F4_RCC_AHB1_##bit)
|
||||
|
||||
|
||||
/* AHB2 */
|
||||
#define STM32F4_RCC_AHB2_DCMI 0
|
||||
#define STM32F4_RCC_AHB2_CRYP 4
|
||||
|
@ -21,6 +21,7 @@ enum axp20x_variants {
|
||||
AXP806_ID,
|
||||
AXP809_ID,
|
||||
AXP813_ID,
|
||||
AXP15060_ID,
|
||||
NR_AXP20X_VARIANTS,
|
||||
};
|
||||
|
||||
@ -131,6 +132,39 @@ enum axp20x_variants {
|
||||
/* Other DCDC regulator control registers are the same as AXP803 */
|
||||
#define AXP813_DCDC7_V_OUT 0x26
|
||||
|
||||
#define AXP15060_STARTUP_SRC 0x00
|
||||
#define AXP15060_PWR_OUT_CTRL1 0x10
|
||||
#define AXP15060_PWR_OUT_CTRL2 0x11
|
||||
#define AXP15060_PWR_OUT_CTRL3 0x12
|
||||
#define AXP15060_DCDC1_V_CTRL 0x13
|
||||
#define AXP15060_DCDC2_V_CTRL 0x14
|
||||
#define AXP15060_DCDC3_V_CTRL 0x15
|
||||
#define AXP15060_DCDC4_V_CTRL 0x16
|
||||
#define AXP15060_DCDC5_V_CTRL 0x17
|
||||
#define AXP15060_DCDC6_V_CTRL 0x18
|
||||
#define AXP15060_ALDO1_V_CTRL 0x19
|
||||
#define AXP15060_DCDC_MODE_CTRL1 0x1a
|
||||
#define AXP15060_DCDC_MODE_CTRL2 0x1b
|
||||
#define AXP15060_OUTPUT_MONITOR_DISCHARGE 0x1e
|
||||
#define AXP15060_IRQ_PWROK_VOFF 0x1f
|
||||
#define AXP15060_ALDO2_V_CTRL 0x20
|
||||
#define AXP15060_ALDO3_V_CTRL 0x21
|
||||
#define AXP15060_ALDO4_V_CTRL 0x22
|
||||
#define AXP15060_ALDO5_V_CTRL 0x23
|
||||
#define AXP15060_BLDO1_V_CTRL 0x24
|
||||
#define AXP15060_BLDO2_V_CTRL 0x25
|
||||
#define AXP15060_BLDO3_V_CTRL 0x26
|
||||
#define AXP15060_BLDO4_V_CTRL 0x27
|
||||
#define AXP15060_BLDO5_V_CTRL 0x28
|
||||
#define AXP15060_CLDO1_V_CTRL 0x29
|
||||
#define AXP15060_CLDO2_V_CTRL 0x2a
|
||||
#define AXP15060_CLDO3_V_CTRL 0x2b
|
||||
#define AXP15060_CLDO4_V_CTRL 0x2d
|
||||
#define AXP15060_CPUSLDO_V_CTRL 0x2e
|
||||
#define AXP15060_PWR_WAKEUP_CTRL 0x31
|
||||
#define AXP15060_PWR_DISABLE_DOWN_SEQ 0x32
|
||||
#define AXP15060_PEK_KEY 0x36
|
||||
|
||||
/* Interrupt */
|
||||
#define AXP152_IRQ1_EN 0x40
|
||||
#define AXP152_IRQ2_EN 0x41
|
||||
@ -152,6 +186,11 @@ enum axp20x_variants {
|
||||
#define AXP20X_IRQ5_STATE 0x4c
|
||||
#define AXP20X_IRQ6_STATE 0x4d
|
||||
|
||||
#define AXP15060_IRQ1_EN 0x40
|
||||
#define AXP15060_IRQ2_EN 0x41
|
||||
#define AXP15060_IRQ1_STATE 0x48
|
||||
#define AXP15060_IRQ2_STATE 0x49
|
||||
|
||||
/* ADC */
|
||||
#define AXP20X_ACIN_V_ADC_H 0x56
|
||||
#define AXP20X_ACIN_V_ADC_L 0x57
|
||||
@ -222,6 +261,8 @@ enum axp20x_variants {
|
||||
#define AXP22X_GPIO_STATE 0x94
|
||||
#define AXP22X_GPIO_PULL_DOWN 0x95
|
||||
|
||||
#define AXP15060_CLDO4_GPIO2_MODESET 0x2c
|
||||
|
||||
/* Battery */
|
||||
#define AXP20X_CHRG_CC_31_24 0xb0
|
||||
#define AXP20X_CHRG_CC_23_16 0xb1
|
||||
@ -419,6 +460,33 @@ enum {
|
||||
AXP813_REG_ID_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
AXP15060_DCDC1 = 0,
|
||||
AXP15060_DCDC2,
|
||||
AXP15060_DCDC3,
|
||||
AXP15060_DCDC4,
|
||||
AXP15060_DCDC5,
|
||||
AXP15060_DCDC6,
|
||||
AXP15060_ALDO1,
|
||||
AXP15060_ALDO2,
|
||||
AXP15060_ALDO3,
|
||||
AXP15060_ALDO4,
|
||||
AXP15060_ALDO5,
|
||||
AXP15060_BLDO1,
|
||||
AXP15060_BLDO2,
|
||||
AXP15060_BLDO3,
|
||||
AXP15060_BLDO4,
|
||||
AXP15060_BLDO5,
|
||||
AXP15060_CLDO1,
|
||||
AXP15060_CLDO2,
|
||||
AXP15060_CLDO3,
|
||||
AXP15060_CLDO4,
|
||||
AXP15060_CPUSLDO,
|
||||
AXP15060_SW,
|
||||
AXP15060_RTC_LDO,
|
||||
AXP15060_REG_ID_MAX,
|
||||
};
|
||||
|
||||
/* IRQs */
|
||||
enum {
|
||||
AXP152_IRQ_LDO0IN_CONNECT = 1,
|
||||
@ -637,6 +705,23 @@ enum axp809_irqs {
|
||||
AXP809_IRQ_GPIO0_INPUT,
|
||||
};
|
||||
|
||||
enum axp15060_irqs {
|
||||
AXP15060_IRQ_DIE_TEMP_HIGH_LV1 = 1,
|
||||
AXP15060_IRQ_DIE_TEMP_HIGH_LV2,
|
||||
AXP15060_IRQ_DCDC1_V_LOW,
|
||||
AXP15060_IRQ_DCDC2_V_LOW,
|
||||
AXP15060_IRQ_DCDC3_V_LOW,
|
||||
AXP15060_IRQ_DCDC4_V_LOW,
|
||||
AXP15060_IRQ_DCDC5_V_LOW,
|
||||
AXP15060_IRQ_DCDC6_V_LOW,
|
||||
AXP15060_IRQ_PEK_LONG,
|
||||
AXP15060_IRQ_PEK_SHORT,
|
||||
AXP15060_IRQ_GPIO1_INPUT,
|
||||
AXP15060_IRQ_PEK_FAL_EDGE,
|
||||
AXP15060_IRQ_PEK_RIS_EDGE,
|
||||
AXP15060_IRQ_GPIO2_INPUT,
|
||||
};
|
||||
|
||||
struct axp20x_dev {
|
||||
struct device *dev;
|
||||
int irq;
|
||||
|
@ -68,9 +68,6 @@ struct mfd_cell {
|
||||
int id;
|
||||
int level;
|
||||
|
||||
int (*enable)(struct platform_device *dev);
|
||||
int (*disable)(struct platform_device *dev);
|
||||
|
||||
int (*suspend)(struct platform_device *dev);
|
||||
int (*resume)(struct platform_device *dev);
|
||||
|
||||
@ -78,6 +75,9 @@ struct mfd_cell {
|
||||
void *platform_data;
|
||||
size_t pdata_size;
|
||||
|
||||
/* Matches ACPI */
|
||||
const struct mfd_cell_acpi_match *acpi_match;
|
||||
|
||||
/* Software node for the device. */
|
||||
const struct software_node *swnode;
|
||||
|
||||
@ -97,9 +97,6 @@ struct mfd_cell {
|
||||
/* Set to 'true' to use 'of_reg' (above) - allows for of_reg=0 */
|
||||
bool use_of_reg;
|
||||
|
||||
/* Matches ACPI */
|
||||
const struct mfd_cell_acpi_match *acpi_match;
|
||||
|
||||
/*
|
||||
* These resources can be specified relative to the parent device.
|
||||
* For accessing hardware you should use resources from the platform dev
|
||||
@ -119,19 +116,10 @@ struct mfd_cell {
|
||||
/* A list of regulator supplies that should be mapped to the MFD
|
||||
* device rather than the child device when requested
|
||||
*/
|
||||
const char * const *parent_supplies;
|
||||
int num_parent_supplies;
|
||||
const char * const *parent_supplies;
|
||||
};
|
||||
|
||||
/*
|
||||
* Convenience functions for clients using shared cells. Refcounting
|
||||
* happens automatically, with the cell's enable/disable callbacks
|
||||
* being called only when a device is first being enabled or no other
|
||||
* clients are making use of it.
|
||||
*/
|
||||
extern int mfd_cell_enable(struct platform_device *pdev);
|
||||
extern int mfd_cell_disable(struct platform_device *pdev);
|
||||
|
||||
/*
|
||||
* Given a platform device that's been created by mfd_add_devices(), fetch
|
||||
* the mfd_cell that created it.
|
||||
|
96
include/linux/mfd/max597x.h
Normal file
96
include/linux/mfd/max597x.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Device driver for regulators in MAX5970 and MAX5978 IC
|
||||
*
|
||||
* Copyright (c) 2022 9elements GmbH
|
||||
*
|
||||
* Author: Patrick Rudolph <patrick.rudolph@9elements.com>
|
||||
*/
|
||||
|
||||
#ifndef _MFD_MAX597X_H
|
||||
#define _MFD_MAX597X_H
|
||||
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define MAX5970_NUM_SWITCHES 2
|
||||
#define MAX5978_NUM_SWITCHES 1
|
||||
#define MAX597X_NUM_LEDS 4
|
||||
|
||||
struct max597x_data {
|
||||
int num_switches;
|
||||
u32 irng[MAX5970_NUM_SWITCHES];
|
||||
u32 mon_rng[MAX5970_NUM_SWITCHES];
|
||||
u32 shunt_micro_ohms[MAX5970_NUM_SWITCHES];
|
||||
};
|
||||
|
||||
enum max597x_chip_type {
|
||||
MAX597x_TYPE_MAX5978 = 1,
|
||||
MAX597x_TYPE_MAX5970,
|
||||
};
|
||||
|
||||
#define MAX5970_REG_CURRENT_L(ch) (0x01 + (ch) * 4)
|
||||
#define MAX5970_REG_CURRENT_H(ch) (0x00 + (ch) * 4)
|
||||
#define MAX5970_REG_VOLTAGE_L(ch) (0x03 + (ch) * 4)
|
||||
#define MAX5970_REG_VOLTAGE_H(ch) (0x02 + (ch) * 4)
|
||||
#define MAX5970_REG_MON_RANGE 0x18
|
||||
#define MAX5970_MON_MASK 0x3
|
||||
#define MAX5970_MON(reg, ch) (((reg) >> ((ch) * 2)) & MAX5970_MON_MASK)
|
||||
#define MAX5970_MON_MAX_RANGE_UV 16000000
|
||||
|
||||
#define MAX5970_REG_CH_UV_WARN_H(ch) (0x1A + (ch) * 10)
|
||||
#define MAX5970_REG_CH_UV_WARN_L(ch) (0x1B + (ch) * 10)
|
||||
#define MAX5970_REG_CH_UV_CRIT_H(ch) (0x1C + (ch) * 10)
|
||||
#define MAX5970_REG_CH_UV_CRIT_L(ch) (0x1D + (ch) * 10)
|
||||
#define MAX5970_REG_CH_OV_WARN_H(ch) (0x1E + (ch) * 10)
|
||||
#define MAX5970_REG_CH_OV_WARN_L(ch) (0x1F + (ch) * 10)
|
||||
#define MAX5970_REG_CH_OV_CRIT_H(ch) (0x20 + (ch) * 10)
|
||||
#define MAX5970_REG_CH_OV_CRIT_L(ch) (0x21 + (ch) * 10)
|
||||
|
||||
#define MAX5970_VAL2REG_H(x) (((x) >> 2) & 0xFF)
|
||||
#define MAX5970_VAL2REG_L(x) ((x) & 0x3)
|
||||
|
||||
#define MAX5970_REG_DAC_FAST(ch) (0x2E + (ch))
|
||||
|
||||
#define MAX5970_FAST2SLOW_RATIO 200
|
||||
|
||||
#define MAX5970_REG_STATUS0 0x31
|
||||
#define MAX5970_CB_IFAULTF(ch) (1 << (ch))
|
||||
#define MAX5970_CB_IFAULTS(ch) (1 << ((ch) + 4))
|
||||
|
||||
#define MAX5970_REG_STATUS1 0x32
|
||||
#define STATUS1_PROT_MASK 0x3
|
||||
#define STATUS1_PROT(reg) \
|
||||
(((reg) >> 6) & STATUS1_PROT_MASK)
|
||||
#define STATUS1_PROT_SHUTDOWN 0
|
||||
#define STATUS1_PROT_CLEAR_PG 1
|
||||
#define STATUS1_PROT_ALERT_ONLY 2
|
||||
|
||||
#define MAX5970_REG_STATUS2 0x33
|
||||
#define MAX5970_IRNG_MASK 0x3
|
||||
#define MAX5970_IRNG(reg, ch) \
|
||||
(((reg) >> ((ch) * 2)) & MAX5970_IRNG_MASK)
|
||||
|
||||
#define MAX5970_REG_STATUS3 0x34
|
||||
#define MAX5970_STATUS3_ALERT BIT(4)
|
||||
#define MAX5970_STATUS3_PG(ch) BIT(ch)
|
||||
|
||||
#define MAX5970_REG_FAULT0 0x35
|
||||
#define UV_STATUS_WARN(ch) (1 << (ch))
|
||||
#define UV_STATUS_CRIT(ch) (1 << ((ch) + 4))
|
||||
|
||||
#define MAX5970_REG_FAULT1 0x36
|
||||
#define OV_STATUS_WARN(ch) (1 << (ch))
|
||||
#define OV_STATUS_CRIT(ch) (1 << ((ch) + 4))
|
||||
|
||||
#define MAX5970_REG_FAULT2 0x37
|
||||
#define OC_STATUS_WARN(ch) (1 << (ch))
|
||||
|
||||
#define MAX5970_REG_CHXEN 0x3b
|
||||
#define CHXEN(ch) (3 << ((ch) * 2))
|
||||
|
||||
#define MAX5970_REG_LED_FLASH 0x43
|
||||
|
||||
#define MAX_REGISTERS 0x49
|
||||
#define ADC_MASK 0x3FF
|
||||
|
||||
#endif /* _MFD_MAX597X_H */
|
@ -8,6 +8,9 @@
|
||||
#ifndef __LINUX_MFD_RSMU_H
|
||||
#define __LINUX_MFD_RSMU_H
|
||||
|
||||
#define RSMU_MAX_WRITE_COUNT (255)
|
||||
#define RSMU_MAX_READ_COUNT (255)
|
||||
|
||||
/* The supported devices are ClockMatrix, Sabre and SnowLotus */
|
||||
enum rsmu_type {
|
||||
RSMU_CM = 0x34000,
|
||||
@ -31,6 +34,6 @@ struct rsmu_ddata {
|
||||
struct regmap *regmap;
|
||||
struct mutex lock;
|
||||
enum rsmu_type type;
|
||||
u16 page;
|
||||
u32 page;
|
||||
};
|
||||
#endif /* __LINUX_MFD_RSMU_H */
|
||||
|
@ -107,14 +107,13 @@ enum rt5033_reg {
|
||||
#define RT5033_LDO_CTRL_MASK 0x1f
|
||||
|
||||
/* RT5033 charger property - model, manufacturer */
|
||||
|
||||
#define RT5033_CHARGER_MODEL "RT5033WSC Charger"
|
||||
#define RT5033_MANUFACTURER "Richtek Technology Corporation"
|
||||
|
||||
/*
|
||||
* RT5033 charger fast-charge current lmits (as in CHGCTRL1 register),
|
||||
* AICR mode limits the input current for example,
|
||||
* the AIRC 100 mode limits the input current to 100 mA.
|
||||
* While RT5033 charger can limit the fast-charge current (as in CHGCTRL1
|
||||
* register), AICR mode limits the input current. For example, the AIRC 100
|
||||
* mode limits the input current to 100 mA.
|
||||
*/
|
||||
#define RT5033_AICR_100_MODE 0x20
|
||||
#define RT5033_AICR_500_MODE 0x40
|
||||
@ -139,10 +138,9 @@ enum rt5033_reg {
|
||||
#define RT5033_TE_ENABLE_MASK 0x08
|
||||
|
||||
/*
|
||||
* RT5033 charger opa mode. RT50300 have two opa mode charger mode
|
||||
* and boost mode for OTG
|
||||
* RT5033 charger opa mode. RT5033 has two opa modes for OTG: charger mode
|
||||
* and boost mode.
|
||||
*/
|
||||
|
||||
#define RT5033_CHARGER_MODE 0x00
|
||||
#define RT5033_BOOST_MODE 0x01
|
||||
|
||||
@ -181,18 +179,17 @@ enum rt5033_reg {
|
||||
* RT5033 charger pre-charge threshold volt limits
|
||||
* (as in CHGCTRL5 register), uV
|
||||
*/
|
||||
|
||||
#define RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MIN 2300000U
|
||||
#define RT5033_CHARGER_PRE_THRESHOLD_STEP_NUM 100000U
|
||||
#define RT5033_CHARGER_PRE_THRESHOLD_LIMIT_MAX 3800000U
|
||||
|
||||
/*
|
||||
* RT5033 charger enable UUG, If UUG enable MOS auto control by H/W charger
|
||||
* RT5033 charger UUG. It enables MOS auto control by H/W charger
|
||||
* circuit.
|
||||
*/
|
||||
#define RT5033_CHARGER_UUG_ENABLE 0x02
|
||||
|
||||
/* RT5033 charger High impedance mode */
|
||||
/* RT5033 charger high impedance mode */
|
||||
#define RT5033_CHARGER_HZ_DISABLE 0x00
|
||||
#define RT5033_CHARGER_HZ_ENABLE 0x01
|
||||
|
||||
|
@ -49,10 +49,9 @@ struct rt5033_charger_data {
|
||||
};
|
||||
|
||||
struct rt5033_charger {
|
||||
struct device *dev;
|
||||
struct rt5033_dev *rt5033;
|
||||
struct power_supply psy;
|
||||
|
||||
struct device *dev;
|
||||
struct rt5033_dev *rt5033;
|
||||
struct power_supply psy;
|
||||
struct rt5033_charger_data *chg;
|
||||
};
|
||||
|
||||
|
257
include/linux/mfd/rz-mtu3.h
Normal file
257
include/linux/mfd/rz-mtu3.h
Normal file
@ -0,0 +1,257 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (C) 2022 Renesas Electronics Corporation
|
||||
*/
|
||||
#ifndef __MFD_RZ_MTU3_H__
|
||||
#define __MFD_RZ_MTU3_H__
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
/* 8-bit shared register offsets macros */
|
||||
#define RZ_MTU3_TSTRA 0x080 /* Timer start register A */
|
||||
#define RZ_MTU3_TSTRB 0x880 /* Timer start register B */
|
||||
|
||||
/* 16-bit shared register offset macros */
|
||||
#define RZ_MTU3_TDDRA 0x016 /* Timer dead time data register A */
|
||||
#define RZ_MTU3_TDDRB 0x816 /* Timer dead time data register B */
|
||||
#define RZ_MTU3_TCDRA 0x014 /* Timer cycle data register A */
|
||||
#define RZ_MTU3_TCDRB 0x814 /* Timer cycle data register B */
|
||||
#define RZ_MTU3_TCBRA 0x022 /* Timer cycle buffer register A */
|
||||
#define RZ_MTU3_TCBRB 0x822 /* Timer cycle buffer register B */
|
||||
#define RZ_MTU3_TCNTSA 0x020 /* Timer subcounter A */
|
||||
#define RZ_MTU3_TCNTSB 0x820 /* Timer subcounter B */
|
||||
|
||||
/*
|
||||
* MTU5 contains 3 timer counter registers and is totaly different
|
||||
* from other channels, so we must separate its offset
|
||||
*/
|
||||
|
||||
/* 8-bit register offset macros of MTU3 channels except MTU5 */
|
||||
#define RZ_MTU3_TIER 0 /* Timer interrupt register */
|
||||
#define RZ_MTU3_NFCR 1 /* Noise filter control register */
|
||||
#define RZ_MTU3_TSR 2 /* Timer status register */
|
||||
#define RZ_MTU3_TCR 3 /* Timer control register */
|
||||
#define RZ_MTU3_TCR2 4 /* Timer control register 2 */
|
||||
|
||||
/* Timer mode register 1 */
|
||||
#define RZ_MTU3_TMDR1 5
|
||||
#define RZ_MTU3_TMDR1_MD GENMASK(3, 0)
|
||||
#define RZ_MTU3_TMDR1_MD_NORMAL FIELD_PREP(RZ_MTU3_TMDR1_MD, 0)
|
||||
#define RZ_MTU3_TMDR1_MD_PWMMODE1 FIELD_PREP(RZ_MTU3_TMDR1_MD, 2)
|
||||
|
||||
#define RZ_MTU3_TIOR 6 /* Timer I/O control register */
|
||||
#define RZ_MTU3_TIORH 6 /* Timer I/O control register H */
|
||||
#define RZ_MTU3_TIORL 7 /* Timer I/O control register L */
|
||||
/* Only MTU3/4/6/7 have TBTM registers */
|
||||
#define RZ_MTU3_TBTM 8 /* Timer buffer operation transfer mode register */
|
||||
|
||||
/* 8-bit MTU5 register offset macros */
|
||||
#define RZ_MTU3_TSTR 2 /* MTU5 Timer start register */
|
||||
#define RZ_MTU3_TCNTCMPCLR 3 /* MTU5 Timer compare match clear register */
|
||||
#define RZ_MTU3_TCRU 4 /* Timer control register U */
|
||||
#define RZ_MTU3_TCR2U 5 /* Timer control register 2U */
|
||||
#define RZ_MTU3_TIORU 6 /* Timer I/O control register U */
|
||||
#define RZ_MTU3_TCRV 7 /* Timer control register V */
|
||||
#define RZ_MTU3_TCR2V 8 /* Timer control register 2V */
|
||||
#define RZ_MTU3_TIORV 9 /* Timer I/O control register V */
|
||||
#define RZ_MTU3_TCRW 10 /* Timer control register W */
|
||||
#define RZ_MTU3_TCR2W 11 /* Timer control register 2W */
|
||||
#define RZ_MTU3_TIORW 12 /* Timer I/O control register W */
|
||||
|
||||
/* 16-bit register offset macros of MTU3 channels except MTU5 */
|
||||
#define RZ_MTU3_TCNT 0 /* Timer counter */
|
||||
#define RZ_MTU3_TGRA 1 /* Timer general register A */
|
||||
#define RZ_MTU3_TGRB 2 /* Timer general register B */
|
||||
#define RZ_MTU3_TGRC 3 /* Timer general register C */
|
||||
#define RZ_MTU3_TGRD 4 /* Timer general register D */
|
||||
#define RZ_MTU3_TGRE 5 /* Timer general register E */
|
||||
#define RZ_MTU3_TGRF 6 /* Timer general register F */
|
||||
/* Timer A/D converter start request registers */
|
||||
#define RZ_MTU3_TADCR 7 /* control register */
|
||||
#define RZ_MTU3_TADCORA 8 /* cycle set register A */
|
||||
#define RZ_MTU3_TADCORB 9 /* cycle set register B */
|
||||
#define RZ_MTU3_TADCOBRA 10 /* cycle set buffer register A */
|
||||
#define RZ_MTU3_TADCOBRB 11 /* cycle set buffer register B */
|
||||
|
||||
/* 16-bit MTU5 register offset macros */
|
||||
#define RZ_MTU3_TCNTU 0 /* MTU5 Timer counter U */
|
||||
#define RZ_MTU3_TGRU 1 /* MTU5 Timer general register U */
|
||||
#define RZ_MTU3_TCNTV 2 /* MTU5 Timer counter V */
|
||||
#define RZ_MTU3_TGRV 3 /* MTU5 Timer general register V */
|
||||
#define RZ_MTU3_TCNTW 4 /* MTU5 Timer counter W */
|
||||
#define RZ_MTU3_TGRW 5 /* MTU5 Timer general register W */
|
||||
|
||||
/* 32-bit register offset */
|
||||
#define RZ_MTU3_TCNTLW 0 /* Timer longword counter */
|
||||
#define RZ_MTU3_TGRALW 1 /* Timer longword general register A */
|
||||
#define RZ_MTU3_TGRBLW 2 /* Timer longowrd general register B */
|
||||
|
||||
#define RZ_MTU3_TMDR3 0x191 /* MTU1 Timer Mode Register 3 */
|
||||
|
||||
/* Macros for setting registers */
|
||||
#define RZ_MTU3_TCR_CCLR GENMASK(7, 5)
|
||||
#define RZ_MTU3_TCR_CKEG GENMASK(4, 3)
|
||||
#define RZ_MTU3_TCR_TPCS GENMASK(2, 0)
|
||||
#define RZ_MTU3_TCR_CCLR_TGRA BIT(5)
|
||||
#define RZ_MTU3_TCR_CCLR_TGRC FIELD_PREP(RZ_MTU3_TCR_CCLR, 5)
|
||||
#define RZ_MTU3_TCR_CKEG_RISING FIELD_PREP(RZ_MTU3_TCR_CKEG, 0)
|
||||
|
||||
#define RZ_MTU3_TIOR_IOB GENMASK(7, 4)
|
||||
#define RZ_MTU3_TIOR_IOA GENMASK(3, 0)
|
||||
#define RZ_MTU3_TIOR_OC_RETAIN 0
|
||||
#define RZ_MTU3_TIOR_OC_INIT_OUT_LO_HI_OUT 2
|
||||
#define RZ_MTU3_TIOR_OC_INIT_OUT_HI_TOGGLE_OUT 7
|
||||
|
||||
#define RZ_MTU3_TIOR_OC_IOA_H_COMP_MATCH \
|
||||
FIELD_PREP(RZ_MTU3_TIOR_IOA, RZ_MTU3_TIOR_OC_INIT_OUT_LO_HI_OUT)
|
||||
#define RZ_MTU3_TIOR_OC_IOB_TOGGLE \
|
||||
FIELD_PREP(RZ_MTU3_TIOR_IOB, RZ_MTU3_TIOR_OC_INIT_OUT_HI_TOGGLE_OUT)
|
||||
|
||||
enum rz_mtu3_channels {
|
||||
RZ_MTU3_CHAN_0,
|
||||
RZ_MTU3_CHAN_1,
|
||||
RZ_MTU3_CHAN_2,
|
||||
RZ_MTU3_CHAN_3,
|
||||
RZ_MTU3_CHAN_4,
|
||||
RZ_MTU3_CHAN_5,
|
||||
RZ_MTU3_CHAN_6,
|
||||
RZ_MTU3_CHAN_7,
|
||||
RZ_MTU3_CHAN_8,
|
||||
RZ_MTU_NUM_CHANNELS
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rz_mtu3_channel - MTU3 channel private data
|
||||
*
|
||||
* @dev: device handle
|
||||
* @channel_number: channel number
|
||||
* @lock: Lock to protect channel state
|
||||
* @is_busy: channel state
|
||||
*/
|
||||
struct rz_mtu3_channel {
|
||||
struct device *dev;
|
||||
unsigned int channel_number;
|
||||
struct mutex lock;
|
||||
bool is_busy;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rz_mtu3 - MTU3 core private data
|
||||
*
|
||||
* @clk: MTU3 module clock
|
||||
* @rz_mtu3_channel: HW channels
|
||||
* @priv_data: MTU3 core driver private data
|
||||
*/
|
||||
struct rz_mtu3 {
|
||||
struct clk *clk;
|
||||
struct rz_mtu3_channel channels[RZ_MTU_NUM_CHANNELS];
|
||||
|
||||
void *priv_data;
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_RZ_MTU3)
|
||||
static inline bool rz_mtu3_request_channel(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
mutex_lock(&ch->lock);
|
||||
if (ch->is_busy) {
|
||||
mutex_unlock(&ch->lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
ch->is_busy = true;
|
||||
mutex_unlock(&ch->lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void rz_mtu3_release_channel(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
mutex_lock(&ch->lock);
|
||||
ch->is_busy = false;
|
||||
mutex_unlock(&ch->lock);
|
||||
}
|
||||
|
||||
bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch);
|
||||
void rz_mtu3_disable(struct rz_mtu3_channel *ch);
|
||||
int rz_mtu3_enable(struct rz_mtu3_channel *ch);
|
||||
|
||||
u8 rz_mtu3_8bit_ch_read(struct rz_mtu3_channel *ch, u16 off);
|
||||
u16 rz_mtu3_16bit_ch_read(struct rz_mtu3_channel *ch, u16 off);
|
||||
u32 rz_mtu3_32bit_ch_read(struct rz_mtu3_channel *ch, u16 off);
|
||||
u16 rz_mtu3_shared_reg_read(struct rz_mtu3_channel *ch, u16 off);
|
||||
|
||||
void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u8 val);
|
||||
void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u16 val);
|
||||
void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u32 val);
|
||||
void rz_mtu3_shared_reg_write(struct rz_mtu3_channel *ch, u16 off, u16 val);
|
||||
void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch, u16 off,
|
||||
u16 pos, u8 val);
|
||||
#else
|
||||
static inline bool rz_mtu3_request_channel(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void rz_mtu3_release_channel(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool rz_mtu3_is_enabled(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void rz_mtu3_disable(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int rz_mtu3_enable(struct rz_mtu3_channel *ch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u8 rz_mtu3_8bit_ch_read(struct rz_mtu3_channel *ch, u16 off)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u16 rz_mtu3_16bit_ch_read(struct rz_mtu3_channel *ch, u16 off)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 rz_mtu3_32bit_ch_read(struct rz_mtu3_channel *ch, u16 off)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u16 rz_mtu3_shared_reg_read(struct rz_mtu3_channel *ch, u16 off)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void rz_mtu3_8bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u8 val)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void rz_mtu3_16bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u16 val)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void rz_mtu3_32bit_ch_write(struct rz_mtu3_channel *ch, u16 off, u32 val)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void rz_mtu3_shared_reg_write(struct rz_mtu3_channel *ch, u16 off, u16 val)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void rz_mtu3_shared_reg_update_bit(struct rz_mtu3_channel *ch,
|
||||
u16 off, u16 pos, u8 val)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MFD_RZ_MTU3_H__ */
|
@ -36,8 +36,6 @@
|
||||
struct gpio_desc;
|
||||
|
||||
enum sec_device_type {
|
||||
S5M8751X,
|
||||
S5M8763X,
|
||||
S5M8767X,
|
||||
S2MPA01,
|
||||
S2MPS11X,
|
||||
|
@ -194,54 +194,4 @@ enum s5m8767_irq {
|
||||
#define S5M8767_IRQ_RTC1S_MASK (1 << 4)
|
||||
#define S5M8767_IRQ_WTSR_MASK (1 << 5)
|
||||
|
||||
enum s5m8763_irq {
|
||||
S5M8763_IRQ_DCINF,
|
||||
S5M8763_IRQ_DCINR,
|
||||
S5M8763_IRQ_JIGF,
|
||||
S5M8763_IRQ_JIGR,
|
||||
S5M8763_IRQ_PWRONF,
|
||||
S5M8763_IRQ_PWRONR,
|
||||
|
||||
S5M8763_IRQ_WTSREVNT,
|
||||
S5M8763_IRQ_SMPLEVNT,
|
||||
S5M8763_IRQ_ALARM1,
|
||||
S5M8763_IRQ_ALARM0,
|
||||
|
||||
S5M8763_IRQ_ONKEY1S,
|
||||
S5M8763_IRQ_TOPOFFR,
|
||||
S5M8763_IRQ_DCINOVPR,
|
||||
S5M8763_IRQ_CHGRSTF,
|
||||
S5M8763_IRQ_DONER,
|
||||
S5M8763_IRQ_CHGFAULT,
|
||||
|
||||
S5M8763_IRQ_LOBAT1,
|
||||
S5M8763_IRQ_LOBAT2,
|
||||
|
||||
S5M8763_IRQ_NR,
|
||||
};
|
||||
|
||||
#define S5M8763_IRQ_DCINF_MASK (1 << 2)
|
||||
#define S5M8763_IRQ_DCINR_MASK (1 << 3)
|
||||
#define S5M8763_IRQ_JIGF_MASK (1 << 4)
|
||||
#define S5M8763_IRQ_JIGR_MASK (1 << 5)
|
||||
#define S5M8763_IRQ_PWRONF_MASK (1 << 6)
|
||||
#define S5M8763_IRQ_PWRONR_MASK (1 << 7)
|
||||
|
||||
#define S5M8763_IRQ_WTSREVNT_MASK (1 << 0)
|
||||
#define S5M8763_IRQ_SMPLEVNT_MASK (1 << 1)
|
||||
#define S5M8763_IRQ_ALARM1_MASK (1 << 2)
|
||||
#define S5M8763_IRQ_ALARM0_MASK (1 << 3)
|
||||
|
||||
#define S5M8763_IRQ_ONKEY1S_MASK (1 << 0)
|
||||
#define S5M8763_IRQ_TOPOFFR_MASK (1 << 2)
|
||||
#define S5M8763_IRQ_DCINOVPR_MASK (1 << 3)
|
||||
#define S5M8763_IRQ_CHGRSTF_MASK (1 << 4)
|
||||
#define S5M8763_IRQ_DONER_MASK (1 << 5)
|
||||
#define S5M8763_IRQ_CHGFAULT_MASK (1 << 7)
|
||||
|
||||
#define S5M8763_IRQ_LOBAT1_MASK (1 << 0)
|
||||
#define S5M8763_IRQ_LOBAT2_MASK (1 << 1)
|
||||
|
||||
#define S5M8763_ENRAMP (1 << 4)
|
||||
|
||||
#endif /* __LINUX_MFD_SEC_IRQ_H */
|
||||
|
@ -1,90 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2011 Samsung Electronics Co., Ltd
|
||||
* http://www.samsung.com
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MFD_S5M8763_H
|
||||
#define __LINUX_MFD_S5M8763_H
|
||||
|
||||
/* S5M8763 registers */
|
||||
enum s5m8763_reg {
|
||||
S5M8763_REG_IRQ1,
|
||||
S5M8763_REG_IRQ2,
|
||||
S5M8763_REG_IRQ3,
|
||||
S5M8763_REG_IRQ4,
|
||||
S5M8763_REG_IRQM1,
|
||||
S5M8763_REG_IRQM2,
|
||||
S5M8763_REG_IRQM3,
|
||||
S5M8763_REG_IRQM4,
|
||||
S5M8763_REG_STATUS1,
|
||||
S5M8763_REG_STATUS2,
|
||||
S5M8763_REG_STATUSM1,
|
||||
S5M8763_REG_STATUSM2,
|
||||
S5M8763_REG_CHGR1,
|
||||
S5M8763_REG_CHGR2,
|
||||
S5M8763_REG_LDO_ACTIVE_DISCHARGE1,
|
||||
S5M8763_REG_LDO_ACTIVE_DISCHARGE2,
|
||||
S5M8763_REG_BUCK_ACTIVE_DISCHARGE3,
|
||||
S5M8763_REG_ONOFF1,
|
||||
S5M8763_REG_ONOFF2,
|
||||
S5M8763_REG_ONOFF3,
|
||||
S5M8763_REG_ONOFF4,
|
||||
S5M8763_REG_BUCK1_VOLTAGE1,
|
||||
S5M8763_REG_BUCK1_VOLTAGE2,
|
||||
S5M8763_REG_BUCK1_VOLTAGE3,
|
||||
S5M8763_REG_BUCK1_VOLTAGE4,
|
||||
S5M8763_REG_BUCK2_VOLTAGE1,
|
||||
S5M8763_REG_BUCK2_VOLTAGE2,
|
||||
S5M8763_REG_BUCK3,
|
||||
S5M8763_REG_BUCK4,
|
||||
S5M8763_REG_LDO1_LDO2,
|
||||
S5M8763_REG_LDO3,
|
||||
S5M8763_REG_LDO4,
|
||||
S5M8763_REG_LDO5,
|
||||
S5M8763_REG_LDO6,
|
||||
S5M8763_REG_LDO7,
|
||||
S5M8763_REG_LDO7_LDO8,
|
||||
S5M8763_REG_LDO9_LDO10,
|
||||
S5M8763_REG_LDO11,
|
||||
S5M8763_REG_LDO12,
|
||||
S5M8763_REG_LDO13,
|
||||
S5M8763_REG_LDO14,
|
||||
S5M8763_REG_LDO15,
|
||||
S5M8763_REG_LDO16,
|
||||
S5M8763_REG_BKCHR,
|
||||
S5M8763_REG_LBCNFG1,
|
||||
S5M8763_REG_LBCNFG2,
|
||||
};
|
||||
|
||||
/* S5M8763 regulator ids */
|
||||
enum s5m8763_regulators {
|
||||
S5M8763_LDO1,
|
||||
S5M8763_LDO2,
|
||||
S5M8763_LDO3,
|
||||
S5M8763_LDO4,
|
||||
S5M8763_LDO5,
|
||||
S5M8763_LDO6,
|
||||
S5M8763_LDO7,
|
||||
S5M8763_LDO8,
|
||||
S5M8763_LDO9,
|
||||
S5M8763_LDO10,
|
||||
S5M8763_LDO11,
|
||||
S5M8763_LDO12,
|
||||
S5M8763_LDO13,
|
||||
S5M8763_LDO14,
|
||||
S5M8763_LDO15,
|
||||
S5M8763_LDO16,
|
||||
S5M8763_BUCK1,
|
||||
S5M8763_BUCK2,
|
||||
S5M8763_BUCK3,
|
||||
S5M8763_BUCK4,
|
||||
S5M8763_AP_EN32KHZ,
|
||||
S5M8763_CP_EN32KHZ,
|
||||
S5M8763_ENCHGVI,
|
||||
S5M8763_ESAFEUSB1,
|
||||
S5M8763_ESAFEUSB2,
|
||||
};
|
||||
|
||||
#define S5M8763_ENRAMP (1 << 4)
|
||||
#endif /* __LINUX_MFD_S5M8763_H */
|
Loading…
Reference in New Issue
Block a user