diff options
Diffstat (limited to '')
-rw-r--r-- | sound/soc/codecs/rt700.c | 49 |
1 files changed, 35 insertions, 14 deletions
diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index ff68f0e4f629..055c3ae974d8 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -162,7 +162,7 @@ static void rt700_jack_detect_handler(struct work_struct *work) if (!rt700->hs_jack) return; - if (!rt700->component->card->instantiated) + if (!rt700->component->card || !rt700->component->card->instantiated) return; reg = RT700_VERB_GET_PIN_SENSE | RT700_HP_OUT; @@ -315,17 +315,27 @@ static int rt700_set_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *hs_jack, void *data) { struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); + int ret; rt700->hs_jack = hs_jack; - if (!rt700->hw_init) { - dev_dbg(&rt700->slave->dev, - "%s hw_init not ready yet\n", __func__); + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0) { + if (ret != -EACCES) { + dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret); + return ret; + } + + /* pm_runtime not enabled yet */ + dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__); return 0; } rt700_jack_init(rt700); + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + return 0; } @@ -808,9 +818,14 @@ static const struct snd_soc_dapm_route rt700_audio_map[] = { static int rt700_probe(struct snd_soc_component *component) { struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); + int ret; rt700->component = component; + ret = pm_runtime_resume(component->dev); + if (ret < 0 && ret != -EACCES) + return ret; + return 0; } @@ -853,6 +868,7 @@ static const struct snd_soc_component_driver soc_codec_dev_rt700 = { .dapm_routes = rt700_audio_map, .num_dapm_routes = ARRAY_SIZE(rt700_audio_map), .set_jack = rt700_set_jack_detect, + .endianness = 1, }; static int rt700_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, @@ -860,11 +876,14 @@ static int rt700_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, { struct sdw_stream_data *stream; + if (!sdw_stream) + return 0; + stream = kzalloc(sizeof(*stream), GFP_KERNEL); if (!stream) return -ENOMEM; - stream->sdw_stream = (struct sdw_stream_runtime *)sdw_stream; + stream->sdw_stream = sdw_stream; /* Use tx_mask or rx_mask to configure stream tag and set dma_data */ if (direction == SNDRV_PCM_STREAM_PLAYBACK) @@ -999,10 +1018,10 @@ static int rt700_pcm_hw_free(struct snd_pcm_substream *substream, #define RT700_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) -static struct snd_soc_dai_ops rt700_ops = { +static const struct snd_soc_dai_ops rt700_ops = { .hw_params = rt700_pcm_hw_params, .hw_free = rt700_pcm_hw_free, - .set_sdw_stream = rt700_set_sdw_stream, + .set_stream = rt700_set_sdw_stream, .shutdown = rt700_shutdown, }; @@ -1109,6 +1128,13 @@ int rt700_init(struct device *dev, struct regmap *sdw_regmap, rt700->sdw_regmap = sdw_regmap; rt700->regmap = regmap; + mutex_init(&rt700->disable_irq_lock); + + INIT_DELAYED_WORK(&rt700->jack_detect_work, + rt700_jack_detect_handler); + INIT_DELAYED_WORK(&rt700->jack_btn_check_work, + rt700_btn_check_handler); + /* * Mark hw_init to false * HW init will be performed when device reports present @@ -1130,6 +1156,8 @@ int rt700_io_init(struct device *dev, struct sdw_slave *slave) { struct rt700_priv *rt700 = dev_get_drvdata(dev); + rt700->disable_irq = false; + if (rt700->hw_init) return 0; @@ -1201,13 +1229,6 @@ int rt700_io_init(struct device *dev, struct sdw_slave *slave) /* Finish Initial Settings, set power to D3 */ regmap_write(rt700->regmap, RT700_SET_AUDIO_POWER_STATE, AC_PWRST_D3); - if (!rt700->first_hw_init) { - INIT_DELAYED_WORK(&rt700->jack_detect_work, - rt700_jack_detect_handler); - INIT_DELAYED_WORK(&rt700->jack_btn_check_work, - rt700_btn_check_handler); - } - /* * if set_jack callback occurred early than io_init, * we set up the jack detection function now |