linux/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * DesignWare HDMI audio driver
 *
 * Written and tested against the Designware HDMI Tx found in iMX6.
 */
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <drm/bridge/dw_hdmi.h>
#include <drm/drm_edid.h>

#include <sound/asoundef.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_drm_eld.h>
#include <sound/pcm_iec958.h>

#include "dw-hdmi-audio.h"

#define DRIVER_NAME

/* Provide some bits rather than bit offsets */
enum {};

struct dw_hdmi_channel_conf {};

/*
 * The default mapping of ALSA channels to HDMI channels and speaker
 * allocation bits.  Note that we can't do channel remapping here -
 * channels must be in the same order.
 *
 * Mappings for alsa-lib pcm/surround*.conf files:
 *
 *		Front	Sur4.0	Sur4.1	Sur5.0	Sur5.1	Sur7.1
 * Channels	2	4	6	6	6	8
 *
 * Our mapping from ALSA channel to CEA686D speaker name and HDMI channel:
 *
 *				Number of ALSA channels
 * ALSA Channel	2	3	4	5	6	7	8
 * 0		FL:0	=	=	=	=	=	=
 * 1		FR:1	=	=	=	=	=	=
 * 2			FC:3	RL:4	LFE:2	=	=	=
 * 3				RR:5	RL:4	FC:3	=	=
 * 4					RR:5	RL:4	=	=
 * 5						RR:5	=	=
 * 6							RC:6	=
 * 7							RLC/FRC	RLC/FRC
 */
static struct dw_hdmi_channel_conf default_hdmi_channel_config[7] =;

struct snd_dw_hdmi {};

static void dw_hdmi_writel(u32 val, void __iomem *ptr)
{}

/*
 * Convert to hardware format: The userspace buffer contains IEC958 samples,
 * with the PCUV bits in bits 31..28 and audio samples in bits 27..4.  We
 * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio
 * samples in 23..0.
 *
 * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd
 *
 * Ideally, we could do with having the data properly formatted in userspace.
 */
static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw,
	size_t offset, size_t bytes)
{}

static u32 parity(u32 sample)
{}

static void dw_hdmi_reformat_s24(struct snd_dw_hdmi *dw,
	size_t offset, size_t bytes)
{}

static void dw_hdmi_create_cs(struct snd_dw_hdmi *dw,
	struct snd_pcm_runtime *runtime)
{}

static void dw_hdmi_start_dma(struct snd_dw_hdmi *dw)
{}

static void dw_hdmi_stop_dma(struct snd_dw_hdmi *dw)
{}

static irqreturn_t snd_dw_hdmi_irq(int irq, void *data)
{}

static const struct snd_pcm_hardware dw_hdmi_hw =;

static int dw_hdmi_open(struct snd_pcm_substream *substream)
{}

static int dw_hdmi_close(struct snd_pcm_substream *substream)
{}

static int dw_hdmi_hw_free(struct snd_pcm_substream *substream)
{}

static int dw_hdmi_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params)
{}

static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
{}

static int dw_hdmi_trigger(struct snd_pcm_substream *substream, int cmd)
{}

static snd_pcm_uframes_t dw_hdmi_pointer(struct snd_pcm_substream *substream)
{}

static const struct snd_pcm_ops snd_dw_hdmi_ops =;

static int snd_dw_hdmi_probe(struct platform_device *pdev)
{}

static void snd_dw_hdmi_remove(struct platform_device *pdev)
{}

#if defined(CONFIG_PM_SLEEP) && defined(IS_NOT_BROKEN)
/*
 * This code is fine, but requires implementation in the dw_hdmi_trigger()
 * method which is currently missing as I have no way to test this.
 */
static int snd_dw_hdmi_suspend(struct device *dev)
{
	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);

	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold);

	return 0;
}

static int snd_dw_hdmi_resume(struct device *dev)
{
	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);

	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D0);

	return 0;
}

static SIMPLE_DEV_PM_OPS(snd_dw_hdmi_pm, snd_dw_hdmi_suspend,
			 snd_dw_hdmi_resume);
#define PM_OPS
#else
#define PM_OPS
#endif

static struct platform_driver snd_dw_hdmi_driver =;

module_platform_driver();

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