1*4882a593Smuzhiyun /* SPDX-License-Identifier: BSD-3-Clause 2*4882a593Smuzhiyun * Copyright (c) 2016-2018, NXP Semiconductors 3*4882a593Smuzhiyun * Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com> 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun #ifndef _LINUX_PACKING_H 6*4882a593Smuzhiyun #define _LINUX_PACKING_H 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include <linux/types.h> 9*4882a593Smuzhiyun #include <linux/bitops.h> 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #define QUIRK_MSB_ON_THE_RIGHT BIT(0) 12*4882a593Smuzhiyun #define QUIRK_LITTLE_ENDIAN BIT(1) 13*4882a593Smuzhiyun #define QUIRK_LSW32_IS_FIRST BIT(2) 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun enum packing_op { 16*4882a593Smuzhiyun PACK, 17*4882a593Smuzhiyun UNPACK, 18*4882a593Smuzhiyun }; 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun /** 21*4882a593Smuzhiyun * packing - Convert numbers (currently u64) between a packed and an unpacked 22*4882a593Smuzhiyun * format. Unpacked means laid out in memory in the CPU's native 23*4882a593Smuzhiyun * understanding of integers, while packed means anything else that 24*4882a593Smuzhiyun * requires translation. 25*4882a593Smuzhiyun * 26*4882a593Smuzhiyun * @pbuf: Pointer to a buffer holding the packed value. 27*4882a593Smuzhiyun * @uval: Pointer to an u64 holding the unpacked value. 28*4882a593Smuzhiyun * @startbit: The index (in logical notation, compensated for quirks) where 29*4882a593Smuzhiyun * the packed value starts within pbuf. Must be larger than, or 30*4882a593Smuzhiyun * equal to, endbit. 31*4882a593Smuzhiyun * @endbit: The index (in logical notation, compensated for quirks) where 32*4882a593Smuzhiyun * the packed value ends within pbuf. Must be smaller than, or equal 33*4882a593Smuzhiyun * to, startbit. 34*4882a593Smuzhiyun * @op: If PACK, then uval will be treated as const pointer and copied (packed) 35*4882a593Smuzhiyun * into pbuf, between startbit and endbit. 36*4882a593Smuzhiyun * If UNPACK, then pbuf will be treated as const pointer and the logical 37*4882a593Smuzhiyun * value between startbit and endbit will be copied (unpacked) to uval. 38*4882a593Smuzhiyun * @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and 39*4882a593Smuzhiyun * QUIRK_MSB_ON_THE_RIGHT. 40*4882a593Smuzhiyun * 41*4882a593Smuzhiyun * Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming 42*4882a593Smuzhiyun * correct usage, return code may be discarded. 43*4882a593Smuzhiyun * If op is PACK, pbuf is modified. 44*4882a593Smuzhiyun * If op is UNPACK, uval is modified. 45*4882a593Smuzhiyun */ 46*4882a593Smuzhiyun int packing(void *pbuf, u64 *uval, int startbit, int endbit, size_t pbuflen, 47*4882a593Smuzhiyun enum packing_op op, u8 quirks); 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun #endif 50