summaryrefslogtreecommitdiff
path: root/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-4-8.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-4-8.patch')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-4-8.patch1285
1 files changed, 0 insertions, 1285 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-4-8.patch b/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-4-8.patch
deleted file mode 100644
index da2912b4e..000000000
--- a/meta-moblin/packages/linux/linux-moblin-2.6.33.2/linux-2.6.34-moorestown-audio-driver-6.0-4-8.patch
+++ /dev/null
@@ -1,1285 +0,0 @@
-From 395150e235d193ad9c9e5071d4752e8f436db99c Mon Sep 17 00:00:00 2001
-From: R, Dharageswari <dharageswari.r@intel.com>
-Date: Thu, 29 Apr 2010 20:25:00 +0530
-Subject: [PATCH] ADR-Post-Beta-0.05.002.03-4/8-Adding Moorestown Audio Drivers: SST IPC modules
-
-This adds the IPC module which uses Inter process mechanism to communicate
-between driver & SST engine. The SST engine is a DSP processor.
-To communicate between IA processor and DSP, IPC doorbell registers are used.
-A write to these registers triggers an interrupt to other side.
-The format of messages and "mailbox" for message payload is defined
-in intel_sst_fw_ipc.h
-
-Signed-off-by: Vinod Koul <vinod.koul@intel.com>
-
- new file: sound/pci/sst/intel_sst_fw_ipc.h
- new file: sound/pci/sst/intel_sst_ipc.c
-Patch-mainline: 2.6.35?
----
- sound/pci/sst/intel_sst_fw_ipc.h | 403 ++++++++++++++++++
- sound/pci/sst/intel_sst_ipc.c | 843 ++++++++++++++++++++++++++++++++++++++
- 2 files changed, 1246 insertions(+), 0 deletions(-)
- create mode 100644 sound/pci/sst/intel_sst_fw_ipc.h
- create mode 100644 sound/pci/sst/intel_sst_ipc.c
-
-diff --git a/sound/pci/sst/intel_sst_fw_ipc.h b/sound/pci/sst/intel_sst_fw_ipc.h
-new file mode 100644
-index 0000000..f2fad9c
---- /dev/null
-+++ b/sound/pci/sst/intel_sst_fw_ipc.h
-@@ -0,0 +1,403 @@
-+#ifndef __INTEL_SST_FW_IPC_H__
-+#define __INTEL_SST_FW_IPC_H__
-+/*
-+* intel_sst_fw_ipc.h - Intel SST Driver for audio engine
-+*
-+* Copyright (C) 2008-10 Intel Corporation
-+* Author: Vinod Koul <vinod.koul@intel.com>
-+* Harsha Priya <priya.harsha@intel.com>
-+* Dharageswari R <dharageswari.r@intel.com>
-+* KP Jeeja <jeeja.kp@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.
-+* This file has definitions shared between the firmware and driver
-+*/
-+
-+#define MAX_NUM_STREAMS 4
-+#define MAX_DBG_RW_BYTES 80
-+#define MAX_NUM_SCATTER_BUFFERS 8
-+#define MAX_LOOP_BACK_DWORDS 8
-+/* IPC base address and mailbox, timestamp offsets */
-+#define SST_MAILBOX_SIZE 0x0400
-+#define SST_MAILBOX_SEND 0x0000
-+#define SST_MAILBOX_RCV 0x0804
-+#define SST_TIME_STAMP 0x1800
-+#define SST_RESERVED_OFFSET 0x1840
-+#define SST_CHEKPOINT_OFFSET 0x1C00
-+#define REPLY_MSG 0x80
-+
-+/* Message ID's for IPC messages */
-+/* Bits B7: SST or IA/SC ; B6-B4: Msg Category; B3-B0: Msg Type */
-+
-+/* I2L Firmware/Codec Download msgs */
-+#define IPC_IA_PREP_LIB_DNLD 0x01
-+#define IPC_IA_LIB_DNLD_CMPLT 0x02
-+
-+#define IPC_IA_SET_PMIC_TYPE 0x03
-+#define IPC_IA_GET_FW_VERSION 0x04
-+#define IPC_IA_GET_FW_BUILD_INF 0x05
-+#define IPC_IA_GET_FW_INFO 0x06
-+
-+/* I2L Codec Config/control msgs */
-+#define IPC_IA_SET_CODEC_PARAMS 0x10
-+#define IPC_IA_GET_CODEC_PARAMS 0x11
-+#define IPC_IA_SET_PPP_PARAMS 0x12
-+#define IPC_IA_GET_PPP_PARAMS 0x13
-+#define IPC_IA_PLAY_FRAMES 0x14
-+#define IPC_IA_CAPT_FRAMES 0x15
-+#define IPC_IA_PLAY_VOICE 0x16
-+#define IPC_IA_CAPT_VOICE 0x17
-+#define IPC_IA_DECODE_FRAMES 0x18
-+
-+/* I2L Stream config/control msgs */
-+#define IPC_IA_ALLOC_STREAM 0x20 /* Allocate a stream ID */
-+#define IPC_IA_FREE_STREAM 0x21 /* Free the stream ID */
-+#define IPC_IA_SET_STREAM_PARAMS 0x22
-+#define IPC_IA_GET_STREAM_PARAMS 0x23
-+#define IPC_IA_PAUSE_STREAM 0x24
-+#define IPC_IA_RESUME_STREAM 0x25
-+#define IPC_IA_DROP_STREAM 0x26
-+#define IPC_IA_DRAIN_STREAM 0x27 /* Short msg with str_id */
-+#define IPC_IA_TARGET_DEV_SELECT 0x28
-+#define IPC_IA_CONTROL_ROUTING 0x29
-+
-+#define IPC_IA_SET_STREAM_VOL 0x2A /*Vol for stream, pre mixer */
-+#define IPC_IA_GET_STREAM_VOL 0x2B
-+#define IPC_IA_SET_STREAM_MUTE 0x2C
-+#define IPC_IA_GET_STREAM_MUTE 0x2D
-+#define IPC_IA_SET_MASTER_VOL 0x2E /* set vol for post mixer */
-+#define IPC_IA_GET_MASTER_VOL 0x2F /* Get Volume for post mixer */
-+#define IPC_IA_SET_MASTER_MUTE 0x30 /* Set Master Mute post mixer */
-+#define IPC_IA_GET_MASTER_MUTE 0x31 /* Get Master Mute; post mixer */
-+
-+/* Debug msgs */
-+#define IPC_IA_DBG_MEM_READ 0x40
-+#define IPC_IA_DBG_MEM_WRITE 0x41
-+#define IPC_IA_DBG_LOOP_BACK 0x42
-+
-+/* L2I Firmware/Codec Download msgs */
-+#define IPC_IA_FW_INIT_CMPLT 0x81
-+#define IPC_IA_LPE_GETTING_STALLED 0x82
-+#define IPC_IA_LPE_UNSTALLED 0x83
-+
-+/* L2I Codec Config/control msgs */
-+#define IPC_SST_GET_PLAY_FRAMES 0x90 /* Request IA more data */
-+#define IPC_SST_GET_CAPT_FRAMES 0x91 /* Request IA more data */
-+#define IPC_SST_BUF_UNDER_RUN 0x92 /* PB Under run and stopped */
-+#define IPC_SST_BUF_OVER_RUN 0x93 /* CAP Under run and stopped */
-+#define IPC_SST_DRAIN_END 0x94 /* PB Drain complete and stopped */
-+#define IPC_SST_CHNGE_SSP_PARAMS 0x95 /* PB SSP parameters changed */
-+#define IPC_SST_STREAM_PROCESS_FATAL_ERR 0x96/* error in processing a stream */
-+#define IPC_SST_PERIOD_ELAPSED 0x97 /* period elapsed */
-+#define IPC_IA_TARGET_DEV_CHNGD 0x98 /* error in processing a stream */
-+
-+/* L2S messages */
-+#define IPC_SC_DDR_LINK_UP 0xC0
-+#define IPC_SC_DDR_LINK_DOWN 0xC1
-+
-+/* L2I Error reporting msgs */
-+#define IPC_IA_MEM_ALLOC_FAIL 0xE0
-+#define IPC_IA_PROC_ERR 0xE1 /* error in processing a
-+ stream can be used by playback and
-+ capture modules */
-+
-+/* L2I Debug msgs */
-+#define IPC_IA_PRINT_STRING 0xF0
-+
-+#define IPC_IA_ENABLE_RX_TIME_SLOT 0x2E /* Enable Rx time slot 0 or 1 */
-+
-+
-+/* Command Response or Acknowledge message to any IPC message will have
-+ * same message ID and stream ID information which is sent.
-+ * There is no specific Ack message ID. The data field is used as response
-+ * meaning.
-+ */
-+enum ackData {
-+ IPC_ACK_SUCCESS = 0,
-+ IPC_ACK_FAILURE
-+};
-+
-+
-+enum sst_error_codes {
-+ /* Error code,response to msgId: Description */
-+ /* Common error codes */
-+ SST_SUCCESS = 0, /* Success */
-+ SST_ERR_INVALID_STREAM_ID, /* Invalid stream ID */
-+ SST_ERR_INVALID_MSG_ID, /* Invalid message ID */
-+ SST_ERR_INVALID_STREAM_OP, /* Invalid stream operation request */
-+ SST_ERR_INVALID_PARAMS, /* Invalid params */
-+ SST_ERR_INVALID_CODEC, /* Invalid codec type */
-+ SST_ERR_INVALID_MEDIA_TYPE, /* Invalid media type */
-+ SST_ERR_STREAM_ERR, /* ANY: Stream control or config or
-+ processing error */
-+
-+ /* IPC specific error codes */
-+ SST_IPC_ERR_CALL_BACK_NOT_REGD, /* Call back for msg not regd */
-+ SST_IPC_ERR_STREAM_NOT_ALLOCATED, /* Stream is not allocated */
-+ SST_IPC_ERR_STREAM_ALLOC_FAILED, /* ALLOC:Stream alloc failed */
-+ SST_IPC_ERR_GET_STREAM_FAILED, /* ALLOC:Get stream id failed*/
-+ SST_ERR_MOD_NOT_AVAIL, /* SET/GET: Mod(AEC/AGC/ALC) not available */
-+ SST_ERR_MOD_DNLD_RQD, /* SET/GET: Mod(AEC/AGC/ALC) download required */
-+ SST_ERR_STREAM_STOPPED, /* ANY: Stream is in stopped state */
-+ SST_ERR_STREAM_IN_USE, /* ANY: Stream is already in use */
-+
-+ /* Capture specific error codes */
-+ SST_CAP_ERR_INCMPLTE_CAPTURE_MSG,/* ANY:Incomplete message */
-+ SST_CAP_ERR_CAPTURE_FAIL, /* ANY:Capture op failed */
-+ SST_CAP_ERR_GET_DDR_NEW_SGLIST,
-+ SST_CAP_ERR_UNDER_RUN, /* lack of input data */
-+ SST_CAP_ERR_OVERFLOW, /* lack of output space */
-+
-+ /* Playback specific error codes*/
-+ SST_PB_ERR_INCMPLTE_PLAY_MSG, /* ANY: Incomplete message */
-+ SST_PB_ERR_PLAY_FAIL, /* ANY: Playback operation failed */
-+ SST_PB_ERR_GET_DDR_NEW_SGLIST,
-+
-+ /* Codec manager specific error codes */
-+ SST_LIB_ERR_LIB_DNLD_REQUIRED, /* ALLOC: Codec download required */
-+ SST_LIB_ERR_LIB_NOT_SUPPORTED, /* Library is not supported */
-+
-+ /* Library manager specific error codes */
-+ SST_SCC_ERR_PREP_DNLD_FAILED, /* Failed to prepare for codec download */
-+ SST_SCC_ERR_LIB_DNLD_RES_FAILED, /* Lib download resume failed */
-+ /* Scheduler specific error codes */
-+ SST_SCH_ERR_FAIL, /* REPORT: */
-+
-+ /* DMA specific error codes */
-+ SST_DMA_ERR_NO_CHNL_AVAILABLE, /* DMA Ch not available */
-+ SST_DMA_ERR_INVALID_INPUT_PARAMS, /* Invalid input params */
-+ SST_DMA_ERR_CHNL_ALREADY_SUSPENDED, /* Ch is suspended */
-+ SST_DMA_ERR_CHNL_ALREADY_STARTED, /* Ch already started */
-+ SST_DMA_ERR_CHNL_NOT_ENABLED, /* Ch not enabled */
-+ SST_DMA_ERR_TRANSFER_FAILED, /* Transfer failed */
-+ SST_SSP_ERR_ALREADY_ENABLED, /* REPORT: SSP already enabled */
-+ SST_SSP_ERR_ALREADY_DISABLED, /* REPORT: SSP already disabled */
-+ SST_SSP_ERR_NOT_INITIALIZED,
-+
-+ /* Other error codes */
-+ SST_ERR_MOD_INIT_FAIL, /* Firmware Module init failed */
-+
-+ /* FW init error codes */
-+ SST_RDR_ERR_IO_DEV_SEL_NOT_ALLOWED,
-+ SST_RDR_ERR_ROUTE_ALREADY_STARTED,
-+ SST_RDR_PREP_CODEC_DNLD_FAILED,
-+
-+ /* Memory debug error codes */
-+ SST_ERR_DBG_MEM_READ_FAIL,
-+ SST_ERR_DBG_MEM_WRITE_FAIL,
-+
-+ /* Decode error codes */
-+ SST_ERR_DEC_NEED_INPUT_BUF,
-+
-+};
-+
-+enum dbg_mem_data_type {
-+ /* Data type of debug read/write */
-+ DATA_TYPE_U32,
-+ DATA_TYPE_U16,
-+ DATA_TYPE_U8,
-+};
-+
-+/* CAUTION NOTE: All IPC message body must be multiple of 32 bits.*/
-+
-+/* IPC Header */
-+union ipc_header {
-+ struct {
-+ u32 msg_id:8; /* Message ID - Max 256 Message Types */
-+ u32 str_id:3; /* Undefined for SC communication */
-+ u32 large:1; /* Large Message if large = 1 */
-+ u32 reserved:4;/* Reserved for future use */
-+ u32 data:14; /* Ack/Info for msg, size of msg in Mailbox */
-+ u32 done:1; /* bit 30 */
-+ u32 busy:1; /* bit 31 */
-+ } part;
-+ u32 full;
-+} __attribute__ ((packed));
-+
-+struct ipc_header_fw_init {
-+ struct snd_sst_fw_version fw_version;/* Firmware version details */
-+ u16 result; /* Fw init result */
-+ u8 module_id; /* Module ID in case of error */
-+ u8 debug_info; /* Debug info from Module ID in case of fail */
-+} __attribute__ ((packed));
-+
-+/* Firmware build info */
-+struct sst_fw_build_info {
-+ unsigned char date[16]; /* Firmware build date */
-+ unsigned char time[16]; /* Firmware build time */
-+} __attribute__ ((packed));
-+
-+/* Address and size info of a frame buffer in DDR */
-+struct sst_address_info {
-+ u32 addr; /* Address at IA */
-+ u32 size; /* Size of the buffer */
-+} __attribute__ ((packed));
-+
-+/* Time stamp */
-+struct snd_sst_tstamp {
-+ u64 samples_processed; /* capture - data in DDR */
-+ u64 samples_rendered; /* playback - data rendered */
-+ u64 bytes_processed; /* bytes decoded or encoded */
-+ u32 sampling_frequency; /* eg: 48000, 44100 */
-+
-+};
-+
-+/* Frame info to play or capture */
-+struct sst_frame_info {
-+ u16 num_entries; /* number of entries to follow */
-+ u16 rsrvd;
-+ struct sst_address_info addr[MAX_NUM_SCATTER_BUFFERS];
-+} __attribute__ ((packed));
-+
-+/* Frames info for decode */
-+struct snd_sst_decode_info {
-+ unsigned long long input_bytes_consumed;
-+ unsigned long long output_bytes_produced;
-+ struct sst_frame_info frames_in;
-+ struct sst_frame_info frames_out;
-+} __attribute__ ((packed));
-+/* SST to IA print debug message*/
-+struct ipc_sst_ia_print_params {
-+ u32 string_size; /* Max value is 160 */
-+ u8 prt_string[160]; /* Null terminated Char string */
-+} __attribute__ ((packed));
-+/* Voice data message */
-+struct snd_sst_voice_data {
-+ u16 num_bytes; /* Number of valid voice data bytes */
-+ u8 pcm_wd_size; /* 0=8 bit, 1=16 bit 2=32 bit */
-+ u8 reserved; /* Reserved */
-+ u8 voice_data_buf[0]; /* Voice data buffer in bytes, little endian */
-+} __attribute__ ((packed));
-+
-+/* SST to IA memory read debug message */
-+struct ipc_sst_ia_dbg_mem_rw {
-+ u16 num_bytes; /* Maximum of MAX_DBG_RW_BYTES */
-+ u16 data_type; /* enum: dbg_mem_data_type */
-+ u32 address; /* Memory address of data memory of data_type */
-+ u8 rw_bytes[MAX_DBG_RW_BYTES];/* Maximum of 64 bytes can be RW */
-+} __attribute__ ((packed));
-+
-+struct ipc_sst_ia_dbg_loop_back {
-+ u16 num_dwords; /* Maximum of MAX_DBG_RW_BYTES */
-+ u16 increment_val;/* Increments dwords by this value, 0- no increment */
-+ u32 lpbk_dwords[MAX_LOOP_BACK_DWORDS];/* Maximum of 8 dwords loopback */
-+} __attribute__ ((packed));
-+
-+/* Stream type params struture for Alloc stream */
-+struct snd_sst_str_type {
-+ u8 codec_type; /* Codec type */
-+ u8 str_type; /* 1 = voice 2 = music */
-+ u8 operation; /* Playback or Capture */
-+ u8 protected_str; /* 0=Non DRM, 1=DRM */
-+ u8 pvt_id; /* Driver Private ID */
-+ u8 reserved; /* Reserved */
-+ u16 result; /* Result used for acknowledgment */
-+} __attribute__ ((packed));
-+
-+/* Library info structure */
-+struct module_info {
-+ u32 lib_version;
-+ u32 lib_type;/*TBD- KLOCKWORK u8 lib_type;*/
-+ u32 media_type;
-+ u8 lib_name[12];
-+ u32 lib_caps;
-+ unsigned char b_date[16]; /* Lib build date */
-+ unsigned char b_time[16]; /* Lib build time */
-+} __attribute__ ((packed));
-+
-+/* Library slot info */
-+struct lib_slot_info {
-+ u8 slot_num; /* 1 or 2 */
-+ u8 reserved1;
-+ u16 reserved2;
-+ u32 iram_size; /* slot size in IRAM */
-+ u32 dram_size; /* slot size in DRAM */
-+ u32 iram_offset; /* starting offset of slot in IRAM */
-+ u32 dram_offset; /* starting offset of slot in DRAM */
-+} __attribute__ ((packed));
-+
-+struct snd_sst_lib_download {
-+ struct module_info lib_info; /* library info type, capabilities etc */
-+ struct lib_slot_info slot_info; /* slot info to be downloaded */
-+ u32 mod_entry_pt;
-+};
-+
-+struct snd_sst_lib_download_info {
-+ struct snd_sst_lib_download dload_lib;
-+ u16 result; /* Result used for acknowledgment */
-+ u8 pvt_id; /* Private ID */
-+ u8 reserved; /* for alignment */
-+};
-+
-+/* Alloc stream params structure */
-+struct snd_sst_alloc_params {
-+ struct snd_sst_str_type str_type;
-+ struct snd_sst_stream_params stream_params;
-+};
-+
-+struct snd_sst_fw_get_stream_params {
-+ struct snd_sst_stream_params codec_params;
-+ struct snd_sst_pmic_config pcm_params;
-+};
-+
-+/* Alloc stream response message */
-+struct snd_sst_alloc_response {
-+ struct snd_sst_str_type str_type; /* Stream type for allocation */
-+ struct snd_sst_lib_download lib_dnld; /* Valid only for codec dnld */
-+};
-+
-+/* Drop response */
-+struct snd_sst_drop_response {
-+ u32 result;
-+ u32 bytes;
-+};
-+
-+/* CSV Voice call routing structure */
-+struct snd_sst_control_routing {
-+ u8 control; /* 0=start, 1=Stop */
-+ u8 reserved[3]; /* Reserved- for 32 bit alignment */
-+};
-+
-+
-+
-+/* struct ipc_msg_body {
-+ union {
-+ CODEC_PARAM_STRUCTURES;
-+ PPP_PARAM_STRUCTURES;
-+ struct snd_sst_alloc_params alloc_params;
-+ struct snd_sst_alloc_response alloc_response;
-+ struct snd_sst_stream_params stream_params;
-+ struct sst_frame_info frames_info;
-+ struct ipc_sst_ia_print_params print_params;
-+ struct ipc_sst_ia_dbg_mem_rw dbg_mem_rw;
-+ struct ipc_sst_ia_dbg_loop_back loop_back;
-+ struct pmic_pcm_params ssp_params;
-+ } u;
-+};*/
-+
-+
-+
-+struct ipc_post {
-+ struct list_head node;
-+ union ipc_header header; /* driver specific */
-+ char *mailbox_data;
-+};
-+
-+#endif /* __INTEL_SST_FW_IPC_H__ */
-diff --git a/sound/pci/sst/intel_sst_ipc.c b/sound/pci/sst/intel_sst_ipc.c
-new file mode 100644
-index 0000000..710cf8f
---- /dev/null
-+++ b/sound/pci/sst/intel_sst_ipc.c
-@@ -0,0 +1,843 @@
-+/*
-+ * intel_sst_ipc.c - Intel SST Driver for audio engine
-+ *
-+ * Copyright (C) 2008-10 Intel Corporation
-+ * Authors: Vinod Koul <vinod.koul@intel.com>
-+ * Harsha Priya <priya.harsha@intel.com>
-+ * Dharageswari R <dharageswari.r@intel.com>
-+ * KP Jeeja <jeeja.kp@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 file defines all ipc functions
-+ */
-+
-+#include <linux/cdev.h>
-+#include <linux/pci.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/syscalls.h>
-+#include <linux/file.h>
-+#include <linux/interrupt.h>
-+#include <linux/list.h>
-+#include <linux/workqueue.h>
-+#include <linux/mutex.h>
-+#include <linux/firmware.h>
-+#include <sound/intel_lpe.h>
-+#include <sound/intel_sst_ioctl.h>
-+#include "intel_sst_fw_ipc.h"
-+#include "intel_sst_common.h"
-+
-+/**
-+* Debug function to test basic IPC between driver and SST firmware
-+*/
-+static void sst_send_loop_test(int loop_no)
-+{
-+ struct ipc_post *msg = NULL;
-+ struct ipc_sst_ia_dbg_loop_back loop_msg;
-+ static int large_num;
-+
-+ printk(KERN_DEBUG "SST DBG:Loop testing %d \n", loop_no);
-+
-+ if (large_num >= 4) {
-+ printk(KERN_DEBUG "SST DBG:Loop testing complete.....\n");
-+ return;
-+ }
-+ if (loop_no >= 4) {
-+ /* large loop */
-+ large_num++;
-+ printk(KERN_DEBUG "SST DBG:Large msg \n");
-+ if (sst_create_large_msg(&msg))
-+ return;
-+
-+ loop_msg.increment_val = 1;
-+ loop_msg.lpbk_dwords[0] = LOOP1;
-+ loop_msg.lpbk_dwords[1] = LOOP2;
-+ loop_msg.lpbk_dwords[2] = LOOP3;
-+ loop_msg.lpbk_dwords[3] = LOOP4;
-+ loop_msg.num_dwords = 4;
-+ sst_fill_header(&msg->header, IPC_IA_DBG_LOOP_BACK, 1, loop_no);
-+ msg->header.part.data = sizeof(u32) + sizeof(loop_msg);
-+ memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
-+ memcpy(msg->mailbox_data + sizeof(u32),
-+ &loop_msg, sizeof(loop_msg));
-+ } else {
-+ /* short loop */
-+ printk(KERN_DEBUG "SST DBG:Loop Short msg \n");
-+ if (sst_create_short_msg(&msg))
-+ return;
-+ sst_fill_header(&msg->header, IPC_IA_DBG_LOOP_BACK, 0, loop_no);
-+ }
-+ mutex_lock(&sst_drv_ctx->list_lock);
-+ list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-+ mutex_unlock(&sst_drv_ctx->list_lock);
-+ sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-+ return;
-+}
-+
-+/**
-+* this function sends the sound card type to sst dsp engine
-+*/
-+static void sst_send_sound_card_type(void)
-+{
-+ struct ipc_post *msg = NULL;
-+
-+ printk(KERN_DEBUG "SST DBG:...called\n");
-+
-+ if (sst_create_short_msg(&msg))
-+ return;
-+
-+ sst_fill_header(&msg->header, IPC_IA_SET_PMIC_TYPE, 0, 0);
-+ msg->header.part.data = sst_drv_ctx->pmic_vendor;
-+ mutex_lock(&sst_drv_ctx->list_lock);
-+ list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
-+ mutex_unlock(&sst_drv_ctx->list_lock);
-+ sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
-+ return;
-+}
-+
-+/**
-+* sst_post_message - Posts message to SST
-+* @work: Pointer to work structure
-+*
-+* This function is called by any component in driver which
-+* wants to send an IPC message. This will post message only if
-+* busy bit is free
-+*/
-+void sst_post_message(struct work_struct *work)
-+{
-+ struct ipc_post *msg;
-+ union ipc_header header;
-+ union interrupt_reg imr;
-+ int retval = 0;
-+ imr.full = 0;
-+
-+ /*To check if LPE is in stalled state.*/
-+ retval = sst_stalled();
-+ if (retval < 0) {
-+ printk(KERN_ERR "SST ERR: SST is in stalled state \n");
-+ return;
-+ }
-+ printk(KERN_DEBUG "SST DBG:..called \n");
-+ mutex_lock(&sst_drv_ctx->list_lock);
-+
-+ /* check list */
-+ if (list_empty(&sst_drv_ctx->ipc_dispatch_list)) {
-+ /* list is empty, mask imr */
-+ printk(KERN_DEBUG "SST DBG: Empty msg queue... masking \n");
-+ imr.full = readl(sst_drv_ctx->shim + SST_IMRX);
-+ if( imr.part.done_interrupt == 0) {
-+ imr.part.done_interrupt = 1;
-+ /* dummy register for shim workaround */
-+ writel(imr.full, sst_drv_ctx->shim + SST_ISRD);
-+ writel(imr.full, sst_drv_ctx->shim + SST_IMRX);
-+ }
-+ mutex_unlock(&sst_drv_ctx->list_lock);
-+ return;
-+ }
-+
-+ /* check busy bit */
-+ header.full = readl(sst_drv_ctx->shim + SST_IPCX);
-+ if (header.part.busy) {
-+ /* busy, unmask */
-+ printk(KERN_DEBUG "SST DBG:Busy not free... unmasking\n");
-+ imr.full = readl(sst_drv_ctx->shim + SST_IMRX);
-+ imr.part.done_interrupt = 0;
-+ /* dummy register for shim workaround */
-+ writel(imr.full, sst_drv_ctx->shim + SST_ISRD);
-+ writel(imr.full, sst_drv_ctx->shim + SST_IMRX);
-+ mutex_unlock(&sst_drv_ctx->list_lock);
-+ return;
-+ }
-+ /* copy msg from list */
-+ msg = list_entry(sst_drv_ctx->ipc_dispatch_list.next,
-+ struct ipc_post, node);
-+ list_del(&msg->node);
-+ printk(KERN_DEBUG "SST DBG:Post message: \
-+ header = %x\n", msg->header.full);
-+ printk(KERN_DEBUG "SST DBG:size: = %x\n", msg->header.part.data);
-+ if (msg->header.part.large)
-+ memcpy_toio(sst_drv_ctx->mailbox + SST_MAILBOX_SEND,
-+ msg->mailbox_data, msg->header.part.data);
-+ /* dummy register for shim workaround */
-+ writel(msg->header.full, sst_drv_ctx->shim + SST_ISRD);
-+ writel(msg->header.full, sst_drv_ctx->shim + SST_IPCX);
-+ mutex_unlock(&sst_drv_ctx->list_lock);
-+
-+ kfree(msg->mailbox_data);
-+ kfree(msg);
-+ printk(KERN_DEBUG "SST DBG:...done\n");
-+ return;
-+}
-+
-+/**
-+* this function clears the interrupt register after the interrupt
-+* bottom half is complete allowing next interrupt to arrive
-+*/
-+void sst_clear_interrupt(void)
-+{
-+ union interrupt_reg isr;
-+ union interrupt_reg imr;
-+ union ipc_header clear_ipc;
-+
-+// printk(KERN_DEBUG "SST DBG:sst clearing interrupt \n");
-+ imr.full = readl(sst_drv_ctx->shim + SST_IMRX);
-+ isr.full = readl(sst_drv_ctx->shim + SST_ISRX);
-+ /* write 1 to clear */;
-+ isr.part.busy_interrupt = 1;
-+ /* dummy register for shim workaround */
-+ writel(isr.full, sst_drv_ctx->shim + SST_ISRD);
-+ writel(isr.full, sst_drv_ctx->shim + SST_ISRX);
-+ /* Set IA done bit */
-+ clear_ipc.full = readl(sst_drv_ctx->shim + SST_IPCD);
-+ clear_ipc.part.busy = 0;
-+ clear_ipc.part.done = 1;
-+ clear_ipc.part.data = IPC_ACK_SUCCESS;
-+ /* dummy register for shim workaround */
-+ writel(clear_ipc.full, sst_drv_ctx->shim + SST_ISRD);
-+ writel(clear_ipc.full, sst_drv_ctx->shim + SST_IPCD);
-+ /* un mask busy interrupt */
-+ imr.part.busy_interrupt = 0;
-+ /* dummy register for shim workaround */
-+ writel(imr.full, sst_drv_ctx->shim + SST_ISRD);
-+ writel(imr.full, sst_drv_ctx->shim + SST_IMRX);
-+}
-+
-+/**
-+* sst_process_message - Processes message from SST
-+* @work: Pointer to work structure
-+*
-+* This function is scheduled by ISR
-+* It take a msg from process_queue and does action based on msg
-+*/
-+void sst_process_message(struct work_struct *work)
-+{
-+ struct sst_ipc_msg_wq *msg =
-+ container_of(work, struct sst_ipc_msg_wq, wq);
-+ int str_id = msg->header.part.str_id;
-+ struct stream_info *stream ;
-+
-+ printk(KERN_DEBUG "SST DBG:called \n");
-+
-+ /* based on msg in list call respective handler */
-+ switch (msg->header.part.msg_id) {
-+ case IPC_SST_BUF_UNDER_RUN:
-+ case IPC_SST_BUF_OVER_RUN:
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n", str_id);
-+ break;
-+ }
-+ printk(KERN_ERR
-+ "SST ERR: Buffer under/overrun for %d\n",\
-+ msg->header.part.str_id);
-+ printk(KERN_DEBUG "SST DBG:Got Underrun & not to send data...ignore\n");
-+ break;
-+
-+ case IPC_SST_GET_PLAY_FRAMES:
-+ {
-+ struct stream_info *stream ;
-+
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n", str_id);
-+ break;
-+ }
-+ /* call sst_play_frame */
-+ stream = &sst_drv_ctx->streams[str_id];
-+ printk(KERN_DEBUG "SST DBG:sst_play_frames for %d\n", \
-+ msg->header.part.str_id);
-+ mutex_lock(&sst_drv_ctx->streams[str_id].lock);
-+ sst_play_frame(msg->header.part.str_id);
-+ mutex_unlock(&sst_drv_ctx->streams[str_id].lock);
-+ break;
-+ }
-+
-+ case IPC_SST_PERIOD_ELAPSED:
-+ {
-+ struct snd_sst_tstamp fw_tstamp = {0,};
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n", str_id);
-+ break;
-+ }
-+ stream = &sst_drv_ctx->streams[str_id];
-+
-+ printk(KERN_DEBUG "SST DBG:Period elapsed \n");
-+ memcpy_fromio(&fw_tstamp,
-+ ((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP) +
-+ (str_id * sizeof(fw_tstamp))),
-+ sizeof(fw_tstamp));
-+ printk(KERN_DEBUG "SST DBG:samples \
-+ played = %lld\n", fw_tstamp.samples_processed);
-+ printk(KERN_DEBUG "SST DBG:diff in \
-+ mesg = %d\n", msg->header.part.data);
-+ sst_clear_interrupt();
-+ if (stream->period_elapsed)
-+ stream->period_elapsed(stream->pcm_substream);
-+ return;
-+ }
-+
-+ case IPC_SST_GET_CAPT_FRAMES:
-+ /* call sst_capture_frame */
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n", str_id);
-+ break;
-+ }
-+ stream = &sst_drv_ctx->streams[str_id];
-+ printk(KERN_DEBUG "SST DBG:sst_capture_frames \
-+ for %d\n", msg->header.part.str_id);
-+ mutex_lock(&stream->lock);
-+ if (stream->mmapped == false && stream->src == SST_DRV) {
-+ printk(KERN_DEBUG "SST DBG:waking up block for copy...\n");
-+ stream->data_blk.ret_code = 0;
-+ stream->data_blk.condition = true;
-+ stream->data_blk.on = false;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ } else
-+ sst_capture_frame(msg->header.part.str_id);
-+ mutex_unlock(&stream->lock);
-+ break;
-+
-+ case IPC_IA_PRINT_STRING:
-+ printk(KERN_DEBUG "SST DBG:been asked to print something by fw\n");
-+ /* TBD */
-+ break;
-+
-+ case IPC_IA_FW_INIT_CMPLT: {
-+ /* send next data to FW */
-+ struct ipc_header_fw_init *init =
-+ (struct ipc_header_fw_init *)msg->mailbox;
-+ int major = init->fw_version.major;
-+ int minor = init->fw_version.minor;
-+ int build = init->fw_version.build;
-+
-+ printk(KERN_DEBUG "SST DBG:*** FW Init msg came*** \n");
-+ if (!init->result) {
-+ sst_drv_ctx->sst_state = SST_FW_RUNNING;
-+ printk(KERN_DEBUG "SST DBG:FW Version %x.%x \n",
-+ init->fw_version.major, init->fw_version.minor);
-+ printk(KERN_DEBUG "SST DBG:Build No %x Type %x \n",
-+ init->fw_version.build, init->fw_version.type);
-+#ifdef SND_LOOP_TEST
-+ sst_send_loop_test(0);
-+#endif
-+ sst_send_sound_card_type();
-+
-+ pr_info(
-+ "INFO: ***SST FW VERSION*** +\
-+ = %02d.%02d.%02d\n", \
-+ major, \
-+ minor, build);
-+
-+ printk(KERN_DEBUG "SST DBG:Time slot Status %d\n", sst_drv_ctx->rx_time_slot_status);
-+ if((sst_drv_ctx->rx_time_slot_status != RX_TIMESLOT_UNINIT) && (sst_drv_ctx->sst_state == SST_FW_RUNNING))
-+ sst_enable_rx_timeslot(sst_drv_ctx->rx_time_slot_status);
-+
-+ } else {
-+ sst_drv_ctx->sst_state = SST_ERROR;
-+ printk(KERN_DEBUG "SST DBG:FW Init \
-+ failed, Error %x\n", init->result);
-+ printk(KERN_DEBUG "SST DBG:FW Init failed, Module %x, Debug Info %x \n",
-+ init->module_id, init->debug_info);
-+ }
-+ printk(KERN_DEBUG "SST DBG:Waking up... open\n");
-+ sst_wake_up_alloc_block(sst_drv_ctx, FW_DWNL_ID, 0, NULL);
-+ break;
-+ }
-+
-+ case IPC_SST_STREAM_PROCESS_FATAL_ERR:
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n", str_id);
-+ break;
-+ }
-+ printk(KERN_ERR
-+ "SST ERR: codec fatal error %x for +\
-+ stream %d... \n",\
-+ msg->header.full, \
-+ msg->header.part.str_id);
-+ printk(KERN_ERR
-+ "SST ERR: Dropping the stream \n");
-+ sst_drop_stream(msg->header.part.str_id);
-+ break;
-+ case IPC_IA_LPE_GETTING_STALLED:
-+ sst_drv_ctx->lpe_stalled = 1;
-+ break;
-+ case IPC_IA_LPE_UNSTALLED:
-+ sst_drv_ctx->lpe_stalled = 0;
-+ break;
-+ default:
-+ /* Illegal case */
-+ printk(KERN_ERR
-+ "SST ERR: Unhandled case msg_id %x +\
-+ message %x\n",\
-+ msg->header.part.msg_id, msg->header.full);
-+ }
-+ sst_clear_interrupt();
-+ return;
-+}
-+
-+/**
-+* sst_process_reply - Processes reply message from SST
-+* @work: Pointer to work structure
-+*
-+* This function is scheduled by ISR
-+* It take a reply msg from response_queue and
-+* does action based on msg
-+*/
-+void sst_process_reply(struct work_struct *work)
-+{
-+ struct sst_ipc_msg_wq *msg =
-+ container_of(work, struct sst_ipc_msg_wq, wq);
-+
-+ int str_id = msg->header.part.str_id;
-+ struct stream_info *str_info;
-+ switch (msg->header.part.msg_id) {
-+ case IPC_IA_TARGET_DEV_SELECT: {
-+ if (!msg->header.part.data) {
-+ sst_drv_ctx->tgt_dev_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x reply +\
-+ error %x \n",\
-+ msg->header.part.msg_id, msg->header.part.data);
-+ sst_drv_ctx->tgt_dev_blk.ret_code =
-+ -msg->header.part.data;
-+ }
-+
-+ if (sst_drv_ctx->tgt_dev_blk.on == true) {
-+ sst_drv_ctx->tgt_dev_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+ }
-+ case IPC_IA_GET_FW_INFO: {
-+ struct snd_sst_fw_info *fw_info =
-+ (struct snd_sst_fw_info *)msg->mailbox;
-+ if (msg->header.part.large) {
-+ int major = fw_info->fw_version.major;
-+ int minor = fw_info->fw_version.minor;
-+ int build = fw_info->fw_version.build;
-+ printk(KERN_DEBUG "SST DBG:Msg \
-+ succedded %x \n", msg->header.part.msg_id);
-+ dev_info(&sst_drv_ctx->pci->dev, \
-+ "INFO: ***FW VERSION*** +\
-+ = %02d.%02d.%02d\n", major, \
-+ minor, build);
-+
-+ memcpy_fromio(sst_drv_ctx->fw_info_blk.data,
-+ ((struct snd_sst_fw_info *)(msg->mailbox)),
-+ sizeof(struct snd_sst_fw_info));
-+ sst_drv_ctx->fw_info_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x reply +\
-+ error %x \n",\
-+ msg->header.part.msg_id, msg->header.part.data);
-+ sst_drv_ctx->fw_info_blk.ret_code =
-+ -msg->header.part.data;
-+ }
-+ if (sst_drv_ctx->fw_info_blk.on == true) {
-+ printk(KERN_DEBUG "SST DBG:Memcopy succedded \n");
-+ sst_drv_ctx->fw_info_blk.on = false;
-+ sst_drv_ctx->fw_info_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+ }
-+ case IPC_IA_SET_STREAM_MUTE: {
-+ if (!msg->header.part.data) {
-+ printk(KERN_DEBUG "SST DBG:Msg \
-+ succedded %x \n", msg->header.part.msg_id);
-+ sst_drv_ctx->mute_info_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x reply +\
-+ error %x \n", \
-+ msg->header.part.msg_id, msg->header.part.data);
-+ sst_drv_ctx->mute_info_blk.ret_code =
-+ -msg->header.part.data;
-+
-+ }
-+ if (sst_drv_ctx->mute_info_blk.on == true) {
-+ sst_drv_ctx->mute_info_blk.on = false;
-+ sst_drv_ctx->mute_info_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+ }
-+ case IPC_IA_SET_STREAM_VOL: {
-+ if (!msg->header.part.data) {
-+ printk(KERN_DEBUG "SST DBG:Msg \
-+ succedded %x \n", msg->header.part.msg_id);
-+ sst_drv_ctx->vol_info_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x reply +\
-+ error %x \n",\
-+ msg->header.part.msg_id, \
-+ msg->header.part.data);
-+ sst_drv_ctx->vol_info_blk.ret_code =
-+ -msg->header.part.data;
-+
-+ }
-+
-+ if (sst_drv_ctx->vol_info_blk.on == true) {
-+ sst_drv_ctx->vol_info_blk.on = false;
-+ sst_drv_ctx->vol_info_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+ }
-+ case IPC_IA_GET_STREAM_VOL:
-+ if (msg->header.part.large) {
-+ printk(KERN_DEBUG "SST DBG:Large Msg Received Successfully\n");
-+ printk(KERN_DEBUG "SST DBG:Msg \
-+ succedded %x \n", msg->header.part.msg_id);
-+ memcpy_fromio(sst_drv_ctx->vol_info_blk.data,
-+ (void *) msg->mailbox,
-+ sizeof(struct snd_sst_vol));
-+ sst_drv_ctx->vol_info_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x +\
-+ reply error %x \n",\
-+ msg->header.part.msg_id, msg->header.part.data);
-+ sst_drv_ctx->vol_info_blk.ret_code =
-+ -msg->header.part.data;
-+ }
-+ if (sst_drv_ctx->vol_info_blk.on == true) {
-+ sst_drv_ctx->vol_info_blk.on = false;
-+ sst_drv_ctx->vol_info_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+
-+ case IPC_IA_GET_STREAM_PARAMS:
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n", str_id);
-+ break;
-+ }
-+ str_info = &sst_drv_ctx->streams[str_id];
-+ if (msg->header.part.large) {
-+ printk(KERN_DEBUG "SST DBG:The Large \
-+ message for get stream params\n");
-+ printk(KERN_DEBUG "SST DBG:Msg +\
-+ succedded %x \n", msg->header.part.msg_id);
-+ memcpy_fromio(str_info->ctrl_blk.data,
-+ ((void *)(msg->mailbox)),
-+ sizeof(struct snd_sst_fw_get_stream_params));
-+ str_info->ctrl_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: The message for +\
-+ get params is not large\n");
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x reply error %x \n",\
-+ msg->header.part.msg_id, msg->header.part.data);
-+ str_info->ctrl_blk.ret_code =
-+ -msg->header.part.data;
-+ }
-+ if (str_info->ctrl_blk.on == true) {
-+ str_info->ctrl_blk.on = false;
-+ str_info->ctrl_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+ case IPC_IA_DECODE_FRAMES:
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n", str_id);
-+ break;
-+ }
-+ str_info = &sst_drv_ctx->streams[str_id];
-+ if (msg->header.part.large) {
-+ printk(KERN_DEBUG "SST DBG:Msg \
-+ succedded %x \n", msg->header.part.msg_id);
-+ memcpy_fromio(str_info->data_blk.data,
-+ ((void *)(msg->mailbox)),
-+ sizeof(struct snd_sst_decode_info));
-+ str_info->data_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x reply error %x \n",\
-+ msg->header.part.msg_id, msg->header.part.data);
-+ str_info->data_blk.ret_code =
-+ -msg->header.part.data;
-+ }
-+ if (str_info->data_blk.on == true) {
-+ str_info->data_blk.on = false;
-+ str_info->data_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+ case IPC_IA_DRAIN_STREAM:
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n", str_id);
-+ break;
-+ }
-+ str_info = &sst_drv_ctx->streams[str_id];
-+ if (!msg->header.part.data) {
-+ printk(KERN_DEBUG "SST DBG:Msg \
-+ succedded %x \n", msg->header.part.msg_id);
-+ str_info->ctrl_blk.ret_code = 0;
-+
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x reply error %x \n",\
-+ msg->header.part.msg_id, msg->header.part.data);
-+ str_info->ctrl_blk.ret_code = -msg->header.part.data;
-+
-+ }
-+ str_info = &sst_drv_ctx->streams[str_id];
-+ if (str_info->data_blk.on == true) {
-+ str_info->data_blk.on = false;
-+ str_info->data_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+
-+ case IPC_IA_DROP_STREAM:
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n", str_id);
-+ break;
-+ }
-+ str_info = &sst_drv_ctx->streams[str_id];
-+ if (msg->header.part.large) {
-+ struct snd_sst_drop_response *drop_resp =
-+ (struct snd_sst_drop_response *)msg->mailbox;
-+
-+ printk(KERN_DEBUG "SST DBG:Drop returns with bytes 0x%x \n",
-+ drop_resp->bytes);
-+
-+ str_info->curr_bytes = drop_resp->bytes;
-+ str_info->ctrl_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x reply error %x \n", \
-+ msg->header.part.msg_id, msg->header.part.data);
-+ str_info->ctrl_blk.ret_code = -msg->header.part.data;
-+ }
-+ if (str_info->ctrl_blk.on == true) {
-+ str_info->ctrl_blk.on = false;
-+ str_info->ctrl_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+ case IPC_IA_ENABLE_RX_TIME_SLOT:
-+ if (!msg->header.part.data) {
-+ printk(KERN_DEBUG "SST DBG:Msg \
-+ succedded IPC_IA_ENABLE_RX_TIME_SLOT %x \n", msg->header.part.msg_id);
-+ sst_drv_ctx->hs_info_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x +\
-+ reply error %x \n", msg->header.part.msg_id, \
-+ msg->header.part.data);
-+ sst_drv_ctx->hs_info_blk.ret_code = -msg->header.part.data;
-+ }
-+
-+
-+ if (sst_drv_ctx->hs_info_blk.on == true) {
-+ sst_drv_ctx->hs_info_blk.on = false;
-+ sst_drv_ctx->hs_info_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+ case IPC_IA_PAUSE_STREAM:
-+ case IPC_IA_RESUME_STREAM:
-+ case IPC_IA_SET_STREAM_PARAMS:
-+ str_info = &sst_drv_ctx->streams[str_id];
-+ if (!msg->header.part.data) {
-+ printk(KERN_DEBUG "SST DBG:Msg \
-+ succedded %x \n", msg->header.part.msg_id);
-+ str_info->ctrl_blk.ret_code = 0;
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Msg %x +\
-+ reply error %x \n", msg->header.part.msg_id, \
-+ msg->header.part.data);
-+ str_info->ctrl_blk.ret_code = -msg->header.part.data;
-+ }
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d +\
-+ invalid\n", str_id);
-+ break;
-+ }
-+
-+ if (str_info->ctrl_blk.on == true) {
-+ str_info->ctrl_blk.on = false;
-+ str_info->ctrl_blk.condition = true;
-+ wake_up(&sst_drv_ctx->wait_queue);
-+ }
-+ break;
-+
-+ case IPC_IA_FREE_STREAM:
-+ if (!msg->header.part.data) {
-+ printk(KERN_DEBUG "SST DBG:Stream %d freed\n", str_id);
-+ } else {
-+ printk(KERN_ERR
-+ "SST ERR: Free for %d +\
-+ returned error %x\n", str_id, msg->header.part.data);
-+ }
-+ break;
-+ case IPC_IA_ALLOC_STREAM: {
-+ /* map to stream, call play */
-+ struct snd_sst_alloc_response *resp =
-+ (struct snd_sst_alloc_response *)msg->mailbox;
-+ if (resp->str_type.result) {
-+ /* error case */
-+ struct snd_sst_alloc_response *lib = NULL;
-+ printk(KERN_ERR
-+ "SST ERR: error +\
-+ alloc stream = %x \n", resp->str_type.result);
-+ if (resp->str_type.result ==
-+ SST_LIB_ERR_LIB_DNLD_REQUIRED) {
-+ lib = kzalloc(sizeof(*lib), GFP_ATOMIC);
-+ if (!lib) {
-+ printk(KERN_ERR
-+ "SST ERR: +\
-+ mem allocation failed \n");
-+ break;
-+ }
-+ memcpy(lib, msg->mailbox, sizeof(*lib));
-+ /* library needs to be downloaded */
-+ printk(KERN_DEBUG "SST DBG:Codec Download required \n");
-+ }
-+ sst_wake_up_alloc_block(sst_drv_ctx,
-+ resp->str_type.pvt_id,
-+ (-resp->str_type.result), lib);
-+ break;
-+ }
-+ sst_alloc_stream_response(str_id, &resp->str_type);
-+ break;
-+ }
-+
-+ case IPC_IA_DBG_LOOP_BACK:
-+ /* Debug loop back msg */
-+ printk(KERN_DEBUG "SST DBG:Loop back came \n");
-+ if (msg->header.part.data)
-+ printk(KERN_DEBUG "SST DBG:Possible error if not large \n");
-+ printk(KERN_DEBUG "SST DBG:Loop ID: %d\n", str_id);
-+ if (msg->header.part.large) {
-+ struct ipc_sst_ia_dbg_loop_back *loop_msg =
-+ (struct ipc_sst_ia_dbg_loop_back *)msg->mailbox;
-+ int i;
-+ printk(KERN_DEBUG "SST DBG:Got large loop back: Words %d\n",
-+ loop_msg->num_dwords);
-+ for (i = 0; i < loop_msg->num_dwords; i++) {
-+ printk(KERN_DEBUG "SST DBG:Loop \
-+ Word %d = %d \n", i,
-+ loop_msg->lpbk_dwords[i]);
-+ }
-+ }
-+ sst_send_loop_test((str_id + 1));
-+ break;
-+
-+ case IPC_IA_PLAY_FRAMES:
-+ case IPC_IA_CAPT_FRAMES:
-+ if (sst_validate_strid(str_id)) {
-+ printk(KERN_ERR
-+ "SST ERR: stream id %d invalid\n" , str_id);
-+ break;
-+ }
-+ printk(KERN_DEBUG "SST DBG:Ack for play/capt frames recived \n");
-+ break;
-+
-+ case IPC_IA_PREP_LIB_DNLD: {
-+ struct snd_sst_str_type *str_type =
-+ (struct snd_sst_str_type *)msg->mailbox;
-+ printk(KERN_DEBUG "SST DBG:Prep Lib \
-+ download %x\n", msg->header.part.msg_id);
-+ if (str_type->result) {
-+ printk(KERN_ERR
-+ "SST ERR: Error in prep lib +\
-+ download 0x%x\n" ,\
-+ str_type->result);
-+ } else
-+ printk(KERN_DEBUG "SST DBG:Need to download codec now...\n");
-+ /* FIXME remove this workaround */
-+ str_type->result = 0;
-+ sst_wake_up_alloc_block(sst_drv_ctx, str_type->pvt_id,
-+ str_type->result, NULL);
-+ break;
-+ }
-+
-+ case IPC_IA_LIB_DNLD_CMPLT: {
-+ struct snd_sst_lib_download_info *resp =
-+ (struct snd_sst_lib_download_info *)msg->mailbox;
-+ int retval = resp->result;
-+
-+ printk(KERN_DEBUG "SST DBG:Lib download \
-+ cmplt %x\n", msg->header.part.msg_id);
-+ if (resp->result) {
-+ printk(KERN_ERR
-+ "SST ERR: Error in +\
-+ lib dload %x\n",\
-+ resp->result);
-+ } else {
-+ printk(KERN_DEBUG "SST DBG:Codec download complete...\n");
-+ printk(KERN_DEBUG "SST DBG:Downloaded codec Type %d Ver %d Built %s: %s\n",
-+ resp->dload_lib.lib_info.lib_type,
-+ resp->dload_lib.lib_info.lib_version,
-+ resp->dload_lib.lib_info.b_date,
-+ resp->dload_lib.lib_info.b_time);
-+ }
-+ sst_wake_up_alloc_block(sst_drv_ctx, resp->pvt_id,
-+ retval, NULL);
-+ break;
-+ }
-+
-+ case IPC_IA_GET_FW_VERSION: {
-+ struct ipc_header_fw_init *version =
-+ (struct ipc_header_fw_init *)msg->mailbox;
-+ int major = version->fw_version.major;
-+ int minor = version->fw_version.minor;
-+ int build = version->fw_version.build;
-+ dev_info(&sst_drv_ctx->pci->dev, \
-+ "INFO: ***LOADED SST FW +\
-+ VERSION*** = %02d.%02d.%02d\n",\
-+ major, minor, build);
-+ break;
-+ }
-+ case IPC_IA_GET_FW_BUILD_INF: {
-+ struct sst_fw_build_info *build =
-+ (struct sst_fw_build_info *)msg->mailbox;
-+ dev_info(&sst_drv_ctx->pci->dev, \
-+ "INFO: Build date %s +\
-+ Time %s",\
-+ build->date, build->time);
-+ break;
-+ }
-+ case IPC_IA_SET_PMIC_TYPE:
-+ break;
-+ default:
-+ /* Illegal case */
-+ printk(KERN_ERR
-+ "SST ERR: process reply :default +\
-+ case = %x\n" , msg->header.full);
-+
-+ }
-+ sst_clear_interrupt();
-+ return;
-+}
---
-1.6.2.2
-