162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards 462306a36Sopenharmony_ci * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci/* 862306a36Sopenharmony_ci * 2002-07 Benny Sjostrand benny@hostmobility.com 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#ifdef CONFIG_SND_CS46XX_NEW_DSP /* hack ... */ 1262306a36Sopenharmony_ci#ifndef __DSP_SPOS_H__ 1362306a36Sopenharmony_ci#define __DSP_SPOS_H__ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#define DSP_MAX_SYMBOLS 1024 1662306a36Sopenharmony_ci#define DSP_MAX_MODULES 64 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define DSP_CODE_BYTE_SIZE 0x00007000UL 1962306a36Sopenharmony_ci#define DSP_PARAMETER_BYTE_SIZE 0x00003000UL 2062306a36Sopenharmony_ci#define DSP_SAMPLE_BYTE_SIZE 0x00003800UL 2162306a36Sopenharmony_ci#define DSP_PARAMETER_BYTE_OFFSET 0x00000000UL 2262306a36Sopenharmony_ci#define DSP_SAMPLE_BYTE_OFFSET 0x00010000UL 2362306a36Sopenharmony_ci#define DSP_CODE_BYTE_OFFSET 0x00020000UL 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define WIDE_INSTR_MASK 0x0040 2662306a36Sopenharmony_ci#define WIDE_LADD_INSTR_MASK 0x0380 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* this instruction types 2962306a36Sopenharmony_ci needs to be reallocated when load 3062306a36Sopenharmony_ci code into DSP */ 3162306a36Sopenharmony_cienum wide_opcode { 3262306a36Sopenharmony_ci WIDE_FOR_BEGIN_LOOP = 0x20, 3362306a36Sopenharmony_ci WIDE_FOR_BEGIN_LOOP2, 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci WIDE_COND_GOTO_ADDR = 0x30, 3662306a36Sopenharmony_ci WIDE_COND_GOTO_CALL, 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci WIDE_TBEQ_COND_GOTO_ADDR = 0x70, 3962306a36Sopenharmony_ci WIDE_TBEQ_COND_CALL_ADDR, 4062306a36Sopenharmony_ci WIDE_TBEQ_NCOND_GOTO_ADDR, 4162306a36Sopenharmony_ci WIDE_TBEQ_NCOND_CALL_ADDR, 4262306a36Sopenharmony_ci WIDE_TBEQ_COND_GOTO1_ADDR, 4362306a36Sopenharmony_ci WIDE_TBEQ_COND_CALL1_ADDR, 4462306a36Sopenharmony_ci WIDE_TBEQ_NCOND_GOTOI_ADDR, 4562306a36Sopenharmony_ci WIDE_TBEQ_NCOND_CALL1_ADDR, 4662306a36Sopenharmony_ci}; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci/* SAMPLE segment */ 4962306a36Sopenharmony_ci#define VARI_DECIMATE_BUF1 0x0000 5062306a36Sopenharmony_ci#define WRITE_BACK_BUF1 0x0400 5162306a36Sopenharmony_ci#define CODEC_INPUT_BUF1 0x0500 5262306a36Sopenharmony_ci#define PCM_READER_BUF1 0x0600 5362306a36Sopenharmony_ci#define SRC_DELAY_BUF1 0x0680 5462306a36Sopenharmony_ci#define VARI_DECIMATE_BUF0 0x0780 5562306a36Sopenharmony_ci#define SRC_OUTPUT_BUF1 0x07A0 5662306a36Sopenharmony_ci#define ASYNC_IP_OUTPUT_BUFFER1 0x0A00 5762306a36Sopenharmony_ci#define OUTPUT_SNOOP_BUFFER 0x0B00 5862306a36Sopenharmony_ci#define SPDIFI_IP_OUTPUT_BUFFER1 0x0E00 5962306a36Sopenharmony_ci#define SPDIFO_IP_OUTPUT_BUFFER1 0x1000 6062306a36Sopenharmony_ci#define MIX_SAMPLE_BUF1 0x1400 6162306a36Sopenharmony_ci#define MIX_SAMPLE_BUF2 0x2E80 6262306a36Sopenharmony_ci#define MIX_SAMPLE_BUF3 0x2F00 6362306a36Sopenharmony_ci#define MIX_SAMPLE_BUF4 0x2F80 6462306a36Sopenharmony_ci#define MIX_SAMPLE_BUF5 0x3000 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* Task stack address */ 6762306a36Sopenharmony_ci#define HFG_STACK 0x066A 6862306a36Sopenharmony_ci#define FG_STACK 0x066E 6962306a36Sopenharmony_ci#define BG_STACK 0x068E 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* SCB's addresses */ 7262306a36Sopenharmony_ci#define SPOSCB_ADDR 0x070 7362306a36Sopenharmony_ci#define BG_TREE_SCB_ADDR 0x635 7462306a36Sopenharmony_ci#define NULL_SCB_ADDR 0x000 7562306a36Sopenharmony_ci#define TIMINGMASTER_SCB_ADDR 0x010 7662306a36Sopenharmony_ci#define CODECOUT_SCB_ADDR 0x020 7762306a36Sopenharmony_ci#define PCMREADER_SCB_ADDR 0x030 7862306a36Sopenharmony_ci#define WRITEBACK_SCB_ADDR 0x040 7962306a36Sopenharmony_ci#define CODECIN_SCB_ADDR 0x080 8062306a36Sopenharmony_ci#define MASTERMIX_SCB_ADDR 0x090 8162306a36Sopenharmony_ci#define SRCTASK_SCB_ADDR 0x0A0 8262306a36Sopenharmony_ci#define VARIDECIMATE_SCB_ADDR 0x0B0 8362306a36Sopenharmony_ci#define PCMSERIALIN_SCB_ADDR 0x0C0 8462306a36Sopenharmony_ci#define FG_TASK_HEADER_ADDR 0x600 8562306a36Sopenharmony_ci#define ASYNCTX_SCB_ADDR 0x0E0 8662306a36Sopenharmony_ci#define ASYNCRX_SCB_ADDR 0x0F0 8762306a36Sopenharmony_ci#define SRCTASKII_SCB_ADDR 0x100 8862306a36Sopenharmony_ci#define OUTPUTSNOOP_SCB_ADDR 0x110 8962306a36Sopenharmony_ci#define PCMSERIALINII_SCB_ADDR 0x120 9062306a36Sopenharmony_ci#define SPIOWRITE_SCB_ADDR 0x130 9162306a36Sopenharmony_ci#define REAR_CODECOUT_SCB_ADDR 0x140 9262306a36Sopenharmony_ci#define OUTPUTSNOOPII_SCB_ADDR 0x150 9362306a36Sopenharmony_ci#define PCMSERIALIN_PCM_SCB_ADDR 0x160 9462306a36Sopenharmony_ci#define RECORD_MIXER_SCB_ADDR 0x170 9562306a36Sopenharmony_ci#define REAR_MIXER_SCB_ADDR 0x180 9662306a36Sopenharmony_ci#define CLFE_MIXER_SCB_ADDR 0x190 9762306a36Sopenharmony_ci#define CLFE_CODEC_SCB_ADDR 0x1A0 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci/* hyperforground SCB's*/ 10062306a36Sopenharmony_ci#define HFG_TREE_SCB 0xBA0 10162306a36Sopenharmony_ci#define SPDIFI_SCB_INST 0xBB0 10262306a36Sopenharmony_ci#define SPDIFO_SCB_INST 0xBC0 10362306a36Sopenharmony_ci#define WRITE_BACK_SPB 0x0D0 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* offsets */ 10662306a36Sopenharmony_ci#define AsyncCIOFIFOPointer 0xd 10762306a36Sopenharmony_ci#define SPDIFOFIFOPointer 0xd 10862306a36Sopenharmony_ci#define SPDIFIFIFOPointer 0xd 10962306a36Sopenharmony_ci#define TCBData 0xb 11062306a36Sopenharmony_ci#define HFGFlags 0xa 11162306a36Sopenharmony_ci#define TCBContextBlk 0x10 11262306a36Sopenharmony_ci#define AFGTxAccumPhi 0x4 11362306a36Sopenharmony_ci#define SCBsubListPtr 0x9 11462306a36Sopenharmony_ci#define SCBfuncEntryPtr 0xA 11562306a36Sopenharmony_ci#define SRCCorPerGof 0x2 11662306a36Sopenharmony_ci#define SRCPhiIncr6Int26Frac 0xd 11762306a36Sopenharmony_ci#define SCBVolumeCtrl 0xe 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/* conf */ 12062306a36Sopenharmony_ci#define UseASER1Input 1 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci/* 12562306a36Sopenharmony_ci * The following defines are for the flags in the rsConfig01/23 registers of 12662306a36Sopenharmony_ci * the SP. 12762306a36Sopenharmony_ci */ 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci#define RSCONFIG_MODULO_SIZE_MASK 0x0000000FL 13062306a36Sopenharmony_ci#define RSCONFIG_MODULO_16 0x00000001L 13162306a36Sopenharmony_ci#define RSCONFIG_MODULO_32 0x00000002L 13262306a36Sopenharmony_ci#define RSCONFIG_MODULO_64 0x00000003L 13362306a36Sopenharmony_ci#define RSCONFIG_MODULO_128 0x00000004L 13462306a36Sopenharmony_ci#define RSCONFIG_MODULO_256 0x00000005L 13562306a36Sopenharmony_ci#define RSCONFIG_MODULO_512 0x00000006L 13662306a36Sopenharmony_ci#define RSCONFIG_MODULO_1024 0x00000007L 13762306a36Sopenharmony_ci#define RSCONFIG_MODULO_4 0x00000008L 13862306a36Sopenharmony_ci#define RSCONFIG_MODULO_8 0x00000009L 13962306a36Sopenharmony_ci#define RSCONFIG_SAMPLE_SIZE_MASK 0x000000C0L 14062306a36Sopenharmony_ci#define RSCONFIG_SAMPLE_8MONO 0x00000000L 14162306a36Sopenharmony_ci#define RSCONFIG_SAMPLE_8STEREO 0x00000040L 14262306a36Sopenharmony_ci#define RSCONFIG_SAMPLE_16MONO 0x00000080L 14362306a36Sopenharmony_ci#define RSCONFIG_SAMPLE_16STEREO 0x000000C0L 14462306a36Sopenharmony_ci#define RSCONFIG_UNDERRUN_ZERO 0x00004000L 14562306a36Sopenharmony_ci#define RSCONFIG_DMA_TO_HOST 0x00008000L 14662306a36Sopenharmony_ci#define RSCONFIG_STREAM_NUM_MASK 0x00FF0000L 14762306a36Sopenharmony_ci#define RSCONFIG_MAX_DMA_SIZE_MASK 0x1F000000L 14862306a36Sopenharmony_ci#define RSCONFIG_DMA_ENABLE 0x20000000L 14962306a36Sopenharmony_ci#define RSCONFIG_PRIORITY_MASK 0xC0000000L 15062306a36Sopenharmony_ci#define RSCONFIG_PRIORITY_HIGH 0x00000000L 15162306a36Sopenharmony_ci#define RSCONFIG_PRIORITY_MEDIUM_HIGH 0x40000000L 15262306a36Sopenharmony_ci#define RSCONFIG_PRIORITY_MEDIUM_LOW 0x80000000L 15362306a36Sopenharmony_ci#define RSCONFIG_PRIORITY_LOW 0xC0000000L 15462306a36Sopenharmony_ci#define RSCONFIG_STREAM_NUM_SHIFT 16L 15562306a36Sopenharmony_ci#define RSCONFIG_MAX_DMA_SIZE_SHIFT 24L 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci/* SP constants */ 15862306a36Sopenharmony_ci#define FG_INTERVAL_TIMER_PERIOD 0x0051 15962306a36Sopenharmony_ci#define BG_INTERVAL_TIMER_PERIOD 0x0100 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci/* Only SP accessible registers */ 16362306a36Sopenharmony_ci#define SP_ASER_COUNTDOWN 0x8040 16462306a36Sopenharmony_ci#define SP_SPDOUT_FIFO 0x0108 16562306a36Sopenharmony_ci#define SP_SPDIN_MI_FIFO 0x01E0 16662306a36Sopenharmony_ci#define SP_SPDIN_D_FIFO 0x01F0 16762306a36Sopenharmony_ci#define SP_SPDIN_STATUS 0x8048 16862306a36Sopenharmony_ci#define SP_SPDIN_CONTROL 0x8049 16962306a36Sopenharmony_ci#define SP_SPDIN_FIFOPTR 0x804A 17062306a36Sopenharmony_ci#define SP_SPDOUT_STATUS 0x804C 17162306a36Sopenharmony_ci#define SP_SPDOUT_CONTROL 0x804D 17262306a36Sopenharmony_ci#define SP_SPDOUT_CSUV 0x808E 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistatic inline u8 _wrap_all_bits (u8 val) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci u8 wrapped; 17762306a36Sopenharmony_ci 17862306a36Sopenharmony_ci /* wrap all 8 bits */ 17962306a36Sopenharmony_ci wrapped = 18062306a36Sopenharmony_ci ((val & 0x1 ) << 7) | 18162306a36Sopenharmony_ci ((val & 0x2 ) << 5) | 18262306a36Sopenharmony_ci ((val & 0x4 ) << 3) | 18362306a36Sopenharmony_ci ((val & 0x8 ) << 1) | 18462306a36Sopenharmony_ci ((val & 0x10) >> 1) | 18562306a36Sopenharmony_ci ((val & 0x20) >> 3) | 18662306a36Sopenharmony_ci ((val & 0x40) >> 5) | 18762306a36Sopenharmony_ci ((val & 0x80) >> 7); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci return wrapped; 19062306a36Sopenharmony_ci} 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_cistatic inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip, 19362306a36Sopenharmony_ci struct dsp_scb_descriptor * scb) 19462306a36Sopenharmony_ci{ 19562306a36Sopenharmony_ci /* update nextSCB and subListPtr in SCB */ 19662306a36Sopenharmony_ci snd_cs46xx_poke(chip, 19762306a36Sopenharmony_ci (scb->address + SCBsubListPtr) << 2, 19862306a36Sopenharmony_ci (scb->sub_list_ptr->address << 0x10) | 19962306a36Sopenharmony_ci (scb->next_scb_ptr->address)); 20062306a36Sopenharmony_ci scb->updated = 1; 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistatic inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip, 20462306a36Sopenharmony_ci struct dsp_scb_descriptor * scb, 20562306a36Sopenharmony_ci u16 left, u16 right) 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci unsigned int val = ((0xffff - left) << 16 | (0xffff - right)); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val); 21062306a36Sopenharmony_ci snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val); 21162306a36Sopenharmony_ci scb->volume_set = 1; 21262306a36Sopenharmony_ci scb->volume[0] = left; 21362306a36Sopenharmony_ci scb->volume[1] = right; 21462306a36Sopenharmony_ci} 21562306a36Sopenharmony_ci#endif /* __DSP_SPOS_H__ */ 21662306a36Sopenharmony_ci#endif /* CONFIG_SND_CS46XX_NEW_DSP */ 217