xref: /linux/sound/pci/hda/hda_controller.c (revision e09f9f52)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
205e84878SDylan Reid /*
305e84878SDylan Reid  *
405e84878SDylan Reid  *  Implementation of primary alsa driver code base for Intel HD Audio.
505e84878SDylan Reid  *
6*e09f9f52SPierre-Louis Bossart  *  Copyright(c) 2004 Intel Corporation
705e84878SDylan Reid  *
805e84878SDylan Reid  *  Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
905e84878SDylan Reid  *                     PeiSen Hou <pshou@realtek.com.tw>
1005e84878SDylan Reid  */
1105e84878SDylan Reid 
1205e84878SDylan Reid #include <linux/clocksource.h>
1305e84878SDylan Reid #include <linux/delay.h>
14f0b1df88SDylan Reid #include <linux/interrupt.h>
1505e84878SDylan Reid #include <linux/kernel.h>
1605e84878SDylan Reid #include <linux/module.h>
17154867cfSDylan Reid #include <linux/pm_runtime.h>
1805e84878SDylan Reid #include <linux/slab.h>
19bfcba288SGuneshwor Singh 
20bfcba288SGuneshwor Singh #ifdef CONFIG_X86
21bfcba288SGuneshwor Singh /* for art-tsc conversion */
22bfcba288SGuneshwor Singh #include <asm/tsc.h>
23bfcba288SGuneshwor Singh #endif
24bfcba288SGuneshwor Singh 
2505e84878SDylan Reid #include <sound/core.h>
2605e84878SDylan Reid #include <sound/initval.h>
2704438a06STakashi Iwai #include <sound/pcm_params.h>
2805e84878SDylan Reid #include "hda_controller.h"
29c0f1886dSTakashi Iwai #include "hda_local.h"
3005e84878SDylan Reid 
3143db4a59STakashi Iwai #define CREATE_TRACE_POINTS
3218486508SLibin Yang #include "hda_controller_trace.h"
3343db4a59STakashi Iwai 
342b5fd6c2SDylan Reid /* DSP lock helpers */
357833c3f8STakashi Iwai #define dsp_lock(dev)		snd_hdac_dsp_lock(azx_stream(dev))
367833c3f8STakashi Iwai #define dsp_unlock(dev)		snd_hdac_dsp_unlock(azx_stream(dev))
377833c3f8STakashi Iwai #define dsp_is_locked(dev)	snd_hdac_stream_is_locked(azx_stream(dev))
382b5fd6c2SDylan Reid 
3905e84878SDylan Reid /* assign a stream for the PCM */
4005e84878SDylan Reid static inline struct azx_dev *
azx_assign_device(struct azx * chip,struct snd_pcm_substream * substream)4105e84878SDylan Reid azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
4205e84878SDylan Reid {
437833c3f8STakashi Iwai 	struct hdac_stream *s;
4405e84878SDylan Reid 
457833c3f8STakashi Iwai 	s = snd_hdac_stream_assign(azx_bus(chip), substream);
467833c3f8STakashi Iwai 	if (!s)
477833c3f8STakashi Iwai 		return NULL;
487833c3f8STakashi Iwai 	return stream_to_azx_dev(s);
4905e84878SDylan Reid }
5005e84878SDylan Reid 
5105e84878SDylan Reid /* release the assigned stream */
azx_release_device(struct azx_dev * azx_dev)5205e84878SDylan Reid static inline void azx_release_device(struct azx_dev *azx_dev)
5305e84878SDylan Reid {
547833c3f8STakashi Iwai 	snd_hdac_stream_release(azx_stream(azx_dev));
5505e84878SDylan Reid }
5605e84878SDylan Reid 
57820cc6cfSTakashi Iwai static inline struct hda_pcm_stream *
to_hda_pcm_stream(struct snd_pcm_substream * substream)58820cc6cfSTakashi Iwai to_hda_pcm_stream(struct snd_pcm_substream *substream)
59820cc6cfSTakashi Iwai {
60820cc6cfSTakashi Iwai 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
61820cc6cfSTakashi Iwai 	return &apcm->info->stream[substream->stream];
62820cc6cfSTakashi Iwai }
63820cc6cfSTakashi Iwai 
azx_adjust_codec_delay(struct snd_pcm_substream * substream,u64 nsec)6405e84878SDylan Reid static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream,
6505e84878SDylan Reid 				u64 nsec)
6605e84878SDylan Reid {
6705e84878SDylan Reid 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
68820cc6cfSTakashi Iwai 	struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
6905e84878SDylan Reid 	u64 codec_frames, codec_nsecs;
7005e84878SDylan Reid 
7105e84878SDylan Reid 	if (!hinfo->ops.get_delay)
7205e84878SDylan Reid 		return nsec;
7305e84878SDylan Reid 
7405e84878SDylan Reid 	codec_frames = hinfo->ops.get_delay(hinfo, apcm->codec, substream);
7505e84878SDylan Reid 	codec_nsecs = div_u64(codec_frames * 1000000000LL,
7605e84878SDylan Reid 			      substream->runtime->rate);
7705e84878SDylan Reid 
7805e84878SDylan Reid 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
7905e84878SDylan Reid 		return nsec + codec_nsecs;
8005e84878SDylan Reid 
8105e84878SDylan Reid 	return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0;
8205e84878SDylan Reid }
8305e84878SDylan Reid 
8405e84878SDylan Reid /*
8505e84878SDylan Reid  * PCM ops
8605e84878SDylan Reid  */
8705e84878SDylan Reid 
azx_pcm_close(struct snd_pcm_substream * substream)8805e84878SDylan Reid static int azx_pcm_close(struct snd_pcm_substream *substream)
8905e84878SDylan Reid {
9005e84878SDylan Reid 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
91820cc6cfSTakashi Iwai 	struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
9205e84878SDylan Reid 	struct azx *chip = apcm->chip;
9305e84878SDylan Reid 	struct azx_dev *azx_dev = get_azx_dev(substream);
9405e84878SDylan Reid 
9518486508SLibin Yang 	trace_azx_pcm_close(chip, azx_dev);
9605e84878SDylan Reid 	mutex_lock(&chip->open_mutex);
9705e84878SDylan Reid 	azx_release_device(azx_dev);
9861ca4107STakashi Iwai 	if (hinfo->ops.close)
9905e84878SDylan Reid 		hinfo->ops.close(hinfo, apcm->codec, substream);
10005e84878SDylan Reid 	snd_hda_power_down(apcm->codec);
10105e84878SDylan Reid 	mutex_unlock(&chip->open_mutex);
1029a6246ffSTakashi Iwai 	snd_hda_codec_pcm_put(apcm->info);
10305e84878SDylan Reid 	return 0;
10405e84878SDylan Reid }
10505e84878SDylan Reid 
azx_pcm_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)10605e84878SDylan Reid static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
10705e84878SDylan Reid 			     struct snd_pcm_hw_params *hw_params)
10805e84878SDylan Reid {
10905e84878SDylan Reid 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
11005e84878SDylan Reid 	struct azx *chip = apcm->chip;
111602518a2STakashi Iwai 	struct azx_dev *azx_dev = get_azx_dev(substream);
11204438a06STakashi Iwai 	struct hdac_stream *hdas = azx_stream(azx_dev);
1137a6d4a5aSTakashi Iwai 	int ret = 0;
11405e84878SDylan Reid 
11518486508SLibin Yang 	trace_azx_pcm_hw_params(chip, azx_dev);
116602518a2STakashi Iwai 	dsp_lock(azx_dev);
117602518a2STakashi Iwai 	if (dsp_is_locked(azx_dev)) {
11805e84878SDylan Reid 		ret = -EBUSY;
11905e84878SDylan Reid 		goto unlock;
12005e84878SDylan Reid 	}
12105e84878SDylan Reid 
12204438a06STakashi Iwai 	/* Set up BDLEs here, return -ENOMEM if too many BDLEs are required */
12304438a06STakashi Iwai 	hdas->bufsize = params_buffer_bytes(hw_params);
12404438a06STakashi Iwai 	hdas->period_bytes = params_period_bytes(hw_params);
12504438a06STakashi Iwai 	hdas->format_val = 0;
12604438a06STakashi Iwai 	hdas->no_period_wakeup =
12704438a06STakashi Iwai 		(hw_params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
12804438a06STakashi Iwai 		(hw_params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
12904438a06STakashi Iwai 	if (snd_hdac_stream_setup_periods(hdas) < 0)
13004438a06STakashi Iwai 		ret = -ENOMEM;
131193c7e14STakashi Iwai 
13205e84878SDylan Reid unlock:
133602518a2STakashi Iwai 	dsp_unlock(azx_dev);
13405e84878SDylan Reid 	return ret;
13505e84878SDylan Reid }
13605e84878SDylan Reid 
azx_pcm_hw_free(struct snd_pcm_substream * substream)13705e84878SDylan Reid static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
13805e84878SDylan Reid {
13905e84878SDylan Reid 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
14005e84878SDylan Reid 	struct azx_dev *azx_dev = get_azx_dev(substream);
141820cc6cfSTakashi Iwai 	struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
14205e84878SDylan Reid 
14305e84878SDylan Reid 	/* reset BDL address */
14405e84878SDylan Reid 	dsp_lock(azx_dev);
145ccc98865STakashi Iwai 	if (!dsp_is_locked(azx_dev))
146ccc98865STakashi Iwai 		snd_hdac_stream_cleanup(azx_stream(azx_dev));
14705e84878SDylan Reid 
14805e84878SDylan Reid 	snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
14905e84878SDylan Reid 
1506d23c8f5STakashi Iwai 	azx_stream(azx_dev)->prepared = 0;
15105e84878SDylan Reid 	dsp_unlock(azx_dev);
1527a6d4a5aSTakashi Iwai 	return 0;
15305e84878SDylan Reid }
15405e84878SDylan Reid 
azx_pcm_prepare(struct snd_pcm_substream * substream)15505e84878SDylan Reid static int azx_pcm_prepare(struct snd_pcm_substream *substream)
15605e84878SDylan Reid {
15705e84878SDylan Reid 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
15805e84878SDylan Reid 	struct azx *chip = apcm->chip;
15905e84878SDylan Reid 	struct azx_dev *azx_dev = get_azx_dev(substream);
160820cc6cfSTakashi Iwai 	struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
16105e84878SDylan Reid 	struct snd_pcm_runtime *runtime = substream->runtime;
16261b52df4SCezary Rojewski 	unsigned int format_val, stream_tag, bits;
16305e84878SDylan Reid 	int err;
16405e84878SDylan Reid 	struct hda_spdif_out *spdif =
16505e84878SDylan Reid 		snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
16605e84878SDylan Reid 	unsigned short ctls = spdif ? spdif->ctls : 0;
16705e84878SDylan Reid 
16818486508SLibin Yang 	trace_azx_pcm_prepare(chip, azx_dev);
16905e84878SDylan Reid 	dsp_lock(azx_dev);
17005e84878SDylan Reid 	if (dsp_is_locked(azx_dev)) {
17105e84878SDylan Reid 		err = -EBUSY;
17205e84878SDylan Reid 		goto unlock;
17305e84878SDylan Reid 	}
17405e84878SDylan Reid 
1757833c3f8STakashi Iwai 	snd_hdac_stream_reset(azx_stream(azx_dev));
17661b52df4SCezary Rojewski 	bits = snd_hdac_stream_format_bits(runtime->format, SNDRV_PCM_SUBFORMAT_STD, hinfo->maxbps);
17761b52df4SCezary Rojewski 
17861b52df4SCezary Rojewski 	format_val = snd_hdac_spdif_stream_format(runtime->channels, bits, runtime->rate, ctls);
17905e84878SDylan Reid 	if (!format_val) {
18005e84878SDylan Reid 		dev_err(chip->card->dev,
18105e84878SDylan Reid 			"invalid format_val, rate=%d, ch=%d, format=%d\n",
18205e84878SDylan Reid 			runtime->rate, runtime->channels, runtime->format);
18305e84878SDylan Reid 		err = -EINVAL;
18405e84878SDylan Reid 		goto unlock;
18505e84878SDylan Reid 	}
18605e84878SDylan Reid 
1870dd76f36STakashi Iwai 	err = snd_hdac_stream_set_params(azx_stream(azx_dev), format_val);
18805e84878SDylan Reid 	if (err < 0)
18905e84878SDylan Reid 		goto unlock;
19005e84878SDylan Reid 
1915eb4ff88SCezary Rojewski 	snd_hdac_stream_setup(azx_stream(azx_dev), false);
19205e84878SDylan Reid 
1937833c3f8STakashi Iwai 	stream_tag = azx_dev->core.stream_tag;
19405e84878SDylan Reid 	/* CA-IBG chips need the playback stream starting from 1 */
19505e84878SDylan Reid 	if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) &&
19605e84878SDylan Reid 	    stream_tag > chip->capture_streams)
19705e84878SDylan Reid 		stream_tag -= chip->capture_streams;
19805e84878SDylan Reid 	err = snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
1997833c3f8STakashi Iwai 				     azx_dev->core.format_val, substream);
20005e84878SDylan Reid 
20105e84878SDylan Reid  unlock:
20205e84878SDylan Reid 	if (!err)
2036d23c8f5STakashi Iwai 		azx_stream(azx_dev)->prepared = 1;
20405e84878SDylan Reid 	dsp_unlock(azx_dev);
20505e84878SDylan Reid 	return err;
20605e84878SDylan Reid }
20705e84878SDylan Reid 
azx_pcm_trigger(struct snd_pcm_substream * substream,int cmd)20805e84878SDylan Reid static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
20905e84878SDylan Reid {
21005e84878SDylan Reid 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
21105e84878SDylan Reid 	struct azx *chip = apcm->chip;
212a41d1224STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
21305e84878SDylan Reid 	struct azx_dev *azx_dev;
21405e84878SDylan Reid 	struct snd_pcm_substream *s;
215ccc98865STakashi Iwai 	struct hdac_stream *hstr;
216ccc98865STakashi Iwai 	bool start;
217ccc98865STakashi Iwai 	int sbits = 0;
218ccc98865STakashi Iwai 	int sync_reg;
21905e84878SDylan Reid 
22005e84878SDylan Reid 	azx_dev = get_azx_dev(substream);
22143db4a59STakashi Iwai 	trace_azx_pcm_trigger(chip, azx_dev, cmd);
22243db4a59STakashi Iwai 
223ccc98865STakashi Iwai 	hstr = azx_stream(azx_dev);
224ccc98865STakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
225ccc98865STakashi Iwai 		sync_reg = AZX_REG_OLD_SSYNC;
226ccc98865STakashi Iwai 	else
227ccc98865STakashi Iwai 		sync_reg = AZX_REG_SSYNC;
22805e84878SDylan Reid 
2296d23c8f5STakashi Iwai 	if (dsp_is_locked(azx_dev) || !hstr->prepared)
23005e84878SDylan Reid 		return -EPIPE;
23105e84878SDylan Reid 
23205e84878SDylan Reid 	switch (cmd) {
23305e84878SDylan Reid 	case SNDRV_PCM_TRIGGER_START:
23405e84878SDylan Reid 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
23505e84878SDylan Reid 	case SNDRV_PCM_TRIGGER_RESUME:
236ccc98865STakashi Iwai 		start = true;
23705e84878SDylan Reid 		break;
23805e84878SDylan Reid 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
23905e84878SDylan Reid 	case SNDRV_PCM_TRIGGER_SUSPEND:
24005e84878SDylan Reid 	case SNDRV_PCM_TRIGGER_STOP:
241ccc98865STakashi Iwai 		start = false;
24205e84878SDylan Reid 		break;
24305e84878SDylan Reid 	default:
24405e84878SDylan Reid 		return -EINVAL;
24505e84878SDylan Reid 	}
24605e84878SDylan Reid 
24705e84878SDylan Reid 	snd_pcm_group_for_each_entry(s, substream) {
24805e84878SDylan Reid 		if (s->pcm->card != substream->pcm->card)
24905e84878SDylan Reid 			continue;
25005e84878SDylan Reid 		azx_dev = get_azx_dev(s);
2517833c3f8STakashi Iwai 		sbits |= 1 << azx_dev->core.index;
25205e84878SDylan Reid 		snd_pcm_trigger_done(s, substream);
25305e84878SDylan Reid 	}
25405e84878SDylan Reid 
255a41d1224STakashi Iwai 	spin_lock(&bus->reg_lock);
25605e84878SDylan Reid 
25705e84878SDylan Reid 	/* first, set SYNC bits of corresponding streams */
258ccc98865STakashi Iwai 	snd_hdac_stream_sync_trigger(hstr, true, sbits, sync_reg);
25905e84878SDylan Reid 
26005e84878SDylan Reid 	snd_pcm_group_for_each_entry(s, substream) {
26105e84878SDylan Reid 		if (s->pcm->card != substream->pcm->card)
26205e84878SDylan Reid 			continue;
26305e84878SDylan Reid 		azx_dev = get_azx_dev(s);
26405e84878SDylan Reid 		if (start) {
2657833c3f8STakashi Iwai 			azx_dev->insufficient = 1;
2664fe20d62SZhang Yiqun 			snd_hdac_stream_start(azx_stream(azx_dev));
26705e84878SDylan Reid 		} else {
2687833c3f8STakashi Iwai 			snd_hdac_stream_stop(azx_stream(azx_dev));
26905e84878SDylan Reid 		}
27005e84878SDylan Reid 	}
271a41d1224STakashi Iwai 	spin_unlock(&bus->reg_lock);
272ccc98865STakashi Iwai 
273ccc98865STakashi Iwai 	snd_hdac_stream_sync(hstr, start, sbits);
274ccc98865STakashi Iwai 
275a41d1224STakashi Iwai 	spin_lock(&bus->reg_lock);
27605e84878SDylan Reid 	/* reset SYNC bits */
277ccc98865STakashi Iwai 	snd_hdac_stream_sync_trigger(hstr, false, sbits, sync_reg);
278ccc98865STakashi Iwai 	if (start)
279ccc98865STakashi Iwai 		snd_hdac_stream_timecounter_init(hstr, sbits);
280a41d1224STakashi Iwai 	spin_unlock(&bus->reg_lock);
28105e84878SDylan Reid 	return 0;
28205e84878SDylan Reid }
28305e84878SDylan Reid 
azx_get_pos_lpib(struct azx * chip,struct azx_dev * azx_dev)284b6050ef6STakashi Iwai unsigned int azx_get_pos_lpib(struct azx *chip, struct azx_dev *azx_dev)
28505e84878SDylan Reid {
2867833c3f8STakashi Iwai 	return snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev));
28705e84878SDylan Reid }
288b6050ef6STakashi Iwai EXPORT_SYMBOL_GPL(azx_get_pos_lpib);
28905e84878SDylan Reid 
azx_get_pos_posbuf(struct azx * chip,struct azx_dev * azx_dev)290b6050ef6STakashi Iwai unsigned int azx_get_pos_posbuf(struct azx *chip, struct azx_dev *azx_dev)
291b6050ef6STakashi Iwai {
2927833c3f8STakashi Iwai 	return snd_hdac_stream_get_pos_posbuf(azx_stream(azx_dev));
29305e84878SDylan Reid }
294b6050ef6STakashi Iwai EXPORT_SYMBOL_GPL(azx_get_pos_posbuf);
29505e84878SDylan Reid 
azx_get_position(struct azx * chip,struct azx_dev * azx_dev)29605e84878SDylan Reid unsigned int azx_get_position(struct azx *chip,
297b6050ef6STakashi Iwai 			      struct azx_dev *azx_dev)
29805e84878SDylan Reid {
2997833c3f8STakashi Iwai 	struct snd_pcm_substream *substream = azx_dev->core.substream;
30005e84878SDylan Reid 	unsigned int pos;
30105e84878SDylan Reid 	int stream = substream->stream;
30205e84878SDylan Reid 	int delay = 0;
30305e84878SDylan Reid 
304b6050ef6STakashi Iwai 	if (chip->get_position[stream])
305b6050ef6STakashi Iwai 		pos = chip->get_position[stream](chip, azx_dev);
306b6050ef6STakashi Iwai 	else /* use the position buffer as default */
307b6050ef6STakashi Iwai 		pos = azx_get_pos_posbuf(chip, azx_dev);
30805e84878SDylan Reid 
3097833c3f8STakashi Iwai 	if (pos >= azx_dev->core.bufsize)
31005e84878SDylan Reid 		pos = 0;
31105e84878SDylan Reid 
31205e84878SDylan Reid 	if (substream->runtime) {
313b6050ef6STakashi Iwai 		struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
314820cc6cfSTakashi Iwai 		struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
315b6050ef6STakashi Iwai 
316b6050ef6STakashi Iwai 		if (chip->get_delay[stream])
317b6050ef6STakashi Iwai 			delay += chip->get_delay[stream](chip, azx_dev, pos);
31805e84878SDylan Reid 		if (hinfo->ops.get_delay)
31905e84878SDylan Reid 			delay += hinfo->ops.get_delay(hinfo, apcm->codec,
32005e84878SDylan Reid 						      substream);
32105e84878SDylan Reid 		substream->runtime->delay = delay;
32205e84878SDylan Reid 	}
32305e84878SDylan Reid 
32443db4a59STakashi Iwai 	trace_azx_get_position(chip, azx_dev, pos, delay);
32505e84878SDylan Reid 	return pos;
32605e84878SDylan Reid }
32705e84878SDylan Reid EXPORT_SYMBOL_GPL(azx_get_position);
32805e84878SDylan Reid 
azx_pcm_pointer(struct snd_pcm_substream * substream)32905e84878SDylan Reid static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
33005e84878SDylan Reid {
33105e84878SDylan Reid 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
33205e84878SDylan Reid 	struct azx *chip = apcm->chip;
33305e84878SDylan Reid 	struct azx_dev *azx_dev = get_azx_dev(substream);
33405e84878SDylan Reid 	return bytes_to_frames(substream->runtime,
335b6050ef6STakashi Iwai 			       azx_get_position(chip, azx_dev));
33605e84878SDylan Reid }
33705e84878SDylan Reid 
338bfcba288SGuneshwor Singh /*
339bfcba288SGuneshwor Singh  * azx_scale64: Scale base by mult/div while not overflowing sanely
340bfcba288SGuneshwor Singh  *
341bfcba288SGuneshwor Singh  * Derived from scale64_check_overflow in kernel/time/timekeeping.c
342bfcba288SGuneshwor Singh  *
343bfcba288SGuneshwor Singh  * The tmestamps for a 48Khz stream can overflow after (2^64/10^9)/48K which
344bfcba288SGuneshwor Singh  * is about 384307 ie ~4.5 days.
345bfcba288SGuneshwor Singh  *
346bfcba288SGuneshwor Singh  * This scales the calculation so that overflow will happen but after 2^64 /
347bfcba288SGuneshwor Singh  * 48000 secs, which is pretty large!
348bfcba288SGuneshwor Singh  *
349bfcba288SGuneshwor Singh  * In caln below:
350bfcba288SGuneshwor Singh  *	base may overflow, but since there isn’t any additional division
351bfcba288SGuneshwor Singh  *	performed on base it’s OK
352bfcba288SGuneshwor Singh  *	rem can’t overflow because both are 32-bit values
353bfcba288SGuneshwor Singh  */
354bfcba288SGuneshwor Singh 
355bfcba288SGuneshwor Singh #ifdef CONFIG_X86
azx_scale64(u64 base,u32 num,u32 den)356bfcba288SGuneshwor Singh static u64 azx_scale64(u64 base, u32 num, u32 den)
357bfcba288SGuneshwor Singh {
358bfcba288SGuneshwor Singh 	u64 rem;
359bfcba288SGuneshwor Singh 
360bfcba288SGuneshwor Singh 	rem = do_div(base, den);
361bfcba288SGuneshwor Singh 
362bfcba288SGuneshwor Singh 	base *= num;
363bfcba288SGuneshwor Singh 	rem *= num;
364bfcba288SGuneshwor Singh 
365bfcba288SGuneshwor Singh 	do_div(rem, den);
366bfcba288SGuneshwor Singh 
367bfcba288SGuneshwor Singh 	return base + rem;
368bfcba288SGuneshwor Singh }
369bfcba288SGuneshwor Singh 
azx_get_sync_time(ktime_t * device,struct system_counterval_t * system,void * ctx)370bfcba288SGuneshwor Singh static int azx_get_sync_time(ktime_t *device,
371bfcba288SGuneshwor Singh 		struct system_counterval_t *system, void *ctx)
372bfcba288SGuneshwor Singh {
373bfcba288SGuneshwor Singh 	struct snd_pcm_substream *substream = ctx;
374bfcba288SGuneshwor Singh 	struct azx_dev *azx_dev = get_azx_dev(substream);
375bfcba288SGuneshwor Singh 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
376bfcba288SGuneshwor Singh 	struct azx *chip = apcm->chip;
377bfcba288SGuneshwor Singh 	struct snd_pcm_runtime *runtime;
378bfcba288SGuneshwor Singh 	u64 ll_counter, ll_counter_l, ll_counter_h;
379bfcba288SGuneshwor Singh 	u64 tsc_counter, tsc_counter_l, tsc_counter_h;
380bfcba288SGuneshwor Singh 	u32 wallclk_ctr, wallclk_cycles;
381bfcba288SGuneshwor Singh 	bool direction;
382bfcba288SGuneshwor Singh 	u32 dma_select;
3834dca80b4SColin Ian King 	u32 timeout;
384bfcba288SGuneshwor Singh 	u32 retry_count = 0;
385bfcba288SGuneshwor Singh 
386bfcba288SGuneshwor Singh 	runtime = substream->runtime;
387bfcba288SGuneshwor Singh 
388bfcba288SGuneshwor Singh 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
389bfcba288SGuneshwor Singh 		direction = 1;
390bfcba288SGuneshwor Singh 	else
391bfcba288SGuneshwor Singh 		direction = 0;
392bfcba288SGuneshwor Singh 
393bfcba288SGuneshwor Singh 	/* 0th stream tag is not used, so DMA ch 0 is for 1st stream tag */
394bfcba288SGuneshwor Singh 	do {
395bfcba288SGuneshwor Singh 		timeout = 100;
396bfcba288SGuneshwor Singh 		dma_select = (direction << GTSCC_CDMAS_DMA_DIR_SHIFT) |
397bfcba288SGuneshwor Singh 					(azx_dev->core.stream_tag - 1);
398bfcba288SGuneshwor Singh 		snd_hdac_chip_writel(azx_bus(chip), GTSCC, dma_select);
399bfcba288SGuneshwor Singh 
400bfcba288SGuneshwor Singh 		/* Enable the capture */
401bfcba288SGuneshwor Singh 		snd_hdac_chip_updatel(azx_bus(chip), GTSCC, 0, GTSCC_TSCCI_MASK);
402bfcba288SGuneshwor Singh 
403bfcba288SGuneshwor Singh 		while (timeout) {
404bfcba288SGuneshwor Singh 			if (snd_hdac_chip_readl(azx_bus(chip), GTSCC) &
405bfcba288SGuneshwor Singh 						GTSCC_TSCCD_MASK)
406bfcba288SGuneshwor Singh 				break;
407bfcba288SGuneshwor Singh 
408bfcba288SGuneshwor Singh 			timeout--;
409bfcba288SGuneshwor Singh 		}
410bfcba288SGuneshwor Singh 
411bfcba288SGuneshwor Singh 		if (!timeout) {
412bfcba288SGuneshwor Singh 			dev_err(chip->card->dev, "GTSCC capture Timedout!\n");
413bfcba288SGuneshwor Singh 			return -EIO;
414bfcba288SGuneshwor Singh 		}
415bfcba288SGuneshwor Singh 
416bfcba288SGuneshwor Singh 		/* Read wall clock counter */
417bfcba288SGuneshwor Singh 		wallclk_ctr = snd_hdac_chip_readl(azx_bus(chip), WALFCC);
418bfcba288SGuneshwor Singh 
419bfcba288SGuneshwor Singh 		/* Read TSC counter */
420bfcba288SGuneshwor Singh 		tsc_counter_l = snd_hdac_chip_readl(azx_bus(chip), TSCCL);
421bfcba288SGuneshwor Singh 		tsc_counter_h = snd_hdac_chip_readl(azx_bus(chip), TSCCU);
422bfcba288SGuneshwor Singh 
423bfcba288SGuneshwor Singh 		/* Read Link counter */
424bfcba288SGuneshwor Singh 		ll_counter_l = snd_hdac_chip_readl(azx_bus(chip), LLPCL);
425bfcba288SGuneshwor Singh 		ll_counter_h = snd_hdac_chip_readl(azx_bus(chip), LLPCU);
426bfcba288SGuneshwor Singh 
427bfcba288SGuneshwor Singh 		/* Ack: registers read done */
428bfcba288SGuneshwor Singh 		snd_hdac_chip_writel(azx_bus(chip), GTSCC, GTSCC_TSCCD_SHIFT);
429bfcba288SGuneshwor Singh 
430bfcba288SGuneshwor Singh 		tsc_counter = (tsc_counter_h << TSCCU_CCU_SHIFT) |
431bfcba288SGuneshwor Singh 						tsc_counter_l;
432bfcba288SGuneshwor Singh 
433bfcba288SGuneshwor Singh 		ll_counter = (ll_counter_h << LLPC_CCU_SHIFT) |	ll_counter_l;
434bfcba288SGuneshwor Singh 		wallclk_cycles = wallclk_ctr & WALFCC_CIF_MASK;
435bfcba288SGuneshwor Singh 
436bfcba288SGuneshwor Singh 		/*
437bfcba288SGuneshwor Singh 		 * An error occurs near frame "rollover". The clocks in
438bfcba288SGuneshwor Singh 		 * frame value indicates whether this error may have
439bfcba288SGuneshwor Singh 		 * occurred. Here we use the value of 10 i.e.,
440bfcba288SGuneshwor Singh 		 * HDA_MAX_CYCLE_OFFSET
441bfcba288SGuneshwor Singh 		 */
442bfcba288SGuneshwor Singh 		if (wallclk_cycles < HDA_MAX_CYCLE_VALUE - HDA_MAX_CYCLE_OFFSET
443bfcba288SGuneshwor Singh 					&& wallclk_cycles > HDA_MAX_CYCLE_OFFSET)
444bfcba288SGuneshwor Singh 			break;
445bfcba288SGuneshwor Singh 
446bfcba288SGuneshwor Singh 		/*
447bfcba288SGuneshwor Singh 		 * Sleep before we read again, else we may again get
448bfcba288SGuneshwor Singh 		 * value near to MAX_CYCLE. Try to sleep for different
449bfcba288SGuneshwor Singh 		 * amount of time so we dont hit the same number again
450bfcba288SGuneshwor Singh 		 */
451bfcba288SGuneshwor Singh 		udelay(retry_count++);
452bfcba288SGuneshwor Singh 
453bfcba288SGuneshwor Singh 	} while (retry_count != HDA_MAX_CYCLE_READ_RETRY);
454bfcba288SGuneshwor Singh 
455bfcba288SGuneshwor Singh 	if (retry_count == HDA_MAX_CYCLE_READ_RETRY) {
456bfcba288SGuneshwor Singh 		dev_err_ratelimited(chip->card->dev,
457bfcba288SGuneshwor Singh 			"Error in WALFCC cycle count\n");
458bfcba288SGuneshwor Singh 		return -EIO;
459bfcba288SGuneshwor Singh 	}
460bfcba288SGuneshwor Singh 
461bfcba288SGuneshwor Singh 	*device = ns_to_ktime(azx_scale64(ll_counter,
462bfcba288SGuneshwor Singh 				NSEC_PER_SEC, runtime->rate));
463bfcba288SGuneshwor Singh 	*device = ktime_add_ns(*device, (wallclk_cycles * NSEC_PER_SEC) /
464bfcba288SGuneshwor Singh 			       ((HDA_MAX_CYCLE_VALUE + 1) * runtime->rate));
465bfcba288SGuneshwor Singh 
466bfcba288SGuneshwor Singh 	*system = convert_art_to_tsc(tsc_counter);
467bfcba288SGuneshwor Singh 
468bfcba288SGuneshwor Singh 	return 0;
469bfcba288SGuneshwor Singh }
470bfcba288SGuneshwor Singh 
471bfcba288SGuneshwor Singh #else
azx_get_sync_time(ktime_t * device,struct system_counterval_t * system,void * ctx)472bfcba288SGuneshwor Singh static int azx_get_sync_time(ktime_t *device,
473bfcba288SGuneshwor Singh 		struct system_counterval_t *system, void *ctx)
474bfcba288SGuneshwor Singh {
475bfcba288SGuneshwor Singh 	return -ENXIO;
476bfcba288SGuneshwor Singh }
477bfcba288SGuneshwor Singh #endif
478bfcba288SGuneshwor Singh 
azx_get_crosststamp(struct snd_pcm_substream * substream,struct system_device_crosststamp * xtstamp)479bfcba288SGuneshwor Singh static int azx_get_crosststamp(struct snd_pcm_substream *substream,
480bfcba288SGuneshwor Singh 			      struct system_device_crosststamp *xtstamp)
481bfcba288SGuneshwor Singh {
482bfcba288SGuneshwor Singh 	return get_device_system_crosststamp(azx_get_sync_time,
483bfcba288SGuneshwor Singh 					substream, NULL, xtstamp);
484bfcba288SGuneshwor Singh }
485bfcba288SGuneshwor Singh 
is_link_time_supported(struct snd_pcm_runtime * runtime,struct snd_pcm_audio_tstamp_config * ts)486bfcba288SGuneshwor Singh static inline bool is_link_time_supported(struct snd_pcm_runtime *runtime,
487bfcba288SGuneshwor Singh 				struct snd_pcm_audio_tstamp_config *ts)
488bfcba288SGuneshwor Singh {
489bfcba288SGuneshwor Singh 	if (runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME)
490bfcba288SGuneshwor Singh 		if (ts->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED)
491bfcba288SGuneshwor Singh 			return true;
492bfcba288SGuneshwor Singh 
493bfcba288SGuneshwor Singh 	return false;
494bfcba288SGuneshwor Singh }
495bfcba288SGuneshwor Singh 
azx_get_time_info(struct snd_pcm_substream * substream,struct timespec64 * system_ts,struct timespec64 * audio_ts,struct snd_pcm_audio_tstamp_config * audio_tstamp_config,struct snd_pcm_audio_tstamp_report * audio_tstamp_report)4969e94df3aSPierre-Louis Bossart static int azx_get_time_info(struct snd_pcm_substream *substream,
497fcae40c9SBaolin Wang 			struct timespec64 *system_ts, struct timespec64 *audio_ts,
4989e94df3aSPierre-Louis Bossart 			struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
4999e94df3aSPierre-Louis Bossart 			struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
50005e84878SDylan Reid {
50105e84878SDylan Reid 	struct azx_dev *azx_dev = get_azx_dev(substream);
502bfcba288SGuneshwor Singh 	struct snd_pcm_runtime *runtime = substream->runtime;
503bfcba288SGuneshwor Singh 	struct system_device_crosststamp xtstamp;
504bfcba288SGuneshwor Singh 	int ret;
50505e84878SDylan Reid 	u64 nsec;
50605e84878SDylan Reid 
5079e94df3aSPierre-Louis Bossart 	if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) &&
5089e94df3aSPierre-Louis Bossart 		(audio_tstamp_config->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK)) {
5099e94df3aSPierre-Louis Bossart 
5109e94df3aSPierre-Louis Bossart 		snd_pcm_gettime(substream->runtime, system_ts);
5119e94df3aSPierre-Louis Bossart 
5127833c3f8STakashi Iwai 		nsec = timecounter_read(&azx_dev->core.tc);
5139e94df3aSPierre-Louis Bossart 		if (audio_tstamp_config->report_delay)
51405e84878SDylan Reid 			nsec = azx_adjust_codec_delay(substream, nsec);
51505e84878SDylan Reid 
516fcae40c9SBaolin Wang 		*audio_ts = ns_to_timespec64(nsec);
5179e94df3aSPierre-Louis Bossart 
5189e94df3aSPierre-Louis Bossart 		audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK;
5199e94df3aSPierre-Louis Bossart 		audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */
5209e94df3aSPierre-Louis Bossart 		audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */
5219e94df3aSPierre-Louis Bossart 
522bfcba288SGuneshwor Singh 	} else if (is_link_time_supported(runtime, audio_tstamp_config)) {
523bfcba288SGuneshwor Singh 
524bfcba288SGuneshwor Singh 		ret = azx_get_crosststamp(substream, &xtstamp);
525bfcba288SGuneshwor Singh 		if (ret)
526bfcba288SGuneshwor Singh 			return ret;
527bfcba288SGuneshwor Singh 
528bfcba288SGuneshwor Singh 		switch (runtime->tstamp_type) {
529bfcba288SGuneshwor Singh 		case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC:
530bfcba288SGuneshwor Singh 			return -EINVAL;
531bfcba288SGuneshwor Singh 
532bfcba288SGuneshwor Singh 		case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW:
533fcae40c9SBaolin Wang 			*system_ts = ktime_to_timespec64(xtstamp.sys_monoraw);
534bfcba288SGuneshwor Singh 			break;
535bfcba288SGuneshwor Singh 
536bfcba288SGuneshwor Singh 		default:
537fcae40c9SBaolin Wang 			*system_ts = ktime_to_timespec64(xtstamp.sys_realtime);
538bfcba288SGuneshwor Singh 			break;
539bfcba288SGuneshwor Singh 
540bfcba288SGuneshwor Singh 		}
541bfcba288SGuneshwor Singh 
542fcae40c9SBaolin Wang 		*audio_ts = ktime_to_timespec64(xtstamp.device);
543bfcba288SGuneshwor Singh 
544bfcba288SGuneshwor Singh 		audio_tstamp_report->actual_type =
545bfcba288SGuneshwor Singh 			SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED;
546bfcba288SGuneshwor Singh 		audio_tstamp_report->accuracy_report = 1;
547bfcba288SGuneshwor Singh 		/* 24 MHz WallClock == 42ns resolution */
548bfcba288SGuneshwor Singh 		audio_tstamp_report->accuracy = 42;
549bfcba288SGuneshwor Singh 
550bfcba288SGuneshwor Singh 	} else {
5519e94df3aSPierre-Louis Bossart 		audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
552bfcba288SGuneshwor Singh 	}
55305e84878SDylan Reid 
55405e84878SDylan Reid 	return 0;
55505e84878SDylan Reid }
55605e84878SDylan Reid 
557c56fc8c9SJulia Lawall static const struct snd_pcm_hardware azx_pcm_hw = {
55805e84878SDylan Reid 	.info =			(SNDRV_PCM_INFO_MMAP |
55905e84878SDylan Reid 				 SNDRV_PCM_INFO_INTERLEAVED |
56005e84878SDylan Reid 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
56105e84878SDylan Reid 				 SNDRV_PCM_INFO_MMAP_VALID |
56205e84878SDylan Reid 				 /* No full-resume yet implemented */
56305e84878SDylan Reid 				 /* SNDRV_PCM_INFO_RESUME |*/
56405e84878SDylan Reid 				 SNDRV_PCM_INFO_PAUSE |
56505e84878SDylan Reid 				 SNDRV_PCM_INFO_SYNC_START |
5669e94df3aSPierre-Louis Bossart 				 SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */
5679e94df3aSPierre-Louis Bossart 				 SNDRV_PCM_INFO_HAS_LINK_ATIME |
56805e84878SDylan Reid 				 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
56905e84878SDylan Reid 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
57005e84878SDylan Reid 	.rates =		SNDRV_PCM_RATE_48000,
57105e84878SDylan Reid 	.rate_min =		48000,
57205e84878SDylan Reid 	.rate_max =		48000,
57305e84878SDylan Reid 	.channels_min =		2,
57405e84878SDylan Reid 	.channels_max =		2,
57505e84878SDylan Reid 	.buffer_bytes_max =	AZX_MAX_BUF_SIZE,
57605e84878SDylan Reid 	.period_bytes_min =	128,
57705e84878SDylan Reid 	.period_bytes_max =	AZX_MAX_BUF_SIZE / 2,
57805e84878SDylan Reid 	.periods_min =		2,
57905e84878SDylan Reid 	.periods_max =		AZX_MAX_FRAG,
58005e84878SDylan Reid 	.fifo_size =		0,
58105e84878SDylan Reid };
58205e84878SDylan Reid 
azx_pcm_open(struct snd_pcm_substream * substream)58305e84878SDylan Reid static int azx_pcm_open(struct snd_pcm_substream *substream)
58405e84878SDylan Reid {
58505e84878SDylan Reid 	struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
586820cc6cfSTakashi Iwai 	struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
58705e84878SDylan Reid 	struct azx *chip = apcm->chip;
58805e84878SDylan Reid 	struct azx_dev *azx_dev;
58905e84878SDylan Reid 	struct snd_pcm_runtime *runtime = substream->runtime;
59005e84878SDylan Reid 	int err;
59105e84878SDylan Reid 	int buff_step;
59205e84878SDylan Reid 
5939a6246ffSTakashi Iwai 	snd_hda_codec_pcm_get(apcm->info);
59405e84878SDylan Reid 	mutex_lock(&chip->open_mutex);
59505e84878SDylan Reid 	azx_dev = azx_assign_device(chip, substream);
59618486508SLibin Yang 	trace_azx_pcm_open(chip, azx_dev);
59705e84878SDylan Reid 	if (azx_dev == NULL) {
59861ca4107STakashi Iwai 		err = -EBUSY;
59961ca4107STakashi Iwai 		goto unlock;
60005e84878SDylan Reid 	}
601ccc98865STakashi Iwai 	runtime->private_data = azx_dev;
60250279d9bSGuneshwor Singh 
60305e84878SDylan Reid 	runtime->hw = azx_pcm_hw;
604c1c6c877STakashi Iwai 	if (chip->gts_present)
605c1c6c877STakashi Iwai 		runtime->hw.info |= SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME;
60605e84878SDylan Reid 	runtime->hw.channels_min = hinfo->channels_min;
60705e84878SDylan Reid 	runtime->hw.channels_max = hinfo->channels_max;
60805e84878SDylan Reid 	runtime->hw.formats = hinfo->formats;
60905e84878SDylan Reid 	runtime->hw.rates = hinfo->rates;
61005e84878SDylan Reid 	snd_pcm_limit_hw_rates(runtime);
61105e84878SDylan Reid 	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
61205e84878SDylan Reid 
61305e84878SDylan Reid 	/* avoid wrap-around with wall-clock */
61405e84878SDylan Reid 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME,
61505e84878SDylan Reid 				     20,
61605e84878SDylan Reid 				     178000000);
61705e84878SDylan Reid 
61805e84878SDylan Reid 	if (chip->align_buffer_size)
61905e84878SDylan Reid 		/* constrain buffer sizes to be multiple of 128
62005e84878SDylan Reid 		   bytes. This is more efficient in terms of memory
62105e84878SDylan Reid 		   access but isn't required by the HDA spec and
62205e84878SDylan Reid 		   prevents users from specifying exact period/buffer
62305e84878SDylan Reid 		   sizes. For example for 44.1kHz, a period size set
62405e84878SDylan Reid 		   to 20ms will be rounded to 19.59ms. */
62505e84878SDylan Reid 		buff_step = 128;
62605e84878SDylan Reid 	else
62705e84878SDylan Reid 		/* Don't enforce steps on buffer sizes, still need to
62805e84878SDylan Reid 		   be multiple of 4 bytes (HDA spec). Tested on Intel
62905e84878SDylan Reid 		   HDA controllers, may not work on all devices where
63005e84878SDylan Reid 		   option needs to be disabled */
63105e84878SDylan Reid 		buff_step = 4;
63205e84878SDylan Reid 
63305e84878SDylan Reid 	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
63405e84878SDylan Reid 				   buff_step);
63505e84878SDylan Reid 	snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
63605e84878SDylan Reid 				   buff_step);
637cc72da7dSTakashi Iwai 	snd_hda_power_up(apcm->codec);
63861ca4107STakashi Iwai 	if (hinfo->ops.open)
63905e84878SDylan Reid 		err = hinfo->ops.open(hinfo, apcm->codec, substream);
64061ca4107STakashi Iwai 	else
64161ca4107STakashi Iwai 		err = -ENODEV;
64205e84878SDylan Reid 	if (err < 0) {
64305e84878SDylan Reid 		azx_release_device(azx_dev);
64461ca4107STakashi Iwai 		goto powerdown;
64505e84878SDylan Reid 	}
64605e84878SDylan Reid 	snd_pcm_limit_hw_rates(runtime);
64705e84878SDylan Reid 	/* sanity check */
64805e84878SDylan Reid 	if (snd_BUG_ON(!runtime->hw.channels_min) ||
64905e84878SDylan Reid 	    snd_BUG_ON(!runtime->hw.channels_max) ||
65005e84878SDylan Reid 	    snd_BUG_ON(!runtime->hw.formats) ||
65105e84878SDylan Reid 	    snd_BUG_ON(!runtime->hw.rates)) {
65205e84878SDylan Reid 		azx_release_device(azx_dev);
65361ca4107STakashi Iwai 		if (hinfo->ops.close)
65405e84878SDylan Reid 			hinfo->ops.close(hinfo, apcm->codec, substream);
65561ca4107STakashi Iwai 		err = -EINVAL;
65661ca4107STakashi Iwai 		goto powerdown;
65705e84878SDylan Reid 	}
65805e84878SDylan Reid 
6599e94df3aSPierre-Louis Bossart 	/* disable LINK_ATIME timestamps for capture streams
66005e84878SDylan Reid 	   until we figure out how to handle digital inputs */
6619e94df3aSPierre-Louis Bossart 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
6629e94df3aSPierre-Louis Bossart 		runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */
6639e94df3aSPierre-Louis Bossart 		runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME;
6649e94df3aSPierre-Louis Bossart 	}
66505e84878SDylan Reid 
66605e84878SDylan Reid 	snd_pcm_set_sync(substream);
66705e84878SDylan Reid 	mutex_unlock(&chip->open_mutex);
66805e84878SDylan Reid 	return 0;
66961ca4107STakashi Iwai 
67061ca4107STakashi Iwai  powerdown:
67161ca4107STakashi Iwai 	snd_hda_power_down(apcm->codec);
67261ca4107STakashi Iwai  unlock:
67361ca4107STakashi Iwai 	mutex_unlock(&chip->open_mutex);
6749a6246ffSTakashi Iwai 	snd_hda_codec_pcm_put(apcm->info);
67561ca4107STakashi Iwai 	return err;
67605e84878SDylan Reid }
67705e84878SDylan Reid 
6786769e988SJulia Lawall static const struct snd_pcm_ops azx_pcm_ops = {
67905e84878SDylan Reid 	.open = azx_pcm_open,
68005e84878SDylan Reid 	.close = azx_pcm_close,
68105e84878SDylan Reid 	.hw_params = azx_pcm_hw_params,
68205e84878SDylan Reid 	.hw_free = azx_pcm_hw_free,
68305e84878SDylan Reid 	.prepare = azx_pcm_prepare,
68405e84878SDylan Reid 	.trigger = azx_pcm_trigger,
68505e84878SDylan Reid 	.pointer = azx_pcm_pointer,
6869e94df3aSPierre-Louis Bossart 	.get_time_info =  azx_get_time_info,
68705e84878SDylan Reid };
68805e84878SDylan Reid 
azx_pcm_free(struct snd_pcm * pcm)68905e84878SDylan Reid static void azx_pcm_free(struct snd_pcm *pcm)
69005e84878SDylan Reid {
69105e84878SDylan Reid 	struct azx_pcm *apcm = pcm->private_data;
69205e84878SDylan Reid 	if (apcm) {
69305e84878SDylan Reid 		list_del(&apcm->list);
694820cc6cfSTakashi Iwai 		apcm->info->pcm = NULL;
69505e84878SDylan Reid 		kfree(apcm);
69605e84878SDylan Reid 	}
69705e84878SDylan Reid }
69805e84878SDylan Reid 
69905e84878SDylan Reid #define MAX_PREALLOC_SIZE	(32 * 1024 * 1024)
70005e84878SDylan Reid 
snd_hda_attach_pcm_stream(struct hda_bus * _bus,struct hda_codec * codec,struct hda_pcm * cpcm)7010a50575bSTakashi Iwai int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec,
70205e84878SDylan Reid 			      struct hda_pcm *cpcm)
70305e84878SDylan Reid {
704a41d1224STakashi Iwai 	struct hdac_bus *bus = &_bus->core;
705a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(bus);
70605e84878SDylan Reid 	struct snd_pcm *pcm;
70705e84878SDylan Reid 	struct azx_pcm *apcm;
70805e84878SDylan Reid 	int pcm_dev = cpcm->device;
70905e84878SDylan Reid 	unsigned int size;
71005e84878SDylan Reid 	int s, err;
711fc478143STakashi Iwai 	int type = SNDRV_DMA_TYPE_DEV_SG;
71205e84878SDylan Reid 
71305e84878SDylan Reid 	list_for_each_entry(apcm, &chip->pcm_list, list) {
71405e84878SDylan Reid 		if (apcm->pcm->device == pcm_dev) {
71505e84878SDylan Reid 			dev_err(chip->card->dev, "PCM %d already exists\n",
71605e84878SDylan Reid 				pcm_dev);
71705e84878SDylan Reid 			return -EBUSY;
71805e84878SDylan Reid 		}
71905e84878SDylan Reid 	}
72005e84878SDylan Reid 	err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
72105e84878SDylan Reid 			  cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams,
72205e84878SDylan Reid 			  cpcm->stream[SNDRV_PCM_STREAM_CAPTURE].substreams,
72305e84878SDylan Reid 			  &pcm);
72405e84878SDylan Reid 	if (err < 0)
72505e84878SDylan Reid 		return err;
72675b1a8f9SJoe Perches 	strscpy(pcm->name, cpcm->name, sizeof(pcm->name));
72705e84878SDylan Reid 	apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
728a3aa60d5SBo Chen 	if (apcm == NULL) {
729a3aa60d5SBo Chen 		snd_device_free(chip->card, pcm);
73005e84878SDylan Reid 		return -ENOMEM;
731a3aa60d5SBo Chen 	}
73205e84878SDylan Reid 	apcm->chip = chip;
73305e84878SDylan Reid 	apcm->pcm = pcm;
73405e84878SDylan Reid 	apcm->codec = codec;
735820cc6cfSTakashi Iwai 	apcm->info = cpcm;
73605e84878SDylan Reid 	pcm->private_data = apcm;
73705e84878SDylan Reid 	pcm->private_free = azx_pcm_free;
73805e84878SDylan Reid 	if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM)
73905e84878SDylan Reid 		pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
74005e84878SDylan Reid 	list_add_tail(&apcm->list, &chip->pcm_list);
74105e84878SDylan Reid 	cpcm->pcm = pcm;
74205e84878SDylan Reid 	for (s = 0; s < 2; s++) {
74305e84878SDylan Reid 		if (cpcm->stream[s].substreams)
74405e84878SDylan Reid 			snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
74505e84878SDylan Reid 	}
74605e84878SDylan Reid 	/* buffer pre-allocation */
74705e84878SDylan Reid 	size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
74805e84878SDylan Reid 	if (size > MAX_PREALLOC_SIZE)
74905e84878SDylan Reid 		size = MAX_PREALLOC_SIZE;
750fc478143STakashi Iwai 	if (chip->uc_buffer)
75158a95dfaSTakashi Iwai 		type = SNDRV_DMA_TYPE_DEV_WC_SG;
7527a6d4a5aSTakashi Iwai 	snd_pcm_set_managed_buffer_all(pcm, type, chip->card->dev,
75305e84878SDylan Reid 				       size, MAX_PREALLOC_SIZE);
75405e84878SDylan Reid 	return 0;
75505e84878SDylan Reid }
75605e84878SDylan Reid 
azx_command_addr(u32 cmd)7576e85dddcSDylan Reid static unsigned int azx_command_addr(u32 cmd)
7586e85dddcSDylan Reid {
7596e85dddcSDylan Reid 	unsigned int addr = cmd >> 28;
7606e85dddcSDylan Reid 
7616e85dddcSDylan Reid 	if (addr >= AZX_MAX_CODECS) {
7626e85dddcSDylan Reid 		snd_BUG();
7636e85dddcSDylan Reid 		addr = 0;
7646e85dddcSDylan Reid 	}
7656e85dddcSDylan Reid 
7666e85dddcSDylan Reid 	return addr;
7676e85dddcSDylan Reid }
7686e85dddcSDylan Reid 
7696e85dddcSDylan Reid /* receive a response */
azx_rirb_get_response(struct hdac_bus * bus,unsigned int addr,unsigned int * res)770a41d1224STakashi Iwai static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
771cad372f1STakashi Iwai 				 unsigned int *res)
7726e85dddcSDylan Reid {
773a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(bus);
774a41d1224STakashi Iwai 	struct hda_bus *hbus = &chip->bus;
7755f2cb361STakashi Iwai 	int err;
7766e85dddcSDylan Reid 
7776e85dddcSDylan Reid  again:
7785f2cb361STakashi Iwai 	err = snd_hdac_bus_get_response(bus, addr, res);
7795f2cb361STakashi Iwai 	if (!err)
780cad372f1STakashi Iwai 		return 0;
78188452da9STakashi Iwai 
782a41d1224STakashi Iwai 	if (hbus->no_response_fallback)
783cad372f1STakashi Iwai 		return -EIO;
7846e85dddcSDylan Reid 
7858af42130SBard Liao 	if (!bus->polling_mode) {
7866e85dddcSDylan Reid 		dev_warn(chip->card->dev,
7876e85dddcSDylan Reid 			 "azx_get_response timeout, switching to polling mode: last cmd=0x%08x\n",
788a41d1224STakashi Iwai 			 bus->last_cmd[addr]);
7898af42130SBard Liao 		bus->polling_mode = 1;
7906e85dddcSDylan Reid 		goto again;
7916e85dddcSDylan Reid 	}
7926e85dddcSDylan Reid 
7936e85dddcSDylan Reid 	if (chip->msi) {
7946e85dddcSDylan Reid 		dev_warn(chip->card->dev,
7956e85dddcSDylan Reid 			 "No response from codec, disabling MSI: last cmd=0x%08x\n",
796a41d1224STakashi Iwai 			 bus->last_cmd[addr]);
797a41d1224STakashi Iwai 		if (chip->ops->disable_msi_reset_irq &&
798cad372f1STakashi Iwai 		    chip->ops->disable_msi_reset_irq(chip) < 0)
799cad372f1STakashi Iwai 			return -EIO;
8006e85dddcSDylan Reid 		goto again;
8016e85dddcSDylan Reid 	}
8026e85dddcSDylan Reid 
8036e85dddcSDylan Reid 	if (chip->probing) {
8046e85dddcSDylan Reid 		/* If this critical timeout happens during the codec probing
8056e85dddcSDylan Reid 		 * phase, this is likely an access to a non-existing codec
8066e85dddcSDylan Reid 		 * slot.  Better to return an error and reset the system.
8076e85dddcSDylan Reid 		 */
808cad372f1STakashi Iwai 		return -EIO;
8096e85dddcSDylan Reid 	}
8106e85dddcSDylan Reid 
81141438f13STakashi Iwai 	/* no fallback mechanism? */
81241438f13STakashi Iwai 	if (!chip->fallback_to_single_cmd)
81341438f13STakashi Iwai 		return -EIO;
81441438f13STakashi Iwai 
8156e85dddcSDylan Reid 	/* a fatal communication error; need either to reset or to fallback
8166e85dddcSDylan Reid 	 * to the single_cmd mode
8176e85dddcSDylan Reid 	 */
818a41d1224STakashi Iwai 	if (hbus->allow_bus_reset && !hbus->response_reset && !hbus->in_reset) {
819a41d1224STakashi Iwai 		hbus->response_reset = 1;
820dd65f7e1STakashi Iwai 		dev_err(chip->card->dev,
821dd65f7e1STakashi Iwai 			"No response from codec, resetting bus: last cmd=0x%08x\n",
822dd65f7e1STakashi Iwai 			bus->last_cmd[addr]);
823cad372f1STakashi Iwai 		return -EAGAIN; /* give a chance to retry */
8246e85dddcSDylan Reid 	}
8256e85dddcSDylan Reid 
826475feec0STakashi Iwai 	dev_err(chip->card->dev,
8276e85dddcSDylan Reid 		"azx_get_response timeout, switching to single_cmd mode: last cmd=0x%08x\n",
828a41d1224STakashi Iwai 		bus->last_cmd[addr]);
8296e85dddcSDylan Reid 	chip->single_cmd = 1;
830a41d1224STakashi Iwai 	hbus->response_reset = 0;
831a41d1224STakashi Iwai 	snd_hdac_bus_stop_cmd_io(bus);
832cad372f1STakashi Iwai 	return -EIO;
8336e85dddcSDylan Reid }
8346e85dddcSDylan Reid 
8356e85dddcSDylan Reid /*
8366e85dddcSDylan Reid  * Use the single immediate command instead of CORB/RIRB for simplicity
8376e85dddcSDylan Reid  *
8386e85dddcSDylan Reid  * Note: according to Intel, this is not preferred use.  The command was
8396e85dddcSDylan Reid  *       intended for the BIOS only, and may get confused with unsolicited
8406e85dddcSDylan Reid  *       responses.  So, we shouldn't use it for normal operation from the
8416e85dddcSDylan Reid  *       driver.
8426e85dddcSDylan Reid  *       I left the codes, however, for debugging/testing purposes.
8436e85dddcSDylan Reid  */
8446e85dddcSDylan Reid 
8456e85dddcSDylan Reid /* receive a response */
azx_single_wait_for_response(struct azx * chip,unsigned int addr)8466e85dddcSDylan Reid static int azx_single_wait_for_response(struct azx *chip, unsigned int addr)
8476e85dddcSDylan Reid {
8486e85dddcSDylan Reid 	int timeout = 50;
8496e85dddcSDylan Reid 
8506e85dddcSDylan Reid 	while (timeout--) {
8516e85dddcSDylan Reid 		/* check IRV busy bit */
852fb1d8ac2STakashi Iwai 		if (azx_readw(chip, IRS) & AZX_IRS_VALID) {
8536e85dddcSDylan Reid 			/* reuse rirb.res as the response return value */
854a41d1224STakashi Iwai 			azx_bus(chip)->rirb.res[addr] = azx_readl(chip, IR);
8556e85dddcSDylan Reid 			return 0;
8566e85dddcSDylan Reid 		}
8576e85dddcSDylan Reid 		udelay(1);
8586e85dddcSDylan Reid 	}
8596e85dddcSDylan Reid 	if (printk_ratelimit())
8606e85dddcSDylan Reid 		dev_dbg(chip->card->dev, "get_response timeout: IRS=0x%x\n",
8616e85dddcSDylan Reid 			azx_readw(chip, IRS));
862a41d1224STakashi Iwai 	azx_bus(chip)->rirb.res[addr] = -1;
8636e85dddcSDylan Reid 	return -EIO;
8646e85dddcSDylan Reid }
8656e85dddcSDylan Reid 
8666e85dddcSDylan Reid /* send a command */
azx_single_send_cmd(struct hdac_bus * bus,u32 val)867a41d1224STakashi Iwai static int azx_single_send_cmd(struct hdac_bus *bus, u32 val)
8686e85dddcSDylan Reid {
869a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(bus);
8706e85dddcSDylan Reid 	unsigned int addr = azx_command_addr(val);
8716e85dddcSDylan Reid 	int timeout = 50;
8726e85dddcSDylan Reid 
873a41d1224STakashi Iwai 	bus->last_cmd[azx_command_addr(val)] = val;
8746e85dddcSDylan Reid 	while (timeout--) {
8756e85dddcSDylan Reid 		/* check ICB busy bit */
876fb1d8ac2STakashi Iwai 		if (!((azx_readw(chip, IRS) & AZX_IRS_BUSY))) {
8776e85dddcSDylan Reid 			/* Clear IRV valid bit */
8786e85dddcSDylan Reid 			azx_writew(chip, IRS, azx_readw(chip, IRS) |
879fb1d8ac2STakashi Iwai 				   AZX_IRS_VALID);
8806e85dddcSDylan Reid 			azx_writel(chip, IC, val);
8816e85dddcSDylan Reid 			azx_writew(chip, IRS, azx_readw(chip, IRS) |
882fb1d8ac2STakashi Iwai 				   AZX_IRS_BUSY);
8836e85dddcSDylan Reid 			return azx_single_wait_for_response(chip, addr);
8846e85dddcSDylan Reid 		}
8856e85dddcSDylan Reid 		udelay(1);
8866e85dddcSDylan Reid 	}
8876e85dddcSDylan Reid 	if (printk_ratelimit())
8886e85dddcSDylan Reid 		dev_dbg(chip->card->dev,
8896e85dddcSDylan Reid 			"send_cmd timeout: IRS=0x%x, val=0x%x\n",
8906e85dddcSDylan Reid 			azx_readw(chip, IRS), val);
8916e85dddcSDylan Reid 	return -EIO;
8926e85dddcSDylan Reid }
8936e85dddcSDylan Reid 
8946e85dddcSDylan Reid /* receive a response */
azx_single_get_response(struct hdac_bus * bus,unsigned int addr,unsigned int * res)895a41d1224STakashi Iwai static int azx_single_get_response(struct hdac_bus *bus, unsigned int addr,
896cad372f1STakashi Iwai 				   unsigned int *res)
8976e85dddcSDylan Reid {
898cad372f1STakashi Iwai 	if (res)
899a41d1224STakashi Iwai 		*res = bus->rirb.res[addr];
900cad372f1STakashi Iwai 	return 0;
9016e85dddcSDylan Reid }
9026e85dddcSDylan Reid 
9036e85dddcSDylan Reid /*
9046e85dddcSDylan Reid  * The below are the main callbacks from hda_codec.
9056e85dddcSDylan Reid  *
9066e85dddcSDylan Reid  * They are just the skeleton to call sub-callbacks according to the
9076e85dddcSDylan Reid  * current setting of chip->single_cmd.
9086e85dddcSDylan Reid  */
9096e85dddcSDylan Reid 
9106e85dddcSDylan Reid /* send a command */
azx_send_cmd(struct hdac_bus * bus,unsigned int val)911a41d1224STakashi Iwai static int azx_send_cmd(struct hdac_bus *bus, unsigned int val)
9126e85dddcSDylan Reid {
913a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(bus);
9146e85dddcSDylan Reid 
9156e85dddcSDylan Reid 	if (chip->disabled)
9166e85dddcSDylan Reid 		return 0;
917b13593e3SPeter Ujfalusi 	if (chip->single_cmd || bus->use_pio_for_commands)
9186e85dddcSDylan Reid 		return azx_single_send_cmd(bus, val);
9196e85dddcSDylan Reid 	else
920a41d1224STakashi Iwai 		return snd_hdac_bus_send_cmd(bus, val);
9216e85dddcSDylan Reid }
9226e85dddcSDylan Reid 
9236e85dddcSDylan Reid /* get a response */
azx_get_response(struct hdac_bus * bus,unsigned int addr,unsigned int * res)924a41d1224STakashi Iwai static int azx_get_response(struct hdac_bus *bus, unsigned int addr,
925cad372f1STakashi Iwai 			    unsigned int *res)
9266e85dddcSDylan Reid {
927a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(bus);
928a41d1224STakashi Iwai 
9296e85dddcSDylan Reid 	if (chip->disabled)
9306e85dddcSDylan Reid 		return 0;
931b13593e3SPeter Ujfalusi 	if (chip->single_cmd || bus->use_pio_for_commands)
932cad372f1STakashi Iwai 		return azx_single_get_response(bus, addr, res);
9336e85dddcSDylan Reid 	else
934cad372f1STakashi Iwai 		return azx_rirb_get_response(bus, addr, res);
9356e85dddcSDylan Reid }
9366e85dddcSDylan Reid 
9377e8be1b3STakashi Iwai static const struct hdac_bus_ops bus_core_ops = {
9387e8be1b3STakashi Iwai 	.command = azx_send_cmd,
9397e8be1b3STakashi Iwai 	.get_response = azx_get_response,
9407e8be1b3STakashi Iwai };
9417e8be1b3STakashi Iwai 
9422b5fd6c2SDylan Reid #ifdef CONFIG_SND_HDA_DSP_LOADER
9432b5fd6c2SDylan Reid /*
9442b5fd6c2SDylan Reid  * DSP loading code (e.g. for CA0132)
9452b5fd6c2SDylan Reid  */
9462b5fd6c2SDylan Reid 
9472b5fd6c2SDylan Reid /* use the first stream for loading DSP */
9482b5fd6c2SDylan Reid static struct azx_dev *
azx_get_dsp_loader_dev(struct azx * chip)9492b5fd6c2SDylan Reid azx_get_dsp_loader_dev(struct azx *chip)
9502b5fd6c2SDylan Reid {
9517833c3f8STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
9527833c3f8STakashi Iwai 	struct hdac_stream *s;
9537833c3f8STakashi Iwai 
9547833c3f8STakashi Iwai 	list_for_each_entry(s, &bus->stream_list, list)
9557833c3f8STakashi Iwai 		if (s->index == chip->playback_index_offset)
9567833c3f8STakashi Iwai 			return stream_to_azx_dev(s);
9577833c3f8STakashi Iwai 
9587833c3f8STakashi Iwai 	return NULL;
9592b5fd6c2SDylan Reid }
9602b5fd6c2SDylan Reid 
snd_hda_codec_load_dsp_prepare(struct hda_codec * codec,unsigned int format,unsigned int byte_size,struct snd_dma_buffer * bufp)9610a50575bSTakashi Iwai int snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
9622b5fd6c2SDylan Reid 				   unsigned int byte_size,
9632b5fd6c2SDylan Reid 				   struct snd_dma_buffer *bufp)
9642b5fd6c2SDylan Reid {
9650a50575bSTakashi Iwai 	struct hdac_bus *bus = &codec->bus->core;
966a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(bus);
9672b5fd6c2SDylan Reid 	struct azx_dev *azx_dev;
968ccc98865STakashi Iwai 	struct hdac_stream *hstr;
969ccc98865STakashi Iwai 	bool saved = false;
9702b5fd6c2SDylan Reid 	int err;
9712b5fd6c2SDylan Reid 
9722b5fd6c2SDylan Reid 	azx_dev = azx_get_dsp_loader_dev(chip);
973ccc98865STakashi Iwai 	hstr = azx_stream(azx_dev);
974a41d1224STakashi Iwai 	spin_lock_irq(&bus->reg_lock);
975ccc98865STakashi Iwai 	if (hstr->opened) {
9762b5fd6c2SDylan Reid 		chip->saved_azx_dev = *azx_dev;
977ccc98865STakashi Iwai 		saved = true;
978ccc98865STakashi Iwai 	}
979a41d1224STakashi Iwai 	spin_unlock_irq(&bus->reg_lock);
9802b5fd6c2SDylan Reid 
981ccc98865STakashi Iwai 	err = snd_hdac_dsp_prepare(hstr, format, byte_size, bufp);
982ccc98865STakashi Iwai 	if (err < 0) {
983a41d1224STakashi Iwai 		spin_lock_irq(&bus->reg_lock);
984ccc98865STakashi Iwai 		if (saved)
9852b5fd6c2SDylan Reid 			*azx_dev = chip->saved_azx_dev;
986a41d1224STakashi Iwai 		spin_unlock_irq(&bus->reg_lock);
987ccc98865STakashi Iwai 		return err;
988ccc98865STakashi Iwai 	}
989ccc98865STakashi Iwai 
9906d23c8f5STakashi Iwai 	hstr->prepared = 0;
9912b5fd6c2SDylan Reid 	return err;
9922b5fd6c2SDylan Reid }
9930a50575bSTakashi Iwai EXPORT_SYMBOL_GPL(snd_hda_codec_load_dsp_prepare);
9942b5fd6c2SDylan Reid 
snd_hda_codec_load_dsp_trigger(struct hda_codec * codec,bool start)9950a50575bSTakashi Iwai void snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start)
9962b5fd6c2SDylan Reid {
9970a50575bSTakashi Iwai 	struct hdac_bus *bus = &codec->bus->core;
998a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(bus);
9992b5fd6c2SDylan Reid 	struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
10002b5fd6c2SDylan Reid 
1001ccc98865STakashi Iwai 	snd_hdac_dsp_trigger(azx_stream(azx_dev), start);
10022b5fd6c2SDylan Reid }
10030a50575bSTakashi Iwai EXPORT_SYMBOL_GPL(snd_hda_codec_load_dsp_trigger);
10042b5fd6c2SDylan Reid 
snd_hda_codec_load_dsp_cleanup(struct hda_codec * codec,struct snd_dma_buffer * dmab)10050a50575bSTakashi Iwai void snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
10062b5fd6c2SDylan Reid 				    struct snd_dma_buffer *dmab)
10072b5fd6c2SDylan Reid {
10080a50575bSTakashi Iwai 	struct hdac_bus *bus = &codec->bus->core;
1009a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(bus);
10102b5fd6c2SDylan Reid 	struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
1011ccc98865STakashi Iwai 	struct hdac_stream *hstr = azx_stream(azx_dev);
10122b5fd6c2SDylan Reid 
10130a50575bSTakashi Iwai 	if (!dmab->area || !hstr->locked)
10142b5fd6c2SDylan Reid 		return;
10152b5fd6c2SDylan Reid 
1016ccc98865STakashi Iwai 	snd_hdac_dsp_cleanup(hstr, dmab);
1017a41d1224STakashi Iwai 	spin_lock_irq(&bus->reg_lock);
1018ccc98865STakashi Iwai 	if (hstr->opened)
10192b5fd6c2SDylan Reid 		*azx_dev = chip->saved_azx_dev;
1020ccc98865STakashi Iwai 	hstr->locked = false;
1021a41d1224STakashi Iwai 	spin_unlock_irq(&bus->reg_lock);
10222b5fd6c2SDylan Reid }
10230a50575bSTakashi Iwai EXPORT_SYMBOL_GPL(snd_hda_codec_load_dsp_cleanup);
10242b5fd6c2SDylan Reid #endif /* CONFIG_SND_HDA_DSP_LOADER */
10252b5fd6c2SDylan Reid 
1026f43923ffSDylan Reid /*
1027f43923ffSDylan Reid  * reset and start the controller registers
1028f43923ffSDylan Reid  */
azx_init_chip(struct azx * chip,bool full_reset)102917c3ad03SThierry Reding void azx_init_chip(struct azx *chip, bool full_reset)
1030f43923ffSDylan Reid {
1031a41d1224STakashi Iwai 	if (snd_hdac_bus_init_chip(azx_bus(chip), full_reset)) {
1032a41d1224STakashi Iwai 		/* correct RINTCNT for CXT */
1033a41d1224STakashi Iwai 		if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
1034a41d1224STakashi Iwai 			azx_writew(chip, RINTCNT, 0xc0);
1035a41d1224STakashi Iwai 	}
1036f43923ffSDylan Reid }
1037f43923ffSDylan Reid EXPORT_SYMBOL_GPL(azx_init_chip);
1038f43923ffSDylan Reid 
azx_stop_all_streams(struct azx * chip)10397833c3f8STakashi Iwai void azx_stop_all_streams(struct azx *chip)
10407833c3f8STakashi Iwai {
10417833c3f8STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
10427833c3f8STakashi Iwai 
104324ad3835SPierre-Louis Bossart 	snd_hdac_stop_streams(bus);
10447833c3f8STakashi Iwai }
10457833c3f8STakashi Iwai EXPORT_SYMBOL_GPL(azx_stop_all_streams);
10467833c3f8STakashi Iwai 
azx_stop_chip(struct azx * chip)1047f43923ffSDylan Reid void azx_stop_chip(struct azx *chip)
1048f43923ffSDylan Reid {
1049a41d1224STakashi Iwai 	snd_hdac_bus_stop_chip(azx_bus(chip));
1050f43923ffSDylan Reid }
1051154867cfSDylan Reid EXPORT_SYMBOL_GPL(azx_stop_chip);
1052f43923ffSDylan Reid 
1053f0b1df88SDylan Reid /*
1054f0b1df88SDylan Reid  * interrupt handler
1055f0b1df88SDylan Reid  */
stream_update(struct hdac_bus * bus,struct hdac_stream * s)10567833c3f8STakashi Iwai static void stream_update(struct hdac_bus *bus, struct hdac_stream *s)
10577833c3f8STakashi Iwai {
1058a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(bus);
10597833c3f8STakashi Iwai 	struct azx_dev *azx_dev = stream_to_azx_dev(s);
10607833c3f8STakashi Iwai 
10617833c3f8STakashi Iwai 	/* check whether this IRQ is really acceptable */
10627833c3f8STakashi Iwai 	if (!chip->ops->position_check ||
10637833c3f8STakashi Iwai 	    chip->ops->position_check(chip, azx_dev)) {
1064a41d1224STakashi Iwai 		spin_unlock(&bus->reg_lock);
1065a41d1224STakashi Iwai 		snd_pcm_period_elapsed(azx_stream(azx_dev)->substream);
1066a41d1224STakashi Iwai 		spin_lock(&bus->reg_lock);
10677833c3f8STakashi Iwai 	}
10687833c3f8STakashi Iwai }
10697833c3f8STakashi Iwai 
azx_interrupt(int irq,void * dev_id)1070f0b1df88SDylan Reid irqreturn_t azx_interrupt(int irq, void *dev_id)
1071f0b1df88SDylan Reid {
1072f0b1df88SDylan Reid 	struct azx *chip = dev_id;
10737833c3f8STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
1074f0b1df88SDylan Reid 	u32 status;
1075473f4145STakashi Iwai 	bool active, handled = false;
1076473f4145STakashi Iwai 	int repeat = 0; /* count for avoiding endless loop */
1077f0b1df88SDylan Reid 
1078364aa716STakashi Iwai 	if (azx_has_pm_runtime(chip))
10797b0a48f3SDylan Reid 		if (!pm_runtime_active(chip->card->dev))
1080f0b1df88SDylan Reid 			return IRQ_NONE;
1081f0b1df88SDylan Reid 
1082a41d1224STakashi Iwai 	spin_lock(&bus->reg_lock);
1083f0b1df88SDylan Reid 
1084473f4145STakashi Iwai 	if (chip->disabled)
1085473f4145STakashi Iwai 		goto unlock;
1086f0b1df88SDylan Reid 
1087473f4145STakashi Iwai 	do {
1088f0b1df88SDylan Reid 		status = azx_readl(chip, INTSTS);
1089473f4145STakashi Iwai 		if (status == 0 || status == 0xffffffff)
1090473f4145STakashi Iwai 			break;
1091f0b1df88SDylan Reid 
1092473f4145STakashi Iwai 		handled = true;
1093473f4145STakashi Iwai 		active = false;
1094473f4145STakashi Iwai 		if (snd_hdac_bus_handle_stream_irq(bus, status, stream_update))
1095473f4145STakashi Iwai 			active = true;
1096f0b1df88SDylan Reid 
1097f0b1df88SDylan Reid 		status = azx_readb(chip, RIRBSTS);
1098f0b1df88SDylan Reid 		if (status & RIRB_INT_MASK) {
10996d011d50SMohan Kumar 			/*
11006d011d50SMohan Kumar 			 * Clearing the interrupt status here ensures that no
11016d011d50SMohan Kumar 			 * interrupt gets masked after the RIRB wp is read in
11026d011d50SMohan Kumar 			 * snd_hdac_bus_update_rirb. This avoids a possible
11036d011d50SMohan Kumar 			 * race condition where codec response in RIRB may
11046d011d50SMohan Kumar 			 * remain unserviced by IRQ, eventually falling back
11056d011d50SMohan Kumar 			 * to polling mode in azx_rirb_get_response.
11066d011d50SMohan Kumar 			 */
11076d011d50SMohan Kumar 			azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
1108473f4145STakashi Iwai 			active = true;
1109f0b1df88SDylan Reid 			if (status & RIRB_INT_RESPONSE) {
1110ef85f299STakashi Iwai 				if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
1111f0b1df88SDylan Reid 					udelay(80);
1112a41d1224STakashi Iwai 				snd_hdac_bus_update_rirb(bus);
1113f0b1df88SDylan Reid 			}
1114f0b1df88SDylan Reid 		}
1115473f4145STakashi Iwai 	} while (active && ++repeat < 10);
1116f0b1df88SDylan Reid 
1117473f4145STakashi Iwai  unlock:
1118a41d1224STakashi Iwai 	spin_unlock(&bus->reg_lock);
1119f0b1df88SDylan Reid 
1120473f4145STakashi Iwai 	return IRQ_RETVAL(handled);
1121f0b1df88SDylan Reid }
1122f0b1df88SDylan Reid EXPORT_SYMBOL_GPL(azx_interrupt);
1123f0b1df88SDylan Reid 
1124154867cfSDylan Reid /*
1125154867cfSDylan Reid  * Codec initerface
1126154867cfSDylan Reid  */
1127154867cfSDylan Reid 
1128154867cfSDylan Reid /*
1129154867cfSDylan Reid  * Probe the given codec address
1130154867cfSDylan Reid  */
probe_codec(struct azx * chip,int addr)1131154867cfSDylan Reid static int probe_codec(struct azx *chip, int addr)
1132154867cfSDylan Reid {
1133154867cfSDylan Reid 	unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
1134154867cfSDylan Reid 		(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
11357833c3f8STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
1136cad372f1STakashi Iwai 	int err;
1137a41d1224STakashi Iwai 	unsigned int res = -1;
1138154867cfSDylan Reid 
11397e8be1b3STakashi Iwai 	mutex_lock(&bus->cmd_mutex);
1140154867cfSDylan Reid 	chip->probing = 1;
11417e8be1b3STakashi Iwai 	azx_send_cmd(bus, cmd);
11427e8be1b3STakashi Iwai 	err = azx_get_response(bus, addr, &res);
1143154867cfSDylan Reid 	chip->probing = 0;
11447e8be1b3STakashi Iwai 	mutex_unlock(&bus->cmd_mutex);
1145cad372f1STakashi Iwai 	if (err < 0 || res == -1)
1146154867cfSDylan Reid 		return -EIO;
1147154867cfSDylan Reid 	dev_dbg(chip->card->dev, "codec #%d probed OK\n", addr);
1148154867cfSDylan Reid 	return 0;
1149154867cfSDylan Reid }
1150154867cfSDylan Reid 
snd_hda_bus_reset(struct hda_bus * bus)11510a50575bSTakashi Iwai void snd_hda_bus_reset(struct hda_bus *bus)
1152154867cfSDylan Reid {
1153a41d1224STakashi Iwai 	struct azx *chip = bus_to_azx(&bus->core);
1154154867cfSDylan Reid 
1155154867cfSDylan Reid 	bus->in_reset = 1;
1156154867cfSDylan Reid 	azx_stop_chip(chip);
115717c3ad03SThierry Reding 	azx_init_chip(chip, true);
1158a41d1224STakashi Iwai 	if (bus->core.chip_init)
11590a50575bSTakashi Iwai 		snd_hda_bus_reset_codecs(bus);
1160154867cfSDylan Reid 	bus->in_reset = 0;
1161154867cfSDylan Reid }
1162154867cfSDylan Reid 
116396d2bd6eSTakashi Iwai /* HD-audio bus initialization */
azx_bus_init(struct azx * chip,const char * model)116419abfefdSTakashi Iwai int azx_bus_init(struct azx *chip, const char *model)
1165154867cfSDylan Reid {
1166a41d1224STakashi Iwai 	struct hda_bus *bus = &chip->bus;
116796d2bd6eSTakashi Iwai 	int err;
1168154867cfSDylan Reid 
116919abfefdSTakashi Iwai 	err = snd_hdac_bus_init(&bus->core, chip->card->dev, &bus_core_ops);
1170154867cfSDylan Reid 	if (err < 0)
1171154867cfSDylan Reid 		return err;
1172154867cfSDylan Reid 
1173a41d1224STakashi Iwai 	bus->card = chip->card;
1174a41d1224STakashi Iwai 	mutex_init(&bus->prepare_mutex);
1175ef744978STakashi Iwai 	bus->pci = chip->pci;
1176ef744978STakashi Iwai 	bus->modelname = model;
11772f0eaad9STakashi Iwai 	bus->mixer_assigned = -1;
1178ccc98865STakashi Iwai 	bus->core.snoop = azx_snoop(chip);
1179ccc98865STakashi Iwai 	if (chip->get_position[0] != azx_get_pos_lpib ||
1180ccc98865STakashi Iwai 	    chip->get_position[1] != azx_get_pos_lpib)
1181ccc98865STakashi Iwai 		bus->core.use_posbuf = true;
11824f0189beSTakashi Iwai 	bus->core.bdl_pos_adj = chip->bdl_pos_adj;
1183a41d1224STakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR)
1184a41d1224STakashi Iwai 		bus->core.corbrp_self_clear = true;
1185ef744978STakashi Iwai 
1186de1ab6afSTakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY)
1187de1ab6afSTakashi Iwai 		bus->core.align_bdle_4k = true;
1188de1ab6afSTakashi Iwai 
1189b13593e3SPeter Ujfalusi 	if (chip->driver_caps & AZX_DCAPS_PIO_COMMANDS)
1190b13593e3SPeter Ujfalusi 		bus->core.use_pio_for_commands = true;
1191b13593e3SPeter Ujfalusi 
1192f34a4c9dSTakashi Iwai 	/* enable sync_write flag for stable communication as default */
1193d068ebc2STakashi Iwai 	bus->core.sync_write = 1;
119496d2bd6eSTakashi Iwai 
119596d2bd6eSTakashi Iwai 	return 0;
119696d2bd6eSTakashi Iwai }
1197a41d1224STakashi Iwai EXPORT_SYMBOL_GPL(azx_bus_init);
119896d2bd6eSTakashi Iwai 
119996d2bd6eSTakashi Iwai /* Probe codecs */
azx_probe_codecs(struct azx * chip,unsigned int max_slots)120096d2bd6eSTakashi Iwai int azx_probe_codecs(struct azx *chip, unsigned int max_slots)
120196d2bd6eSTakashi Iwai {
1202a41d1224STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
120396d2bd6eSTakashi Iwai 	int c, codecs, err;
120496d2bd6eSTakashi Iwai 
1205154867cfSDylan Reid 	codecs = 0;
1206154867cfSDylan Reid 	if (!max_slots)
1207154867cfSDylan Reid 		max_slots = AZX_DEFAULT_CODECS;
1208154867cfSDylan Reid 
1209154867cfSDylan Reid 	/* First try to probe all given codec slots */
1210154867cfSDylan Reid 	for (c = 0; c < max_slots; c++) {
1211a41d1224STakashi Iwai 		if ((bus->codec_mask & (1 << c)) & chip->codec_probe_mask) {
1212154867cfSDylan Reid 			if (probe_codec(chip, c) < 0) {
1213154867cfSDylan Reid 				/* Some BIOSen give you wrong codec addresses
1214154867cfSDylan Reid 				 * that don't exist
1215154867cfSDylan Reid 				 */
1216154867cfSDylan Reid 				dev_warn(chip->card->dev,
1217154867cfSDylan Reid 					 "Codec #%d probe error; disabling it...\n", c);
1218a41d1224STakashi Iwai 				bus->codec_mask &= ~(1 << c);
1219642b02b4Ssongxiebing 				/* no codecs */
1220642b02b4Ssongxiebing 				if (bus->codec_mask == 0)
1221642b02b4Ssongxiebing 					break;
1222154867cfSDylan Reid 				/* More badly, accessing to a non-existing
1223154867cfSDylan Reid 				 * codec often screws up the controller chip,
1224154867cfSDylan Reid 				 * and disturbs the further communications.
1225154867cfSDylan Reid 				 * Thus if an error occurs during probing,
1226154867cfSDylan Reid 				 * better to reset the controller chip to
1227154867cfSDylan Reid 				 * get back to the sanity state.
1228154867cfSDylan Reid 				 */
1229154867cfSDylan Reid 				azx_stop_chip(chip);
123017c3ad03SThierry Reding 				azx_init_chip(chip, true);
1231154867cfSDylan Reid 			}
1232154867cfSDylan Reid 		}
1233154867cfSDylan Reid 	}
1234154867cfSDylan Reid 
1235154867cfSDylan Reid 	/* Then create codec instances */
1236154867cfSDylan Reid 	for (c = 0; c < max_slots; c++) {
1237a41d1224STakashi Iwai 		if ((bus->codec_mask & (1 << c)) & chip->codec_probe_mask) {
1238154867cfSDylan Reid 			struct hda_codec *codec;
1239a41d1224STakashi Iwai 			err = snd_hda_codec_new(&chip->bus, chip->card, c, &codec);
1240154867cfSDylan Reid 			if (err < 0)
1241154867cfSDylan Reid 				continue;
12423a182c84STakashi Iwai 			codec->jackpoll_interval = chip->jackpoll_interval;
1243154867cfSDylan Reid 			codec->beep_mode = chip->beep_mode;
1244d045bcefSJaroslav Kysela 			codec->ctl_dev_id = chip->ctl_dev_id;
1245154867cfSDylan Reid 			codecs++;
1246154867cfSDylan Reid 		}
1247154867cfSDylan Reid 	}
1248154867cfSDylan Reid 	if (!codecs) {
1249154867cfSDylan Reid 		dev_err(chip->card->dev, "no codecs initialized\n");
1250154867cfSDylan Reid 		return -ENXIO;
1251154867cfSDylan Reid 	}
1252154867cfSDylan Reid 	return 0;
1253154867cfSDylan Reid }
125496d2bd6eSTakashi Iwai EXPORT_SYMBOL_GPL(azx_probe_codecs);
1255154867cfSDylan Reid 
1256154867cfSDylan Reid /* configure each codec instance */
azx_codec_configure(struct azx * chip)1257154867cfSDylan Reid int azx_codec_configure(struct azx *chip)
1258154867cfSDylan Reid {
1259d94815f9STakashi Iwai 	struct hda_codec *codec, *next;
1260c0f1886dSTakashi Iwai 	int success = 0;
1261d94815f9STakashi Iwai 
1262c0f1886dSTakashi Iwai 	list_for_each_codec(codec, &chip->bus) {
1263c0f1886dSTakashi Iwai 		if (!snd_hda_codec_configure(codec))
1264c0f1886dSTakashi Iwai 			success++;
1265154867cfSDylan Reid 	}
126617890880STakashi Iwai 
1267c0f1886dSTakashi Iwai 	if (success) {
1268c0f1886dSTakashi Iwai 		/* unregister failed codecs if any codec has been probed */
1269c0f1886dSTakashi Iwai 		list_for_each_codec_safe(codec, next, &chip->bus) {
1270c0f1886dSTakashi Iwai 			if (!codec->configured) {
1271c0f1886dSTakashi Iwai 				codec_err(codec, "Unable to configure, disabling\n");
1272c0f1886dSTakashi Iwai 				snd_hdac_device_unregister(&codec->core);
1273c0f1886dSTakashi Iwai 			}
1274c0f1886dSTakashi Iwai 		}
1275c0f1886dSTakashi Iwai 	}
1276c0f1886dSTakashi Iwai 
1277c0f1886dSTakashi Iwai 	return success ? 0 : -ENODEV;
1278154867cfSDylan Reid }
1279154867cfSDylan Reid EXPORT_SYMBOL_GPL(azx_codec_configure);
1280154867cfSDylan Reid 
stream_direction(struct azx * chip,unsigned char index)12817833c3f8STakashi Iwai static int stream_direction(struct azx *chip, unsigned char index)
128293e3423eSRafal Redzimski {
12837833c3f8STakashi Iwai 	if (index >= chip->capture_index_offset &&
12847833c3f8STakashi Iwai 	    index < chip->capture_index_offset + chip->capture_streams)
12857833c3f8STakashi Iwai 		return SNDRV_PCM_STREAM_CAPTURE;
12867833c3f8STakashi Iwai 	return SNDRV_PCM_STREAM_PLAYBACK;
128793e3423eSRafal Redzimski }
128893e3423eSRafal Redzimski 
1289154867cfSDylan Reid /* initialize SD streams */
azx_init_streams(struct azx * chip)1290a41d1224STakashi Iwai int azx_init_streams(struct azx *chip)
1291154867cfSDylan Reid {
1292154867cfSDylan Reid 	int i;
12937833c3f8STakashi Iwai 	int stream_tags[2] = { 0, 0 };
1294154867cfSDylan Reid 
1295154867cfSDylan Reid 	/* initialize each stream (aka device)
1296154867cfSDylan Reid 	 * assign the starting bdl address to each stream (device)
1297154867cfSDylan Reid 	 * and initialize
1298154867cfSDylan Reid 	 */
1299154867cfSDylan Reid 	for (i = 0; i < chip->num_streams; i++) {
13007833c3f8STakashi Iwai 		struct azx_dev *azx_dev = kzalloc(sizeof(*azx_dev), GFP_KERNEL);
13017833c3f8STakashi Iwai 		int dir, tag;
130293e3423eSRafal Redzimski 
13037833c3f8STakashi Iwai 		if (!azx_dev)
13047833c3f8STakashi Iwai 			return -ENOMEM;
13057833c3f8STakashi Iwai 
13067833c3f8STakashi Iwai 		dir = stream_direction(chip, i);
130793e3423eSRafal Redzimski 		/* stream tag must be unique throughout
130893e3423eSRafal Redzimski 		 * the stream direction group,
130993e3423eSRafal Redzimski 		 * valid values 1...15
131093e3423eSRafal Redzimski 		 * use separate stream tag if the flag
131193e3423eSRafal Redzimski 		 * AZX_DCAPS_SEPARATE_STREAM_TAG is used
131293e3423eSRafal Redzimski 		 */
131393e3423eSRafal Redzimski 		if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG)
13147833c3f8STakashi Iwai 			tag = ++stream_tags[dir];
131593e3423eSRafal Redzimski 		else
13167833c3f8STakashi Iwai 			tag = i + 1;
13177833c3f8STakashi Iwai 		snd_hdac_stream_init(azx_bus(chip), azx_stream(azx_dev),
13187833c3f8STakashi Iwai 				     i, dir, tag);
1319154867cfSDylan Reid 	}
1320154867cfSDylan Reid 
1321154867cfSDylan Reid 	return 0;
1322154867cfSDylan Reid }
1323a41d1224STakashi Iwai EXPORT_SYMBOL_GPL(azx_init_streams);
1324a41d1224STakashi Iwai 
azx_free_streams(struct azx * chip)1325a41d1224STakashi Iwai void azx_free_streams(struct azx *chip)
1326a41d1224STakashi Iwai {
1327a41d1224STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
1328a41d1224STakashi Iwai 	struct hdac_stream *s;
1329a41d1224STakashi Iwai 
1330a41d1224STakashi Iwai 	while (!list_empty(&bus->stream_list)) {
1331a41d1224STakashi Iwai 		s = list_first_entry(&bus->stream_list, struct hdac_stream, list);
1332a41d1224STakashi Iwai 		list_del(&s->list);
1333a41d1224STakashi Iwai 		kfree(stream_to_azx_dev(s));
1334a41d1224STakashi Iwai 	}
1335a41d1224STakashi Iwai }
1336a41d1224STakashi Iwai EXPORT_SYMBOL_GPL(azx_free_streams);
1337