217 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2/*3 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards4 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>5 */6 7/*8 * 2002-07 Benny Sjostrand benny@hostmobility.com9 */10 11#ifdef CONFIG_SND_CS46XX_NEW_DSP /* hack ... */12#ifndef __DSP_SPOS_H__13#define __DSP_SPOS_H__14 15#define DSP_MAX_SYMBOLS 102416#define DSP_MAX_MODULES 6417 18#define DSP_CODE_BYTE_SIZE 0x00007000UL19#define DSP_PARAMETER_BYTE_SIZE 0x00003000UL20#define DSP_SAMPLE_BYTE_SIZE 0x00003800UL21#define DSP_PARAMETER_BYTE_OFFSET 0x00000000UL22#define DSP_SAMPLE_BYTE_OFFSET 0x00010000UL23#define DSP_CODE_BYTE_OFFSET 0x00020000UL24 25#define WIDE_INSTR_MASK 0x004026#define WIDE_LADD_INSTR_MASK 0x038027 28/* this instruction types29 needs to be reallocated when load30 code into DSP */31enum wide_opcode {32 WIDE_FOR_BEGIN_LOOP = 0x20,33 WIDE_FOR_BEGIN_LOOP2,34 35 WIDE_COND_GOTO_ADDR = 0x30,36 WIDE_COND_GOTO_CALL,37 38 WIDE_TBEQ_COND_GOTO_ADDR = 0x70,39 WIDE_TBEQ_COND_CALL_ADDR,40 WIDE_TBEQ_NCOND_GOTO_ADDR,41 WIDE_TBEQ_NCOND_CALL_ADDR,42 WIDE_TBEQ_COND_GOTO1_ADDR,43 WIDE_TBEQ_COND_CALL1_ADDR,44 WIDE_TBEQ_NCOND_GOTOI_ADDR,45 WIDE_TBEQ_NCOND_CALL1_ADDR,46};47 48/* SAMPLE segment */49#define VARI_DECIMATE_BUF1 0x000050#define WRITE_BACK_BUF1 0x040051#define CODEC_INPUT_BUF1 0x050052#define PCM_READER_BUF1 0x060053#define SRC_DELAY_BUF1 0x068054#define VARI_DECIMATE_BUF0 0x078055#define SRC_OUTPUT_BUF1 0x07A056#define ASYNC_IP_OUTPUT_BUFFER1 0x0A0057#define OUTPUT_SNOOP_BUFFER 0x0B0058#define SPDIFI_IP_OUTPUT_BUFFER1 0x0E0059#define SPDIFO_IP_OUTPUT_BUFFER1 0x100060#define MIX_SAMPLE_BUF1 0x140061#define MIX_SAMPLE_BUF2 0x2E8062#define MIX_SAMPLE_BUF3 0x2F0063#define MIX_SAMPLE_BUF4 0x2F8064#define MIX_SAMPLE_BUF5 0x300065 66/* Task stack address */67#define HFG_STACK 0x066A68#define FG_STACK 0x066E69#define BG_STACK 0x068E70 71/* SCB's addresses */72#define SPOSCB_ADDR 0x07073#define BG_TREE_SCB_ADDR 0x63574#define NULL_SCB_ADDR 0x00075#define TIMINGMASTER_SCB_ADDR 0x01076#define CODECOUT_SCB_ADDR 0x02077#define PCMREADER_SCB_ADDR 0x03078#define WRITEBACK_SCB_ADDR 0x04079#define CODECIN_SCB_ADDR 0x08080#define MASTERMIX_SCB_ADDR 0x09081#define SRCTASK_SCB_ADDR 0x0A082#define VARIDECIMATE_SCB_ADDR 0x0B083#define PCMSERIALIN_SCB_ADDR 0x0C084#define FG_TASK_HEADER_ADDR 0x60085#define ASYNCTX_SCB_ADDR 0x0E086#define ASYNCRX_SCB_ADDR 0x0F087#define SRCTASKII_SCB_ADDR 0x10088#define OUTPUTSNOOP_SCB_ADDR 0x11089#define PCMSERIALINII_SCB_ADDR 0x12090#define SPIOWRITE_SCB_ADDR 0x13091#define REAR_CODECOUT_SCB_ADDR 0x14092#define OUTPUTSNOOPII_SCB_ADDR 0x15093#define PCMSERIALIN_PCM_SCB_ADDR 0x16094#define RECORD_MIXER_SCB_ADDR 0x17095#define REAR_MIXER_SCB_ADDR 0x18096#define CLFE_MIXER_SCB_ADDR 0x19097#define CLFE_CODEC_SCB_ADDR 0x1A098 99/* hyperforground SCB's*/100#define HFG_TREE_SCB 0xBA0101#define SPDIFI_SCB_INST 0xBB0102#define SPDIFO_SCB_INST 0xBC0103#define WRITE_BACK_SPB 0x0D0104 105/* offsets */106#define AsyncCIOFIFOPointer 0xd107#define SPDIFOFIFOPointer 0xd108#define SPDIFIFIFOPointer 0xd109#define TCBData 0xb110#define HFGFlags 0xa111#define TCBContextBlk 0x10112#define AFGTxAccumPhi 0x4113#define SCBsubListPtr 0x9114#define SCBfuncEntryPtr 0xA115#define SRCCorPerGof 0x2116#define SRCPhiIncr6Int26Frac 0xd117#define SCBVolumeCtrl 0xe118 119/* conf */120#define UseASER1Input 1121 122 123 124/*125 * The following defines are for the flags in the rsConfig01/23 registers of126 * the SP.127 */128 129#define RSCONFIG_MODULO_SIZE_MASK 0x0000000FL130#define RSCONFIG_MODULO_16 0x00000001L131#define RSCONFIG_MODULO_32 0x00000002L132#define RSCONFIG_MODULO_64 0x00000003L133#define RSCONFIG_MODULO_128 0x00000004L134#define RSCONFIG_MODULO_256 0x00000005L135#define RSCONFIG_MODULO_512 0x00000006L136#define RSCONFIG_MODULO_1024 0x00000007L137#define RSCONFIG_MODULO_4 0x00000008L138#define RSCONFIG_MODULO_8 0x00000009L139#define RSCONFIG_SAMPLE_SIZE_MASK 0x000000C0L140#define RSCONFIG_SAMPLE_8MONO 0x00000000L141#define RSCONFIG_SAMPLE_8STEREO 0x00000040L142#define RSCONFIG_SAMPLE_16MONO 0x00000080L143#define RSCONFIG_SAMPLE_16STEREO 0x000000C0L144#define RSCONFIG_UNDERRUN_ZERO 0x00004000L145#define RSCONFIG_DMA_TO_HOST 0x00008000L146#define RSCONFIG_STREAM_NUM_MASK 0x00FF0000L147#define RSCONFIG_MAX_DMA_SIZE_MASK 0x1F000000L148#define RSCONFIG_DMA_ENABLE 0x20000000L149#define RSCONFIG_PRIORITY_MASK 0xC0000000L150#define RSCONFIG_PRIORITY_HIGH 0x00000000L151#define RSCONFIG_PRIORITY_MEDIUM_HIGH 0x40000000L152#define RSCONFIG_PRIORITY_MEDIUM_LOW 0x80000000L153#define RSCONFIG_PRIORITY_LOW 0xC0000000L154#define RSCONFIG_STREAM_NUM_SHIFT 16L155#define RSCONFIG_MAX_DMA_SIZE_SHIFT 24L156 157/* SP constants */158#define FG_INTERVAL_TIMER_PERIOD 0x0051159#define BG_INTERVAL_TIMER_PERIOD 0x0100160 161 162/* Only SP accessible registers */163#define SP_ASER_COUNTDOWN 0x8040164#define SP_SPDOUT_FIFO 0x0108165#define SP_SPDIN_MI_FIFO 0x01E0166#define SP_SPDIN_D_FIFO 0x01F0167#define SP_SPDIN_STATUS 0x8048168#define SP_SPDIN_CONTROL 0x8049169#define SP_SPDIN_FIFOPTR 0x804A170#define SP_SPDOUT_STATUS 0x804C171#define SP_SPDOUT_CONTROL 0x804D172#define SP_SPDOUT_CSUV 0x808E173 174static inline u8 _wrap_all_bits (u8 val)175{176 u8 wrapped;177 178 /* wrap all 8 bits */179 wrapped = 180 ((val & 0x1 ) << 7) |181 ((val & 0x2 ) << 5) |182 ((val & 0x4 ) << 3) |183 ((val & 0x8 ) << 1) |184 ((val & 0x10) >> 1) |185 ((val & 0x20) >> 3) |186 ((val & 0x40) >> 5) |187 ((val & 0x80) >> 7);188 189 return wrapped;190}191 192static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip,193 struct dsp_scb_descriptor * scb) 194{195 /* update nextSCB and subListPtr in SCB */196 snd_cs46xx_poke(chip,197 (scb->address + SCBsubListPtr) << 2,198 (scb->sub_list_ptr->address << 0x10) |199 (scb->next_scb_ptr->address)); 200 scb->updated = 1;201}202 203static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,204 struct dsp_scb_descriptor * scb,205 u16 left, u16 right)206{207 unsigned int val = ((0xffff - left) << 16 | (0xffff - right));208 209 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);210 snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);211 scb->volume_set = 1;212 scb->volume[0] = left;213 scb->volume[1] = right;214}215#endif /* __DSP_SPOS_H__ */216#endif /* CONFIG_SND_CS46XX_NEW_DSP */217