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 *
605e84878SDylan Reid * Copyright(c) 2004 Intel Corporation. All rights reserved.
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>
2705e84878SDylan Reid #include "hda_controller.h"
28c0f1886dSTakashi Iwai #include "hda_local.h"
2905e84878SDylan Reid
3043db4a59STakashi Iwai #define CREATE_TRACE_POINTS
3118486508SLibin Yang #include "hda_controller_trace.h"
3243db4a59STakashi Iwai
332b5fd6c2SDylan Reid /* DSP lock helpers */
347833c3f8STakashi Iwai #define dsp_lock(dev) snd_hdac_dsp_lock(azx_stream(dev))
357833c3f8STakashi Iwai #define dsp_unlock(dev) snd_hdac_dsp_unlock(azx_stream(dev))
367833c3f8STakashi Iwai #define dsp_is_locked(dev) snd_hdac_stream_is_locked(azx_stream(dev))
372b5fd6c2SDylan Reid
3805e84878SDylan Reid /* assign a stream for the PCM */
3905e84878SDylan Reid static inline struct azx_dev *
azx_assign_device(struct azx * chip,struct snd_pcm_substream * substream)4005e84878SDylan Reid azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream)
4105e84878SDylan Reid {
427833c3f8STakashi Iwai struct hdac_stream *s;
4305e84878SDylan Reid
447833c3f8STakashi Iwai s = snd_hdac_stream_assign(azx_bus(chip), substream);
457833c3f8STakashi Iwai if (!s)
467833c3f8STakashi Iwai return NULL;
477833c3f8STakashi Iwai return stream_to_azx_dev(s);
4805e84878SDylan Reid }
4905e84878SDylan Reid
5005e84878SDylan Reid /* release the assigned stream */
azx_release_device(struct azx_dev * azx_dev)5105e84878SDylan Reid static inline void azx_release_device(struct azx_dev *azx_dev)
5205e84878SDylan Reid {
537833c3f8STakashi Iwai snd_hdac_stream_release(azx_stream(azx_dev));
5405e84878SDylan Reid }
5505e84878SDylan Reid
56820cc6cfSTakashi Iwai static inline struct hda_pcm_stream *
to_hda_pcm_stream(struct snd_pcm_substream * substream)57820cc6cfSTakashi Iwai to_hda_pcm_stream(struct snd_pcm_substream *substream)
58820cc6cfSTakashi Iwai {
59820cc6cfSTakashi Iwai struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
60820cc6cfSTakashi Iwai return &apcm->info->stream[substream->stream];
61820cc6cfSTakashi Iwai }
62820cc6cfSTakashi Iwai
azx_adjust_codec_delay(struct snd_pcm_substream * substream,u64 nsec)6305e84878SDylan Reid static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream,
6405e84878SDylan Reid u64 nsec)
6505e84878SDylan Reid {
6605e84878SDylan Reid struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
67820cc6cfSTakashi Iwai struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
6805e84878SDylan Reid u64 codec_frames, codec_nsecs;
6905e84878SDylan Reid
7005e84878SDylan Reid if (!hinfo->ops.get_delay)
7105e84878SDylan Reid return nsec;
7205e84878SDylan Reid
7305e84878SDylan Reid codec_frames = hinfo->ops.get_delay(hinfo, apcm->codec, substream);
7405e84878SDylan Reid codec_nsecs = div_u64(codec_frames * 1000000000LL,
7505e84878SDylan Reid substream->runtime->rate);
7605e84878SDylan Reid
7705e84878SDylan Reid if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
7805e84878SDylan Reid return nsec + codec_nsecs;
7905e84878SDylan Reid
8005e84878SDylan Reid return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0;
8105e84878SDylan Reid }
8205e84878SDylan Reid
8305e84878SDylan Reid /*
8405e84878SDylan Reid * PCM ops
8505e84878SDylan Reid */
8605e84878SDylan Reid
azx_pcm_close(struct snd_pcm_substream * substream)8705e84878SDylan Reid static int azx_pcm_close(struct snd_pcm_substream *substream)
8805e84878SDylan Reid {
8905e84878SDylan Reid struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
90820cc6cfSTakashi Iwai struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
9105e84878SDylan Reid struct azx *chip = apcm->chip;
9205e84878SDylan Reid struct azx_dev *azx_dev = get_azx_dev(substream);
9305e84878SDylan Reid
9418486508SLibin Yang trace_azx_pcm_close(chip, azx_dev);
9505e84878SDylan Reid mutex_lock(&chip->open_mutex);
9605e84878SDylan Reid azx_release_device(azx_dev);
9761ca4107STakashi Iwai if (hinfo->ops.close)
9805e84878SDylan Reid hinfo->ops.close(hinfo, apcm->codec, substream);
9905e84878SDylan Reid snd_hda_power_down(apcm->codec);
10005e84878SDylan Reid mutex_unlock(&chip->open_mutex);
1019a6246ffSTakashi Iwai snd_hda_codec_pcm_put(apcm->info);
10205e84878SDylan Reid return 0;
10305e84878SDylan Reid }
10405e84878SDylan Reid
azx_pcm_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * hw_params)10505e84878SDylan Reid static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
10605e84878SDylan Reid struct snd_pcm_hw_params *hw_params)
10705e84878SDylan Reid {
10805e84878SDylan Reid struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
10905e84878SDylan Reid struct azx *chip = apcm->chip;
110602518a2STakashi Iwai struct azx_dev *azx_dev = get_azx_dev(substream);
1117a6d4a5aSTakashi Iwai int ret = 0;
11205e84878SDylan Reid
11318486508SLibin Yang trace_azx_pcm_hw_params(chip, azx_dev);
114602518a2STakashi Iwai dsp_lock(azx_dev);
115602518a2STakashi Iwai if (dsp_is_locked(azx_dev)) {
11605e84878SDylan Reid ret = -EBUSY;
11705e84878SDylan Reid goto unlock;
11805e84878SDylan Reid }
11905e84878SDylan Reid
120602518a2STakashi Iwai azx_dev->core.bufsize = 0;
121602518a2STakashi Iwai azx_dev->core.period_bytes = 0;
122602518a2STakashi Iwai azx_dev->core.format_val = 0;
123193c7e14STakashi Iwai
12405e84878SDylan Reid unlock:
125602518a2STakashi Iwai dsp_unlock(azx_dev);
12605e84878SDylan Reid return ret;
12705e84878SDylan Reid }
12805e84878SDylan Reid
azx_pcm_hw_free(struct snd_pcm_substream * substream)12905e84878SDylan Reid static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
13005e84878SDylan Reid {
13105e84878SDylan Reid struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
13205e84878SDylan Reid struct azx_dev *azx_dev = get_azx_dev(substream);
133820cc6cfSTakashi Iwai struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
13405e84878SDylan Reid
13505e84878SDylan Reid /* reset BDL address */
13605e84878SDylan Reid dsp_lock(azx_dev);
137ccc98865STakashi Iwai if (!dsp_is_locked(azx_dev))
138ccc98865STakashi Iwai snd_hdac_stream_cleanup(azx_stream(azx_dev));
13905e84878SDylan Reid
14005e84878SDylan Reid snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
14105e84878SDylan Reid
1426d23c8f5STakashi Iwai azx_stream(azx_dev)->prepared = 0;
14305e84878SDylan Reid dsp_unlock(azx_dev);
1447a6d4a5aSTakashi Iwai return 0;
14505e84878SDylan Reid }
14605e84878SDylan Reid
azx_pcm_prepare(struct snd_pcm_substream * substream)14705e84878SDylan Reid static int azx_pcm_prepare(struct snd_pcm_substream *substream)
14805e84878SDylan Reid {
14905e84878SDylan Reid struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
15005e84878SDylan Reid struct azx *chip = apcm->chip;
15105e84878SDylan Reid struct azx_dev *azx_dev = get_azx_dev(substream);
152820cc6cfSTakashi Iwai struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
15305e84878SDylan Reid struct snd_pcm_runtime *runtime = substream->runtime;
1540dd76f36STakashi Iwai unsigned int format_val, stream_tag;
15505e84878SDylan Reid int err;
15605e84878SDylan Reid struct hda_spdif_out *spdif =
15705e84878SDylan Reid snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
15805e84878SDylan Reid unsigned short ctls = spdif ? spdif->ctls : 0;
15905e84878SDylan Reid
16018486508SLibin Yang trace_azx_pcm_prepare(chip, azx_dev);
16105e84878SDylan Reid dsp_lock(azx_dev);
16205e84878SDylan Reid if (dsp_is_locked(azx_dev)) {
16305e84878SDylan Reid err = -EBUSY;
16405e84878SDylan Reid goto unlock;
16505e84878SDylan Reid }
16605e84878SDylan Reid
1677833c3f8STakashi Iwai snd_hdac_stream_reset(azx_stream(azx_dev));
168b7d023e1STakashi Iwai format_val = snd_hdac_calc_stream_format(runtime->rate,
16905e84878SDylan Reid runtime->channels,
17005e84878SDylan Reid runtime->format,
17105e84878SDylan Reid hinfo->maxbps,
17205e84878SDylan Reid ctls);
17305e84878SDylan Reid if (!format_val) {
17405e84878SDylan Reid dev_err(chip->card->dev,
17505e84878SDylan Reid "invalid format_val, rate=%d, ch=%d, format=%d\n",
17605e84878SDylan Reid runtime->rate, runtime->channels, runtime->format);
17705e84878SDylan Reid err = -EINVAL;
17805e84878SDylan Reid goto unlock;
17905e84878SDylan Reid }
18005e84878SDylan Reid
1810dd76f36STakashi Iwai err = snd_hdac_stream_set_params(azx_stream(azx_dev), format_val);
18205e84878SDylan Reid if (err < 0)
18305e84878SDylan Reid goto unlock;
18405e84878SDylan Reid
185ccc98865STakashi Iwai snd_hdac_stream_setup(azx_stream(azx_dev));
18605e84878SDylan Reid
1877833c3f8STakashi Iwai stream_tag = azx_dev->core.stream_tag;
18805e84878SDylan Reid /* CA-IBG chips need the playback stream starting from 1 */
18905e84878SDylan Reid if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) &&
19005e84878SDylan Reid stream_tag > chip->capture_streams)
19105e84878SDylan Reid stream_tag -= chip->capture_streams;
19205e84878SDylan Reid err = snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag,
1937833c3f8STakashi Iwai azx_dev->core.format_val, substream);
19405e84878SDylan Reid
19505e84878SDylan Reid unlock:
19605e84878SDylan Reid if (!err)
1976d23c8f5STakashi Iwai azx_stream(azx_dev)->prepared = 1;
19805e84878SDylan Reid dsp_unlock(azx_dev);
19905e84878SDylan Reid return err;
20005e84878SDylan Reid }
20105e84878SDylan Reid
azx_pcm_trigger(struct snd_pcm_substream * substream,int cmd)20205e84878SDylan Reid static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
20305e84878SDylan Reid {
20405e84878SDylan Reid struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
20505e84878SDylan Reid struct azx *chip = apcm->chip;
206a41d1224STakashi Iwai struct hdac_bus *bus = azx_bus(chip);
20705e84878SDylan Reid struct azx_dev *azx_dev;
20805e84878SDylan Reid struct snd_pcm_substream *s;
209ccc98865STakashi Iwai struct hdac_stream *hstr;
210ccc98865STakashi Iwai bool start;
211ccc98865STakashi Iwai int sbits = 0;
212ccc98865STakashi Iwai int sync_reg;
21305e84878SDylan Reid
21405e84878SDylan Reid azx_dev = get_azx_dev(substream);
21543db4a59STakashi Iwai trace_azx_pcm_trigger(chip, azx_dev, cmd);
21643db4a59STakashi Iwai
217ccc98865STakashi Iwai hstr = azx_stream(azx_dev);
218ccc98865STakashi Iwai if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
219ccc98865STakashi Iwai sync_reg = AZX_REG_OLD_SSYNC;
220ccc98865STakashi Iwai else
221ccc98865STakashi Iwai sync_reg = AZX_REG_SSYNC;
22205e84878SDylan Reid
2236d23c8f5STakashi Iwai if (dsp_is_locked(azx_dev) || !hstr->prepared)
22405e84878SDylan Reid return -EPIPE;
22505e84878SDylan Reid
22605e84878SDylan Reid switch (cmd) {
22705e84878SDylan Reid case SNDRV_PCM_TRIGGER_START:
22805e84878SDylan Reid case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
22905e84878SDylan Reid case SNDRV_PCM_TRIGGER_RESUME:
230ccc98865STakashi Iwai start = true;
23105e84878SDylan Reid break;
23205e84878SDylan Reid case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
23305e84878SDylan Reid case SNDRV_PCM_TRIGGER_SUSPEND:
23405e84878SDylan Reid case SNDRV_PCM_TRIGGER_STOP:
235ccc98865STakashi Iwai start = false;
23605e84878SDylan Reid break;
23705e84878SDylan Reid default:
23805e84878SDylan Reid return -EINVAL;
23905e84878SDylan Reid }
24005e84878SDylan Reid
24105e84878SDylan Reid snd_pcm_group_for_each_entry(s, substream) {
24205e84878SDylan Reid if (s->pcm->card != substream->pcm->card)
24305e84878SDylan Reid continue;
24405e84878SDylan Reid azx_dev = get_azx_dev(s);
2457833c3f8STakashi Iwai sbits |= 1 << azx_dev->core.index;
24605e84878SDylan Reid snd_pcm_trigger_done(s, substream);
24705e84878SDylan Reid }
24805e84878SDylan Reid
249a41d1224STakashi Iwai spin_lock(&bus->reg_lock);
25005e84878SDylan Reid
25105e84878SDylan Reid /* first, set SYNC bits of corresponding streams */
252ccc98865STakashi Iwai snd_hdac_stream_sync_trigger(hstr, true, sbits, sync_reg);
25305e84878SDylan Reid
25405e84878SDylan Reid snd_pcm_group_for_each_entry(s, substream) {
25505e84878SDylan Reid if (s->pcm->card != substream->pcm->card)
25605e84878SDylan Reid continue;
25705e84878SDylan Reid azx_dev = get_azx_dev(s);
25805e84878SDylan Reid if (start) {
2597833c3f8STakashi Iwai azx_dev->insufficient = 1;
260*4fe20d62SZhang Yiqun snd_hdac_stream_start(azx_stream(azx_dev));
26105e84878SDylan Reid } else {
2627833c3f8STakashi Iwai snd_hdac_stream_stop(azx_stream(azx_dev));
26305e84878SDylan Reid }
26405e84878SDylan Reid }
265a41d1224STakashi Iwai spin_unlock(&bus->reg_lock);
266ccc98865STakashi Iwai
267ccc98865STakashi Iwai snd_hdac_stream_sync(hstr, start, sbits);
268ccc98865STakashi Iwai
269a41d1224STakashi Iwai spin_lock(&bus->reg_lock);
27005e84878SDylan Reid /* reset SYNC bits */
271ccc98865STakashi Iwai snd_hdac_stream_sync_trigger(hstr, false, sbits, sync_reg);
272ccc98865STakashi Iwai if (start)
273ccc98865STakashi Iwai snd_hdac_stream_timecounter_init(hstr, sbits);
274a41d1224STakashi Iwai spin_unlock(&bus->reg_lock);
27505e84878SDylan Reid return 0;
27605e84878SDylan Reid }
27705e84878SDylan Reid
azx_get_pos_lpib(struct azx * chip,struct azx_dev * azx_dev)278b6050ef6STakashi Iwai unsigned int azx_get_pos_lpib(struct azx *chip, struct azx_dev *azx_dev)
27905e84878SDylan Reid {
2807833c3f8STakashi Iwai return snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev));
28105e84878SDylan Reid }
282b6050ef6STakashi Iwai EXPORT_SYMBOL_GPL(azx_get_pos_lpib);
28305e84878SDylan Reid
azx_get_pos_posbuf(struct azx * chip,struct azx_dev * azx_dev)284b6050ef6STakashi Iwai unsigned int azx_get_pos_posbuf(struct azx *chip, struct azx_dev *azx_dev)
285b6050ef6STakashi Iwai {
2867833c3f8STakashi Iwai return snd_hdac_stream_get_pos_posbuf(azx_stream(azx_dev));
28705e84878SDylan Reid }
288b6050ef6STakashi Iwai EXPORT_SYMBOL_GPL(azx_get_pos_posbuf);
28905e84878SDylan Reid
azx_get_position(struct azx * chip,struct azx_dev * azx_dev)29005e84878SDylan Reid unsigned int azx_get_position(struct azx *chip,
291b6050ef6STakashi Iwai struct azx_dev *azx_dev)
29205e84878SDylan Reid {
2937833c3f8STakashi Iwai struct snd_pcm_substream *substream = azx_dev->core.substream;
29405e84878SDylan Reid unsigned int pos;
29505e84878SDylan Reid int stream = substream->stream;
29605e84878SDylan Reid int delay = 0;
29705e84878SDylan Reid
298b6050ef6STakashi Iwai if (chip->get_position[stream])
299b6050ef6STakashi Iwai pos = chip->get_position[stream](chip, azx_dev);
300b6050ef6STakashi Iwai else /* use the position buffer as default */
301b6050ef6STakashi Iwai pos = azx_get_pos_posbuf(chip, azx_dev);
30205e84878SDylan Reid
3037833c3f8STakashi Iwai if (pos >= azx_dev->core.bufsize)
30405e84878SDylan Reid pos = 0;
30505e84878SDylan Reid
30605e84878SDylan Reid if (substream->runtime) {
307b6050ef6STakashi Iwai struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
308820cc6cfSTakashi Iwai struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
309b6050ef6STakashi Iwai
310b6050ef6STakashi Iwai if (chip->get_delay[stream])
311b6050ef6STakashi Iwai delay += chip->get_delay[stream](chip, azx_dev, pos);
31205e84878SDylan Reid if (hinfo->ops.get_delay)
31305e84878SDylan Reid delay += hinfo->ops.get_delay(hinfo, apcm->codec,
31405e84878SDylan Reid substream);
31505e84878SDylan Reid substream->runtime->delay = delay;
31605e84878SDylan Reid }
31705e84878SDylan Reid
31843db4a59STakashi Iwai trace_azx_get_position(chip, azx_dev, pos, delay);
31905e84878SDylan Reid return pos;
32005e84878SDylan Reid }
32105e84878SDylan Reid EXPORT_SYMBOL_GPL(azx_get_position);
32205e84878SDylan Reid
azx_pcm_pointer(struct snd_pcm_substream * substream)32305e84878SDylan Reid static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
32405e84878SDylan Reid {
32505e84878SDylan Reid struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
32605e84878SDylan Reid struct azx *chip = apcm->chip;
32705e84878SDylan Reid struct azx_dev *azx_dev = get_azx_dev(substream);
32805e84878SDylan Reid return bytes_to_frames(substream->runtime,
329b6050ef6STakashi Iwai azx_get_position(chip, azx_dev));
33005e84878SDylan Reid }
33105e84878SDylan Reid
332bfcba288SGuneshwor Singh /*
333bfcba288SGuneshwor Singh * azx_scale64: Scale base by mult/div while not overflowing sanely
334bfcba288SGuneshwor Singh *
335bfcba288SGuneshwor Singh * Derived from scale64_check_overflow in kernel/time/timekeeping.c
336bfcba288SGuneshwor Singh *
337bfcba288SGuneshwor Singh * The tmestamps for a 48Khz stream can overflow after (2^64/10^9)/48K which
338bfcba288SGuneshwor Singh * is about 384307 ie ~4.5 days.
339bfcba288SGuneshwor Singh *
340bfcba288SGuneshwor Singh * This scales the calculation so that overflow will happen but after 2^64 /
341bfcba288SGuneshwor Singh * 48000 secs, which is pretty large!
342bfcba288SGuneshwor Singh *
343bfcba288SGuneshwor Singh * In caln below:
344bfcba288SGuneshwor Singh * base may overflow, but since there isn’t any additional division
345bfcba288SGuneshwor Singh * performed on base it’s OK
346bfcba288SGuneshwor Singh * rem can’t overflow because both are 32-bit values
347bfcba288SGuneshwor Singh */
348bfcba288SGuneshwor Singh
349bfcba288SGuneshwor Singh #ifdef CONFIG_X86
azx_scale64(u64 base,u32 num,u32 den)350bfcba288SGuneshwor Singh static u64 azx_scale64(u64 base, u32 num, u32 den)
351bfcba288SGuneshwor Singh {
352bfcba288SGuneshwor Singh u64 rem;
353bfcba288SGuneshwor Singh
354bfcba288SGuneshwor Singh rem = do_div(base, den);
355bfcba288SGuneshwor Singh
356bfcba288SGuneshwor Singh base *= num;
357bfcba288SGuneshwor Singh rem *= num;
358bfcba288SGuneshwor Singh
359bfcba288SGuneshwor Singh do_div(rem, den);
360bfcba288SGuneshwor Singh
361bfcba288SGuneshwor Singh return base + rem;
362bfcba288SGuneshwor Singh }
363bfcba288SGuneshwor Singh
azx_get_sync_time(ktime_t * device,struct system_counterval_t * system,void * ctx)364bfcba288SGuneshwor Singh static int azx_get_sync_time(ktime_t *device,
365bfcba288SGuneshwor Singh struct system_counterval_t *system, void *ctx)
366bfcba288SGuneshwor Singh {
367bfcba288SGuneshwor Singh struct snd_pcm_substream *substream = ctx;
368bfcba288SGuneshwor Singh struct azx_dev *azx_dev = get_azx_dev(substream);
369bfcba288SGuneshwor Singh struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
370bfcba288SGuneshwor Singh struct azx *chip = apcm->chip;
371bfcba288SGuneshwor Singh struct snd_pcm_runtime *runtime;
372bfcba288SGuneshwor Singh u64 ll_counter, ll_counter_l, ll_counter_h;
373bfcba288SGuneshwor Singh u64 tsc_counter, tsc_counter_l, tsc_counter_h;
374bfcba288SGuneshwor Singh u32 wallclk_ctr, wallclk_cycles;
375bfcba288SGuneshwor Singh bool direction;
376bfcba288SGuneshwor Singh u32 dma_select;
3774dca80b4SColin Ian King u32 timeout;
378bfcba288SGuneshwor Singh u32 retry_count = 0;
379bfcba288SGuneshwor Singh
380bfcba288SGuneshwor Singh runtime = substream->runtime;
381bfcba288SGuneshwor Singh
382bfcba288SGuneshwor Singh if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
383bfcba288SGuneshwor Singh direction = 1;
384bfcba288SGuneshwor Singh else
385bfcba288SGuneshwor Singh direction = 0;
386bfcba288SGuneshwor Singh
387bfcba288SGuneshwor Singh /* 0th stream tag is not used, so DMA ch 0 is for 1st stream tag */
388bfcba288SGuneshwor Singh do {
389bfcba288SGuneshwor Singh timeout = 100;
390bfcba288SGuneshwor Singh dma_select = (direction << GTSCC_CDMAS_DMA_DIR_SHIFT) |
391bfcba288SGuneshwor Singh (azx_dev->core.stream_tag - 1);
392bfcba288SGuneshwor Singh snd_hdac_chip_writel(azx_bus(chip), GTSCC, dma_select);
393bfcba288SGuneshwor Singh
394bfcba288SGuneshwor Singh /* Enable the capture */
395bfcba288SGuneshwor Singh snd_hdac_chip_updatel(azx_bus(chip), GTSCC, 0, GTSCC_TSCCI_MASK);
396bfcba288SGuneshwor Singh
397bfcba288SGuneshwor Singh while (timeout) {
398bfcba288SGuneshwor Singh if (snd_hdac_chip_readl(azx_bus(chip), GTSCC) &
399bfcba288SGuneshwor Singh GTSCC_TSCCD_MASK)
400bfcba288SGuneshwor Singh break;
401bfcba288SGuneshwor Singh
402bfcba288SGuneshwor Singh timeout--;
403bfcba288SGuneshwor Singh }
404bfcba288SGuneshwor Singh
405bfcba288SGuneshwor Singh if (!timeout) {
406bfcba288SGuneshwor Singh dev_err(chip->card->dev, "GTSCC capture Timedout!\n");
407bfcba288SGuneshwor Singh return -EIO;
408bfcba288SGuneshwor Singh }
409bfcba288SGuneshwor Singh
410bfcba288SGuneshwor Singh /* Read wall clock counter */
411bfcba288SGuneshwor Singh wallclk_ctr = snd_hdac_chip_readl(azx_bus(chip), WALFCC);
412bfcba288SGuneshwor Singh
413bfcba288SGuneshwor Singh /* Read TSC counter */
414bfcba288SGuneshwor Singh tsc_counter_l = snd_hdac_chip_readl(azx_bus(chip), TSCCL);
415bfcba288SGuneshwor Singh tsc_counter_h = snd_hdac_chip_readl(azx_bus(chip), TSCCU);
416bfcba288SGuneshwor Singh
417bfcba288SGuneshwor Singh /* Read Link counter */
418bfcba288SGuneshwor Singh ll_counter_l = snd_hdac_chip_readl(azx_bus(chip), LLPCL);
419bfcba288SGuneshwor Singh ll_counter_h = snd_hdac_chip_readl(azx_bus(chip), LLPCU);
420bfcba288SGuneshwor Singh
421bfcba288SGuneshwor Singh /* Ack: registers read done */
422bfcba288SGuneshwor Singh snd_hdac_chip_writel(azx_bus(chip), GTSCC, GTSCC_TSCCD_SHIFT);
423bfcba288SGuneshwor Singh
424bfcba288SGuneshwor Singh tsc_counter = (tsc_counter_h << TSCCU_CCU_SHIFT) |
425bfcba288SGuneshwor Singh tsc_counter_l;
426bfcba288SGuneshwor Singh
427bfcba288SGuneshwor Singh ll_counter = (ll_counter_h << LLPC_CCU_SHIFT) | ll_counter_l;
428bfcba288SGuneshwor Singh wallclk_cycles = wallclk_ctr & WALFCC_CIF_MASK;
429bfcba288SGuneshwor Singh
430bfcba288SGuneshwor Singh /*
431bfcba288SGuneshwor Singh * An error occurs near frame "rollover". The clocks in
432bfcba288SGuneshwor Singh * frame value indicates whether this error may have
433bfcba288SGuneshwor Singh * occurred. Here we use the value of 10 i.e.,
434bfcba288SGuneshwor Singh * HDA_MAX_CYCLE_OFFSET
435bfcba288SGuneshwor Singh */
436bfcba288SGuneshwor Singh if (wallclk_cycles < HDA_MAX_CYCLE_VALUE - HDA_MAX_CYCLE_OFFSET
437bfcba288SGuneshwor Singh && wallclk_cycles > HDA_MAX_CYCLE_OFFSET)
438bfcba288SGuneshwor Singh break;
439bfcba288SGuneshwor Singh
440bfcba288SGuneshwor Singh /*
441bfcba288SGuneshwor Singh * Sleep before we read again, else we may again get
442bfcba288SGuneshwor Singh * value near to MAX_CYCLE. Try to sleep for different
443bfcba288SGuneshwor Singh * amount of time so we dont hit the same number again
444bfcba288SGuneshwor Singh */
445bfcba288SGuneshwor Singh udelay(retry_count++);
446bfcba288SGuneshwor Singh
447bfcba288SGuneshwor Singh } while (retry_count != HDA_MAX_CYCLE_READ_RETRY);
448bfcba288SGuneshwor Singh
449bfcba288SGuneshwor Singh if (retry_count == HDA_MAX_CYCLE_READ_RETRY) {
450bfcba288SGuneshwor Singh dev_err_ratelimited(chip->card->dev,
451bfcba288SGuneshwor Singh "Error in WALFCC cycle count\n");
452bfcba288SGuneshwor Singh return -EIO;
453bfcba288SGuneshwor Singh }
454bfcba288SGuneshwor Singh
455bfcba288SGuneshwor Singh *device = ns_to_ktime(azx_scale64(ll_counter,
456bfcba288SGuneshwor Singh NSEC_PER_SEC, runtime->rate));
457bfcba288SGuneshwor Singh *device = ktime_add_ns(*device, (wallclk_cycles * NSEC_PER_SEC) /
458bfcba288SGuneshwor Singh ((HDA_MAX_CYCLE_VALUE + 1) * runtime->rate));
459bfcba288SGuneshwor Singh
460bfcba288SGuneshwor Singh *system = convert_art_to_tsc(tsc_counter);
461bfcba288SGuneshwor Singh
462bfcba288SGuneshwor Singh return 0;
463bfcba288SGuneshwor Singh }
464bfcba288SGuneshwor Singh
465bfcba288SGuneshwor Singh #else
azx_get_sync_time(ktime_t * device,struct system_counterval_t * system,void * ctx)466bfcba288SGuneshwor Singh static int azx_get_sync_time(ktime_t *device,
467bfcba288SGuneshwor Singh struct system_counterval_t *system, void *ctx)
468bfcba288SGuneshwor Singh {
469bfcba288SGuneshwor Singh return -ENXIO;
470bfcba288SGuneshwor Singh }
471bfcba288SGuneshwor Singh #endif
472bfcba288SGuneshwor Singh
azx_get_crosststamp(struct snd_pcm_substream * substream,struct system_device_crosststamp * xtstamp)473bfcba288SGuneshwor Singh static int azx_get_crosststamp(struct snd_pcm_substream *substream,
474bfcba288SGuneshwor Singh struct system_device_crosststamp *xtstamp)
475bfcba288SGuneshwor Singh {
476bfcba288SGuneshwor Singh return get_device_system_crosststamp(azx_get_sync_time,
477bfcba288SGuneshwor Singh substream, NULL, xtstamp);
478bfcba288SGuneshwor Singh }
479bfcba288SGuneshwor Singh
is_link_time_supported(struct snd_pcm_runtime * runtime,struct snd_pcm_audio_tstamp_config * ts)480bfcba288SGuneshwor Singh static inline bool is_link_time_supported(struct snd_pcm_runtime *runtime,
481bfcba288SGuneshwor Singh struct snd_pcm_audio_tstamp_config *ts)
482bfcba288SGuneshwor Singh {
483bfcba288SGuneshwor Singh if (runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME)
484bfcba288SGuneshwor Singh if (ts->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED)
485bfcba288SGuneshwor Singh return true;
486bfcba288SGuneshwor Singh
487bfcba288SGuneshwor Singh return false;
488bfcba288SGuneshwor Singh }
489bfcba288SGuneshwor 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)4909e94df3aSPierre-Louis Bossart static int azx_get_time_info(struct snd_pcm_substream *substream,
491fcae40c9SBaolin Wang struct timespec64 *system_ts, struct timespec64 *audio_ts,
4929e94df3aSPierre-Louis Bossart struct snd_pcm_audio_tstamp_config *audio_tstamp_config,
4939e94df3aSPierre-Louis Bossart struct snd_pcm_audio_tstamp_report *audio_tstamp_report)
49405e84878SDylan Reid {
49505e84878SDylan Reid struct azx_dev *azx_dev = get_azx_dev(substream);
496bfcba288SGuneshwor Singh struct snd_pcm_runtime *runtime = substream->runtime;
497bfcba288SGuneshwor Singh struct system_device_crosststamp xtstamp;
498bfcba288SGuneshwor Singh int ret;
49905e84878SDylan Reid u64 nsec;
50005e84878SDylan Reid
5019e94df3aSPierre-Louis Bossart if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) &&
5029e94df3aSPierre-Louis Bossart (audio_tstamp_config->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK)) {
5039e94df3aSPierre-Louis Bossart
5049e94df3aSPierre-Louis Bossart snd_pcm_gettime(substream->runtime, system_ts);
5059e94df3aSPierre-Louis Bossart
5067833c3f8STakashi Iwai nsec = timecounter_read(&azx_dev->core.tc);
5079e94df3aSPierre-Louis Bossart if (audio_tstamp_config->report_delay)
50805e84878SDylan Reid nsec = azx_adjust_codec_delay(substream, nsec);
50905e84878SDylan Reid
510fcae40c9SBaolin Wang *audio_ts = ns_to_timespec64(nsec);
5119e94df3aSPierre-Louis Bossart
5129e94df3aSPierre-Louis Bossart audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK;
5139e94df3aSPierre-Louis Bossart audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */
5149e94df3aSPierre-Louis Bossart audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */
5159e94df3aSPierre-Louis Bossart
516bfcba288SGuneshwor Singh } else if (is_link_time_supported(runtime, audio_tstamp_config)) {
517bfcba288SGuneshwor Singh
518bfcba288SGuneshwor Singh ret = azx_get_crosststamp(substream, &xtstamp);
519bfcba288SGuneshwor Singh if (ret)
520bfcba288SGuneshwor Singh return ret;
521bfcba288SGuneshwor Singh
522bfcba288SGuneshwor Singh switch (runtime->tstamp_type) {
523bfcba288SGuneshwor Singh case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC:
524bfcba288SGuneshwor Singh return -EINVAL;
525bfcba288SGuneshwor Singh
526bfcba288SGuneshwor Singh case SNDRV_PCM_TSTAMP_TYPE_MONOTONIC_RAW:
527fcae40c9SBaolin Wang *system_ts = ktime_to_timespec64(xtstamp.sys_monoraw);
528bfcba288SGuneshwor Singh break;
529bfcba288SGuneshwor Singh
530bfcba288SGuneshwor Singh default:
531fcae40c9SBaolin Wang *system_ts = ktime_to_timespec64(xtstamp.sys_realtime);
532bfcba288SGuneshwor Singh break;
533bfcba288SGuneshwor Singh
534bfcba288SGuneshwor Singh }
535bfcba288SGuneshwor Singh
536fcae40c9SBaolin Wang *audio_ts = ktime_to_timespec64(xtstamp.device);
537bfcba288SGuneshwor Singh
538bfcba288SGuneshwor Singh audio_tstamp_report->actual_type =
539bfcba288SGuneshwor Singh SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED;
540bfcba288SGuneshwor Singh audio_tstamp_report->accuracy_report = 1;
541bfcba288SGuneshwor Singh /* 24 MHz WallClock == 42ns resolution */
542bfcba288SGuneshwor Singh audio_tstamp_report->accuracy = 42;
543bfcba288SGuneshwor Singh
544bfcba288SGuneshwor Singh } else {
5459e94df3aSPierre-Louis Bossart audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT;
546bfcba288SGuneshwor Singh }
54705e84878SDylan Reid
54805e84878SDylan Reid return 0;
54905e84878SDylan Reid }
55005e84878SDylan Reid
551c56fc8c9SJulia Lawall static const struct snd_pcm_hardware azx_pcm_hw = {
55205e84878SDylan Reid .info = (SNDRV_PCM_INFO_MMAP |
55305e84878SDylan Reid SNDRV_PCM_INFO_INTERLEAVED |
55405e84878SDylan Reid SNDRV_PCM_INFO_BLOCK_TRANSFER |
55505e84878SDylan Reid SNDRV_PCM_INFO_MMAP_VALID |
55605e84878SDylan Reid /* No full-resume yet implemented */
55705e84878SDylan Reid /* SNDRV_PCM_INFO_RESUME |*/
55805e84878SDylan Reid SNDRV_PCM_INFO_PAUSE |
55905e84878SDylan Reid SNDRV_PCM_INFO_SYNC_START |
5609e94df3aSPierre-Louis Bossart SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */
5619e94df3aSPierre-Louis Bossart SNDRV_PCM_INFO_HAS_LINK_ATIME |
56205e84878SDylan Reid SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
56305e84878SDylan Reid .formats = SNDRV_PCM_FMTBIT_S16_LE,
56405e84878SDylan Reid .rates = SNDRV_PCM_RATE_48000,
56505e84878SDylan Reid .rate_min = 48000,
56605e84878SDylan Reid .rate_max = 48000,
56705e84878SDylan Reid .channels_min = 2,
56805e84878SDylan Reid .channels_max = 2,
56905e84878SDylan Reid .buffer_bytes_max = AZX_MAX_BUF_SIZE,
57005e84878SDylan Reid .period_bytes_min = 128,
57105e84878SDylan Reid .period_bytes_max = AZX_MAX_BUF_SIZE / 2,
57205e84878SDylan Reid .periods_min = 2,
57305e84878SDylan Reid .periods_max = AZX_MAX_FRAG,
57405e84878SDylan Reid .fifo_size = 0,
57505e84878SDylan Reid };
57605e84878SDylan Reid
azx_pcm_open(struct snd_pcm_substream * substream)57705e84878SDylan Reid static int azx_pcm_open(struct snd_pcm_substream *substream)
57805e84878SDylan Reid {
57905e84878SDylan Reid struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
580820cc6cfSTakashi Iwai struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream);
58105e84878SDylan Reid struct azx *chip = apcm->chip;
58205e84878SDylan Reid struct azx_dev *azx_dev;
58305e84878SDylan Reid struct snd_pcm_runtime *runtime = substream->runtime;
58405e84878SDylan Reid int err;
58505e84878SDylan Reid int buff_step;
58605e84878SDylan Reid
5879a6246ffSTakashi Iwai snd_hda_codec_pcm_get(apcm->info);
58805e84878SDylan Reid mutex_lock(&chip->open_mutex);
58905e84878SDylan Reid azx_dev = azx_assign_device(chip, substream);
59018486508SLibin Yang trace_azx_pcm_open(chip, azx_dev);
59105e84878SDylan Reid if (azx_dev == NULL) {
59261ca4107STakashi Iwai err = -EBUSY;
59361ca4107STakashi Iwai goto unlock;
59405e84878SDylan Reid }
595ccc98865STakashi Iwai runtime->private_data = azx_dev;
59650279d9bSGuneshwor Singh
59705e84878SDylan Reid runtime->hw = azx_pcm_hw;
598c1c6c877STakashi Iwai if (chip->gts_present)
599c1c6c877STakashi Iwai runtime->hw.info |= SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME;
60005e84878SDylan Reid runtime->hw.channels_min = hinfo->channels_min;
60105e84878SDylan Reid runtime->hw.channels_max = hinfo->channels_max;
60205e84878SDylan Reid runtime->hw.formats = hinfo->formats;
60305e84878SDylan Reid runtime->hw.rates = hinfo->rates;
60405e84878SDylan Reid snd_pcm_limit_hw_rates(runtime);
60505e84878SDylan Reid snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
60605e84878SDylan Reid
60705e84878SDylan Reid /* avoid wrap-around with wall-clock */
60805e84878SDylan Reid snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME,
60905e84878SDylan Reid 20,
61005e84878SDylan Reid 178000000);
61105e84878SDylan Reid
61205e84878SDylan Reid if (chip->align_buffer_size)
61305e84878SDylan Reid /* constrain buffer sizes to be multiple of 128
61405e84878SDylan Reid bytes. This is more efficient in terms of memory
61505e84878SDylan Reid access but isn't required by the HDA spec and
61605e84878SDylan Reid prevents users from specifying exact period/buffer
61705e84878SDylan Reid sizes. For example for 44.1kHz, a period size set
61805e84878SDylan Reid to 20ms will be rounded to 19.59ms. */
61905e84878SDylan Reid buff_step = 128;
62005e84878SDylan Reid else
62105e84878SDylan Reid /* Don't enforce steps on buffer sizes, still need to
62205e84878SDylan Reid be multiple of 4 bytes (HDA spec). Tested on Intel
62305e84878SDylan Reid HDA controllers, may not work on all devices where
62405e84878SDylan Reid option needs to be disabled */
62505e84878SDylan Reid buff_step = 4;
62605e84878SDylan Reid
62705e84878SDylan Reid snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
62805e84878SDylan Reid buff_step);
62905e84878SDylan Reid snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
63005e84878SDylan Reid buff_step);
631cc72da7dSTakashi Iwai snd_hda_power_up(apcm->codec);
63261ca4107STakashi Iwai if (hinfo->ops.open)
63305e84878SDylan Reid err = hinfo->ops.open(hinfo, apcm->codec, substream);
63461ca4107STakashi Iwai else
63561ca4107STakashi Iwai err = -ENODEV;
63605e84878SDylan Reid if (err < 0) {
63705e84878SDylan Reid azx_release_device(azx_dev);
63861ca4107STakashi Iwai goto powerdown;
63905e84878SDylan Reid }
64005e84878SDylan Reid snd_pcm_limit_hw_rates(runtime);
64105e84878SDylan Reid /* sanity check */
64205e84878SDylan Reid if (snd_BUG_ON(!runtime->hw.channels_min) ||
64305e84878SDylan Reid snd_BUG_ON(!runtime->hw.channels_max) ||
64405e84878SDylan Reid snd_BUG_ON(!runtime->hw.formats) ||
64505e84878SDylan Reid snd_BUG_ON(!runtime->hw.rates)) {
64605e84878SDylan Reid azx_release_device(azx_dev);
64761ca4107STakashi Iwai if (hinfo->ops.close)
64805e84878SDylan Reid hinfo->ops.close(hinfo, apcm->codec, substream);
64961ca4107STakashi Iwai err = -EINVAL;
65061ca4107STakashi Iwai goto powerdown;
65105e84878SDylan Reid }
65205e84878SDylan Reid
6539e94df3aSPierre-Louis Bossart /* disable LINK_ATIME timestamps for capture streams
65405e84878SDylan Reid until we figure out how to handle digital inputs */
6559e94df3aSPierre-Louis Bossart if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
6569e94df3aSPierre-Louis Bossart runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */
6579e94df3aSPierre-Louis Bossart runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME;
6589e94df3aSPierre-Louis Bossart }
65905e84878SDylan Reid
66005e84878SDylan Reid snd_pcm_set_sync(substream);
66105e84878SDylan Reid mutex_unlock(&chip->open_mutex);
66205e84878SDylan Reid return 0;
66361ca4107STakashi Iwai
66461ca4107STakashi Iwai powerdown:
66561ca4107STakashi Iwai snd_hda_power_down(apcm->codec);
66661ca4107STakashi Iwai unlock:
66761ca4107STakashi Iwai mutex_unlock(&chip->open_mutex);
6689a6246ffSTakashi Iwai snd_hda_codec_pcm_put(apcm->info);
66961ca4107STakashi Iwai return err;
67005e84878SDylan Reid }
67105e84878SDylan Reid
6726769e988SJulia Lawall static const struct snd_pcm_ops azx_pcm_ops = {
67305e84878SDylan Reid .open = azx_pcm_open,
67405e84878SDylan Reid .close = azx_pcm_close,
67505e84878SDylan Reid .hw_params = azx_pcm_hw_params,
67605e84878SDylan Reid .hw_free = azx_pcm_hw_free,
67705e84878SDylan Reid .prepare = azx_pcm_prepare,
67805e84878SDylan Reid .trigger = azx_pcm_trigger,
67905e84878SDylan Reid .pointer = azx_pcm_pointer,
6809e94df3aSPierre-Louis Bossart .get_time_info = azx_get_time_info,
68105e84878SDylan Reid };
68205e84878SDylan Reid
azx_pcm_free(struct snd_pcm * pcm)68305e84878SDylan Reid static void azx_pcm_free(struct snd_pcm *pcm)
68405e84878SDylan Reid {
68505e84878SDylan Reid struct azx_pcm *apcm = pcm->private_data;
68605e84878SDylan Reid if (apcm) {
68705e84878SDylan Reid list_del(&apcm->list);
688820cc6cfSTakashi Iwai apcm->info->pcm = NULL;
68905e84878SDylan Reid kfree(apcm);
69005e84878SDylan Reid }
69105e84878SDylan Reid }
69205e84878SDylan Reid
69305e84878SDylan Reid #define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
69405e84878SDylan Reid
snd_hda_attach_pcm_stream(struct hda_bus * _bus,struct hda_codec * codec,struct hda_pcm * cpcm)6950a50575bSTakashi Iwai int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec,
69605e84878SDylan Reid struct hda_pcm *cpcm)
69705e84878SDylan Reid {
698a41d1224STakashi Iwai struct hdac_bus *bus = &_bus->core;
699a41d1224STakashi Iwai struct azx *chip = bus_to_azx(bus);
70005e84878SDylan Reid struct snd_pcm *pcm;
70105e84878SDylan Reid struct azx_pcm *apcm;
70205e84878SDylan Reid int pcm_dev = cpcm->device;
70305e84878SDylan Reid unsigned int size;
70405e84878SDylan Reid int s, err;
705fc478143STakashi Iwai int type = SNDRV_DMA_TYPE_DEV_SG;
70605e84878SDylan Reid
70705e84878SDylan Reid list_for_each_entry(apcm, &chip->pcm_list, list) {
70805e84878SDylan Reid if (apcm->pcm->device == pcm_dev) {
70905e84878SDylan Reid dev_err(chip->card->dev, "PCM %d already exists\n",
71005e84878SDylan Reid pcm_dev);
71105e84878SDylan Reid return -EBUSY;
71205e84878SDylan Reid }
71305e84878SDylan Reid }
71405e84878SDylan Reid err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
71505e84878SDylan Reid cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams,
71605e84878SDylan Reid cpcm->stream[SNDRV_PCM_STREAM_CAPTURE].substreams,
71705e84878SDylan Reid &pcm);
71805e84878SDylan Reid if (err < 0)
71905e84878SDylan Reid return err;
72075b1a8f9SJoe Perches strscpy(pcm->name, cpcm->name, sizeof(pcm->name));
72105e84878SDylan Reid apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
722a3aa60d5SBo Chen if (apcm == NULL) {
723a3aa60d5SBo Chen snd_device_free(chip->card, pcm);
72405e84878SDylan Reid return -ENOMEM;
725a3aa60d5SBo Chen }
72605e84878SDylan Reid apcm->chip = chip;
72705e84878SDylan Reid apcm->pcm = pcm;
72805e84878SDylan Reid apcm->codec = codec;
729820cc6cfSTakashi Iwai apcm->info = cpcm;
73005e84878SDylan Reid pcm->private_data = apcm;
73105e84878SDylan Reid pcm->private_free = azx_pcm_free;
73205e84878SDylan Reid if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM)
73305e84878SDylan Reid pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
73405e84878SDylan Reid list_add_tail(&apcm->list, &chip->pcm_list);
73505e84878SDylan Reid cpcm->pcm = pcm;
73605e84878SDylan Reid for (s = 0; s < 2; s++) {
73705e84878SDylan Reid if (cpcm->stream[s].substreams)
73805e84878SDylan Reid snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
73905e84878SDylan Reid }
74005e84878SDylan Reid /* buffer pre-allocation */
74105e84878SDylan Reid size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
74205e84878SDylan Reid if (size > MAX_PREALLOC_SIZE)
74305e84878SDylan Reid size = MAX_PREALLOC_SIZE;
744fc478143STakashi Iwai if (chip->uc_buffer)
74558a95dfaSTakashi Iwai type = SNDRV_DMA_TYPE_DEV_WC_SG;
7467a6d4a5aSTakashi Iwai snd_pcm_set_managed_buffer_all(pcm, type, chip->card->dev,
74705e84878SDylan Reid size, MAX_PREALLOC_SIZE);
74805e84878SDylan Reid return 0;
74905e84878SDylan Reid }
75005e84878SDylan Reid
azx_command_addr(u32 cmd)7516e85dddcSDylan Reid static unsigned int azx_command_addr(u32 cmd)
7526e85dddcSDylan Reid {
7536e85dddcSDylan Reid unsigned int addr = cmd >> 28;
7546e85dddcSDylan Reid
7556e85dddcSDylan Reid if (addr >= AZX_MAX_CODECS) {
7566e85dddcSDylan Reid snd_BUG();
7576e85dddcSDylan Reid addr = 0;
7586e85dddcSDylan Reid }
7596e85dddcSDylan Reid
7606e85dddcSDylan Reid return addr;
7616e85dddcSDylan Reid }
7626e85dddcSDylan Reid
7636e85dddcSDylan Reid /* receive a response */
azx_rirb_get_response(struct hdac_bus * bus,unsigned int addr,unsigned int * res)764a41d1224STakashi Iwai static int azx_rirb_get_response(struct hdac_bus *bus, unsigned int addr,
765cad372f1STakashi Iwai unsigned int *res)
7666e85dddcSDylan Reid {
767a41d1224STakashi Iwai struct azx *chip = bus_to_azx(bus);
768a41d1224STakashi Iwai struct hda_bus *hbus = &chip->bus;
7695f2cb361STakashi Iwai int err;
7706e85dddcSDylan Reid
7716e85dddcSDylan Reid again:
7725f2cb361STakashi Iwai err = snd_hdac_bus_get_response(bus, addr, res);
7735f2cb361STakashi Iwai if (!err)
774cad372f1STakashi Iwai return 0;
77588452da9STakashi Iwai
776a41d1224STakashi Iwai if (hbus->no_response_fallback)
777cad372f1STakashi Iwai return -EIO;
7786e85dddcSDylan Reid
7798af42130SBard Liao if (!bus->polling_mode) {
7806e85dddcSDylan Reid dev_warn(chip->card->dev,
7816e85dddcSDylan Reid "azx_get_response timeout, switching to polling mode: last cmd=0x%08x\n",
782a41d1224STakashi Iwai bus->last_cmd[addr]);
7838af42130SBard Liao bus->polling_mode = 1;
7846e85dddcSDylan Reid goto again;
7856e85dddcSDylan Reid }
7866e85dddcSDylan Reid
7876e85dddcSDylan Reid if (chip->msi) {
7886e85dddcSDylan Reid dev_warn(chip->card->dev,
7896e85dddcSDylan Reid "No response from codec, disabling MSI: last cmd=0x%08x\n",
790a41d1224STakashi Iwai bus->last_cmd[addr]);
791a41d1224STakashi Iwai if (chip->ops->disable_msi_reset_irq &&
792cad372f1STakashi Iwai chip->ops->disable_msi_reset_irq(chip) < 0)
793cad372f1STakashi Iwai return -EIO;
7946e85dddcSDylan Reid goto again;
7956e85dddcSDylan Reid }
7966e85dddcSDylan Reid
7976e85dddcSDylan Reid if (chip->probing) {
7986e85dddcSDylan Reid /* If this critical timeout happens during the codec probing
7996e85dddcSDylan Reid * phase, this is likely an access to a non-existing codec
8006e85dddcSDylan Reid * slot. Better to return an error and reset the system.
8016e85dddcSDylan Reid */
802cad372f1STakashi Iwai return -EIO;
8036e85dddcSDylan Reid }
8046e85dddcSDylan Reid
80541438f13STakashi Iwai /* no fallback mechanism? */
80641438f13STakashi Iwai if (!chip->fallback_to_single_cmd)
80741438f13STakashi Iwai return -EIO;
80841438f13STakashi Iwai
8096e85dddcSDylan Reid /* a fatal communication error; need either to reset or to fallback
8106e85dddcSDylan Reid * to the single_cmd mode
8116e85dddcSDylan Reid */
812a41d1224STakashi Iwai if (hbus->allow_bus_reset && !hbus->response_reset && !hbus->in_reset) {
813a41d1224STakashi Iwai hbus->response_reset = 1;
814dd65f7e1STakashi Iwai dev_err(chip->card->dev,
815dd65f7e1STakashi Iwai "No response from codec, resetting bus: last cmd=0x%08x\n",
816dd65f7e1STakashi Iwai bus->last_cmd[addr]);
817cad372f1STakashi Iwai return -EAGAIN; /* give a chance to retry */
8186e85dddcSDylan Reid }
8196e85dddcSDylan Reid
820475feec0STakashi Iwai dev_err(chip->card->dev,
8216e85dddcSDylan Reid "azx_get_response timeout, switching to single_cmd mode: last cmd=0x%08x\n",
822a41d1224STakashi Iwai bus->last_cmd[addr]);
8236e85dddcSDylan Reid chip->single_cmd = 1;
824a41d1224STakashi Iwai hbus->response_reset = 0;
825a41d1224STakashi Iwai snd_hdac_bus_stop_cmd_io(bus);
826cad372f1STakashi Iwai return -EIO;
8276e85dddcSDylan Reid }
8286e85dddcSDylan Reid
8296e85dddcSDylan Reid /*
8306e85dddcSDylan Reid * Use the single immediate command instead of CORB/RIRB for simplicity
8316e85dddcSDylan Reid *
8326e85dddcSDylan Reid * Note: according to Intel, this is not preferred use. The command was
8336e85dddcSDylan Reid * intended for the BIOS only, and may get confused with unsolicited
8346e85dddcSDylan Reid * responses. So, we shouldn't use it for normal operation from the
8356e85dddcSDylan Reid * driver.
8366e85dddcSDylan Reid * I left the codes, however, for debugging/testing purposes.
8376e85dddcSDylan Reid */
8386e85dddcSDylan Reid
8396e85dddcSDylan Reid /* receive a response */
azx_single_wait_for_response(struct azx * chip,unsigned int addr)8406e85dddcSDylan Reid static int azx_single_wait_for_response(struct azx *chip, unsigned int addr)
8416e85dddcSDylan Reid {
8426e85dddcSDylan Reid int timeout = 50;
8436e85dddcSDylan Reid
8446e85dddcSDylan Reid while (timeout--) {
8456e85dddcSDylan Reid /* check IRV busy bit */
846fb1d8ac2STakashi Iwai if (azx_readw(chip, IRS) & AZX_IRS_VALID) {
8476e85dddcSDylan Reid /* reuse rirb.res as the response return value */
848a41d1224STakashi Iwai azx_bus(chip)->rirb.res[addr] = azx_readl(chip, IR);
8496e85dddcSDylan Reid return 0;
8506e85dddcSDylan Reid }
8516e85dddcSDylan Reid udelay(1);
8526e85dddcSDylan Reid }
8536e85dddcSDylan Reid if (printk_ratelimit())
8546e85dddcSDylan Reid dev_dbg(chip->card->dev, "get_response timeout: IRS=0x%x\n",
8556e85dddcSDylan Reid azx_readw(chip, IRS));
856a41d1224STakashi Iwai azx_bus(chip)->rirb.res[addr] = -1;
8576e85dddcSDylan Reid return -EIO;
8586e85dddcSDylan Reid }
8596e85dddcSDylan Reid
8606e85dddcSDylan Reid /* send a command */
azx_single_send_cmd(struct hdac_bus * bus,u32 val)861a41d1224STakashi Iwai static int azx_single_send_cmd(struct hdac_bus *bus, u32 val)
8626e85dddcSDylan Reid {
863a41d1224STakashi Iwai struct azx *chip = bus_to_azx(bus);
8646e85dddcSDylan Reid unsigned int addr = azx_command_addr(val);
8656e85dddcSDylan Reid int timeout = 50;
8666e85dddcSDylan Reid
867a41d1224STakashi Iwai bus->last_cmd[azx_command_addr(val)] = val;
8686e85dddcSDylan Reid while (timeout--) {
8696e85dddcSDylan Reid /* check ICB busy bit */
870fb1d8ac2STakashi Iwai if (!((azx_readw(chip, IRS) & AZX_IRS_BUSY))) {
8716e85dddcSDylan Reid /* Clear IRV valid bit */
8726e85dddcSDylan Reid azx_writew(chip, IRS, azx_readw(chip, IRS) |
873fb1d8ac2STakashi Iwai AZX_IRS_VALID);
8746e85dddcSDylan Reid azx_writel(chip, IC, val);
8756e85dddcSDylan Reid azx_writew(chip, IRS, azx_readw(chip, IRS) |
876fb1d8ac2STakashi Iwai AZX_IRS_BUSY);
8776e85dddcSDylan Reid return azx_single_wait_for_response(chip, addr);
8786e85dddcSDylan Reid }
8796e85dddcSDylan Reid udelay(1);
8806e85dddcSDylan Reid }
8816e85dddcSDylan Reid if (printk_ratelimit())
8826e85dddcSDylan Reid dev_dbg(chip->card->dev,
8836e85dddcSDylan Reid "send_cmd timeout: IRS=0x%x, val=0x%x\n",
8846e85dddcSDylan Reid azx_readw(chip, IRS), val);
8856e85dddcSDylan Reid return -EIO;
8866e85dddcSDylan Reid }
8876e85dddcSDylan Reid
8886e85dddcSDylan Reid /* receive a response */
azx_single_get_response(struct hdac_bus * bus,unsigned int addr,unsigned int * res)889a41d1224STakashi Iwai static int azx_single_get_response(struct hdac_bus *bus, unsigned int addr,
890cad372f1STakashi Iwai unsigned int *res)
8916e85dddcSDylan Reid {
892cad372f1STakashi Iwai if (res)
893a41d1224STakashi Iwai *res = bus->rirb.res[addr];
894cad372f1STakashi Iwai return 0;
8956e85dddcSDylan Reid }
8966e85dddcSDylan Reid
8976e85dddcSDylan Reid /*
8986e85dddcSDylan Reid * The below are the main callbacks from hda_codec.
8996e85dddcSDylan Reid *
9006e85dddcSDylan Reid * They are just the skeleton to call sub-callbacks according to the
9016e85dddcSDylan Reid * current setting of chip->single_cmd.
9026e85dddcSDylan Reid */
9036e85dddcSDylan Reid
9046e85dddcSDylan Reid /* send a command */
azx_send_cmd(struct hdac_bus * bus,unsigned int val)905a41d1224STakashi Iwai static int azx_send_cmd(struct hdac_bus *bus, unsigned int val)
9066e85dddcSDylan Reid {
907a41d1224STakashi Iwai struct azx *chip = bus_to_azx(bus);
9086e85dddcSDylan Reid
9096e85dddcSDylan Reid if (chip->disabled)
9106e85dddcSDylan Reid return 0;
9116e85dddcSDylan Reid if (chip->single_cmd)
9126e85dddcSDylan Reid return azx_single_send_cmd(bus, val);
9136e85dddcSDylan Reid else
914a41d1224STakashi Iwai return snd_hdac_bus_send_cmd(bus, val);
9156e85dddcSDylan Reid }
9166e85dddcSDylan Reid
9176e85dddcSDylan Reid /* get a response */
azx_get_response(struct hdac_bus * bus,unsigned int addr,unsigned int * res)918a41d1224STakashi Iwai static int azx_get_response(struct hdac_bus *bus, unsigned int addr,
919cad372f1STakashi Iwai unsigned int *res)
9206e85dddcSDylan Reid {
921a41d1224STakashi Iwai struct azx *chip = bus_to_azx(bus);
922a41d1224STakashi Iwai
9236e85dddcSDylan Reid if (chip->disabled)
9246e85dddcSDylan Reid return 0;
9256e85dddcSDylan Reid if (chip->single_cmd)
926cad372f1STakashi Iwai return azx_single_get_response(bus, addr, res);
9276e85dddcSDylan Reid else
928cad372f1STakashi Iwai return azx_rirb_get_response(bus, addr, res);
9296e85dddcSDylan Reid }
9306e85dddcSDylan Reid
9317e8be1b3STakashi Iwai static const struct hdac_bus_ops bus_core_ops = {
9327e8be1b3STakashi Iwai .command = azx_send_cmd,
9337e8be1b3STakashi Iwai .get_response = azx_get_response,
9347e8be1b3STakashi Iwai };
9357e8be1b3STakashi Iwai
9362b5fd6c2SDylan Reid #ifdef CONFIG_SND_HDA_DSP_LOADER
9372b5fd6c2SDylan Reid /*
9382b5fd6c2SDylan Reid * DSP loading code (e.g. for CA0132)
9392b5fd6c2SDylan Reid */
9402b5fd6c2SDylan Reid
9412b5fd6c2SDylan Reid /* use the first stream for loading DSP */
9422b5fd6c2SDylan Reid static struct azx_dev *
azx_get_dsp_loader_dev(struct azx * chip)9432b5fd6c2SDylan Reid azx_get_dsp_loader_dev(struct azx *chip)
9442b5fd6c2SDylan Reid {
9457833c3f8STakashi Iwai struct hdac_bus *bus = azx_bus(chip);
9467833c3f8STakashi Iwai struct hdac_stream *s;
9477833c3f8STakashi Iwai
9487833c3f8STakashi Iwai list_for_each_entry(s, &bus->stream_list, list)
9497833c3f8STakashi Iwai if (s->index == chip->playback_index_offset)
9507833c3f8STakashi Iwai return stream_to_azx_dev(s);
9517833c3f8STakashi Iwai
9527833c3f8STakashi Iwai return NULL;
9532b5fd6c2SDylan Reid }
9542b5fd6c2SDylan Reid
snd_hda_codec_load_dsp_prepare(struct hda_codec * codec,unsigned int format,unsigned int byte_size,struct snd_dma_buffer * bufp)9550a50575bSTakashi Iwai int snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
9562b5fd6c2SDylan Reid unsigned int byte_size,
9572b5fd6c2SDylan Reid struct snd_dma_buffer *bufp)
9582b5fd6c2SDylan Reid {
9590a50575bSTakashi Iwai struct hdac_bus *bus = &codec->bus->core;
960a41d1224STakashi Iwai struct azx *chip = bus_to_azx(bus);
9612b5fd6c2SDylan Reid struct azx_dev *azx_dev;
962ccc98865STakashi Iwai struct hdac_stream *hstr;
963ccc98865STakashi Iwai bool saved = false;
9642b5fd6c2SDylan Reid int err;
9652b5fd6c2SDylan Reid
9662b5fd6c2SDylan Reid azx_dev = azx_get_dsp_loader_dev(chip);
967ccc98865STakashi Iwai hstr = azx_stream(azx_dev);
968a41d1224STakashi Iwai spin_lock_irq(&bus->reg_lock);
969ccc98865STakashi Iwai if (hstr->opened) {
9702b5fd6c2SDylan Reid chip->saved_azx_dev = *azx_dev;
971ccc98865STakashi Iwai saved = true;
972ccc98865STakashi Iwai }
973a41d1224STakashi Iwai spin_unlock_irq(&bus->reg_lock);
9742b5fd6c2SDylan Reid
975ccc98865STakashi Iwai err = snd_hdac_dsp_prepare(hstr, format, byte_size, bufp);
976ccc98865STakashi Iwai if (err < 0) {
977a41d1224STakashi Iwai spin_lock_irq(&bus->reg_lock);
978ccc98865STakashi Iwai if (saved)
9792b5fd6c2SDylan Reid *azx_dev = chip->saved_azx_dev;
980a41d1224STakashi Iwai spin_unlock_irq(&bus->reg_lock);
981ccc98865STakashi Iwai return err;
982ccc98865STakashi Iwai }
983ccc98865STakashi Iwai
9846d23c8f5STakashi Iwai hstr->prepared = 0;
9852b5fd6c2SDylan Reid return err;
9862b5fd6c2SDylan Reid }
9870a50575bSTakashi Iwai EXPORT_SYMBOL_GPL(snd_hda_codec_load_dsp_prepare);
9882b5fd6c2SDylan Reid
snd_hda_codec_load_dsp_trigger(struct hda_codec * codec,bool start)9890a50575bSTakashi Iwai void snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start)
9902b5fd6c2SDylan Reid {
9910a50575bSTakashi Iwai struct hdac_bus *bus = &codec->bus->core;
992a41d1224STakashi Iwai struct azx *chip = bus_to_azx(bus);
9932b5fd6c2SDylan Reid struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
9942b5fd6c2SDylan Reid
995ccc98865STakashi Iwai snd_hdac_dsp_trigger(azx_stream(azx_dev), start);
9962b5fd6c2SDylan Reid }
9970a50575bSTakashi Iwai EXPORT_SYMBOL_GPL(snd_hda_codec_load_dsp_trigger);
9982b5fd6c2SDylan Reid
snd_hda_codec_load_dsp_cleanup(struct hda_codec * codec,struct snd_dma_buffer * dmab)9990a50575bSTakashi Iwai void snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
10002b5fd6c2SDylan Reid struct snd_dma_buffer *dmab)
10012b5fd6c2SDylan Reid {
10020a50575bSTakashi Iwai struct hdac_bus *bus = &codec->bus->core;
1003a41d1224STakashi Iwai struct azx *chip = bus_to_azx(bus);
10042b5fd6c2SDylan Reid struct azx_dev *azx_dev = azx_get_dsp_loader_dev(chip);
1005ccc98865STakashi Iwai struct hdac_stream *hstr = azx_stream(azx_dev);
10062b5fd6c2SDylan Reid
10070a50575bSTakashi Iwai if (!dmab->area || !hstr->locked)
10082b5fd6c2SDylan Reid return;
10092b5fd6c2SDylan Reid
1010ccc98865STakashi Iwai snd_hdac_dsp_cleanup(hstr, dmab);
1011a41d1224STakashi Iwai spin_lock_irq(&bus->reg_lock);
1012ccc98865STakashi Iwai if (hstr->opened)
10132b5fd6c2SDylan Reid *azx_dev = chip->saved_azx_dev;
1014ccc98865STakashi Iwai hstr->locked = false;
1015a41d1224STakashi Iwai spin_unlock_irq(&bus->reg_lock);
10162b5fd6c2SDylan Reid }
10170a50575bSTakashi Iwai EXPORT_SYMBOL_GPL(snd_hda_codec_load_dsp_cleanup);
10182b5fd6c2SDylan Reid #endif /* CONFIG_SND_HDA_DSP_LOADER */
10192b5fd6c2SDylan Reid
1020f43923ffSDylan Reid /*
1021f43923ffSDylan Reid * reset and start the controller registers
1022f43923ffSDylan Reid */
azx_init_chip(struct azx * chip,bool full_reset)102317c3ad03SThierry Reding void azx_init_chip(struct azx *chip, bool full_reset)
1024f43923ffSDylan Reid {
1025a41d1224STakashi Iwai if (snd_hdac_bus_init_chip(azx_bus(chip), full_reset)) {
1026a41d1224STakashi Iwai /* correct RINTCNT for CXT */
1027a41d1224STakashi Iwai if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
1028a41d1224STakashi Iwai azx_writew(chip, RINTCNT, 0xc0);
1029a41d1224STakashi Iwai }
1030f43923ffSDylan Reid }
1031f43923ffSDylan Reid EXPORT_SYMBOL_GPL(azx_init_chip);
1032f43923ffSDylan Reid
azx_stop_all_streams(struct azx * chip)10337833c3f8STakashi Iwai void azx_stop_all_streams(struct azx *chip)
10347833c3f8STakashi Iwai {
10357833c3f8STakashi Iwai struct hdac_bus *bus = azx_bus(chip);
10367833c3f8STakashi Iwai
103724ad3835SPierre-Louis Bossart snd_hdac_stop_streams(bus);
10387833c3f8STakashi Iwai }
10397833c3f8STakashi Iwai EXPORT_SYMBOL_GPL(azx_stop_all_streams);
10407833c3f8STakashi Iwai
azx_stop_chip(struct azx * chip)1041f43923ffSDylan Reid void azx_stop_chip(struct azx *chip)
1042f43923ffSDylan Reid {
1043a41d1224STakashi Iwai snd_hdac_bus_stop_chip(azx_bus(chip));
1044f43923ffSDylan Reid }
1045154867cfSDylan Reid EXPORT_SYMBOL_GPL(azx_stop_chip);
1046f43923ffSDylan Reid
1047f0b1df88SDylan Reid /*
1048f0b1df88SDylan Reid * interrupt handler
1049f0b1df88SDylan Reid */
stream_update(struct hdac_bus * bus,struct hdac_stream * s)10507833c3f8STakashi Iwai static void stream_update(struct hdac_bus *bus, struct hdac_stream *s)
10517833c3f8STakashi Iwai {
1052a41d1224STakashi Iwai struct azx *chip = bus_to_azx(bus);
10537833c3f8STakashi Iwai struct azx_dev *azx_dev = stream_to_azx_dev(s);
10547833c3f8STakashi Iwai
10557833c3f8STakashi Iwai /* check whether this IRQ is really acceptable */
10567833c3f8STakashi Iwai if (!chip->ops->position_check ||
10577833c3f8STakashi Iwai chip->ops->position_check(chip, azx_dev)) {
1058a41d1224STakashi Iwai spin_unlock(&bus->reg_lock);
1059a41d1224STakashi Iwai snd_pcm_period_elapsed(azx_stream(azx_dev)->substream);
1060a41d1224STakashi Iwai spin_lock(&bus->reg_lock);
10617833c3f8STakashi Iwai }
10627833c3f8STakashi Iwai }
10637833c3f8STakashi Iwai
azx_interrupt(int irq,void * dev_id)1064f0b1df88SDylan Reid irqreturn_t azx_interrupt(int irq, void *dev_id)
1065f0b1df88SDylan Reid {
1066f0b1df88SDylan Reid struct azx *chip = dev_id;
10677833c3f8STakashi Iwai struct hdac_bus *bus = azx_bus(chip);
1068f0b1df88SDylan Reid u32 status;
1069473f4145STakashi Iwai bool active, handled = false;
1070473f4145STakashi Iwai int repeat = 0; /* count for avoiding endless loop */
1071f0b1df88SDylan Reid
1072641d334bSRafael J. Wysocki #ifdef CONFIG_PM
1073364aa716STakashi Iwai if (azx_has_pm_runtime(chip))
10747b0a48f3SDylan Reid if (!pm_runtime_active(chip->card->dev))
1075f0b1df88SDylan Reid return IRQ_NONE;
1076f0b1df88SDylan Reid #endif
1077f0b1df88SDylan Reid
1078a41d1224STakashi Iwai spin_lock(&bus->reg_lock);
1079f0b1df88SDylan Reid
1080473f4145STakashi Iwai if (chip->disabled)
1081473f4145STakashi Iwai goto unlock;
1082f0b1df88SDylan Reid
1083473f4145STakashi Iwai do {
1084f0b1df88SDylan Reid status = azx_readl(chip, INTSTS);
1085473f4145STakashi Iwai if (status == 0 || status == 0xffffffff)
1086473f4145STakashi Iwai break;
1087f0b1df88SDylan Reid
1088473f4145STakashi Iwai handled = true;
1089473f4145STakashi Iwai active = false;
1090473f4145STakashi Iwai if (snd_hdac_bus_handle_stream_irq(bus, status, stream_update))
1091473f4145STakashi Iwai active = true;
1092f0b1df88SDylan Reid
1093f0b1df88SDylan Reid status = azx_readb(chip, RIRBSTS);
1094f0b1df88SDylan Reid if (status & RIRB_INT_MASK) {
10956d011d50SMohan Kumar /*
10966d011d50SMohan Kumar * Clearing the interrupt status here ensures that no
10976d011d50SMohan Kumar * interrupt gets masked after the RIRB wp is read in
10986d011d50SMohan Kumar * snd_hdac_bus_update_rirb. This avoids a possible
10996d011d50SMohan Kumar * race condition where codec response in RIRB may
11006d011d50SMohan Kumar * remain unserviced by IRQ, eventually falling back
11016d011d50SMohan Kumar * to polling mode in azx_rirb_get_response.
11026d011d50SMohan Kumar */
11036d011d50SMohan Kumar azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
1104473f4145STakashi Iwai active = true;
1105f0b1df88SDylan Reid if (status & RIRB_INT_RESPONSE) {
1106ef85f299STakashi Iwai if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
1107f0b1df88SDylan Reid udelay(80);
1108a41d1224STakashi Iwai snd_hdac_bus_update_rirb(bus);
1109f0b1df88SDylan Reid }
1110f0b1df88SDylan Reid }
1111473f4145STakashi Iwai } while (active && ++repeat < 10);
1112f0b1df88SDylan Reid
1113473f4145STakashi Iwai unlock:
1114a41d1224STakashi Iwai spin_unlock(&bus->reg_lock);
1115f0b1df88SDylan Reid
1116473f4145STakashi Iwai return IRQ_RETVAL(handled);
1117f0b1df88SDylan Reid }
1118f0b1df88SDylan Reid EXPORT_SYMBOL_GPL(azx_interrupt);
1119f0b1df88SDylan Reid
1120154867cfSDylan Reid /*
1121154867cfSDylan Reid * Codec initerface
1122154867cfSDylan Reid */
1123154867cfSDylan Reid
1124154867cfSDylan Reid /*
1125154867cfSDylan Reid * Probe the given codec address
1126154867cfSDylan Reid */
probe_codec(struct azx * chip,int addr)1127154867cfSDylan Reid static int probe_codec(struct azx *chip, int addr)
1128154867cfSDylan Reid {
1129154867cfSDylan Reid unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
1130154867cfSDylan Reid (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
11317833c3f8STakashi Iwai struct hdac_bus *bus = azx_bus(chip);
1132cad372f1STakashi Iwai int err;
1133a41d1224STakashi Iwai unsigned int res = -1;
1134154867cfSDylan Reid
11357e8be1b3STakashi Iwai mutex_lock(&bus->cmd_mutex);
1136154867cfSDylan Reid chip->probing = 1;
11377e8be1b3STakashi Iwai azx_send_cmd(bus, cmd);
11387e8be1b3STakashi Iwai err = azx_get_response(bus, addr, &res);
1139154867cfSDylan Reid chip->probing = 0;
11407e8be1b3STakashi Iwai mutex_unlock(&bus->cmd_mutex);
1141cad372f1STakashi Iwai if (err < 0 || res == -1)
1142154867cfSDylan Reid return -EIO;
1143154867cfSDylan Reid dev_dbg(chip->card->dev, "codec #%d probed OK\n", addr);
1144154867cfSDylan Reid return 0;
1145154867cfSDylan Reid }
1146154867cfSDylan Reid
snd_hda_bus_reset(struct hda_bus * bus)11470a50575bSTakashi Iwai void snd_hda_bus_reset(struct hda_bus *bus)
1148154867cfSDylan Reid {
1149a41d1224STakashi Iwai struct azx *chip = bus_to_azx(&bus->core);
1150154867cfSDylan Reid
1151154867cfSDylan Reid bus->in_reset = 1;
1152154867cfSDylan Reid azx_stop_chip(chip);
115317c3ad03SThierry Reding azx_init_chip(chip, true);
1154a41d1224STakashi Iwai if (bus->core.chip_init)
11550a50575bSTakashi Iwai snd_hda_bus_reset_codecs(bus);
1156154867cfSDylan Reid bus->in_reset = 0;
1157154867cfSDylan Reid }
1158154867cfSDylan Reid
115996d2bd6eSTakashi Iwai /* HD-audio bus initialization */
azx_bus_init(struct azx * chip,const char * model)116019abfefdSTakashi Iwai int azx_bus_init(struct azx *chip, const char *model)
1161154867cfSDylan Reid {
1162a41d1224STakashi Iwai struct hda_bus *bus = &chip->bus;
116396d2bd6eSTakashi Iwai int err;
1164154867cfSDylan Reid
116519abfefdSTakashi Iwai err = snd_hdac_bus_init(&bus->core, chip->card->dev, &bus_core_ops);
1166154867cfSDylan Reid if (err < 0)
1167154867cfSDylan Reid return err;
1168154867cfSDylan Reid
1169a41d1224STakashi Iwai bus->card = chip->card;
1170a41d1224STakashi Iwai mutex_init(&bus->prepare_mutex);
1171ef744978STakashi Iwai bus->pci = chip->pci;
1172ef744978STakashi Iwai bus->modelname = model;
11732f0eaad9STakashi Iwai bus->mixer_assigned = -1;
1174ccc98865STakashi Iwai bus->core.snoop = azx_snoop(chip);
1175ccc98865STakashi Iwai if (chip->get_position[0] != azx_get_pos_lpib ||
1176ccc98865STakashi Iwai chip->get_position[1] != azx_get_pos_lpib)
1177ccc98865STakashi Iwai bus->core.use_posbuf = true;
11784f0189beSTakashi Iwai bus->core.bdl_pos_adj = chip->bdl_pos_adj;
1179a41d1224STakashi Iwai if (chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR)
1180a41d1224STakashi Iwai bus->core.corbrp_self_clear = true;
1181ef744978STakashi Iwai
1182de1ab6afSTakashi Iwai if (chip->driver_caps & AZX_DCAPS_4K_BDLE_BOUNDARY)
1183de1ab6afSTakashi Iwai bus->core.align_bdle_4k = true;
1184de1ab6afSTakashi Iwai
1185f34a4c9dSTakashi Iwai /* enable sync_write flag for stable communication as default */
1186d068ebc2STakashi Iwai bus->core.sync_write = 1;
118796d2bd6eSTakashi Iwai
118896d2bd6eSTakashi Iwai return 0;
118996d2bd6eSTakashi Iwai }
1190a41d1224STakashi Iwai EXPORT_SYMBOL_GPL(azx_bus_init);
119196d2bd6eSTakashi Iwai
119296d2bd6eSTakashi Iwai /* Probe codecs */
azx_probe_codecs(struct azx * chip,unsigned int max_slots)119396d2bd6eSTakashi Iwai int azx_probe_codecs(struct azx *chip, unsigned int max_slots)
119496d2bd6eSTakashi Iwai {
1195a41d1224STakashi Iwai struct hdac_bus *bus = azx_bus(chip);
119696d2bd6eSTakashi Iwai int c, codecs, err;
119796d2bd6eSTakashi Iwai
1198154867cfSDylan Reid codecs = 0;
1199154867cfSDylan Reid if (!max_slots)
1200154867cfSDylan Reid max_slots = AZX_DEFAULT_CODECS;
1201154867cfSDylan Reid
1202154867cfSDylan Reid /* First try to probe all given codec slots */
1203154867cfSDylan Reid for (c = 0; c < max_slots; c++) {
1204a41d1224STakashi Iwai if ((bus->codec_mask & (1 << c)) & chip->codec_probe_mask) {
1205154867cfSDylan Reid if (probe_codec(chip, c) < 0) {
1206154867cfSDylan Reid /* Some BIOSen give you wrong codec addresses
1207154867cfSDylan Reid * that don't exist
1208154867cfSDylan Reid */
1209154867cfSDylan Reid dev_warn(chip->card->dev,
1210154867cfSDylan Reid "Codec #%d probe error; disabling it...\n", c);
1211a41d1224STakashi Iwai bus->codec_mask &= ~(1 << c);
1212154867cfSDylan Reid /* More badly, accessing to a non-existing
1213154867cfSDylan Reid * codec often screws up the controller chip,
1214154867cfSDylan Reid * and disturbs the further communications.
1215154867cfSDylan Reid * Thus if an error occurs during probing,
1216154867cfSDylan Reid * better to reset the controller chip to
1217154867cfSDylan Reid * get back to the sanity state.
1218154867cfSDylan Reid */
1219154867cfSDylan Reid azx_stop_chip(chip);
122017c3ad03SThierry Reding azx_init_chip(chip, true);
1221154867cfSDylan Reid }
1222154867cfSDylan Reid }
1223154867cfSDylan Reid }
1224154867cfSDylan Reid
1225154867cfSDylan Reid /* Then create codec instances */
1226154867cfSDylan Reid for (c = 0; c < max_slots; c++) {
1227a41d1224STakashi Iwai if ((bus->codec_mask & (1 << c)) & chip->codec_probe_mask) {
1228154867cfSDylan Reid struct hda_codec *codec;
1229a41d1224STakashi Iwai err = snd_hda_codec_new(&chip->bus, chip->card, c, &codec);
1230154867cfSDylan Reid if (err < 0)
1231154867cfSDylan Reid continue;
12323a182c84STakashi Iwai codec->jackpoll_interval = chip->jackpoll_interval;
1233154867cfSDylan Reid codec->beep_mode = chip->beep_mode;
1234d045bcefSJaroslav Kysela codec->ctl_dev_id = chip->ctl_dev_id;
1235154867cfSDylan Reid codecs++;
1236154867cfSDylan Reid }
1237154867cfSDylan Reid }
1238154867cfSDylan Reid if (!codecs) {
1239154867cfSDylan Reid dev_err(chip->card->dev, "no codecs initialized\n");
1240154867cfSDylan Reid return -ENXIO;
1241154867cfSDylan Reid }
1242154867cfSDylan Reid return 0;
1243154867cfSDylan Reid }
124496d2bd6eSTakashi Iwai EXPORT_SYMBOL_GPL(azx_probe_codecs);
1245154867cfSDylan Reid
1246154867cfSDylan Reid /* configure each codec instance */
azx_codec_configure(struct azx * chip)1247154867cfSDylan Reid int azx_codec_configure(struct azx *chip)
1248154867cfSDylan Reid {
1249d94815f9STakashi Iwai struct hda_codec *codec, *next;
1250c0f1886dSTakashi Iwai int success = 0;
1251d94815f9STakashi Iwai
1252c0f1886dSTakashi Iwai list_for_each_codec(codec, &chip->bus) {
1253c0f1886dSTakashi Iwai if (!snd_hda_codec_configure(codec))
1254c0f1886dSTakashi Iwai success++;
1255154867cfSDylan Reid }
125617890880STakashi Iwai
1257c0f1886dSTakashi Iwai if (success) {
1258c0f1886dSTakashi Iwai /* unregister failed codecs if any codec has been probed */
1259c0f1886dSTakashi Iwai list_for_each_codec_safe(codec, next, &chip->bus) {
1260c0f1886dSTakashi Iwai if (!codec->configured) {
1261c0f1886dSTakashi Iwai codec_err(codec, "Unable to configure, disabling\n");
1262c0f1886dSTakashi Iwai snd_hdac_device_unregister(&codec->core);
1263c0f1886dSTakashi Iwai }
1264c0f1886dSTakashi Iwai }
1265c0f1886dSTakashi Iwai }
1266c0f1886dSTakashi Iwai
1267c0f1886dSTakashi Iwai return success ? 0 : -ENODEV;
1268154867cfSDylan Reid }
1269154867cfSDylan Reid EXPORT_SYMBOL_GPL(azx_codec_configure);
1270154867cfSDylan Reid
stream_direction(struct azx * chip,unsigned char index)12717833c3f8STakashi Iwai static int stream_direction(struct azx *chip, unsigned char index)
127293e3423eSRafal Redzimski {
12737833c3f8STakashi Iwai if (index >= chip->capture_index_offset &&
12747833c3f8STakashi Iwai index < chip->capture_index_offset + chip->capture_streams)
12757833c3f8STakashi Iwai return SNDRV_PCM_STREAM_CAPTURE;
12767833c3f8STakashi Iwai return SNDRV_PCM_STREAM_PLAYBACK;
127793e3423eSRafal Redzimski }
127893e3423eSRafal Redzimski
1279154867cfSDylan Reid /* initialize SD streams */
azx_init_streams(struct azx * chip)1280a41d1224STakashi Iwai int azx_init_streams(struct azx *chip)
1281154867cfSDylan Reid {
1282154867cfSDylan Reid int i;
12837833c3f8STakashi Iwai int stream_tags[2] = { 0, 0 };
1284154867cfSDylan Reid
1285154867cfSDylan Reid /* initialize each stream (aka device)
1286154867cfSDylan Reid * assign the starting bdl address to each stream (device)
1287154867cfSDylan Reid * and initialize
1288154867cfSDylan Reid */
1289154867cfSDylan Reid for (i = 0; i < chip->num_streams; i++) {
12907833c3f8STakashi Iwai struct azx_dev *azx_dev = kzalloc(sizeof(*azx_dev), GFP_KERNEL);
12917833c3f8STakashi Iwai int dir, tag;
129293e3423eSRafal Redzimski
12937833c3f8STakashi Iwai if (!azx_dev)
12947833c3f8STakashi Iwai return -ENOMEM;
12957833c3f8STakashi Iwai
12967833c3f8STakashi Iwai dir = stream_direction(chip, i);
129793e3423eSRafal Redzimski /* stream tag must be unique throughout
129893e3423eSRafal Redzimski * the stream direction group,
129993e3423eSRafal Redzimski * valid values 1...15
130093e3423eSRafal Redzimski * use separate stream tag if the flag
130193e3423eSRafal Redzimski * AZX_DCAPS_SEPARATE_STREAM_TAG is used
130293e3423eSRafal Redzimski */
130393e3423eSRafal Redzimski if (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG)
13047833c3f8STakashi Iwai tag = ++stream_tags[dir];
130593e3423eSRafal Redzimski else
13067833c3f8STakashi Iwai tag = i + 1;
13077833c3f8STakashi Iwai snd_hdac_stream_init(azx_bus(chip), azx_stream(azx_dev),
13087833c3f8STakashi Iwai i, dir, tag);
1309154867cfSDylan Reid }
1310154867cfSDylan Reid
1311154867cfSDylan Reid return 0;
1312154867cfSDylan Reid }
1313a41d1224STakashi Iwai EXPORT_SYMBOL_GPL(azx_init_streams);
1314a41d1224STakashi Iwai
azx_free_streams(struct azx * chip)1315a41d1224STakashi Iwai void azx_free_streams(struct azx *chip)
1316a41d1224STakashi Iwai {
1317a41d1224STakashi Iwai struct hdac_bus *bus = azx_bus(chip);
1318a41d1224STakashi Iwai struct hdac_stream *s;
1319a41d1224STakashi Iwai
1320a41d1224STakashi Iwai while (!list_empty(&bus->stream_list)) {
1321a41d1224STakashi Iwai s = list_first_entry(&bus->stream_list, struct hdac_stream, list);
1322a41d1224STakashi Iwai list_del(&s->list);
1323a41d1224STakashi Iwai kfree(stream_to_azx_dev(s));
1324a41d1224STakashi Iwai }
1325a41d1224STakashi Iwai }
1326a41d1224STakashi Iwai EXPORT_SYMBOL_GPL(azx_free_streams);
1327