]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/x86/intel_hdmi_audio.c
ALSA: x86: Explicit specify 32bit DMA
[mirror_ubuntu-bionic-kernel.git] / sound / x86 / intel_hdmi_audio.c
CommitLineData
5dab11d8
JA
1/*
2 * intel_hdmi_audio.c - Intel HDMI audio driver
3 *
4 * Copyright (C) 2016 Intel Corp
5 * Authors: Sailaja Bandarupalli <sailaja.bandarupalli@intel.com>
6 * Ramesh Babu K V <ramesh.babu@intel.com>
7 * Vaibhav Agarwal <vaibhav.agarwal@intel.com>
8 * Jerome Anand <jerome.anand@intel.com>
9 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2 of the License.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 * ALSA driver for Intel HDMI audio
22 */
23
03c34377 24#include <linux/types.h>
5dab11d8
JA
25#include <linux/platform_device.h>
26#include <linux/io.h>
27#include <linux/slab.h>
28#include <linux/module.h>
da864809 29#include <linux/interrupt.h>
03c34377 30#include <linux/pm_runtime.h>
412bbe7d 31#include <linux/dma-mapping.h>
5dab11d8 32#include <asm/cacheflush.h>
5dab11d8 33#include <sound/core.h>
03c34377
TI
34#include <sound/asoundef.h>
35#include <sound/pcm.h>
5dab11d8
JA
36#include <sound/pcm_params.h>
37#include <sound/initval.h>
38#include <sound/control.h>
03c34377 39#include <drm/drm_edid.h>
da864809 40#include <drm/intel_lpe_audio.h>
5dab11d8
JA
41#include "intel_hdmi_audio.h"
42
5dab11d8
JA
43/*standard module options for ALSA. This module supports only one card*/
44static int hdmi_card_index = SNDRV_DEFAULT_IDX1;
45static char *hdmi_card_id = SNDRV_DEFAULT_STR1;
5dab11d8
JA
46
47module_param_named(index, hdmi_card_index, int, 0444);
48MODULE_PARM_DESC(index,
49 "Index value for INTEL Intel HDMI Audio controller.");
50module_param_named(id, hdmi_card_id, charp, 0444);
51MODULE_PARM_DESC(id,
52 "ID string for INTEL Intel HDMI Audio controller.");
53
54/*
55 * ELD SA bits in the CEA Speaker Allocation data block
56 */
4a5ddb2c 57static const int eld_speaker_allocation_bits[] = {
5dab11d8
JA
58 [0] = FL | FR,
59 [1] = LFE,
60 [2] = FC,
61 [3] = RL | RR,
62 [4] = RC,
63 [5] = FLC | FRC,
64 [6] = RLC | RRC,
65 /* the following are not defined in ELD yet */
66 [7] = 0,
67};
68
69/*
70 * This is an ordered list!
71 *
72 * The preceding ones have better chances to be selected by
73 * hdmi_channel_allocation().
74 */
75static struct cea_channel_speaker_allocation channel_allocations[] = {
76/* channel: 7 6 5 4 3 2 1 0 */
77{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
78 /* 2.1 */
79{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
80 /* Dolby Surround */
81{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
82 /* surround40 */
83{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
84 /* surround41 */
85{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
86 /* surround50 */
87{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
88 /* surround51 */
89{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
90 /* 6.1 */
91{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
92 /* surround71 */
93{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
94
95{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
96{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
97{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
98{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
99{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
100{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
101{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
102{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
103{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
104{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
105{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
106{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
107{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
108{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
109{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
110{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
111{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
112{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
113{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
114{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
115{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
116{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
117{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
118};
119
4a5ddb2c 120static const struct channel_map_table map_tables[] = {
5dab11d8
JA
121 { SNDRV_CHMAP_FL, 0x00, FL },
122 { SNDRV_CHMAP_FR, 0x01, FR },
123 { SNDRV_CHMAP_RL, 0x04, RL },
124 { SNDRV_CHMAP_RR, 0x05, RR },
125 { SNDRV_CHMAP_LFE, 0x02, LFE },
126 { SNDRV_CHMAP_FC, 0x03, FC },
127 { SNDRV_CHMAP_RLC, 0x06, RLC },
128 { SNDRV_CHMAP_RRC, 0x07, RRC },
129 {} /* terminator */
130};
131
132/* hardware capability structure */
133static const struct snd_pcm_hardware snd_intel_hadstream = {
134 .info = (SNDRV_PCM_INFO_INTERLEAVED |
135 SNDRV_PCM_INFO_DOUBLE |
136 SNDRV_PCM_INFO_MMAP|
137 SNDRV_PCM_INFO_MMAP_VALID |
138 SNDRV_PCM_INFO_BATCH),
139 .formats = (SNDRV_PCM_FMTBIT_S24 |
140 SNDRV_PCM_FMTBIT_U24),
141 .rates = SNDRV_PCM_RATE_32000 |
142 SNDRV_PCM_RATE_44100 |
143 SNDRV_PCM_RATE_48000 |
144 SNDRV_PCM_RATE_88200 |
145 SNDRV_PCM_RATE_96000 |
146 SNDRV_PCM_RATE_176400 |
147 SNDRV_PCM_RATE_192000,
148 .rate_min = HAD_MIN_RATE,
149 .rate_max = HAD_MAX_RATE,
150 .channels_min = HAD_MIN_CHANNEL,
151 .channels_max = HAD_MAX_CHANNEL,
152 .buffer_bytes_max = HAD_MAX_BUFFER,
153 .period_bytes_min = HAD_MIN_PERIOD_BYTES,
154 .period_bytes_max = HAD_MAX_PERIOD_BYTES,
155 .periods_min = HAD_MIN_PERIODS,
156 .periods_max = HAD_MAX_PERIODS,
157 .fifo_size = HAD_FIFO_SIZE,
158};
159
313d9f28
TI
160/* Get the active PCM substream;
161 * Call had_substream_put() for unreferecing.
162 * Don't call this inside had_spinlock, as it takes by itself
163 */
164static struct snd_pcm_substream *
165had_substream_get(struct snd_intelhad *intelhaddata)
166{
167 struct snd_pcm_substream *substream;
168 unsigned long flags;
169
170 spin_lock_irqsave(&intelhaddata->had_spinlock, flags);
171 substream = intelhaddata->stream_info.substream;
172 if (substream)
173 intelhaddata->stream_info.substream_refcount++;
174 spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags);
175 return substream;
176}
177
178/* Unref the active PCM substream;
179 * Don't call this inside had_spinlock, as it takes by itself
180 */
181static void had_substream_put(struct snd_intelhad *intelhaddata)
182{
183 unsigned long flags;
184
185 spin_lock_irqsave(&intelhaddata->had_spinlock, flags);
186 intelhaddata->stream_info.substream_refcount--;
187 spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags);
188}
189
5dab11d8 190/* Register access functions */
da864809
TI
191static inline void
192mid_hdmi_audio_read(struct snd_intelhad *ctx, u32 reg, u32 *val)
5dab11d8 193{
da864809 194 *val = ioread32(ctx->mmio_start + ctx->had_config_offset + reg);
5dab11d8
JA
195}
196
da864809
TI
197static inline void
198mid_hdmi_audio_write(struct snd_intelhad *ctx, u32 reg, u32 val)
5dab11d8 199{
da864809 200 iowrite32(val, ctx->mmio_start + ctx->had_config_offset + reg);
5dab11d8
JA
201}
202
372d855f
TI
203static int had_read_register(struct snd_intelhad *intelhaddata,
204 u32 offset, u32 *data)
5dab11d8 205{
91b0cb0c 206 if (!intelhaddata->connected)
79f439ea 207 return -ENODEV;
5dab11d8 208
da864809
TI
209 mid_hdmi_audio_read(intelhaddata, offset, data);
210 return 0;
211}
212
213static void fixup_dp_config(struct snd_intelhad *intelhaddata,
214 u32 offset, u32 *data)
215{
216 if (intelhaddata->dp_output) {
217 if (offset == AUD_CONFIG && (*data & AUD_CONFIG_VALID_BIT))
218 *data |= AUD_CONFIG_DP_MODE | AUD_CONFIG_BLOCK_BIT;
219 }
5dab11d8
JA
220}
221
372d855f
TI
222static int had_write_register(struct snd_intelhad *intelhaddata,
223 u32 offset, u32 data)
5dab11d8 224{
91b0cb0c 225 if (!intelhaddata->connected)
79f439ea 226 return -ENODEV;
5dab11d8 227
da864809
TI
228 fixup_dp_config(intelhaddata, offset, &data);
229 mid_hdmi_audio_write(intelhaddata, offset, data);
230 return 0;
5dab11d8
JA
231}
232
372d855f
TI
233static int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset,
234 u32 data, u32 mask)
5dab11d8 235{
da864809 236 u32 val_tmp;
5dab11d8 237
91b0cb0c 238 if (!intelhaddata->connected)
79f439ea 239 return -ENODEV;
5dab11d8 240
da864809
TI
241 mid_hdmi_audio_read(intelhaddata, offset, &val_tmp);
242 val_tmp &= ~mask;
243 val_tmp |= (data & mask);
244
245 fixup_dp_config(intelhaddata, offset, &val_tmp);
246 mid_hdmi_audio_write(intelhaddata, offset, val_tmp);
247 return 0;
5dab11d8 248}
da864809
TI
249
250/*
313d9f28
TI
251 * enable / disable audio configuration
252 *
da864809
TI
253 * The had_read_modify() function should not directly be used on VLV2 for
254 * updating AUD_CONFIG register.
5dab11d8
JA
255 * This is because:
256 * Bit6 of AUD_CONFIG register is writeonly due to a silicon bug on VLV2
257 * HDMI IP. As a result a read-modify of AUD_CONFIG regiter will always
258 * clear bit6. AUD_CONFIG[6:4] represents the "channels" field of the
259 * register. This field should be 1xy binary for configuration with 6 or
260 * more channels. Read-modify of AUD_CONFIG (Eg. for enabling audio)
261 * causes the "channels" field to be updated as 0xy binary resulting in
262 * bad audio. The fix is to always write the AUD_CONFIG[6:4] with
263 * appropriate value when doing read-modify of AUD_CONFIG register.
5dab11d8 264 */
313d9f28
TI
265static void snd_intelhad_enable_audio(struct snd_pcm_substream *substream,
266 struct snd_intelhad *intelhaddata,
267 bool enable)
5dab11d8 268{
7ceba75f 269 union aud_cfg cfg_val = {.regval = 0};
313d9f28 270 u8 channels, data, mask;
5dab11d8
JA
271
272 /*
273 * If substream is NULL, there is no active stream.
274 * In this case just set channels to 2
275 */
313d9f28 276 channels = substream ? substream->runtime->channels : 2;
7ceba75f 277 cfg_val.regx.num_ch = channels - 2;
5dab11d8 278
7ceba75f 279 data = cfg_val.regval;
313d9f28
TI
280 if (enable)
281 data |= 1;
282 mask = AUD_CONFIG_CH_MASK | 1;
5dab11d8 283
c75b0476
TI
284 dev_dbg(intelhaddata->dev, "%s : data = %x, mask =%x\n",
285 __func__, data, mask);
5dab11d8 286
313d9f28 287 had_read_modify(intelhaddata, AUD_CONFIG, data, mask);
5dab11d8
JA
288}
289
313d9f28 290/* enable / disable the audio interface */
372d855f 291static void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable)
da864809
TI
292{
293 u32 status_reg;
294
295 if (enable) {
4151ee84 296 mid_hdmi_audio_read(ctx, AUD_HDMI_STATUS, &status_reg);
da864809 297 status_reg |= HDMI_AUDIO_BUFFER_DONE | HDMI_AUDIO_UNDERRUN;
4151ee84
TI
298 mid_hdmi_audio_write(ctx, AUD_HDMI_STATUS, status_reg);
299 mid_hdmi_audio_read(ctx, AUD_HDMI_STATUS, &status_reg);
da864809
TI
300 }
301}
302
79dda75a
TI
303static void snd_intelhad_reset_audio(struct snd_intelhad *intelhaddata,
304 u8 reset)
5dab11d8 305{
4151ee84 306 had_write_register(intelhaddata, AUD_HDMI_STATUS, reset);
5dab11d8
JA
307}
308
2e52f5e5 309/*
5dab11d8
JA
310 * initialize audio channel status registers
311 * This function is called in the prepare callback
312 */
313static int had_prog_status_reg(struct snd_pcm_substream *substream,
314 struct snd_intelhad *intelhaddata)
315{
7ceba75f
TI
316 union aud_cfg cfg_val = {.regval = 0};
317 union aud_ch_status_0 ch_stat0 = {.regval = 0};
318 union aud_ch_status_1 ch_stat1 = {.regval = 0};
5dab11d8
JA
319 int format;
320
7ceba75f 321 ch_stat0.regx.lpcm_id = (intelhaddata->aes_bits &
2e52f5e5 322 IEC958_AES0_NONAUDIO) >> 1;
7ceba75f 323 ch_stat0.regx.clk_acc = (intelhaddata->aes_bits &
2e52f5e5 324 IEC958_AES3_CON_CLOCK) >> 4;
7ceba75f 325 cfg_val.regx.val_bit = ch_stat0.regx.lpcm_id;
5dab11d8
JA
326
327 switch (substream->runtime->rate) {
328 case AUD_SAMPLE_RATE_32:
7ceba75f 329 ch_stat0.regx.samp_freq = CH_STATUS_MAP_32KHZ;
5dab11d8
JA
330 break;
331
332 case AUD_SAMPLE_RATE_44_1:
7ceba75f 333 ch_stat0.regx.samp_freq = CH_STATUS_MAP_44KHZ;
5dab11d8
JA
334 break;
335 case AUD_SAMPLE_RATE_48:
7ceba75f 336 ch_stat0.regx.samp_freq = CH_STATUS_MAP_48KHZ;
5dab11d8
JA
337 break;
338 case AUD_SAMPLE_RATE_88_2:
7ceba75f 339 ch_stat0.regx.samp_freq = CH_STATUS_MAP_88KHZ;
5dab11d8
JA
340 break;
341 case AUD_SAMPLE_RATE_96:
7ceba75f 342 ch_stat0.regx.samp_freq = CH_STATUS_MAP_96KHZ;
5dab11d8
JA
343 break;
344 case AUD_SAMPLE_RATE_176_4:
7ceba75f 345 ch_stat0.regx.samp_freq = CH_STATUS_MAP_176KHZ;
5dab11d8
JA
346 break;
347 case AUD_SAMPLE_RATE_192:
7ceba75f 348 ch_stat0.regx.samp_freq = CH_STATUS_MAP_192KHZ;
5dab11d8
JA
349 break;
350
351 default:
352 /* control should never come here */
353 return -EINVAL;
5dab11d8 354 }
2e52f5e5 355
79dda75a 356 had_write_register(intelhaddata,
7ceba75f 357 AUD_CH_STATUS_0, ch_stat0.regval);
5dab11d8
JA
358
359 format = substream->runtime->format;
360
361 if (format == SNDRV_PCM_FORMAT_S16_LE) {
7ceba75f
TI
362 ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_20;
363 ch_stat1.regx.wrd_len = SMPL_WIDTH_16BITS;
5dab11d8 364 } else if (format == SNDRV_PCM_FORMAT_S24_LE) {
7ceba75f
TI
365 ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_24;
366 ch_stat1.regx.wrd_len = SMPL_WIDTH_24BITS;
5dab11d8 367 } else {
7ceba75f
TI
368 ch_stat1.regx.max_wrd_len = 0;
369 ch_stat1.regx.wrd_len = 0;
5dab11d8 370 }
2e52f5e5 371
79dda75a 372 had_write_register(intelhaddata,
7ceba75f 373 AUD_CH_STATUS_1, ch_stat1.regval);
5dab11d8
JA
374 return 0;
375}
376
76296ef0 377/*
5dab11d8
JA
378 * function to initialize audio
379 * registers and buffer confgiuration registers
380 * This function is called in the prepare callback
381 */
76296ef0
TI
382static int snd_intelhad_audio_ctrl(struct snd_pcm_substream *substream,
383 struct snd_intelhad *intelhaddata)
5dab11d8 384{
7ceba75f
TI
385 union aud_cfg cfg_val = {.regval = 0};
386 union aud_buf_config buf_cfg = {.regval = 0};
5dab11d8
JA
387 u8 channels;
388
389 had_prog_status_reg(substream, intelhaddata);
390
7ceba75f
TI
391 buf_cfg.regx.audio_fifo_watermark = FIFO_THRESHOLD;
392 buf_cfg.regx.dma_fifo_watermark = DMA_FIFO_THRESHOLD;
393 buf_cfg.regx.aud_delay = 0;
394 had_write_register(intelhaddata, AUD_BUF_CONFIG, buf_cfg.regval);
5dab11d8
JA
395
396 channels = substream->runtime->channels;
7ceba75f 397 cfg_val.regx.num_ch = channels - 2;
5dab11d8 398 if (channels <= 2)
7ceba75f 399 cfg_val.regx.layout = LAYOUT0;
5dab11d8 400 else
7ceba75f 401 cfg_val.regx.layout = LAYOUT1;
5dab11d8 402
7ceba75f
TI
403 cfg_val.regx.val_bit = 1;
404 had_write_register(intelhaddata, AUD_CONFIG, cfg_val.regval);
5dab11d8
JA
405 return 0;
406}
407
5dab11d8
JA
408/*
409 * Compute derived values in channel_allocations[].
410 */
411static void init_channel_allocations(void)
412{
413 int i, j;
414 struct cea_channel_speaker_allocation *p;
415
5dab11d8
JA
416 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
417 p = channel_allocations + i;
418 p->channels = 0;
419 p->spk_mask = 0;
420 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
421 if (p->speakers[j]) {
422 p->channels++;
423 p->spk_mask |= p->speakers[j];
424 }
425 }
426}
427
428/*
429 * The transformation takes two steps:
430 *
431 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
432 * spk_mask => (channel_allocations[]) => ai->CA
433 *
434 * TODO: it could select the wrong CA from multiple candidates.
435 */
436static int snd_intelhad_channel_allocation(struct snd_intelhad *intelhaddata,
437 int channels)
438{
439 int i;
440 int ca = 0;
441 int spk_mask = 0;
442
443 /*
444 * CA defaults to 0 for basic stereo audio
445 */
446 if (channels <= 2)
447 return 0;
448
449 /*
450 * expand ELD's speaker allocation mask
451 *
452 * ELD tells the speaker mask in a compact(paired) form,
453 * expand ELD's notions to match the ones used by Audio InfoFrame.
454 */
455
456 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
df0435db 457 if (intelhaddata->eld[DRM_ELD_SPEAKER] & (1 << i))
5dab11d8
JA
458 spk_mask |= eld_speaker_allocation_bits[i];
459 }
460
461 /* search for the first working match in the CA table */
462 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
463 if (channels == channel_allocations[i].channels &&
464 (spk_mask & channel_allocations[i].spk_mask) ==
465 channel_allocations[i].spk_mask) {
466 ca = channel_allocations[i].ca_index;
467 break;
468 }
469 }
470
c75b0476 471 dev_dbg(intelhaddata->dev, "select CA 0x%x for %d\n", ca, channels);
5dab11d8
JA
472
473 return ca;
474}
475
476/* from speaker bit mask to ALSA API channel position */
477static int spk_to_chmap(int spk)
478{
4a5ddb2c 479 const struct channel_map_table *t = map_tables;
5dab11d8
JA
480
481 for (; t->map; t++) {
482 if (t->spk_mask == spk)
483 return t->map;
484 }
485 return 0;
486}
487
372d855f 488static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata)
5dab11d8 489{
2e52f5e5 490 int i, c;
5dab11d8
JA
491 int spk_mask = 0;
492 struct snd_pcm_chmap_elem *chmap;
493 u8 eld_high, eld_high_mask = 0xF0;
494 u8 high_msb;
495
496 chmap = kzalloc(sizeof(*chmap), GFP_KERNEL);
2e52f5e5 497 if (!chmap) {
5dab11d8
JA
498 intelhaddata->chmap->chmap = NULL;
499 return;
500 }
501
df0435db
TI
502 dev_dbg(intelhaddata->dev, "eld speaker = %x\n",
503 intelhaddata->eld[DRM_ELD_SPEAKER]);
5dab11d8
JA
504
505 /* WA: Fix the max channel supported to 8 */
506
507 /*
508 * Sink may support more than 8 channels, if eld_high has more than
509 * one bit set. SOC supports max 8 channels.
510 * Refer eld_speaker_allocation_bits, for sink speaker allocation
511 */
512
513 /* if 0x2F < eld < 0x4F fall back to 0x2f, else fall back to 0x4F */
df0435db 514 eld_high = intelhaddata->eld[DRM_ELD_SPEAKER] & eld_high_mask;
5dab11d8
JA
515 if ((eld_high & (eld_high-1)) && (eld_high > 0x1F)) {
516 /* eld_high & (eld_high-1): if more than 1 bit set */
517 /* 0x1F: 7 channels */
518 for (i = 1; i < 4; i++) {
519 high_msb = eld_high & (0x80 >> i);
520 if (high_msb) {
df0435db 521 intelhaddata->eld[DRM_ELD_SPEAKER] &=
5dab11d8
JA
522 high_msb | 0xF;
523 break;
524 }
525 }
526 }
527
528 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
df0435db 529 if (intelhaddata->eld[DRM_ELD_SPEAKER] & (1 << i))
5dab11d8
JA
530 spk_mask |= eld_speaker_allocation_bits[i];
531 }
532
533 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
534 if (spk_mask == channel_allocations[i].spk_mask) {
535 for (c = 0; c < channel_allocations[i].channels; c++) {
536 chmap->map[c] = spk_to_chmap(
537 channel_allocations[i].speakers[
2e52f5e5 538 (MAX_SPEAKERS - 1) - c]);
5dab11d8
JA
539 }
540 chmap->channels = channel_allocations[i].channels;
541 intelhaddata->chmap->chmap = chmap;
542 break;
543 }
544 }
545 if (i >= ARRAY_SIZE(channel_allocations)) {
546 intelhaddata->chmap->chmap = NULL;
547 kfree(chmap);
548 }
549}
550
551/*
552 * ALSA API channel-map control callbacks
553 */
554static int had_chmap_ctl_info(struct snd_kcontrol *kcontrol,
555 struct snd_ctl_elem_info *uinfo)
556{
557 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
558 struct snd_intelhad *intelhaddata = info->private_data;
559
91b0cb0c 560 if (!intelhaddata->connected)
5dab11d8
JA
561 return -ENODEV;
562 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
563 uinfo->count = HAD_MAX_CHANNEL;
564 uinfo->value.integer.min = 0;
565 uinfo->value.integer.max = SNDRV_CHMAP_LAST;
566 return 0;
567}
568
569static int had_chmap_ctl_get(struct snd_kcontrol *kcontrol,
570 struct snd_ctl_elem_value *ucontrol)
571{
572 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
573 struct snd_intelhad *intelhaddata = info->private_data;
2e52f5e5 574 int i;
5dab11d8
JA
575 const struct snd_pcm_chmap_elem *chmap;
576
91b0cb0c 577 if (!intelhaddata->connected)
5dab11d8 578 return -ENODEV;
8f8d1d7f
TI
579
580 mutex_lock(&intelhaddata->mutex);
581 if (!intelhaddata->chmap->chmap) {
582 mutex_unlock(&intelhaddata->mutex);
5dab11d8 583 return -ENODATA;
8f8d1d7f
TI
584 }
585
5dab11d8 586 chmap = intelhaddata->chmap->chmap;
c75b0476 587 for (i = 0; i < chmap->channels; i++)
5dab11d8 588 ucontrol->value.integer.value[i] = chmap->map[i];
8f8d1d7f 589 mutex_unlock(&intelhaddata->mutex);
5dab11d8
JA
590
591 return 0;
592}
593
594static int had_register_chmap_ctls(struct snd_intelhad *intelhaddata,
595 struct snd_pcm *pcm)
596{
2e52f5e5 597 int err;
5dab11d8
JA
598
599 err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
600 NULL, 0, (unsigned long)intelhaddata,
601 &intelhaddata->chmap);
602 if (err < 0)
603 return err;
604
605 intelhaddata->chmap->private_data = intelhaddata;
e9d65abf
TI
606 intelhaddata->chmap->kctl->info = had_chmap_ctl_info;
607 intelhaddata->chmap->kctl->get = had_chmap_ctl_get;
5dab11d8
JA
608 intelhaddata->chmap->chmap = NULL;
609 return 0;
610}
611
76296ef0 612/*
44684f61 613 * Initialize Data Island Packets registers
5dab11d8
JA
614 * This function is called in the prepare callback
615 */
76296ef0
TI
616static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream,
617 struct snd_intelhad *intelhaddata)
5dab11d8
JA
618{
619 int i;
7ceba75f
TI
620 union aud_ctrl_st ctrl_state = {.regval = 0};
621 union aud_info_frame2 frame2 = {.regval = 0};
622 union aud_info_frame3 frame3 = {.regval = 0};
5dab11d8 623 u8 checksum = 0;
964ca808 624 u32 info_frame;
5dab11d8 625 int channels;
36ed3466 626 int ca;
5dab11d8
JA
627
628 channels = substream->runtime->channels;
629
7ceba75f 630 had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.regval);
5dab11d8 631
36ed3466 632 ca = snd_intelhad_channel_allocation(intelhaddata, channels);
964ca808
PLB
633 if (intelhaddata->dp_output) {
634 info_frame = DP_INFO_FRAME_WORD1;
36ed3466 635 frame2.regval = (substream->runtime->channels - 1) | (ca << 24);
964ca808
PLB
636 } else {
637 info_frame = HDMI_INFO_FRAME_WORD1;
7ceba75f 638 frame2.regx.chnl_cnt = substream->runtime->channels - 1;
36ed3466 639 frame3.regx.chnl_alloc = ca;
5dab11d8 640
2e52f5e5 641 /* Calculte the byte wide checksum for all valid DIP words */
964ca808 642 for (i = 0; i < BYTES_PER_WORD; i++)
7ceba75f 643 checksum += (info_frame >> (i * 8)) & 0xff;
964ca808 644 for (i = 0; i < BYTES_PER_WORD; i++)
7ceba75f 645 checksum += (frame2.regval >> (i * 8)) & 0xff;
964ca808 646 for (i = 0; i < BYTES_PER_WORD; i++)
7ceba75f 647 checksum += (frame3.regval >> (i * 8)) & 0xff;
5dab11d8 648
7ceba75f 649 frame2.regx.chksum = -(checksum);
964ca808 650 }
5dab11d8 651
4151ee84 652 had_write_register(intelhaddata, AUD_HDMIW_INFOFR, info_frame);
7ceba75f
TI
653 had_write_register(intelhaddata, AUD_HDMIW_INFOFR, frame2.regval);
654 had_write_register(intelhaddata, AUD_HDMIW_INFOFR, frame3.regval);
5dab11d8
JA
655
656 /* program remaining DIP words with zero */
657 for (i = 0; i < HAD_MAX_DIP_WORDS-VALID_DIP_WORDS; i++)
4151ee84 658 had_write_register(intelhaddata, AUD_HDMIW_INFOFR, 0x0);
5dab11d8 659
7ceba75f
TI
660 ctrl_state.regx.dip_freq = 1;
661 ctrl_state.regx.dip_en_sta = 1;
662 had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.regval);
5dab11d8
JA
663}
664
2e52f5e5 665/*
44684f61 666 * Programs buffer address and length registers
5dab11d8
JA
667 * This function programs ring buffer address and length into registers.
668 */
313d9f28
TI
669static int snd_intelhad_prog_buffer(struct snd_pcm_substream *substream,
670 struct snd_intelhad *intelhaddata,
671 int start, int end)
5dab11d8
JA
672{
673 u32 ring_buf_addr, ring_buf_size, period_bytes;
674 u8 i, num_periods;
5dab11d8
JA
675
676 ring_buf_addr = substream->runtime->dma_addr;
677 ring_buf_size = snd_pcm_lib_buffer_bytes(substream);
678 intelhaddata->stream_info.ring_buf_size = ring_buf_size;
679 period_bytes = frames_to_bytes(substream->runtime,
680 substream->runtime->period_size);
681 num_periods = substream->runtime->periods;
682
683 /*
684 * buffer addr should be 64 byte aligned, period bytes
685 * will be used to calculate addr offset
686 */
687 period_bytes &= ~0x3F;
688
689 /* Hardware supports MAX_PERIODS buffers */
690 if (end >= HAD_MAX_PERIODS)
691 return -EINVAL;
692
693 for (i = start; i <= end; i++) {
694 /* Program the buf registers with addr and len */
695 intelhaddata->buf_info[i].buf_addr = ring_buf_addr +
696 (i * period_bytes);
697 if (i < num_periods-1)
698 intelhaddata->buf_info[i].buf_size = period_bytes;
699 else
700 intelhaddata->buf_info[i].buf_size = ring_buf_size -
2e52f5e5 701 (i * period_bytes);
5dab11d8 702
79dda75a
TI
703 had_write_register(intelhaddata,
704 AUD_BUF_A_ADDR + (i * HAD_REG_WIDTH),
5dab11d8
JA
705 intelhaddata->buf_info[i].buf_addr |
706 BIT(0) | BIT(1));
79dda75a
TI
707 had_write_register(intelhaddata,
708 AUD_BUF_A_LENGTH + (i * HAD_REG_WIDTH),
5dab11d8
JA
709 period_bytes);
710 intelhaddata->buf_info[i].is_valid = true;
711 }
c75b0476
TI
712 dev_dbg(intelhaddata->dev, "%s:buf[%d-%d] addr=%#x and size=%d\n",
713 __func__, start, end,
714 intelhaddata->buf_info[start].buf_addr,
715 intelhaddata->buf_info[start].buf_size);
5dab11d8
JA
716 intelhaddata->valid_buf_cnt = num_periods;
717 return 0;
718}
719
372d855f 720static int snd_intelhad_read_len(struct snd_intelhad *intelhaddata)
5dab11d8
JA
721{
722 int i, retval = 0;
723 u32 len[4];
724
725 for (i = 0; i < 4 ; i++) {
79dda75a
TI
726 had_read_register(intelhaddata,
727 AUD_BUF_A_LENGTH + (i * HAD_REG_WIDTH),
728 &len[i]);
5dab11d8
JA
729 if (!len[i])
730 retval++;
731 }
732 if (retval != 1) {
733 for (i = 0; i < 4 ; i++)
c75b0476
TI
734 dev_dbg(intelhaddata->dev, "buf[%d] size=%d\n",
735 i, len[i]);
5dab11d8
JA
736 }
737
738 return retval;
739}
740
964ca808
PLB
741static int had_calculate_maud_value(u32 aud_samp_freq, u32 link_rate)
742{
743 u32 maud_val;
744
2e52f5e5 745 /* Select maud according to DP 1.2 spec */
964ca808
PLB
746 if (link_rate == DP_2_7_GHZ) {
747 switch (aud_samp_freq) {
748 case AUD_SAMPLE_RATE_32:
749 maud_val = AUD_SAMPLE_RATE_32_DP_2_7_MAUD_VAL;
750 break;
751
752 case AUD_SAMPLE_RATE_44_1:
753 maud_val = AUD_SAMPLE_RATE_44_1_DP_2_7_MAUD_VAL;
754 break;
755
756 case AUD_SAMPLE_RATE_48:
757 maud_val = AUD_SAMPLE_RATE_48_DP_2_7_MAUD_VAL;
758 break;
759
760 case AUD_SAMPLE_RATE_88_2:
761 maud_val = AUD_SAMPLE_RATE_88_2_DP_2_7_MAUD_VAL;
762 break;
763
764 case AUD_SAMPLE_RATE_96:
765 maud_val = AUD_SAMPLE_RATE_96_DP_2_7_MAUD_VAL;
766 break;
767
768 case AUD_SAMPLE_RATE_176_4:
769 maud_val = AUD_SAMPLE_RATE_176_4_DP_2_7_MAUD_VAL;
770 break;
771
772 case HAD_MAX_RATE:
773 maud_val = HAD_MAX_RATE_DP_2_7_MAUD_VAL;
774 break;
775
776 default:
777 maud_val = -EINVAL;
778 break;
779 }
780 } else if (link_rate == DP_1_62_GHZ) {
781 switch (aud_samp_freq) {
782 case AUD_SAMPLE_RATE_32:
783 maud_val = AUD_SAMPLE_RATE_32_DP_1_62_MAUD_VAL;
784 break;
785
786 case AUD_SAMPLE_RATE_44_1:
787 maud_val = AUD_SAMPLE_RATE_44_1_DP_1_62_MAUD_VAL;
788 break;
789
790 case AUD_SAMPLE_RATE_48:
791 maud_val = AUD_SAMPLE_RATE_48_DP_1_62_MAUD_VAL;
792 break;
793
794 case AUD_SAMPLE_RATE_88_2:
795 maud_val = AUD_SAMPLE_RATE_88_2_DP_1_62_MAUD_VAL;
796 break;
797
798 case AUD_SAMPLE_RATE_96:
799 maud_val = AUD_SAMPLE_RATE_96_DP_1_62_MAUD_VAL;
800 break;
801
802 case AUD_SAMPLE_RATE_176_4:
803 maud_val = AUD_SAMPLE_RATE_176_4_DP_1_62_MAUD_VAL;
804 break;
805
806 case HAD_MAX_RATE:
807 maud_val = HAD_MAX_RATE_DP_1_62_MAUD_VAL;
808 break;
809
810 default:
811 maud_val = -EINVAL;
812 break;
813 }
814 } else
815 maud_val = -EINVAL;
816
817 return maud_val;
818}
819
76296ef0 820/*
44684f61 821 * Program HDMI audio CTS value
5dab11d8
JA
822 *
823 * @aud_samp_freq: sampling frequency of audio data
824 * @tmds: sampling frequency of the display data
825 * @n_param: N value, depends on aud_samp_freq
826 * @intelhaddata:substream private data
827 *
828 * Program CTS register based on the audio and display sampling frequency
829 */
76296ef0
TI
830static void snd_intelhad_prog_cts(u32 aud_samp_freq, u32 tmds,
831 u32 link_rate, u32 n_param,
832 struct snd_intelhad *intelhaddata)
5dab11d8
JA
833{
834 u32 cts_val;
835 u64 dividend, divisor;
836
964ca808
PLB
837 if (intelhaddata->dp_output) {
838 /* Substitute cts_val with Maud according to DP 1.2 spec*/
839 cts_val = had_calculate_maud_value(aud_samp_freq, link_rate);
840 } else {
841 /* Calculate CTS according to HDMI 1.3a spec*/
842 dividend = (u64)tmds * n_param*1000;
843 divisor = 128 * aud_samp_freq;
844 cts_val = div64_u64(dividend, divisor);
845 }
c75b0476 846 dev_dbg(intelhaddata->dev, "TMDS value=%d, N value=%d, CTS Value=%d\n",
964ca808 847 tmds, n_param, cts_val);
79dda75a 848 had_write_register(intelhaddata, AUD_HDMI_CTS, (BIT(24) | cts_val));
5dab11d8
JA
849}
850
851static int had_calculate_n_value(u32 aud_samp_freq)
852{
2e52f5e5 853 int n_val;
5dab11d8
JA
854
855 /* Select N according to HDMI 1.3a spec*/
856 switch (aud_samp_freq) {
857 case AUD_SAMPLE_RATE_32:
858 n_val = 4096;
2e52f5e5 859 break;
5dab11d8
JA
860
861 case AUD_SAMPLE_RATE_44_1:
862 n_val = 6272;
2e52f5e5 863 break;
5dab11d8
JA
864
865 case AUD_SAMPLE_RATE_48:
866 n_val = 6144;
2e52f5e5 867 break;
5dab11d8
JA
868
869 case AUD_SAMPLE_RATE_88_2:
870 n_val = 12544;
2e52f5e5 871 break;
5dab11d8
JA
872
873 case AUD_SAMPLE_RATE_96:
874 n_val = 12288;
2e52f5e5 875 break;
5dab11d8
JA
876
877 case AUD_SAMPLE_RATE_176_4:
878 n_val = 25088;
2e52f5e5 879 break;
5dab11d8
JA
880
881 case HAD_MAX_RATE:
882 n_val = 24576;
2e52f5e5 883 break;
5dab11d8
JA
884
885 default:
886 n_val = -EINVAL;
2e52f5e5 887 break;
5dab11d8
JA
888 }
889 return n_val;
890}
891
76296ef0 892/*
44684f61 893 * Program HDMI audio N value
5dab11d8
JA
894 *
895 * @aud_samp_freq: sampling frequency of audio data
896 * @n_param: N value, depends on aud_samp_freq
897 * @intelhaddata:substream private data
898 *
899 * This function is called in the prepare callback.
900 * It programs based on the audio and display sampling frequency
901 */
76296ef0
TI
902static int snd_intelhad_prog_n(u32 aud_samp_freq, u32 *n_param,
903 struct snd_intelhad *intelhaddata)
5dab11d8 904{
2e52f5e5 905 int n_val;
5dab11d8 906
964ca808
PLB
907 if (intelhaddata->dp_output) {
908 /*
909 * According to DP specs, Maud and Naud values hold
910 * a relationship, which is stated as:
911 * Maud/Naud = 512 * fs / f_LS_Clk
912 * where, fs is the sampling frequency of the audio stream
913 * and Naud is 32768 for Async clock.
914 */
915
916 n_val = DP_NAUD_VAL;
917 } else
918 n_val = had_calculate_n_value(aud_samp_freq);
5dab11d8
JA
919
920 if (n_val < 0)
921 return n_val;
922
79dda75a 923 had_write_register(intelhaddata, AUD_N_ENABLE, (BIT(24) | n_val));
5dab11d8
JA
924 *n_param = n_val;
925 return 0;
926}
927
03c34377
TI
928#define MAX_CNT 0xFF
929
372d855f 930static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata)
5dab11d8 931{
79f439ea 932 u32 hdmi_status = 0, i = 0;
5dab11d8
JA
933
934 /* Handle Underrun interrupt within Audio Unit */
79dda75a 935 had_write_register(intelhaddata, AUD_CONFIG, 0);
5dab11d8 936 /* Reset buffer pointers */
4151ee84
TI
937 had_write_register(intelhaddata, AUD_HDMI_STATUS, 1);
938 had_write_register(intelhaddata, AUD_HDMI_STATUS, 0);
2e52f5e5 939 /*
5dab11d8
JA
940 * The interrupt status 'sticky' bits might not be cleared by
941 * setting '1' to that bit once...
942 */
943 do { /* clear bit30, 31 AUD_HDMI_STATUS */
4151ee84 944 had_read_register(intelhaddata, AUD_HDMI_STATUS,
79dda75a 945 &hdmi_status);
c75b0476 946 dev_dbg(intelhaddata->dev, "HDMI status =0x%x\n", hdmi_status);
5dab11d8
JA
947 if (hdmi_status & AUD_CONFIG_MASK_UNDERRUN) {
948 i++;
79dda75a 949 had_write_register(intelhaddata,
4151ee84 950 AUD_HDMI_STATUS, hdmi_status);
5dab11d8
JA
951 } else
952 break;
953 } while (i < MAX_CNT);
954 if (i >= MAX_CNT)
c75b0476 955 dev_err(intelhaddata->dev, "Unable to clear UNDERRUN bits\n");
5dab11d8
JA
956}
957
2e52f5e5 958/*
44684f61 959 * ALSA PCM open callback
5dab11d8
JA
960 */
961static int snd_intelhad_open(struct snd_pcm_substream *substream)
962{
963 struct snd_intelhad *intelhaddata;
964 struct snd_pcm_runtime *runtime;
5dab11d8
JA
965 int retval;
966
5dab11d8 967 intelhaddata = snd_pcm_substream_chip(substream);
5dab11d8
JA
968 runtime = substream->runtime;
969
182cdf23 970 pm_runtime_get_sync(intelhaddata->dev);
5dab11d8 971
91b0cb0c 972 if (!intelhaddata->connected) {
c75b0476
TI
973 dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n",
974 __func__);
5dab11d8 975 retval = -ENODEV;
fa5dfe6a 976 goto error;
5dab11d8
JA
977 }
978
979 /* set the runtime hw parameter with local snd_pcm_hardware struct */
980 runtime->hw = snd_intel_hadstream;
981
5dab11d8
JA
982 retval = snd_pcm_hw_constraint_integer(runtime,
983 SNDRV_PCM_HW_PARAM_PERIODS);
984 if (retval < 0)
fa5dfe6a 985 goto error;
5dab11d8
JA
986
987 /* Make sure, that the period size is always aligned
988 * 64byte boundary
989 */
990 retval = snd_pcm_hw_constraint_step(substream->runtime, 0,
991 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64);
73997b05 992 if (retval < 0)
fa5dfe6a 993 goto error;
5dab11d8 994
73997b05 995 /* expose PCM substream */
313d9f28
TI
996 spin_lock_irq(&intelhaddata->had_spinlock);
997 intelhaddata->stream_info.substream = substream;
998 intelhaddata->stream_info.substream_refcount++;
999 spin_unlock_irq(&intelhaddata->had_spinlock);
1000
73997b05
TI
1001 /* these are cleared in prepare callback, but just to be sure */
1002 intelhaddata->curr_buf = 0;
1003 intelhaddata->underrun_count = 0;
1004 intelhaddata->stream_info.buffer_rendered = 0;
1005
5dab11d8 1006 return retval;
fa5dfe6a 1007 error:
5dab11d8 1008 pm_runtime_put(intelhaddata->dev);
5dab11d8
JA
1009 return retval;
1010}
1011
2e52f5e5 1012/*
44684f61 1013 * ALSA PCM close callback
5dab11d8
JA
1014 */
1015static int snd_intelhad_close(struct snd_pcm_substream *substream)
1016{
1017 struct snd_intelhad *intelhaddata;
5dab11d8 1018
5dab11d8 1019 intelhaddata = snd_pcm_substream_chip(substream);
5dab11d8 1020
73997b05 1021 /* unreference and sync with the pending PCM accesses */
313d9f28
TI
1022 spin_lock_irq(&intelhaddata->had_spinlock);
1023 intelhaddata->stream_info.substream = NULL;
1024 intelhaddata->stream_info.substream_refcount--;
1025 while (intelhaddata->stream_info.substream_refcount > 0) {
1026 spin_unlock_irq(&intelhaddata->had_spinlock);
1027 cpu_relax();
1028 spin_lock_irq(&intelhaddata->had_spinlock);
1029 }
1030 spin_unlock_irq(&intelhaddata->had_spinlock);
5dab11d8 1031
5dab11d8
JA
1032 pm_runtime_put(intelhaddata->dev);
1033 return 0;
1034}
1035
2e52f5e5 1036/*
44684f61 1037 * ALSA PCM hw_params callback
5dab11d8
JA
1038 */
1039static int snd_intelhad_hw_params(struct snd_pcm_substream *substream,
1040 struct snd_pcm_hw_params *hw_params)
1041{
c75b0476 1042 struct snd_intelhad *intelhaddata;
5dab11d8
JA
1043 unsigned long addr;
1044 int pages, buf_size, retval;
1045
c75b0476 1046 intelhaddata = snd_pcm_substream_chip(substream);
5dab11d8
JA
1047 buf_size = params_buffer_bytes(hw_params);
1048 retval = snd_pcm_lib_malloc_pages(substream, buf_size);
1049 if (retval < 0)
1050 return retval;
c75b0476
TI
1051 dev_dbg(intelhaddata->dev, "%s:allocated memory = %d\n",
1052 __func__, buf_size);
5dab11d8
JA
1053 /* mark the pages as uncached region */
1054 addr = (unsigned long) substream->runtime->dma_area;
1055 pages = (substream->runtime->dma_bytes + PAGE_SIZE - 1) / PAGE_SIZE;
1056 retval = set_memory_uc(addr, pages);
1057 if (retval) {
c75b0476
TI
1058 dev_err(intelhaddata->dev, "set_memory_uc failed.Error:%d\n",
1059 retval);
5dab11d8
JA
1060 return retval;
1061 }
1062 memset(substream->runtime->dma_area, 0, buf_size);
1063
1064 return retval;
1065}
1066
2e52f5e5 1067/*
44684f61 1068 * ALSA PCM hw_free callback
5dab11d8
JA
1069 */
1070static int snd_intelhad_hw_free(struct snd_pcm_substream *substream)
1071{
1072 unsigned long addr;
1073 u32 pages;
1074
5dab11d8
JA
1075 /* mark back the pages as cached/writeback region before the free */
1076 if (substream->runtime->dma_area != NULL) {
1077 addr = (unsigned long) substream->runtime->dma_area;
1078 pages = (substream->runtime->dma_bytes + PAGE_SIZE - 1) /
1079 PAGE_SIZE;
1080 set_memory_wb(addr, pages);
1081 return snd_pcm_lib_free_pages(substream);
1082 }
1083 return 0;
1084}
1085
2e52f5e5 1086/*
44684f61 1087 * ALSA PCM trigger callback
5dab11d8
JA
1088 */
1089static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream,
1090 int cmd)
1091{
da864809 1092 int retval = 0;
5dab11d8 1093 struct snd_intelhad *intelhaddata;
5dab11d8 1094
5dab11d8 1095 intelhaddata = snd_pcm_substream_chip(substream);
5dab11d8
JA
1096
1097 switch (cmd) {
1098 case SNDRV_PCM_TRIGGER_START:
182cdf23
TI
1099 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1100 case SNDRV_PCM_TRIGGER_RESUME:
5dab11d8 1101 /* Disable local INTRs till register prgmng is done */
91b0cb0c 1102 if (!intelhaddata->connected) {
c75b0476
TI
1103 dev_dbg(intelhaddata->dev,
1104 "_START: HDMI cable plugged-out\n");
5dab11d8
JA
1105 retval = -ENODEV;
1106 break;
1107 }
5dab11d8 1108
f69bd104 1109 intelhaddata->stream_info.running = true;
5dab11d8
JA
1110
1111 /* Enable Audio */
da864809 1112 snd_intelhad_enable_audio_int(intelhaddata, true);
313d9f28 1113 snd_intelhad_enable_audio(substream, intelhaddata, true);
5dab11d8
JA
1114 break;
1115
1116 case SNDRV_PCM_TRIGGER_STOP:
182cdf23
TI
1117 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1118 case SNDRV_PCM_TRIGGER_SUSPEND:
bcce775c 1119 spin_lock(&intelhaddata->had_spinlock);
5dab11d8 1120
c75b0476 1121 /* Stop reporting BUFFER_DONE/UNDERRUN to above layers */
5dab11d8 1122
f69bd104 1123 intelhaddata->stream_info.running = false;
bcce775c 1124 spin_unlock(&intelhaddata->had_spinlock);
5dab11d8 1125 /* Disable Audio */
da864809 1126 snd_intelhad_enable_audio_int(intelhaddata, false);
313d9f28 1127 snd_intelhad_enable_audio(substream, intelhaddata, false);
5dab11d8 1128 /* Reset buffer pointers */
79dda75a
TI
1129 snd_intelhad_reset_audio(intelhaddata, 1);
1130 snd_intelhad_reset_audio(intelhaddata, 0);
da864809 1131 snd_intelhad_enable_audio_int(intelhaddata, false);
5dab11d8
JA
1132 break;
1133
1134 default:
1135 retval = -EINVAL;
1136 }
1137 return retval;
1138}
1139
2e52f5e5 1140/*
44684f61 1141 * ALSA PCM prepare callback
5dab11d8
JA
1142 */
1143static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream)
1144{
1145 int retval;
1146 u32 disp_samp_freq, n_param;
964ca808 1147 u32 link_rate = 0;
5dab11d8
JA
1148 struct snd_intelhad *intelhaddata;
1149 struct snd_pcm_runtime *runtime;
5dab11d8 1150
5dab11d8
JA
1151 intelhaddata = snd_pcm_substream_chip(substream);
1152 runtime = substream->runtime;
5dab11d8 1153
91b0cb0c 1154 if (!intelhaddata->connected) {
c75b0476
TI
1155 dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n",
1156 __func__);
5dab11d8
JA
1157 retval = -ENODEV;
1158 goto prep_end;
1159 }
1160
c75b0476 1161 dev_dbg(intelhaddata->dev, "period_size=%d\n",
5dab11d8 1162 (int)frames_to_bytes(runtime, runtime->period_size));
c75b0476
TI
1163 dev_dbg(intelhaddata->dev, "periods=%d\n", runtime->periods);
1164 dev_dbg(intelhaddata->dev, "buffer_size=%d\n",
1165 (int)snd_pcm_lib_buffer_bytes(substream));
1166 dev_dbg(intelhaddata->dev, "rate=%d\n", runtime->rate);
1167 dev_dbg(intelhaddata->dev, "channels=%d\n", runtime->channels);
5dab11d8 1168
73997b05
TI
1169 intelhaddata->curr_buf = 0;
1170 intelhaddata->underrun_count = 0;
2e52f5e5 1171 intelhaddata->stream_info.buffer_rendered = 0;
5dab11d8
JA
1172
1173 /* Get N value in KHz */
da864809 1174 disp_samp_freq = intelhaddata->tmds_clock_speed;
5dab11d8 1175
76296ef0
TI
1176 retval = snd_intelhad_prog_n(substream->runtime->rate, &n_param,
1177 intelhaddata);
5dab11d8 1178 if (retval) {
c75b0476
TI
1179 dev_err(intelhaddata->dev,
1180 "programming N value failed %#x\n", retval);
5dab11d8
JA
1181 goto prep_end;
1182 }
964ca808
PLB
1183
1184 if (intelhaddata->dp_output)
da864809 1185 link_rate = intelhaddata->link_rate;
964ca808 1186
76296ef0
TI
1187 snd_intelhad_prog_cts(substream->runtime->rate,
1188 disp_samp_freq, link_rate,
1189 n_param, intelhaddata);
5dab11d8 1190
76296ef0 1191 snd_intelhad_prog_dip(substream, intelhaddata);
5dab11d8 1192
76296ef0 1193 retval = snd_intelhad_audio_ctrl(substream, intelhaddata);
5dab11d8
JA
1194
1195 /* Prog buffer address */
313d9f28 1196 retval = snd_intelhad_prog_buffer(substream, intelhaddata,
5dab11d8
JA
1197 HAD_BUF_TYPE_A, HAD_BUF_TYPE_D);
1198
1199 /*
1200 * Program channel mapping in following order:
1201 * FL, FR, C, LFE, RL, RR
1202 */
1203
79dda75a 1204 had_write_register(intelhaddata, AUD_BUF_CH_SWAP, SWAP_LFE_CENTER);
5dab11d8
JA
1205
1206prep_end:
1207 return retval;
1208}
1209
2e52f5e5 1210/*
44684f61 1211 * ALSA PCM pointer callback
5dab11d8 1212 */
44684f61
TI
1213static snd_pcm_uframes_t
1214snd_intelhad_pcm_pointer(struct snd_pcm_substream *substream)
5dab11d8
JA
1215{
1216 struct snd_intelhad *intelhaddata;
1217 u32 bytes_rendered = 0;
1218 u32 t;
1219 int buf_id;
1220
5dab11d8
JA
1221 intelhaddata = snd_pcm_substream_chip(substream);
1222
91b0cb0c 1223 if (!intelhaddata->connected)
79f439ea
TI
1224 return SNDRV_PCM_POS_XRUN;
1225
5dab11d8
JA
1226 /* Use a hw register to calculate sub-period position reports.
1227 * This makes PulseAudio happier.
1228 */
1229
1230 buf_id = intelhaddata->curr_buf % 4;
79dda75a
TI
1231 had_read_register(intelhaddata,
1232 AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), &t);
232892fb
JA
1233
1234 if ((t == 0) || (t == ((u32)-1L))) {
6ddb3ab6 1235 intelhaddata->underrun_count++;
c75b0476
TI
1236 dev_dbg(intelhaddata->dev,
1237 "discovered buffer done for buf %d, count = %d\n",
6ddb3ab6 1238 buf_id, intelhaddata->underrun_count);
232892fb 1239
6ddb3ab6 1240 if (intelhaddata->underrun_count > (HAD_MIN_PERIODS/2)) {
c75b0476
TI
1241 dev_dbg(intelhaddata->dev,
1242 "assume audio_codec_reset, underrun = %d - do xrun\n",
6ddb3ab6 1243 intelhaddata->underrun_count);
232892fb
JA
1244 return SNDRV_PCM_POS_XRUN;
1245 }
1246 } else {
1247 /* Reset Counter */
6ddb3ab6 1248 intelhaddata->underrun_count = 0;
5dab11d8 1249 }
232892fb 1250
5dab11d8
JA
1251 t = intelhaddata->buf_info[buf_id].buf_size - t;
1252
1253 if (intelhaddata->stream_info.buffer_rendered)
1254 div_u64_rem(intelhaddata->stream_info.buffer_rendered,
1255 intelhaddata->stream_info.ring_buf_size,
1256 &(bytes_rendered));
1257
7d9e7986 1258 return bytes_to_frames(substream->runtime, bytes_rendered + t);
5dab11d8
JA
1259}
1260
2e52f5e5 1261/*
44684f61 1262 * ALSA PCM mmap callback
5dab11d8
JA
1263 */
1264static int snd_intelhad_pcm_mmap(struct snd_pcm_substream *substream,
1265 struct vm_area_struct *vma)
1266{
5dab11d8
JA
1267 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1268 return remap_pfn_range(vma, vma->vm_start,
1269 substream->dma_buffer.addr >> PAGE_SHIFT,
1270 vma->vm_end - vma->vm_start, vma->vm_page_prot);
1271}
1272
73997b05
TI
1273/*
1274 * ALSA PCM ops
1275 */
1276static const struct snd_pcm_ops snd_intelhad_playback_ops = {
1277 .open = snd_intelhad_open,
1278 .close = snd_intelhad_close,
1279 .ioctl = snd_pcm_lib_ioctl,
1280 .hw_params = snd_intelhad_hw_params,
1281 .hw_free = snd_intelhad_hw_free,
1282 .prepare = snd_intelhad_pcm_prepare,
1283 .trigger = snd_intelhad_pcm_trigger,
1284 .pointer = snd_intelhad_pcm_pointer,
1285 .mmap = snd_intelhad_pcm_mmap,
1286};
1287
8f8d1d7f 1288/* process mode change of the running stream; called in mutex */
da864809 1289static int hdmi_audio_mode_change(struct snd_intelhad *intelhaddata)
5dab11d8 1290{
da864809 1291 struct snd_pcm_substream *substream;
5dab11d8
JA
1292 int retval = 0;
1293 u32 disp_samp_freq, n_param;
964ca808 1294 u32 link_rate = 0;
5dab11d8 1295
313d9f28
TI
1296 substream = had_substream_get(intelhaddata);
1297 if (!substream)
da864809 1298 return 0;
5dab11d8
JA
1299
1300 /* Disable Audio */
313d9f28 1301 snd_intelhad_enable_audio(substream, intelhaddata, false);
5dab11d8
JA
1302
1303 /* Update CTS value */
da864809 1304 disp_samp_freq = intelhaddata->tmds_clock_speed;
5dab11d8 1305
76296ef0
TI
1306 retval = snd_intelhad_prog_n(substream->runtime->rate, &n_param,
1307 intelhaddata);
5dab11d8 1308 if (retval) {
c75b0476
TI
1309 dev_err(intelhaddata->dev,
1310 "programming N value failed %#x\n", retval);
5dab11d8
JA
1311 goto out;
1312 }
964ca808
PLB
1313
1314 if (intelhaddata->dp_output)
da864809 1315 link_rate = intelhaddata->link_rate;
964ca808 1316
76296ef0
TI
1317 snd_intelhad_prog_cts(substream->runtime->rate,
1318 disp_samp_freq, link_rate,
1319 n_param, intelhaddata);
5dab11d8
JA
1320
1321 /* Enable Audio */
313d9f28 1322 snd_intelhad_enable_audio(substream, intelhaddata, true);
5dab11d8
JA
1323
1324out:
313d9f28 1325 had_substream_put(intelhaddata);
5dab11d8
JA
1326 return retval;
1327}
1328
372d855f
TI
1329static inline int had_chk_intrmiss(struct snd_intelhad *intelhaddata,
1330 enum intel_had_aud_buf_type buf_id)
1331{
1332 int i, intr_count = 0;
1333 enum intel_had_aud_buf_type buff_done;
1334 u32 buf_size, buf_addr;
372d855f
TI
1335
1336 buff_done = buf_id;
1337
1338 intr_count = snd_intelhad_read_len(intelhaddata);
1339 if (intr_count > 1) {
1340 /* In case of active playback */
c75b0476
TI
1341 dev_err(intelhaddata->dev,
1342 "Driver detected %d missed buffer done interrupt(s)\n",
1343 (intr_count - 1));
372d855f
TI
1344 if (intr_count > 3)
1345 return intr_count;
1346
1347 buf_id += (intr_count - 1);
1348 /* Reprogram registers*/
1349 for (i = buff_done; i < buf_id; i++) {
1350 int j = i % 4;
1351
1352 buf_size = intelhaddata->buf_info[j].buf_size;
1353 buf_addr = intelhaddata->buf_info[j].buf_addr;
1354 had_write_register(intelhaddata,
1355 AUD_BUF_A_LENGTH +
1356 (j * HAD_REG_WIDTH), buf_size);
1357 had_write_register(intelhaddata,
1358 AUD_BUF_A_ADDR+(j * HAD_REG_WIDTH),
1359 (buf_addr | BIT(0) | BIT(1)));
1360 }
1361 buf_id = buf_id % 4;
372d855f 1362 intelhaddata->buff_done = buf_id;
372d855f
TI
1363 }
1364
1365 return intr_count;
1366}
1367
bcce775c 1368/* called from irq handler */
372d855f
TI
1369static int had_process_buffer_done(struct snd_intelhad *intelhaddata)
1370{
1371 u32 len = 1;
1372 enum intel_had_aud_buf_type buf_id;
1373 enum intel_had_aud_buf_type buff_done;
1374 struct pcm_stream_info *stream;
313d9f28 1375 struct snd_pcm_substream *substream;
372d855f 1376 u32 buf_size;
372d855f 1377 int intr_count;
bcce775c 1378 unsigned long flags;
372d855f 1379
372d855f
TI
1380 stream = &intelhaddata->stream_info;
1381 intr_count = 1;
1382
bcce775c 1383 spin_lock_irqsave(&intelhaddata->had_spinlock, flags);
91b0cb0c 1384 if (!intelhaddata->connected) {
bcce775c 1385 spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags);
c75b0476
TI
1386 dev_dbg(intelhaddata->dev,
1387 "%s:Device already disconnected\n", __func__);
372d855f
TI
1388 return 0;
1389 }
1390 buf_id = intelhaddata->curr_buf;
1391 intelhaddata->buff_done = buf_id;
1392 buff_done = intelhaddata->buff_done;
1393 buf_size = intelhaddata->buf_info[buf_id].buf_size;
372d855f 1394
372d855f
TI
1395 /* Every debug statement has an implication
1396 * of ~5msec. Thus, avoid having >3 debug statements
1397 * for each buffer_done handling.
1398 */
1399
1400 /* Check for any intr_miss in case of active playback */
f69bd104 1401 if (stream->running) {
372d855f
TI
1402 intr_count = had_chk_intrmiss(intelhaddata, buf_id);
1403 if (!intr_count || (intr_count > 3)) {
bcce775c
TI
1404 spin_unlock_irqrestore(&intelhaddata->had_spinlock,
1405 flags);
c75b0476
TI
1406 dev_err(intelhaddata->dev,
1407 "HAD SW state in non-recoverable mode\n");
372d855f
TI
1408 return 0;
1409 }
1410 buf_id += (intr_count - 1);
1411 buf_id = buf_id % 4;
372d855f
TI
1412 }
1413
1414 intelhaddata->buf_info[buf_id].is_valid = true;
1415 if (intelhaddata->valid_buf_cnt-1 == buf_id) {
f69bd104 1416 if (stream->running)
372d855f
TI
1417 intelhaddata->curr_buf = HAD_BUF_TYPE_A;
1418 } else
1419 intelhaddata->curr_buf = buf_id + 1;
1420
bcce775c 1421 spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags);
372d855f 1422
91b0cb0c 1423 if (!intelhaddata->connected) {
c75b0476 1424 dev_dbg(intelhaddata->dev, "HDMI cable plugged-out\n");
372d855f
TI
1425 return 0;
1426 }
1427
2e52f5e5 1428 /* Reprogram the registers with addr and length */
372d855f
TI
1429 had_write_register(intelhaddata,
1430 AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH),
1431 buf_size);
1432 had_write_register(intelhaddata,
1433 AUD_BUF_A_ADDR + (buf_id * HAD_REG_WIDTH),
1434 intelhaddata->buf_info[buf_id].buf_addr |
1435 BIT(0) | BIT(1));
1436
1437 had_read_register(intelhaddata,
1438 AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH),
1439 &len);
c75b0476 1440 dev_dbg(intelhaddata->dev, "%s:Enabled buf[%d]\n", __func__, buf_id);
372d855f
TI
1441
1442 /* In case of actual data,
1443 * report buffer_done to above ALSA layer
1444 */
313d9f28
TI
1445 substream = had_substream_get(intelhaddata);
1446 if (substream) {
1447 buf_size = intelhaddata->buf_info[buf_id].buf_size;
372d855f
TI
1448 intelhaddata->stream_info.buffer_rendered +=
1449 (intr_count * buf_size);
313d9f28
TI
1450 snd_pcm_period_elapsed(substream);
1451 had_substream_put(intelhaddata);
372d855f
TI
1452 }
1453
1454 return 0;
1455}
1456
bcce775c 1457/* called from irq handler */
372d855f
TI
1458static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata)
1459{
1460 enum intel_had_aud_buf_type buf_id;
1461 struct pcm_stream_info *stream;
313d9f28 1462 struct snd_pcm_substream *substream;
bcce775c 1463 unsigned long flags;
91b0cb0c 1464 int connected;
372d855f 1465
372d855f
TI
1466 stream = &intelhaddata->stream_info;
1467
bcce775c 1468 spin_lock_irqsave(&intelhaddata->had_spinlock, flags);
372d855f 1469 buf_id = intelhaddata->curr_buf;
372d855f 1470 intelhaddata->buff_done = buf_id;
91b0cb0c 1471 connected = intelhaddata->connected;
f69bd104 1472 if (stream->running)
372d855f
TI
1473 intelhaddata->curr_buf = HAD_BUF_TYPE_A;
1474
bcce775c 1475 spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags);
372d855f 1476
f69bd104
TI
1477 dev_dbg(intelhaddata->dev, "Enter:%s buf_id=%d, stream_running=%d\n",
1478 __func__, buf_id, stream->running);
372d855f
TI
1479
1480 snd_intelhad_handle_underrun(intelhaddata);
1481
91b0cb0c 1482 if (!connected) {
c75b0476
TI
1483 dev_dbg(intelhaddata->dev,
1484 "%s:Device already disconnected\n", __func__);
372d855f
TI
1485 return 0;
1486 }
1487
f69bd104
TI
1488 /* Report UNDERRUN error to above layers */
1489 substream = had_substream_get(intelhaddata);
1490 if (substream) {
1491 snd_pcm_stop_xrun(substream);
1492 had_substream_put(intelhaddata);
372d855f
TI
1493 }
1494
1495 return 0;
1496}
1497
8f8d1d7f 1498/* process hot plug, called from wq with mutex locked */
0e9c67d7 1499static void had_process_hot_plug(struct snd_intelhad *intelhaddata)
372d855f
TI
1500{
1501 enum intel_had_aud_buf_type buf_id;
1502 struct snd_pcm_substream *substream;
372d855f 1503
bcce775c 1504 spin_lock_irq(&intelhaddata->had_spinlock);
91b0cb0c 1505 if (intelhaddata->connected) {
c75b0476 1506 dev_dbg(intelhaddata->dev, "Device already connected\n");
bcce775c 1507 spin_unlock_irq(&intelhaddata->had_spinlock);
0e9c67d7 1508 return;
372d855f 1509 }
0e9c67d7 1510
372d855f
TI
1511 buf_id = intelhaddata->curr_buf;
1512 intelhaddata->buff_done = buf_id;
91b0cb0c 1513 intelhaddata->connected = true;
c75b0476
TI
1514 dev_dbg(intelhaddata->dev,
1515 "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n",
372d855f 1516 __func__, __LINE__);
bcce775c 1517 spin_unlock_irq(&intelhaddata->had_spinlock);
372d855f 1518
c75b0476
TI
1519 dev_dbg(intelhaddata->dev, "Processing HOT_PLUG, buf_id = %d\n",
1520 buf_id);
372d855f
TI
1521
1522 /* Safety check */
313d9f28 1523 substream = had_substream_get(intelhaddata);
372d855f 1524 if (substream) {
c75b0476
TI
1525 dev_dbg(intelhaddata->dev,
1526 "Force to stop the active stream by disconnection\n");
372d855f
TI
1527 /* Set runtime->state to hw_params done */
1528 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
313d9f28 1529 had_substream_put(intelhaddata);
372d855f
TI
1530 }
1531
1532 had_build_channel_allocation_map(intelhaddata);
372d855f
TI
1533}
1534
8f8d1d7f 1535/* process hot unplug, called from wq with mutex locked */
0e9c67d7 1536static void had_process_hot_unplug(struct snd_intelhad *intelhaddata)
372d855f
TI
1537{
1538 enum intel_had_aud_buf_type buf_id;
313d9f28 1539 struct snd_pcm_substream *substream;
372d855f 1540
372d855f
TI
1541 buf_id = intelhaddata->curr_buf;
1542
313d9f28
TI
1543 substream = had_substream_get(intelhaddata);
1544
bcce775c 1545 spin_lock_irq(&intelhaddata->had_spinlock);
372d855f 1546
91b0cb0c 1547 if (!intelhaddata->connected) {
c75b0476 1548 dev_dbg(intelhaddata->dev, "Device already disconnected\n");
bcce775c 1549 spin_unlock_irq(&intelhaddata->had_spinlock);
313d9f28 1550 goto out;
372d855f 1551
372d855f
TI
1552 }
1553
0e9c67d7
TI
1554 /* Disable Audio */
1555 snd_intelhad_enable_audio_int(intelhaddata, false);
313d9f28 1556 snd_intelhad_enable_audio(substream, intelhaddata, false);
0e9c67d7 1557
91b0cb0c 1558 intelhaddata->connected = false;
c75b0476
TI
1559 dev_dbg(intelhaddata->dev,
1560 "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n",
372d855f 1561 __func__, __LINE__);
313d9f28 1562 spin_unlock_irq(&intelhaddata->had_spinlock);
372d855f
TI
1563
1564 /* Report to above ALSA layer */
313d9f28
TI
1565 if (substream)
1566 snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
372d855f 1567
313d9f28
TI
1568 out:
1569 if (substream)
1570 had_substream_put(intelhaddata);
372d855f
TI
1571 kfree(intelhaddata->chmap->chmap);
1572 intelhaddata->chmap->chmap = NULL;
372d855f
TI
1573}
1574
73997b05
TI
1575/*
1576 * ALSA iec958 and ELD controls
1577 */
5dab11d8 1578
5dab11d8
JA
1579static int had_iec958_info(struct snd_kcontrol *kcontrol,
1580 struct snd_ctl_elem_info *uinfo)
1581{
1582 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
1583 uinfo->count = 1;
1584 return 0;
1585}
1586
1587static int had_iec958_get(struct snd_kcontrol *kcontrol,
1588 struct snd_ctl_elem_value *ucontrol)
1589{
1590 struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol);
1591
8f8d1d7f 1592 mutex_lock(&intelhaddata->mutex);
5dab11d8
JA
1593 ucontrol->value.iec958.status[0] = (intelhaddata->aes_bits >> 0) & 0xff;
1594 ucontrol->value.iec958.status[1] = (intelhaddata->aes_bits >> 8) & 0xff;
1595 ucontrol->value.iec958.status[2] =
1596 (intelhaddata->aes_bits >> 16) & 0xff;
1597 ucontrol->value.iec958.status[3] =
1598 (intelhaddata->aes_bits >> 24) & 0xff;
8f8d1d7f 1599 mutex_unlock(&intelhaddata->mutex);
5dab11d8
JA
1600 return 0;
1601}
372d855f 1602
5dab11d8
JA
1603static int had_iec958_mask_get(struct snd_kcontrol *kcontrol,
1604 struct snd_ctl_elem_value *ucontrol)
1605{
1606 ucontrol->value.iec958.status[0] = 0xff;
1607 ucontrol->value.iec958.status[1] = 0xff;
1608 ucontrol->value.iec958.status[2] = 0xff;
1609 ucontrol->value.iec958.status[3] = 0xff;
1610 return 0;
1611}
372d855f 1612
5dab11d8
JA
1613static int had_iec958_put(struct snd_kcontrol *kcontrol,
1614 struct snd_ctl_elem_value *ucontrol)
1615{
1616 unsigned int val;
1617 struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol);
8f8d1d7f 1618 int changed = 0;
5dab11d8 1619
5dab11d8
JA
1620 val = (ucontrol->value.iec958.status[0] << 0) |
1621 (ucontrol->value.iec958.status[1] << 8) |
1622 (ucontrol->value.iec958.status[2] << 16) |
1623 (ucontrol->value.iec958.status[3] << 24);
8f8d1d7f 1624 mutex_lock(&intelhaddata->mutex);
5dab11d8
JA
1625 if (intelhaddata->aes_bits != val) {
1626 intelhaddata->aes_bits = val;
8f8d1d7f 1627 changed = 1;
5dab11d8 1628 }
8f8d1d7f
TI
1629 mutex_unlock(&intelhaddata->mutex);
1630 return changed;
5dab11d8
JA
1631}
1632
4aedb946
TI
1633static int had_ctl_eld_info(struct snd_kcontrol *kcontrol,
1634 struct snd_ctl_elem_info *uinfo)
1635{
1636 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
1637 uinfo->count = HDMI_MAX_ELD_BYTES;
1638 return 0;
1639}
1640
1641static int had_ctl_eld_get(struct snd_kcontrol *kcontrol,
1642 struct snd_ctl_elem_value *ucontrol)
1643{
1644 struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol);
1645
1646 mutex_lock(&intelhaddata->mutex);
1647 memcpy(ucontrol->value.bytes.data, intelhaddata->eld,
1648 HDMI_MAX_ELD_BYTES);
1649 mutex_unlock(&intelhaddata->mutex);
1650 return 0;
1651}
5dab11d8 1652
73997b05 1653static const struct snd_kcontrol_new had_controls[] = {
4aedb946
TI
1654 {
1655 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1656 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1657 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
1658 .info = had_iec958_info, /* shared */
1659 .get = had_iec958_mask_get,
1660 },
1661 {
1662 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1663 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
1664 .info = had_iec958_info,
1665 .get = had_iec958_get,
1666 .put = had_iec958_put,
1667 },
1668 {
1669 .access = (SNDRV_CTL_ELEM_ACCESS_READ |
1670 SNDRV_CTL_ELEM_ACCESS_VOLATILE),
1671 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1672 .name = "ELD",
1673 .info = had_ctl_eld_info,
1674 .get = had_ctl_eld_get,
1675 },
5dab11d8
JA
1676};
1677
73997b05
TI
1678/*
1679 * audio interrupt handler
1680 */
da864809
TI
1681static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id)
1682{
1683 struct snd_intelhad *ctx = dev_id;
1684 u32 audio_stat, audio_reg;
1685
4151ee84 1686 audio_reg = AUD_HDMI_STATUS;
da864809
TI
1687 mid_hdmi_audio_read(ctx, audio_reg, &audio_stat);
1688
1689 if (audio_stat & HDMI_AUDIO_UNDERRUN) {
1690 mid_hdmi_audio_write(ctx, audio_reg, HDMI_AUDIO_UNDERRUN);
1691 had_process_buffer_underrun(ctx);
1692 }
1693
1694 if (audio_stat & HDMI_AUDIO_BUFFER_DONE) {
1695 mid_hdmi_audio_write(ctx, audio_reg, HDMI_AUDIO_BUFFER_DONE);
1696 had_process_buffer_done(ctx);
1697 }
1698
1699 return IRQ_HANDLED;
1700}
1701
73997b05
TI
1702/*
1703 * monitor plug/unplug notification from i915; just kick off the work
1704 */
da864809
TI
1705static void notify_audio_lpe(struct platform_device *pdev)
1706{
1707 struct snd_intelhad *ctx = platform_get_drvdata(pdev);
da864809 1708
99b2ab9d
TI
1709 schedule_work(&ctx->hdmi_audio_wq);
1710}
da864809 1711
73997b05 1712/* the work to handle monitor hot plug/unplug */
99b2ab9d
TI
1713static void had_audio_wq(struct work_struct *work)
1714{
1715 struct snd_intelhad *ctx =
1716 container_of(work, struct snd_intelhad, hdmi_audio_wq);
1717 struct intel_hdmi_lpe_audio_pdata *pdata = ctx->dev->platform_data;
da864809 1718
182cdf23 1719 pm_runtime_get_sync(ctx->dev);
8f8d1d7f 1720 mutex_lock(&ctx->mutex);
99b2ab9d
TI
1721 if (!pdata->hdmi_connected) {
1722 dev_dbg(ctx->dev, "%s: Event: HAD_NOTIFY_HOT_UNPLUG\n",
1723 __func__);
4aedb946 1724 memset(ctx->eld, 0, sizeof(ctx->eld)); /* clear the old ELD */
0e9c67d7 1725 had_process_hot_unplug(ctx);
da864809
TI
1726 } else {
1727 struct intel_hdmi_lpe_audio_eld *eld = &pdata->eld;
1728
0e9c67d7
TI
1729 dev_dbg(ctx->dev, "%s: HAD_NOTIFY_ELD : port = %d, tmds = %d\n",
1730 __func__, eld->port_id, pdata->tmds_clock_speed);
1731
da864809
TI
1732 switch (eld->pipe_id) {
1733 case 0:
1734 ctx->had_config_offset = AUDIO_HDMI_CONFIG_A;
1735 break;
1736 case 1:
1737 ctx->had_config_offset = AUDIO_HDMI_CONFIG_B;
1738 break;
1739 case 2:
1740 ctx->had_config_offset = AUDIO_HDMI_CONFIG_C;
1741 break;
1742 default:
99b2ab9d 1743 dev_dbg(ctx->dev, "Invalid pipe %d\n",
da864809
TI
1744 eld->pipe_id);
1745 break;
1746 }
1747
df0435db 1748 memcpy(ctx->eld, eld->eld_data, sizeof(ctx->eld));
da864809 1749
0e9c67d7
TI
1750 ctx->dp_output = pdata->dp_output;
1751 ctx->tmds_clock_speed = pdata->tmds_clock_speed;
1752 ctx->link_rate = pdata->link_rate;
da864809 1753
0e9c67d7 1754 had_process_hot_plug(ctx);
da864809 1755
0e9c67d7 1756 /* Process mode change if stream is active */
f69bd104 1757 hdmi_audio_mode_change(ctx);
da864809 1758 }
8f8d1d7f 1759 mutex_unlock(&ctx->mutex);
182cdf23
TI
1760 pm_runtime_put(ctx->dev);
1761}
1762
1763/*
1764 * PM callbacks
1765 */
1766
1767static int hdmi_lpe_audio_runtime_suspend(struct device *dev)
1768{
1769 struct snd_intelhad *ctx = dev_get_drvdata(dev);
1770 struct snd_pcm_substream *substream;
1771
1772 substream = had_substream_get(ctx);
1773 if (substream) {
1774 snd_pcm_suspend(substream);
1775 had_substream_put(ctx);
1776 }
1777
1778 return 0;
1779}
1780
1781static int hdmi_lpe_audio_suspend(struct device *dev)
1782{
1783 struct snd_intelhad *ctx = dev_get_drvdata(dev);
1784 int err;
1785
1786 err = hdmi_lpe_audio_runtime_suspend(dev);
1787 if (!err)
1788 snd_power_change_state(ctx->card, SNDRV_CTL_POWER_D3hot);
1789 return err;
1790}
1791
1792static int hdmi_lpe_audio_resume(struct device *dev)
1793{
1794 struct snd_intelhad *ctx = dev_get_drvdata(dev);
1795
1796 snd_power_change_state(ctx->card, SNDRV_CTL_POWER_D0);
1797 return 0;
da864809
TI
1798}
1799
1800/* release resources */
1801static void hdmi_lpe_audio_free(struct snd_card *card)
1802{
1803 struct snd_intelhad *ctx = card->private_data;
1804
99b2ab9d
TI
1805 cancel_work_sync(&ctx->hdmi_audio_wq);
1806
da864809
TI
1807 if (ctx->mmio_start)
1808 iounmap(ctx->mmio_start);
1809 if (ctx->irq >= 0)
1810 free_irq(ctx->irq, ctx);
1811}
1812
79dda75a 1813/*
da864809 1814 * hdmi_lpe_audio_probe - start bridge with i915
5dab11d8 1815 *
da864809 1816 * This function is called when the i915 driver creates the
2e52f5e5 1817 * hdmi-lpe-audio platform device.
5dab11d8 1818 */
da864809 1819static int hdmi_lpe_audio_probe(struct platform_device *pdev)
5dab11d8 1820{
5dab11d8 1821 struct snd_card *card;
da864809
TI
1822 struct snd_intelhad *ctx;
1823 struct snd_pcm *pcm;
1824 struct intel_hdmi_lpe_audio_pdata *pdata;
1825 int irq;
1826 struct resource *res_mmio;
4aedb946 1827 int i, ret;
da864809 1828
da864809
TI
1829 pdata = pdev->dev.platform_data;
1830 if (!pdata) {
1831 dev_err(&pdev->dev, "%s: quit: pdata not allocated by i915!!\n", __func__);
1832 return -EINVAL;
1833 }
5dab11d8 1834
da864809
TI
1835 /* get resources */
1836 irq = platform_get_irq(pdev, 0);
1837 if (irq < 0) {
1838 dev_err(&pdev->dev, "Could not get irq resource\n");
1839 return -ENODEV;
1840 }
1841
1842 res_mmio = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1843 if (!res_mmio) {
1844 dev_err(&pdev->dev, "Could not get IO_MEM resources\n");
1845 return -ENXIO;
1846 }
5dab11d8 1847
5647aec2 1848 /* create a card instance with ALSA framework */
da864809
TI
1849 ret = snd_card_new(&pdev->dev, hdmi_card_index, hdmi_card_id,
1850 THIS_MODULE, sizeof(*ctx), &card);
1851 if (ret)
1852 return ret;
1853
1854 ctx = card->private_data;
1855 spin_lock_init(&ctx->had_spinlock);
8f8d1d7f 1856 mutex_init(&ctx->mutex);
91b0cb0c 1857 ctx->connected = false;
da864809
TI
1858 ctx->dev = &pdev->dev;
1859 ctx->card = card;
da864809
TI
1860 ctx->aes_bits = SNDRV_PCM_DEFAULT_CON_SPDIF;
1861 strcpy(card->driver, INTEL_HAD);
1862 strcpy(card->shortname, INTEL_HAD);
1863
1864 ctx->irq = -1;
1865 ctx->tmds_clock_speed = DIS_SAMPLE_RATE_148_5;
99b2ab9d 1866 INIT_WORK(&ctx->hdmi_audio_wq, had_audio_wq);
da864809
TI
1867
1868 card->private_free = hdmi_lpe_audio_free;
1869
1870 /* assume pipe A as default */
1871 ctx->had_config_offset = AUDIO_HDMI_CONFIG_A;
1872
1873 platform_set_drvdata(pdev, ctx);
1874
1875 dev_dbg(&pdev->dev, "%s: mmio_start = 0x%x, mmio_end = 0x%x\n",
1876 __func__, (unsigned int)res_mmio->start,
1877 (unsigned int)res_mmio->end);
1878
1879 ctx->mmio_start = ioremap_nocache(res_mmio->start,
1880 (size_t)(resource_size(res_mmio)));
1881 if (!ctx->mmio_start) {
1882 dev_err(&pdev->dev, "Could not get ioremap\n");
1883 ret = -EACCES;
1884 goto err;
1885 }
5dab11d8 1886
da864809
TI
1887 /* setup interrupt handler */
1888 ret = request_irq(irq, display_pipe_interrupt_handler, 0,
1889 pdev->name, ctx);
1890 if (ret < 0) {
1891 dev_err(&pdev->dev, "request_irq failed\n");
1892 goto err;
1893 }
5dab11d8 1894
da864809
TI
1895 ctx->irq = irq;
1896
1897 ret = snd_pcm_new(card, INTEL_HAD, PCM_INDEX, MAX_PB_STREAMS,
1898 MAX_CAP_STREAMS, &pcm);
1899 if (ret)
5dab11d8
JA
1900 goto err;
1901
1902 /* setup private data which can be retrieved when required */
da864809 1903 pcm->private_data = ctx;
5dab11d8
JA
1904 pcm->info_flags = 0;
1905 strncpy(pcm->name, card->shortname, strlen(card->shortname));
da864809 1906 /* setup the ops for playabck */
5dab11d8
JA
1907 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1908 &snd_intelhad_playback_ops);
412bbe7d
TI
1909
1910 /* only 32bit addressable */
1911 dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
1912 dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
1913
5dab11d8
JA
1914 /* allocate dma pages for ALSA stream operations
1915 * memory allocated is based on size, not max value
1916 * thus using same argument for max & size
1917 */
da864809 1918 snd_pcm_lib_preallocate_pages_for_all(pcm,
5dab11d8
JA
1919 SNDRV_DMA_TYPE_DEV, NULL,
1920 HAD_MAX_BUFFER, HAD_MAX_BUFFER);
5dab11d8 1921
4aedb946
TI
1922 /* create controls */
1923 for (i = 0; i < ARRAY_SIZE(had_controls); i++) {
1924 ret = snd_ctl_add(card, snd_ctl_new1(&had_controls[i], ctx));
1925 if (ret < 0)
1926 goto err;
1927 }
5dab11d8
JA
1928
1929 init_channel_allocations();
1930
1931 /* Register channel map controls */
da864809
TI
1932 ret = had_register_chmap_ctls(ctx, pcm);
1933 if (ret < 0)
5dab11d8
JA
1934 goto err;
1935
da864809
TI
1936 ret = snd_card_register(card);
1937 if (ret)
36ec0d99
TI
1938 goto err;
1939
bcce775c 1940 spin_lock_irq(&pdata->lpe_audio_slock);
da864809 1941 pdata->notify_audio_lpe = notify_audio_lpe;
99b2ab9d 1942 pdata->notify_pending = false;
bcce775c 1943 spin_unlock_irq(&pdata->lpe_audio_slock);
da864809
TI
1944
1945 pm_runtime_set_active(&pdev->dev);
1946 pm_runtime_enable(&pdev->dev);
1947
99b2ab9d 1948 dev_dbg(&pdev->dev, "%s: handle pending notification\n", __func__);
da864809 1949 schedule_work(&ctx->hdmi_audio_wq);
5dab11d8 1950
79dda75a 1951 return 0;
5647aec2 1952
5dab11d8
JA
1953err:
1954 snd_card_free(card);
da864809 1955 return ret;
5dab11d8
JA
1956}
1957
79dda75a 1958/*
da864809 1959 * hdmi_lpe_audio_remove - stop bridge with i915
5dab11d8 1960 *
2e52f5e5 1961 * This function is called when the platform device is destroyed.
5dab11d8 1962 */
da864809 1963static int hdmi_lpe_audio_remove(struct platform_device *pdev)
5dab11d8 1964{
da864809 1965 struct snd_intelhad *ctx = platform_get_drvdata(pdev);
5dab11d8 1966
91b0cb0c 1967 if (ctx->connected)
da864809
TI
1968 snd_intelhad_enable_audio_int(ctx, false);
1969 snd_card_free(ctx->card);
5dab11d8
JA
1970 return 0;
1971}
1972
182cdf23
TI
1973static const struct dev_pm_ops hdmi_lpe_audio_pm = {
1974 SET_SYSTEM_SLEEP_PM_OPS(hdmi_lpe_audio_suspend, hdmi_lpe_audio_resume)
1975 SET_RUNTIME_PM_OPS(hdmi_lpe_audio_runtime_suspend, NULL, NULL)
1976};
1977
da864809
TI
1978static struct platform_driver hdmi_lpe_audio_driver = {
1979 .driver = {
1980 .name = "hdmi-lpe-audio",
182cdf23 1981 .pm = &hdmi_lpe_audio_pm,
da864809
TI
1982 },
1983 .probe = hdmi_lpe_audio_probe,
1984 .remove = hdmi_lpe_audio_remove,
da864809
TI
1985};
1986
1987module_platform_driver(hdmi_lpe_audio_driver);
1988MODULE_ALIAS("platform:hdmi_lpe_audio");
1989
5dab11d8
JA
1990MODULE_AUTHOR("Sailaja Bandarupalli <sailaja.bandarupalli@intel.com>");
1991MODULE_AUTHOR("Ramesh Babu K V <ramesh.babu@intel.com>");
1992MODULE_AUTHOR("Vaibhav Agarwal <vaibhav.agarwal@intel.com>");
1993MODULE_AUTHOR("Jerome Anand <jerome.anand@intel.com>");
1994MODULE_DESCRIPTION("Intel HDMI Audio driver");
1995MODULE_LICENSE("GPL v2");
1996MODULE_SUPPORTED_DEVICE("{Intel,Intel_HAD}");