[alsa-devel] [PATCH] [RFC 5/13] Intel SST driver interface module
Takashi Iwai
tiwai at suse.de
Fri Jul 3 13:14:00 CEST 2009
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 at intel.com>
> Signed-off-by: Harsha Priya <priya.harsha at intel.com>
> Signed-off-by: R Dharageswari <dharageswari.r at 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 at intel.com>
> + * Harsha Priya <priya.harsha at intel.com>
> + * R Dharageswari <dharageswari.r at 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
More information about the Alsa-devel
mailing list