linux/sound/pci/cs46xx/dsp_spos.h
<<
>>
Prefs
   1/*
   2 *  The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
   3 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
   4 *
   5 *
   6 *   This program is free software; you can redistribute it and/or modify
   7 *   it under the terms of the GNU General Public License as published by
   8 *   the Free Software Foundation; either version 2 of the License, or
   9 *   (at your option) any later version.
  10 *
  11 *   This program is distributed in the hope that it will be useful,
  12 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *   GNU General Public License for more details.
  15 *
  16 *   You should have received a copy of the GNU General Public License
  17 *   along with this program; if not, write to the Free Software
  18 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  19 *
  20 */
  21
  22/*
  23 * 2002-07 Benny Sjostrand benny@hostmobility.com
  24 */
  25
  26#ifdef  CONFIG_SND_CS46XX_NEW_DSP /* hack ... */
  27#ifndef __DSP_SPOS_H__
  28#define __DSP_SPOS_H__
  29
  30#define DSP_MAX_SYMBOLS 1024
  31#define DSP_MAX_MODULES 64
  32
  33#define DSP_CODE_BYTE_SIZE             0x00007000UL
  34#define DSP_PARAMETER_BYTE_SIZE        0x00003000UL
  35#define DSP_SAMPLE_BYTE_SIZE           0x00003800UL
  36#define DSP_PARAMETER_BYTE_OFFSET      0x00000000UL
  37#define DSP_SAMPLE_BYTE_OFFSET         0x00010000UL
  38#define DSP_CODE_BYTE_OFFSET           0x00020000UL
  39
  40#define WIDE_INSTR_MASK       0x0040
  41#define WIDE_LADD_INSTR_MASK  0x0380
  42
  43/* this instruction types
  44   needs to be reallocated when load
  45   code into DSP */
  46enum wide_opcode {
  47        WIDE_FOR_BEGIN_LOOP = 0x20,
  48        WIDE_FOR_BEGIN_LOOP2,
  49
  50        WIDE_COND_GOTO_ADDR = 0x30,
  51        WIDE_COND_GOTO_CALL,
  52
  53        WIDE_TBEQ_COND_GOTO_ADDR = 0x70,
  54        WIDE_TBEQ_COND_CALL_ADDR,
  55        WIDE_TBEQ_NCOND_GOTO_ADDR,
  56        WIDE_TBEQ_NCOND_CALL_ADDR,
  57        WIDE_TBEQ_COND_GOTO1_ADDR,
  58        WIDE_TBEQ_COND_CALL1_ADDR,
  59        WIDE_TBEQ_NCOND_GOTOI_ADDR,
  60        WIDE_TBEQ_NCOND_CALL1_ADDR,
  61};
  62
  63/* SAMPLE segment */
  64#define VARI_DECIMATE_BUF1       0x0000
  65#define WRITE_BACK_BUF1          0x0400
  66#define CODEC_INPUT_BUF1         0x0500
  67#define PCM_READER_BUF1          0x0600
  68#define SRC_DELAY_BUF1           0x0680
  69#define VARI_DECIMATE_BUF0       0x0780
  70#define SRC_OUTPUT_BUF1          0x07A0
  71#define ASYNC_IP_OUTPUT_BUFFER1  0x0A00
  72#define OUTPUT_SNOOP_BUFFER      0x0B00
  73#define SPDIFI_IP_OUTPUT_BUFFER1 0x0E00
  74#define SPDIFO_IP_OUTPUT_BUFFER1 0x1000
  75#define MIX_SAMPLE_BUF1          0x1400
  76#define MIX_SAMPLE_BUF2          0x2E80
  77#define MIX_SAMPLE_BUF3          0x2F00
  78#define MIX_SAMPLE_BUF4          0x2F80
  79#define MIX_SAMPLE_BUF5          0x3000
  80
  81/* Task stack address */
  82#define HFG_STACK                0x066A
  83#define FG_STACK                 0x066E
  84#define BG_STACK                 0x068E
  85
  86/* SCB's addresses */
  87#define SPOSCB_ADDR              0x070
  88#define BG_TREE_SCB_ADDR         0x635
  89#define NULL_SCB_ADDR            0x000
  90#define TIMINGMASTER_SCB_ADDR    0x010
  91#define CODECOUT_SCB_ADDR        0x020
  92#define PCMREADER_SCB_ADDR       0x030
  93#define WRITEBACK_SCB_ADDR       0x040
  94#define CODECIN_SCB_ADDR         0x080
  95#define MASTERMIX_SCB_ADDR       0x090
  96#define SRCTASK_SCB_ADDR         0x0A0
  97#define VARIDECIMATE_SCB_ADDR    0x0B0
  98#define PCMSERIALIN_SCB_ADDR     0x0C0
  99#define FG_TASK_HEADER_ADDR      0x600
 100#define ASYNCTX_SCB_ADDR         0x0E0
 101#define ASYNCRX_SCB_ADDR         0x0F0
 102#define SRCTASKII_SCB_ADDR       0x100
 103#define OUTPUTSNOOP_SCB_ADDR     0x110
 104#define PCMSERIALINII_SCB_ADDR   0x120
 105#define SPIOWRITE_SCB_ADDR       0x130
 106#define REAR_CODECOUT_SCB_ADDR   0x140
 107#define OUTPUTSNOOPII_SCB_ADDR   0x150
 108#define PCMSERIALIN_PCM_SCB_ADDR 0x160
 109#define RECORD_MIXER_SCB_ADDR    0x170
 110#define REAR_MIXER_SCB_ADDR      0x180
 111#define CLFE_MIXER_SCB_ADDR      0x190
 112#define CLFE_CODEC_SCB_ADDR      0x1A0
 113
 114/* hyperforground SCB's*/
 115#define HFG_TREE_SCB             0xBA0
 116#define SPDIFI_SCB_INST          0xBB0
 117#define SPDIFO_SCB_INST          0xBC0
 118#define WRITE_BACK_SPB           0x0D0
 119
 120/* offsets */
 121#define AsyncCIOFIFOPointer  0xd
 122#define SPDIFOFIFOPointer    0xd
 123#define SPDIFIFIFOPointer    0xd
 124#define TCBData              0xb
 125#define HFGFlags             0xa
 126#define TCBContextBlk        0x10
 127#define AFGTxAccumPhi        0x4
 128#define SCBsubListPtr        0x9
 129#define SCBfuncEntryPtr      0xA
 130#define SRCCorPerGof         0x2
 131#define SRCPhiIncr6Int26Frac 0xd
 132#define SCBVolumeCtrl        0xe
 133
 134/* conf */
 135#define UseASER1Input 1
 136
 137
 138
 139/*
 140 * The following defines are for the flags in the rsConfig01/23 registers of
 141 * the SP.
 142 */
 143
 144#define RSCONFIG_MODULO_SIZE_MASK               0x0000000FL
 145#define RSCONFIG_MODULO_16                      0x00000001L
 146#define RSCONFIG_MODULO_32                      0x00000002L
 147#define RSCONFIG_MODULO_64                      0x00000003L
 148#define RSCONFIG_MODULO_128                     0x00000004L
 149#define RSCONFIG_MODULO_256                     0x00000005L
 150#define RSCONFIG_MODULO_512                     0x00000006L
 151#define RSCONFIG_MODULO_1024                    0x00000007L
 152#define RSCONFIG_MODULO_4                       0x00000008L
 153#define RSCONFIG_MODULO_8                       0x00000009L
 154#define RSCONFIG_SAMPLE_SIZE_MASK               0x000000C0L
 155#define RSCONFIG_SAMPLE_8MONO                   0x00000000L
 156#define RSCONFIG_SAMPLE_8STEREO                 0x00000040L
 157#define RSCONFIG_SAMPLE_16MONO                  0x00000080L
 158#define RSCONFIG_SAMPLE_16STEREO                0x000000C0L
 159#define RSCONFIG_UNDERRUN_ZERO                  0x00004000L
 160#define RSCONFIG_DMA_TO_HOST                    0x00008000L
 161#define RSCONFIG_STREAM_NUM_MASK                0x00FF0000L
 162#define RSCONFIG_MAX_DMA_SIZE_MASK              0x1F000000L
 163#define RSCONFIG_DMA_ENABLE                     0x20000000L
 164#define RSCONFIG_PRIORITY_MASK                  0xC0000000L
 165#define RSCONFIG_PRIORITY_HIGH                  0x00000000L
 166#define RSCONFIG_PRIORITY_MEDIUM_HIGH           0x40000000L
 167#define RSCONFIG_PRIORITY_MEDIUM_LOW            0x80000000L
 168#define RSCONFIG_PRIORITY_LOW                   0xC0000000L
 169#define RSCONFIG_STREAM_NUM_SHIFT               16L
 170#define RSCONFIG_MAX_DMA_SIZE_SHIFT             24L
 171
 172/* SP constants */
 173#define FG_INTERVAL_TIMER_PERIOD                0x0051
 174#define BG_INTERVAL_TIMER_PERIOD                0x0100
 175
 176
 177/* Only SP accessible registers */
 178#define SP_ASER_COUNTDOWN 0x8040
 179#define SP_SPDOUT_FIFO    0x0108
 180#define SP_SPDIN_MI_FIFO  0x01E0
 181#define SP_SPDIN_D_FIFO   0x01F0
 182#define SP_SPDIN_STATUS   0x8048
 183#define SP_SPDIN_CONTROL  0x8049
 184#define SP_SPDIN_FIFOPTR  0x804A
 185#define SP_SPDOUT_STATUS  0x804C
 186#define SP_SPDOUT_CONTROL 0x804D
 187#define SP_SPDOUT_CSUV    0x808E
 188
 189static inline u8 _wrap_all_bits (u8 val)
 190{
 191        u8 wrapped;
 192        
 193        /* wrap all 8 bits */
 194        wrapped = 
 195                ((val & 0x1 ) << 7) |
 196                ((val & 0x2 ) << 5) |
 197                ((val & 0x4 ) << 3) |
 198                ((val & 0x8 ) << 1) |
 199                ((val & 0x10) >> 1) |
 200                ((val & 0x20) >> 3) |
 201                ((val & 0x40) >> 5) |
 202                ((val & 0x80) >> 7);
 203
 204        return wrapped;
 205}
 206
 207static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip,
 208                                               struct dsp_scb_descriptor * scb) 
 209{
 210        /* update nextSCB and subListPtr in SCB */
 211        snd_cs46xx_poke(chip,
 212                        (scb->address + SCBsubListPtr) << 2,
 213                        (scb->sub_list_ptr->address << 0x10) |
 214                        (scb->next_scb_ptr->address));  
 215        scb->updated = 1;
 216}
 217
 218static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,
 219                                              struct dsp_scb_descriptor * scb,
 220                                              u16 left, u16 right)
 221{
 222        unsigned int val = ((0xffff - left) << 16 | (0xffff - right));
 223
 224        snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
 225        snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
 226        scb->volume_set = 1;
 227        scb->volume[0] = left;
 228        scb->volume[1] = right;
 229}
 230#endif /* __DSP_SPOS_H__ */
 231#endif /* CONFIG_SND_CS46XX_NEW_DSP  */
 232