[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