124be24beSVincent Jardin.. SPDX-License-Identifier: GPL-2.0-only 224be24beSVincent Jardin.. Copyright (c) 2026 Free Mobile - Vincent Jardin <vjardin@free.fr> 324be24beSVincent Jardin 424be24beSVincent JardinKernel driver mpq8646 524be24beSVincent Jardin===================== 624be24beSVincent Jardin 724be24beSVincent JardinSupported chips: 824be24beSVincent Jardin 924be24beSVincent Jardin * MPS MPQ8646 1024be24beSVincent Jardin 1124be24beSVincent Jardin Prefix: 'mpq8646' 1224be24beSVincent Jardin 1324be24beSVincent JardinAuthor: 1424be24beSVincent Jardin - Vincent Jardin <vjardin@free.fr> 1524be24beSVincent Jardin 1624be24beSVincent JardinChip-identity 1724be24beSVincent Jardin------------- 1824be24beSVincent Jardin 1924be24beSVincent JardinSupport the boards that are designed with the MPS MPQ8646 probed thanks 2024be24beSVincent Jardinto``MFR_MODEL`` register. 2124be24beSVincent Jardin 2224be24beSVincent JardinThis driver targets the MPQ8646 silicon specifically. 2324be24beSVincent Jardin 2424be24beSVincent JardinDescription 2524be24beSVincent Jardin----------- 2624be24beSVincent Jardin 2724be24beSVincent JardinThe MPQ8646 is a fully integrated, PMBus-compatible, high-frequency, 2824be24beSVincent Jardinsynchronous buck converter. It offers a compact solution that 2924be24beSVincent Jardinachieves up high Amps output current per phase, with excellent load 3024be24beSVincent Jardinand line regulation over a wide input supply range. The chip 3124be24beSVincent Jardinoperates at high efficiency over a wide output current load range. 3224be24beSVincent Jardin 3324be24beSVincent JardinThe PMBus interface provides converter configurations and key 3424be24beSVincent Jardinparameters monitoring. 3524be24beSVincent Jardin 3624be24beSVincent JardinThe device adopts MPS's proprietary multi-phase digital 3724be24beSVincent Jardinconstant-on-time (MCOT) control, which provides fast transient 3824be24beSVincent Jardinresponse and eases loop stabilization. The MCOT scheme also allows 3924be24beSVincent Jardinmultiple devices or channels to be connected in parallel with 4024be24beSVincent Jardinexcellent current sharing and phase interleaving for high-current 4124be24beSVincent Jardinapplications. 4224be24beSVincent Jardin 4324be24beSVincent JardinFully integrated protection features include over-current 4424be24beSVincent Jardinprotection (OCP), over-voltage protection (OVP), under-voltage 4524be24beSVincent Jardinprotection (UVP), and over-temperature protection (OTP). 4624be24beSVincent Jardin 4724be24beSVincent JardinThis device is compliant with: 4824be24beSVincent Jardin 4924be24beSVincent Jardin- PMBus rev 1.3 interface. 5024be24beSVincent Jardin 5124be24beSVincent JardinThe driver exports the following attributes via the 'sysfs' files 5224be24beSVincent Jardinfor input voltage: 5324be24beSVincent Jardin 5424be24beSVincent Jardin- in1_input 5524be24beSVincent Jardin- in1_label 5624be24beSVincent Jardin- in1_max 5724be24beSVincent Jardin- in1_max_alarm 5824be24beSVincent Jardin- in1_min 5924be24beSVincent Jardin- in1_min_alarm 6024be24beSVincent Jardin- in1_crit 6124be24beSVincent Jardin- in1_crit_alarm 6224be24beSVincent Jardin 6324be24beSVincent JardinThe driver provides the following attributes for output voltage: 6424be24beSVincent Jardin 6524be24beSVincent Jardin- in2_input 6624be24beSVincent Jardin- in2_label 6724be24beSVincent Jardin- in2_alarm 6824be24beSVincent Jardin- in2_max 6924be24beSVincent Jardin- in2_max_alarm 7024be24beSVincent Jardin- in2_min 7124be24beSVincent Jardin- in2_min_alarm 7224be24beSVincent Jardin- in2_crit 7324be24beSVincent Jardin- in2_crit_alarm 7424be24beSVincent Jardin- in2_lcrit 7524be24beSVincent Jardin- in2_lcrit_alarm 7624be24beSVincent Jardin 7724be24beSVincent JardinThe driver provides the following attributes for output current: 7824be24beSVincent Jardin 7924be24beSVincent Jardin- curr1_input 8024be24beSVincent Jardin- curr1_label 8124be24beSVincent Jardin- curr1_max 8224be24beSVincent Jardin- curr1_max_alarm 8324be24beSVincent Jardin- curr1_crit 8424be24beSVincent Jardin- curr1_crit_alarm 8524be24beSVincent Jardin 8624be24beSVincent JardinThe driver provides the following attributes for temperature: 8724be24beSVincent Jardin 8824be24beSVincent Jardin- temp1_input 8924be24beSVincent Jardin- temp1_max 9024be24beSVincent Jardin- temp1_max_alarm 9124be24beSVincent Jardin- temp1_crit 9224be24beSVincent Jardin- temp1_crit_alarm 9324be24beSVincent Jardin 9424be24beSVincent JardinAlarm acknowledgment 9524be24beSVincent Jardin--------------------- 9624be24beSVincent Jardin 9724be24beSVincent JardinThe hwmon-class ``inX_alarm``/``currX_alarm``/``tempX_alarm`` files are 9824be24beSVincent Jardinread-only in pmbus_core. The driver exposes the standard 9924be24beSVincent Jardin``PMBUS_VIRT_RESET_*_HISTORY`` virtual-register channel for fault 10024be24beSVincent Jardinacknowledgment: writing ``1`` to ``inX_reset_history`` / 10124be24beSVincent Jardin``currX_reset_history`` / ``tempX_reset_history`` sends the chip a 10224be24beSVincent Jardin``CLEAR_FAULTS`` (0x03) Send-Byte, which clears the latched 10324be24beSVincent Jardin``STATUS_WORD`` / ``STATUS_VOUT`` / ``STATUS_IOUT`` / 10424be24beSVincent Jardin``STATUS_INPUT`` / ``STATUS_TEMPERATURE`` bits the chip is currently 10524be24beSVincent Jardinexposing. 10624be24beSVincent Jardin 10724be24beSVincent JardinThe MPS-specific NVM post-mortem register 10824be24beSVincent Jardin``PROTECTION_LAST`` (0xFB) is not cleared by this path; it can be read 10924be24beSVincent Jardin(decoded) via the ``protection_last`` debugfs entry described below. 11024be24beSVincent Jardin 11124be24beSVincent JardinRegulator framework integration 11224be24beSVincent Jardin------------------------------- 11324be24beSVincent Jardin 11424be24beSVincent JardinWhen ``CONFIG_REGULATOR=y`` is set, the chip is 11524be24beSVincent Jardinexposed under ``/sys/class/regulator/`` and accepts the standard 11624be24beSVincent Jardinregulator framework operations: 11724be24beSVincent Jardin 11824be24beSVincent Jardin- ``regulator_enable()`` / ``regulator_disable()`` -> ``OPERATION`` (0x01) 11924be24beSVincent Jardin- ``regulator_set_voltage()`` -> ``VOUT_COMMAND`` (0x21) 12024be24beSVincent Jardin- ``regulator_get_voltage()`` -> ``READ_VOUT`` (0x8B) 12124be24beSVincent Jardin- ``regulator_is_enabled()`` -> ``OPERATION`` bit-decode 12224be24beSVincent Jardin 12324be24beSVincent JardinThe single regulator descriptor is named ``"vout"`` (page 0). For a 12424be24beSVincent Jardinmulti-page configuration the descriptor table can be extended in 12524be24beSVincent Jardinthe driver. 12624be24beSVincent Jardin 12724be24beSVincent JardinIn-driver alarm-poll fallback 12824be24beSVincent Jardin----------------------------- 12924be24beSVincent Jardin 13024be24beSVincent JardinOn boards where the chip's ``SMBALERT#`` pin is unavailable to the 13124be24beSVincent JardinSoC, ``pmbus_core::pmbus_irq_setup`` cannot deliver SMBALERT-driven 13224be24beSVincent Jardin``poll(POLLPRI)`` wakes or ``udev change@...`` events on the 13324be24beSVincent Jardin``inX_alarm`` files. The driver provides a ``delayed_work``-based 13424be24beSVincent Jardinpolling fallback that 13524be24beSVincent Jardinperiodically invokes the pmbus core fault check, 13624be24beSVincent Jardin``pmbus_check_and_notify_faults()``, which sends the notifications and 13724be24beSVincent Jardinthen clears the latched faults, exactly like the ``SMBALERT#`` 13824be24beSVincent Jardininterrupt path. The frequency of polling is tunable: 13924be24beSVincent Jardin 14024be24beSVincent Jardin:: 14124be24beSVincent Jardin 14224be24beSVincent Jardin /sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/alarm_poll_interval_ms 14324be24beSVincent Jardin 14424be24beSVincent JardinThe default is 1000 ms. 14524be24beSVincent Jardin 14624be24beSVincent JardinSet it to 0 to disable. The worker self-suppresses 14724be24beSVincent Jardinwhen ``client->irq != 0`` (i.e. when DT supplies an 14824be24beSVincent Jardin``interrupts = <...>`` property on the regulator node), so adding 14924be24beSVincent Jardin``SMBALERT#`` wiring is a zero-driver-change uplift on a future 15024be24beSVincent Jardinboard rev. 15124be24beSVincent Jardin 15224be24beSVincent JardinMPS post-mortem (PROTECTION_LAST) 15324be24beSVincent Jardin--------------------------------- 15424be24beSVincent Jardin 15524be24beSVincent JardinThe MPQ8646 silicon keeps a single 16-bit NVM-backed record of the 15624be24beSVincent Jardinlast protection event in ``PROTECTION_LAST`` (0xFB). It survives 15724be24beSVincent Jardinchip power/reset. The following debugfs entries expose it: 15824be24beSVincent Jardin 15924be24beSVincent Jardin:: 16024be24beSVincent Jardin 16124be24beSVincent Jardin /sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/protection_last (RO) 16224be24beSVincent Jardin /sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/status_decoded (RO) 16324be24beSVincent Jardin 16424be24beSVincent Jardin``protection_last`` decodes the 16-bit value based on the datasheet 16524be24beSVincent Jardinfault names (``INIT_FAULT``, ``NVM_CRC_ERROR``, ``NVM_FAULT``, 16624be24beSVincent Jardin``OC_PHASE_FAULT``, ``OTP_SELF_FAULT``, ``SWITCH_PRD_FAULT``, 16724be24beSVincent Jardin``VIN_OV_FAULT``, ``VOUT_OV_FAULT``, ``VOUT_UV_FAULT``, 16824be24beSVincent Jardin``OC_TOT_FAULT``, ``VIN_UVLO_FAULT``, ``DRMOS_OTP``). 16924be24beSVincent Jardin 17024be24beSVincent Jardin``status_decoded`` reads ``STATUS_WORD`` (0x79) and renders the 17124be24beSVincent Jardin16 bits with MPS-extension labels (bit12 = ``NVM_SUMMARY``, 17224be24beSVincent Jardinbit8 = ``WATCH_DOG``, bit0 = ``DRMOS_FAULT``) instead of the 17324be24beSVincent JardinPMBus 1.3 spec generic names. 17424be24beSVincent Jardin 17524be24beSVincent JardinNVMEM snapshot 17624be24beSVincent Jardin-------------- 17724be24beSVincent Jardin 17824be24beSVincent JardinWhen ``CONFIG_NVMEM=y`` is set, the chip's NVM-backed 17924be24beSVincent Jardinobservability registers are exposed as a single 16-byte read-only 18024be24beSVincent Jardin``nvmem_device`` at ``/sys/bus/nvmem/devices/<i2c-name>/nvmem``. 18124be24beSVincent JardinLayout (little-endian for 16-bit fields, zero-fill on per-entry read 18224be24beSVincent Jardinfailure and for the reserved tail): 18324be24beSVincent Jardin 18424be24beSVincent Jardin:: 18524be24beSVincent Jardin 18624be24beSVincent Jardin offset 0..1 PROTECTION_LAST (0xFB) word 18724be24beSVincent Jardin offset 2..3 MFR_RETRY_TIMES (0xF4) word 18824be24beSVincent Jardin offset 4..5 MFR_CONFIG_ID (0xC0) word 18924be24beSVincent Jardin offset 6..7 MFR_VBOOT_CFG (0xFC) word 19024be24beSVincent Jardin offset 8 MFR_SILICON_REV (0xC3) byte 19124be24beSVincent Jardin offset 9..15 reserved (zero) 19224be24beSVincent Jardin 19324be24beSVincent JardinSuitable for single-``cat`` post-mortem capture by a fleet daemon. 19424be24beSVincent Jardin 19524be24beSVincent JardinDiagnostics and introspection 19624be24beSVincent Jardin----------------------------- 19724be24beSVincent Jardin 19824be24beSVincent JardinWhen ``CONFIG_DEBUG_FS=y`` is set, the driver adds a read-only 19924be24beSVincent Jardindecode surface to the client's pmbus debugfs directory, 20024be24beSVincent Jardin``/sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/``. 20124be24beSVincent JardinThe driver intentionally exposes no raw register poke/peek debugfs; 20224be24beSVincent Jardinuse i2c-dev (``i2cget``/``i2cset``/``i2ctransfer``) for that. 20324be24beSVincent Jardin 20424be24beSVincent JardinIdentity / observability (read-only): 20524be24beSVincent Jardin 20624be24beSVincent Jardin========================== ================== ================================= 20724be24beSVincent JardinFile PMBus / MFR cmd Description 20824be24beSVincent Jardin========================== ================== ================================= 20924be24beSVincent Jardin``mfr_config_id`` 0xC0 (word) board / SKU NVM identifier 21024be24beSVincent Jardin``mfr_config_code_rev`` 0xC1 (word) NVM image revision (PART_RECOG + 21124be24beSVincent Jardin config code rev fields) 21224be24beSVincent Jardin``mfr_silicon_rev`` 0xC3 (byte) die revision 21324be24beSVincent Jardin``mfr_retry_times`` 0xF4 (word) per-fault-class recovery-mode 21424be24beSVincent Jardin configuration (NOT a retry 21524be24beSVincent Jardin count). Four 4-bit fields 21624be24beSVincent Jardin [15:12]=OTP, [11:8]=VOUT_OV, 21724be24beSVincent Jardin [7:4]=VOUT_UV, [3:0]=OCP. 21824be24beSVincent Jardin Each field: 0x0=latch-off, 21924be24beSVincent Jardin 0x1..0xE=retry N times then 22024be24beSVincent Jardin latch off, 0xF=hiccup 22124be24beSVincent Jardin (retry indefinitely). The 22224be24beSVincent Jardin chip exposes no in-NVM 22324be24beSVincent Jardin retry-event counter; track 22424be24beSVincent Jardin transitions externally if 22524be24beSVincent Jardin needed (poll 22624be24beSVincent Jardin ``protection_last`` or watch 22724be24beSVincent Jardin ``inX_alarm`` / ``temp1_alarm`` 22824be24beSVincent Jardin ``poll(POLLPRI)`` wakes). 22924be24beSVincent Jardin``mfr_vboot_cfg`` 0xFC (word) ADDR/VBOOT latched at POR 23024be24beSVincent Jardin========================== ================== ================================= 23124be24beSVincent Jardin 23224be24beSVincent JardinTiming / UVLO knobs (read-only): 23324be24beSVincent Jardin 23424be24beSVincent Jardin========================== ================== ================================= 23524be24beSVincent JardinFile PMBus cmd Description 23624be24beSVincent Jardin========================== ================== ================================= 23724be24beSVincent Jardin``vin_on`` 0x35 (word) UVLO turn-on threshold 23824be24beSVincent Jardin``vin_off`` 0x36 (word) UVLO turn-off threshold 23924be24beSVincent Jardin``ton_delay`` 0x60 (word) soft-start delay 24024be24beSVincent Jardin``ton_rise`` 0x61 (word) soft-start ramp time 24124be24beSVincent Jardin``toff_delay`` 0x64 (word) soft-stop delay 24224be24beSVincent Jardin``toff_fall`` 0x65 (word) soft-stop ramp time 24324be24beSVincent Jardin========================== ================== ================================= 24424be24beSVincent Jardin 24524be24beSVincent JardinThe only writable entry is ``alarm_poll_interval_ms`` (the alarm-poll 24624be24beSVincent Jardinworker cadence, see above), it is driver-local and never touches the 24724be24beSVincent Jardinchip. 24824be24beSVincent Jardin 249*25ad6213SVincent JardinUnsafe provisioning 250*25ad6213SVincent Jardin------------------- 251*25ad6213SVincent Jardin 252*25ad6213SVincent JardinAvailable only when ``CONFIG_SENSORS_MPQ8646_DEBUG_UNSAFE=y`` 253*25ad6213SVincent Jardin(``default n``, it is for boards bring up only). They WRITE to the regulator. 254*25ad6213SVincent JardinOn many designs the MPQ8646 powers the main CPU core rail, so a wrong write can 255*25ad6213SVincent Jardinbrown out the board or persist a bad setpoint into finite-cycle NVM. 256*25ad6213SVincent JardinWARNING: Some wrong register writes can and likely will physically damage or 257*25ad6213SVincent Jardindestroy the chip and/or the board. An explicit warning banner is printed at probe 258*25ad6213SVincent Jardintime when this option is enabled. 259*25ad6213SVincent Jardin 260*25ad6213SVincent Jardin=============================== =============== ========================================================= 261*25ad6213SVincent JardinFile PMBus / MFR cmd Description 262*25ad6213SVincent Jardin=============================== =============== ========================================================= 263*25ad6213SVincent Jardin``store_all`` 0x15 STORE_USER_ALL Send-Byte (commit RAM config to NVM) 264*25ad6213SVincent Jardin``restore_all`` 0x16 RESTORE_USER_ALL Send-Byte (revert RAM to last-NVM image) 265*25ad6213SVincent Jardin``clear_protection_last`` 0x08 CLEAR_LAST_FAULT Send-Byte 266*25ad6213SVincent Jardin``clear_protection_last_force`` -- gated CLEAR_LAST_FAULT, see below 267*25ad6213SVincent Jardin``on_off_config`` 0x02 (byte) PMBus vs CTRL-pin on/off source + active polarity 268*25ad6213SVincent Jardin``vout_margin_high`` 0x25 (word) margin-high VOUT setpoint 269*25ad6213SVincent Jardin``vout_margin_low`` 0x26 (word) margin-low VOUT setpoint 270*25ad6213SVincent Jardin``mfr_pmbus_lock`` 0xEE (word) programmable PMBus write-lock 271*25ad6213SVincent Jardin``mfr_product_rev_user`` 0xC2 (word) user-programmable product revision 272*25ad6213SVincent Jardin=============================== =============== ========================================================= 273*25ad6213SVincent Jardin 274*25ad6213SVincent Jardin``clear_protection_last`` writes ``CLEAR_LAST_FAULT`` (0x08) Send-Byte. 275*25ad6213SVincent JardinThe chip silently no-ops unless ``MFR_CFG_EXT`` (0xF5) bit[6] is set. 276*25ad6213SVincent Jardin 277*25ad6213SVincent Jardin``clear_protection_last_force`` performs the unlock with the following 278*25ad6213SVincent Jardinsix-step dancing: 279*25ad6213SVincent Jardin 280*25ad6213SVincent Jardin1. read ``WRITE_PROTECT`` (0x10) and ``MFR_CFG_EXT`` (0xF5) for restore 281*25ad6213SVincent Jardin2. clear ``WRITE_PROTECT`` if set 282*25ad6213SVincent Jardin3. set ``MFR_CFG_EXT`` bit[6] = 1, preserving other bits 283*25ad6213SVincent Jardin4. send ``CLEAR_LAST_FAULT`` (0x08) 284*25ad6213SVincent Jardin5. restore ``MFR_CFG_EXT`` (with retry to handle the chip's 285*25ad6213SVincent Jardin undocumented post-NVM-write busy window) 286*25ad6213SVincent Jardin6. restore ``WRITE_PROTECT`` 287*25ad6213SVincent Jardin 28824be24beSVincent JardinDevicetree 28924be24beSVincent Jardin---------- 29024be24beSVincent Jardin 29124be24beSVincent JardinThe driver uses ``compatible = "mps,mpq8646"``. There are some few optional 29224be24beSVincent Jardinproperties: 29324be24beSVincent Jardin 29424be24beSVincent Jardin- ``mps,vout-fb-divider-ratio-permille`` : it writes ``VOUT_SCALE_LOOP`` 29524be24beSVincent Jardin (0x29) at probe to compensate for an external resistor divider in 29624be24beSVincent Jardin the VOUT feedback path. The valid range is 11-bit. 29724be24beSVincent Jardin- ``interrupts = <...>`` : if the board routes the chip's 29824be24beSVincent Jardin ``SMBALERT#`` pin to a SoC GPIO, declaring it here lights up 29924be24beSVincent Jardin ``pmbus_core::pmbus_irq_setup`` and disables the in-driver 30024be24beSVincent Jardin alarm-poll fallback 301