|
@@ -1669,22 +1669,52 @@ static int had_iec958_put(struct snd_kcontrol *kcontrol,
|
|
|
return changed;
|
|
|
}
|
|
|
|
|
|
-static struct snd_kcontrol_new had_control_iec958_mask = {
|
|
|
- .access = SNDRV_CTL_ELEM_ACCESS_READ,
|
|
|
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
|
|
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
|
|
|
- .info = had_iec958_info, /* shared */
|
|
|
- .get = had_iec958_mask_get,
|
|
|
-};
|
|
|
+static int had_ctl_eld_info(struct snd_kcontrol *kcontrol,
|
|
|
+ struct snd_ctl_elem_info *uinfo)
|
|
|
+{
|
|
|
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
|
|
|
+ uinfo->count = HDMI_MAX_ELD_BYTES;
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
-static struct snd_kcontrol_new had_control_iec958 = {
|
|
|
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
|
|
- .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
|
|
|
- .info = had_iec958_info,
|
|
|
- .get = had_iec958_get,
|
|
|
- .put = had_iec958_put
|
|
|
+static int had_ctl_eld_get(struct snd_kcontrol *kcontrol,
|
|
|
+ struct snd_ctl_elem_value *ucontrol)
|
|
|
+{
|
|
|
+ struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol);
|
|
|
+
|
|
|
+ mutex_lock(&intelhaddata->mutex);
|
|
|
+ memcpy(ucontrol->value.bytes.data, intelhaddata->eld,
|
|
|
+ HDMI_MAX_ELD_BYTES);
|
|
|
+ mutex_unlock(&intelhaddata->mutex);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct snd_kcontrol_new had_controls[] = {
|
|
|
+ {
|
|
|
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
|
|
|
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
|
|
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
|
|
|
+ .info = had_iec958_info, /* shared */
|
|
|
+ .get = had_iec958_mask_get,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
|
|
+ .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
|
|
|
+ .info = had_iec958_info,
|
|
|
+ .get = had_iec958_get,
|
|
|
+ .put = had_iec958_put,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ .access = (SNDRV_CTL_ELEM_ACCESS_READ |
|
|
|
+ SNDRV_CTL_ELEM_ACCESS_VOLATILE),
|
|
|
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
|
|
+ .name = "ELD",
|
|
|
+ .info = had_ctl_eld_info,
|
|
|
+ .get = had_ctl_eld_get,
|
|
|
+ },
|
|
|
};
|
|
|
|
|
|
+
|
|
|
static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id)
|
|
|
{
|
|
|
struct snd_intelhad *ctx = dev_id;
|
|
@@ -1724,6 +1754,7 @@ static void had_audio_wq(struct work_struct *work)
|
|
|
if (!pdata->hdmi_connected) {
|
|
|
dev_dbg(ctx->dev, "%s: Event: HAD_NOTIFY_HOT_UNPLUG\n",
|
|
|
__func__);
|
|
|
+ memset(ctx->eld, 0, sizeof(ctx->eld)); /* clear the old ELD */
|
|
|
had_process_hot_unplug(ctx);
|
|
|
} else {
|
|
|
struct intel_hdmi_lpe_audio_eld *eld = &pdata->eld;
|
|
@@ -1826,7 +1857,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
|
|
|
struct intel_hdmi_lpe_audio_pdata *pdata;
|
|
|
int irq;
|
|
|
struct resource *res_mmio;
|
|
|
- int ret;
|
|
|
+ int i, ret;
|
|
|
|
|
|
dev_dbg(&pdev->dev, "dma_mask: %p\n", pdev->dev.dma_mask);
|
|
|
|
|
@@ -1918,13 +1949,12 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev)
|
|
|
SNDRV_DMA_TYPE_DEV, NULL,
|
|
|
HAD_MAX_BUFFER, HAD_MAX_BUFFER);
|
|
|
|
|
|
- /* IEC958 controls */
|
|
|
- ret = snd_ctl_add(card, snd_ctl_new1(&had_control_iec958_mask, ctx));
|
|
|
- if (ret < 0)
|
|
|
- goto err;
|
|
|
- ret = snd_ctl_add(card, snd_ctl_new1(&had_control_iec958, ctx));
|
|
|
- if (ret < 0)
|
|
|
- goto err;
|
|
|
+ /* create controls */
|
|
|
+ for (i = 0; i < ARRAY_SIZE(had_controls); i++) {
|
|
|
+ ret = snd_ctl_add(card, snd_ctl_new1(&had_controls[i], ctx));
|
|
|
+ if (ret < 0)
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
|
|
|
init_channel_allocations();
|
|
|
|