162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Driver for Digigram pcxhr soundcards 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * main header file 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (c) 2004 by Digigram <alsa@digigram.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#ifndef __SOUND_PCXHR_H 1162306a36Sopenharmony_ci#define __SOUND_PCXHR_H 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/interrupt.h> 1462306a36Sopenharmony_ci#include <linux/mutex.h> 1562306a36Sopenharmony_ci#include <sound/pcm.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define PCXHR_DRIVER_VERSION 0x000906 /* 0.9.6 */ 1862306a36Sopenharmony_ci#define PCXHR_DRIVER_VERSION_STRING "0.9.6" /* 0.9.6 */ 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define PCXHR_MAX_CARDS 6 2262306a36Sopenharmony_ci#define PCXHR_PLAYBACK_STREAMS 4 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#define PCXHR_GRANULARITY 96 /* min 96 and multiple of 48 */ 2562306a36Sopenharmony_ci/* transfer granularity of pipes and the dsp time (MBOX4) */ 2662306a36Sopenharmony_ci#define PCXHR_GRANULARITY_MIN 96 2762306a36Sopenharmony_ci/* TODO : granularity could be 64 or 128 */ 2862306a36Sopenharmony_ci#define PCXHR_GRANULARITY_HR22 192 /* granularity for stereo cards */ 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistruct snd_pcxhr; 3162306a36Sopenharmony_cistruct pcxhr_mgr; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_cistruct pcxhr_stream; 3462306a36Sopenharmony_cistruct pcxhr_pipe; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cienum pcxhr_clock_type { 3762306a36Sopenharmony_ci PCXHR_CLOCK_TYPE_INTERNAL = 0, 3862306a36Sopenharmony_ci PCXHR_CLOCK_TYPE_WORD_CLOCK, 3962306a36Sopenharmony_ci PCXHR_CLOCK_TYPE_AES_SYNC, 4062306a36Sopenharmony_ci PCXHR_CLOCK_TYPE_AES_1, 4162306a36Sopenharmony_ci PCXHR_CLOCK_TYPE_AES_2, 4262306a36Sopenharmony_ci PCXHR_CLOCK_TYPE_AES_3, 4362306a36Sopenharmony_ci PCXHR_CLOCK_TYPE_AES_4, 4462306a36Sopenharmony_ci PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4, 4562306a36Sopenharmony_ci HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL, 4662306a36Sopenharmony_ci HR22_CLOCK_TYPE_AES_SYNC, 4762306a36Sopenharmony_ci HR22_CLOCK_TYPE_AES_1, 4862306a36Sopenharmony_ci HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1, 4962306a36Sopenharmony_ci}; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistruct pcxhr_mgr { 5262306a36Sopenharmony_ci unsigned int num_cards; 5362306a36Sopenharmony_ci struct snd_pcxhr *chip[PCXHR_MAX_CARDS]; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci struct pci_dev *pci; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci int irq; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci int granularity; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci /* card access with 1 mem bar and 2 io bar's */ 6262306a36Sopenharmony_ci unsigned long port[3]; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci /* share the name */ 6562306a36Sopenharmony_ci char name[40]; /* name of this soundcard */ 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci struct pcxhr_rmh *prmh; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci struct mutex lock; /* interrupt lock */ 7062306a36Sopenharmony_ci struct mutex msg_lock; /* message lock */ 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci struct mutex setup_mutex; /* mutex used in hw_params, open and close */ 7362306a36Sopenharmony_ci struct mutex mixer_mutex; /* mutex for mixer */ 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci /* hardware interface */ 7662306a36Sopenharmony_ci unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ 7762306a36Sopenharmony_ci unsigned int dsp_version; /* read from embedded once firmware is loaded */ 7862306a36Sopenharmony_ci int playback_chips; 7962306a36Sopenharmony_ci int capture_chips; 8062306a36Sopenharmony_ci int fw_file_set; 8162306a36Sopenharmony_ci int firmware_num; 8262306a36Sopenharmony_ci unsigned int is_hr_stereo:1; 8362306a36Sopenharmony_ci unsigned int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */ 8462306a36Sopenharmony_ci unsigned int board_has_analog:1; /* if 0 the board is digital only */ 8562306a36Sopenharmony_ci unsigned int board_has_mic:1; /* if 1 the board has microphone input */ 8662306a36Sopenharmony_ci unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ 8762306a36Sopenharmony_ci unsigned int mono_capture:1; /* if 1 the board does mono capture */ 8862306a36Sopenharmony_ci unsigned int capture_ltc:1; /* if 1 the board captures LTC input */ 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci struct snd_dma_buffer hostport; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci enum pcxhr_clock_type use_clock_type; /* clock type selected by mixer */ 9362306a36Sopenharmony_ci enum pcxhr_clock_type cur_clock_type; /* current clock type synced */ 9462306a36Sopenharmony_ci int sample_rate; 9562306a36Sopenharmony_ci int ref_count_rate; 9662306a36Sopenharmony_ci int timer_toggle; /* timer interrupt toggles between the two values 0x200 and 0x300 */ 9762306a36Sopenharmony_ci int dsp_time_last; /* the last dsp time (read by interrupt) */ 9862306a36Sopenharmony_ci int dsp_time_err; /* dsp time errors */ 9962306a36Sopenharmony_ci unsigned int src_it_dsp; /* dsp interrupt source */ 10062306a36Sopenharmony_ci unsigned int io_num_reg_cont; /* backup of IO_NUM_REG_CONT */ 10162306a36Sopenharmony_ci unsigned int codec_speed; /* speed mode of the codecs */ 10262306a36Sopenharmony_ci unsigned int sample_rate_real; /* current real sample rate */ 10362306a36Sopenharmony_ci int last_reg_stat; 10462306a36Sopenharmony_ci int async_err_stream_xrun; 10562306a36Sopenharmony_ci int async_err_pipe_xrun; 10662306a36Sopenharmony_ci int async_err_other_last; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci unsigned char xlx_cfg; /* copy of PCXHR_XLX_CFG register */ 10962306a36Sopenharmony_ci unsigned char xlx_selmic; /* copy of PCXHR_XLX_SELMIC register */ 11062306a36Sopenharmony_ci unsigned char dsp_reset; /* copy of PCXHR_DSP_RESET register */ 11162306a36Sopenharmony_ci}; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cienum pcxhr_stream_status { 11562306a36Sopenharmony_ci PCXHR_STREAM_STATUS_FREE, 11662306a36Sopenharmony_ci PCXHR_STREAM_STATUS_OPEN, 11762306a36Sopenharmony_ci PCXHR_STREAM_STATUS_SCHEDULE_RUN, 11862306a36Sopenharmony_ci PCXHR_STREAM_STATUS_STARTED, 11962306a36Sopenharmony_ci PCXHR_STREAM_STATUS_RUNNING, 12062306a36Sopenharmony_ci PCXHR_STREAM_STATUS_SCHEDULE_STOP, 12162306a36Sopenharmony_ci PCXHR_STREAM_STATUS_STOPPED, 12262306a36Sopenharmony_ci PCXHR_STREAM_STATUS_PAUSED 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistruct pcxhr_stream { 12662306a36Sopenharmony_ci struct snd_pcm_substream *substream; 12762306a36Sopenharmony_ci snd_pcm_format_t format; 12862306a36Sopenharmony_ci struct pcxhr_pipe *pipe; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci enum pcxhr_stream_status status; /* free, open, running, draining, pause */ 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci u_int64_t timer_abs_periods; /* timer: samples elapsed since TRIGGER_START (multiple of period_size) */ 13362306a36Sopenharmony_ci u_int32_t timer_period_frag; /* timer: samples elapsed since last call to snd_pcm_period_elapsed (0..period_size) */ 13462306a36Sopenharmony_ci u_int32_t timer_buf_periods; /* nb of periods in the buffer that have already elapsed */ 13562306a36Sopenharmony_ci int timer_is_synced; /* if(0) : timer needs to be resynced with real hardware pointer */ 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci int channels; 13862306a36Sopenharmony_ci}; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cienum pcxhr_pipe_status { 14262306a36Sopenharmony_ci PCXHR_PIPE_UNDEFINED, 14362306a36Sopenharmony_ci PCXHR_PIPE_DEFINED 14462306a36Sopenharmony_ci}; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_cistruct pcxhr_pipe { 14762306a36Sopenharmony_ci enum pcxhr_pipe_status status; 14862306a36Sopenharmony_ci int is_capture; /* this is a capture pipe */ 14962306a36Sopenharmony_ci int first_audio; /* first audio num */ 15062306a36Sopenharmony_ci}; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistruct snd_pcxhr { 15462306a36Sopenharmony_ci struct snd_card *card; 15562306a36Sopenharmony_ci struct pcxhr_mgr *mgr; 15662306a36Sopenharmony_ci int chip_idx; /* zero based */ 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci struct snd_pcm *pcm; /* PCM */ 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */ 16162306a36Sopenharmony_ci struct pcxhr_pipe capture_pipe[2]; /* 1 stereo or 2 mono pipes */ 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS]; 16462306a36Sopenharmony_ci struct pcxhr_stream capture_stream[2]; /* 1 stereo or 2 mono streams */ 16562306a36Sopenharmony_ci int nb_streams_play; 16662306a36Sopenharmony_ci int nb_streams_capt; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci int analog_playback_active[2]; /* Mixer : Master Playback !mute */ 16962306a36Sopenharmony_ci int analog_playback_volume[2]; /* Mixer : Master Playback Volume */ 17062306a36Sopenharmony_ci int analog_capture_volume[2]; /* Mixer : Master Capture Volume */ 17162306a36Sopenharmony_ci int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2]; 17262306a36Sopenharmony_ci int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2]; 17362306a36Sopenharmony_ci int digital_capture_volume[2]; /* Mixer : Digital Capture Volume */ 17462306a36Sopenharmony_ci int monitoring_active[2]; /* Mixer : Monitoring Active */ 17562306a36Sopenharmony_ci int monitoring_volume[2]; /* Mixer : Monitoring Volume */ 17662306a36Sopenharmony_ci int audio_capture_source; /* Mixer : Audio Capture Source */ 17762306a36Sopenharmony_ci int mic_volume; /* used by cards with MIC only */ 17862306a36Sopenharmony_ci int mic_boost; /* used by cards with MIC only */ 17962306a36Sopenharmony_ci int mic_active; /* used by cards with MIC only */ 18062306a36Sopenharmony_ci int analog_capture_active; /* used by cards with MIC only */ 18162306a36Sopenharmony_ci int phantom_power; /* used by cards with MIC only */ 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */ 18462306a36Sopenharmony_ci}; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_cistruct pcxhr_hostport 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci char purgebuffer[6]; 18962306a36Sopenharmony_ci char reserved[2]; 19062306a36Sopenharmony_ci}; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci/* exported */ 19362306a36Sopenharmony_ciint pcxhr_create_pcm(struct snd_pcxhr *chip); 19462306a36Sopenharmony_ciint pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate); 19562306a36Sopenharmony_ciint pcxhr_get_external_clock(struct pcxhr_mgr *mgr, 19662306a36Sopenharmony_ci enum pcxhr_clock_type clock_type, 19762306a36Sopenharmony_ci int *sample_rate); 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci#endif /* __SOUND_PCXHR_H */ 200