linux/sound/soc/codecs/hdac_hdmi.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 *  hdac_hdmi.c - ASoc HDA-HDMI codec driver for Intel platforms
 *
 *  Copyright (C) 2014-2015 Intel Corp
 *  Author: Samreen Nilofer <[email protected]>
 *	    Subhransu S. Prusty <[email protected]>
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/hdmi.h>
#include <drm/drm_edid.h>
#include <drm/drm_eld.h>
#include <sound/pcm_params.h>
#include <sound/jack.h>
#include <sound/soc.h>
#include <sound/hdaudio_ext.h>
#include <sound/hda_i915.h>
#include <sound/pcm_drm_eld.h>
#include <sound/hda_chmap.h>
#include "../../hda/local.h"
#include "hdac_hdmi.h"

#define NAME_SIZE

#define AMP_OUT_MUTE
#define AMP_OUT_UNMUTE
#define PIN_OUT

#define HDA_MAX_CONNECTIONS

#define HDA_MAX_CVTS
#define HDA_MAX_PORTS

#define ELD_MAX_SIZE
#define ELD_FIXED_BYTES

#define ELD_VER_CEA_861D
#define ELD_VER_PARTIAL
#define ELD_MAX_MNL

struct hdac_hdmi_cvt_params {};

struct hdac_hdmi_cvt {};

/* Currently only spk_alloc, more to be added */
struct hdac_hdmi_parsed_eld {};

struct hdac_hdmi_eld {};

struct hdac_hdmi_pin {};

struct hdac_hdmi_port {};

struct hdac_hdmi_pcm {};

struct hdac_hdmi_dai_port_map {};

struct hdac_hdmi_drv_data {};

struct hdac_hdmi_priv {};

#define hdev_to_hdmi_priv(_hdev)

static struct hdac_hdmi_pcm *
hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,
			   struct hdac_hdmi_cvt *cvt)
{}

static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
		struct hdac_hdmi_port *port, bool is_connect)
{}

static void hdac_hdmi_port_dapm_update(struct hdac_hdmi_port *port)
{}

static void hdac_hdmi_jack_dapm_work(struct work_struct *work)
{}

static void hdac_hdmi_jack_report_sync(struct hdac_hdmi_pcm *pcm,
		struct hdac_hdmi_port *port, bool is_connect)
{}

/* MST supported verbs */
/*
 * Get the no devices that can be connected to a port on the Pin widget.
 */
static int hdac_hdmi_get_port_len(struct hdac_device *hdev, hda_nid_t nid)
{}

/*
 * Get the port entry select on the pin. Return the port entry
 * id selected on the pin. Return 0 means the first port entry
 * is selected or MST is not supported.
 */
static int hdac_hdmi_port_select_get(struct hdac_device *hdev,
					struct hdac_hdmi_port *port)
{}

/*
 * Sets the selected port entry for the configuring Pin widget verb.
 * returns error if port set is not equal to port get otherwise success
 */
static int hdac_hdmi_port_select_set(struct hdac_device *hdev,
					struct hdac_hdmi_port *port)
{}

static struct hdac_hdmi_pcm *get_hdmi_pcm_from_id(struct hdac_hdmi_priv *hdmi,
						int pcm_idx)
{}

static unsigned int sad_format(const u8 *sad)
{}

static unsigned int sad_sample_bits_lpcm(const u8 *sad)
{}

static int hdac_hdmi_eld_limit_formats(struct snd_pcm_runtime *runtime,
						void *eld)
{}

static void
hdac_hdmi_set_dip_index(struct hdac_device *hdev, hda_nid_t pin_nid,
				int packet_index, int byte_index)
{}

struct dp_audio_infoframe {};

static int hdac_hdmi_setup_audio_infoframe(struct hdac_device *hdev,
		   struct hdac_hdmi_pcm *pcm, struct hdac_hdmi_port *port)
{}

static int hdac_hdmi_set_stream(struct snd_soc_dai *dai,
				void *stream, int direction)
{}

static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)
{}

static int hdac_hdmi_query_port_connlist(struct hdac_device *hdev,
					struct hdac_hdmi_pin *pin,
					struct hdac_hdmi_port *port)
{}

/*
 * Query pcm list and return port to which stream is routed.
 *
 * Also query connection list of the pin, to validate the cvt to port map.
 *
 * Same stream rendering to multiple ports simultaneously can be done
 * possibly, but not supported for now in driver. So return the first port
 * connected.
 */
static struct hdac_hdmi_port *hdac_hdmi_get_port_from_cvt(
			struct hdac_device *hdev,
			struct hdac_hdmi_priv *hdmi,
			struct hdac_hdmi_cvt *cvt)
{}

/*
 * Go through all converters and ensure connection is set to
 * the correct pin as set via kcontrols.
 */
static void hdac_hdmi_verify_connect_sel_all_pins(struct hdac_device *hdev)
{}

/*
 * This tries to get a valid pin and set the HW constraints based on the
 * ELD. Even if a valid pin is not found return success so that device open
 * doesn't fail.
 */
static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
			struct snd_soc_dai *dai)
{}

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

static int
hdac_hdmi_query_cvt_params(struct hdac_device *hdev, struct hdac_hdmi_cvt *cvt)
{}

static int hdac_hdmi_fill_widget_info(struct device *dev,
		struct snd_soc_dapm_widget *w, enum snd_soc_dapm_type id,
		void *priv, const char *wname, const char *stream,
		struct snd_kcontrol_new *wc, int numkc,
		int (*event)(struct snd_soc_dapm_widget *,
		struct snd_kcontrol *, int), unsigned short event_flags)
{}

static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
		const char *sink, const char *control, const char *src,
		int (*handler)(struct snd_soc_dapm_widget *src,
			struct snd_soc_dapm_widget *sink))
{}

static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_device *hdev,
					struct hdac_hdmi_port *port)
{}

static void hdac_hdmi_set_power_state(struct hdac_device *hdev,
			     hda_nid_t nid, unsigned int pwr_state)
{}

static void hdac_hdmi_set_amp(struct hdac_device *hdev,
				   hda_nid_t nid, int val)
{}


static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w,
					struct snd_kcontrol *kc, int event)
{}

static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w,
					struct snd_kcontrol *kc, int event)
{}

static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w,
					struct snd_kcontrol *kc, int event)
{}

/*
 * Based on user selection, map the PINs with the PCMs.
 */
static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{}

/*
 * Ideally the Mux inputs should be based on the num_muxs enumerated, but
 * the display driver seem to be programming the connection list for the pin
 * widget runtime.
 *
 * So programming all the possible inputs for the mux, the user has to take
 * care of selecting the right one and leaving all other inputs selected to
 * "NONE"
 */
static int hdac_hdmi_create_pin_port_muxs(struct hdac_device *hdev,
				struct hdac_hdmi_port *port,
				struct snd_soc_dapm_widget *widget,
				const char *widget_name)
{}

/* Add cvt <- input <- mux route map */
static void hdac_hdmi_add_pinmux_cvt_route(struct hdac_device *hdev,
			struct snd_soc_dapm_widget *widgets,
			struct snd_soc_dapm_route *route, int rindex)
{}

/*
 * Widgets are added in the below sequence
 *	Converter widgets for num converters enumerated
 *	Pin-port widgets for num ports for Pins enumerated
 *	Pin-port mux widgets to represent connenction list of pin widget
 *
 * For each port, one Mux and One output widget is added
 * Total widgets elements = num_cvt + (num_ports * 2);
 *
 * Routes are added as below:
 *	pin-port mux -> pin (based on num_ports)
 *	cvt -> "Input sel control" -> pin-port_mux
 *
 * Total route elements:
 *	num_ports + (pin_muxes * num_cvt)
 */
static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm)
{}

static int hdac_hdmi_init_dai_map(struct hdac_device *hdev)
{}

static int hdac_hdmi_add_cvt(struct hdac_device *hdev, hda_nid_t nid)
{}

static int hdac_hdmi_parse_eld(struct hdac_device *hdev,
			struct hdac_hdmi_port *port)
{}

static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
				    struct hdac_hdmi_port *port)
{}

static int hdac_hdmi_add_ports(struct hdac_device *hdev,
			       struct hdac_hdmi_pin *pin)
{}

static int hdac_hdmi_add_pin(struct hdac_device *hdev, hda_nid_t nid)
{}

#define INTEL_VENDOR_NID
#define INTEL_GLK_VENDOR_NID
#define INTEL_GET_VENDOR_VERB
#define INTEL_SET_VENDOR_VERB
#define INTEL_EN_DP12
#define INTEL_EN_ALL_PIN_CVTS

static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdev)
{}

static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdev)
{}

static int hdac_hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
			     struct snd_ctl_elem_info *uinfo)
{}

static int hdac_hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
			    struct snd_ctl_elem_value *ucontrol)
{}

static int hdac_hdmi_create_eld_ctl(struct snd_soc_component *component, struct hdac_hdmi_pcm *pcm)
{}

static const struct snd_soc_dai_ops hdmi_dai_ops =;

/*
 * Each converter can support a stream independently. So a dai is created
 * based on the number of converter queried.
 */
static int hdac_hdmi_create_dais(struct hdac_device *hdev,
		struct snd_soc_dai_driver **dais,
		struct hdac_hdmi_priv *hdmi, int num_dais)
{}

/*
 * Parse all nodes and store the cvt/pin nids in array
 * Add one time initialization for pin and cvt widgets
 */
static int hdac_hdmi_parse_and_map_nid(struct hdac_device *hdev,
		struct snd_soc_dai_driver **dais, int *num_dais)
{}

static int hdac_hdmi_pin2port(void *aptr, int pin)
{}

static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
{}

static struct drm_audio_component_audio_ops aops =;

static struct snd_pcm *hdac_hdmi_get_pcm_from_id(struct snd_soc_card *card,
						int device)
{}

/* create jack pin kcontrols */
static int create_fill_jack_kcontrols(struct snd_soc_card *card,
				    struct hdac_device *hdev)
{}

int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
			struct snd_soc_dapm_context *dapm)
{}
EXPORT_SYMBOL_GPL();

int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
				struct snd_soc_jack *jack)
{}
EXPORT_SYMBOL_GPL();

static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
{}

static int hdmi_codec_probe(struct snd_soc_component *component)
{}

static void hdmi_codec_remove(struct snd_soc_component *component)
{}

#ifdef CONFIG_PM_SLEEP
static int hdmi_codec_resume(struct device *dev)
{}
#else
#define hdmi_codec_resume
#endif

static const struct snd_soc_component_driver hdmi_hda_codec =;

static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx,
					unsigned char *chmap)
{}

static void hdac_hdmi_set_chmap(struct hdac_device *hdev, int pcm_idx,
				unsigned char *chmap, int prepared)
{}

static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdev, int pcm_idx)
{}

static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdev, int pcm_idx)
{}

static struct hdac_hdmi_drv_data intel_glk_drv_data  =;

static struct hdac_hdmi_drv_data intel_drv_data  =;

static int hdac_hdmi_dev_probe(struct hdac_device *hdev)
{}

static void clear_dapm_works(struct hdac_device *hdev)
{}

static int hdac_hdmi_dev_remove(struct hdac_device *hdev)
{}

#ifdef CONFIG_PM
static int hdac_hdmi_runtime_suspend(struct device *dev)
{}

static int hdac_hdmi_runtime_resume(struct device *dev)
{}
#else
#define hdac_hdmi_runtime_suspend
#define hdac_hdmi_runtime_resume
#endif

static const struct dev_pm_ops hdac_hdmi_pm =;

static const struct hda_device_id hdmi_list[] =;

MODULE_DEVICE_TABLE(hdaudio, hdmi_list);

static struct hdac_driver hdmi_driver =;

static int __init hdmi_init(void)
{}

static void __exit hdmi_exit(void)
{}

module_init();
module_exit(hdmi_exit);

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