Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * omap-hdmi-audio.c -- OMAP4+ DSS HDMI audio support library
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author: Jyri Sarha <jsarha@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <sound/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <sound/dmaengine_pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <uapi/sound/asound.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <sound/omap-hdmi-audio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "sdma-pcm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define DRV_NAME "omap-hdmi-audio"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) struct hdmi_audio_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct snd_soc_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	const struct omap_hdmi_audio_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	struct device *dssdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct snd_dmaengine_dai_dma_data dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct omap_dss_audio dss_audio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct snd_aes_iec958 iec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct snd_cea_861_aud_if cea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	struct mutex current_stream_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	struct snd_pcm_substream *current_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) struct hdmi_audio_data *card_drvdata_substream(struct snd_pcm_substream *ss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	struct snd_soc_pcm_runtime *rtd = ss->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	return snd_soc_card_get_drvdata(rtd->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static void hdmi_dai_abort(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	struct hdmi_audio_data *ad = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	mutex_lock(&ad->current_stream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	if (ad->current_stream && ad->current_stream->runtime &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	    snd_pcm_running(ad->current_stream)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		dev_err(dev, "HDMI display disabled, aborting playback\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		snd_pcm_stream_lock_irq(ad->current_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		snd_pcm_stop(ad->current_stream, SNDRV_PCM_STATE_DISCONNECTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		snd_pcm_stream_unlock_irq(ad->current_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	mutex_unlock(&ad->current_stream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) static int hdmi_dai_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 			    struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	struct hdmi_audio_data *ad = card_drvdata_substream(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	 * Make sure that the period bytes are multiple of the DMA packet size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 * Largest packet size we use is 32 32-bit words = 128 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		dev_err(dai->dev, "Could not apply period constraint: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 			ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 					 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		dev_err(dai->dev, "Could not apply buffer constraint: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 			ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	snd_soc_dai_set_dma_data(dai, substream, &ad->dma_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	mutex_lock(&ad->current_stream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	ad->current_stream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	mutex_unlock(&ad->current_stream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	ret = ad->ops->audio_startup(ad->dssdev, hdmi_dai_abort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		mutex_lock(&ad->current_stream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		ad->current_stream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		mutex_unlock(&ad->current_stream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int hdmi_dai_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			      struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			      struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	struct hdmi_audio_data *ad = card_drvdata_substream(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	struct snd_aes_iec958 *iec = &ad->iec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	struct snd_cea_861_aud_if *cea = &ad->cea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	WARN_ON(ad->current_stream != substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	switch (params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		ad->dma_data.maxburst = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	case SNDRV_PCM_FORMAT_S24_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		ad->dma_data.maxburst = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		dev_err(dai->dev, "format not supported!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	ad->dss_audio.iec = iec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	ad->dss_audio.cea = cea;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	 * fill the IEC-60958 channel status word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/* initialize the word bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	memset(iec->status, 0, sizeof(iec->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	/* specify IEC-60958-3 (commercial use) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	iec->status[0] &= ~IEC958_AES0_PROFESSIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	/* specify that the audio is LPCM*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	iec->status[0] &= ~IEC958_AES0_NONAUDIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	iec->status[0] |= IEC958_AES0_CON_NOT_COPYRIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	iec->status[0] |= IEC958_AES0_CON_EMPHASIS_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	iec->status[1] = IEC958_AES1_CON_GENERAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	iec->status[2] |= IEC958_AES2_CON_SOURCE_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	iec->status[2] |= IEC958_AES2_CON_CHANNEL_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	switch (params_rate(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	case 32000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		iec->status[3] |= IEC958_AES3_CON_FS_32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	case 44100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		iec->status[3] |= IEC958_AES3_CON_FS_44100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	case 48000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		iec->status[3] |= IEC958_AES3_CON_FS_48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	case 88200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		iec->status[3] |= IEC958_AES3_CON_FS_88200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	case 96000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		iec->status[3] |= IEC958_AES3_CON_FS_96000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	case 176400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		iec->status[3] |= IEC958_AES3_CON_FS_176400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	case 192000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		iec->status[3] |= IEC958_AES3_CON_FS_192000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		dev_err(dai->dev, "rate not supported!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	/* specify the clock accuracy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	iec->status[3] |= IEC958_AES3_CON_CLOCK_1000PPM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	 * specify the word length. The same word length value can mean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	 * two different lengths. Hence, we need to specify the maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	 * word length as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	switch (params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	case SNDRV_PCM_FORMAT_S16_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		iec->status[4] |= IEC958_AES4_CON_WORDLEN_20_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		iec->status[4] &= ~IEC958_AES4_CON_MAX_WORDLEN_24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	case SNDRV_PCM_FORMAT_S24_LE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		iec->status[4] |= IEC958_AES4_CON_WORDLEN_24_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		iec->status[4] |= IEC958_AES4_CON_MAX_WORDLEN_24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		dev_err(dai->dev, "format not supported!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	 * Fill the CEA-861 audio infoframe (see spec for details)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	cea->db1_ct_cc = (params_channels(params) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		& CEA861_AUDIO_INFOFRAME_DB1CC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	cea->db1_ct_cc |= CEA861_AUDIO_INFOFRAME_DB1CT_FROM_STREAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	cea->db2_sf_ss = CEA861_AUDIO_INFOFRAME_DB2SF_FROM_STREAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	cea->db2_sf_ss |= CEA861_AUDIO_INFOFRAME_DB2SS_FROM_STREAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	cea->db3 = 0; /* not used, all zeros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (params_channels(params) == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		cea->db4_ca = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	else if (params_channels(params) == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		cea->db4_ca = 0xb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		cea->db4_ca = 0x13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (cea->db4_ca == 0x00)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		cea->db5_dminh_lsv = CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PERMITTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		cea->db5_dminh_lsv = CEA861_AUDIO_INFOFRAME_DB5_DM_INH_PROHIBITED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	/* the expression is trivial but makes clear what we are doing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	cea->db5_dminh_lsv |= (0 & CEA861_AUDIO_INFOFRAME_DB5_LSV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	return ad->ops->audio_config(ad->dssdev, &ad->dss_audio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static int hdmi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			    struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	struct hdmi_audio_data *ad = card_drvdata_substream(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	WARN_ON(ad->current_stream != substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		err = ad->ops->audio_start(ad->dssdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		ad->ops->audio_stop(ad->dssdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static void hdmi_dai_shutdown(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 			      struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	struct hdmi_audio_data *ad = card_drvdata_substream(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	WARN_ON(ad->current_stream != substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	ad->ops->audio_shutdown(ad->dssdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	mutex_lock(&ad->current_stream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	ad->current_stream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	mutex_unlock(&ad->current_stream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static const struct snd_soc_dai_ops hdmi_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	.startup	= hdmi_dai_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	.hw_params	= hdmi_dai_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	.trigger	= hdmi_dai_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	.shutdown	= hdmi_dai_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static const struct snd_soc_component_driver omap_hdmi_component = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	.name = "omapdss_hdmi",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static struct snd_soc_dai_driver omap5_hdmi_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	.name = "omap5-hdmi-dai",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	.playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		.channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		.channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		.rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			  SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 			  SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			  SNDRV_PCM_RATE_192000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	.ops = &hdmi_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static struct snd_soc_dai_driver omap4_hdmi_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	.name = "omap4-hdmi-dai",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	.playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		.channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		.channels_max = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		.rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			  SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			  SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 			  SNDRV_PCM_RATE_192000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	.ops = &hdmi_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static int omap_hdmi_audio_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	struct omap_hdmi_audio_pdata *ha = pdev->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	struct hdmi_audio_data *ad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	struct snd_soc_dai_driver *dai_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	struct snd_soc_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	struct snd_soc_dai_link_component *compnent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	if (!ha) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		dev_err(dev, "No platform data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	ad = devm_kzalloc(dev, sizeof(*ad), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (!ad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	ad->dssdev = ha->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	ad->ops = ha->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	ad->dma_data.addr = ha->audio_dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	ad->dma_data.filter_data = "audio_tx";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	ad->dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	mutex_init(&ad->current_stream_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	switch (ha->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		dai_drv = &omap4_hdmi_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		dai_drv = &omap5_hdmi_dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	ret = devm_snd_soc_register_component(ad->dssdev, &omap_hdmi_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 					 dai_drv, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	ret = sdma_pcm_platform_register(ad->dssdev, "audio_tx", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	if (!card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	card->name = devm_kasprintf(dev, GFP_KERNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 				    "HDMI %s", dev_name(ad->dssdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (!card->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	card->owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	card->dai_link =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		devm_kzalloc(dev, sizeof(*(card->dai_link)), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	if (!card->dai_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	compnent = devm_kzalloc(dev, 3 * sizeof(*compnent), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (!compnent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	card->dai_link->cpus		= &compnent[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	card->dai_link->num_cpus	= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	card->dai_link->codecs		= &compnent[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	card->dai_link->num_codecs	= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	card->dai_link->platforms	= &compnent[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	card->dai_link->num_platforms	= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	card->dai_link->name = card->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	card->dai_link->stream_name = card->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	card->dai_link->cpus->dai_name = dev_name(ad->dssdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	card->dai_link->platforms->name = dev_name(ad->dssdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	card->dai_link->codecs->name = "snd-soc-dummy";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	card->dai_link->codecs->dai_name = "snd-soc-dummy-dai";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	card->num_links = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	card->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	ret = snd_soc_register_card(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		dev_err(dev, "snd_soc_register_card failed (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	ad->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	snd_soc_card_set_drvdata(card, ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	dev_set_drvdata(dev, ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int omap_hdmi_audio_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	struct hdmi_audio_data *ad = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	snd_soc_unregister_card(ad->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static struct platform_driver hdmi_audio_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		.name = DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	.probe = omap_hdmi_audio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	.remove = omap_hdmi_audio_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) module_platform_driver(hdmi_audio_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) MODULE_DESCRIPTION("OMAP HDMI Audio Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) MODULE_ALIAS("platform:" DRV_NAME);