2 * intel_sst_interface.c - Intel SST Driver for audio engine
4 * Copyright (C) 2008-10 Intel Corp
5 * Authors: Vinod Koul <vinod.koul@intel.com>
6 * Harsha Priya <priya.harsha@intel.com>
7 * Dharageswari R <dharageswari.r@intel.com)
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 * This driver exposes the audio engine functionalities to the ALSA
26 * Upper layer interfaces (MAD driver, MMF) to SST driver
29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #include <linux/delay.h>
32 #include <linux/pci.h>
34 #include <linux/firmware.h>
35 #include <linux/pm_runtime.h>
36 #include "intel_sst.h"
37 #include "intel_sst_ioctl.h"
38 #include "intel_sst_fw_ipc.h"
39 #include "intel_sst_common.h"
43 * sst_download_fw - download the audio firmware to DSP
45 * This function is called when the FW needs to be downloaded to SST DSP engine
47 int sst_download_fw(void)
50 const struct firmware
*fw_sst
;
53 if (sst_drv_ctx
->sst_state
!= SST_UN_INIT
)
56 /* Reload firmware is not needed for MRST */
57 if ( (sst_drv_ctx
->pci_id
== SST_MRST_PCI_ID
) && sst_drv_ctx
->fw_downloaded
) {
58 pr_debug("FW already downloaded, skip for MRST platform\n");
59 sst_drv_ctx
->sst_state
= SST_FW_RUNNING
;
63 snprintf(name
, sizeof(name
), "%s%04x%s", "fw_sst_",
64 sst_drv_ctx
->pci_id
, ".bin");
66 pr_debug("Downloading %s FW now...\n", name
);
67 retval
= request_firmware(&fw_sst
, name
, &sst_drv_ctx
->pci
->dev
);
69 pr_err("request fw failed %d\n", retval
);
72 sst_drv_ctx
->alloc_block
[0].sst_id
= FW_DWNL_ID
;
73 sst_drv_ctx
->alloc_block
[0].ops_block
.condition
= false;
74 retval
= sst_load_fw(fw_sst
, NULL
);
78 retval
= sst_wait_timeout(sst_drv_ctx
, &sst_drv_ctx
->alloc_block
[0]);
80 pr_err("fw download failed %d\n" , retval
);
82 sst_drv_ctx
->fw_downloaded
= 1;
85 release_firmware(fw_sst
);
86 sst_drv_ctx
->alloc_block
[0].sst_id
= BLOCK_UNINIT
;
92 * sst_stalled - this function checks if the lpe is in stalled state
100 if (!sst_drv_ctx
->lpe_stalled
)
102 /*wait for time and re-check*/
107 pr_debug("in Stalled State\n");
111 void free_stream_context(unsigned int str_id
)
113 struct stream_info
*stream
;
115 if (!sst_validate_strid(str_id
)) {
116 /* str_id is valid, so stream is alloacted */
117 stream
= &sst_drv_ctx
->streams
[str_id
];
118 if (sst_free_stream(str_id
))
119 sst_clean_stream(&sst_drv_ctx
->streams
[str_id
]);
120 if (stream
->ops
== STREAM_OPS_PLAYBACK
||
121 stream
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
122 sst_drv_ctx
->pb_streams
--;
123 if (sst_drv_ctx
->pci_id
== SST_MFLD_PCI_ID
)
124 sst_drv_ctx
->scard_ops
->power_down_pmic_pb(
127 if (sst_drv_ctx
->pb_streams
== 0)
128 sst_drv_ctx
->scard_ops
->
129 power_down_pmic_pb(stream
->device
);
131 } else if (stream
->ops
== STREAM_OPS_CAPTURE
) {
132 sst_drv_ctx
->cp_streams
--;
133 if (sst_drv_ctx
->cp_streams
== 0)
134 sst_drv_ctx
->scard_ops
->power_down_pmic_cp(
137 if (sst_drv_ctx
->pb_streams
== 0
138 && sst_drv_ctx
->cp_streams
== 0)
139 sst_drv_ctx
->scard_ops
->power_down_pmic();
144 * sst_get_stream_allocated - this function gets a stream allocated with
147 * @str_param : stream params
148 * @lib_dnld : pointer to pointer of lib downlaod struct
150 * This creates new stream id for a stream, in case lib is to be downloaded to
151 * DSP, it downloads that
153 int sst_get_stream_allocated(struct snd_sst_params
*str_param
,
154 struct snd_sst_lib_download
**lib_dnld
)
157 struct stream_info
*str_info
;
159 retval
= sst_alloc_stream((char *) &str_param
->sparams
, str_param
->ops
,
160 str_param
->codec
, str_param
->device_type
);
162 pr_err("sst_alloc_stream failed %d\n", retval
);
165 pr_debug("Stream allocated %d\n", retval
);
167 str_info
= &sst_drv_ctx
->streams
[str_id
];
168 /* Block the call for reply */
169 retval
= sst_wait_interruptible_timeout(sst_drv_ctx
,
170 &str_info
->ctrl_blk
, SST_BLOCK_TIMEOUT
);
171 if ((retval
!= 0) || (str_info
->ctrl_blk
.ret_code
!= 0)) {
172 pr_debug("FW alloc failed retval %d, ret_code %d\n",
173 retval
, str_info
->ctrl_blk
.ret_code
);
174 str_id
= -str_info
->ctrl_blk
.ret_code
; /*return error*/
175 *lib_dnld
= str_info
->ctrl_blk
.data
;
176 sst_clean_stream(str_info
);
178 pr_debug("FW Stream allocated success\n");
179 return str_id
; /*will ret either error (in above if) or correct str id*/
183 * sst_get_sfreq - this function returns the frequency of the stream
185 * @str_param : stream params
187 static int sst_get_sfreq(struct snd_sst_params
*str_param
)
189 switch (str_param
->codec
) {
190 case SST_CODEC_TYPE_PCM
:
191 return 48000; /*str_param->sparams.uc.pcm_params.sfreq;*/
192 case SST_CODEC_TYPE_MP3
:
193 return str_param
->sparams
.uc
.mp3_params
.sfreq
;
194 case SST_CODEC_TYPE_AAC
:
195 return str_param
->sparams
.uc
.aac_params
.sfreq
;
196 case SST_CODEC_TYPE_WMA9
:
197 return str_param
->sparams
.uc
.wma_params
.sfreq
;
204 * sst_get_stream - this function prepares for stream allocation
206 * @str_param : stream param
208 int sst_get_stream(struct snd_sst_params
*str_param
)
211 struct stream_info
*str_info
;
212 struct snd_sst_lib_download
*lib_dnld
;
214 /* stream is not allocated, we are allocating */
215 retval
= sst_get_stream_allocated(str_param
, &lib_dnld
);
216 if (retval
== -(SST_LIB_ERR_LIB_DNLD_REQUIRED
)) {
217 /* codec download is required */
218 struct snd_sst_alloc_response
*response
;
220 pr_debug("Codec is required.... trying that\n");
221 if (lib_dnld
== NULL
) {
222 pr_err("lib download null!!! abort\n");
225 i
= sst_get_block_stream(sst_drv_ctx
);
226 response
= sst_drv_ctx
->alloc_block
[i
].ops_block
.data
;
227 pr_debug("alloc block allocated = %d\n", i
);
232 retval
= sst_load_library(lib_dnld
, str_param
->ops
);
235 sst_drv_ctx
->alloc_block
[i
].sst_id
= BLOCK_UNINIT
;
237 pr_debug("codec was downloaded successfully\n");
239 retval
= sst_get_stream_allocated(str_param
, &lib_dnld
);
243 pr_debug("Alloc done stream id %d\n", retval
);
245 pr_debug("codec download failed\n");
249 } else if (retval
<= 0)
252 set_port_params(str_param, str_param->ops);*/
254 /* store sampling freq */
255 str_info
= &sst_drv_ctx
->streams
[retval
];
256 str_info
->sfreq
= sst_get_sfreq(str_param
);
258 /* power on the analog, if reqd */
259 if (str_param
->ops
== STREAM_OPS_PLAYBACK
||
260 str_param
->ops
== STREAM_OPS_PLAYBACK_DRM
) {
261 if (sst_drv_ctx
->pci_id
== SST_MRST_PCI_ID
)
262 sst_drv_ctx
->scard_ops
->power_up_pmic_pb(
263 sst_drv_ctx
->pmic_port_instance
);
265 sst_drv_ctx
->scard_ops
->power_up_pmic_pb(
267 /*Only if the playback is MP3 - Send a message*/
268 sst_drv_ctx
->pb_streams
++;
269 } else if (str_param
->ops
== STREAM_OPS_CAPTURE
) {
271 sst_drv_ctx
->scard_ops
->power_up_pmic_cp(
272 sst_drv_ctx
->pmic_port_instance
);
273 /*Send a messageif not sent already*/
274 sst_drv_ctx
->cp_streams
++;
281 void sst_process_mad_ops(struct work_struct
*work
)
284 struct mad_ops_wq
*mad_ops
=
285 container_of(work
, struct mad_ops_wq
, wq
);
288 switch (mad_ops
->control_op
) {
290 retval
= sst_pause_stream(mad_ops
->stream_id
);
293 retval
= sst_resume_stream(mad_ops
->stream_id
);
296 retval
= sst_drop_stream(mad_ops
->stream_id
);
299 pr_debug("SST Debug: start stream\n");
300 retval
= sst_start_stream(mad_ops
->stream_id
);
302 case SST_SND_STREAM_PROCESS
:
303 pr_debug("play/capt frames...\n");
306 pr_err(" wrong control_ops reported\n");
311 void send_intial_rx_timeslot(void)
313 if (sst_drv_ctx
->pci_id
== SST_MRST_PCI_ID
&&
314 sst_drv_ctx
->rx_time_slot_status
!= RX_TIMESLOT_UNINIT
315 && sst_drv_ctx
->pmic_vendor
!= SND_NC
)
316 sst_enable_rx_timeslot(sst_drv_ctx
->rx_time_slot_status
);
320 * sst_open_pcm_stream - Open PCM interface
322 * @str_param: parameters of pcm stream
324 * This function is called by MID sound card driver to open
325 * a new pcm interface
327 int sst_open_pcm_stream(struct snd_sst_params
*str_param
)
329 struct stream_info
*str_info
;
332 pm_runtime_get_sync(&sst_drv_ctx
->pci
->dev
);
334 if (sst_drv_ctx
->sst_state
== SST_SUSPENDED
) {
335 /* LPE is suspended, resume it before proceeding*/
336 pr_debug("Resuming from Suspended state\n");
337 retval
= intel_sst_resume(sst_drv_ctx
->pci
);
339 pr_err("Resume Failed = %#x, abort\n", retval
);
340 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
344 if (sst_drv_ctx
->sst_state
== SST_UN_INIT
) {
345 /* FW is not downloaded */
346 pr_debug("DSP Downloading FW now...\n");
347 retval
= sst_download_fw();
349 pr_err("FW download fail %x, abort\n", retval
);
350 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
353 send_intial_rx_timeslot();
357 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
361 retval
= sst_get_stream(str_param
);
363 sst_drv_ctx
->stream_cnt
++;
364 str_info
= &sst_drv_ctx
->streams
[retval
];
365 str_info
->src
= MAD_DRV
;
367 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
373 * sst_close_pcm_stream - Close PCM interface
375 * @str_id: stream id to be closed
377 * This function is called by MID sound card driver to close
378 * an existing pcm interface
380 int sst_close_pcm_stream(unsigned int str_id
)
382 struct stream_info
*stream
;
384 pr_debug("sst: stream free called\n");
385 if (sst_validate_strid(str_id
))
387 stream
= &sst_drv_ctx
->streams
[str_id
];
388 free_stream_context(str_id
);
389 stream
->pcm_substream
= NULL
;
390 stream
->status
= STREAM_UN_INIT
;
391 stream
->period_elapsed
= NULL
;
392 sst_drv_ctx
->stream_cnt
--;
393 pr_debug("sst: will call runtime put now\n");
394 pm_runtime_put(&sst_drv_ctx
->pci
->dev
);
399 * sst_device_control - Set Control params
401 * @cmd: control cmd to be set
402 * @arg: command argument
404 * This function is called by MID sound card driver to set
405 * SST/Sound card controls for an opened stream.
406 * This is registered with MID driver
408 int sst_device_control(int cmd
, void *arg
)
410 int retval
= 0, str_id
= 0;
417 sst_drv_ctx
->mad_ops
.control_op
= cmd
;
418 sst_drv_ctx
->mad_ops
.stream_id
= *(int *)arg
;
419 queue_work(sst_drv_ctx
->mad_wq
, &sst_drv_ctx
->mad_ops
.wq
);
422 case SST_SND_STREAM_INIT
: {
423 struct pcm_stream_info
*str_info
;
424 struct stream_info
*stream
;
426 pr_debug("stream init called\n");
427 str_info
= (struct pcm_stream_info
*)arg
;
428 str_id
= str_info
->str_id
;
429 retval
= sst_validate_strid(str_id
);
433 stream
= &sst_drv_ctx
->streams
[str_id
];
434 pr_debug("setting the period ptrs\n");
435 stream
->pcm_substream
= str_info
->mad_substream
;
436 stream
->period_elapsed
= str_info
->period_elapsed
;
437 stream
->sfreq
= str_info
->sfreq
;
438 stream
->prev
= stream
->status
;
439 stream
->status
= STREAM_INIT
;
443 case SST_SND_BUFFER_POINTER
: {
444 struct pcm_stream_info
*stream_info
;
445 struct snd_sst_tstamp fw_tstamp
= {0,};
446 struct stream_info
*stream
;
449 stream_info
= (struct pcm_stream_info
*)arg
;
450 str_id
= stream_info
->str_id
;
451 retval
= sst_validate_strid(str_id
);
454 stream
= &sst_drv_ctx
->streams
[str_id
];
456 if (!stream
->pcm_substream
)
458 memcpy_fromio(&fw_tstamp
,
459 ((void *)(sst_drv_ctx
->mailbox
+ SST_TIME_STAMP
)
460 +(str_id
* sizeof(fw_tstamp
))),
463 pr_debug("Pointer Query on strid = %d ops %d\n",
464 str_id
, stream
->ops
);
466 if (stream
->ops
== STREAM_OPS_PLAYBACK
)
467 stream_info
->buffer_ptr
= fw_tstamp
.samples_rendered
;
469 stream_info
->buffer_ptr
= fw_tstamp
.samples_processed
;
470 pr_debug("Samples rendered = %llu, buffer ptr %llu\n",
471 fw_tstamp
.samples_rendered
, stream_info
->buffer_ptr
);
474 case SST_ENABLE_RX_TIME_SLOT
: {
475 int status
= *(int *)arg
;
476 sst_drv_ctx
->rx_time_slot_status
= status
;
477 sst_enable_rx_timeslot(status
);
482 pr_warn("illegal req\n");
490 struct intel_sst_pcm_control pcm_ops
= {
491 .open
= sst_open_pcm_stream
,
492 .device_control
= sst_device_control
,
493 .close
= sst_close_pcm_stream
,
496 struct intel_sst_card_ops sst_pmic_ops
= {
497 .pcm_control
= &pcm_ops
,
501 * register_sst_card - function for sound card to register
503 * @card: pointer to structure of operations
505 * This function is called card driver loads and is ready for registration
507 int register_sst_card(struct intel_sst_card_ops
*card
)
510 pr_err("No SST driver register card reject\n");
514 if (!card
|| !card
->module_name
) {
515 pr_err("Null Pointer Passed\n");
518 if (sst_drv_ctx
->pmic_state
== SND_MAD_UN_INIT
) {
519 /* register this driver */
520 if ((strncmp(SST_CARD_NAMES
, card
->module_name
,
521 strlen(SST_CARD_NAMES
))) == 0) {
522 sst_drv_ctx
->pmic_vendor
= card
->vendor_id
;
523 sst_drv_ctx
->scard_ops
= card
->scard_ops
;
524 sst_pmic_ops
.module_name
= card
->module_name
;
525 sst_drv_ctx
->pmic_state
= SND_MAD_INIT_DONE
;
526 sst_drv_ctx
->rx_time_slot_status
= 0; /*default AMIC*/
527 card
->pcm_control
= sst_pmic_ops
.pcm_control
;
530 pr_err("strcmp fail %s\n", card
->module_name
);
535 /* already registered a driver */
536 pr_err("Repeat for registration..denied\n");
539 /* The ASoC code doesn't set scard_ops */
540 if (sst_drv_ctx
->scard_ops
)
541 sst_drv_ctx
->scard_ops
->card_status
= SND_CARD_UN_INIT
;
544 EXPORT_SYMBOL_GPL(register_sst_card
);
547 * unregister_sst_card- function for sound card to un-register
549 * @card: pointer to structure of operations
551 * This function is called when card driver unloads
553 void unregister_sst_card(struct intel_sst_card_ops
*card
)
555 if (sst_pmic_ops
.pcm_control
== card
->pcm_control
) {
557 sst_pmic_ops
.module_name
= "";
558 sst_drv_ctx
->pmic_state
= SND_MAD_UN_INIT
;
559 pr_debug("Unregistered %s\n", card
->module_name
);
563 EXPORT_SYMBOL_GPL(unregister_sst_card
);