/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
 * Copyright (c) 2021 MediaTek Inc.
 */

#ifndef ATSC30_COMMON_UTILS_H
#define ATSC30_COMMON_UTILS_H

#include <linux/types.h>
#include <linux/printk.h>
#include <linux/kernel.h>
#include <linux/string.h>

#include "alp_parser_common.h"

#define SWAP_ENDIAN16(x) \
	((((u16)(x) & 0xff00) >> 8) | (((u16)(x) & 0x00ff) << 8))
#define SWAP_ENDIAN32(x) \
	((((u32)(x) & 0xff000000) >> 24) \
		| (((u32)(x) & 0x00ff0000) >> 8) \
		| (((u32)(x) & 0x0000ff00) << 8) \
		| (((u32)(x) & 0x000000ff) << 24))

#define ATSC30_NULL_PTR_CHECK(ptr) \
	({ \
		bool __ret = (void *)(ptr) == NULL; \
		if (__ret) \
			pr_err("%s, %d Pointer NULL\n", __func__, __LINE__); \
		__ret; \
	})

#define WIDTH_2_BYTES(width) ((width) / 8)
#define BYTES_2_WIDTH(bytes) ((bytes) * 8)

struct u128_t {
	u64 l;
	u64 h;
};

uintptr_t atsc30_utils_ring_addr_inc(
		uintptr_t ptrCurAddr,
		u32 u4IncStep,
		uintptr_t ptrBufStart,
		uintptr_t ptrBufEnd);
uintptr_t atsc30_utils_ring_addr_dec(
		uintptr_t ptrCurAddr,
		u32 u4DecStep,
		uintptr_t ptrBufStart,
		uintptr_t ptrBufEnd);
void atsc30_utils_ring_flush_Dcache_size(
		uintptr_t ptrRingStart,
		uintptr_t ptrRingEnd,
		uintptr_t ptrStartAddr,
		u32 u4Size);
void atsc30_utils_ring_flush_Dcache_addr(
		uintptr_t ptrRingStart,
		uintptr_t ptrRingEnd,
		uintptr_t ptrStartAddr,
		uintptr_t ptrEndAddr);
u32 atsc30_utils_ring_get_data_size(
		uintptr_t ptrRingStart,
		uintptr_t ptrRingEnd,
		uintptr_t ptrStartAddr,
		uintptr_t ptrEndAddr);
void atsc30_utils_ring_copy(
		uintptr_t ptrdst,
		uintptr_t ptrRingStart,
		uintptr_t ptrRingEnd,
		uintptr_t ptrStartAddr,
		uintptr_t ptrEndAddr);

u32 atsc30_utils_Str2Int(
		const char *str,
		u32 *p);

ALP_RET_CODE_T atsc30_utils_mult_64_to_128(
		u64 u_u64,
		u64 v_u64,
		struct u128_t *product);

ALP_RET_CODE_T atsc30_utils_div_128_by_64(
		const u64 u_u128_h,
		const u64 u_u128_l,
		u64 v_u64,
		u64 *q_u64,
		u64 *r_u64);

#endif /* ATSC30_COMMON_UTILS_H */
