linux/sound/soc/sof/intel/hda-mlink.c

// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license.  When using or
// redistributing this file, you may do so under either license.
//
// Copyright(c) 2022 Intel Corporation
//

/*
 * Management of HDaudio multi-link (capabilities, power, coupling)
 */

#include <sound/hdaudio_ext.h>
#include <sound/hda_register.h>
#include <sound/hda-mlink.h>

#include <linux/bitfield.h>
#include <linux/module.h>

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_MLINK)

/* worst-case number of sublinks is used for sublink refcount array allocation only */
#define HDAML_MAX_SUBLINKS

/**
 * struct hdac_ext2_link - HDAudio extended+alternate link
 *
 * @hext_link:		hdac_ext_link
 * @alt:		flag set for alternate extended links
 * @intc:		boolean for interrupt capable
 * @ofls:		boolean for offload support
 * @lss:		boolean for link synchronization capabilities
 * @slcount:		sublink count
 * @elid:		extended link ID (AZX_REG_ML_LEPTR_ID_ defines)
 * @elver:		extended link version
 * @leptr:		extended link pointer
 * @eml_lock:		mutual exclusion to access shared registers e.g. CPA/SPA bits
 * in LCTL register
 * @sublink_ref_count:	array of refcounts, required to power-manage sublinks independently
 * @base_ptr:		pointer to shim/ip/shim_vs space
 * @instance_offset:	offset between each of @slcount instances managed by link
 * @shim_offset:	offset to SHIM register base
 * @ip_offset:		offset to IP register base
 * @shim_vs_offset:	offset to vendor-specific (VS) SHIM base
 */
struct hdac_ext2_link {};

#define hdac_ext_link_to_ext2(h)

#define AZX_REG_SDW_INSTANCE_OFFSET
#define AZX_REG_SDW_SHIM_OFFSET
#define AZX_REG_SDW_IP_OFFSET
#define AZX_REG_SDW_VS_SHIM_OFFSET
#define AZX_REG_SDW_SHIM_PCMSyCM(y)

/* only one instance supported */
#define AZX_REG_INTEL_DMIC_SHIM_OFFSET
#define AZX_REG_INTEL_DMIC_IP_OFFSET
#define AZX_REG_INTEL_DMIC_VS_SHIM_OFFSET

#define AZX_REG_INTEL_SSP_INSTANCE_OFFSET
#define AZX_REG_INTEL_SSP_SHIM_OFFSET
#define AZX_REG_INTEL_SSP_IP_OFFSET
#define AZX_REG_INTEL_SSP_VS_SHIM_OFFSET

/* only one instance supported */
#define AZX_REG_INTEL_UAOL_SHIM_OFFSET
#define AZX_REG_INTEL_UAOL_IP_OFFSET
#define AZX_REG_INTEL_UAOL_VS_SHIM_OFFSET

/* HDAML section - this part follows sequences in the hardware specification,
 * including naming conventions and the use of the hdaml_ prefix.
 * The code is intentionally minimal with limited dependencies on frameworks or
 * helpers. Locking and scanning lists is handled at a higher level
 */

static int hdaml_lnk_enum(struct device *dev, struct hdac_ext2_link *h2link,
			  void __iomem *remap_addr, void __iomem *ml_addr, int link_idx)
{}

/*
 * Hardware recommendations are to wait ~10us before checking any hardware transition
 * reported by bits changing status.
 * This value does not need to be super-precise, a slack of 5us is perfectly acceptable.
 * The worst-case is about 1ms before reporting an issue
 */
#define HDAML_POLL_DELAY_MIN_US
#define HDAML_POLL_DELAY_SLACK_US
#define HDAML_POLL_DELAY_RETRY

static int check_sublink_power(u32 __iomem *lctl, int sublink, bool enabled)
{}

static int hdaml_link_init(u32 __iomem *lctl, int sublink)
{}

static int hdaml_link_shutdown(u32 __iomem *lctl, int sublink)
{}

static void hdaml_link_enable_interrupt(u32 __iomem *lctl, bool enable)
{}

static bool hdaml_link_check_interrupt(u32 __iomem *lctl)
{}

static int hdaml_wait_bit(void __iomem *base, int offset, u32 mask, u32 target)
{}

static void hdaml_link_set_syncprd(u32 __iomem *lsync, u32 syncprd)
{}

static int hdaml_link_wait_syncpu(u32 __iomem *lsync)
{}

static void hdaml_link_sync_arm(u32 __iomem *lsync, int sublink)
{}

static void hdaml_link_sync_go(u32 __iomem *lsync)
{}

static bool hdaml_link_check_cmdsync(u32 __iomem *lsync, u32 cmdsync_mask)
{}

static u16 hdaml_link_get_lsdiid(u16 __iomem *lsdiid)
{}

static void hdaml_link_set_lsdiid(u16 __iomem *lsdiid, int dev_num)
{}

static void hdaml_shim_map_stream_ch(u16 __iomem *pcmsycm, int lchan, int hchan,
				     int stream_id, int dir)
{}

static void hdaml_lctl_offload_enable(u32 __iomem *lctl, bool enable)
{}

/* END HDAML section */

static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index)
{}

int hda_bus_ml_init(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

void hda_bus_ml_free(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

static struct hdac_ext2_link *
find_ext2_link(struct hdac_bus *bus, bool alt, int elid)
{}

int hdac_bus_eml_get_count(struct hdac_bus *bus, bool alt, int elid)
{}
EXPORT_SYMBOL_NS();

void hdac_bus_eml_enable_interrupt(struct hdac_bus *bus, bool alt, int elid, bool enable)
{}
EXPORT_SYMBOL_NS();

bool hdac_bus_eml_check_interrupt(struct hdac_bus *bus, bool alt, int elid)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_set_syncprd_unlocked(struct hdac_bus *bus, bool alt, int elid, u32 syncprd)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_sdw_set_syncprd_unlocked(struct hdac_bus *bus, u32 syncprd)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_wait_syncpu_unlocked(struct hdac_bus *bus, bool alt, int elid)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_sdw_wait_syncpu_unlocked(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

void hdac_bus_eml_sync_arm_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
{}
EXPORT_SYMBOL_NS();

void hdac_bus_eml_sdw_sync_arm_unlocked(struct hdac_bus *bus, int sublink)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_sync_go_unlocked(struct hdac_bus *bus, bool alt, int elid)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_sdw_sync_go_unlocked(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

bool hdac_bus_eml_check_cmdsync_unlocked(struct hdac_bus *bus, bool alt, int elid)
{}
EXPORT_SYMBOL_NS();

bool hdac_bus_eml_sdw_check_cmdsync_unlocked(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

static int hdac_bus_eml_power_up_base(struct hdac_bus *bus, bool alt, int elid, int sublink,
				      bool eml_lock)
{}

int hdac_bus_eml_power_up(struct hdac_bus *bus, bool alt, int elid, int sublink)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_power_up_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
{}
EXPORT_SYMBOL_NS();

static int hdac_bus_eml_power_down_base(struct hdac_bus *bus, bool alt, int elid, int sublink,
					bool eml_lock)
{}

int hdac_bus_eml_power_down(struct hdac_bus *bus, bool alt, int elid, int sublink)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_power_down_unlocked(struct hdac_bus *bus, bool alt, int elid, int sublink)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_sdw_power_up_unlocked(struct hdac_bus *bus, int sublink)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_sdw_get_lsdiid_unlocked(struct hdac_bus *bus, int sublink, u16 *lsdiid)
{} EXPORT_SYMBOL_NS();

int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num)
{} EXPORT_SYMBOL_NS();

/*
 * the 'y' parameter comes from the PCMSyCM hardware register naming. 'y' refers to the
 * PDI index, i.e. the FIFO used for RX or TX
 */
int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
				   int channel_mask, int stream_id, int dir)
{} EXPORT_SYMBOL_NS();

void hda_bus_ml_put_all(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

void hda_bus_ml_reset_losidv(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

int hda_bus_ml_resume(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

int hda_bus_ml_suspend(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

struct mutex *hdac_bus_eml_get_mutex(struct hdac_bus *bus, bool alt, int elid)
{}
EXPORT_SYMBOL_NS();

struct hdac_ext_link *hdac_bus_eml_ssp_get_hlink(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

struct hdac_ext_link *hdac_bus_eml_dmic_get_hlink(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

struct hdac_ext_link *hdac_bus_eml_sdw_get_hlink(struct hdac_bus *bus)
{}
EXPORT_SYMBOL_NS();

int hdac_bus_eml_enable_offload(struct hdac_bus *bus, bool alt, int elid, bool enable)
{}
EXPORT_SYMBOL_NS();

#endif

MODULE_LICENSE();
MODULE_DESCRIPTION();