diff options
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.patch | 1285 |
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 - |