1.. SPDX-License-Identifier: GPL-2.0-only 2.. Copyright (c) 2026 Free Mobile - Vincent Jardin <vjardin@free.fr> 3 4Kernel driver mpq8646 5===================== 6 7Supported chips: 8 9 * MPS MPQ8646 10 11 Prefix: 'mpq8646' 12 13Author: 14 - Vincent Jardin <vjardin@free.fr> 15 16Chip-identity 17------------- 18 19Support the boards that are designed with the MPS MPQ8646 probed thanks 20to``MFR_MODEL`` register. 21 22This driver targets the MPQ8646 silicon specifically. 23 24Description 25----------- 26 27The MPQ8646 is a fully integrated, PMBus-compatible, high-frequency, 28synchronous buck converter. It offers a compact solution that 29achieves up high Amps output current per phase, with excellent load 30and line regulation over a wide input supply range. The chip 31operates at high efficiency over a wide output current load range. 32 33The PMBus interface provides converter configurations and key 34parameters monitoring. 35 36The device adopts MPS's proprietary multi-phase digital 37constant-on-time (MCOT) control, which provides fast transient 38response and eases loop stabilization. The MCOT scheme also allows 39multiple devices or channels to be connected in parallel with 40excellent current sharing and phase interleaving for high-current 41applications. 42 43Fully integrated protection features include over-current 44protection (OCP), over-voltage protection (OVP), under-voltage 45protection (UVP), and over-temperature protection (OTP). 46 47This device is compliant with: 48 49- PMBus rev 1.3 interface. 50 51The driver exports the following attributes via the 'sysfs' files 52for input voltage: 53 54- in1_input 55- in1_label 56- in1_max 57- in1_max_alarm 58- in1_min 59- in1_min_alarm 60- in1_crit 61- in1_crit_alarm 62 63The driver provides the following attributes for output voltage: 64 65- in2_input 66- in2_label 67- in2_alarm 68- in2_max 69- in2_max_alarm 70- in2_min 71- in2_min_alarm 72- in2_crit 73- in2_crit_alarm 74- in2_lcrit 75- in2_lcrit_alarm 76 77The driver provides the following attributes for output current: 78 79- curr1_input 80- curr1_label 81- curr1_max 82- curr1_max_alarm 83- curr1_crit 84- curr1_crit_alarm 85 86The driver provides the following attributes for temperature: 87 88- temp1_input 89- temp1_max 90- temp1_max_alarm 91- temp1_crit 92- temp1_crit_alarm 93 94Alarm acknowledgment 95--------------------- 96 97The hwmon-class ``inX_alarm``/``currX_alarm``/``tempX_alarm`` files are 98read-only in pmbus_core. The driver exposes the standard 99``PMBUS_VIRT_RESET_*_HISTORY`` virtual-register channel for fault 100acknowledgment: writing ``1`` to ``inX_reset_history`` / 101``currX_reset_history`` / ``tempX_reset_history`` sends the chip a 102``CLEAR_FAULTS`` (0x03) Send-Byte, which clears the latched 103``STATUS_WORD`` / ``STATUS_VOUT`` / ``STATUS_IOUT`` / 104``STATUS_INPUT`` / ``STATUS_TEMPERATURE`` bits the chip is currently 105exposing. 106 107The MPS-specific NVM post-mortem register 108``PROTECTION_LAST`` (0xFB) is not cleared by this path; it can be read 109(decoded) via the ``protection_last`` debugfs entry described below. 110 111Regulator framework integration 112------------------------------- 113 114When ``CONFIG_REGULATOR=y`` is set, the chip is 115exposed under ``/sys/class/regulator/`` and accepts the standard 116regulator framework operations: 117 118- ``regulator_enable()`` / ``regulator_disable()`` -> ``OPERATION`` (0x01) 119- ``regulator_set_voltage()`` -> ``VOUT_COMMAND`` (0x21) 120- ``regulator_get_voltage()`` -> ``READ_VOUT`` (0x8B) 121- ``regulator_is_enabled()`` -> ``OPERATION`` bit-decode 122 123The single regulator descriptor is named ``"vout"`` (page 0). For a 124multi-page configuration the descriptor table can be extended in 125the driver. 126 127In-driver alarm-poll fallback 128----------------------------- 129 130On boards where the chip's ``SMBALERT#`` pin is unavailable to the 131SoC, ``pmbus_core::pmbus_irq_setup`` cannot deliver SMBALERT-driven 132``poll(POLLPRI)`` wakes or ``udev change@...`` events on the 133``inX_alarm`` files. The driver provides a ``delayed_work``-based 134polling fallback that 135periodically invokes the pmbus core fault check, 136``pmbus_check_and_notify_faults()``, which sends the notifications and 137then clears the latched faults, exactly like the ``SMBALERT#`` 138interrupt path. The frequency of polling is tunable: 139 140:: 141 142 /sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/alarm_poll_interval_ms 143 144The default is 1000 ms. 145 146Set it to 0 to disable. The worker self-suppresses 147when ``client->irq != 0`` (i.e. when DT supplies an 148``interrupts = <...>`` property on the regulator node), so adding 149``SMBALERT#`` wiring is a zero-driver-change uplift on a future 150board rev. 151 152MPS post-mortem (PROTECTION_LAST) 153--------------------------------- 154 155The MPQ8646 silicon keeps a single 16-bit NVM-backed record of the 156last protection event in ``PROTECTION_LAST`` (0xFB). It survives 157chip power/reset. The following debugfs entries expose it: 158 159:: 160 161 /sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/protection_last (RO) 162 /sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/status_decoded (RO) 163 164``protection_last`` decodes the 16-bit value based on the datasheet 165fault names (``INIT_FAULT``, ``NVM_CRC_ERROR``, ``NVM_FAULT``, 166``OC_PHASE_FAULT``, ``OTP_SELF_FAULT``, ``SWITCH_PRD_FAULT``, 167``VIN_OV_FAULT``, ``VOUT_OV_FAULT``, ``VOUT_UV_FAULT``, 168``OC_TOT_FAULT``, ``VIN_UVLO_FAULT``, ``DRMOS_OTP``). 169 170``status_decoded`` reads ``STATUS_WORD`` (0x79) and renders the 17116 bits with MPS-extension labels (bit12 = ``NVM_SUMMARY``, 172bit8 = ``WATCH_DOG``, bit0 = ``DRMOS_FAULT``) instead of the 173PMBus 1.3 spec generic names. 174 175NVMEM snapshot 176-------------- 177 178When ``CONFIG_NVMEM=y`` is set, the chip's NVM-backed 179observability registers are exposed as a single 16-byte read-only 180``nvmem_device`` at ``/sys/bus/nvmem/devices/<i2c-name>/nvmem``. 181Layout (little-endian for 16-bit fields, zero-fill on per-entry read 182failure and for the reserved tail): 183 184:: 185 186 offset 0..1 PROTECTION_LAST (0xFB) word 187 offset 2..3 MFR_RETRY_TIMES (0xF4) word 188 offset 4..5 MFR_CONFIG_ID (0xC0) word 189 offset 6..7 MFR_VBOOT_CFG (0xFC) word 190 offset 8 MFR_SILICON_REV (0xC3) byte 191 offset 9..15 reserved (zero) 192 193Suitable for single-``cat`` post-mortem capture by a fleet daemon. 194 195Diagnostics and introspection 196----------------------------- 197 198When ``CONFIG_DEBUG_FS=y`` is set, the driver adds a read-only 199decode surface to the client's pmbus debugfs directory, 200``/sys/kernel/debug/i2c/i2c-<bus>/<bus>-<addr>/``. 201The driver intentionally exposes no raw register poke/peek debugfs; 202use i2c-dev (``i2cget``/``i2cset``/``i2ctransfer``) for that. 203 204Identity / observability (read-only): 205 206========================== ================== ================================= 207File PMBus / MFR cmd Description 208========================== ================== ================================= 209``mfr_config_id`` 0xC0 (word) board / SKU NVM identifier 210``mfr_config_code_rev`` 0xC1 (word) NVM image revision (PART_RECOG + 211 config code rev fields) 212``mfr_silicon_rev`` 0xC3 (byte) die revision 213``mfr_retry_times`` 0xF4 (word) per-fault-class recovery-mode 214 configuration (NOT a retry 215 count). Four 4-bit fields 216 [15:12]=OTP, [11:8]=VOUT_OV, 217 [7:4]=VOUT_UV, [3:0]=OCP. 218 Each field: 0x0=latch-off, 219 0x1..0xE=retry N times then 220 latch off, 0xF=hiccup 221 (retry indefinitely). The 222 chip exposes no in-NVM 223 retry-event counter; track 224 transitions externally if 225 needed (poll 226 ``protection_last`` or watch 227 ``inX_alarm`` / ``temp1_alarm`` 228 ``poll(POLLPRI)`` wakes). 229``mfr_vboot_cfg`` 0xFC (word) ADDR/VBOOT latched at POR 230========================== ================== ================================= 231 232Timing / UVLO knobs (read-only): 233 234========================== ================== ================================= 235File PMBus cmd Description 236========================== ================== ================================= 237``vin_on`` 0x35 (word) UVLO turn-on threshold 238``vin_off`` 0x36 (word) UVLO turn-off threshold 239``ton_delay`` 0x60 (word) soft-start delay 240``ton_rise`` 0x61 (word) soft-start ramp time 241``toff_delay`` 0x64 (word) soft-stop delay 242``toff_fall`` 0x65 (word) soft-stop ramp time 243========================== ================== ================================= 244 245The only writable entry is ``alarm_poll_interval_ms`` (the alarm-poll 246worker cadence, see above), it is driver-local and never touches the 247chip. 248 249Unsafe provisioning 250------------------- 251 252Available only when ``CONFIG_SENSORS_MPQ8646_DEBUG_UNSAFE=y`` 253(``default n``, it is for boards bring up only). They WRITE to the regulator. 254On many designs the MPQ8646 powers the main CPU core rail, so a wrong write can 255brown out the board or persist a bad setpoint into finite-cycle NVM. 256WARNING: Some wrong register writes can and likely will physically damage or 257destroy the chip and/or the board. An explicit warning banner is printed at probe 258time when this option is enabled. 259 260=============================== =============== ========================================================= 261File PMBus / MFR cmd Description 262=============================== =============== ========================================================= 263``store_all`` 0x15 STORE_USER_ALL Send-Byte (commit RAM config to NVM) 264``restore_all`` 0x16 RESTORE_USER_ALL Send-Byte (revert RAM to last-NVM image) 265``clear_protection_last`` 0x08 CLEAR_LAST_FAULT Send-Byte 266``clear_protection_last_force`` -- gated CLEAR_LAST_FAULT, see below 267``on_off_config`` 0x02 (byte) PMBus vs CTRL-pin on/off source + active polarity 268``vout_margin_high`` 0x25 (word) margin-high VOUT setpoint 269``vout_margin_low`` 0x26 (word) margin-low VOUT setpoint 270``mfr_pmbus_lock`` 0xEE (word) programmable PMBus write-lock 271``mfr_product_rev_user`` 0xC2 (word) user-programmable product revision 272=============================== =============== ========================================================= 273 274``clear_protection_last`` writes ``CLEAR_LAST_FAULT`` (0x08) Send-Byte. 275The chip silently no-ops unless ``MFR_CFG_EXT`` (0xF5) bit[6] is set. 276 277``clear_protection_last_force`` performs the unlock with the following 278six-step dancing: 279 2801. read ``WRITE_PROTECT`` (0x10) and ``MFR_CFG_EXT`` (0xF5) for restore 2812. clear ``WRITE_PROTECT`` if set 2823. set ``MFR_CFG_EXT`` bit[6] = 1, preserving other bits 2834. send ``CLEAR_LAST_FAULT`` (0x08) 2845. restore ``MFR_CFG_EXT`` (with retry to handle the chip's 285 undocumented post-NVM-write busy window) 2866. restore ``WRITE_PROTECT`` 287 288Devicetree 289---------- 290 291The driver uses ``compatible = "mps,mpq8646"``. There are some few optional 292properties: 293 294- ``mps,vout-fb-divider-ratio-permille`` : it writes ``VOUT_SCALE_LOOP`` 295 (0x29) at probe to compensate for an external resistor divider in 296 the VOUT feedback path. The valid range is 11-bit. 297- ``interrupts = <...>`` : if the board routes the chip's 298 ``SMBALERT#`` pin to a SoC GPIO, declaring it here lights up 299 ``pmbus_core::pmbus_irq_setup`` and disables the in-driver 300 alarm-poll fallback 301