0132-bcm2835-only-allow-stereo-if-analogue-jack-is-select.patch 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. From 1a2d7c95e3ee81f352345ecf1f65944739c7cf53 Mon Sep 17 00:00:00 2001
  2. From: wm4 <wm4@nowhere>
  3. Date: Wed, 13 Jan 2016 19:44:24 +0100
  4. Subject: [PATCH 132/381] bcm2835: only allow stereo if analogue jack is
  5. selected
  6. Sending more than 2 channels to videocore while outputting to analogue
  7. mysteriously outputs heavy artifacts. So just paint it over with a
  8. hack: if analogue is explicitly selected as destination, do not
  9. reporting support for anything other than stereo.
  10. I'm not sure how to deal with the auto case (destination 0). There's
  11. probably way to retrieve this and even to listen to plug events, but
  12. I didn't find one yet, and it's probably not worth the trouble. Just
  13. don't use this setting, I guess. Unless you like noise.
  14. Changing the setting while an audio stream is active also doesn't
  15. work properly. We could probably interrupt running streams by
  16. returning ENODEV or using kernel hotplug stuff (maybe), but that
  17. also doesn't seem worth the trouble.
  18. ---
  19. sound/arm/bcm2835-ctl.c | 12 ++++++++++++
  20. 1 file changed, 12 insertions(+)
  21. --- a/sound/arm/bcm2835-ctl.c
  22. +++ b/sound/arm/bcm2835-ctl.c
  23. @@ -423,9 +423,16 @@ static struct cea_channel_speaker_alloca
  24. { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
  25. };
  26. +static int uses_analogue(bcm2835_chip_t *chip)
  27. +{
  28. + return chip->dest == 1;
  29. +}
  30. +
  31. static int snd_bcm2835_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
  32. unsigned int size, unsigned int __user *tlv)
  33. {
  34. + struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
  35. + bcm2835_chip_t *chip = info->private_data;
  36. unsigned int __user *dst;
  37. int count = 0;
  38. int i;
  39. @@ -442,6 +449,9 @@ static int snd_bcm2835_chmap_ctl_tlv(str
  40. int chs_bytes;
  41. int c;
  42. + if (i > 0 && uses_analogue(chip))
  43. + break;
  44. +
  45. for (c = 0; c < 8; c++) {
  46. if (ch->speakers[c])
  47. num_chs++;
  48. @@ -552,6 +562,8 @@ static int snd_bcm2835_chmap_ctl_put(str
  49. int matches = 1;
  50. int cur = 0;
  51. int x;
  52. + if (i > 0 && uses_analogue(chip))
  53. + break;
  54. memset(remap, 0, sizeof(remap));
  55. for (x = 0; x < substream->runtime->channels; x++) {
  56. int sp = ucontrol->value.integer.value[x];