MFD for v6.19

* Add Core, Regulator, Onkey and Battery Charger support for the NXP PF1550
     Power Management IC (PMIC).
   * Introduce __SMC_KEY macro to fix GCC 15.2.1 errors in macsmc.
   * Add board definitions for TQMxCU1-HPCM and TQMxCU2-HPCM to the tqmx86 driver.
   * Add support for Broadcom BCM2712 SoC to the bcm2835-pm driver.
   * Hook up the qnap-mcu-eeprom sub-device to qnap-mcu.
 
   * Enable compile testing for the Altera SOCFPGA System Manager driver.
   * Fix device reference leak in altr_sysmgr_regmap_lookup_by_phandle().
   * Reserve the unused second I2C address for DA9063 to prevent userspace
     interference.
   * Fix resource leak in da9055_device_init() by calling regmap_del_irq_chip()
     in the error path.
   * Fix potential IRQ chip conflict when probing multiple MAX77620 devices by
     using devm_kmemdup for regmap_irq_chip.
   * Return -EPROBE_DEFER when a syscon devuice is not found to allow deferred
     probing.
   * Update email address for the PF1550 PMIC driver in MAINTAINERS.
   * Correct file entry for PF1550 MFD driver in MAINTAINERS from pfd1550.h to
     pf1550.h.
   * Calculate checksum on the actual number of received bytes in qnap-mcu for
     error messages.
   * Use -EPROTO instead of -EIO for checksum errors in qnap-mcu.
   * Add proper error handling for command errors (e.g., "@8", "@9") in qnap-mcu.
   * Fix missing irq_domain_remove() in error path of mt63{58,97}_irq_init().
 
   * Mark SMC write buffer arguments as const in apple_smc_write(), apple_smc_rw(),
     and apple_smc_write_atomic().
   * Simplify the error handling path in da9055_device_init() by removing a
     redundant mfd_remove_devices() call.
   * Use regmap_reg_range() and a real one-element array for pmic_status_range in
     rohm-bd718x7 for cleaner initialization.
   * Remove select I2C_K1 from MFD_SPACEMIT_P1 to avoid build failures when
     I2C_K1's dependencies are disabled.
   * Remove unneeded semicolon from ls2k_bmc_recover_pci_data().
   * Drop OF dependency for MFD_MAX5970 in Kconfig to allow wider compile testing
     and non-OF systems.
   * Make OF ID table style consistent in simple-mfd-i2c driver.
   * Update header inclusions in simple-mfd-i2c to follow IWYU (Include What You
     Use) principle.
   * Move checksum verification logic to a separate function in qnap-mcu.
   * Use chained IRQs for S2MPG10 in the Samsung SEC driver to simplify interrupt
     handling.
   * Drop a stray semicolon from sec-irq.c.
 
   * Remove the unused TI WL1273 FM radio core driver.
   * Remove the unused wl1273-core.h header and tidy up its reference in
     documentation.
 
   * Add Device Tree binding for the NXP PF1550 PMIC.
   * Add missing GPIO pins and supply properties to the Silergy SY7636A PMIC
     binding.
   * Add interrupt-controller property to the Maxim MAX77705 binding for
     sub-device interrupt source determination.
   * Add Device Tree binding for the Renesas R2A11302FT PMIC.
   * Allow the wakeup-source property in the Dialog DA9063 binding.
   * Make interrupt-related properties optional in the TI TPS65910 PMIC binding.
   * Document the Qualcomm PMIV0104 PMIC compatible string.
   * Document the Qualcomm PM7550 PMIC compatible string.
   * Enable power button subnode for TWL603x in the TI TWL binding.
   * Convert the Dialog DA9052/53 I2C binding from .txt to .yaml format,
     including compatible string fallback and interrupt properties.
   * Document control-scb and sysreg-scb syscons on pic64gx with fallback
     compatibles.
   * Document sama7g5-sfrbu and sama7d65-sfrbu syscons with fallback to
     atmel,sama5d2-sfrbu.
   * Fix LEDs node schema in fsl,mc13xxx binding by adding led@ child nodes and
     missing properties.
   * Add mt7981-topmisc compatible string to the syscon binding.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEdrbJNaO+IJqU8IdIUa+KL4f8d2EFAmkxtwoACgkQUa+KL4f8
 d2GiAw/9Ewvlpm+p0Ac/CjxwTRgeM08OJv7xzni3kHtefOvU/0dVTkqJsm3235yc
 SOO4zqCrpldUqAqLzycOmm1bDOMi3qCvmR/Es7gqhkskCHNZ9WDv3z6aZJEAo2g5
 A6RHb5W8lHWc8BqyyyahDfX0D5sHerh03CCWitHkr49oCqzMMaRssVY5Wp1tzKb/
 DYj+gCm8POLu5+0vuGm+I5t90mLOQA/MjHCVBMZ+4vtnXmre6w+fRWNSwGdqhTci
 zsrPUuKUgOy3PvVhjugk4dPHEEwxaZuQ/Az41fpeb8qj0Y0XEaLv6g2/O3Sc8E/j
 esyvbitg49noQCBWpefTUlWZjyxJivLIfIc2n3o+Tn+yWOVZ2+6AqXzhCYOqPeZw
 sodep1W8uweI66+MF67zwTfNuplVLQrRMWbv/mhnvQLxnc8cllhboUUu6SFGQ8hP
 phG5Zf1Gzmz3vJNGZRApwQnwj2nc7tY3FZdZnQW24gBU9tnrIH/LQyOEXoJsvRxC
 AU/VoRA6Tbr1PGuyXJuqaxzkYCbTXUX294wMW9w1HZiXB2wLGDEItLm55pcjZEYI
 ro3GRHW/7UjNg1Omwld5CuszNWFk06SSqBdP4XVJK5tpf02Rplk6EI6ftGH1zaoL
 n7FRKsc7W5Xhky0bTGrtqxNkXodUEVCR45n+wlkJv6VM66m9WeU=
 =2TS8
 -----END PGP SIGNATURE-----

Merge tag 'mfd-next-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "Updates:
   - Add Core, Regulator, Onkey and Battery Charger support for the NXP
     PF1550 Power Management IC (PMIC)
   - Introduce __SMC_KEY macro to fix GCC 15.2.1 errors in macsmc
   - Add board definitions for TQMxCU1-HPCM and TQMxCU2-HPCM to the
     tqmx86 driver
   - Add support for Broadcom BCM2712 SoC to the bcm2835-pm driver
   - Hook up the qnap-mcu-eeprom sub-device to qnap-mcu

  Fixes:
   - Enable compile testing for the Altera SOCFPGA System Manager driver
   - Fix device reference leak in altr_sysmgr_regmap_lookup_by_phandle()
   - Reserve the unused second I2C address for DA9063 to prevent
     userspace interference
   - Fix resource leak in da9055_device_init() by calling
     regmap_del_irq_chip() in the error path
   - Fix potential IRQ chip conflict when probing multiple MAX77620
     devices by using devm_kmemdup for regmap_irq_chip
   - Return -EPROBE_DEFER when a syscon devuice is not found to allow
     deferred probing
   - Update email address for the PF1550 PMIC driver in MAINTAINERS
   - Correct file entry for PF1550 MFD driver in MAINTAINERS from
     pfd1550.h to pf1550.h
   - Calculate checksum on the actual number of received bytes in
     qnap-mcu for error messages
   - Use -EPROTO instead of -EIO for checksum errors in qnap-mcu
   - Add proper error handling for command errors (e.g., "@8", "@9") in
     qnap-mcu
   - Fix missing irq_domain_remove() in error path of
     mt63{58,97}_irq_init()

  Cleanups:
   - Mark SMC write buffer arguments as const in apple_smc_write(),
     apple_smc_rw(), and apple_smc_write_atomic()
   - Simplify the error handling path in da9055_device_init() by
     removing a redundant mfd_remove_devices() call
   - Use regmap_reg_range() and a real one-element array for
     pmic_status_range in rohm-bd718x7 for cleaner initialization
   - Remove select I2C_K1 from MFD_SPACEMIT_P1 to avoid build failures
     when I2C_K1's dependencies are disabled
   - Remove unneeded semicolon from ls2k_bmc_recover_pci_data()
   - Drop OF dependency for MFD_MAX5970 in Kconfig to allow wider
     compile testing and non-OF systems
   - Make OF ID table style consistent in simple-mfd-i2c driver
   - Update header inclusions in simple-mfd-i2c to follow IWYU (Include
     What You Use) principle
   - Move checksum verification logic to a separate function in qnap-mcu
   - Use chained IRQs for S2MPG10 in the Samsung SEC driver to simplify
     interrupt handling
   - Drop a stray semicolon from sec-irq.c

  Removals:
   - Remove the unused TI WL1273 FM radio core driver
   - Remove the unused wl1273-core.h header and tidy up its reference in
     documentation

  Device tree bindings:
   - Add Device Tree binding for the NXP PF1550 PMIC
   - Add missing GPIO pins and supply properties to the Silergy SY7636A
     PMIC binding
   - Add interrupt-controller property to the Maxim MAX77705 binding for
     sub-device interrupt source determination
   - Add Device Tree binding for the Renesas R2A11302FT PMIC
   - Allow the wakeup-source property in the Dialog DA9063 binding
   - Make interrupt-related properties optional in the TI TPS65910 PMIC
     binding
   - Document the Qualcomm PMIV0104 PMIC compatible string
   - Document the Qualcomm PM7550 PMIC compatible string
   - Enable power button subnode for TWL603x in the TI TWL binding
   - Convert the Dialog DA9052/53 I2C binding from .txt to .yaml format,
     including compatible string fallback and interrupt properties
   - Document control-scb and sysreg-scb syscons on pic64gx with
     fallback compatibles
   - Document sama7g5-sfrbu and sama7d65-sfrbu syscons with fallback to
     atmel,sama5d2-sfrbu
   - Fix LEDs node schema in fsl,mc13xxx binding by adding led@ child
     nodes and missing properties
   - Add mt7981-topmisc compatible string to the syscon binding"

* tag 'mfd-next-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (42 commits)
  mfd: sec: Drop a stray semicolon
  mfd: qnap-mcu: Hook up the EEPROM sub-device
  dt-bindings: mfd: syscon: Add mt7981-topmisc
  dt-bindings: mfd: fsl,mc13xxx: Fix LEDs node schema
  mfd: mt6358-irq: Fix missing irq_domain_remove() in error path
  mfd: mt6397-irq: Fix missing irq_domain_remove() in error path
  dt-bindings: mfd: Document syscons falling back to atmel,sama5d2-sfrbu
  dt-bindings: mfd: Document control-scb and sysreg-scb on pic64gx
  dt-bindings: mfd: Convert dlg,da9052-i2c.txt to yaml format
  mfd: sec: Use chained IRQs for s2mpg10
  mfd: qnap-mcu: Add proper error handling for command errors
  mfd: qnap-mcu: Move checksum verification to its own function
  mfd: qnap-mcu: Use EPROTO in stead of EIO on checksum errors
  mfd: qnap-mcu: Calculate the checksum on the actual number of bytes received
  mfd: simple-mfd-i2c: Don't use "proxy" headers
  mfd: simple-mfd-i2c: Make ID table style consistent
  mfd: Kconfig: Drop OF dependency on MFD_MAX5970
  mfd: ls2kbmc: Remove unneeded semicolon from ls2k_bmc_recover_pci_data()
  dt-bindings: mfd: twl: Enable power button also for TWL603X
  MAINTAINERS: Adjust file entry in NXP PF1550 PMIC MFD DRIVER
  ...
This commit is contained in:
Linus Torvalds 2025-12-04 15:18:33 -08:00
commit 980190a947
36 changed files with 583 additions and 821 deletions

View File

@ -696,6 +696,7 @@ Sakari Ailus <sakari.ailus@linux.intel.com> <sakari.ailus@iki.fi>
Sam Protsenko <semen.protsenko@linaro.org>
Sam Protsenko <semen.protsenko@linaro.org> <semen.protsenko@globallogic.com>
Sam Ravnborg <sam@mars.ravnborg.org>
Samuel Kayode <samkay014@gmail.com> <samuel.kayode@savoirfairelinux.com>
Sankeerth Billakanti <quic_sbillaka@quicinc.com> <sbillaka@codeaurora.org>
Santosh Shilimkar <santosh.shilimkar@oracle.org>
Santosh Shilimkar <ssantosh@kernel.org>

View File

@ -30,7 +30,6 @@ radio-terratec TerraTec ActiveRadio ISA Standalone
radio-timb Enable the Timberdale radio driver
radio-trust Trust FM radio card
radio-typhoon Typhoon Radio (a.k.a. EcoRadio)
radio-wl1273 Texas Instruments WL1273 I2C FM Radio
fm_drv ISA radio devices
fm_drv ISA radio devices
radio-zoltrix Zoltrix Radio

View File

@ -1,67 +0,0 @@
* Dialog DA9052/53 Power Management Integrated Circuit (PMIC)
Required properties:
- compatible : Should be "dlg,da9052", "dlg,da9053-aa",
"dlg,da9053-ab", or "dlg,da9053-bb"
Optional properties:
- dlg,tsi-as-adc : Boolean, if set the X+, X-, Y+, Y- touchscreen
input lines are used as general purpose analogue
input.
- tsiref-supply: Phandle to the regulator, which provides the reference
voltage for the TSIREF pin. Must be provided when the
touchscreen pins are used for ADC purposes.
Sub-nodes:
- regulators : Contain the regulator nodes. The DA9052/53 regulators are
bound using their names as listed below:
buck1 : regulator BUCK CORE
buck2 : regulator BUCK PRO
buck3 : regulator BUCK MEM
buck4 : regulator BUCK PERI
ldo1 : regulator LDO1
ldo2 : regulator LDO2
ldo3 : regulator LDO3
ldo4 : regulator LDO4
ldo5 : regulator LDO5
ldo6 : regulator LDO6
ldo7 : regulator LDO7
ldo8 : regulator LDO8
ldo9 : regulator LDO9
ldo10 : regulator LDO10
The bindings details of individual regulator device can be found in:
Documentation/devicetree/bindings/regulator/regulator.txt
Examples:
i2c@63fc8000 { /* I2C1 */
pmic: dialog@48 {
compatible = "dlg,da9053-aa";
reg = <0x48>;
regulators {
buck1 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2075000>;
};
buck2 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2075000>;
};
buck3 {
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <2500000>;
};
buck4 {
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <2500000>;
};
};
};
};

View File

@ -0,0 +1,89 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mfd/dlg,da9052.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Dialog DA9052/53 Power Management Integrated Circuit (PMIC)
maintainers:
- Frank Li <Frank.Li@nxp.com>
properties:
compatible:
oneOf:
- enum:
- dlg,da9053-aa
- dlg,da9053-ab
- dlg,da9053-bb
- dlg,da9053-bc
- dlg,da9052
reg:
maxItems: 1
interrupts:
maxItems: 1
dlg,tsi-as-adc:
type: boolean
description:
if set the X+, X-, Y+, Y- touchscreen input lines are used as general
purpose analogue input.
tsiref-supply:
description: The reference voltage for the TSIREF pin.
regulators:
type: object
additionalProperties: false
patternProperties:
"^(ldo([1-9]|10)|buck[1-4])$":
type: object
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
required:
- compatible
- reg
- regulators
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
pmic@48 {
compatible = "dlg,da9053-aa";
reg = <0x48>;
regulators {
buck1 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2075000>;
};
buck2 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2075000>;
};
buck3 {
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <2500000>;
};
buck4 {
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <2500000>;
};
};
};
};

View File

@ -81,6 +81,8 @@ properties:
watchdog:
$ref: /schemas/watchdog/dlg,da9062-watchdog.yaml
wakeup-source: true
patternProperties:
"^(.+-hog(-[0-9]+)?)$":
type: object

View File

@ -93,7 +93,25 @@ properties:
leds:
type: object
additionalProperties: false
properties:
'#address-cells':
const: 1
'#size-cells':
const: 0
led-control:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: |
Setting for LED-Control register array length depends on model,
mc13783: 6, mc13892: 4, mc34708: 1
patternProperties:
'^led@[0-9a-b]$':
$ref: /schemas/leds/common.yaml#
unevaluatedProperties: false
properties:
reg:
@ -126,12 +144,6 @@ properties:
1: Charger Green
maxItems: 1
led-control:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: |
Setting for LED-Control register array length depends on model,
mc13783: 6, mc13892: 4, mc34708: 1
regulators:
type: object
@ -262,7 +274,7 @@ examples:
#size-cells = <0>;
led-control = <0x000 0x000 0x0e0 0x000>;
sysled@3 {
led@3 {
reg = <3>;
label = "system:red:live";
linux,default-trigger = "heartbeat";

View File

@ -26,6 +26,18 @@ properties:
interrupts:
maxItems: 1
interrupt-controller:
description:
The driver implements an interrupt controller for the sub devices.
The interrupt number mapping is as follows
0 - charger
1 - topsys
2 - fuelgauge
3 - usb type-c management block.
'#interrupt-cells':
const: 1
haptic:
type: object
additionalProperties: false
@ -118,8 +130,10 @@ examples:
pmic@66 {
compatible = "maxim,max77705";
reg = <0x66>;
#interrupt-cells = <1>;
interrupt-parent = <&pm8998_gpios>;
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
pinctrl-0 = <&chg_int_default>;
pinctrl-names = "default";

View File

@ -43,6 +43,7 @@ properties:
- qcom,pm7250b
- qcom,pm7550ba
- qcom,pm7325
- qcom,pm7550
- qcom,pm8004
- qcom,pm8005
- qcom,pm8009
@ -84,6 +85,7 @@ properties:
- qcom,pmi8994
- qcom,pmi8998
- qcom,pmih0108
- qcom,pmiv0104
- qcom,pmk8002
- qcom,pmk8350
- qcom,pmk8550

View File

@ -0,0 +1,58 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/mfd/renesas,r2a11302ft.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas R2A11302FT Power Supply ICs for R-Car
maintainers:
- Wolfram Sang <wsa+renesas@sang-engineering.com>
description: |
The Renesas R2A11302FT PMIC is used with Renesas R-Car Gen1/Gen2
based SoCs.
FIXME: The binding is incomplete and resembles the information gathered
so far.
properties:
compatible:
const: renesas,r2a11302ft
reg:
maxItems: 1
spi-max-frequency:
maximum: 6000000
spi-cpol: true
spi-cpha: true
required:
- compatible
- reg
- spi-cpol
- spi-cpha
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
pmic@0 {
compatible = "renesas,r2a11302ft";
reg = <0>;
spi-max-frequency = <6000000>;
spi-cpol;
spi-cpha;
};
};
...

View File

@ -32,6 +32,17 @@ properties:
Specifying the power good GPIOs.
maxItems: 1
enable-gpios:
maxItems: 1
vcom-en-gpios:
maxItems: 1
vin-supply:
description:
Supply for the whole chip. Some vendor kernels and devicetrees
declare this as a non-existing GPIO named "pwrall".
regulators:
type: object

View File

@ -85,6 +85,7 @@ select:
- mediatek,mt2701-pctl-a-syscfg
- mediatek,mt2712-pctl-a-syscfg
- mediatek,mt6397-pctl-pmic-syscfg
- mediatek,mt7981-topmisc
- mediatek,mt7988-topmisc
- mediatek,mt8135-pctl-a-syscfg
- mediatek,mt8135-pctl-b-syscfg
@ -133,7 +134,8 @@ select:
properties:
compatible:
items:
oneOf:
- items:
- enum:
- airoha,en7581-pbus-csr
- al,alpine-sysfabric-service
@ -238,6 +240,20 @@ properties:
- ti,j784s4-pcie-ctrl
- ti,keystone-pllctrl
- const: syscon
- items:
- enum:
- microchip,sama7g5-sfrbu
- microchip,sama7d65-sfrbu
- const: atmel,sama5d2-sfrbu
- const: syscon
- items:
- const: microchip,pic64gx-control-scb
- const: microchip,mpfs-control-scb
- const: syscon
- items:
- const: microchip,pic64gx-sysreg-scb
- const: microchip,mpfs-sysreg-scb
- const: syscon
reg:
maxItems: 1

View File

@ -166,9 +166,6 @@ patternProperties:
required:
- compatible
- reg
- interrupts
- interrupt-controller
- '#interrupt-cells'
- gpio-controller
- '#gpio-cells'
- regulators

View File

@ -55,6 +55,15 @@ allOf:
gpadc: false
pwrbutton:
properties:
compatible:
const: ti,twl4030-pwrbutton
interrupts:
items:
- items:
const: 8
usb-comparator: false
- if:
@ -95,7 +104,14 @@ allOf:
compatible:
const: ti,twl6030-gpadc
pwrbutton: false
pwrbutton:
properties:
compatible:
const: ti,twl6030-pwrbutton
interrupts:
items:
- items:
const: 0
madc: false
@ -146,7 +162,14 @@ allOf:
compatible:
const: ti,twl6032-gpadc
pwrbutton: false
pwrbutton:
properties:
compatible:
const: ti,twl6030-pwrbutton
interrupts:
items:
- items:
const: 0
madc: false
@ -226,11 +249,11 @@ properties:
properties:
compatible:
const: ti,twl4030-pwrbutton
enum:
- ti,twl4030-pwrbutton
- ti,twl6030-pwrbutton
interrupts:
items:
- items:
const: 8
maxItems: 1
watchdog:
type: object
@ -459,6 +482,11 @@ examples:
#io-channel-cells = <1>;
};
pwrbutton {
compatible = "ti,twl6030-pwrbutton";
interrupts = <0>;
};
rtc {
compatible = "ti,twl4030-rtc";
interrupts = <8>;

View File

@ -18742,7 +18742,7 @@ F: Documentation/devicetree/bindings/regulator/nxp,pf5300.yaml
F: drivers/regulator/pf530x-regulator.c
NXP PF1550 PMIC MFD DRIVER
M: Samuel Kayode <samuel.kayode@savoirfairelinux.com>
M: Samuel Kayode <samkay014@gmail.com>
L: imx@lists.linux.dev
S: Maintained
F: Documentation/devicetree/bindings/mfd/nxp,pf1550.yaml
@ -18750,7 +18750,7 @@ F: drivers/input/misc/pf1550-onkey.c
F: drivers/mfd/pf1550.c
F: drivers/power/supply/pf1550-charger.c
F: drivers/regulator/pf1550-regulator.c
F: include/linux/mfd/pfd1550.h
F: include/linux/mfd/pf1550.h
NXP PF8100/PF8121A/PF8200 PMIC REGULATOR DEVICE DRIVER
M: Jagan Teki <jagan@amarulasolutions.com>

View File

@ -45,7 +45,8 @@ config MFD_ALTERA_A10SR
config MFD_ALTERA_SYSMGR
bool "Altera SOCFPGA System Manager"
depends on ARCH_INTEL_SOCFPGA && OF
depends on ARCH_INTEL_SOCFPGA || COMPILE_TEST
depends on OF
select MFD_SYSCON
help
Select this to get System Manager support for all Altera branded
@ -895,7 +896,7 @@ config MFD_88PM886_PMIC
config MFD_MAX5970
tristate "Maxim 5970/5978 power switch and monitor"
depends on I2C && OF
depends on I2C
select MFD_SIMPLE_MFD_I2C
help
This driver controls a Maxim 5970/5978 switch via I2C bus.
@ -1274,7 +1275,6 @@ config MFD_SPACEMIT_P1
tristate "SpacemiT P1 PMIC"
depends on ARCH_SPACEMIT || COMPILE_TEST
depends on I2C
select I2C_K1
select MFD_SIMPLE_MFD_I2C
help
This option supports the I2C-based SpacemiT P1 PMIC, which
@ -2002,16 +2002,6 @@ config MENELAUS
and other features that are often used in portable devices like
cell phones and PDAs.
config MFD_WL1273_CORE
tristate "TI WL1273 FM radio"
depends on I2C
select MFD_CORE
default n
help
This is the core driver for the TI WL1273 FM radio. This MFD
driver connects the radio-wl1273 V4L2 module and the wl1273
audio codec.
config MFD_LM3533
tristate "TI/National Semiconductor LM3533 Lighting Power chip"
depends on I2C

View File

@ -207,7 +207,6 @@ obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o
obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
obj-$(CONFIG_MFD_VX855) += vx855.o
obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
si476x-core-y := si476x-cmd.o si476x-prop.o si476x-i2c.o
obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o

View File

@ -117,6 +117,8 @@ struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
sysmgr = dev_get_drvdata(dev);
put_device(dev);
return sysmgr->regmap;
}
EXPORT_SYMBOL_GPL(altr_sysmgr_regmap_lookup_by_phandle);

View File

@ -108,6 +108,7 @@ static const struct of_device_id bcm2835_pm_of_match[] = {
{ .compatible = "brcm,bcm2835-pm-wdt", },
{ .compatible = "brcm,bcm2835-pm", },
{ .compatible = "brcm,bcm2711-pm", },
{ .compatible = "brcm,bcm2712-pm", },
{},
};
MODULE_DEVICE_TABLE(of, bcm2835_pm_of_match);

View File

@ -387,7 +387,7 @@ int da9055_device_init(struct da9055 *da9055)
return 0;
err:
mfd_remove_devices(da9055->dev);
regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
return ret;
}

View File

@ -469,6 +469,9 @@ static int da9063_i2c_probe(struct i2c_client *i2c)
}
}
/* Reserve our unused second address so userspace won't interfere */
devm_i2c_new_dummy_device(&i2c->dev, i2c->adapter, i2c->addr + 1);
return da9063_device_init(da9063, i2c->irq);
}

View File

@ -265,7 +265,7 @@ static int ls2k_bmc_recover_pci_data(void *data)
if (!ls2k_bmc_bar0_addr_is_set(parent))
break;
mdelay(1);
};
}
if (i == 0)
return false;

View File

@ -173,7 +173,7 @@ int apple_smc_read(struct apple_smc *smc, smc_key key, void *buf, size_t size)
}
EXPORT_SYMBOL(apple_smc_read);
int apple_smc_write(struct apple_smc *smc, smc_key key, void *buf, size_t size)
int apple_smc_write(struct apple_smc *smc, smc_key key, const void *buf, size_t size)
{
guard(mutex)(&smc->mutex);
@ -181,7 +181,7 @@ int apple_smc_write(struct apple_smc *smc, smc_key key, void *buf, size_t size)
}
EXPORT_SYMBOL(apple_smc_write);
int apple_smc_rw(struct apple_smc *smc, smc_key key, void *wbuf, size_t wsize,
int apple_smc_rw(struct apple_smc *smc, smc_key key, const void *wbuf, size_t wsize,
void *rbuf, size_t rsize)
{
guard(mutex)(&smc->mutex);
@ -239,7 +239,7 @@ int apple_smc_enter_atomic(struct apple_smc *smc)
}
EXPORT_SYMBOL(apple_smc_enter_atomic);
int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, void *buf, size_t size)
int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, const void *buf, size_t size)
{
guard(spinlock_irqsave)(&smc->lock);
u8 result;

View File

@ -254,7 +254,7 @@ static int max77620_irq_global_unmask(void *irq_drv_data)
return ret;
}
static struct regmap_irq_chip max77620_top_irq_chip = {
static const struct regmap_irq_chip max77620_top_irq_chip = {
.name = "max77620-top",
.irqs = max77620_top_irqs,
.num_irqs = ARRAY_SIZE(max77620_top_irqs),
@ -498,6 +498,7 @@ static int max77620_probe(struct i2c_client *client)
const struct i2c_device_id *id = i2c_client_get_device_id(client);
const struct regmap_config *rmap_config;
struct max77620_chip *chip;
struct regmap_irq_chip *chip_desc;
const struct mfd_cell *mfd_cells;
int n_mfd_cells;
bool pm_off;
@ -508,6 +509,14 @@ static int max77620_probe(struct i2c_client *client)
return -ENOMEM;
i2c_set_clientdata(client, chip);
chip_desc = devm_kmemdup(&client->dev, &max77620_top_irq_chip,
sizeof(max77620_top_irq_chip),
GFP_KERNEL);
if (!chip_desc)
return -ENOMEM;
chip_desc->irq_drv_data = chip;
chip->dev = &client->dev;
chip->chip_irq = client->irq;
chip->chip_id = (enum max77620_chip_id)id->driver_data;
@ -544,11 +553,9 @@ static int max77620_probe(struct i2c_client *client)
if (ret < 0)
return ret;
max77620_top_irq_chip.irq_drv_data = chip;
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
IRQF_ONESHOT | IRQF_SHARED, 0,
&max77620_top_irq_chip,
&chip->top_irq_data);
chip_desc, &chip->top_irq_data);
if (ret < 0) {
dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret);
return ret;

View File

@ -285,6 +285,7 @@ int mt6358_irq_init(struct mt6397_chip *chip)
if (ret) {
dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n",
chip->irq, ret);
irq_domain_remove(chip->irq_domain);
return ret;
}

View File

@ -229,6 +229,7 @@ int mt6397_irq_init(struct mt6397_chip *chip)
if (ret) {
dev_err(chip->dev, "failed to register irq=%d; err: %d\n",
chip->irq, ret);
irq_domain_remove(chip->irq_domain);
return ret;
}

View File

@ -19,6 +19,7 @@
/* The longest command found so far is 5 bytes long */
#define QNAP_MCU_MAX_CMD_SIZE 5
#define QNAP_MCU_MAX_DATA_SIZE 36
#define QNAP_MCU_ERROR_SIZE 2
#define QNAP_MCU_CHECKSUM_SIZE 1
#define QNAP_MCU_RX_BUFFER_SIZE \
@ -78,6 +79,13 @@ static u8 qnap_mcu_csum(const u8 *buf, size_t size)
return csum;
}
static bool qnap_mcu_verify_checksum(const u8 *buf, size_t size)
{
u8 crc = qnap_mcu_csum(buf, size - QNAP_MCU_CHECKSUM_SIZE);
return crc == buf[size - QNAP_MCU_CHECKSUM_SIZE];
}
static int qnap_mcu_write(struct qnap_mcu *mcu, const u8 *data, u8 data_size)
{
unsigned char tx[QNAP_MCU_TX_BUFFER_SIZE];
@ -96,6 +104,48 @@ static int qnap_mcu_write(struct qnap_mcu *mcu, const u8 *data, u8 data_size)
return serdev_device_write(mcu->serdev, tx, length, HZ);
}
static bool qnap_mcu_is_error_msg(size_t size)
{
return (size == QNAP_MCU_ERROR_SIZE + QNAP_MCU_CHECKSUM_SIZE);
}
static bool qnap_mcu_reply_is_generic_error(unsigned char *buf, size_t size)
{
if (!qnap_mcu_is_error_msg(size))
return false;
if (buf[0] == '@' && buf[1] == '9')
return true;
return false;
}
static bool qnap_mcu_reply_is_checksum_error(unsigned char *buf, size_t size)
{
if (!qnap_mcu_is_error_msg(size))
return false;
if (buf[0] == '@' && buf[1] == '8')
return true;
return false;
}
static bool qnap_mcu_reply_is_any_error(struct qnap_mcu *mcu, unsigned char *buf, size_t size)
{
if (qnap_mcu_reply_is_generic_error(buf, size)) {
dev_err(&mcu->serdev->dev, "Controller sent generic error response\n");
return true;
}
if (qnap_mcu_reply_is_checksum_error(buf, size)) {
dev_err(&mcu->serdev->dev, "Controller received invalid checksum for the command\n");
return true;
}
return false;
}
static size_t qnap_mcu_receive_buf(struct serdev_device *serdev, const u8 *buf, size_t size)
{
struct device *dev = &serdev->dev;
@ -129,6 +179,24 @@ static size_t qnap_mcu_receive_buf(struct serdev_device *serdev, const u8 *buf,
}
}
/*
* We received everything the uart had to offer for now.
* This could mean that either the uart will send more in a 2nd
* receive run, or that the MCU cut the reply short because it
* sent an error code instead of the expected reply.
*
* So check if the received data has the correct size for an error
* reply and if it matches, is an actual error code.
*/
if (qnap_mcu_is_error_msg(reply->received) &&
qnap_mcu_verify_checksum(reply->data, reply->received) &&
qnap_mcu_reply_is_any_error(mcu, reply->data, reply->received)) {
/* The reply was an error code, we're done */
reply->length = 0;
complete(&reply->done);
}
/*
* The only way to get out of the above loop and end up here
* is through consuming all of the supplied data, so here we
@ -150,7 +218,6 @@ int qnap_mcu_exec(struct qnap_mcu *mcu,
size_t length = reply_data_size + QNAP_MCU_CHECKSUM_SIZE;
struct qnap_mcu_reply *reply = &mcu->reply;
int ret = 0;
u8 crc;
if (length > sizeof(rx)) {
dev_err(&mcu->serdev->dev, "expected data too big for receive buffer");
@ -175,12 +242,14 @@ int qnap_mcu_exec(struct qnap_mcu *mcu,
return -ETIMEDOUT;
}
crc = qnap_mcu_csum(rx, reply_data_size);
if (crc != rx[reply_data_size]) {
dev_err(&mcu->serdev->dev, "Invalid Checksum received\n");
return -EIO;
if (!qnap_mcu_verify_checksum(rx, reply->received)) {
dev_err(&mcu->serdev->dev, "Invalid Checksum received from controller\n");
return -EPROTO;
}
if (qnap_mcu_reply_is_any_error(mcu, rx, reply->received))
return -EPROTO;
memcpy(reply_data, rx, reply_data_size);
return 0;
@ -264,6 +333,7 @@ static const struct qnap_mcu_variant qnap_ts433_mcu = {
};
static struct mfd_cell qnap_mcu_cells[] = {
{ .name = "qnap-mcu-eeprom", },
{ .name = "qnap-mcu-input", },
{ .name = "qnap-mcu-leds", },
{ .name = "qnap-mcu-hwmon", }

View File

@ -72,14 +72,13 @@ static const struct regmap_irq_chip bd718xx_irq_chip = {
.init_ack_masked = true,
};
static const struct regmap_range pmic_status_range = {
.range_min = BD718XX_REG_IRQ,
.range_max = BD718XX_REG_POW_STATE,
static const struct regmap_range pmic_status_range[] = {
regmap_reg_range(BD718XX_REG_IRQ, BD718XX_REG_POW_STATE),
};
static const struct regmap_access_table volatile_regs = {
.yes_ranges = &pmic_status_range,
.n_yes_ranges = 1,
.yes_ranges = &pmic_status_range[0],
.n_yes_ranges = ARRAY_SIZE(pmic_status_range),
};
static const struct regmap_config bd718xx_regmap_config = {

View File

@ -325,11 +325,6 @@ static struct regmap *sec_pmic_acpm_regmap_init(struct device *dev,
return regmap;
}
static void sec_pmic_acpm_mask_common_irqs(void *regmap_common)
{
regmap_write(regmap_common, S2MPG10_COMMON_INT_MASK, S2MPG10_COMMON_INT_SRC);
}
static int sec_pmic_acpm_probe(struct platform_device *pdev)
{
struct regmap *regmap_common, *regmap_pmic, *regmap;
@ -360,15 +355,10 @@ static int sec_pmic_acpm_probe(struct platform_device *pdev)
shared_ctx->speedy_channel = pdata->speedy_channel;
regmap_common = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_COMMON,
pdata->regmap_cfg_common, false);
pdata->regmap_cfg_common, true);
if (IS_ERR(regmap_common))
return PTR_ERR(regmap_common);
/* Mask all interrupts from 'common' block, until successful init */
ret = regmap_write(regmap_common, S2MPG10_COMMON_INT_MASK, S2MPG10_COMMON_INT_SRC);
if (ret)
return dev_err_probe(dev, ret, "failed to mask common block interrupts\n");
regmap_pmic = sec_pmic_acpm_regmap_init(dev, shared_ctx, SEC_PMIC_ACPM_ACCESSTYPE_PMIC,
pdata->regmap_cfg_pmic, false);
if (IS_ERR(regmap_pmic))
@ -391,17 +381,6 @@ static int sec_pmic_acpm_probe(struct platform_device *pdev)
if (device_property_read_bool(dev, "wakeup-source"))
devm_device_init_wakeup(dev);
/* Unmask PMIC interrupt from 'common' block, now that everything is in place. */
ret = regmap_clear_bits(regmap_common, S2MPG10_COMMON_INT_MASK,
S2MPG10_COMMON_INT_SRC_PMIC);
if (ret)
return dev_err_probe(dev, ret, "failed to unmask PMIC interrupt\n");
/* Mask all interrupts from 'common' block on shutdown */
ret = devm_add_action_or_reset(dev, sec_pmic_acpm_mask_common_irqs, regmap_common);
if (ret)
return ret;
return 0;
}

View File

@ -20,6 +20,12 @@
#include "sec-core.h"
static const struct regmap_irq s2mpg10_irqs[] = {
REGMAP_IRQ_REG(S2MPG10_COMMON_IRQ_PMIC, 0, S2MPG10_COMMON_INT_SRC_PMIC),
/* No documentation or other reference for remaining bits */
REGMAP_IRQ_REG(S2MPG10_COMMON_IRQ_UNUSED, 0, GENMASK(7, 1)),
};
static const struct regmap_irq s2mpg10_pmic_irqs[] = {
REGMAP_IRQ_REG(S2MPG10_IRQ_PWRONF, 0, S2MPG10_IRQ_PWRONF_MASK),
REGMAP_IRQ_REG(S2MPG10_IRQ_PWRONR, 0, S2MPG10_IRQ_PWRONR_MASK),
REGMAP_IRQ_REG(S2MPG10_IRQ_JIGONBF, 0, S2MPG10_IRQ_JIGONBF_MASK),
@ -183,11 +189,20 @@ static const struct regmap_irq s5m8767_irqs[] = {
/* All S2MPG10 interrupt sources are read-only and don't require clearing */
static const struct regmap_irq_chip s2mpg10_irq_chip = {
.name = "s2mpg10",
.status_base = S2MPG10_COMMON_INT,
.mask_base = S2MPG10_COMMON_INT_MASK,
.num_regs = 1,
.irqs = s2mpg10_irqs,
.num_irqs = ARRAY_SIZE(s2mpg10_irqs),
.num_regs = 6,
};
static const struct regmap_irq_chip s2mpg10_irq_chip_pmic = {
.name = "s2mpg10-pmic",
.status_base = S2MPG10_PMIC_INT1,
.mask_base = S2MPG10_PMIC_INT1M,
.num_regs = 6,
.irqs = s2mpg10_pmic_irqs,
.num_irqs = ARRAY_SIZE(s2mpg10_pmic_irqs),
};
static const struct regmap_irq_chip s2mps11_irq_chip = {
@ -253,6 +268,59 @@ static const struct regmap_irq_chip s5m8767_irq_chip = {
.ack_base = S5M8767_REG_INT1,
};
static int s2mpg1x_add_chained_irq_chip(struct device *dev, struct regmap *regmap, int pirq,
struct regmap_irq_chip_data *parent,
const struct regmap_irq_chip *chip,
struct regmap_irq_chip_data **data)
{
int irq, ret;
irq = regmap_irq_get_virq(parent, pirq);
if (irq < 0)
return dev_err_probe(dev, irq, "Failed to get parent vIRQ(%d) for chip %s\n", pirq,
chip->name);
ret = devm_regmap_add_irq_chip(dev, regmap, irq, IRQF_ONESHOT | IRQF_SHARED, 0, chip, data);
if (ret)
return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name);
return 0;
}
static int sec_irq_init_s2mpg1x(struct sec_pmic_dev *sec_pmic)
{
const struct regmap_irq_chip *irq_chip, *chained_irq_chip;
struct regmap_irq_chip_data *irq_data;
struct regmap *regmap_common;
int chained_pirq;
int ret;
switch (sec_pmic->device_type) {
case S2MPG10:
irq_chip = &s2mpg10_irq_chip;
chained_irq_chip = &s2mpg10_irq_chip_pmic;
chained_pirq = S2MPG10_COMMON_IRQ_PMIC;
break;
default:
return dev_err_probe(sec_pmic->dev, -EINVAL, "Unsupported device type %d\n",
sec_pmic->device_type);
}
regmap_common = dev_get_regmap(sec_pmic->dev, "common");
if (!regmap_common)
return dev_err_probe(sec_pmic->dev, -EINVAL, "No 'common' regmap %d\n",
sec_pmic->device_type);
ret = devm_regmap_add_irq_chip(sec_pmic->dev, regmap_common, sec_pmic->irq, IRQF_ONESHOT, 0,
irq_chip, &irq_data);
if (ret)
return dev_err_probe(sec_pmic->dev, ret, "Failed to add %s IRQ chip\n",
irq_chip->name);
return s2mpg1x_add_chained_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic, chained_pirq,
irq_data, chained_irq_chip, &sec_pmic->irq_data);
}
int sec_irq_init(struct sec_pmic_dev *sec_pmic)
{
const struct regmap_irq_chip *sec_irq_chip;
@ -268,8 +336,7 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
sec_irq_chip = &s2mps14_irq_chip;
break;
case S2MPG10:
sec_irq_chip = &s2mpg10_irq_chip;
break;
return sec_irq_init_s2mpg1x(sec_pmic);
case S2MPS11X:
sec_irq_chip = &s2mps11_irq_chip;
break;

View File

@ -15,12 +15,18 @@
* will be subsequently registered.
*/
#include <linux/array_size.h>
#include <linux/dev_printk.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/stddef.h>
#include "simple-mfd-i2c.h"
@ -118,7 +124,7 @@ static const struct of_device_id simple_mfd_i2c_of_match[] = {
{ .compatible = "maxim,max5978", .data = &maxim_max5970 },
{ .compatible = "maxim,max77705-battery", .data = &maxim_mon_max77705 },
{ .compatible = "silergy,sy7636a", .data = &silergy_sy7636a },
{ .compatible = "spacemit,p1", .data = &spacemit_p1, },
{ .compatible = "spacemit,p1", .data = &spacemit_p1 },
{}
};
MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);

View File

@ -183,7 +183,7 @@ static struct regmap *device_node_get_regmap(struct device_node *np,
if (create_regmap)
syscon = of_syscon_register(np, check_res);
else
syscon = ERR_PTR(-EINVAL);
syscon = ERR_PTR(-EPROBE_DEFER);
}
mutex_unlock(&syscon_list_lock);

View File

@ -43,6 +43,8 @@
#define TQMX86_REG_BOARD_ID_E40C2 15
#define TQMX86_REG_BOARD_ID_130UC 16
#define TQMX86_REG_BOARD_ID_E41S 19
#define TQMX86_REG_BOARD_ID_CU1_HPCM 24
#define TQMX86_REG_BOARD_ID_CU2_HPCM 25
#define TQMX86_REG_BOARD_REV 0x01
#define TQMX86_REG_IO_EXT_INT 0x06
#define TQMX86_REG_IO_EXT_INT_NONE 0
@ -165,6 +167,10 @@ static const char *tqmx86_board_id_to_name(u8 board_id, u8 sauc)
return "TQMx130UC";
case TQMX86_REG_BOARD_ID_E41S:
return "TQMxE41S";
case TQMX86_REG_BOARD_ID_CU1_HPCM:
return "TQMxCU1-HPCM";
case TQMX86_REG_BOARD_ID_CU2_HPCM:
return "TQMxCU2-HPCM";
default:
return "Unknown";
}
@ -185,6 +191,8 @@ static int tqmx86_board_id_to_clk_rate(struct device *dev, u8 board_id)
case TQMX86_REG_BOARD_ID_E40C2:
case TQMX86_REG_BOARD_ID_130UC:
case TQMX86_REG_BOARD_ID_E41S:
case TQMX86_REG_BOARD_ID_CU1_HPCM:
case TQMX86_REG_BOARD_ID_CU2_HPCM:
return 24000;
case TQMX86_REG_BOARD_ID_E39MS:
case TQMX86_REG_BOARD_ID_E39C1:

View File

@ -1,262 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* MFD driver for wl1273 FM radio and audio codec submodules.
*
* Copyright (C) 2011 Nokia Corporation
* Author: Matti Aaltonen <matti.j.aaltonen@nokia.com>
*/
#include <linux/mfd/wl1273-core.h>
#include <linux/slab.h>
#include <linux/module.h>
#define DRIVER_DESC "WL1273 FM Radio Core"
static const struct i2c_device_id wl1273_driver_id_table[] = {
{ WL1273_FM_DRIVER_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table);
static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
{
struct i2c_client *client = core->client;
u8 b[2];
int r;
r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
if (r != 2) {
dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
return -EREMOTEIO;
}
*value = (u16)b[0] << 8 | b[1];
return 0;
}
static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
{
struct i2c_client *client = core->client;
u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
int r;
r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
if (r) {
dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
return r;
}
return 0;
}
static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
{
struct i2c_client *client = core->client;
struct i2c_msg msg;
int r;
msg.addr = client->addr;
msg.flags = 0;
msg.buf = data;
msg.len = len;
r = i2c_transfer(client->adapter, &msg, 1);
if (r != 1) {
dev_err(&client->dev, "%s: write error.\n", __func__);
return -EREMOTEIO;
}
return 0;
}
/**
* wl1273_fm_set_audio() - Set audio mode.
* @core: A pointer to the device struct.
* @new_mode: The new audio mode.
*
* Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
*/
static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
{
int r = 0;
if (core->mode == WL1273_MODE_OFF ||
core->mode == WL1273_MODE_SUSPENDED)
return -EPERM;
if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
WL1273_PCM_DEF_MODE);
if (r)
goto out;
r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
core->i2s_mode);
if (r)
goto out;
r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
WL1273_AUDIO_ENABLE_I2S);
if (r)
goto out;
} else if (core->mode == WL1273_MODE_RX &&
new_mode == WL1273_AUDIO_ANALOG) {
r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
WL1273_AUDIO_ENABLE_ANALOG);
if (r)
goto out;
} else if (core->mode == WL1273_MODE_TX &&
new_mode == WL1273_AUDIO_DIGITAL) {
r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
core->i2s_mode);
if (r)
goto out;
r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
WL1273_AUDIO_IO_SET_I2S);
if (r)
goto out;
} else if (core->mode == WL1273_MODE_TX &&
new_mode == WL1273_AUDIO_ANALOG) {
r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
WL1273_AUDIO_IO_SET_ANALOG);
if (r)
goto out;
}
core->audio_mode = new_mode;
out:
return r;
}
/**
* wl1273_fm_set_volume() - Set volume.
* @core: A pointer to the device struct.
* @volume: The new volume value.
*/
static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
{
int r;
if (volume > WL1273_MAX_VOLUME)
return -EINVAL;
if (core->volume == volume)
return 0;
r = wl1273_fm_write_cmd(core, WL1273_VOLUME_SET, volume);
if (r)
return r;
core->volume = volume;
return 0;
}
static int wl1273_core_probe(struct i2c_client *client)
{
struct wl1273_fm_platform_data *pdata = dev_get_platdata(&client->dev);
struct wl1273_core *core;
struct mfd_cell *cell;
int children = 0;
int r = 0;
dev_dbg(&client->dev, "%s\n", __func__);
if (!pdata) {
dev_err(&client->dev, "No platform data.\n");
return -EINVAL;
}
if (!(pdata->children & WL1273_RADIO_CHILD)) {
dev_err(&client->dev, "Cannot function without radio child.\n");
return -EINVAL;
}
core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
if (!core)
return -ENOMEM;
core->pdata = pdata;
core->client = client;
mutex_init(&core->lock);
i2c_set_clientdata(client, core);
dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__);
cell = &core->cells[children];
cell->name = "wl1273_fm_radio";
cell->platform_data = &core;
cell->pdata_size = sizeof(core);
children++;
core->read = wl1273_fm_read_reg;
core->write = wl1273_fm_write_cmd;
core->write_data = wl1273_fm_write_data;
core->set_audio = wl1273_fm_set_audio;
core->set_volume = wl1273_fm_set_volume;
if (pdata->children & WL1273_CODEC_CHILD) {
cell = &core->cells[children];
dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
cell->name = "wl1273-codec";
cell->platform_data = &core;
cell->pdata_size = sizeof(core);
children++;
}
dev_dbg(&client->dev, "%s: number of children: %d.\n",
__func__, children);
r = devm_mfd_add_devices(&client->dev, -1, core->cells,
children, NULL, 0, NULL);
if (r)
goto err;
return 0;
err:
pdata->free_resources();
dev_dbg(&client->dev, "%s\n", __func__);
return r;
}
static struct i2c_driver wl1273_core_driver = {
.driver = {
.name = WL1273_FM_DRIVER_NAME,
},
.probe = wl1273_core_probe,
.id_table = wl1273_driver_id_table,
};
static int __init wl1273_core_init(void)
{
int r;
r = i2c_add_driver(&wl1273_core_driver);
if (r) {
pr_err(WL1273_FM_DRIVER_NAME
": driver registration failed\n");
return r;
}
return r;
}
static void __exit wl1273_core_exit(void)
{
i2c_del_driver(&wl1273_core_driver);
}
late_initcall(wl1273_core_init);
module_exit(wl1273_core_exit);
MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

View File

@ -150,7 +150,7 @@ int apple_smc_read(struct apple_smc *smc, smc_key key, void *buf, size_t size);
*
* Return: Zero on success, negative errno on error
*/
int apple_smc_write(struct apple_smc *smc, smc_key key, void *buf, size_t size);
int apple_smc_write(struct apple_smc *smc, smc_key key, const void *buf, size_t size);
/**
* apple_smc_enter_atomic - Enter atomic mode to be able to use apple_smc_write_atomic
@ -177,7 +177,7 @@ int apple_smc_enter_atomic(struct apple_smc *smc);
*
* Return: Zero on success, negative errno on error
*/
int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, void *buf, size_t size);
int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, const void *buf, size_t size);
/**
* apple_smc_rw - Write and then read using the given SMC key
@ -190,7 +190,7 @@ int apple_smc_write_atomic(struct apple_smc *smc, smc_key key, void *buf, size_t
*
* Return: Zero on success, negative errno on error
*/
int apple_smc_rw(struct apple_smc *smc, smc_key key, void *wbuf, size_t wsize,
int apple_smc_rw(struct apple_smc *smc, smc_key key, const void *wbuf, size_t wsize,
void *rbuf, size_t rsize);
/**

View File

@ -57,6 +57,12 @@ enum s2mpa01_irq {
#define S2MPA01_IRQ_B24_TSD_MASK (1 << 4)
#define S2MPA01_IRQ_B35_TSD_MASK (1 << 5)
enum s2mpg10_common_irq {
/* Top-level (common) block */
S2MPG10_COMMON_IRQ_PMIC,
S2MPG10_COMMON_IRQ_UNUSED,
};
enum s2mpg10_irq {
/* PMIC */
S2MPG10_IRQ_PWRONF,

View File

@ -1,277 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* include/linux/mfd/wl1273-core.h
*
* Some definitions for the wl1273 radio receiver/transmitter chip.
*
* Copyright (C) 2010 Nokia Corporation
* Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com>
*/
#ifndef WL1273_CORE_H
#define WL1273_CORE_H
#include <linux/i2c.h>
#include <linux/mfd/core.h>
#define WL1273_FM_DRIVER_NAME "wl1273-fm"
#define RX71_FM_I2C_ADDR 0x22
#define WL1273_STEREO_GET 0
#define WL1273_RSSI_LVL_GET 1
#define WL1273_IF_COUNT_GET 2
#define WL1273_FLAG_GET 3
#define WL1273_RDS_SYNC_GET 4
#define WL1273_RDS_DATA_GET 5
#define WL1273_FREQ_SET 10
#define WL1273_AF_FREQ_SET 11
#define WL1273_MOST_MODE_SET 12
#define WL1273_MOST_BLEND_SET 13
#define WL1273_DEMPH_MODE_SET 14
#define WL1273_SEARCH_LVL_SET 15
#define WL1273_BAND_SET 16
#define WL1273_MUTE_STATUS_SET 17
#define WL1273_RDS_PAUSE_LVL_SET 18
#define WL1273_RDS_PAUSE_DUR_SET 19
#define WL1273_RDS_MEM_SET 20
#define WL1273_RDS_BLK_B_SET 21
#define WL1273_RDS_MSK_B_SET 22
#define WL1273_RDS_PI_MASK_SET 23
#define WL1273_RDS_PI_SET 24
#define WL1273_RDS_SYSTEM_SET 25
#define WL1273_INT_MASK_SET 26
#define WL1273_SEARCH_DIR_SET 27
#define WL1273_VOLUME_SET 28
#define WL1273_AUDIO_ENABLE 29
#define WL1273_PCM_MODE_SET 30
#define WL1273_I2S_MODE_CONFIG_SET 31
#define WL1273_POWER_SET 32
#define WL1273_INTX_CONFIG_SET 33
#define WL1273_PULL_EN_SET 34
#define WL1273_HILO_SET 35
#define WL1273_SWITCH2FREF 36
#define WL1273_FREQ_DRIFT_REPORT 37
#define WL1273_PCE_GET 40
#define WL1273_FIRM_VER_GET 41
#define WL1273_ASIC_VER_GET 42
#define WL1273_ASIC_ID_GET 43
#define WL1273_MAN_ID_GET 44
#define WL1273_TUNER_MODE_SET 45
#define WL1273_STOP_SEARCH 46
#define WL1273_RDS_CNTRL_SET 47
#define WL1273_WRITE_HARDWARE_REG 100
#define WL1273_CODE_DOWNLOAD 101
#define WL1273_RESET 102
#define WL1273_FM_POWER_MODE 254
#define WL1273_FM_INTERRUPT 255
/* Transmitter API */
#define WL1273_CHANL_SET 55
#define WL1273_SCAN_SPACING_SET 56
#define WL1273_REF_SET 57
#define WL1273_POWER_ENB_SET 90
#define WL1273_POWER_ATT_SET 58
#define WL1273_POWER_LEV_SET 59
#define WL1273_AUDIO_DEV_SET 60
#define WL1273_PILOT_DEV_SET 61
#define WL1273_RDS_DEV_SET 62
#define WL1273_PUPD_SET 91
#define WL1273_AUDIO_IO_SET 63
#define WL1273_PREMPH_SET 64
#define WL1273_MONO_SET 66
#define WL1273_MUTE 92
#define WL1273_MPX_LMT_ENABLE 67
#define WL1273_PI_SET 93
#define WL1273_ECC_SET 69
#define WL1273_PTY 70
#define WL1273_AF 71
#define WL1273_DISPLAY_MODE 74
#define WL1273_RDS_REP_SET 77
#define WL1273_RDS_CONFIG_DATA_SET 98
#define WL1273_RDS_DATA_SET 99
#define WL1273_RDS_DATA_ENB 94
#define WL1273_TA_SET 78
#define WL1273_TP_SET 79
#define WL1273_DI_SET 80
#define WL1273_MS_SET 81
#define WL1273_PS_SCROLL_SPEED 82
#define WL1273_TX_AUDIO_LEVEL_TEST 96
#define WL1273_TX_AUDIO_LEVEL_TEST_THRESHOLD 73
#define WL1273_TX_AUDIO_INPUT_LEVEL_RANGE_SET 54
#define WL1273_RX_ANTENNA_SELECT 87
#define WL1273_I2C_DEV_ADDR_SET 86
#define WL1273_REF_ERR_CALIB_PARAM_SET 88
#define WL1273_REF_ERR_CALIB_PERIODICITY_SET 89
#define WL1273_SOC_INT_TRIGGER 52
#define WL1273_SOC_AUDIO_PATH_SET 83
#define WL1273_SOC_PCMI_OVERRIDE 84
#define WL1273_SOC_I2S_OVERRIDE 85
#define WL1273_RSSI_BLOCK_SCAN_FREQ_SET 95
#define WL1273_RSSI_BLOCK_SCAN_START 97
#define WL1273_RSSI_BLOCK_SCAN_DATA_GET 5
#define WL1273_READ_FMANT_TUNE_VALUE 104
#define WL1273_RDS_OFF 0
#define WL1273_RDS_ON 1
#define WL1273_RDS_RESET 2
#define WL1273_AUDIO_DIGITAL 0
#define WL1273_AUDIO_ANALOG 1
#define WL1273_MODE_RX BIT(0)
#define WL1273_MODE_TX BIT(1)
#define WL1273_MODE_OFF BIT(2)
#define WL1273_MODE_SUSPENDED BIT(3)
#define WL1273_RADIO_CHILD BIT(0)
#define WL1273_CODEC_CHILD BIT(1)
#define WL1273_RX_MONO 1
#define WL1273_RX_STEREO 0
#define WL1273_TX_MONO 0
#define WL1273_TX_STEREO 1
#define WL1273_MAX_VOLUME 0xffff
#define WL1273_DEFAULT_VOLUME 0x78b8
/* I2S protocol, left channel first, data width 16 bits */
#define WL1273_PCM_DEF_MODE 0x00
/* Rx */
#define WL1273_AUDIO_ENABLE_I2S BIT(0)
#define WL1273_AUDIO_ENABLE_ANALOG BIT(1)
/* Tx */
#define WL1273_AUDIO_IO_SET_ANALOG 0
#define WL1273_AUDIO_IO_SET_I2S 1
#define WL1273_PUPD_SET_OFF 0x00
#define WL1273_PUPD_SET_ON 0x01
#define WL1273_PUPD_SET_RETENTION 0x10
/* I2S mode */
#define WL1273_IS2_WIDTH_32 0x0
#define WL1273_IS2_WIDTH_40 0x1
#define WL1273_IS2_WIDTH_22_23 0x2
#define WL1273_IS2_WIDTH_23_22 0x3
#define WL1273_IS2_WIDTH_48 0x4
#define WL1273_IS2_WIDTH_50 0x5
#define WL1273_IS2_WIDTH_60 0x6
#define WL1273_IS2_WIDTH_64 0x7
#define WL1273_IS2_WIDTH_80 0x8
#define WL1273_IS2_WIDTH_96 0x9
#define WL1273_IS2_WIDTH_128 0xa
#define WL1273_IS2_WIDTH 0xf
#define WL1273_IS2_FORMAT_STD (0x0 << 4)
#define WL1273_IS2_FORMAT_LEFT (0x1 << 4)
#define WL1273_IS2_FORMAT_RIGHT (0x2 << 4)
#define WL1273_IS2_FORMAT_USER (0x3 << 4)
#define WL1273_IS2_MASTER (0x0 << 6)
#define WL1273_IS2_SLAVEW (0x1 << 6)
#define WL1273_IS2_TRI_AFTER_SENDING (0x0 << 7)
#define WL1273_IS2_TRI_ALWAYS_ACTIVE (0x1 << 7)
#define WL1273_IS2_SDOWS_RR (0x0 << 8)
#define WL1273_IS2_SDOWS_RF (0x1 << 8)
#define WL1273_IS2_SDOWS_FR (0x2 << 8)
#define WL1273_IS2_SDOWS_FF (0x3 << 8)
#define WL1273_IS2_TRI_OPT (0x0 << 10)
#define WL1273_IS2_TRI_ALWAYS (0x1 << 10)
#define WL1273_IS2_RATE_48K (0x0 << 12)
#define WL1273_IS2_RATE_44_1K (0x1 << 12)
#define WL1273_IS2_RATE_32K (0x2 << 12)
#define WL1273_IS2_RATE_22_05K (0x4 << 12)
#define WL1273_IS2_RATE_16K (0x5 << 12)
#define WL1273_IS2_RATE_12K (0x8 << 12)
#define WL1273_IS2_RATE_11_025 (0x9 << 12)
#define WL1273_IS2_RATE_8K (0xa << 12)
#define WL1273_IS2_RATE (0xf << 12)
#define WL1273_I2S_DEF_MODE (WL1273_IS2_WIDTH_32 | \
WL1273_IS2_FORMAT_STD | \
WL1273_IS2_MASTER | \
WL1273_IS2_TRI_AFTER_SENDING | \
WL1273_IS2_SDOWS_RR | \
WL1273_IS2_TRI_OPT | \
WL1273_IS2_RATE_48K)
#define SCHAR_MIN (-128)
#define SCHAR_MAX 127
#define WL1273_FR_EVENT BIT(0)
#define WL1273_BL_EVENT BIT(1)
#define WL1273_RDS_EVENT BIT(2)
#define WL1273_BBLK_EVENT BIT(3)
#define WL1273_LSYNC_EVENT BIT(4)
#define WL1273_LEV_EVENT BIT(5)
#define WL1273_IFFR_EVENT BIT(6)
#define WL1273_PI_EVENT BIT(7)
#define WL1273_PD_EVENT BIT(8)
#define WL1273_STIC_EVENT BIT(9)
#define WL1273_MAL_EVENT BIT(10)
#define WL1273_POW_ENB_EVENT BIT(11)
#define WL1273_SCAN_OVER_EVENT BIT(12)
#define WL1273_ERROR_EVENT BIT(13)
#define TUNER_MODE_STOP_SEARCH 0
#define TUNER_MODE_PRESET 1
#define TUNER_MODE_AUTO_SEEK 2
#define TUNER_MODE_AF 3
#define TUNER_MODE_AUTO_SEEK_PI 4
#define TUNER_MODE_AUTO_SEEK_BULK 5
#define RDS_BLOCK_SIZE 3
struct wl1273_fm_platform_data {
int (*request_resources) (struct i2c_client *client);
void (*free_resources) (void);
void (*enable) (void);
void (*disable) (void);
u8 forbidden_modes;
unsigned int children;
};
#define WL1273_FM_CORE_CELLS 2
#define WL1273_BAND_OTHER 0
#define WL1273_BAND_JAPAN 1
#define WL1273_BAND_JAPAN_LOW 76000
#define WL1273_BAND_JAPAN_HIGH 90000
#define WL1273_BAND_OTHER_LOW 87500
#define WL1273_BAND_OTHER_HIGH 108000
#define WL1273_BAND_TX_LOW 76000
#define WL1273_BAND_TX_HIGH 108000
struct wl1273_core {
struct mfd_cell cells[WL1273_FM_CORE_CELLS];
struct wl1273_fm_platform_data *pdata;
unsigned int mode;
unsigned int i2s_mode;
unsigned int volume;
unsigned int audio_mode;
unsigned int channel_number;
struct mutex lock; /* for serializing fm radio operations */
struct i2c_client *client;
int (*read)(struct wl1273_core *core, u8, u16 *);
int (*write)(struct wl1273_core *core, u8, u16);
int (*write_data)(struct wl1273_core *core, u8 *, u16);
int (*set_audio)(struct wl1273_core *core, unsigned int);
int (*set_volume)(struct wl1273_core *core, unsigned int);
};
#endif /* ifndef WL1273_CORE_H */