Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions include/sound/hdaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,8 +348,9 @@ struct hdac_bus {
bool corbrp_self_clear:1; /* CORBRP clears itself after reset */
bool polling_mode:1;
bool needs_damn_long_delay:1;
bool not_use_interrupts:1; /* prohibiting the RIRB IRQ */
bool access_sdnctl_in_dword:1; /* accessing the sdnctl register by dword */
bool not_use_interrupts:1; /* prohibiting the RIRB IRQ */
bool access_sdnctl_in_dword:1; /* accessing the sdnctl register by dword */
bool cmd_resend; /* command resend */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

是否使用:1

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以不这样,因为在azx_first_init会赋值成1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以不这样,因为在azx_first_init会赋值成1

这里的 :1 不是初始值,而是位域占用空间大小, :1 的话编译器可以看情况压缩成和其他 bool 在同一个字节里,节约内存


int poll_count;

Expand Down
39 changes: 39 additions & 0 deletions sound/hda/hdac_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val)
{
unsigned int addr = azx_command_addr(val);
unsigned int wp, rp;
unsigned long timeout;
unsigned int rirb_wp;
int i = 0;

spin_lock_irq(&bus->reg_lock);

Expand All @@ -172,6 +175,42 @@ int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val)
bus->corb.buf[wp] = cpu_to_le32(val);
snd_hdac_chip_writew(bus, CORBWP, wp);

if (bus->cmd_resend) {
timeout = jiffies + msecs_to_jiffies(1000);
udelay(80);
rirb_wp = snd_hdac_chip_readw(bus, RIRBWP);
while (rirb_wp == bus->rirb.wp) {
udelay(80);
rirb_wp = snd_hdac_chip_readw(bus, RIRBWP);
if (rirb_wp != bus->rirb.wp)
break;
if (i > 5)
break;
if (time_after(jiffies, timeout))
break;

/* add command to corb */
wp = snd_hdac_chip_readw(bus, CORBWP);
if (wp == 0xffff) {
/* something wrong, controller likely turned to D3 */
spin_unlock_irq(&bus->reg_lock);
return -EIO;
}
wp++;
wp %= AZX_MAX_CORB_ENTRIES;

rp = snd_hdac_chip_readw(bus, CORBRP);
if (wp == rp) {
/* oops, it's full */
spin_unlock_irq(&bus->reg_lock);
return -EAGAIN;
}
bus->corb.buf[wp] = cpu_to_le32(val);
snd_hdac_chip_writew(bus, CORBWP, wp);
i++;
}
}

spin_unlock_irq(&bus->reg_lock);

return 0;
Expand Down
8 changes: 8 additions & 0 deletions sound/hda/hdac_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ void snd_hdac_stream_start(struct hdac_stream *azx_dev)

trace_snd_hdac_stream_start(bus, azx_dev);

#ifdef CONFIG_SND_HDA_PHYTIUM
azx_dev->start_wallclk = snd_hdac_chip_readl(bus, WALLCLK) / 15;
#else
azx_dev->start_wallclk = snd_hdac_chip_readl(bus, WALLCLK);
#endif

/* enable SIE */
snd_hdac_chip_updatel(bus, INTCTL,
Expand Down Expand Up @@ -611,7 +615,11 @@ static u64 azx_cc_read(const struct cyclecounter *cc)
{
struct hdac_stream *azx_dev = container_of(cc, struct hdac_stream, cc);

#ifdef CONFIG_SND_HDA_PHYTIUM
return snd_hdac_chip_readl(azx_dev->bus, WALLCLK) / 25;
#else
return snd_hdac_chip_readl(azx_dev->bus, WALLCLK);
#endif
}

static void azx_timecounter_init(struct hdac_stream *azx_dev,
Expand Down
16 changes: 16 additions & 0 deletions sound/pci/hda/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ config SND_HDA_INTEL
To compile this driver as a module, choose M here: the module
will be called snd-hda-intel.

config SND_HDA_PHYTIUM
tristate "PHYTIUM HD Audio"
depends on SOUND
select SND_HDA
select SND_HDA_ALIGNED_MMIO
help
Say Y here to support the HDA controller present in PHYTIUM
SoCs

This options enables support for the HD Audio controller
present in some PHYTIUM SoCs, used to communicate audio
to the "High Definition Audio" codec.

To compile this driver as a module, choose M here: the module
will be called snd-hda-phytium.

config SND_HDA_TEGRA
tristate "NVIDIA Tegra HD Audio"
depends on ARCH_TEGRA
Expand Down
2 changes: 2 additions & 0 deletions sound/pci/hda/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
snd-hda-intel-objs := hda_intel.o
snd-hda-tegra-objs := hda_tegra.o
snd-hda-phytium-objs := hda_phytium.o

snd-hda-codec-y := hda_bind.o hda_codec.o hda_jack.o hda_auto_parser.o hda_sysfs.o
snd-hda-codec-y += hda_controller.o
Expand Down Expand Up @@ -70,3 +71,4 @@ obj-$(CONFIG_SND_HDA_SCODEC_TAS2781_I2C) += snd-hda-scodec-tas2781-i2c.o
# when built in kernel
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
obj-$(CONFIG_SND_HDA_TEGRA) += snd-hda-tegra.o
obj-$(CONFIG_SND_HDA_PHYTIUM) += snd-hda-phytium.o
5 changes: 5 additions & 0 deletions sound/pci/hda/hda_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include <linux/pm_runtime.h>
#include <linux/slab.h>

#include "hda_phytium.h"

#ifdef CONFIG_X86
/* for art-tsc conversion */
#include <asm/tsc.h>
Expand Down Expand Up @@ -156,6 +158,9 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
struct hda_spdif_out *spdif =
snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
unsigned short ctls = spdif ? spdif->ctls : 0;
struct hda_ft *hda = container_of(chip, struct hda_ft, chip);

hda->substream = substream;

trace_azx_pcm_prepare(chip, azx_dev);
dsp_lock(azx_dev);
Expand Down
Loading