mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 18:09:56 +00:00
Add HDMI1 facility to the driver.
Also check for which HDMI devices are connected and only create devices for those that are present. Signed-off-by: James Hughes <james.hughes@raspberrypi.org> Signed-off-by: Dom Cobley <popcornmix@gmail.com>
This commit is contained in:
@@ -321,10 +321,11 @@ static const struct snd_pcm_ops snd_bcm2835_playback_spdif_ops = {
|
|||||||
|
|
||||||
/* create a pcm device */
|
/* create a pcm device */
|
||||||
int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name,
|
int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name,
|
||||||
int idx, enum snd_bcm2835_route route,
|
enum snd_bcm2835_route route,
|
||||||
u32 numchannels, bool spdif)
|
u32 numchannels, bool spdif)
|
||||||
{
|
{
|
||||||
struct snd_pcm *pcm;
|
struct snd_pcm *pcm;
|
||||||
|
int idx = chip->index++;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = snd_pcm_new(chip->card, name, idx, numchannels, 0, &pcm);
|
err = snd_pcm_new(chip->card, name, idx, numchannels, 0, &pcm);
|
||||||
|
|||||||
@@ -8,8 +8,9 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include "bcm2835.h"
|
#include "bcm2835.h"
|
||||||
|
#include <soc/bcm2835/raspberrypi-firmware.h>
|
||||||
|
|
||||||
static bool enable_hdmi;
|
static bool enable_hdmi, enable_hdmi0, enable_hdmi1;
|
||||||
static bool enable_headphones = true;
|
static bool enable_headphones = true;
|
||||||
static int num_channels = MAX_SUBSTREAMS;
|
static int num_channels = MAX_SUBSTREAMS;
|
||||||
|
|
||||||
@@ -65,14 +66,13 @@ static int bcm2835_audio_dual_newpcm(struct bcm2835_chip *chip,
|
|||||||
u32 numchannels)
|
u32 numchannels)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
err = snd_bcm2835_new_pcm(chip, name, route,
|
||||||
err = snd_bcm2835_new_pcm(chip, name, 0, route,
|
|
||||||
numchannels, false);
|
numchannels, false);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = snd_bcm2835_new_pcm(chip, "IEC958", 1, route, 1, true);
|
err = snd_bcm2835_new_pcm(chip, name, route, 1, true);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
@@ -84,20 +84,33 @@ static int bcm2835_audio_simple_newpcm(struct bcm2835_chip *chip,
|
|||||||
enum snd_bcm2835_route route,
|
enum snd_bcm2835_route route,
|
||||||
u32 numchannels)
|
u32 numchannels)
|
||||||
{
|
{
|
||||||
return snd_bcm2835_new_pcm(chip, name, 0, route, numchannels, false);
|
return snd_bcm2835_new_pcm(chip, name, route, numchannels, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct bcm2835_audio_driver bcm2835_audio_hdmi = {
|
static struct bcm2835_audio_driver bcm2835_audio_hdmi0 = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "bcm2835_hdmi",
|
.name = "bcm2835_hdmi",
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
},
|
},
|
||||||
.shortname = "bcm2835 HDMI",
|
.shortname = "bcm2835 HDMI 1",
|
||||||
.longname = "bcm2835 HDMI",
|
.longname = "bcm2835 HDMI 1",
|
||||||
.minchannels = 1,
|
.minchannels = 1,
|
||||||
.newpcm = bcm2835_audio_dual_newpcm,
|
.newpcm = bcm2835_audio_dual_newpcm,
|
||||||
.newctl = snd_bcm2835_new_hdmi_ctl,
|
.newctl = snd_bcm2835_new_hdmi_ctl,
|
||||||
.route = AUDIO_DEST_HDMI
|
.route = AUDIO_DEST_HDMI0
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bcm2835_audio_driver bcm2835_audio_hdmi1 = {
|
||||||
|
.driver = {
|
||||||
|
.name = "bcm2835_hdmi",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
.shortname = "bcm2835 HDMI 2",
|
||||||
|
.longname = "bcm2835 HDMI 2",
|
||||||
|
.minchannels = 1,
|
||||||
|
.newpcm = bcm2835_audio_dual_newpcm,
|
||||||
|
.newctl = snd_bcm2835_new_hdmi_ctl,
|
||||||
|
.route = AUDIO_DEST_HDMI1
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct bcm2835_audio_driver bcm2835_audio_headphones = {
|
static struct bcm2835_audio_driver bcm2835_audio_headphones = {
|
||||||
@@ -120,8 +133,12 @@ struct bcm2835_audio_drivers {
|
|||||||
|
|
||||||
static struct bcm2835_audio_drivers children_devices[] = {
|
static struct bcm2835_audio_drivers children_devices[] = {
|
||||||
{
|
{
|
||||||
.audio_driver = &bcm2835_audio_hdmi,
|
.audio_driver = &bcm2835_audio_hdmi0,
|
||||||
.is_enabled = &enable_hdmi,
|
.is_enabled = &enable_hdmi0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.audio_driver = &bcm2835_audio_hdmi1,
|
||||||
|
.is_enabled = &enable_hdmi1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.audio_driver = &bcm2835_audio_headphones,
|
.audio_driver = &bcm2835_audio_headphones,
|
||||||
@@ -268,6 +285,53 @@ static int snd_add_child_devices(struct device *device, u32 numchans)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_hdmi_enables(struct device *dev)
|
||||||
|
{
|
||||||
|
struct device_node *firmware_node;
|
||||||
|
struct rpi_firmware *firmware;
|
||||||
|
u32 num_displays, i, display_id;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
firmware_node = of_parse_phandle(dev->of_node, "brcm,firmware", 0);
|
||||||
|
firmware = rpi_firmware_get(firmware_node);
|
||||||
|
|
||||||
|
if (!firmware)
|
||||||
|
return;
|
||||||
|
|
||||||
|
of_node_put(firmware_node);
|
||||||
|
|
||||||
|
ret = rpi_firmware_property(firmware,
|
||||||
|
RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS,
|
||||||
|
&num_displays, sizeof(u32));
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < num_displays; i++) {
|
||||||
|
display_id = i;
|
||||||
|
ret = rpi_firmware_property(firmware,
|
||||||
|
RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID,
|
||||||
|
&display_id, sizeof(display_id));
|
||||||
|
if (!ret) {
|
||||||
|
if (display_id == 2)
|
||||||
|
enable_hdmi0 = true;
|
||||||
|
if (display_id == 7)
|
||||||
|
enable_hdmi1 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enable_hdmi0 && enable_hdmi1) {
|
||||||
|
/* Swap them over and reassign route. This means
|
||||||
|
* that if we only have one connected, it is always named
|
||||||
|
* HDMI1, irrespective of if its on port HDMI0 or HDMI1.
|
||||||
|
* This should match with the naming of HDMI ports in DRM
|
||||||
|
*/
|
||||||
|
enable_hdmi0 = true;
|
||||||
|
enable_hdmi1 = false;
|
||||||
|
bcm2835_audio_hdmi0.route = AUDIO_DEST_HDMI1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int snd_bcm2835_alsa_probe(struct platform_device *pdev)
|
static int snd_bcm2835_alsa_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
@@ -279,6 +343,8 @@ static int snd_bcm2835_alsa_probe(struct platform_device *pdev)
|
|||||||
num_channels);
|
num_channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set_hdmi_enables(dev);
|
||||||
|
|
||||||
err = bcm2835_devm_add_vchi_ctx(dev);
|
err = bcm2835_devm_add_vchi_ctx(dev);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ enum {
|
|||||||
enum snd_bcm2835_route {
|
enum snd_bcm2835_route {
|
||||||
AUDIO_DEST_AUTO = 0,
|
AUDIO_DEST_AUTO = 0,
|
||||||
AUDIO_DEST_HEADPHONES = 1,
|
AUDIO_DEST_HEADPHONES = 1,
|
||||||
AUDIO_DEST_HDMI = 2,
|
AUDIO_DEST_HDMI0 = 2,
|
||||||
|
AUDIO_DEST_HDMI1 = 3,
|
||||||
AUDIO_DEST_MAX,
|
AUDIO_DEST_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ struct bcm2835_chip {
|
|||||||
int volume;
|
int volume;
|
||||||
int dest;
|
int dest;
|
||||||
int mute;
|
int mute;
|
||||||
|
int index;
|
||||||
|
|
||||||
unsigned int opened;
|
unsigned int opened;
|
||||||
unsigned int spdif_status;
|
unsigned int spdif_status;
|
||||||
@@ -85,7 +87,7 @@ struct bcm2835_alsa_stream {
|
|||||||
|
|
||||||
int snd_bcm2835_new_ctl(struct bcm2835_chip *chip);
|
int snd_bcm2835_new_ctl(struct bcm2835_chip *chip);
|
||||||
int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name,
|
int snd_bcm2835_new_pcm(struct bcm2835_chip *chip, const char *name,
|
||||||
int idx, enum snd_bcm2835_route route,
|
enum snd_bcm2835_route route,
|
||||||
u32 numchannels, bool spdif);
|
u32 numchannels, bool spdif);
|
||||||
|
|
||||||
int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip);
|
int snd_bcm2835_new_hdmi_ctl(struct bcm2835_chip *chip);
|
||||||
|
|||||||
Reference in New Issue
Block a user