0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0013
0014 #include <linux/slab.h>
0015 #include <linux/io.h>
0016 #include <linux/module.h>
0017 #include <sound/core.h>
0018 #include <sound/pcm.h>
0019 #include <sound/pcm_params.h>
0020 #include <sound/soc.h>
0021 #include <sound/compress_driver.h>
0022 #include <asm/platform_sst_audio.h>
0023 #include "sst-mfld-platform.h"
0024 #include "sst-atom-controls.h"
0025
0026 struct sst_device *sst;
0027 static DEFINE_MUTEX(sst_lock);
0028
0029 int sst_register_dsp(struct sst_device *dev)
0030 {
0031 if (WARN_ON(!dev))
0032 return -EINVAL;
0033 if (!try_module_get(dev->dev->driver->owner))
0034 return -ENODEV;
0035 mutex_lock(&sst_lock);
0036 if (sst) {
0037 dev_err(dev->dev, "we already have a device %s\n", sst->name);
0038 module_put(dev->dev->driver->owner);
0039 mutex_unlock(&sst_lock);
0040 return -EEXIST;
0041 }
0042 dev_dbg(dev->dev, "registering device %s\n", dev->name);
0043 sst = dev;
0044 mutex_unlock(&sst_lock);
0045 return 0;
0046 }
0047 EXPORT_SYMBOL_GPL(sst_register_dsp);
0048
0049 int sst_unregister_dsp(struct sst_device *dev)
0050 {
0051 if (WARN_ON(!dev))
0052 return -EINVAL;
0053 if (dev != sst)
0054 return -EINVAL;
0055
0056 mutex_lock(&sst_lock);
0057
0058 if (!sst) {
0059 mutex_unlock(&sst_lock);
0060 return -EIO;
0061 }
0062
0063 module_put(sst->dev->driver->owner);
0064 dev_dbg(dev->dev, "unreg %s\n", sst->name);
0065 sst = NULL;
0066 mutex_unlock(&sst_lock);
0067 return 0;
0068 }
0069 EXPORT_SYMBOL_GPL(sst_unregister_dsp);
0070
0071 static const struct snd_pcm_hardware sst_platform_pcm_hw = {
0072 .info = (SNDRV_PCM_INFO_INTERLEAVED |
0073 SNDRV_PCM_INFO_DOUBLE |
0074 SNDRV_PCM_INFO_PAUSE |
0075 SNDRV_PCM_INFO_RESUME |
0076 SNDRV_PCM_INFO_MMAP|
0077 SNDRV_PCM_INFO_MMAP_VALID |
0078 SNDRV_PCM_INFO_BLOCK_TRANSFER |
0079 SNDRV_PCM_INFO_SYNC_START),
0080 .buffer_bytes_max = SST_MAX_BUFFER,
0081 .period_bytes_min = SST_MIN_PERIOD_BYTES,
0082 .period_bytes_max = SST_MAX_PERIOD_BYTES,
0083 .periods_min = SST_MIN_PERIODS,
0084 .periods_max = SST_MAX_PERIODS,
0085 .fifo_size = SST_FIFO_SIZE,
0086 };
0087
0088 static struct sst_dev_stream_map dpcm_strm_map[] = {
0089 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
0090 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA1_IN, SST_TASK_ID_MEDIA, 0},
0091 {MERR_DPCM_COMPR, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA0_IN, SST_TASK_ID_MEDIA, 0},
0092 {MERR_DPCM_AUDIO, 0, SNDRV_PCM_STREAM_CAPTURE, PIPE_PCM1_OUT, SST_TASK_ID_MEDIA, 0},
0093 {MERR_DPCM_DEEP_BUFFER, 0, SNDRV_PCM_STREAM_PLAYBACK, PIPE_MEDIA3_IN, SST_TASK_ID_MEDIA, 0},
0094 };
0095
0096 static int sst_media_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
0097 {
0098
0099 return sst_send_pipe_gains(dai, stream, mute);
0100 }
0101
0102
0103 void sst_set_stream_status(struct sst_runtime_stream *stream,
0104 int state)
0105 {
0106 unsigned long flags;
0107 spin_lock_irqsave(&stream->status_lock, flags);
0108 stream->stream_status = state;
0109 spin_unlock_irqrestore(&stream->status_lock, flags);
0110 }
0111
0112 static inline int sst_get_stream_status(struct sst_runtime_stream *stream)
0113 {
0114 int state;
0115 unsigned long flags;
0116
0117 spin_lock_irqsave(&stream->status_lock, flags);
0118 state = stream->stream_status;
0119 spin_unlock_irqrestore(&stream->status_lock, flags);
0120 return state;
0121 }
0122
0123 static void sst_fill_alloc_params(struct snd_pcm_substream *substream,
0124 struct snd_sst_alloc_params_ext *alloc_param)
0125 {
0126 unsigned int channels;
0127 snd_pcm_uframes_t period_size;
0128 ssize_t periodbytes;
0129 ssize_t buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
0130 u32 buffer_addr = substream->runtime->dma_addr;
0131
0132 channels = substream->runtime->channels;
0133 period_size = substream->runtime->period_size;
0134 periodbytes = samples_to_bytes(substream->runtime, period_size);
0135 alloc_param->ring_buf_info[0].addr = buffer_addr;
0136 alloc_param->ring_buf_info[0].size = buffer_bytes;
0137 alloc_param->sg_count = 1;
0138 alloc_param->reserved = 0;
0139 alloc_param->frag_size = periodbytes * channels;
0140
0141 }
0142 static void sst_fill_pcm_params(struct snd_pcm_substream *substream,
0143 struct snd_sst_stream_params *param)
0144 {
0145 param->uc.pcm_params.num_chan = (u8) substream->runtime->channels;
0146 param->uc.pcm_params.pcm_wd_sz = substream->runtime->sample_bits;
0147 param->uc.pcm_params.sfreq = substream->runtime->rate;
0148
0149
0150 param->uc.pcm_params.use_offload_path = 0;
0151 param->uc.pcm_params.reserved2 = 0;
0152 memset(param->uc.pcm_params.channel_map, 0, sizeof(u8));
0153
0154 }
0155
0156 static int sst_get_stream_mapping(int dev, int sdev, int dir,
0157 struct sst_dev_stream_map *map, int size)
0158 {
0159 int i;
0160
0161 if (map == NULL)
0162 return -EINVAL;
0163
0164
0165
0166 for (i = 1; i < size; i++) {
0167 if ((map[i].dev_num == dev) && (map[i].direction == dir))
0168 return i;
0169 }
0170 return 0;
0171 }
0172
0173 int sst_fill_stream_params(void *substream,
0174 const struct sst_data *ctx, struct snd_sst_params *str_params, bool is_compress)
0175 {
0176 int map_size;
0177 int index;
0178 struct sst_dev_stream_map *map;
0179 struct snd_pcm_substream *pstream = NULL;
0180 struct snd_compr_stream *cstream = NULL;
0181
0182 map = ctx->pdata->pdev_strm_map;
0183 map_size = ctx->pdata->strm_map_size;
0184
0185 if (is_compress)
0186 cstream = (struct snd_compr_stream *)substream;
0187 else
0188 pstream = (struct snd_pcm_substream *)substream;
0189
0190 str_params->stream_type = SST_STREAM_TYPE_MUSIC;
0191
0192
0193 if (pstream) {
0194 index = sst_get_stream_mapping(pstream->pcm->device,
0195 pstream->number, pstream->stream,
0196 map, map_size);
0197 if (index <= 0)
0198 return -EINVAL;
0199
0200 str_params->stream_id = index;
0201 str_params->device_type = map[index].device_id;
0202 str_params->task = map[index].task_id;
0203
0204 str_params->ops = (u8)pstream->stream;
0205 }
0206
0207 if (cstream) {
0208 index = sst_get_stream_mapping(cstream->device->device,
0209 0, cstream->direction,
0210 map, map_size);
0211 if (index <= 0)
0212 return -EINVAL;
0213 str_params->stream_id = index;
0214 str_params->device_type = map[index].device_id;
0215 str_params->task = map[index].task_id;
0216
0217 str_params->ops = (u8)cstream->direction;
0218 }
0219 return 0;
0220 }
0221
0222 static int sst_platform_alloc_stream(struct snd_pcm_substream *substream,
0223 struct snd_soc_dai *dai)
0224 {
0225 struct sst_runtime_stream *stream =
0226 substream->runtime->private_data;
0227 struct snd_sst_stream_params param = {{{0,},},};
0228 struct snd_sst_params str_params = {0};
0229 struct snd_sst_alloc_params_ext alloc_params = {0};
0230 int ret_val = 0;
0231 struct sst_data *ctx = snd_soc_dai_get_drvdata(dai);
0232
0233
0234 sst_fill_pcm_params(substream, ¶m);
0235 sst_fill_alloc_params(substream, &alloc_params);
0236 str_params.sparams = param;
0237 str_params.aparams = alloc_params;
0238 str_params.codec = SST_CODEC_TYPE_PCM;
0239
0240
0241 ret_val = sst_fill_stream_params(substream, ctx, &str_params, false);
0242 if (ret_val < 0)
0243 return ret_val;
0244
0245 stream->stream_info.str_id = str_params.stream_id;
0246
0247 ret_val = stream->ops->open(sst->dev, &str_params);
0248 if (ret_val <= 0)
0249 return ret_val;
0250
0251
0252 return ret_val;
0253 }
0254
0255 static void sst_period_elapsed(void *arg)
0256 {
0257 struct snd_pcm_substream *substream = arg;
0258 struct sst_runtime_stream *stream;
0259 int status;
0260
0261 if (!substream || !substream->runtime)
0262 return;
0263 stream = substream->runtime->private_data;
0264 if (!stream)
0265 return;
0266 status = sst_get_stream_status(stream);
0267 if (status != SST_PLATFORM_RUNNING)
0268 return;
0269 snd_pcm_period_elapsed(substream);
0270 }
0271
0272 static int sst_platform_init_stream(struct snd_pcm_substream *substream)
0273 {
0274 struct sst_runtime_stream *stream =
0275 substream->runtime->private_data;
0276 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0277 int ret_val;
0278
0279 dev_dbg(rtd->dev, "setting buffer ptr param\n");
0280 sst_set_stream_status(stream, SST_PLATFORM_INIT);
0281 stream->stream_info.period_elapsed = sst_period_elapsed;
0282 stream->stream_info.arg = substream;
0283 stream->stream_info.buffer_ptr = 0;
0284 stream->stream_info.sfreq = substream->runtime->rate;
0285 ret_val = stream->ops->stream_init(sst->dev, &stream->stream_info);
0286 if (ret_val)
0287 dev_err(rtd->dev, "control_set ret error %d\n", ret_val);
0288 return ret_val;
0289
0290 }
0291
0292 static int power_up_sst(struct sst_runtime_stream *stream)
0293 {
0294 return stream->ops->power(sst->dev, true);
0295 }
0296
0297 static void power_down_sst(struct sst_runtime_stream *stream)
0298 {
0299 stream->ops->power(sst->dev, false);
0300 }
0301
0302 static int sst_media_open(struct snd_pcm_substream *substream,
0303 struct snd_soc_dai *dai)
0304 {
0305 int ret_val = 0;
0306 struct snd_pcm_runtime *runtime = substream->runtime;
0307 struct sst_runtime_stream *stream;
0308
0309 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
0310 if (!stream)
0311 return -ENOMEM;
0312 spin_lock_init(&stream->status_lock);
0313
0314
0315 mutex_lock(&sst_lock);
0316 if (!sst ||
0317 !try_module_get(sst->dev->driver->owner)) {
0318 dev_err(dai->dev, "no device available to run\n");
0319 ret_val = -ENODEV;
0320 goto out_ops;
0321 }
0322 stream->ops = sst->ops;
0323 mutex_unlock(&sst_lock);
0324
0325 stream->stream_info.str_id = 0;
0326
0327 stream->stream_info.arg = substream;
0328
0329 runtime->private_data = stream;
0330
0331 ret_val = power_up_sst(stream);
0332 if (ret_val < 0)
0333 goto out_power_up;
0334
0335
0336
0337
0338
0339
0340
0341 snd_pcm_hw_constraint_step(substream->runtime, 0,
0342 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 48);
0343 snd_pcm_hw_constraint_step(substream->runtime, 0,
0344 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 48);
0345
0346
0347 snd_pcm_hw_constraint_step(substream->runtime, 0,
0348 SNDRV_PCM_HW_PARAM_PERIODS, 2);
0349
0350 return snd_pcm_hw_constraint_integer(runtime,
0351 SNDRV_PCM_HW_PARAM_PERIODS);
0352 out_ops:
0353 mutex_unlock(&sst_lock);
0354 out_power_up:
0355 kfree(stream);
0356 return ret_val;
0357 }
0358
0359 static void sst_media_close(struct snd_pcm_substream *substream,
0360 struct snd_soc_dai *dai)
0361 {
0362 struct sst_runtime_stream *stream;
0363 int str_id;
0364
0365 stream = substream->runtime->private_data;
0366 power_down_sst(stream);
0367
0368 str_id = stream->stream_info.str_id;
0369 if (str_id)
0370 stream->ops->close(sst->dev, str_id);
0371 module_put(sst->dev->driver->owner);
0372 kfree(stream);
0373 }
0374
0375 static int sst_media_prepare(struct snd_pcm_substream *substream,
0376 struct snd_soc_dai *dai)
0377 {
0378 struct sst_runtime_stream *stream;
0379 int ret_val, str_id;
0380
0381 stream = substream->runtime->private_data;
0382 str_id = stream->stream_info.str_id;
0383 if (stream->stream_info.str_id) {
0384 ret_val = stream->ops->stream_drop(sst->dev, str_id);
0385 return ret_val;
0386 }
0387
0388 ret_val = sst_platform_alloc_stream(substream, dai);
0389 if (ret_val <= 0)
0390 return ret_val;
0391 snprintf(substream->pcm->id, sizeof(substream->pcm->id),
0392 "%d", stream->stream_info.str_id);
0393
0394 ret_val = sst_platform_init_stream(substream);
0395 if (ret_val)
0396 return ret_val;
0397 substream->runtime->hw.info = SNDRV_PCM_INFO_BLOCK_TRANSFER;
0398 return 0;
0399 }
0400
0401 static int sst_enable_ssp(struct snd_pcm_substream *substream,
0402 struct snd_soc_dai *dai)
0403 {
0404 int ret = 0;
0405
0406 if (!snd_soc_dai_active(dai)) {
0407 ret = sst_handle_vb_timer(dai, true);
0408 sst_fill_ssp_defaults(dai);
0409 }
0410 return ret;
0411 }
0412
0413 static int sst_be_hw_params(struct snd_pcm_substream *substream,
0414 struct snd_pcm_hw_params *params,
0415 struct snd_soc_dai *dai)
0416 {
0417 int ret = 0;
0418
0419 if (snd_soc_dai_active(dai) == 1)
0420 ret = send_ssp_cmd(dai, dai->name, 1);
0421 return ret;
0422 }
0423
0424 static int sst_set_format(struct snd_soc_dai *dai, unsigned int fmt)
0425 {
0426 int ret = 0;
0427
0428 if (!snd_soc_dai_active(dai))
0429 return 0;
0430
0431 ret = sst_fill_ssp_config(dai, fmt);
0432 if (ret < 0)
0433 dev_err(dai->dev, "sst_set_format failed..\n");
0434
0435 return ret;
0436 }
0437
0438 static int sst_platform_set_ssp_slot(struct snd_soc_dai *dai,
0439 unsigned int tx_mask, unsigned int rx_mask,
0440 int slots, int slot_width) {
0441 int ret = 0;
0442
0443 if (!snd_soc_dai_active(dai))
0444 return ret;
0445
0446 ret = sst_fill_ssp_slot(dai, tx_mask, rx_mask, slots, slot_width);
0447 if (ret < 0)
0448 dev_err(dai->dev, "sst_fill_ssp_slot failed..%d\n", ret);
0449
0450 return ret;
0451 }
0452
0453 static void sst_disable_ssp(struct snd_pcm_substream *substream,
0454 struct snd_soc_dai *dai)
0455 {
0456 if (!snd_soc_dai_active(dai)) {
0457 send_ssp_cmd(dai, dai->name, 0);
0458 sst_handle_vb_timer(dai, false);
0459 }
0460 }
0461
0462 static const struct snd_soc_dai_ops sst_media_dai_ops = {
0463 .startup = sst_media_open,
0464 .shutdown = sst_media_close,
0465 .prepare = sst_media_prepare,
0466 .mute_stream = sst_media_digital_mute,
0467 };
0468
0469 static const struct snd_soc_dai_ops sst_compr_dai_ops = {
0470 .mute_stream = sst_media_digital_mute,
0471 };
0472
0473 static const struct snd_soc_dai_ops sst_be_dai_ops = {
0474 .startup = sst_enable_ssp,
0475 .hw_params = sst_be_hw_params,
0476 .set_fmt = sst_set_format,
0477 .set_tdm_slot = sst_platform_set_ssp_slot,
0478 .shutdown = sst_disable_ssp,
0479 };
0480
0481 static struct snd_soc_dai_driver sst_platform_dai[] = {
0482 {
0483 .name = "media-cpu-dai",
0484 .ops = &sst_media_dai_ops,
0485 .playback = {
0486 .stream_name = "Headset Playback",
0487 .channels_min = SST_STEREO,
0488 .channels_max = SST_STEREO,
0489 .rates = SNDRV_PCM_RATE_48000,
0490 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0491 },
0492 .capture = {
0493 .stream_name = "Headset Capture",
0494 .channels_min = 1,
0495 .channels_max = 2,
0496 .rates = SNDRV_PCM_RATE_48000,
0497 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0498 },
0499 },
0500 {
0501 .name = "deepbuffer-cpu-dai",
0502 .ops = &sst_media_dai_ops,
0503 .playback = {
0504 .stream_name = "Deepbuffer Playback",
0505 .channels_min = SST_STEREO,
0506 .channels_max = SST_STEREO,
0507 .rates = SNDRV_PCM_RATE_48000,
0508 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0509 },
0510 },
0511 {
0512 .name = "compress-cpu-dai",
0513 .compress_new = snd_soc_new_compress,
0514 .ops = &sst_compr_dai_ops,
0515 .playback = {
0516 .stream_name = "Compress Playback",
0517 .channels_min = 1,
0518 },
0519 },
0520
0521 {
0522 .name = "ssp0-port",
0523 .ops = &sst_be_dai_ops,
0524 .playback = {
0525 .stream_name = "ssp0 Tx",
0526 .channels_min = SST_STEREO,
0527 .channels_max = SST_STEREO,
0528 .rates = SNDRV_PCM_RATE_48000,
0529 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0530 },
0531 .capture = {
0532 .stream_name = "ssp0 Rx",
0533 .channels_min = SST_STEREO,
0534 .channels_max = SST_STEREO,
0535 .rates = SNDRV_PCM_RATE_48000,
0536 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0537 },
0538 },
0539 {
0540 .name = "ssp1-port",
0541 .ops = &sst_be_dai_ops,
0542 .playback = {
0543 .stream_name = "ssp1 Tx",
0544 .channels_min = SST_STEREO,
0545 .channels_max = SST_STEREO,
0546 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000,
0547 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0548 },
0549 .capture = {
0550 .stream_name = "ssp1 Rx",
0551 .channels_min = SST_STEREO,
0552 .channels_max = SST_STEREO,
0553 .rates = SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_48000,
0554 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0555 },
0556 },
0557 {
0558 .name = "ssp2-port",
0559 .ops = &sst_be_dai_ops,
0560 .playback = {
0561 .stream_name = "ssp2 Tx",
0562 .channels_min = SST_STEREO,
0563 .channels_max = SST_STEREO,
0564 .rates = SNDRV_PCM_RATE_48000,
0565 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0566 },
0567 .capture = {
0568 .stream_name = "ssp2 Rx",
0569 .channels_min = SST_STEREO,
0570 .channels_max = SST_STEREO,
0571 .rates = SNDRV_PCM_RATE_48000,
0572 .formats = SNDRV_PCM_FMTBIT_S16_LE,
0573 },
0574 },
0575 };
0576
0577 static int sst_soc_open(struct snd_soc_component *component,
0578 struct snd_pcm_substream *substream)
0579 {
0580 struct snd_pcm_runtime *runtime;
0581
0582 if (substream->pcm->internal)
0583 return 0;
0584
0585 runtime = substream->runtime;
0586 runtime->hw = sst_platform_pcm_hw;
0587 return 0;
0588 }
0589
0590 static int sst_soc_trigger(struct snd_soc_component *component,
0591 struct snd_pcm_substream *substream, int cmd)
0592 {
0593 int ret_val = 0, str_id;
0594 struct sst_runtime_stream *stream;
0595 int status;
0596 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0597
0598 dev_dbg(rtd->dev, "%s called\n", __func__);
0599 if (substream->pcm->internal)
0600 return 0;
0601 stream = substream->runtime->private_data;
0602 str_id = stream->stream_info.str_id;
0603 switch (cmd) {
0604 case SNDRV_PCM_TRIGGER_START:
0605 dev_dbg(rtd->dev, "sst: Trigger Start\n");
0606 status = SST_PLATFORM_RUNNING;
0607 stream->stream_info.arg = substream;
0608 ret_val = stream->ops->stream_start(sst->dev, str_id);
0609 break;
0610 case SNDRV_PCM_TRIGGER_STOP:
0611 dev_dbg(rtd->dev, "sst: in stop\n");
0612 status = SST_PLATFORM_DROPPED;
0613 ret_val = stream->ops->stream_drop(sst->dev, str_id);
0614 break;
0615 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0616 case SNDRV_PCM_TRIGGER_SUSPEND:
0617 dev_dbg(rtd->dev, "sst: in pause\n");
0618 status = SST_PLATFORM_PAUSED;
0619 ret_val = stream->ops->stream_pause(sst->dev, str_id);
0620 break;
0621 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0622 case SNDRV_PCM_TRIGGER_RESUME:
0623 dev_dbg(rtd->dev, "sst: in pause release\n");
0624 status = SST_PLATFORM_RUNNING;
0625 ret_val = stream->ops->stream_pause_release(sst->dev, str_id);
0626 break;
0627 default:
0628 return -EINVAL;
0629 }
0630
0631 if (!ret_val)
0632 sst_set_stream_status(stream, status);
0633
0634 return ret_val;
0635 }
0636
0637
0638 static snd_pcm_uframes_t sst_soc_pointer(struct snd_soc_component *component,
0639 struct snd_pcm_substream *substream)
0640 {
0641 struct sst_runtime_stream *stream;
0642 int ret_val, status;
0643 struct pcm_stream_info *str_info;
0644 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0645
0646 stream = substream->runtime->private_data;
0647 status = sst_get_stream_status(stream);
0648 if (status == SST_PLATFORM_INIT)
0649 return 0;
0650 str_info = &stream->stream_info;
0651 ret_val = stream->ops->stream_read_tstamp(sst->dev, str_info);
0652 if (ret_val) {
0653 dev_err(rtd->dev, "sst: error code = %d\n", ret_val);
0654 return ret_val;
0655 }
0656 return str_info->buffer_ptr;
0657 }
0658
0659 static snd_pcm_sframes_t sst_soc_delay(struct snd_soc_component *component,
0660 struct snd_pcm_substream *substream)
0661 {
0662 struct sst_runtime_stream *stream = substream->runtime->private_data;
0663 struct pcm_stream_info *str_info = &stream->stream_info;
0664
0665 if (sst_get_stream_status(stream) == SST_PLATFORM_INIT)
0666 return 0;
0667
0668 return str_info->pcm_delay;
0669 }
0670
0671 static int sst_soc_pcm_new(struct snd_soc_component *component,
0672 struct snd_soc_pcm_runtime *rtd)
0673 {
0674 struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
0675 struct snd_pcm *pcm = rtd->pcm;
0676
0677 if (dai->driver->playback.channels_min ||
0678 dai->driver->capture.channels_min) {
0679 snd_pcm_set_managed_buffer_all(pcm,
0680 SNDRV_DMA_TYPE_CONTINUOUS,
0681 snd_dma_continuous_data(GFP_DMA),
0682 SST_MIN_BUFFER, SST_MAX_BUFFER);
0683 }
0684 return 0;
0685 }
0686
0687 static int sst_soc_probe(struct snd_soc_component *component)
0688 {
0689 struct sst_data *drv = dev_get_drvdata(component->dev);
0690
0691 drv->soc_card = component->card;
0692 return sst_dsp_init_v2_dpcm(component);
0693 }
0694
0695 static void sst_soc_remove(struct snd_soc_component *component)
0696 {
0697 struct sst_data *drv = dev_get_drvdata(component->dev);
0698
0699 drv->soc_card = NULL;
0700 }
0701
0702 static const struct snd_soc_component_driver sst_soc_platform_drv = {
0703 .name = DRV_NAME,
0704 .probe = sst_soc_probe,
0705 .remove = sst_soc_remove,
0706 .open = sst_soc_open,
0707 .trigger = sst_soc_trigger,
0708 .pointer = sst_soc_pointer,
0709 .delay = sst_soc_delay,
0710 .compress_ops = &sst_platform_compress_ops,
0711 .pcm_construct = sst_soc_pcm_new,
0712 };
0713
0714 static int sst_platform_probe(struct platform_device *pdev)
0715 {
0716 struct sst_data *drv;
0717 int ret;
0718 struct sst_platform_data *pdata;
0719
0720 drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
0721 if (drv == NULL) {
0722 return -ENOMEM;
0723 }
0724
0725 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
0726 if (pdata == NULL) {
0727 return -ENOMEM;
0728 }
0729
0730 pdata->pdev_strm_map = dpcm_strm_map;
0731 pdata->strm_map_size = ARRAY_SIZE(dpcm_strm_map);
0732 drv->pdata = pdata;
0733 drv->pdev = pdev;
0734 mutex_init(&drv->lock);
0735 dev_set_drvdata(&pdev->dev, drv);
0736
0737 ret = devm_snd_soc_register_component(&pdev->dev, &sst_soc_platform_drv,
0738 sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
0739 if (ret)
0740 dev_err(&pdev->dev, "registering cpu dais failed\n");
0741
0742 return ret;
0743 }
0744
0745 static int sst_platform_remove(struct platform_device *pdev)
0746 {
0747 dev_dbg(&pdev->dev, "sst_platform_remove success\n");
0748 return 0;
0749 }
0750
0751 #ifdef CONFIG_PM_SLEEP
0752
0753 static int sst_soc_prepare(struct device *dev)
0754 {
0755 struct sst_data *drv = dev_get_drvdata(dev);
0756 struct snd_soc_pcm_runtime *rtd;
0757
0758 if (!drv->soc_card)
0759 return 0;
0760
0761
0762 snd_soc_suspend(drv->soc_card->dev);
0763 snd_soc_poweroff(drv->soc_card->dev);
0764
0765
0766 for_each_card_rtds(drv->soc_card, rtd) {
0767 struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
0768
0769 if (snd_soc_dai_active(dai)) {
0770 send_ssp_cmd(dai, dai->name, 0);
0771 sst_handle_vb_timer(dai, false);
0772 }
0773 }
0774
0775 return 0;
0776 }
0777
0778 static void sst_soc_complete(struct device *dev)
0779 {
0780 struct sst_data *drv = dev_get_drvdata(dev);
0781 struct snd_soc_pcm_runtime *rtd;
0782
0783 if (!drv->soc_card)
0784 return;
0785
0786
0787 for_each_card_rtds(drv->soc_card, rtd) {
0788 struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
0789
0790 if (snd_soc_dai_active(dai)) {
0791 sst_handle_vb_timer(dai, true);
0792 send_ssp_cmd(dai, dai->name, 1);
0793 }
0794 }
0795 snd_soc_resume(drv->soc_card->dev);
0796 }
0797
0798 #else
0799
0800 #define sst_soc_prepare NULL
0801 #define sst_soc_complete NULL
0802
0803 #endif
0804
0805
0806 static const struct dev_pm_ops sst_platform_pm = {
0807 .prepare = sst_soc_prepare,
0808 .complete = sst_soc_complete,
0809 };
0810
0811 static struct platform_driver sst_platform_driver = {
0812 .driver = {
0813 .name = "sst-mfld-platform",
0814 .pm = &sst_platform_pm,
0815 },
0816 .probe = sst_platform_probe,
0817 .remove = sst_platform_remove,
0818 };
0819
0820 module_platform_driver(sst_platform_driver);
0821
0822 MODULE_DESCRIPTION("ASoC Intel(R) MID Platform driver");
0823 MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
0824 MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
0825 MODULE_LICENSE("GPL v2");
0826 MODULE_ALIAS("platform:sst-atom-hifi2-platform");
0827 MODULE_ALIAS("platform:sst-mfld-platform");