diff options
| -rw-r--r-- | sound/pci/hda/hda_eld.c | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 7ae7578bdcc0..c1da422e085a 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
| @@ -347,18 +347,28 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
| 347 | 347 | ||
| 348 | for (i = 0; i < size; i++) { | 348 | for (i = 0; i < size; i++) { |
| 349 | unsigned int val = hdmi_get_eld_data(codec, nid, i); | 349 | unsigned int val = hdmi_get_eld_data(codec, nid, i); |
| 350 | /* | ||
| 351 | * Graphics driver might be writing to ELD buffer right now. | ||
| 352 | * Just abort. The caller will repoll after a while. | ||
| 353 | */ | ||
| 350 | if (!(val & AC_ELDD_ELD_VALID)) { | 354 | if (!(val & AC_ELDD_ELD_VALID)) { |
| 351 | if (!i) { | ||
| 352 | snd_printd(KERN_INFO | ||
| 353 | "HDMI: invalid ELD data\n"); | ||
| 354 | ret = -EINVAL; | ||
| 355 | goto error; | ||
| 356 | } | ||
| 357 | snd_printd(KERN_INFO | 355 | snd_printd(KERN_INFO |
| 358 | "HDMI: invalid ELD data byte %d\n", i); | 356 | "HDMI: invalid ELD data byte %d\n", i); |
| 359 | val = 0; | 357 | ret = -EINVAL; |
| 360 | } else | 358 | goto error; |
| 361 | val &= AC_ELDD_ELD_DATA; | 359 | } |
| 360 | val &= AC_ELDD_ELD_DATA; | ||
| 361 | /* | ||
| 362 | * The first byte cannot be zero. This can happen on some DVI | ||
| 363 | * connections. Some Intel chips may also need some 250ms delay | ||
| 364 | * to return non-zero ELD data, even when the graphics driver | ||
| 365 | * correctly writes ELD content before setting ELD_valid bit. | ||
| 366 | */ | ||
| 367 | if (!val && !i) { | ||
| 368 | snd_printdd(KERN_INFO "HDMI: 0 ELD data\n"); | ||
| 369 | ret = -EINVAL; | ||
| 370 | goto error; | ||
| 371 | } | ||
| 362 | buf[i] = val; | 372 | buf[i] = val; |
| 363 | } | 373 | } |
| 364 | 374 | ||
