8ec836621d565e3f2838987409388ef4e55f2089
[oweals/openwrt.git] /
1 From 95709d5c58c57f31a70e96fe9ebb8d34c046f877 Mon Sep 17 00:00:00 2001
2 From: James Hughes <james.hughes@raspberrypi.org>
3 Date: Tue, 24 Sep 2019 18:26:55 +0100
4 Subject: [PATCH] Rename HDMI ALSA device names, check for enable state
5
6 HDMI Alsa devices renamed to match names used by DRM, to
7 HDMI 1 and HDMI 2
8
9 Check for which HDMI devices are connected and only create
10 devices for those that are present.
11
12 The rename of the devices might cause some backwards compatibility
13 issues, but since this particular part of the driver needs to be
14 specifically enabled, I suspect the number of people who will see
15 the problem will be very small.
16
17 Signed-off-by: James Hughes <james.hughes@raspberrypi.org>
18 ---
19  .../vc04_services/bcm2835-audio/bcm2835.c     | 70 +++++++++++++++++--
20  1 file changed, 63 insertions(+), 7 deletions(-)
21
22 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
23 +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835.c
24 @@ -9,8 +9,9 @@
25  #include <linux/of.h>
26  
27  #include "bcm2835.h"
28 +#include <soc/bcm2835/raspberrypi-firmware.h>
29  
30 -static bool enable_hdmi;
31 +static bool enable_hdmi, enable_hdmi0, enable_hdmi1;
32  static bool enable_headphones;
33  static bool enable_compat_alsa = true;
34  
35 @@ -115,8 +116,8 @@ static struct bcm2835_audio_driver bcm28
36                 .name = "bcm2835_hdmi",
37                 .owner = THIS_MODULE,
38         },
39 -       .shortname = "bcm2835 HDMI",
40 -       .longname  = "bcm2835 HDMI",
41 +       .shortname = "bcm2835 HDMI 1",
42 +       .longname  = "bcm2835 HDMI 1",
43         .minchannels = 1,
44         .newpcm = bcm2835_audio_simple_newpcm,
45         .newctl = snd_bcm2835_new_hdmi_ctl,
46 @@ -128,8 +129,8 @@ static struct bcm2835_audio_driver bcm28
47                 .name = "bcm2835_hdmi",
48                 .owner = THIS_MODULE,
49         },
50 -       .shortname = "bcm2835 HDMI 1",
51 -       .longname  = "bcm2835 HDMI 1",
52 +       .shortname = "bcm2835 HDMI 2",
53 +       .longname  = "bcm2835 HDMI 2",
54         .minchannels = 1,
55         .newpcm = bcm2835_audio_simple_newpcm,
56         .newctl = snd_bcm2835_new_hdmi_ctl,
57 @@ -161,11 +162,11 @@ static struct bcm2835_audio_drivers chil
58         },
59         {
60                 .audio_driver = &bcm2835_audio_hdmi0,
61 -               .is_enabled = &enable_hdmi,
62 +               .is_enabled = &enable_hdmi0,
63         },
64         {
65                 .audio_driver = &bcm2835_audio_hdmi1,
66 -               .is_enabled = &enable_hdmi,
67 +               .is_enabled = &enable_hdmi1,
68         },
69         {
70                 .audio_driver = &bcm2835_audio_headphones,
71 @@ -312,6 +313,53 @@ static int snd_add_child_devices(struct
72         return 0;
73  }
74  
75 +static void set_hdmi_enables(struct device *dev)
76 +{
77 +       struct device_node *firmware_node;
78 +       struct rpi_firmware *firmware;
79 +       u32 num_displays, i, display_id;
80 +       int ret;
81 +
82 +       firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0);
83 +       firmware = rpi_firmware_get(firmware_node);
84 +
85 +       if (!firmware)
86 +               return;
87 +
88 +       of_node_put(firmware_node);
89 +
90 +       ret = rpi_firmware_property(firmware,
91 +                                   RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS,
92 +                                   &num_displays, sizeof(u32));
93 +
94 +       if (ret)
95 +               return;
96 +
97 +       for (i = 0; i < num_displays; i++) {
98 +               display_id = i;
99 +               ret = rpi_firmware_property(firmware,
100 +                               RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID,
101 +                               &display_id, sizeof(display_id));
102 +               if (!ret) {
103 +                       if (display_id == 2)
104 +                               enable_hdmi0 = true;
105 +                       if (display_id == 7)
106 +                               enable_hdmi1 = true;
107 +               }
108 +       }
109 +
110 +       if (!enable_hdmi0 && enable_hdmi1) {
111 +               /* Swap them over and reassign route. This means
112 +                * that if we only have one connected, it is always named
113 +                *  HDMI1, irrespective of if its on port HDMI0 or HDMI1.
114 +                *  This should match with the naming of HDMI ports in DRM
115 +                */
116 +               enable_hdmi0 = true;
117 +               enable_hdmi1 = false;
118 +               bcm2835_audio_hdmi0.route = AUDIO_DEST_HDMI1;
119 +       }
120 +}
121 +
122  static int snd_bcm2835_alsa_probe(struct platform_device *pdev)
123  {
124         struct device *dev = &pdev->dev;
125 @@ -332,6 +380,14 @@ static int snd_bcm2835_alsa_probe(struct
126                          numchans);
127         }
128  
129 +       if (!enable_compat_alsa) {
130 +               set_hdmi_enables(dev);
131 +               // In this mode, always enable analog output
132 +               enable_headphones = true;
133 +       } else {
134 +               enable_hdmi0 = enable_hdmi;
135 +       }
136 +
137         err = bcm2835_devm_add_vchi_ctx(dev);
138         if (err)
139                 return err;