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@xxxxxxxxx> > Signed-off-by: Harsha Priya <priya.harsha@xxxxxxxxx> > Signed-off-by: R Dharageswari <dharageswari.r@xxxxxxxxx> > > 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@xxxxxxxxx> > + * Harsha Priya <priya.harsha@xxxxxxxxx> > + * R Dharageswari <dharageswari.r@xxxxxxxxx> > + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + * > + * 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 _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel