summaryrefslogtreecommitdiff
path: root/sound/pci/hda/hda_tegra.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_tegra.c')
-rw-r--r--sound/pci/hda/hda_tegra.c55
1 files changed, 47 insertions, 8 deletions
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index a590d431c5ff..6ab338f37db5 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -72,6 +72,10 @@
struct hda_tegra_soc {
bool has_hda2codec_2x_reset;
bool has_hda2hdmi;
+ bool has_hda2codec_2x;
+ bool input_stream;
+ bool always_on;
+ bool requires_init;
};
struct hda_tegra {
@@ -187,7 +191,9 @@ static int hda_tegra_runtime_resume(struct device *dev)
if (rc != 0)
return rc;
if (chip->running) {
- hda_tegra_init(hda);
+ if (hda->soc->requires_init)
+ hda_tegra_init(hda);
+
azx_init_chip(chip, 1);
/* disable controller wake up event*/
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
@@ -250,7 +256,8 @@ static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev)
bus->remap_addr = hda->regs + HDA_BAR0;
bus->addr = res->start + HDA_BAR0;
- hda_tegra_init(hda);
+ if (hda->soc->requires_init)
+ hda_tegra_init(hda);
return 0;
}
@@ -323,7 +330,7 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
* starts with offset 0 which is wrong as HW register for output stream
* offset starts with 4.
*/
- if (of_device_is_compatible(np, "nvidia,tegra234-hda"))
+ if (!hda->soc->input_stream)
chip->capture_streams = 4;
chip->playback_streams = (gcap >> 12) & 0x0f;
@@ -377,14 +384,14 @@ static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
}
/* driver name */
- strscpy(card->driver, drv_name, sizeof(card->driver));
+ strscpy(card->driver, drv_name);
/* shortname for card */
sname = of_get_property(np, "nvidia,model", NULL);
if (!sname)
sname = drv_name;
if (strlen(sname) > sizeof(card->shortname))
dev_info(card->dev, "truncating shortname for card\n");
- strscpy(card->shortname, sname, sizeof(card->shortname));
+ strscpy(card->shortname, sname);
/* longname for card */
snprintf(card->longname, sizeof(card->longname),
@@ -419,7 +426,6 @@ static int hda_tegra_create(struct snd_card *card,
chip->driver_caps = driver_caps;
chip->driver_type = driver_caps & 0xff;
chip->dev_index = 0;
- chip->jackpoll_interval = msecs_to_jiffies(5000);
INIT_LIST_HEAD(&chip->pcm_list);
chip->codec_probe_mask = -1;
@@ -436,7 +442,16 @@ static int hda_tegra_create(struct snd_card *card,
chip->bus.core.sync_write = 0;
chip->bus.core.needs_damn_long_delay = 1;
chip->bus.core.aligned_mmio = 1;
- chip->bus.jackpoll_in_suspend = 1;
+
+ /*
+ * HDA power domain and clocks are always on for Tegra264 and
+ * the jack detection logic would work always, so no need of
+ * jack polling mechanism running.
+ */
+ if (!hda->soc->always_on) {
+ chip->jackpoll_interval = msecs_to_jiffies(5000);
+ chip->bus.jackpoll_in_suspend = 1;
+ }
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
@@ -450,22 +465,44 @@ static int hda_tegra_create(struct snd_card *card,
static const struct hda_tegra_soc tegra30_data = {
.has_hda2codec_2x_reset = true,
.has_hda2hdmi = true,
+ .has_hda2codec_2x = true,
+ .input_stream = true,
+ .always_on = false,
+ .requires_init = true,
};
static const struct hda_tegra_soc tegra194_data = {
.has_hda2codec_2x_reset = false,
.has_hda2hdmi = true,
+ .has_hda2codec_2x = true,
+ .input_stream = true,
+ .always_on = false,
+ .requires_init = true,
};
static const struct hda_tegra_soc tegra234_data = {
.has_hda2codec_2x_reset = true,
.has_hda2hdmi = false,
+ .has_hda2codec_2x = true,
+ .input_stream = false,
+ .always_on = false,
+ .requires_init = true,
+};
+
+static const struct hda_tegra_soc tegra264_data = {
+ .has_hda2codec_2x_reset = true,
+ .has_hda2hdmi = false,
+ .has_hda2codec_2x = false,
+ .input_stream = false,
+ .always_on = true,
+ .requires_init = false,
};
static const struct of_device_id hda_tegra_match[] = {
{ .compatible = "nvidia,tegra30-hda", .data = &tegra30_data },
{ .compatible = "nvidia,tegra194-hda", .data = &tegra194_data },
{ .compatible = "nvidia,tegra234-hda", .data = &tegra234_data },
+ { .compatible = "nvidia,tegra264-hda", .data = &tegra264_data },
{},
};
MODULE_DEVICE_TABLE(of, hda_tegra_match);
@@ -520,7 +557,9 @@ static int hda_tegra_probe(struct platform_device *pdev)
hda->clocks[hda->nclocks++].id = "hda";
if (hda->soc->has_hda2hdmi)
hda->clocks[hda->nclocks++].id = "hda2hdmi";
- hda->clocks[hda->nclocks++].id = "hda2codec_2x";
+
+ if (hda->soc->has_hda2codec_2x)
+ hda->clocks[hda->nclocks++].id = "hda2codec_2x";
err = devm_clk_bulk_get(&pdev->dev, hda->nclocks, hda->clocks);
if (err < 0)