Merge branch 'for-linus' into for-next
Pull 5.3 development branch for further fixes of USB-audio stuff. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
commit
dae02c8c64
|
@ -8044,6 +8044,7 @@ S: Maintained
|
|||
F: drivers/video/fbdev/i810/
|
||||
|
||||
INTEL ASoC DRIVERS
|
||||
M: Cezary Rojewski <cezary.rojewski@intel.com>
|
||||
M: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
|
||||
M: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
M: Jie Yang <yang.jie@linux.intel.com>
|
||||
|
@ -16078,7 +16079,7 @@ S: Maintained
|
|||
F: drivers/net/ethernet/ti/netcp*
|
||||
|
||||
TI PCM3060 ASoC CODEC DRIVER
|
||||
M: Kirill Marinushkin <kmarinushkin@birdec.tech>
|
||||
M: Kirill Marinushkin <kmarinushkin@birdec.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/sound/pcm3060.txt
|
||||
|
|
|
@ -173,10 +173,7 @@ static inline void snd_compr_drain_notify(struct snd_compr_stream *stream)
|
|||
if (snd_BUG_ON(!stream))
|
||||
return;
|
||||
|
||||
if (stream->direction == SND_COMPRESS_PLAYBACK)
|
||||
stream->runtime->state = SNDRV_PCM_STATE_SETUP;
|
||||
else
|
||||
stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
|
||||
stream->runtime->state = SNDRV_PCM_STATE_SETUP;
|
||||
|
||||
wake_up(&stream->runtime->sleep);
|
||||
}
|
||||
|
|
|
@ -141,6 +141,10 @@ inline void asoc_simple_debug_dai(struct asoc_simple_priv *priv,
|
|||
{
|
||||
struct device *dev = simple_priv_to_dev(priv);
|
||||
|
||||
/* dai might be NULL */
|
||||
if (!dai)
|
||||
return;
|
||||
|
||||
if (dai->name)
|
||||
dev_dbg(dev, "%s dai name = %s\n",
|
||||
name, dai->name);
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#ifndef __INCLUDE_UAPI_SOF_FW_H__
|
||||
#define __INCLUDE_UAPI_SOF_FW_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define SND_SOF_FW_SIG_SIZE 4
|
||||
#define SND_SOF_FW_ABI 1
|
||||
#define SND_SOF_FW_SIG "Reef"
|
||||
|
@ -46,8 +48,8 @@ enum snd_sof_fw_blk_type {
|
|||
|
||||
struct snd_sof_blk_hdr {
|
||||
enum snd_sof_fw_blk_type type;
|
||||
uint32_t size; /* bytes minus this header */
|
||||
uint32_t offset; /* offset from base */
|
||||
__u32 size; /* bytes minus this header */
|
||||
__u32 offset; /* offset from base */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
|
@ -61,8 +63,8 @@ enum snd_sof_fw_mod_type {
|
|||
|
||||
struct snd_sof_mod_hdr {
|
||||
enum snd_sof_fw_mod_type type;
|
||||
uint32_t size; /* bytes minus this header */
|
||||
uint32_t num_blocks; /* number of blocks */
|
||||
__u32 size; /* bytes minus this header */
|
||||
__u32 num_blocks; /* number of blocks */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
|
@ -70,9 +72,9 @@ struct snd_sof_mod_hdr {
|
|||
*/
|
||||
struct snd_sof_fw_header {
|
||||
unsigned char sig[SND_SOF_FW_SIG_SIZE]; /* "Reef" */
|
||||
uint32_t file_size; /* size of file minus this header */
|
||||
uint32_t num_modules; /* number of modules */
|
||||
uint32_t abi; /* version of header format */
|
||||
__u32 file_size; /* size of file minus this header */
|
||||
__u32 num_modules; /* number of modules */
|
||||
__u32 abi; /* version of header format */
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#ifndef __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__
|
||||
#define __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* Header for all non IPC ABI data.
|
||||
*
|
||||
|
@ -16,12 +18,12 @@
|
|||
* Used by any bespoke component data structures or binary blobs.
|
||||
*/
|
||||
struct sof_abi_hdr {
|
||||
uint32_t magic; /**< 'S', 'O', 'F', '\0' */
|
||||
uint32_t type; /**< component specific type */
|
||||
uint32_t size; /**< size in bytes of data excl. this struct */
|
||||
uint32_t abi; /**< SOF ABI version */
|
||||
uint32_t reserved[4]; /**< reserved for future use */
|
||||
uint32_t data[0]; /**< Component data - opaque to core */
|
||||
__u32 magic; /**< 'S', 'O', 'F', '\0' */
|
||||
__u32 type; /**< component specific type */
|
||||
__u32 size; /**< size in bytes of data excl. this struct */
|
||||
__u32 abi; /**< SOF ABI version */
|
||||
__u32 reserved[4]; /**< reserved for future use */
|
||||
__u32 data[0]; /**< Component data - opaque to core */
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -122,17 +122,12 @@ static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
|
|||
vendor_id);
|
||||
|
||||
ret = device_add(&codec->dev);
|
||||
if (ret)
|
||||
goto err_free_codec;
|
||||
if (ret) {
|
||||
put_device(&codec->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_free_codec:
|
||||
of_node_put(codec->dev.of_node);
|
||||
put_device(&codec->dev);
|
||||
kfree(codec);
|
||||
ac97_ctrl->codecs[idx] = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int snd_ac97_bus_scan_one(struct ac97_controller *adrv,
|
||||
|
|
|
@ -574,10 +574,7 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
|
|||
stream->metadata_set = false;
|
||||
stream->next_track = false;
|
||||
|
||||
if (stream->direction == SND_COMPRESS_PLAYBACK)
|
||||
stream->runtime->state = SNDRV_PCM_STATE_SETUP;
|
||||
else
|
||||
stream->runtime->state = SNDRV_PCM_STATE_PREPARED;
|
||||
stream->runtime->state = SNDRV_PCM_STATE_SETUP;
|
||||
} else {
|
||||
return -EPERM;
|
||||
}
|
||||
|
@ -693,8 +690,17 @@ static int snd_compr_start(struct snd_compr_stream *stream)
|
|||
{
|
||||
int retval;
|
||||
|
||||
if (stream->runtime->state != SNDRV_PCM_STATE_PREPARED)
|
||||
switch (stream->runtime->state) {
|
||||
case SNDRV_PCM_STATE_SETUP:
|
||||
if (stream->direction != SND_COMPRESS_CAPTURE)
|
||||
return -EPERM;
|
||||
break;
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
break;
|
||||
default:
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_START);
|
||||
if (!retval)
|
||||
stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
|
||||
|
@ -705,9 +711,15 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
|
|||
{
|
||||
int retval;
|
||||
|
||||
if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED ||
|
||||
stream->runtime->state == SNDRV_PCM_STATE_SETUP)
|
||||
switch (stream->runtime->state) {
|
||||
case SNDRV_PCM_STATE_OPEN:
|
||||
case SNDRV_PCM_STATE_SETUP:
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
return -EPERM;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
|
||||
if (!retval) {
|
||||
snd_compr_drain_notify(stream);
|
||||
|
@ -795,9 +807,17 @@ static int snd_compr_drain(struct snd_compr_stream *stream)
|
|||
{
|
||||
int retval;
|
||||
|
||||
if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED ||
|
||||
stream->runtime->state == SNDRV_PCM_STATE_SETUP)
|
||||
switch (stream->runtime->state) {
|
||||
case SNDRV_PCM_STATE_OPEN:
|
||||
case SNDRV_PCM_STATE_SETUP:
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
case SNDRV_PCM_STATE_PAUSED:
|
||||
return -EPERM;
|
||||
case SNDRV_PCM_STATE_XRUN:
|
||||
return -EPIPE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
|
||||
if (retval) {
|
||||
|
@ -817,6 +837,10 @@ static int snd_compr_next_track(struct snd_compr_stream *stream)
|
|||
if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING)
|
||||
return -EPERM;
|
||||
|
||||
/* next track doesn't have any meaning for capture streams */
|
||||
if (stream->direction == SND_COMPRESS_CAPTURE)
|
||||
return -EPERM;
|
||||
|
||||
/* you can signal next track if this is intended to be a gapless stream
|
||||
* and current track metadata is set
|
||||
*/
|
||||
|
@ -834,9 +858,23 @@ static int snd_compr_next_track(struct snd_compr_stream *stream)
|
|||
static int snd_compr_partial_drain(struct snd_compr_stream *stream)
|
||||
{
|
||||
int retval;
|
||||
if (stream->runtime->state == SNDRV_PCM_STATE_PREPARED ||
|
||||
stream->runtime->state == SNDRV_PCM_STATE_SETUP)
|
||||
|
||||
switch (stream->runtime->state) {
|
||||
case SNDRV_PCM_STATE_OPEN:
|
||||
case SNDRV_PCM_STATE_SETUP:
|
||||
case SNDRV_PCM_STATE_PREPARED:
|
||||
case SNDRV_PCM_STATE_PAUSED:
|
||||
return -EPERM;
|
||||
case SNDRV_PCM_STATE_XRUN:
|
||||
return -EPIPE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* partial drain doesn't have any meaning for capture streams */
|
||||
if (stream->direction == SND_COMPRESS_CAPTURE)
|
||||
return -EPERM;
|
||||
|
||||
/* stream can be drained only when next track has been signalled */
|
||||
if (stream->next_track == false)
|
||||
return -EPERM;
|
||||
|
|
|
@ -1873,6 +1873,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
|
|||
if (!to_check)
|
||||
break; /* all drained */
|
||||
init_waitqueue_entry(&wait, current);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
add_wait_queue(&to_check->sleep, &wait);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
if (runtime->no_period_wakeup)
|
||||
|
@ -1885,7 +1886,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
|
|||
}
|
||||
tout = msecs_to_jiffies(tout * 1000);
|
||||
}
|
||||
tout = schedule_timeout_interruptible(tout);
|
||||
tout = schedule_timeout(tout);
|
||||
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
group = snd_pcm_stream_group_ref(substream);
|
||||
|
|
|
@ -136,10 +136,12 @@ int snd_hdac_i915_init(struct hdac_bus *bus)
|
|||
if (!acomp)
|
||||
return -ENODEV;
|
||||
if (!acomp->ops) {
|
||||
request_module("i915");
|
||||
/* 60s timeout */
|
||||
wait_for_completion_timeout(&bind_complete,
|
||||
msecs_to_jiffies(60 * 1000));
|
||||
if (!IS_ENABLED(CONFIG_MODULES) ||
|
||||
!request_module("i915")) {
|
||||
/* 60s timeout */
|
||||
wait_for_completion_timeout(&bind_complete,
|
||||
msecs_to_jiffies(60 * 1000));
|
||||
}
|
||||
}
|
||||
if (!acomp->ops) {
|
||||
dev_info(bus->dev, "couldn't bind with audio component\n");
|
||||
|
|
|
@ -318,11 +318,10 @@ enum {
|
|||
|
||||
#define AZX_DCAPS_INTEL_SKYLAKE \
|
||||
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
|
||||
AZX_DCAPS_SYNC_WRITE |\
|
||||
AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT)
|
||||
|
||||
#define AZX_DCAPS_INTEL_BROXTON \
|
||||
(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
|
||||
AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT)
|
||||
#define AZX_DCAPS_INTEL_BROXTON AZX_DCAPS_INTEL_SKYLAKE
|
||||
|
||||
/* quirks for ATI SB / AMD Hudson */
|
||||
#define AZX_DCAPS_PRESET_ATI_SB \
|
||||
|
|
|
@ -1083,6 +1083,7 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
|||
*/
|
||||
|
||||
static const struct hda_device_id snd_hda_id_conexant[] = {
|
||||
HDA_CODEC_ENTRY(0x14f11f86, "CX8070", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto),
|
||||
HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto),
|
||||
|
|
|
@ -31,8 +31,8 @@ struct i2s_stream_instance {
|
|||
u16 num_pages;
|
||||
u16 channels;
|
||||
u32 xfer_resolution;
|
||||
struct page *pg;
|
||||
u64 bytescount;
|
||||
dma_addr_t dma_addr;
|
||||
void __iomem *acp3x_base;
|
||||
};
|
||||
|
||||
|
@ -211,9 +211,8 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
|
|||
static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
|
||||
{
|
||||
u16 page_idx;
|
||||
u64 addr;
|
||||
u32 low, high, val, acp_fifo_addr;
|
||||
struct page *pg = rtd->pg;
|
||||
dma_addr_t addr = rtd->dma_addr;
|
||||
|
||||
/* 8 scratch registers used to map one 64 bit address */
|
||||
if (direction == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
|
@ -229,7 +228,6 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
|
|||
|
||||
for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
|
||||
/* Load the low address of page int ACP SRAM through SRBM */
|
||||
addr = page_to_phys(pg);
|
||||
low = lower_32_bits(addr);
|
||||
high = upper_32_bits(addr);
|
||||
|
||||
|
@ -239,7 +237,7 @@ static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction)
|
|||
+ 4);
|
||||
/* Move to next physically contiguos page */
|
||||
val += 8;
|
||||
pg++;
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
|
||||
if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
|
@ -341,7 +339,6 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
|
|||
{
|
||||
int status;
|
||||
u64 size;
|
||||
struct page *pg;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct i2s_stream_instance *rtd = runtime->private_data;
|
||||
|
||||
|
@ -354,9 +351,8 @@ static int acp3x_dma_hw_params(struct snd_pcm_substream *substream,
|
|||
return status;
|
||||
|
||||
memset(substream->runtime->dma_area, 0, params_buffer_bytes(params));
|
||||
pg = virt_to_page(substream->dma_buffer.area);
|
||||
if (pg) {
|
||||
rtd->pg = pg;
|
||||
if (substream->dma_buffer.area) {
|
||||
rtd->dma_addr = substream->dma_buffer.addr;
|
||||
rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
|
||||
config_acp3x_dma(rtd, substream->stream);
|
||||
status = 0;
|
||||
|
@ -385,9 +381,11 @@ static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream)
|
|||
|
||||
static int acp3x_dma_new(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd,
|
||||
DRV_NAME);
|
||||
struct device *parent = component->dev->parent;
|
||||
snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
|
||||
rtd->pcm->card->dev,
|
||||
MIN_BUFFER, MAX_BUFFER);
|
||||
parent, MIN_BUFFER, MAX_BUFFER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ struct cs42xx8_priv {
|
|||
unsigned long sysclk;
|
||||
u32 tx_channels;
|
||||
struct gpio_desc *gpiod_reset;
|
||||
u32 rate[2];
|
||||
};
|
||||
|
||||
/* -127.5dB to 0dB with step of 0.5dB */
|
||||
|
@ -176,21 +177,27 @@ static const struct snd_soc_dapm_route cs42xx8_adc3_dapm_routes[] = {
|
|||
};
|
||||
|
||||
struct cs42xx8_ratios {
|
||||
unsigned int ratio;
|
||||
unsigned char speed;
|
||||
unsigned char mclk;
|
||||
unsigned int mfreq;
|
||||
unsigned int min_mclk;
|
||||
unsigned int max_mclk;
|
||||
unsigned int ratio[3];
|
||||
};
|
||||
|
||||
/*
|
||||
* According to reference mannual, define the cs42xx8_ratio struct
|
||||
* MFreq2 | MFreq1 | MFreq0 | Description | SSM | DSM | QSM |
|
||||
* 0 | 0 | 0 |1.029MHz to 12.8MHz | 256 | 128 | 64 |
|
||||
* 0 | 0 | 1 |1.536MHz to 19.2MHz | 384 | 192 | 96 |
|
||||
* 0 | 1 | 0 |2.048MHz to 25.6MHz | 512 | 256 | 128 |
|
||||
* 0 | 1 | 1 |3.072MHz to 38.4MHz | 768 | 384 | 192 |
|
||||
* 1 | x | x |4.096MHz to 51.2MHz |1024 | 512 | 256 |
|
||||
*/
|
||||
static const struct cs42xx8_ratios cs42xx8_ratios[] = {
|
||||
{ 64, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_256(4) },
|
||||
{ 96, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_384(4) },
|
||||
{ 128, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_512(4) },
|
||||
{ 192, CS42XX8_FM_QUAD, CS42XX8_FUNCMOD_MFREQ_768(4) },
|
||||
{ 256, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_256(1) },
|
||||
{ 384, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_384(1) },
|
||||
{ 512, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_512(1) },
|
||||
{ 768, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_768(1) },
|
||||
{ 1024, CS42XX8_FM_SINGLE, CS42XX8_FUNCMOD_MFREQ_1024(1) }
|
||||
{ 0, 1029000, 12800000, {256, 128, 64} },
|
||||
{ 2, 1536000, 19200000, {384, 192, 96} },
|
||||
{ 4, 2048000, 25600000, {512, 256, 128} },
|
||||
{ 6, 3072000, 38400000, {768, 384, 192} },
|
||||
{ 8, 4096000, 51200000, {1024, 512, 256} },
|
||||
};
|
||||
|
||||
static int cs42xx8_set_dai_sysclk(struct snd_soc_dai *codec_dai,
|
||||
|
@ -257,14 +264,68 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
|
|||
struct snd_soc_component *component = dai->component;
|
||||
struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
|
||||
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||
u32 ratio = cs42xx8->sysclk / params_rate(params);
|
||||
u32 i, fm, val, mask;
|
||||
u32 ratio[2];
|
||||
u32 rate[2];
|
||||
u32 fm[2];
|
||||
u32 i, val, mask;
|
||||
bool condition1, condition2;
|
||||
|
||||
if (tx)
|
||||
cs42xx8->tx_channels = params_channels(params);
|
||||
|
||||
rate[tx] = params_rate(params);
|
||||
rate[!tx] = cs42xx8->rate[!tx];
|
||||
|
||||
ratio[tx] = rate[tx] > 0 ? cs42xx8->sysclk / rate[tx] : 0;
|
||||
ratio[!tx] = rate[!tx] > 0 ? cs42xx8->sysclk / rate[!tx] : 0;
|
||||
|
||||
/* Get functional mode for tx and rx according to rate */
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (cs42xx8->slave_mode) {
|
||||
fm[i] = CS42XX8_FM_AUTO;
|
||||
} else {
|
||||
if (rate[i] < 50000) {
|
||||
fm[i] = CS42XX8_FM_SINGLE;
|
||||
} else if (rate[i] > 50000 && rate[i] < 100000) {
|
||||
fm[i] = CS42XX8_FM_DOUBLE;
|
||||
} else if (rate[i] > 100000 && rate[i] < 200000) {
|
||||
fm[i] = CS42XX8_FM_QUAD;
|
||||
} else {
|
||||
dev_err(component->dev,
|
||||
"unsupported sample rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs42xx8_ratios); i++) {
|
||||
if (cs42xx8_ratios[i].ratio == ratio)
|
||||
/* Is the ratio[tx] valid ? */
|
||||
condition1 = ((fm[tx] == CS42XX8_FM_AUTO) ?
|
||||
(cs42xx8_ratios[i].ratio[0] == ratio[tx] ||
|
||||
cs42xx8_ratios[i].ratio[1] == ratio[tx] ||
|
||||
cs42xx8_ratios[i].ratio[2] == ratio[tx]) :
|
||||
(cs42xx8_ratios[i].ratio[fm[tx]] == ratio[tx])) &&
|
||||
cs42xx8->sysclk >= cs42xx8_ratios[i].min_mclk &&
|
||||
cs42xx8->sysclk <= cs42xx8_ratios[i].max_mclk;
|
||||
|
||||
if (!ratio[tx])
|
||||
condition1 = true;
|
||||
|
||||
/* Is the ratio[!tx] valid ? */
|
||||
condition2 = ((fm[!tx] == CS42XX8_FM_AUTO) ?
|
||||
(cs42xx8_ratios[i].ratio[0] == ratio[!tx] ||
|
||||
cs42xx8_ratios[i].ratio[1] == ratio[!tx] ||
|
||||
cs42xx8_ratios[i].ratio[2] == ratio[!tx]) :
|
||||
(cs42xx8_ratios[i].ratio[fm[!tx]] == ratio[!tx]));
|
||||
|
||||
if (!ratio[!tx])
|
||||
condition2 = true;
|
||||
|
||||
/*
|
||||
* Both ratio[tx] and ratio[!tx] is valid, then we get
|
||||
* a proper MFreq.
|
||||
*/
|
||||
if (condition1 && condition2)
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -273,18 +334,34 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
mask = CS42XX8_FUNCMOD_MFREQ_MASK;
|
||||
val = cs42xx8_ratios[i].mclk;
|
||||
cs42xx8->rate[tx] = params_rate(params);
|
||||
|
||||
fm = cs42xx8->slave_mode ? CS42XX8_FM_AUTO : cs42xx8_ratios[i].speed;
|
||||
mask = CS42XX8_FUNCMOD_MFREQ_MASK;
|
||||
val = cs42xx8_ratios[i].mfreq;
|
||||
|
||||
regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
|
||||
CS42XX8_FUNCMOD_xC_FM_MASK(tx) | mask,
|
||||
CS42XX8_FUNCMOD_xC_FM(tx, fm) | val);
|
||||
CS42XX8_FUNCMOD_xC_FM(tx, fm[tx]) | val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs42xx8_hw_free(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct cs42xx8_priv *cs42xx8 = snd_soc_component_get_drvdata(component);
|
||||
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
|
||||
|
||||
/* Clear stored rate */
|
||||
cs42xx8->rate[tx] = 0;
|
||||
|
||||
regmap_update_bits(cs42xx8->regmap, CS42XX8_FUNCMOD,
|
||||
CS42XX8_FUNCMOD_xC_FM_MASK(tx),
|
||||
CS42XX8_FUNCMOD_xC_FM(tx, CS42XX8_FM_AUTO));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs42xx8_digital_mute(struct snd_soc_dai *dai, int mute)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
|
@ -302,6 +379,7 @@ static const struct snd_soc_dai_ops cs42xx8_dai_ops = {
|
|||
.set_fmt = cs42xx8_set_dai_fmt,
|
||||
.set_sysclk = cs42xx8_set_dai_sysclk,
|
||||
.hw_params = cs42xx8_hw_params,
|
||||
.hw_free = cs42xx8_hw_free,
|
||||
.digital_mute = cs42xx8_digital_mute,
|
||||
};
|
||||
|
||||
|
|
|
@ -20,20 +20,10 @@
|
|||
#include <sound/soc-dapm.h>
|
||||
|
||||
struct max98357a_priv {
|
||||
struct delayed_work enable_sdmode_work;
|
||||
struct gpio_desc *sdmode;
|
||||
unsigned int sdmode_delay;
|
||||
};
|
||||
|
||||
static void max98357a_enable_sdmode_work(struct work_struct *work)
|
||||
{
|
||||
struct max98357a_priv *max98357a =
|
||||
container_of(work, struct max98357a_priv,
|
||||
enable_sdmode_work.work);
|
||||
|
||||
gpiod_set_value(max98357a->sdmode, 1);
|
||||
}
|
||||
|
||||
static int max98357a_daiops_trigger(struct snd_pcm_substream *substream,
|
||||
int cmd, struct snd_soc_dai *dai)
|
||||
{
|
||||
|
@ -46,14 +36,12 @@ static int max98357a_daiops_trigger(struct snd_pcm_substream *substream,
|
|||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
queue_delayed_work(system_power_efficient_wq,
|
||||
&max98357a->enable_sdmode_work,
|
||||
msecs_to_jiffies(max98357a->sdmode_delay));
|
||||
mdelay(max98357a->sdmode_delay);
|
||||
gpiod_set_value(max98357a->sdmode, 1);
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
cancel_delayed_work_sync(&max98357a->enable_sdmode_work);
|
||||
gpiod_set_value(max98357a->sdmode, 0);
|
||||
break;
|
||||
}
|
||||
|
@ -112,30 +100,25 @@ static int max98357a_platform_probe(struct platform_device *pdev)
|
|||
int ret;
|
||||
|
||||
max98357a = devm_kzalloc(&pdev->dev, sizeof(*max98357a), GFP_KERNEL);
|
||||
|
||||
if (!max98357a)
|
||||
return -ENOMEM;
|
||||
|
||||
max98357a->sdmode = devm_gpiod_get_optional(&pdev->dev,
|
||||
"sdmode", GPIOD_OUT_LOW);
|
||||
|
||||
if (IS_ERR(max98357a->sdmode))
|
||||
return PTR_ERR(max98357a->sdmode);
|
||||
|
||||
ret = device_property_read_u32(&pdev->dev, "sdmode-delay",
|
||||
&max98357a->sdmode_delay);
|
||||
|
||||
if (ret) {
|
||||
max98357a->sdmode_delay = 0;
|
||||
dev_dbg(&pdev->dev,
|
||||
"no optional property 'sdmode-delay' found, default: no delay\n");
|
||||
"no optional property 'sdmode-delay' found, "
|
||||
"default: no delay\n");
|
||||
}
|
||||
|
||||
dev_set_drvdata(&pdev->dev, max98357a);
|
||||
|
||||
INIT_DELAYED_WORK(&max98357a->enable_sdmode_work,
|
||||
max98357a_enable_sdmode_work);
|
||||
|
||||
return devm_snd_soc_register_component(&pdev->dev,
|
||||
&max98357a_component_driver,
|
||||
&max98357a_dai_driver, 1);
|
||||
|
|
|
@ -267,6 +267,12 @@ static int max98373_dai_hw_params(struct snd_pcm_substream *substream,
|
|||
case 48000:
|
||||
sampling_rate = MAX98373_PCM_SR_SET1_SR_48000;
|
||||
break;
|
||||
case 88200:
|
||||
sampling_rate = MAX98373_PCM_SR_SET1_SR_88200;
|
||||
break;
|
||||
case 96000:
|
||||
sampling_rate = MAX98373_PCM_SR_SET1_SR_96000;
|
||||
break;
|
||||
default:
|
||||
dev_err(component->dev, "rate %d not supported\n",
|
||||
params_rate(params));
|
||||
|
|
|
@ -130,6 +130,8 @@
|
|||
#define MAX98373_PCM_SR_SET1_SR_32000 (0x6 << 0)
|
||||
#define MAX98373_PCM_SR_SET1_SR_44100 (0x7 << 0)
|
||||
#define MAX98373_PCM_SR_SET1_SR_48000 (0x8 << 0)
|
||||
#define MAX98373_PCM_SR_SET1_SR_88200 (0x9 << 0)
|
||||
#define MAX98373_PCM_SR_SET1_SR_96000 (0xA << 0)
|
||||
|
||||
/* MAX98373_R2028_PCM_SR_SETUP_2 */
|
||||
#define MAX98373_PCM_SR_SET2_SR_MASK (0xF << 4)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// PCM3060 I2C driver
|
||||
//
|
||||
// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.tech>
|
||||
// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com>
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
|
@ -56,5 +56,5 @@ static struct i2c_driver pcm3060_i2c_driver = {
|
|||
module_i2c_driver(pcm3060_i2c_driver);
|
||||
|
||||
MODULE_DESCRIPTION("PCM3060 I2C driver");
|
||||
MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.tech>");
|
||||
MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// PCM3060 SPI driver
|
||||
//
|
||||
// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.tech>
|
||||
// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
@ -55,5 +55,5 @@ static struct spi_driver pcm3060_spi_driver = {
|
|||
module_spi_driver(pcm3060_spi_driver);
|
||||
|
||||
MODULE_DESCRIPTION("PCM3060 SPI driver");
|
||||
MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.tech>");
|
||||
MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// PCM3060 codec driver
|
||||
//
|
||||
// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.tech>
|
||||
// Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com>
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
@ -342,5 +342,5 @@ int pcm3060_probe(struct device *dev)
|
|||
EXPORT_SYMBOL(pcm3060_probe);
|
||||
|
||||
MODULE_DESCRIPTION("PCM3060 codec driver");
|
||||
MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.tech>");
|
||||
MODULE_AUTHOR("Kirill Marinushkin <kmarinushkin@birdec.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/*
|
||||
* PCM3060 codec driver
|
||||
*
|
||||
* Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.tech>
|
||||
* Copyright (C) 2018 Kirill Marinushkin <kmarinushkin@birdec.com>
|
||||
*/
|
||||
|
||||
#ifndef _SND_SOC_PCM3060_H
|
||||
|
|
|
@ -39,7 +39,7 @@ static const struct reg_sequence init_list[] = {
|
|||
{ RT1011_POWER_9, 0xa840 },
|
||||
|
||||
{ RT1011_ADC_SET_5, 0x0a20 },
|
||||
{ RT1011_DAC_SET_2, 0xa232 },
|
||||
{ RT1011_DAC_SET_2, 0xa032 },
|
||||
{ RT1011_ADC_SET_1, 0x2925 },
|
||||
|
||||
{ RT1011_SPK_PRO_DC_DET_1, 0xb00c },
|
||||
|
@ -1917,7 +1917,7 @@ static int rt1011_set_bias_level(struct snd_soc_component *component,
|
|||
snd_soc_component_write(component,
|
||||
RT1011_SYSTEM_RESET_2, 0x0000);
|
||||
snd_soc_component_write(component,
|
||||
RT1011_SYSTEM_RESET_3, 0x0000);
|
||||
RT1011_SYSTEM_RESET_3, 0x0001);
|
||||
snd_soc_component_write(component,
|
||||
RT1011_SYSTEM_RESET_1, 0x003f);
|
||||
snd_soc_component_write(component,
|
||||
|
|
|
@ -63,6 +63,7 @@ static int graph_get_dai_id(struct device_node *ep)
|
|||
struct device_node *endpoint;
|
||||
struct of_endpoint info;
|
||||
int i, id;
|
||||
const u32 *reg;
|
||||
int ret;
|
||||
|
||||
/* use driver specified DAI ID if exist */
|
||||
|
@ -83,8 +84,9 @@ static int graph_get_dai_id(struct device_node *ep)
|
|||
return info.id;
|
||||
|
||||
node = of_get_parent(ep);
|
||||
reg = of_get_property(node, "reg", NULL);
|
||||
of_node_put(node);
|
||||
if (of_get_property(node, "reg", NULL))
|
||||
if (reg)
|
||||
return info.port;
|
||||
}
|
||||
node = of_graph_get_port_parent(ep);
|
||||
|
@ -208,10 +210,6 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
|
|||
|
||||
dev_dbg(dev, "link_of DPCM (%pOF)\n", ep);
|
||||
|
||||
of_node_put(ports);
|
||||
of_node_put(port);
|
||||
of_node_put(node);
|
||||
|
||||
if (li->cpu) {
|
||||
int is_single_links = 0;
|
||||
|
||||
|
@ -229,17 +227,17 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
|
|||
|
||||
ret = asoc_simple_parse_cpu(ep, dai_link, &is_single_links);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_parse_clk_cpu(dev, ep, dai_link, dai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_set_dailink_name(dev, dai_link,
|
||||
"fe.%s",
|
||||
cpus->dai_name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
/* card->num_links includes Codec */
|
||||
asoc_simple_canonicalize_cpu(dai_link, is_single_links);
|
||||
|
@ -263,17 +261,17 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
|
|||
|
||||
ret = asoc_simple_parse_codec(ep, dai_link);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_parse_clk_codec(dev, ep, dai_link, dai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_set_dailink_name(dev, dai_link,
|
||||
"be.%s",
|
||||
codecs->dai_name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
/* check "prefix" from top node */
|
||||
snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node,
|
||||
|
@ -293,19 +291,23 @@ static int graph_dai_link_of_dpcm(struct asoc_simple_priv *priv,
|
|||
|
||||
ret = asoc_simple_parse_tdm(ep, dai);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_parse_daifmt(dev, cpu_ep, codec_ep,
|
||||
NULL, &dai_link->dai_fmt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
dai_link->dpcm_playback = 1;
|
||||
dai_link->dpcm_capture = 1;
|
||||
dai_link->ops = &graph_ops;
|
||||
dai_link->init = asoc_simple_dai_init;
|
||||
|
||||
return 0;
|
||||
out_put_node:
|
||||
of_node_put(ports);
|
||||
of_node_put(port);
|
||||
of_node_put(node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int graph_dai_link_of(struct asoc_simple_priv *priv,
|
||||
|
|
|
@ -349,6 +349,13 @@ void asoc_simple_canonicalize_platform(struct snd_soc_dai_link *dai_link)
|
|||
/* Assumes platform == cpu */
|
||||
if (!dai_link->platforms->of_node)
|
||||
dai_link->platforms->of_node = dai_link->cpus->of_node;
|
||||
|
||||
/*
|
||||
* DPCM BE can be no platform.
|
||||
* Alloced memory will be waste, but not leak.
|
||||
*/
|
||||
if (!dai_link->platforms->of_node)
|
||||
dai_link->num_platforms = 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_platform);
|
||||
|
||||
|
|
|
@ -124,8 +124,6 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
|
|||
|
||||
li->link++;
|
||||
|
||||
of_node_put(node);
|
||||
|
||||
/* For single DAI link & old style of DT node */
|
||||
if (is_top)
|
||||
prefix = PREFIX;
|
||||
|
@ -147,17 +145,17 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
|
|||
|
||||
ret = asoc_simple_parse_cpu(np, dai_link, &is_single_links);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_parse_clk_cpu(dev, np, dai_link, dai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_set_dailink_name(dev, dai_link,
|
||||
"fe.%s",
|
||||
cpus->dai_name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
asoc_simple_canonicalize_cpu(dai_link, is_single_links);
|
||||
} else {
|
||||
|
@ -180,17 +178,17 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
|
|||
|
||||
ret = asoc_simple_parse_codec(np, dai_link);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_parse_clk_codec(dev, np, dai_link, dai);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_set_dailink_name(dev, dai_link,
|
||||
"be.%s",
|
||||
codecs->dai_name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
/* check "prefix" from top node */
|
||||
snd_soc_of_parse_node_prefix(top, cconf, codecs->of_node,
|
||||
|
@ -208,19 +206,21 @@ static int simple_dai_link_of_dpcm(struct asoc_simple_priv *priv,
|
|||
|
||||
ret = asoc_simple_parse_tdm(np, dai);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
ret = asoc_simple_parse_daifmt(dev, node, codec,
|
||||
prefix, &dai_link->dai_fmt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto out_put_node;
|
||||
|
||||
dai_link->dpcm_playback = 1;
|
||||
dai_link->dpcm_capture = 1;
|
||||
dai_link->ops = &simple_ops;
|
||||
dai_link->init = asoc_simple_dai_init;
|
||||
|
||||
return 0;
|
||||
out_put_node:
|
||||
of_node_put(node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int simple_dai_link_of(struct asoc_simple_priv *priv,
|
||||
|
@ -364,8 +364,6 @@ static int simple_for_each_link(struct asoc_simple_priv *priv,
|
|||
goto error;
|
||||
}
|
||||
|
||||
of_node_put(codec);
|
||||
|
||||
/* get convert-xxx property */
|
||||
memset(&adata, 0, sizeof(adata));
|
||||
for_each_child_of_node(node, np)
|
||||
|
@ -387,11 +385,13 @@ static int simple_for_each_link(struct asoc_simple_priv *priv,
|
|||
ret = func_noml(priv, np, codec, li, is_top);
|
||||
|
||||
if (ret < 0) {
|
||||
of_node_put(codec);
|
||||
of_node_put(np);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
of_node_put(codec);
|
||||
node = of_get_next_child(top, node);
|
||||
} while (!is_top && node);
|
||||
|
||||
|
|
|
@ -437,6 +437,14 @@ static const struct acpi_gpio_mapping byt_cht_es8316_gpios[] = {
|
|||
|
||||
/* Please keep this list alphabetically sorted */
|
||||
static const struct dmi_system_id byt_cht_es8316_quirk_table[] = {
|
||||
{ /* Irbis NB41 */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "IRBIS"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "NB41"),
|
||||
},
|
||||
.driver_data = (void *)(BYT_CHT_ES8316_INTMIC_IN2_MAP
|
||||
| BYT_CHT_ES8316_JD_INVERTED),
|
||||
},
|
||||
{ /* Teclast X98 Plus II */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* soc-apci-intel-bxt-match.c - tables and support for BXT ACPI enumeration.
|
||||
* soc-acpi-intel-bxt-match.c - tables and support for BXT ACPI enumeration.
|
||||
*
|
||||
* Copyright (c) 2018, Intel Corporation.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* soc-apci-intel-byt-match.c - tables and support for BYT ACPI enumeration.
|
||||
* soc-acpi-intel-byt-match.c - tables and support for BYT ACPI enumeration.
|
||||
*
|
||||
* Copyright (c) 2017, Intel Corporation.
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* soc-apci-intel-cht-match.c - tables and support for CHT ACPI enumeration.
|
||||
* soc-acpi-intel-cht-match.c - tables and support for CHT ACPI enumeration.
|
||||
*
|
||||
* Copyright (c) 2017, Intel Corporation.
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* soc-apci-intel-cnl-match.c - tables and support for CNL ACPI enumeration.
|
||||
* soc-acpi-intel-cnl-match.c - tables and support for CNL ACPI enumeration.
|
||||
*
|
||||
* Copyright (c) 2018, Intel Corporation.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* soc-apci-intel-glk-match.c - tables and support for GLK ACPI enumeration.
|
||||
* soc-acpi-intel-glk-match.c - tables and support for GLK ACPI enumeration.
|
||||
*
|
||||
* Copyright (c) 2018, Intel Corporation.
|
||||
*
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Copyright (c) 2018, Intel Corporation.
|
||||
|
||||
/*
|
||||
* soc-apci-intel-hda-match.c - tables and support for HDA+ACPI enumeration.
|
||||
* soc-acpi-intel-hda-match.c - tables and support for HDA+ACPI enumeration.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* soc-apci-intel-hsw-bdw-match.c - tables and support for ACPI enumeration.
|
||||
* soc-acpi-intel-hsw-bdw-match.c - tables and support for ACPI enumeration.
|
||||
*
|
||||
* Copyright (c) 2017, Intel Corporation.
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* soc-apci-intel-icl-match.c - tables and support for ICL ACPI enumeration.
|
||||
* soc-acpi-intel-icl-match.c - tables and support for ICL ACPI enumeration.
|
||||
*
|
||||
* Copyright (c) 2018, Intel Corporation.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* soc-apci-intel-kbl-match.c - tables and support for KBL ACPI enumeration.
|
||||
* soc-acpi-intel-kbl-match.c - tables and support for KBL ACPI enumeration.
|
||||
*
|
||||
* Copyright (c) 2018, Intel Corporation.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* soc-apci-intel-skl-match.c - tables and support for SKL ACPI enumeration.
|
||||
* soc-acpi-intel-skl-match.c - tables and support for SKL ACPI enumeration.
|
||||
*
|
||||
* Copyright (c) 2018, Intel Corporation.
|
||||
*
|
||||
|
|
|
@ -150,17 +150,17 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
|
|||
|
||||
link = data->dai_link;
|
||||
|
||||
dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
|
||||
if (!dlc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
link->cpus = &dlc[0];
|
||||
link->platforms = &dlc[1];
|
||||
|
||||
link->num_cpus = 1;
|
||||
link->num_platforms = 1;
|
||||
|
||||
for_each_child_of_node(node, np) {
|
||||
dlc = devm_kzalloc(dev, 2 * sizeof(*dlc), GFP_KERNEL);
|
||||
if (!dlc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
link->cpus = &dlc[0];
|
||||
link->platforms = &dlc[1];
|
||||
|
||||
link->num_cpus = 1;
|
||||
link->num_platforms = 1;
|
||||
|
||||
cpu = of_get_child_by_name(np, "cpu");
|
||||
codec = of_get_child_by_name(np, "codec");
|
||||
|
||||
|
|
|
@ -326,7 +326,6 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
|
|||
val |= I2S_CHN_4;
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
val |= I2S_CHN_2;
|
||||
break;
|
||||
default:
|
||||
|
@ -459,7 +458,7 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = {
|
|||
},
|
||||
.capture = {
|
||||
.stream_name = "Capture",
|
||||
.channels_min = 1,
|
||||
.channels_min = 2,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_192000,
|
||||
.formats = (SNDRV_PCM_FMTBIT_S8 |
|
||||
|
@ -659,7 +658,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
|
||||
if (val >= 1 && val <= 8)
|
||||
if (val >= 2 && val <= 8)
|
||||
soc_dai->capture.channels_max = val;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,37 @@ static const struct snd_kcontrol_new rk_mc_controls[] = {
|
|||
SOC_DAPM_PIN_SWITCH("Speaker"),
|
||||
};
|
||||
|
||||
static int rk_jack_event(struct notifier_block *nb, unsigned long event,
|
||||
void *data)
|
||||
{
|
||||
struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
|
||||
struct snd_soc_dapm_context *dapm = &jack->card->dapm;
|
||||
|
||||
if (event & SND_JACK_MICROPHONE)
|
||||
snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
|
||||
else
|
||||
snd_soc_dapm_disable_pin(dapm, "MICBIAS");
|
||||
|
||||
snd_soc_dapm_sync(dapm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block rk_jack_nb = {
|
||||
.notifier_call = rk_jack_event,
|
||||
};
|
||||
|
||||
static int rk_init(struct snd_soc_pcm_runtime *runtime)
|
||||
{
|
||||
/*
|
||||
* The jack has already been created in the rk_98090_headset_init()
|
||||
* function.
|
||||
*/
|
||||
snd_soc_jack_notifier_register(&headset_jack, &rk_jack_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
|
@ -119,6 +150,7 @@ SND_SOC_DAILINK_DEFS(hifi,
|
|||
static struct snd_soc_dai_link rk_dailink = {
|
||||
.name = "max98090",
|
||||
.stream_name = "Audio",
|
||||
.init = rk_init,
|
||||
.ops = &rk_aif1_ops,
|
||||
/* set max98090 as slave */
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
|
|
|
@ -284,9 +284,8 @@ static int odroid_audio_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
of_node_put(cpu);
|
||||
of_node_put(codec);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto err_put_node;
|
||||
|
||||
ret = snd_soc_of_get_dai_link_codecs(dev, codec, codec_link);
|
||||
if (ret < 0)
|
||||
|
@ -309,7 +308,6 @@ static int odroid_audio_probe(struct platform_device *pdev)
|
|||
ret = PTR_ERR(priv->clk_i2s_bus);
|
||||
goto err_put_sclk;
|
||||
}
|
||||
of_node_put(cpu_dai);
|
||||
|
||||
ret = devm_snd_soc_register_card(dev, card);
|
||||
if (ret < 0) {
|
||||
|
@ -317,6 +315,8 @@ static int odroid_audio_probe(struct platform_device *pdev)
|
|||
goto err_put_clk_i2s;
|
||||
}
|
||||
|
||||
of_node_put(cpu_dai);
|
||||
of_node_put(codec);
|
||||
return 0;
|
||||
|
||||
err_put_clk_i2s:
|
||||
|
@ -326,6 +326,8 @@ err_put_sclk:
|
|||
err_put_cpu_dai:
|
||||
of_node_put(cpu_dai);
|
||||
snd_soc_of_put_dai_link_codecs(codec_link);
|
||||
err_put_node:
|
||||
of_node_put(codec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1515,8 +1515,11 @@ static int soc_probe_link_dais(struct snd_soc_card *card,
|
|||
}
|
||||
}
|
||||
|
||||
if (dai_link->dai_fmt)
|
||||
snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
|
||||
if (dai_link->dai_fmt) {
|
||||
ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = soc_post_component_init(rtd, dai_link->name);
|
||||
if (ret)
|
||||
|
|
|
@ -1157,8 +1157,8 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
|
|||
list_add_tail(&widget->work_list, list);
|
||||
|
||||
if (custom_stop_condition && custom_stop_condition(widget, dir)) {
|
||||
widget->endpoints[dir] = 1;
|
||||
return widget->endpoints[dir];
|
||||
list = NULL;
|
||||
custom_stop_condition = NULL;
|
||||
}
|
||||
|
||||
if ((widget->is_ep & SND_SOC_DAPM_DIR_TO_EP(dir)) && widget->connected) {
|
||||
|
@ -1195,8 +1195,8 @@ static __always_inline int is_connected_ep(struct snd_soc_dapm_widget *widget,
|
|||
*
|
||||
* Optionally, can be supplied with a function acting as a stopping condition.
|
||||
* This function takes the dapm widget currently being examined and the walk
|
||||
* direction as an arguments, it should return true if the walk should be
|
||||
* stopped and false otherwise.
|
||||
* direction as an arguments, it should return true if widgets from that point
|
||||
* in the graph onwards should not be added to the widget list.
|
||||
*/
|
||||
static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
|
||||
struct list_head *list,
|
||||
|
@ -3706,6 +3706,8 @@ request_failed:
|
|||
dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
|
||||
w->name, ret);
|
||||
|
||||
kfree_const(w->sname);
|
||||
kfree(w);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -101,8 +101,8 @@ static irqreturn_t cnl_ipc_irq_thread(int irq, void *context)
|
|||
/*
|
||||
* This interrupt is not shared so no need to return IRQ_NONE.
|
||||
*/
|
||||
dev_err_ratelimited(sdev->dev,
|
||||
"error: nothing to do in IRQ thread\n");
|
||||
dev_dbg_ratelimited(sdev->dev,
|
||||
"nothing to do in IPC IRQ thread\n");
|
||||
}
|
||||
|
||||
/* re-enable IPC interrupt */
|
||||
|
|
|
@ -224,8 +224,8 @@ irqreturn_t hda_dsp_ipc_irq_thread(int irq, void *context)
|
|||
/*
|
||||
* This interrupt is not shared so no need to return IRQ_NONE.
|
||||
*/
|
||||
dev_err_ratelimited(sdev->dev,
|
||||
"error: nothing to do in IRQ thread\n");
|
||||
dev_dbg_ratelimited(sdev->dev,
|
||||
"nothing to do in IPC IRQ thread\n");
|
||||
}
|
||||
|
||||
/* re-enable IPC interrupt */
|
||||
|
|
|
@ -1002,8 +1002,8 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = {
|
|||
.field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31),
|
||||
.field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2),
|
||||
.field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2),
|
||||
.get_sr = sun8i_i2s_get_sr_wss,
|
||||
.get_wss = sun8i_i2s_get_sr_wss,
|
||||
.get_sr = sun4i_i2s_get_sr,
|
||||
.get_wss = sun4i_i2s_get_wss,
|
||||
};
|
||||
|
||||
static int sun4i_i2s_init_regmap_fields(struct device *dev,
|
||||
|
|
|
@ -195,7 +195,7 @@ static inline void mcasp_set_axr_pdir(struct davinci_mcasp *mcasp, bool enable)
|
|||
{
|
||||
u32 bit;
|
||||
|
||||
for_each_set_bit(bit, &mcasp->pdir, PIN_BIT_AFSR) {
|
||||
for_each_set_bit(bit, &mcasp->pdir, PIN_BIT_AMUTE) {
|
||||
if (enable)
|
||||
mcasp_set_bits(mcasp, DAVINCI_MCASP_PDIR_REG, BIT(bit));
|
||||
else
|
||||
|
@ -223,6 +223,7 @@ static void mcasp_start_rx(struct davinci_mcasp *mcasp)
|
|||
if (mcasp_is_synchronous(mcasp)) {
|
||||
mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
|
||||
mcasp_set_ctl_reg(mcasp, DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
|
||||
mcasp_set_clk_pdir(mcasp, true);
|
||||
}
|
||||
|
||||
/* Activate serializer(s) */
|
||||
|
@ -1256,6 +1257,28 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int davinci_mcasp_hw_rule_slot_width(struct snd_pcm_hw_params *params,
|
||||
struct snd_pcm_hw_rule *rule)
|
||||
{
|
||||
struct davinci_mcasp_ruledata *rd = rule->private;
|
||||
struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
|
||||
struct snd_mask nfmt;
|
||||
int i, slot_width;
|
||||
|
||||
snd_mask_none(&nfmt);
|
||||
slot_width = rd->mcasp->slot_width;
|
||||
|
||||
for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
|
||||
if (snd_mask_test(fmt, i)) {
|
||||
if (snd_pcm_format_width(i) <= slot_width) {
|
||||
snd_mask_set(&nfmt, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return snd_mask_refine(fmt, &nfmt);
|
||||
}
|
||||
|
||||
static const unsigned int davinci_mcasp_dai_rates[] = {
|
||||
8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000,
|
||||
88200, 96000, 176400, 192000,
|
||||
|
@ -1377,7 +1400,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
|
|||
struct davinci_mcasp_ruledata *ruledata =
|
||||
&mcasp->ruledata[substream->stream];
|
||||
u32 max_channels = 0;
|
||||
int i, dir;
|
||||
int i, dir, ret;
|
||||
int tdm_slots = mcasp->tdm_slots;
|
||||
|
||||
/* Do not allow more then one stream per direction */
|
||||
|
@ -1406,6 +1429,7 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
|
|||
max_channels++;
|
||||
}
|
||||
ruledata->serializers = max_channels;
|
||||
ruledata->mcasp = mcasp;
|
||||
max_channels *= tdm_slots;
|
||||
/*
|
||||
* If the already active stream has less channels than the calculated
|
||||
|
@ -1431,20 +1455,22 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
|
|||
0, SNDRV_PCM_HW_PARAM_CHANNELS,
|
||||
&mcasp->chconstr[substream->stream]);
|
||||
|
||||
if (mcasp->slot_width)
|
||||
snd_pcm_hw_constraint_minmax(substream->runtime,
|
||||
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
|
||||
8, mcasp->slot_width);
|
||||
if (mcasp->slot_width) {
|
||||
/* Only allow formats require <= slot_width bits on the bus */
|
||||
ret = snd_pcm_hw_rule_add(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_FORMAT,
|
||||
davinci_mcasp_hw_rule_slot_width,
|
||||
ruledata,
|
||||
SNDRV_PCM_HW_PARAM_FORMAT, -1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we rely on implicit BCLK divider setting we should
|
||||
* set constraints based on what we can provide.
|
||||
*/
|
||||
if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) {
|
||||
int ret;
|
||||
|
||||
ruledata->mcasp = mcasp;
|
||||
|
||||
ret = snd_pcm_hw_rule_add(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_RATE,
|
||||
davinci_mcasp_hw_rule_rate,
|
||||
|
|
|
@ -72,7 +72,7 @@ int snd_usb_pipe_sanity_check(struct usb_device *dev, unsigned int pipe)
|
|||
struct usb_host_endpoint *ep;
|
||||
|
||||
ep = usb_pipe_endpoint(dev, pipe);
|
||||
if (usb_pipetype(pipe) != pipetypes[usb_endpoint_type(&ep->desc)])
|
||||
if (!ep || usb_pipetype(pipe) != pipetypes[usb_endpoint_type(&ep->desc)])
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1043,6 +1043,7 @@ found_clock:
|
|||
|
||||
pd = kzalloc(sizeof(*pd), GFP_KERNEL);
|
||||
if (!pd) {
|
||||
kfree(fp->chmap);
|
||||
kfree(fp->rate_table);
|
||||
kfree(fp);
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue