linux/sound/soc/apple/mca.c

// SPDX-License-Identifier: GPL-2.0-only
//
// Apple SoCs MCA driver
//
// Copyright (C) The Asahi Linux Contributors
//
// The MCA peripheral is made up of a number of identical units called clusters.
// Each cluster has its separate clock parent, SYNC signal generator, carries
// four SERDES units and has a dedicated I2S port on the SoC's periphery.
//
// The clusters can operate independently, or can be combined together in a
// configurable manner. We mostly treat them as self-contained independent
// units and don't configure any cross-cluster connections except for the I2S
// ports. The I2S ports can be routed to any of the clusters (irrespective
// of their native cluster). We map this onto ASoC's (DPCM) notion of backend
// and frontend DAIs. The 'cluster guts' are frontends which are dynamically
// routed to backend I2S ports.
//
// DAI references in devicetree are resolved to backends. The routing between
// frontends and backends is determined by the machine driver in the DAPM paths
// it supplies.

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_clk.h>
#include <linux/of_dma.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/dmaengine_pcm.h>

#define USE_RXB_FOR_CAPTURE

/* Relative to cluster base */
#define REG_STATUS
#define STATUS_MCLK_EN
#define REG_MCLK_CONF
#define MCLK_CONF_DIV

#define REG_SYNCGEN_STATUS
#define SYNCGEN_STATUS_EN
#define REG_SYNCGEN_MCLK_SEL
#define SYNCGEN_MCLK_SEL
#define REG_SYNCGEN_HI_PERIOD
#define REG_SYNCGEN_LO_PERIOD

#define REG_PORT_ENABLES
#define PORT_ENABLES_CLOCKS
#define PORT_ENABLES_TX_DATA
#define REG_PORT_CLOCK_SEL
#define PORT_CLOCK_SEL
#define REG_PORT_DATA_SEL
#define PORT_DATA_SEL_TXA(cl)
#define PORT_DATA_SEL_TXB(cl)

#define REG_INTSTATE
#define REG_INTMASK

/* Bases of serdes units (relative to cluster) */
#define CLUSTER_RXA_OFF
#define CLUSTER_TXA_OFF
#define CLUSTER_RXB_OFF
#define CLUSTER_TXB_OFF

#define CLUSTER_TX_OFF

#ifndef USE_RXB_FOR_CAPTURE
#define CLUSTER_RX_OFF
#else
#define CLUSTER_RX_OFF
#endif

/* Relative to serdes unit base */
#define REG_SERDES_STATUS
#define SERDES_STATUS_EN
#define SERDES_STATUS_RST
#define REG_TX_SERDES_CONF
#define REG_RX_SERDES_CONF
#define SERDES_CONF_NCHANS
#define SERDES_CONF_WIDTH_MASK
#define SERDES_CONF_WIDTH_16BIT
#define SERDES_CONF_WIDTH_20BIT
#define SERDES_CONF_WIDTH_24BIT
#define SERDES_CONF_WIDTH_32BIT
#define SERDES_CONF_BCLK_POL
#define SERDES_CONF_LSB_FIRST
#define SERDES_CONF_UNK1
#define SERDES_CONF_UNK2
#define SERDES_CONF_UNK3
#define SERDES_CONF_NO_DATA_FEEDBACK
#define SERDES_CONF_SYNC_SEL
#define REG_TX_SERDES_BITSTART
#define REG_RX_SERDES_BITSTART
#define REG_TX_SERDES_SLOTMASK
#define REG_RX_SERDES_SLOTMASK
#define REG_RX_SERDES_PORT

/* Relative to switch base */
#define REG_DMA_ADAPTER_A(cl)
#define REG_DMA_ADAPTER_B(cl)
#define DMA_ADAPTER_TX_LSB_PAD
#define DMA_ADAPTER_TX_NCHANS
#define DMA_ADAPTER_RX_MSB_PAD
#define DMA_ADAPTER_RX_NCHANS
#define DMA_ADAPTER_NCHANS

#define SWITCH_STRIDE
#define CLUSTER_STRIDE

#define MAX_NCLUSTERS

#define APPLE_MCA_FMTBITS

struct mca_cluster {};

struct mca_data {};

static void mca_modify(struct mca_cluster *cl, int regoffset, u32 mask, u32 val)
{}

/*
 * Get the cluster of FE or BE DAI
 */
static struct mca_cluster *mca_dai_to_cluster(struct snd_soc_dai *dai)
{}

/* called before PCM trigger */
static void mca_fe_early_trigger(struct snd_pcm_substream *substream, int cmd,
				 struct snd_soc_dai *dai)
{}

static int mca_fe_trigger(struct snd_pcm_substream *substream, int cmd,
			  struct snd_soc_dai *dai)
{}

static int mca_fe_enable_clocks(struct mca_cluster *cl)
{}

static void mca_fe_disable_clocks(struct mca_cluster *cl)
{}

static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
{}

static int mca_be_prepare(struct snd_pcm_substream *substream,
			  struct snd_soc_dai *dai)
{}

static int mca_be_hw_free(struct snd_pcm_substream *substream,
			  struct snd_soc_dai *dai)
{}

static unsigned int mca_crop_mask(unsigned int mask, int nchans)
{}

static int mca_configure_serdes(struct mca_cluster *cl, int serdes_unit,
				unsigned int mask, int slots, int nchans,
				int slot_width, bool is_tx, int port)
{}

static int mca_fe_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
			       unsigned int rx_mask, int slots, int slot_width)
{}

static int mca_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{}

static int mca_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
{}

static int mca_fe_get_port(struct snd_pcm_substream *substream)
{}

static int mca_fe_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
{}

static const struct snd_soc_dai_ops mca_fe_ops =;

static bool mca_be_started(struct mca_cluster *cl)
{}

static int mca_be_startup(struct snd_pcm_substream *substream,
			  struct snd_soc_dai *dai)
{}

static void mca_be_shutdown(struct snd_pcm_substream *substream,
			    struct snd_soc_dai *dai)
{}

static const struct snd_soc_dai_ops mca_be_ops =;

static int mca_set_runtime_hwparams(struct snd_soc_component *component,
				    struct snd_pcm_substream *substream,
				    struct dma_chan *chan)
{}

static int mca_pcm_open(struct snd_soc_component *component,
			struct snd_pcm_substream *substream)
{}

static int mca_hw_params(struct snd_soc_component *component,
			 struct snd_pcm_substream *substream,
			 struct snd_pcm_hw_params *params)
{}

static int mca_close(struct snd_soc_component *component,
		     struct snd_pcm_substream *substream)
{}

static int mca_trigger(struct snd_soc_component *component,
		       struct snd_pcm_substream *substream, int cmd)
{}

static snd_pcm_uframes_t mca_pointer(struct snd_soc_component *component,
				     struct snd_pcm_substream *substream)
{}

static struct dma_chan *mca_request_dma_channel(struct mca_cluster *cl, unsigned int stream)
{}

static void mca_pcm_free(struct snd_soc_component *component,
			 struct snd_pcm *pcm)
{}


static int mca_pcm_new(struct snd_soc_component *component,
		       struct snd_soc_pcm_runtime *rtd)
{}

static const struct snd_soc_component_driver mca_component =;

static void apple_mca_release(struct mca_data *mca)
{}

static int apple_mca_probe(struct platform_device *pdev)
{}

static void apple_mca_remove(struct platform_device *pdev)
{}

static const struct of_device_id apple_mca_of_match[] =;
MODULE_DEVICE_TABLE(of, apple_mca_of_match);

static struct platform_driver apple_mca_driver =;
module_platform_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();