Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.14.15.
  1/* SPDX-License-Identifier: GPL-2.0 */
  2
  3/* Copyright (C) 2022-2024 Linaro Ltd. */
  4
  5#ifndef _REG_H_
  6#define _REG_H_
  7
  8#include <linux/array_size.h>
  9#include <linux/bits.h>
 10#include <linux/bug.h>
 11#include <linux/log2.h>
 12#include <linux/types.h>
 13
 14/**
 15 * struct reg - A register descriptor
 16 * @offset:	Register offset relative to base of register memory
 17 * @stride:	Distance between two instances, if parameterized
 18 * @fcount:	Number of entries in the @fmask array
 19 * @fmask:	Array of mask values defining position and width of fields
 20 * @name:	Upper-case name of the register
 21 */
 22struct reg {
 23	u32 offset;
 24	u32 stride;
 25	u32 fcount;
 26	const u32 *fmask;			/* BIT(nr) or GENMASK(h, l) */
 27	const char *name;
 28};
 29
 30/* Helper macro for defining "simple" (non-parameterized) registers */
 31#define REG(__NAME, __reg_id, __offset)					\
 32	REG_STRIDE(__NAME, __reg_id, __offset, 0)
 33
 34/* Helper macro for defining parameterized registers, specifying stride */
 35#define REG_STRIDE(__NAME, __reg_id, __offset, __stride)		\
 36	static const struct reg reg_ ## __reg_id = {			\
 37		.name	= #__NAME,					\
 38		.offset	= __offset,					\
 39		.stride	= __stride,					\
 40	}
 41
 42#define REG_FIELDS(__NAME, __name, __offset)				\
 43	REG_STRIDE_FIELDS(__NAME, __name, __offset, 0)
 44
 45#define REG_STRIDE_FIELDS(__NAME, __name, __offset, __stride)		\
 46	static const struct reg reg_ ## __name = {			\
 47		.name   = #__NAME,					\
 48		.offset = __offset,					\
 49		.stride = __stride,					\
 50		.fcount = ARRAY_SIZE(reg_ ## __name ## _fmask),		\
 51		.fmask  = reg_ ## __name ## _fmask,			\
 52	}
 53
 54/**
 55 * struct regs - Description of registers supported by hardware
 56 * @reg_count:	Number of registers in the @reg[] array
 57 * @reg:	Array of register descriptors
 58 */
 59struct regs {
 60	u32 reg_count;
 61	const struct reg **reg;
 62};
 63
 64static inline const struct reg *reg(const struct regs *regs, u32 reg_id)
 65{
 66	if (WARN(reg_id >= regs->reg_count,
 67		 "reg out of range (%u > %u)\n", reg_id, regs->reg_count - 1))
 68		return NULL;
 69
 70	return regs->reg[reg_id];
 71}
 72
 73/* Return the field mask for a field in a register, or 0 on error */
 74static inline u32 reg_fmask(const struct reg *reg, u32 field_id)
 75{
 76	if (!reg || WARN_ON(field_id >= reg->fcount))
 77		return 0;
 78
 79	return reg->fmask[field_id];
 80}
 81
 82/* Return the mask for a single-bit field in a register, or 0 on error  */
 83static inline u32 reg_bit(const struct reg *reg, u32 field_id)
 84{
 85	u32 fmask = reg_fmask(reg, field_id);
 86
 87	if (WARN_ON(!is_power_of_2(fmask)))
 88		return 0;
 89
 90	return fmask;
 91}
 92
 93/* Return the maximum value representable by the given field; always 2^n - 1 */
 94static inline u32 reg_field_max(const struct reg *reg, u32 field_id)
 95{
 96	u32 fmask = reg_fmask(reg, field_id);
 97
 98	return fmask ? fmask >> __ffs(fmask) : 0;
 99}
100
101/* Encode a value into the given field of a register */
102static inline u32 reg_encode(const struct reg *reg, u32 field_id, u32 val)
103{
104	u32 fmask = reg_fmask(reg, field_id);
105
106	if (!fmask)
107		return 0;
108
109	val <<= __ffs(fmask);
110	if (WARN_ON(val & ~fmask))
111		return 0;
112
113	return val;
114}
115
116/* Given a register value, decode (extract) the value in the given field */
117static inline u32 reg_decode(const struct reg *reg, u32 field_id, u32 val)
118{
119	u32 fmask = reg_fmask(reg, field_id);
120
121	return fmask ? (val & fmask) >> __ffs(fmask) : 0;
122}
123
124/* Returns 0 for NULL reg; warning should have already been issued */
125static inline u32 reg_offset(const struct reg *reg)
126{
127	return reg ? reg->offset : 0;
128}
129
130/* Returns 0 for NULL reg; warning should have already been issued */
131static inline u32 reg_n_offset(const struct reg *reg, u32 n)
132{
133	return reg ? reg->offset + n * reg->stride : 0;
134}
135
136#endif /* _REG_H_ */