Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.16-rc2 906 lines 25 kB view raw
1/* 2 * Intel SST Haswell/Broadwell PCM Support 3 * 4 * Copyright (C) 2013, Intel Corporation. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License version 8 * 2 as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 */ 16 17#include <linux/module.h> 18#include <linux/dma-mapping.h> 19#include <linux/slab.h> 20#include <linux/delay.h> 21#include <asm/page.h> 22#include <asm/pgtable.h> 23#include <sound/core.h> 24#include <sound/pcm.h> 25#include <sound/pcm_params.h> 26#include <sound/dmaengine_pcm.h> 27#include <sound/soc.h> 28#include <sound/tlv.h> 29#include <sound/compress_driver.h> 30 31#include "sst-haswell-ipc.h" 32#include "sst-dsp-priv.h" 33#include "sst-dsp.h" 34 35#define HSW_PCM_COUNT 6 36#define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */ 37 38/* simple volume table */ 39static const u32 volume_map[] = { 40 HSW_VOLUME_MAX >> 30, 41 HSW_VOLUME_MAX >> 29, 42 HSW_VOLUME_MAX >> 28, 43 HSW_VOLUME_MAX >> 27, 44 HSW_VOLUME_MAX >> 26, 45 HSW_VOLUME_MAX >> 25, 46 HSW_VOLUME_MAX >> 24, 47 HSW_VOLUME_MAX >> 23, 48 HSW_VOLUME_MAX >> 22, 49 HSW_VOLUME_MAX >> 21, 50 HSW_VOLUME_MAX >> 20, 51 HSW_VOLUME_MAX >> 19, 52 HSW_VOLUME_MAX >> 18, 53 HSW_VOLUME_MAX >> 17, 54 HSW_VOLUME_MAX >> 16, 55 HSW_VOLUME_MAX >> 15, 56 HSW_VOLUME_MAX >> 14, 57 HSW_VOLUME_MAX >> 13, 58 HSW_VOLUME_MAX >> 12, 59 HSW_VOLUME_MAX >> 11, 60 HSW_VOLUME_MAX >> 10, 61 HSW_VOLUME_MAX >> 9, 62 HSW_VOLUME_MAX >> 8, 63 HSW_VOLUME_MAX >> 7, 64 HSW_VOLUME_MAX >> 6, 65 HSW_VOLUME_MAX >> 5, 66 HSW_VOLUME_MAX >> 4, 67 HSW_VOLUME_MAX >> 3, 68 HSW_VOLUME_MAX >> 2, 69 HSW_VOLUME_MAX >> 1, 70 HSW_VOLUME_MAX >> 0, 71}; 72 73#define HSW_PCM_PERIODS_MAX 64 74#define HSW_PCM_PERIODS_MIN 2 75 76static const struct snd_pcm_hardware hsw_pcm_hardware = { 77 .info = SNDRV_PCM_INFO_MMAP | 78 SNDRV_PCM_INFO_MMAP_VALID | 79 SNDRV_PCM_INFO_INTERLEAVED | 80 SNDRV_PCM_INFO_PAUSE | 81 SNDRV_PCM_INFO_RESUME | 82 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, 83 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE | 84 SNDRV_PCM_FMTBIT_S32_LE, 85 .period_bytes_min = PAGE_SIZE, 86 .period_bytes_max = (HSW_PCM_PERIODS_MAX / HSW_PCM_PERIODS_MIN) * PAGE_SIZE, 87 .periods_min = HSW_PCM_PERIODS_MIN, 88 .periods_max = HSW_PCM_PERIODS_MAX, 89 .buffer_bytes_max = HSW_PCM_PERIODS_MAX * PAGE_SIZE, 90}; 91 92/* private data for each PCM DSP stream */ 93struct hsw_pcm_data { 94 int dai_id; 95 struct sst_hsw_stream *stream; 96 u32 volume[2]; 97 struct snd_pcm_substream *substream; 98 struct snd_compr_stream *cstream; 99 unsigned int wpos; 100 struct mutex mutex; 101 bool allocated; 102}; 103 104/* private data for the driver */ 105struct hsw_priv_data { 106 /* runtime DSP */ 107 struct sst_hsw *hsw; 108 109 /* page tables */ 110 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; 111 112 /* DAI data */ 113 struct hsw_pcm_data pcm[HSW_PCM_COUNT]; 114}; 115 116static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data); 117 118static inline u32 hsw_mixer_to_ipc(unsigned int value) 119{ 120 if (value >= ARRAY_SIZE(volume_map)) 121 return volume_map[0]; 122 else 123 return volume_map[value]; 124} 125 126static inline unsigned int hsw_ipc_to_mixer(u32 value) 127{ 128 int i; 129 130 for (i = 0; i < ARRAY_SIZE(volume_map); i++) { 131 if (volume_map[i] >= value) 132 return i; 133 } 134 135 return i - 1; 136} 137 138static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, 139 struct snd_ctl_elem_value *ucontrol) 140{ 141 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); 142 struct soc_mixer_control *mc = 143 (struct soc_mixer_control *)kcontrol->private_value; 144 struct hsw_priv_data *pdata = 145 snd_soc_platform_get_drvdata(platform); 146 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 147 struct sst_hsw *hsw = pdata->hsw; 148 u32 volume; 149 150 mutex_lock(&pcm_data->mutex); 151 152 if (!pcm_data->stream) { 153 pcm_data->volume[0] = 154 hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 155 pcm_data->volume[1] = 156 hsw_mixer_to_ipc(ucontrol->value.integer.value[1]); 157 mutex_unlock(&pcm_data->mutex); 158 return 0; 159 } 160 161 if (ucontrol->value.integer.value[0] == 162 ucontrol->value.integer.value[1]) { 163 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 164 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 2, volume); 165 } else { 166 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 167 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 0, volume); 168 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]); 169 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 1, volume); 170 } 171 172 mutex_unlock(&pcm_data->mutex); 173 return 0; 174} 175 176static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, 177 struct snd_ctl_elem_value *ucontrol) 178{ 179 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); 180 struct soc_mixer_control *mc = 181 (struct soc_mixer_control *)kcontrol->private_value; 182 struct hsw_priv_data *pdata = 183 snd_soc_platform_get_drvdata(platform); 184 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 185 struct sst_hsw *hsw = pdata->hsw; 186 u32 volume; 187 188 mutex_lock(&pcm_data->mutex); 189 190 if (!pcm_data->stream) { 191 ucontrol->value.integer.value[0] = 192 hsw_ipc_to_mixer(pcm_data->volume[0]); 193 ucontrol->value.integer.value[1] = 194 hsw_ipc_to_mixer(pcm_data->volume[1]); 195 mutex_unlock(&pcm_data->mutex); 196 return 0; 197 } 198 199 sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 0, &volume); 200 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume); 201 sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 1, &volume); 202 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume); 203 mutex_unlock(&pcm_data->mutex); 204 205 return 0; 206} 207 208static int hsw_volume_put(struct snd_kcontrol *kcontrol, 209 struct snd_ctl_elem_value *ucontrol) 210{ 211 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); 212 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); 213 struct sst_hsw *hsw = pdata->hsw; 214 u32 volume; 215 216 if (ucontrol->value.integer.value[0] == 217 ucontrol->value.integer.value[1]) { 218 219 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 220 sst_hsw_mixer_set_volume(hsw, 0, 2, volume); 221 222 } else { 223 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 224 sst_hsw_mixer_set_volume(hsw, 0, 0, volume); 225 226 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]); 227 sst_hsw_mixer_set_volume(hsw, 0, 1, volume); 228 } 229 230 return 0; 231} 232 233static int hsw_volume_get(struct snd_kcontrol *kcontrol, 234 struct snd_ctl_elem_value *ucontrol) 235{ 236 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); 237 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); 238 struct sst_hsw *hsw = pdata->hsw; 239 unsigned int volume = 0; 240 241 sst_hsw_mixer_get_volume(hsw, 0, 0, &volume); 242 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume); 243 244 sst_hsw_mixer_get_volume(hsw, 0, 1, &volume); 245 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume); 246 247 return 0; 248} 249 250/* TLV used by both global and stream volumes */ 251static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1); 252 253/* System Pin has no volume control */ 254static const struct snd_kcontrol_new hsw_volume_controls[] = { 255 /* Global DSP volume */ 256 SOC_DOUBLE_EXT_TLV("Master Playback Volume", 0, 0, 8, 257 ARRAY_SIZE(volume_map) -1, 0, 258 hsw_volume_get, hsw_volume_put, hsw_vol_tlv), 259 /* Offload 0 volume */ 260 SOC_DOUBLE_EXT_TLV("Media0 Playback Volume", 1, 0, 8, 261 ARRAY_SIZE(volume_map), 0, 262 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 263 /* Offload 1 volume */ 264 SOC_DOUBLE_EXT_TLV("Media1 Playback Volume", 2, 0, 8, 265 ARRAY_SIZE(volume_map), 0, 266 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 267 /* Loopback volume */ 268 SOC_DOUBLE_EXT_TLV("Loopback Capture Volume", 3, 0, 8, 269 ARRAY_SIZE(volume_map), 0, 270 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 271 /* Mic Capture volume */ 272 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8, 273 ARRAY_SIZE(volume_map), 0, 274 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 275}; 276 277/* Create DMA buffer page table for DSP */ 278static int create_adsp_page_table(struct snd_pcm_substream *substream, 279 struct hsw_priv_data *pdata, struct snd_soc_pcm_runtime *rtd, 280 unsigned char *dma_area, size_t size, int pcm) 281{ 282 struct snd_dma_buffer *dmab = snd_pcm_get_dma_buf(substream); 283 int i, pages, stream = substream->stream; 284 285 pages = snd_sgbuf_aligned_pages(size); 286 287 dev_dbg(rtd->dev, "generating page table for %p size 0x%zu pages %d\n", 288 dma_area, size, pages); 289 290 for (i = 0; i < pages; i++) { 291 u32 idx = (((i << 2) + i)) >> 1; 292 u32 pfn = snd_sgbuf_get_addr(dmab, i * PAGE_SIZE) >> PAGE_SHIFT; 293 u32 *pg_table; 294 295 dev_dbg(rtd->dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn); 296 297 pg_table = (u32 *)(pdata->dmab[pcm][stream].area + idx); 298 299 if (i & 1) 300 *pg_table |= (pfn << 4); 301 else 302 *pg_table |= pfn; 303 } 304 305 return 0; 306} 307 308/* this may get called several times by oss emulation */ 309static int hsw_pcm_hw_params(struct snd_pcm_substream *substream, 310 struct snd_pcm_hw_params *params) 311{ 312 struct snd_soc_pcm_runtime *rtd = substream->private_data; 313 struct snd_pcm_runtime *runtime = substream->runtime; 314 struct hsw_priv_data *pdata = 315 snd_soc_platform_get_drvdata(rtd->platform); 316 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 317 struct sst_hsw *hsw = pdata->hsw; 318 struct sst_module *module_data; 319 struct sst_dsp *dsp; 320 struct snd_dma_buffer *dmab; 321 enum sst_hsw_stream_type stream_type; 322 enum sst_hsw_stream_path_id path_id; 323 u32 rate, bits, map, pages, module_id; 324 u8 channels; 325 int ret; 326 327 /* check if we are being called a subsequent time */ 328 if (pcm_data->allocated) { 329 ret = sst_hsw_stream_reset(hsw, pcm_data->stream); 330 if (ret < 0) 331 dev_dbg(rtd->dev, "error: reset stream failed %d\n", 332 ret); 333 334 ret = sst_hsw_stream_free(hsw, pcm_data->stream); 335 if (ret < 0) { 336 dev_dbg(rtd->dev, "error: free stream failed %d\n", 337 ret); 338 return ret; 339 } 340 pcm_data->allocated = false; 341 342 pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id, 343 hsw_notify_pointer, pcm_data); 344 if (pcm_data->stream == NULL) { 345 dev_err(rtd->dev, "error: failed to create stream\n"); 346 return -EINVAL; 347 } 348 } 349 350 /* stream direction */ 351 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 352 path_id = SST_HSW_STREAM_PATH_SSP0_OUT; 353 else 354 path_id = SST_HSW_STREAM_PATH_SSP0_IN; 355 356 /* DSP stream type depends on DAI ID */ 357 switch (rtd->cpu_dai->id) { 358 case 0: 359 stream_type = SST_HSW_STREAM_TYPE_SYSTEM; 360 module_id = SST_HSW_MODULE_PCM_SYSTEM; 361 break; 362 case 1: 363 case 2: 364 stream_type = SST_HSW_STREAM_TYPE_RENDER; 365 module_id = SST_HSW_MODULE_PCM; 366 break; 367 case 3: 368 /* path ID needs to be OUT for loopback */ 369 stream_type = SST_HSW_STREAM_TYPE_LOOPBACK; 370 path_id = SST_HSW_STREAM_PATH_SSP0_OUT; 371 module_id = SST_HSW_MODULE_PCM_REFERENCE; 372 break; 373 case 4: 374 stream_type = SST_HSW_STREAM_TYPE_CAPTURE; 375 module_id = SST_HSW_MODULE_PCM_CAPTURE; 376 break; 377 default: 378 dev_err(rtd->dev, "error: invalid DAI ID %d\n", 379 rtd->cpu_dai->id); 380 return -EINVAL; 381 }; 382 383 ret = sst_hsw_stream_format(hsw, pcm_data->stream, 384 path_id, stream_type, SST_HSW_STREAM_FORMAT_PCM_FORMAT); 385 if (ret < 0) { 386 dev_err(rtd->dev, "error: failed to set format %d\n", ret); 387 return ret; 388 } 389 390 rate = params_rate(params); 391 ret = sst_hsw_stream_set_rate(hsw, pcm_data->stream, rate); 392 if (ret < 0) { 393 dev_err(rtd->dev, "error: could not set rate %d\n", rate); 394 return ret; 395 } 396 397 switch (params_format(params)) { 398 case SNDRV_PCM_FORMAT_S16_LE: 399 bits = SST_HSW_DEPTH_16BIT; 400 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 16); 401 break; 402 case SNDRV_PCM_FORMAT_S24_LE: 403 bits = SST_HSW_DEPTH_24BIT; 404 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 32); 405 break; 406 default: 407 dev_err(rtd->dev, "error: invalid format %d\n", 408 params_format(params)); 409 return -EINVAL; 410 } 411 412 ret = sst_hsw_stream_set_bits(hsw, pcm_data->stream, bits); 413 if (ret < 0) { 414 dev_err(rtd->dev, "error: could not set bits %d\n", bits); 415 return ret; 416 } 417 418 /* we only support stereo atm */ 419 channels = params_channels(params); 420 if (channels != 2) { 421 dev_err(rtd->dev, "error: invalid channels %d\n", channels); 422 return -EINVAL; 423 } 424 425 map = create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO); 426 sst_hsw_stream_set_map_config(hsw, pcm_data->stream, 427 map, SST_HSW_CHANNEL_CONFIG_STEREO); 428 429 ret = sst_hsw_stream_set_channels(hsw, pcm_data->stream, channels); 430 if (ret < 0) { 431 dev_err(rtd->dev, "error: could not set channels %d\n", 432 channels); 433 return ret; 434 } 435 436 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); 437 if (ret < 0) { 438 dev_err(rtd->dev, "error: could not allocate %d bytes for PCM %d\n", 439 params_buffer_bytes(params), ret); 440 return ret; 441 } 442 443 dmab = snd_pcm_get_dma_buf(substream); 444 445 ret = create_adsp_page_table(substream, pdata, rtd, runtime->dma_area, 446 runtime->dma_bytes, rtd->cpu_dai->id); 447 if (ret < 0) 448 return ret; 449 450 sst_hsw_stream_set_style(hsw, pcm_data->stream, 451 SST_HSW_INTERLEAVING_PER_CHANNEL); 452 453 if (runtime->dma_bytes % PAGE_SIZE) 454 pages = (runtime->dma_bytes / PAGE_SIZE) + 1; 455 else 456 pages = runtime->dma_bytes / PAGE_SIZE; 457 458 ret = sst_hsw_stream_buffer(hsw, pcm_data->stream, 459 pdata->dmab[rtd->cpu_dai->id][substream->stream].addr, 460 pages, runtime->dma_bytes, 0, 461 snd_sgbuf_get_addr(dmab, 0) >> PAGE_SHIFT); 462 if (ret < 0) { 463 dev_err(rtd->dev, "error: failed to set DMA buffer %d\n", ret); 464 return ret; 465 } 466 467 dsp = sst_hsw_get_dsp(hsw); 468 469 module_data = sst_module_get_from_id(dsp, module_id); 470 if (module_data == NULL) { 471 dev_err(rtd->dev, "error: failed to get module config\n"); 472 return -EINVAL; 473 } 474 475 /* we use hardcoded memory offsets atm, will be updated for new FW */ 476 if (stream_type == SST_HSW_STREAM_TYPE_CAPTURE) { 477 sst_hsw_stream_set_module_info(hsw, pcm_data->stream, 478 SST_HSW_MODULE_PCM_CAPTURE, module_data->entry); 479 sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream, 480 0x449400, 0x4000); 481 sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream, 482 0x400000, 0); 483 } else { /* stream_type == SST_HSW_STREAM_TYPE_SYSTEM */ 484 sst_hsw_stream_set_module_info(hsw, pcm_data->stream, 485 SST_HSW_MODULE_PCM_SYSTEM, module_data->entry); 486 487 sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream, 488 module_data->offset, module_data->size); 489 sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream, 490 0x44d400, 0x3800); 491 492 sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream, 493 module_data->offset, module_data->size); 494 sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream, 495 0x400000, 0); 496 } 497 498 ret = sst_hsw_stream_commit(hsw, pcm_data->stream); 499 if (ret < 0) { 500 dev_err(rtd->dev, "error: failed to commit stream %d\n", ret); 501 return ret; 502 } 503 pcm_data->allocated = true; 504 505 ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1); 506 if (ret < 0) 507 dev_err(rtd->dev, "error: failed to pause %d\n", ret); 508 509 return 0; 510} 511 512static int hsw_pcm_hw_free(struct snd_pcm_substream *substream) 513{ 514 snd_pcm_lib_free_pages(substream); 515 return 0; 516} 517 518static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 519{ 520 struct snd_soc_pcm_runtime *rtd = substream->private_data; 521 struct hsw_priv_data *pdata = 522 snd_soc_platform_get_drvdata(rtd->platform); 523 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 524 struct sst_hsw *hsw = pdata->hsw; 525 526 switch (cmd) { 527 case SNDRV_PCM_TRIGGER_START: 528 case SNDRV_PCM_TRIGGER_RESUME: 529 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 530 sst_hsw_stream_resume(hsw, pcm_data->stream, 0); 531 break; 532 case SNDRV_PCM_TRIGGER_STOP: 533 case SNDRV_PCM_TRIGGER_SUSPEND: 534 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 535 sst_hsw_stream_pause(hsw, pcm_data->stream, 0); 536 break; 537 default: 538 break; 539 } 540 541 return 0; 542} 543 544static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data) 545{ 546 struct hsw_pcm_data *pcm_data = data; 547 struct snd_pcm_substream *substream = pcm_data->substream; 548 struct snd_pcm_runtime *runtime = substream->runtime; 549 struct snd_soc_pcm_runtime *rtd = substream->private_data; 550 u32 pos; 551 552 pos = frames_to_bytes(runtime, 553 (runtime->control->appl_ptr % runtime->buffer_size)); 554 555 dev_dbg(rtd->dev, "PCM: App pointer %d bytes\n", pos); 556 557 /* let alsa know we have play a period */ 558 snd_pcm_period_elapsed(substream); 559 return pos; 560} 561 562static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream) 563{ 564 struct snd_soc_pcm_runtime *rtd = substream->private_data; 565 struct snd_pcm_runtime *runtime = substream->runtime; 566 struct hsw_priv_data *pdata = 567 snd_soc_platform_get_drvdata(rtd->platform); 568 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 569 struct sst_hsw *hsw = pdata->hsw; 570 snd_pcm_uframes_t offset; 571 uint64_t ppos; 572 u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream); 573 574 offset = bytes_to_frames(runtime, position); 575 ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream); 576 577 dev_dbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n", 578 position, ppos); 579 return offset; 580} 581 582static int hsw_pcm_open(struct snd_pcm_substream *substream) 583{ 584 struct snd_soc_pcm_runtime *rtd = substream->private_data; 585 struct hsw_priv_data *pdata = 586 snd_soc_platform_get_drvdata(rtd->platform); 587 struct hsw_pcm_data *pcm_data; 588 struct sst_hsw *hsw = pdata->hsw; 589 590 pcm_data = &pdata->pcm[rtd->cpu_dai->id]; 591 592 mutex_lock(&pcm_data->mutex); 593 594 snd_soc_pcm_set_drvdata(rtd, pcm_data); 595 pcm_data->substream = substream; 596 597 snd_soc_set_runtime_hwparams(substream, &hsw_pcm_hardware); 598 599 pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id, 600 hsw_notify_pointer, pcm_data); 601 if (pcm_data->stream == NULL) { 602 dev_err(rtd->dev, "error: failed to create stream\n"); 603 mutex_unlock(&pcm_data->mutex); 604 return -EINVAL; 605 } 606 607 /* Set previous saved volume */ 608 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 609 0, pcm_data->volume[0]); 610 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 611 1, pcm_data->volume[1]); 612 613 mutex_unlock(&pcm_data->mutex); 614 return 0; 615} 616 617static int hsw_pcm_close(struct snd_pcm_substream *substream) 618{ 619 struct snd_soc_pcm_runtime *rtd = substream->private_data; 620 struct hsw_priv_data *pdata = 621 snd_soc_platform_get_drvdata(rtd->platform); 622 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); 623 struct sst_hsw *hsw = pdata->hsw; 624 int ret; 625 626 mutex_lock(&pcm_data->mutex); 627 ret = sst_hsw_stream_reset(hsw, pcm_data->stream); 628 if (ret < 0) { 629 dev_dbg(rtd->dev, "error: reset stream failed %d\n", ret); 630 goto out; 631 } 632 633 ret = sst_hsw_stream_free(hsw, pcm_data->stream); 634 if (ret < 0) { 635 dev_dbg(rtd->dev, "error: free stream failed %d\n", ret); 636 goto out; 637 } 638 pcm_data->allocated = 0; 639 pcm_data->stream = NULL; 640 641out: 642 mutex_unlock(&pcm_data->mutex); 643 return ret; 644} 645 646static struct snd_pcm_ops hsw_pcm_ops = { 647 .open = hsw_pcm_open, 648 .close = hsw_pcm_close, 649 .ioctl = snd_pcm_lib_ioctl, 650 .hw_params = hsw_pcm_hw_params, 651 .hw_free = hsw_pcm_hw_free, 652 .trigger = hsw_pcm_trigger, 653 .pointer = hsw_pcm_pointer, 654 .page = snd_pcm_sgbuf_ops_page, 655}; 656 657static void hsw_pcm_free(struct snd_pcm *pcm) 658{ 659 snd_pcm_lib_preallocate_free_for_all(pcm); 660} 661 662static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd) 663{ 664 struct snd_pcm *pcm = rtd->pcm; 665 struct snd_soc_platform *platform = rtd->platform; 666 struct sst_pdata *pdata = dev_get_platdata(platform->dev); 667 struct device *dev = pdata->dma_dev; 668 int ret = 0; 669 670 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream || 671 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { 672 ret = snd_pcm_lib_preallocate_pages_for_all(pcm, 673 SNDRV_DMA_TYPE_DEV_SG, 674 dev, 675 hsw_pcm_hardware.buffer_bytes_max, 676 hsw_pcm_hardware.buffer_bytes_max); 677 if (ret) { 678 dev_err(rtd->dev, "dma buffer allocation failed %d\n", 679 ret); 680 return ret; 681 } 682 } 683 684 return ret; 685} 686 687#define HSW_FORMATS \ 688 (SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\ 689 SNDRV_PCM_FMTBIT_S32_LE) 690 691static struct snd_soc_dai_driver hsw_dais[] = { 692 { 693 .name = "System Pin", 694 .playback = { 695 .stream_name = "System Playback", 696 .channels_min = 2, 697 .channels_max = 2, 698 .rates = SNDRV_PCM_RATE_48000, 699 .formats = SNDRV_PCM_FMTBIT_S16_LE, 700 }, 701 }, 702 { 703 /* PCM */ 704 .name = "Offload0 Pin", 705 .playback = { 706 .stream_name = "Offload0 Playback", 707 .channels_min = 2, 708 .channels_max = 2, 709 .rates = SNDRV_PCM_RATE_8000_192000, 710 .formats = HSW_FORMATS, 711 }, 712 }, 713 { 714 /* PCM */ 715 .name = "Offload1 Pin", 716 .playback = { 717 .stream_name = "Offload1 Playback", 718 .channels_min = 2, 719 .channels_max = 2, 720 .rates = SNDRV_PCM_RATE_8000_192000, 721 .formats = HSW_FORMATS, 722 }, 723 }, 724 { 725 .name = "Loopback Pin", 726 .capture = { 727 .stream_name = "Loopback Capture", 728 .channels_min = 2, 729 .channels_max = 2, 730 .rates = SNDRV_PCM_RATE_8000_192000, 731 .formats = HSW_FORMATS, 732 }, 733 }, 734 { 735 .name = "Capture Pin", 736 .capture = { 737 .stream_name = "Analog Capture", 738 .channels_min = 2, 739 .channels_max = 2, 740 .rates = SNDRV_PCM_RATE_8000_192000, 741 .formats = HSW_FORMATS, 742 }, 743 }, 744}; 745 746static const struct snd_soc_dapm_widget widgets[] = { 747 748 /* Backend DAIs */ 749 SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL, 0, SND_SOC_NOPM, 0, 0), 750 SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL, 0, SND_SOC_NOPM, 0, 0), 751 SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL, 0, SND_SOC_NOPM, 0, 0), 752 SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL, 0, SND_SOC_NOPM, 0, 0), 753 754 /* Global Playback Mixer */ 755 SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM, 0, 0, NULL, 0), 756}; 757 758static const struct snd_soc_dapm_route graph[] = { 759 760 /* Playback Mixer */ 761 {"Playback VMixer", NULL, "System Playback"}, 762 {"Playback VMixer", NULL, "Offload0 Playback"}, 763 {"Playback VMixer", NULL, "Offload1 Playback"}, 764 765 {"SSP0 CODEC OUT", NULL, "Playback VMixer"}, 766 767 {"Analog Capture", NULL, "SSP0 CODEC IN"}, 768}; 769 770static int hsw_pcm_probe(struct snd_soc_platform *platform) 771{ 772 struct sst_pdata *pdata = dev_get_platdata(platform->dev); 773 struct hsw_priv_data *priv_data; 774 struct device *dma_dev; 775 int i, ret = 0; 776 777 if (!pdata) 778 return -ENODEV; 779 780 dma_dev = pdata->dma_dev; 781 782 priv_data = devm_kzalloc(platform->dev, sizeof(*priv_data), GFP_KERNEL); 783 priv_data->hsw = pdata->dsp; 784 snd_soc_platform_set_drvdata(platform, priv_data); 785 786 /* allocate DSP buffer page tables */ 787 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { 788 789 mutex_init(&priv_data->pcm[i].mutex); 790 791 /* playback */ 792 if (hsw_dais[i].playback.channels_min) { 793 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, 794 PAGE_SIZE, &priv_data->dmab[i][0]); 795 if (ret < 0) 796 goto err; 797 } 798 799 /* capture */ 800 if (hsw_dais[i].capture.channels_min) { 801 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev, 802 PAGE_SIZE, &priv_data->dmab[i][1]); 803 if (ret < 0) 804 goto err; 805 } 806 } 807 808 return 0; 809 810err: 811 for (;i >= 0; i--) { 812 if (hsw_dais[i].playback.channels_min) 813 snd_dma_free_pages(&priv_data->dmab[i][0]); 814 if (hsw_dais[i].capture.channels_min) 815 snd_dma_free_pages(&priv_data->dmab[i][1]); 816 } 817 return ret; 818} 819 820static int hsw_pcm_remove(struct snd_soc_platform *platform) 821{ 822 struct hsw_priv_data *priv_data = 823 snd_soc_platform_get_drvdata(platform); 824 int i; 825 826 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { 827 if (hsw_dais[i].playback.channels_min) 828 snd_dma_free_pages(&priv_data->dmab[i][0]); 829 if (hsw_dais[i].capture.channels_min) 830 snd_dma_free_pages(&priv_data->dmab[i][1]); 831 } 832 833 return 0; 834} 835 836static struct snd_soc_platform_driver hsw_soc_platform = { 837 .probe = hsw_pcm_probe, 838 .remove = hsw_pcm_remove, 839 .ops = &hsw_pcm_ops, 840 .pcm_new = hsw_pcm_new, 841 .pcm_free = hsw_pcm_free, 842 .controls = hsw_volume_controls, 843 .num_controls = ARRAY_SIZE(hsw_volume_controls), 844 .dapm_widgets = widgets, 845 .num_dapm_widgets = ARRAY_SIZE(widgets), 846 .dapm_routes = graph, 847 .num_dapm_routes = ARRAY_SIZE(graph), 848}; 849 850static const struct snd_soc_component_driver hsw_dai_component = { 851 .name = "haswell-dai", 852}; 853 854static int hsw_pcm_dev_probe(struct platform_device *pdev) 855{ 856 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev); 857 int ret; 858 859 ret = sst_hsw_dsp_init(&pdev->dev, sst_pdata); 860 if (ret < 0) 861 return -ENODEV; 862 863 ret = snd_soc_register_platform(&pdev->dev, &hsw_soc_platform); 864 if (ret < 0) 865 goto err_plat; 866 867 ret = snd_soc_register_component(&pdev->dev, &hsw_dai_component, 868 hsw_dais, ARRAY_SIZE(hsw_dais)); 869 if (ret < 0) 870 goto err_comp; 871 872 return 0; 873 874err_comp: 875 snd_soc_unregister_platform(&pdev->dev); 876err_plat: 877 sst_hsw_dsp_free(&pdev->dev, sst_pdata); 878 return 0; 879} 880 881static int hsw_pcm_dev_remove(struct platform_device *pdev) 882{ 883 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev); 884 885 snd_soc_unregister_platform(&pdev->dev); 886 snd_soc_unregister_component(&pdev->dev); 887 sst_hsw_dsp_free(&pdev->dev, sst_pdata); 888 889 return 0; 890} 891 892static struct platform_driver hsw_pcm_driver = { 893 .driver = { 894 .name = "haswell-pcm-audio", 895 .owner = THIS_MODULE, 896 }, 897 898 .probe = hsw_pcm_dev_probe, 899 .remove = hsw_pcm_dev_remove, 900}; 901module_platform_driver(hsw_pcm_driver); 902 903MODULE_AUTHOR("Liam Girdwood, Xingchao Wang"); 904MODULE_DESCRIPTION("Haswell/Lynxpoint + Broadwell/Wildcatpoint PCM"); 905MODULE_LICENSE("GPL v2"); 906MODULE_ALIAS("platform:haswell-pcm-audio");