At Fri, 3 Jul 2009 12:33:58 +0530, Vinod Koul wrote:
This patch adds the SST driver interface modules. Interface module is the one which talks to other layers of SST drivers. intel_sst_interface.c - This file implements the MAD driver registration and de registration functions. SST driver is also a character driver that allows players/middleware to communicate with SST driver. All char driver routines are implemented here. The ioctls used by middleware to open/close, control and configure stream and transfer the data are implemented here
Signed-off-by: Vinod Koul vinod.koul@intel.com Signed-off-by: Harsha Priya priya.harsha@intel.com Signed-off-by: R Dharageswari dharageswari.r@intel.com
new file: sound/pci/sst/intel_sst_interface.c
sound/pci/sst/intel_sst_interface.c | 1359 +++++++++++++++++++++++++++++++++++ 1 files changed, 1359 insertions(+), 0 deletions(-) create mode 100644 sound/pci/sst/intel_sst_interface.c
diff --git a/sound/pci/sst/intel_sst_interface.c b/sound/pci/sst/intel_sst_interface.c new file mode 100644 index 0000000..f8cefa5 --- /dev/null +++ b/sound/pci/sst/intel_sst_interface.c @@ -0,0 +1,1359 @@ +/*
- intel_sst_interface.c - Intel SST Driver for audio engine
- Copyright (C) 2008-09 Intel Corporation
- Authors: Vinod Koul vinod.koul@intel.com
Harsha Priya <priya.harsha@intel.com>
R Dharageswari <dharageswari.r@intel.com>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- This driver exposes the audio engine functionalities to the ALSA
- and middleware.
- Upper layer interfaces (MAD driver, MMF) to SST driver
- */
+#include <linux/cdev.h> +#include <linux/pci.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/syscalls.h> +#include <linux/fs.h> +#include <linux/file.h> +#include <linux/fcntl.h> +#include <linux/uaccess.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/slab.h> +#include <linux/mm.h> +#include <linux/workqueue.h> +#include <linux/pci.h> +#include <linux/firmware.h> +#include <asm/div64.h> +#include <linux/ioctl.h> +#include <sound/intel_sst.h> +#include <sound/intel_sst_ioctl.h> +#include "intel_sst_fw_ipc.h" +#include "intel_sst_common.h" +#include "intel_sst_pvt.h" +#ifdef CONFIG_SST_OSPM_SUPPORT +#include <linux/intel_mid.h> +#endif
+int sst_download_fw(void) +{
- int retval = 0;
- const struct firmware *fw_sst;
- sst_dbg("SST Downloading FW now...\n");
- retval = request_firmware(&fw_sst,
SST_FW_STD_FILENAME,
&sst_ops->pci->dev);
- if (0 != retval) {
sst_err("fw load failed %d \n", retval);
return retval;
- }
- sst_ops->alloc_block[0].sst_id = 0xFF;
- sst_load_fw(fw_sst, NULL);
- retval = sst_wait_timeout(sst_ops, &sst_ops->alloc_block[0]);
- release_firmware(fw_sst);
- sst_ops->alloc_block[0].sst_id = BLOCK_UNINIT;
- return retval;
+}
+/** +* intel_sst_open - opens a handle to driver +* @i_node: inode structure +* @file_ptr:pointer to file +* +* This function is called by OS when a user space component +* tries to get a driver handle. Only one handle at a time +* will be allowed +*/ +int intel_sst_open(struct inode *i_node, struct file *file_ptr) +{
- dev_t device = i_node->i_rdev;
- unsigned int retval = 0;
- struct ioctl_pvt_data *data = NULL;
- if (sst_ops->pmic_state != PMIC_SND_INIT_DONE) {
sst_err("Sound card not availble \n");
return -EIO;
- }
- if (SST_UN_INIT == sst_ops->sst_state) {
/*FW is not downloaded*/
retval = sst_download_fw();
if (retval != 0) {
sst_err("FW download failed...abort\n");
return -ENODEV;
}
- }
- if (device == MKDEV(INTEL_SST_MAJOR, 0)) {
/*app open*/
if (sst_ops->active_cnt < MAX_ENC_STREAM) {
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (NULL == data)
return -ENOMEM;
A usual kernel style for NULL check is if (!data).
sst_ops->active_cnt++;
sst_ops->stream_cnt++;
data->pvt_id = sst_assign_pvt_id(sst_ops);
data->str_id = 0;
file_ptr->private_data = (void *)data;
sst_dbg("sst id allocated = %d!\n", data->pvt_id);
} else
retval = -EACCES;
- } else if (device == MKDEV(INTEL_SST_MAJOR, 1)) {
/*audio manager open*/
if (sst_ops->am_cnt < MAX_AM_HANDLES) {
sst_ops->am_cnt++;
sst_dbg("AM handle opened...\n");
} else
retval = -EACCES;
- } else
retval = -EINVAL;
- return retval;
+}
+/** +* intel_sst_release - releases a handle to driver +* @i_node: inode structure +* @file_ptr: pointer to file +* +* This function is called by OS when a user space component +* tries to release a driver handle. +*/ +int intel_sst_release(struct inode *i_node, struct file *file_ptr) +{
- dev_t device = i_node->i_rdev;
- struct ioctl_pvt_data *data =
(struct ioctl_pvt_data *)file_ptr->private_data;
- sst_dbg("Release called \n");
- if (device == MKDEV(INTEL_SST_MAJOR, 0)) {
/*app close*/
sst_dbg("Closing app handle \n");
sst_ops->active_cnt--;
sst_ops->stream_cnt--;
if (0 != sst_free_stream(data->str_id)) {
if (sst_validate_strid(data->str_id) == 0)
sst_clean_stream(
&sst_ops->streams[data->str_id]);
}
kfree(data);
- } else if (device == MKDEV(INTEL_SST_MAJOR, 1))
/*audio manager close*/
sst_dbg("AM handle closed \n");
sst_ops->am_cnt--;
Missing braces. Looks buggy here.
- return 0;
+}
+int intel_sst_mmap(struct file *file_ptr, struct vm_area_struct *vma) +{
- int retval = 0, length = 0;
- struct ioctl_pvt_data *data =
(struct ioctl_pvt_data *)file_ptr->private_data;
- int str_id = data->str_id;
- void *mem_area = NULL;
- retval = sst_validate_strid(str_id);
- if (retval != 0)
return -EINVAL;
- length = vma->vm_end - vma->vm_start;
- sst_dbg("called for stream %d length 0x%x\n", str_id, length);
- if (length > sst_ops->mmap_len)
return -ENOMEM;
- if (sst_ops->mmap_mem == NULL)
return -EIO;
- /* round it up to the page bondary */
- mem_area = (void *)((((unsigned long)sst_ops->mmap_mem) + PAGE_SIZE - 1)
& PAGE_MASK);
There is a standard macro for page alignment.
- mutex_unlock(&stream->lock);
- /*Block the call for reply*/
- if (0 == list_empty(&stream->bufs)) {
This is ugly. Use if (!list_empty(&stream->bufs))
+void set_port_params(struct snd_sst_params *str_param,
enum snd_sst_stream_ops ops)
Is it a global function??
Better to check again all over whether the function is really global.
Takashi