xref: /kernel/linux/linux-5.10/lib/crc4.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * crc4.c - simple crc-4 calculations.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/crc4.h>
78c2ecf20Sopenharmony_ci#include <linux/module.h>
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_cistatic const uint8_t crc4_tab[] = {
108c2ecf20Sopenharmony_ci	0x0, 0x7, 0xe, 0x9, 0xb, 0xc, 0x5, 0x2,
118c2ecf20Sopenharmony_ci	0x1, 0x6, 0xf, 0x8, 0xa, 0xd, 0x4, 0x3,
128c2ecf20Sopenharmony_ci};
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci/**
158c2ecf20Sopenharmony_ci * crc4 - calculate the 4-bit crc of a value.
168c2ecf20Sopenharmony_ci * @c:    starting crc4
178c2ecf20Sopenharmony_ci * @x:    value to checksum
188c2ecf20Sopenharmony_ci * @bits: number of bits in @x to checksum
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci * Returns the crc4 value of @x, using polynomial 0b10111.
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci * The @x value is treated as left-aligned, and bits above @bits are ignored
238c2ecf20Sopenharmony_ci * in the crc calculations.
248c2ecf20Sopenharmony_ci */
258c2ecf20Sopenharmony_ciuint8_t crc4(uint8_t c, uint64_t x, int bits)
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci	int i;
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	/* mask off anything above the top bit */
308c2ecf20Sopenharmony_ci	x &= (1ull << bits) - 1;
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	/* Align to 4-bits */
338c2ecf20Sopenharmony_ci	bits = (bits + 3) & ~0x3;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	/* Calculate crc4 over four-bit nibbles, starting at the MSbit */
368c2ecf20Sopenharmony_ci	for (i = bits - 4; i >= 0; i -= 4)
378c2ecf20Sopenharmony_ci		c = crc4_tab[c ^ ((x >> i) & 0xf)];
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	return c;
408c2ecf20Sopenharmony_ci}
418c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(crc4);
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("CRC4 calculations");
448c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
45