+
     via  c                   s    R t ^ RIt^ RIHtHtHt ^ RIHt ] ! R R]4      4       t] ! R R]4      4       t	RR lt
R	 tR
 tR# )aB  Constants and methods for interfacing with PMBus compliant devices.

Specifications:

- Power Systems Management Protocol Specification.  Revision 1.3.1, 2015.
  Available uppon request, check the PMBus website.

- Power Systems Management Protocol Specification.  Revision 1.2, 2010.
  Available on the PMBus website.
  http://pmbus.org/Assets/PDFS/Public/PMBus_Specification_Part_I_Rev_1-2_20100906.pdf
  http://pmbus.org/Assets/PDFS/Public/PMBus_Specification_Part_II_Rev_1-2_20100906.pdf

- System Management Bus (SMBus) Specification.  Version 3.1, 2018.
  Available on the SMBus website.
  http://smbus.org/specs/SMBus_3_1_20180319.pdf

Additional references:

- Milios, John.  CRC-8 firmware implementations for SMBus.  1999.
 http://sbs-forum.org/marcom/dc2/20_crc-8_firmware_implementations.pdf

- Pircher, Thomas.  pycrc -- parameterisable CRC calculation utility and C
  source code generator: CRC algorithms implemented in Python.
  https://github.com/tpircher/pycrc/blob/master/pycrc/algorithms.py

- White, Robert V.  Using the PMBus Protocol.  2005.
  http://pmbus.org/Assets/Present/Using_The_PMBus_20051012.pdf

Copyright Jonas Malaco and contributors

Includes a CRC-8 implementation adapted from pycrc by Thomas Pircher.
Copyright (c) 2006-2017  Thomas Pircher  <tehpeh-web@tty1.net>

SPDX-License-Identifier: GPL-3.0-or-later
N)IntEnumIntFlaguniquemkCrcFunc                   s    ] tR t^+t^ t^tRtR# )WriteBit N)__name__
__module____qualname____firstlineno__ZWRITEZREAD__static_attributes__r       4/usr/lib/python3.14/site-packages/liquidctl/pmbus.pyr   r   +   s    EDr   r   c                   s    ] tR t^1tRt^ t^t^t^t^ t	^:t
^;t^<t^=t^>t^?t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t^t ^t!^t"^t#^t$^t%^t&^t'^t(^t)^t*^t+^t,^t-^t.^t/Rt0R# )CommandCodez2Incomplete enumeration of the PMBus command codes.r   N)1r   r   r	   r
   __doc__ZPAGEZCLEAR_FAULTSZPAGE_PLUS_WRITEZPAGE_PLUS_READZ	VOUT_MODEZFAN_CONFIG_1_2ZFAN_COMMAND_1ZFAN_COMMAND_2ZFAN_CONFIG_3_4ZFAN_COMMAND_3ZFAN_COMMAND_4ZREAD_EINZ	READ_EOUTZREAD_VINZREAD_IINZ	READ_VCAPZ	READ_VOUTZ	READ_IOUTZREAD_TEMPERATURE_1ZREAD_TEMPERATURE_2ZREAD_TEMPERATURE_3ZREAD_FAN_SPEED_1ZREAD_FAN_SPEED_2ZREAD_FAN_SPEED_3ZREAD_FAN_SPEED_4ZREAD_DUTY_CYCLEZREAD_FREQUENCYZ	READ_POUTZREAD_PINZREAD_PMBUS_REVISONZMFR_IDZ	MFR_MODELZMFR_REVISIONZMFR_LOCATIONZMFR_DATEZ
MFR_SERIALZMFR_SPECIFIC_D1ZMFR_SPECIFIC_D2ZMFR_SPECIFIC_D8ZMFR_SPECIFIC_DCZMFR_SPECIFIC_EEZMFR_SPECIFIC_F0ZMFR_SPECIFIC_FCr   r   r   r   r   r   1   s    <DLONINMMNMMHIHHIIIONIHFILLHJOOOOOOOr   r   c                s    \         P                  V R,          RR7      pVf$   V^,	          pVR,          pVR8  d
   VR,
          pMV^,          pTpV^8  d
   V^ ,
          pV^V,          ,          # )a  Read PMBus LINEAR11 and ULINEAR16 numeric values.

If `vout_exp` is None the value is interpreted as a 2 byte LINEAR11 value.
The mantissa is stored in the lower 11 bits, in two's-complement, and the
exponent is is stored in the upper 5 bits, also in two's-complement.

Otherwise the value is assumed to be encoded in ULINEAR16, where the
exponent is read from the lower 5 bits of `vout_exp` (which is assumed to
be the output from VOUT_MOE) and the mantissa is the unsigned 2 byte
integer in `bytes`.

Per the SMBus specification, the lowest order byte is sent first (endianess
is little).

>>> linear_to_float(bytes.fromhex('67e3'))
54.4375
>>> linear_to_float(bytes.fromhex('6703'), vout_exp=0x1c)
54.4375
:Ni   Nlittle)	byteorderi       )intZ
from_bytes)bytesZvout_expZtmpZexpZfras   &&   r   linear_to_floatr   h   so    ( ..rh.
7CRiEk:*Co
RxBhC<r   c                sd   V ^ 8X  d   R# Rp\         P                  ! \         P                  ! \         P                  ! V 4      V,          ^4      4      p\	        V ^V) ,          ,          4      pV^ 8  d
   V^ ,           pV^ 8  d
   VR,           p\
        P                  V^,          V,          ^RR7      # )a  Encode float in PMBus LINEAR11 format.

A LINEAR11 number is a 2 byte value with an 11 bit two's complement
mantissa and a 5 bit two's complement exponent.

Per the SMBus specification, the lowest order byte is sent first (endianess
is little).

>>> float_to_linear11(3.3).hex()
'4dc3'
>>> float_to_linear11(0.0).hex()
'0000'
>>> linear_to_float(float_to_linear11(2812))
2812
>>> linear_to_float(float_to_linear11(-2812))
-2812
s     r   r   r   )Zlengthr   )mathZceilZlogZfabsZroundr   Zto_bytes)ZfloatZmax_yZnZys   &   r   float_to_linear11r      s    $ zE		$((499U+E1156Aea1"goA1uF1uH<<bAa8<DDr   c                s$    \        R4      ! V 4      # )u  
Compute a 8-bit Packet Error Code (PEC) for `bytes`.

According to the SMBus specification, the PEC is computed using a 8-bit
cyclic rendundancy check (CRC-8) with the polynominal x⁸ + x² + x¹ + x⁰.

The computation uses a 256-byte lookup table.

Based on https://github.com/tpircher/pycrc/blob/master/pycrc/algorithms.py.

>>> hex(compute_pec(bytes('123456789', 'ascii')))
'0xf4'
>>> hex(compute_pec(bytes.fromhex('5c')))
'0x93'
>>> hex(compute_pec(bytes.fromhex('5c93')))
'0x0'
zcrc-8r   )r   s   &r   compute_pecr      s    & GU##r   )N)r   r   Zenumr    r   r   Zliquidctl.utilr   r   r   r   r   r   r   r   r   <module>r      sa   "H  ) ) # w  
 3' 3 3lDE<$r   