mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
ASoC: Fixes for v5.17
Quite a few fixes here, including an unusually large set in the core spurred on by various testing efforts as well as the usual small driver fixes. There are quite a few fixes for out of bounds writes in both the core and the various Qualcomm drivers, plus a couple of fixes for locking in the DPCM code. -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAmH5Vi4ACgkQJNaLcl1U h9Ah6gf/SdlpKMKgAYiXAfmhb/88UgWkXWwHYgK+uHQXy3VpiG3zOso2uHQTbZ0X +QMZ1LwPbcSsz6Ny/w/kQ4MKeklHou0X6GiQ6PRoDukBPQ6yidivwnVXt35qNBwT iYmMuLpWsq0CrbUp9cPX+zurX+jUv/CKuwG1JnHxS2+lQ7UjetUOfKzO80X4zUA5 tm12soU9PSUcSyBICg5Jn+Tt9ZPccJ4cDPLfdRVkKjwb+6o4CnuM56Jq9UeHY6KT SGr8/Jt0I61p8UHPUpqJsj2ItHhy80bNraSaNptQljlIYCPidgFlPKyXxgunm8e5 Z2PUG2mOIR4pk0cj1SxOXwhH9+d3dQ== =UdmQ -----END PGP SIGNATURE----- Merge tag 'asoc-fix-v5.17-rc2' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus ASoC: Fixes for v5.17 Quite a few fixes here, including an unusually large set in the core spurred on by various testing efforts as well as the usual small driver fixes. There are quite a few fixes for out of bounds writes in both the core and the various Qualcomm drivers, plus a couple of fixes for locking in the DPCM code.
This commit is contained in:
commit
52517d9c0c
@ -615,10 +615,9 @@ static int wm97xx_register_touch(struct wm97xx *wm)
|
||||
* extensions)
|
||||
*/
|
||||
wm->touch_dev = platform_device_alloc("wm97xx-touch", -1);
|
||||
if (!wm->touch_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto touch_err;
|
||||
}
|
||||
if (!wm->touch_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(wm->touch_dev, wm);
|
||||
wm->touch_dev->dev.parent = wm->dev;
|
||||
wm->touch_dev->dev.platform_data = pdata;
|
||||
@ -629,9 +628,6 @@ static int wm97xx_register_touch(struct wm97xx *wm)
|
||||
return 0;
|
||||
touch_reg_err:
|
||||
platform_device_put(wm->touch_dev);
|
||||
touch_err:
|
||||
input_unregister_device(wm->input_dev);
|
||||
wm->input_dev = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -639,8 +635,6 @@ touch_err:
|
||||
static void wm97xx_unregister_touch(struct wm97xx *wm)
|
||||
{
|
||||
platform_device_unregister(wm->touch_dev);
|
||||
input_unregister_device(wm->input_dev);
|
||||
wm->input_dev = NULL;
|
||||
}
|
||||
|
||||
static int _wm97xx_probe(struct wm97xx *wm)
|
||||
|
@ -617,6 +617,7 @@ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream);
|
||||
void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream);
|
||||
void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream);
|
||||
unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream);
|
||||
unsigned long _snd_pcm_stream_lock_irqsave_nested(struct snd_pcm_substream *substream);
|
||||
|
||||
/**
|
||||
* snd_pcm_stream_lock_irqsave - Lock the PCM stream
|
||||
@ -635,6 +636,20 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream);
|
||||
void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
|
||||
unsigned long flags);
|
||||
|
||||
/**
|
||||
* snd_pcm_stream_lock_irqsave_nested - Single-nested PCM stream locking
|
||||
* @substream: PCM substream
|
||||
* @flags: irq flags
|
||||
*
|
||||
* This locks the PCM stream like snd_pcm_stream_lock_irqsave() but with
|
||||
* the single-depth lockdep subclass.
|
||||
*/
|
||||
#define snd_pcm_stream_lock_irqsave_nested(substream, flags) \
|
||||
do { \
|
||||
typecheck(unsigned long, flags); \
|
||||
flags = _snd_pcm_stream_lock_irqsave_nested(substream); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* snd_pcm_group_for_each_entry - iterate over the linked substreams
|
||||
* @s: the iterator
|
||||
|
@ -56,8 +56,10 @@
|
||||
* *
|
||||
****************************************************************************/
|
||||
|
||||
#define AES_IEC958_STATUS_SIZE 24
|
||||
|
||||
struct snd_aes_iec958 {
|
||||
unsigned char status[24]; /* AES/IEC958 channel status bits */
|
||||
unsigned char status[AES_IEC958_STATUS_SIZE]; /* AES/IEC958 channel status bits */
|
||||
unsigned char subcode[147]; /* AES/IEC958 subcode bits */
|
||||
unsigned char pad; /* nothing */
|
||||
unsigned char dig_subframe[4]; /* AES/IEC958 subframe bits */
|
||||
|
@ -172,6 +172,19 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
|
||||
|
||||
unsigned long _snd_pcm_stream_lock_irqsave_nested(struct snd_pcm_substream *substream)
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
if (substream->pcm->nonatomic)
|
||||
mutex_lock_nested(&substream->self_group.mutex,
|
||||
SINGLE_DEPTH_NESTING);
|
||||
else
|
||||
spin_lock_irqsave_nested(&substream->self_group.lock, flags,
|
||||
SINGLE_DEPTH_NESTING);
|
||||
return flags;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave_nested);
|
||||
|
||||
/**
|
||||
* snd_pcm_stream_unlock_irqrestore - Unlock the PCM stream
|
||||
* @substream: PCM substream
|
||||
|
@ -303,11 +303,11 @@ static const struct snd_soc_dapm_route rt1019_map_lr[] = {
|
||||
|
||||
static struct snd_soc_codec_conf rt1019_conf[] = {
|
||||
{
|
||||
.dlc = COMP_CODEC_CONF("i2c-10EC1019:00"),
|
||||
.dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
|
||||
.name_prefix = "Left",
|
||||
},
|
||||
{
|
||||
.dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
|
||||
.dlc = COMP_CODEC_CONF("i2c-10EC1019:00"),
|
||||
.name_prefix = "Right",
|
||||
},
|
||||
};
|
||||
|
@ -1667,6 +1667,8 @@ static int cpcap_codec_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *codec_node =
|
||||
of_get_child_by_name(pdev->dev.parent->of_node, "audio-codec");
|
||||
if (!codec_node)
|
||||
return -ENODEV;
|
||||
|
||||
pdev->dev.of_node = codec_node;
|
||||
|
||||
|
@ -277,7 +277,7 @@ struct hdmi_codec_priv {
|
||||
bool busy;
|
||||
struct snd_soc_jack *jack;
|
||||
unsigned int jack_status;
|
||||
u8 iec_status[5];
|
||||
u8 iec_status[AES_IEC958_STATUS_SIZE];
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget hdmi_widgets[] = {
|
||||
|
@ -2688,8 +2688,8 @@ static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
|
||||
int reg, b2_reg;
|
||||
|
||||
/* Address does not automatically update if reading */
|
||||
reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx;
|
||||
b2_reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx;
|
||||
reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx;
|
||||
b2_reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx;
|
||||
|
||||
snd_soc_component_write(component, reg,
|
||||
((band_idx * BAND_MAX + coeff_idx) *
|
||||
@ -2718,7 +2718,7 @@ static uint32_t get_iir_band_coeff(struct snd_soc_component *component,
|
||||
static void set_iir_band_coeff(struct snd_soc_component *component,
|
||||
int iir_idx, int band_idx, uint32_t value)
|
||||
{
|
||||
int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx;
|
||||
int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL + 0x80 * iir_idx;
|
||||
|
||||
snd_soc_component_write(component, reg, (value & 0xFF));
|
||||
snd_soc_component_write(component, reg, (value >> 8) & 0xFF);
|
||||
@ -2739,7 +2739,7 @@ static int rx_macro_put_iir_band_audio_mixer(
|
||||
int iir_idx = ctl->iir_idx;
|
||||
int band_idx = ctl->band_idx;
|
||||
u32 coeff[BAND_MAX];
|
||||
int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx;
|
||||
int reg = CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL + 0x80 * iir_idx;
|
||||
|
||||
memcpy(&coeff[0], ucontrol->value.bytes.data, params->max);
|
||||
|
||||
|
@ -64,7 +64,8 @@ static int speaker_gain_control_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol);
|
||||
struct max9759 *priv = snd_soc_component_get_drvdata(c);
|
||||
|
||||
if (ucontrol->value.integer.value[0] > 3)
|
||||
if (ucontrol->value.integer.value[0] < 0 ||
|
||||
ucontrol->value.integer.value[0] > 3)
|
||||
return -EINVAL;
|
||||
|
||||
priv->gain = ucontrol->value.integer.value[0];
|
||||
|
@ -59,18 +59,12 @@ static void rt5682_jd_check_handler(struct work_struct *work)
|
||||
struct rt5682_priv *rt5682 = container_of(work, struct rt5682_priv,
|
||||
jd_check_work.work);
|
||||
|
||||
if (snd_soc_component_read(rt5682->component, RT5682_AJD1_CTRL)
|
||||
& RT5682_JDH_RS_MASK) {
|
||||
if (snd_soc_component_read(rt5682->component, RT5682_AJD1_CTRL) & RT5682_JDH_RS_MASK)
|
||||
/* jack out */
|
||||
rt5682->jack_type = rt5682_headset_detect(rt5682->component, 0);
|
||||
|
||||
snd_soc_jack_report(rt5682->hs_jack, rt5682->jack_type,
|
||||
SND_JACK_HEADSET |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
SND_JACK_BTN_2 | SND_JACK_BTN_3);
|
||||
} else {
|
||||
mod_delayed_work(system_power_efficient_wq,
|
||||
&rt5682->jack_detect_work, 0);
|
||||
else
|
||||
schedule_delayed_work(&rt5682->jd_check_work, 500);
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t rt5682_irq(int irq, void *data)
|
||||
@ -198,7 +192,6 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
|
||||
}
|
||||
|
||||
mutex_init(&rt5682->calibrate_mutex);
|
||||
mutex_init(&rt5682->jdet_mutex);
|
||||
rt5682_calibrate(rt5682);
|
||||
|
||||
rt5682_apply_patch_list(rt5682, &i2c->dev);
|
||||
|
@ -922,15 +922,13 @@ static void rt5682_enable_push_button_irq(struct snd_soc_component *component,
|
||||
*
|
||||
* Returns detect status.
|
||||
*/
|
||||
int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert)
|
||||
static int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert)
|
||||
{
|
||||
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
|
||||
struct snd_soc_dapm_context *dapm = &component->dapm;
|
||||
unsigned int val, count;
|
||||
|
||||
if (jack_insert) {
|
||||
snd_soc_dapm_mutex_lock(dapm);
|
||||
|
||||
snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1,
|
||||
RT5682_PWR_VREF2 | RT5682_PWR_MB,
|
||||
RT5682_PWR_VREF2 | RT5682_PWR_MB);
|
||||
@ -981,8 +979,6 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert)
|
||||
snd_soc_component_update_bits(component, RT5682_MICBIAS_2,
|
||||
RT5682_PWR_CLK25M_MASK | RT5682_PWR_CLK1M_MASK,
|
||||
RT5682_PWR_CLK25M_PU | RT5682_PWR_CLK1M_PU);
|
||||
|
||||
snd_soc_dapm_mutex_unlock(dapm);
|
||||
} else {
|
||||
rt5682_enable_push_button_irq(component, false);
|
||||
snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1,
|
||||
@ -1011,7 +1007,6 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert)
|
||||
dev_dbg(component->dev, "jack_type = %d\n", rt5682->jack_type);
|
||||
return rt5682->jack_type;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt5682_headset_detect);
|
||||
|
||||
static int rt5682_set_jack_detect(struct snd_soc_component *component,
|
||||
struct snd_soc_jack *hs_jack, void *data)
|
||||
@ -1094,6 +1089,7 @@ void rt5682_jack_detect_handler(struct work_struct *work)
|
||||
{
|
||||
struct rt5682_priv *rt5682 =
|
||||
container_of(work, struct rt5682_priv, jack_detect_work.work);
|
||||
struct snd_soc_dapm_context *dapm;
|
||||
int val, btn_type;
|
||||
|
||||
while (!rt5682->component)
|
||||
@ -1102,7 +1098,9 @@ void rt5682_jack_detect_handler(struct work_struct *work)
|
||||
while (!rt5682->component->card->instantiated)
|
||||
usleep_range(10000, 15000);
|
||||
|
||||
mutex_lock(&rt5682->jdet_mutex);
|
||||
dapm = snd_soc_component_get_dapm(rt5682->component);
|
||||
|
||||
snd_soc_dapm_mutex_lock(dapm);
|
||||
mutex_lock(&rt5682->calibrate_mutex);
|
||||
|
||||
val = snd_soc_component_read(rt5682->component, RT5682_AJD1_CTRL)
|
||||
@ -1162,6 +1160,9 @@ void rt5682_jack_detect_handler(struct work_struct *work)
|
||||
rt5682->irq_work_delay_time = 50;
|
||||
}
|
||||
|
||||
mutex_unlock(&rt5682->calibrate_mutex);
|
||||
snd_soc_dapm_mutex_unlock(dapm);
|
||||
|
||||
snd_soc_jack_report(rt5682->hs_jack, rt5682->jack_type,
|
||||
SND_JACK_HEADSET |
|
||||
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
|
||||
@ -1174,9 +1175,6 @@ void rt5682_jack_detect_handler(struct work_struct *work)
|
||||
else
|
||||
cancel_delayed_work_sync(&rt5682->jd_check_work);
|
||||
}
|
||||
|
||||
mutex_unlock(&rt5682->calibrate_mutex);
|
||||
mutex_unlock(&rt5682->jdet_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt5682_jack_detect_handler);
|
||||
|
||||
@ -1526,7 +1524,6 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
|
||||
{
|
||||
struct snd_soc_component *component =
|
||||
snd_soc_dapm_to_component(w->dapm);
|
||||
struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
@ -1538,17 +1535,12 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w,
|
||||
RT5682_DEPOP_1, 0x60, 0x60);
|
||||
snd_soc_component_update_bits(component,
|
||||
RT5682_DAC_ADC_DIG_VOL1, 0x00c0, 0x0080);
|
||||
|
||||
mutex_lock(&rt5682->jdet_mutex);
|
||||
|
||||
snd_soc_component_update_bits(component, RT5682_HP_CTRL_2,
|
||||
RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN,
|
||||
RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN);
|
||||
usleep_range(5000, 10000);
|
||||
snd_soc_component_update_bits(component, RT5682_CHARGE_PUMP_1,
|
||||
RT5682_CP_SW_SIZE_MASK, RT5682_CP_SW_SIZE_L);
|
||||
|
||||
mutex_unlock(&rt5682->jdet_mutex);
|
||||
break;
|
||||
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
|
@ -1463,7 +1463,6 @@ struct rt5682_priv {
|
||||
|
||||
int jack_type;
|
||||
int irq_work_delay_time;
|
||||
struct mutex jdet_mutex;
|
||||
};
|
||||
|
||||
extern const char *rt5682_supply_names[RT5682_NUM_SUPPLIES];
|
||||
@ -1473,7 +1472,6 @@ int rt5682_sel_asrc_clk_src(struct snd_soc_component *component,
|
||||
|
||||
void rt5682_apply_patch_list(struct rt5682_priv *rt5682, struct device *dev);
|
||||
|
||||
int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert);
|
||||
void rt5682_jack_detect_handler(struct work_struct *work);
|
||||
|
||||
bool rt5682_volatile_register(struct device *dev, unsigned int reg);
|
||||
|
@ -1432,14 +1432,10 @@ static int wcd938x_sdw_connect_port(struct wcd938x_sdw_ch_info *ch_info,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcd938x_connect_port(struct wcd938x_sdw_priv *wcd, u8 ch_id, u8 enable)
|
||||
static int wcd938x_connect_port(struct wcd938x_sdw_priv *wcd, u8 port_num, u8 ch_id, u8 enable)
|
||||
{
|
||||
u8 port_num;
|
||||
|
||||
port_num = wcd->ch_info[ch_id].port_num;
|
||||
|
||||
return wcd938x_sdw_connect_port(&wcd->ch_info[ch_id],
|
||||
&wcd->port_config[port_num],
|
||||
&wcd->port_config[port_num - 1],
|
||||
enable);
|
||||
}
|
||||
|
||||
@ -2563,7 +2559,7 @@ static int wcd938x_ear_pa_put_gain(struct snd_kcontrol *kcontrol,
|
||||
WCD938X_EAR_GAIN_MASK,
|
||||
ucontrol->value.integer.value[0]);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int wcd938x_get_compander(struct snd_kcontrol *kcontrol,
|
||||
@ -2593,6 +2589,7 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol,
|
||||
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
||||
struct wcd938x_sdw_priv *wcd;
|
||||
int value = ucontrol->value.integer.value[0];
|
||||
int portidx;
|
||||
struct soc_mixer_control *mc;
|
||||
bool hphr;
|
||||
|
||||
@ -2606,12 +2603,14 @@ static int wcd938x_set_compander(struct snd_kcontrol *kcontrol,
|
||||
else
|
||||
wcd938x->comp1_enable = value;
|
||||
|
||||
if (value)
|
||||
wcd938x_connect_port(wcd, mc->reg, true);
|
||||
else
|
||||
wcd938x_connect_port(wcd, mc->reg, false);
|
||||
portidx = wcd->ch_info[mc->reg].port_num;
|
||||
|
||||
return 0;
|
||||
if (value)
|
||||
wcd938x_connect_port(wcd, portidx, mc->reg, true);
|
||||
else
|
||||
wcd938x_connect_port(wcd, portidx, mc->reg, false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int wcd938x_ldoh_get(struct snd_kcontrol *kcontrol,
|
||||
@ -2882,9 +2881,11 @@ static int wcd938x_get_swr_port(struct snd_kcontrol *kcontrol,
|
||||
struct wcd938x_sdw_priv *wcd;
|
||||
struct soc_mixer_control *mixer = (struct soc_mixer_control *)kcontrol->private_value;
|
||||
int dai_id = mixer->shift;
|
||||
int portidx = mixer->reg;
|
||||
int portidx, ch_idx = mixer->reg;
|
||||
|
||||
|
||||
wcd = wcd938x->sdw_priv[dai_id];
|
||||
portidx = wcd->ch_info[ch_idx].port_num;
|
||||
|
||||
ucontrol->value.integer.value[0] = wcd->port_enable[portidx];
|
||||
|
||||
@ -2899,12 +2900,14 @@ static int wcd938x_set_swr_port(struct snd_kcontrol *kcontrol,
|
||||
struct wcd938x_sdw_priv *wcd;
|
||||
struct soc_mixer_control *mixer =
|
||||
(struct soc_mixer_control *)kcontrol->private_value;
|
||||
int portidx = mixer->reg;
|
||||
int ch_idx = mixer->reg;
|
||||
int portidx;
|
||||
int dai_id = mixer->shift;
|
||||
bool enable;
|
||||
|
||||
wcd = wcd938x->sdw_priv[dai_id];
|
||||
|
||||
portidx = wcd->ch_info[ch_idx].port_num;
|
||||
if (ucontrol->value.integer.value[0])
|
||||
enable = true;
|
||||
else
|
||||
@ -2912,9 +2915,9 @@ static int wcd938x_set_swr_port(struct snd_kcontrol *kcontrol,
|
||||
|
||||
wcd->port_enable[portidx] = enable;
|
||||
|
||||
wcd938x_connect_port(wcd, portidx, enable);
|
||||
wcd938x_connect_port(wcd, portidx, ch_idx, enable);
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
|
@ -93,16 +93,21 @@ static int pcm030_fabric_probe(struct platform_device *op)
|
||||
dev_err(&op->dev, "platform_device_alloc() failed\n");
|
||||
|
||||
ret = platform_device_add(pdata->codec_device);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(&op->dev, "platform_device_add() failed: %d\n", ret);
|
||||
platform_device_put(pdata->codec_device);
|
||||
}
|
||||
|
||||
ret = snd_soc_register_card(card);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret);
|
||||
platform_device_del(pdata->codec_device);
|
||||
platform_device_put(pdata->codec_device);
|
||||
}
|
||||
|
||||
platform_set_drvdata(op, pdata);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int pcm030_fabric_remove(struct platform_device *op)
|
||||
|
@ -28,6 +28,30 @@ static const struct snd_soc_ops simple_ops = {
|
||||
.hw_params = asoc_simple_hw_params,
|
||||
};
|
||||
|
||||
static int asoc_simple_parse_platform(struct device_node *node,
|
||||
struct snd_soc_dai_link_component *dlc)
|
||||
{
|
||||
struct of_phandle_args args;
|
||||
int ret;
|
||||
|
||||
if (!node)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Get node via "sound-dai = <&phandle port>"
|
||||
* it will be used as xxx_of_node on soc_bind_dai_link()
|
||||
*/
|
||||
ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* dai_name is not required and may not exist for plat component */
|
||||
|
||||
dlc->of_node = args.np;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int asoc_simple_parse_dai(struct device_node *node,
|
||||
struct snd_soc_dai_link_component *dlc,
|
||||
int *is_single_link)
|
||||
@ -289,7 +313,7 @@ static int simple_dai_link_of(struct asoc_simple_priv *priv,
|
||||
if (ret < 0)
|
||||
goto dai_link_of_err;
|
||||
|
||||
ret = asoc_simple_parse_dai(plat, platforms, NULL);
|
||||
ret = asoc_simple_parse_platform(plat, platforms);
|
||||
if (ret < 0)
|
||||
goto dai_link_of_err;
|
||||
|
||||
|
@ -216,7 +216,7 @@ config SND_SOC_MT8195_MT6359_RT1019_RT5682
|
||||
|
||||
config SND_SOC_MT8195_MT6359_RT1011_RT5682
|
||||
tristate "ASoC Audio driver for MT8195 with MT6359 RT1011 RT5682 codec"
|
||||
depends on I2C
|
||||
depends on I2C && GPIOLIB
|
||||
depends on SND_SOC_MT8195 && MTK_PMIC_WRAP
|
||||
select SND_SOC_MT6359
|
||||
select SND_SOC_RT1011
|
||||
|
@ -308,8 +308,11 @@ static int q6apm_dai_close(struct snd_soc_component *component,
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
struct q6apm_dai_rtd *prtd = runtime->private_data;
|
||||
|
||||
q6apm_graph_stop(prtd->graph);
|
||||
q6apm_unmap_memory_regions(prtd->graph, substream->stream);
|
||||
if (prtd->state) { /* only stop graph that is started */
|
||||
q6apm_graph_stop(prtd->graph);
|
||||
q6apm_unmap_memory_regions(prtd->graph, substream->stream);
|
||||
}
|
||||
|
||||
q6apm_graph_close(prtd->graph);
|
||||
prtd->graph = NULL;
|
||||
kfree(prtd);
|
||||
|
@ -316,13 +316,27 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
|
||||
if (sign_bit)
|
||||
mask = BIT(sign_bit + 1) - 1;
|
||||
|
||||
val = ((ucontrol->value.integer.value[0] + min) & mask);
|
||||
if (ucontrol->value.integer.value[0] < 0)
|
||||
return -EINVAL;
|
||||
val = ucontrol->value.integer.value[0];
|
||||
if (mc->platform_max && val > mc->platform_max)
|
||||
return -EINVAL;
|
||||
if (val > max - min)
|
||||
return -EINVAL;
|
||||
val = (val + min) & mask;
|
||||
if (invert)
|
||||
val = max - val;
|
||||
val_mask = mask << shift;
|
||||
val = val << shift;
|
||||
if (snd_soc_volsw_is_stereo(mc)) {
|
||||
val2 = ((ucontrol->value.integer.value[1] + min) & mask);
|
||||
if (ucontrol->value.integer.value[1] < 0)
|
||||
return -EINVAL;
|
||||
val2 = ucontrol->value.integer.value[1];
|
||||
if (mc->platform_max && val2 > mc->platform_max)
|
||||
return -EINVAL;
|
||||
if (val2 > max - min)
|
||||
return -EINVAL;
|
||||
val2 = (val2 + min) & mask;
|
||||
if (invert)
|
||||
val2 = max - val2;
|
||||
if (reg == reg2) {
|
||||
@ -409,8 +423,15 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol,
|
||||
int err = 0;
|
||||
unsigned int val, val_mask;
|
||||
|
||||
if (ucontrol->value.integer.value[0] < 0)
|
||||
return -EINVAL;
|
||||
val = ucontrol->value.integer.value[0];
|
||||
if (mc->platform_max && val > mc->platform_max)
|
||||
return -EINVAL;
|
||||
if (val > max - min)
|
||||
return -EINVAL;
|
||||
val_mask = mask << shift;
|
||||
val = (ucontrol->value.integer.value[0] + min) & mask;
|
||||
val = (val + min) & mask;
|
||||
val = val << shift;
|
||||
|
||||
err = snd_soc_component_update_bits(component, reg, val_mask, val);
|
||||
@ -858,6 +879,8 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol,
|
||||
long val = ucontrol->value.integer.value[0];
|
||||
unsigned int i;
|
||||
|
||||
if (val < mc->min || val > mc->max)
|
||||
return -EINVAL;
|
||||
if (invert)
|
||||
val = max - val;
|
||||
val &= mask;
|
||||
|
@ -46,8 +46,8 @@ static inline void snd_soc_dpcm_stream_lock_irq(struct snd_soc_pcm_runtime *rtd,
|
||||
snd_pcm_stream_lock_irq(snd_soc_dpcm_get_substream(rtd, stream));
|
||||
}
|
||||
|
||||
#define snd_soc_dpcm_stream_lock_irqsave(rtd, stream, flags) \
|
||||
snd_pcm_stream_lock_irqsave(snd_soc_dpcm_get_substream(rtd, stream), flags)
|
||||
#define snd_soc_dpcm_stream_lock_irqsave_nested(rtd, stream, flags) \
|
||||
snd_pcm_stream_lock_irqsave_nested(snd_soc_dpcm_get_substream(rtd, stream), flags)
|
||||
|
||||
static inline void snd_soc_dpcm_stream_unlock_irq(struct snd_soc_pcm_runtime *rtd,
|
||||
int stream)
|
||||
@ -1268,6 +1268,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
|
||||
void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
|
||||
{
|
||||
struct snd_soc_dpcm *dpcm, *d;
|
||||
LIST_HEAD(deleted_dpcms);
|
||||
|
||||
snd_soc_dpcm_mutex_assert_held(fe);
|
||||
|
||||
@ -1287,13 +1288,18 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
|
||||
/* BEs still alive need new FE */
|
||||
dpcm_be_reparent(fe, dpcm->be, stream);
|
||||
|
||||
dpcm_remove_debugfs_state(dpcm);
|
||||
|
||||
list_del(&dpcm->list_be);
|
||||
list_del(&dpcm->list_fe);
|
||||
kfree(dpcm);
|
||||
list_move(&dpcm->list_fe, &deleted_dpcms);
|
||||
}
|
||||
snd_soc_dpcm_stream_unlock_irq(fe, stream);
|
||||
|
||||
while (!list_empty(&deleted_dpcms)) {
|
||||
dpcm = list_first_entry(&deleted_dpcms, struct snd_soc_dpcm,
|
||||
list_fe);
|
||||
list_del(&dpcm->list_fe);
|
||||
dpcm_remove_debugfs_state(dpcm);
|
||||
kfree(dpcm);
|
||||
}
|
||||
}
|
||||
|
||||
/* get BE for DAI widget and stream */
|
||||
@ -2094,7 +2100,7 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
|
||||
be = dpcm->be;
|
||||
be_substream = snd_soc_dpcm_get_substream(be, stream);
|
||||
|
||||
snd_soc_dpcm_stream_lock_irqsave(be, stream, flags);
|
||||
snd_soc_dpcm_stream_lock_irqsave_nested(be, stream, flags);
|
||||
|
||||
/* is this op for this BE ? */
|
||||
if (!snd_soc_dpcm_be_can_update(fe, be, stream))
|
||||
|
@ -37,6 +37,7 @@
|
||||
#define XLNX_AUD_XFER_COUNT 0x28
|
||||
#define XLNX_AUD_CH_STS_START 0x2C
|
||||
#define XLNX_BYTES_PER_CH 0x44
|
||||
#define XLNX_AUD_ALIGN_BYTES 64
|
||||
|
||||
#define AUD_STS_IOC_IRQ_MASK BIT(31)
|
||||
#define AUD_STS_CH_STS_MASK BIT(29)
|
||||
@ -368,12 +369,32 @@ static int xlnx_formatter_pcm_open(struct snd_soc_component *component,
|
||||
snd_soc_set_runtime_hwparams(substream, &xlnx_pcm_hardware);
|
||||
runtime->private_data = stream_data;
|
||||
|
||||
/* Resize the period size divisible by 64 */
|
||||
/* Resize the period bytes as divisible by 64 */
|
||||
err = snd_pcm_hw_constraint_step(runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
|
||||
SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
|
||||
XLNX_AUD_ALIGN_BYTES);
|
||||
if (err) {
|
||||
dev_err(component->dev,
|
||||
"unable to set constraint on period bytes\n");
|
||||
"Unable to set constraint on period bytes\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Resize the buffer bytes as divisible by 64 */
|
||||
err = snd_pcm_hw_constraint_step(runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
|
||||
XLNX_AUD_ALIGN_BYTES);
|
||||
if (err) {
|
||||
dev_err(component->dev,
|
||||
"Unable to set constraint on buffer bytes\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Set periods as integer multiple */
|
||||
err = snd_pcm_hw_constraint_integer(runtime,
|
||||
SNDRV_PCM_HW_PARAM_PERIODS);
|
||||
if (err < 0) {
|
||||
dev_err(component->dev,
|
||||
"Unable to set constraint on periods to be integer\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user