Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Driver for Digigram pcxhr soundcards |
| 3 | * |
| 4 | * main header file |
| 5 | * |
| 6 | * Copyright (c) 2004 by Digigram <alsa@digigram.com> |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. |
| 12 | * |
| 13 | * This program is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | * GNU General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU General Public License |
| 19 | * along with this program; if not, write to the Free Software |
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 | */ |
| 22 | |
| 23 | #ifndef __SOUND_PCXHR_H |
| 24 | #define __SOUND_PCXHR_H |
| 25 | |
| 26 | #include <linux/interrupt.h> |
Ingo Molnar | 62932df | 2006-01-16 16:34:20 +0100 | [diff] [blame] | 27 | #include <linux/mutex.h> |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 28 | #include <sound/pcm.h> |
| 29 | |
Markus Bollinger | 55aef45 | 2009-01-23 14:45:41 +0100 | [diff] [blame] | 30 | #define PCXHR_DRIVER_VERSION 0x000906 /* 0.9.6 */ |
| 31 | #define PCXHR_DRIVER_VERSION_STRING "0.9.6" /* 0.9.6 */ |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 32 | |
| 33 | |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 34 | #define PCXHR_MAX_CARDS 6 |
| 35 | #define PCXHR_PLAYBACK_STREAMS 4 |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 36 | |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 37 | #define PCXHR_GRANULARITY 96 /* min 96 and multiple of 48 */ |
| 38 | /* transfer granularity of pipes and the dsp time (MBOX4) */ |
| 39 | #define PCXHR_GRANULARITY_MIN 96 |
| 40 | /* TODO : granularity could be 64 or 128 */ |
| 41 | #define PCXHR_GRANULARITY_HR22 192 /* granularity for stereo cards */ |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 42 | |
| 43 | struct snd_pcxhr; |
| 44 | struct pcxhr_mgr; |
| 45 | |
| 46 | struct pcxhr_stream; |
| 47 | struct pcxhr_pipe; |
| 48 | |
| 49 | enum pcxhr_clock_type { |
| 50 | PCXHR_CLOCK_TYPE_INTERNAL = 0, |
| 51 | PCXHR_CLOCK_TYPE_WORD_CLOCK, |
| 52 | PCXHR_CLOCK_TYPE_AES_SYNC, |
| 53 | PCXHR_CLOCK_TYPE_AES_1, |
| 54 | PCXHR_CLOCK_TYPE_AES_2, |
| 55 | PCXHR_CLOCK_TYPE_AES_3, |
| 56 | PCXHR_CLOCK_TYPE_AES_4, |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 57 | PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4, |
| 58 | HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL, |
| 59 | HR22_CLOCK_TYPE_AES_SYNC, |
| 60 | HR22_CLOCK_TYPE_AES_1, |
| 61 | HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1, |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 62 | }; |
| 63 | |
| 64 | struct pcxhr_mgr { |
| 65 | unsigned int num_cards; |
| 66 | struct snd_pcxhr *chip[PCXHR_MAX_CARDS]; |
| 67 | |
| 68 | struct pci_dev *pci; |
| 69 | |
| 70 | int irq; |
| 71 | |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 72 | int granularity; |
| 73 | |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 74 | /* card access with 1 mem bar and 2 io bar's */ |
| 75 | unsigned long port[3]; |
| 76 | |
| 77 | /* share the name */ |
| 78 | char shortname[32]; /* short name of this soundcard */ |
| 79 | char longname[96]; /* name of this soundcard */ |
| 80 | |
| 81 | /* message tasklet */ |
| 82 | struct tasklet_struct msg_taskq; |
| 83 | struct pcxhr_rmh *prmh; |
| 84 | /* trigger tasklet */ |
| 85 | struct tasklet_struct trigger_taskq; |
| 86 | |
| 87 | spinlock_t lock; /* interrupt spinlock */ |
| 88 | spinlock_t msg_lock; /* message spinlock */ |
| 89 | |
Ingo Molnar | 62932df | 2006-01-16 16:34:20 +0100 | [diff] [blame] | 90 | struct mutex setup_mutex; /* mutex used in hw_params, open and close */ |
| 91 | struct mutex mixer_mutex; /* mutex for mixer */ |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 92 | |
| 93 | /* hardware interface */ |
| 94 | unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ |
| 95 | unsigned int dsp_version; /* read from embedded once firmware is loaded */ |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 96 | int playback_chips; |
| 97 | int capture_chips; |
| 98 | int fw_file_set; |
| 99 | int firmware_num; |
Harvey Harrison | e32740d978 | 2009-02-19 11:58:37 -0800 | [diff] [blame] | 100 | unsigned int is_hr_stereo:1; |
| 101 | unsigned int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */ |
| 102 | unsigned int board_has_analog:1; /* if 0 the board is digital only */ |
| 103 | unsigned int board_has_mic:1; /* if 1 the board has microphone input */ |
| 104 | unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ |
| 105 | unsigned int mono_capture:1; /* if 1 the board does mono capture */ |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 106 | |
| 107 | struct snd_dma_buffer hostport; |
| 108 | |
| 109 | enum pcxhr_clock_type use_clock_type; /* clock type selected by mixer */ |
| 110 | enum pcxhr_clock_type cur_clock_type; /* current clock type synced */ |
| 111 | int sample_rate; |
| 112 | int ref_count_rate; |
| 113 | int timer_toggle; /* timer interrupt toggles between the two values 0x200 and 0x300 */ |
| 114 | int dsp_time_last; /* the last dsp time (read by interrupt) */ |
| 115 | int dsp_time_err; /* dsp time errors */ |
| 116 | unsigned int src_it_dsp; /* dsp interrupt source */ |
| 117 | unsigned int io_num_reg_cont; /* backup of IO_NUM_REG_CONT */ |
| 118 | unsigned int codec_speed; /* speed mode of the codecs */ |
| 119 | unsigned int sample_rate_real; /* current real sample rate */ |
| 120 | int last_reg_stat; |
| 121 | int async_err_stream_xrun; |
| 122 | int async_err_pipe_xrun; |
| 123 | int async_err_other_last; |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 124 | |
| 125 | unsigned char xlx_cfg; /* copy of PCXHR_XLX_CFG register */ |
| 126 | unsigned char xlx_selmic; /* copy of PCXHR_XLX_SELMIC register */ |
Markus Bollinger | 55aef45 | 2009-01-23 14:45:41 +0100 | [diff] [blame] | 127 | unsigned char dsp_reset; /* copy of PCXHR_DSP_RESET register */ |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 128 | }; |
| 129 | |
| 130 | |
| 131 | enum pcxhr_stream_status { |
| 132 | PCXHR_STREAM_STATUS_FREE, |
| 133 | PCXHR_STREAM_STATUS_OPEN, |
| 134 | PCXHR_STREAM_STATUS_SCHEDULE_RUN, |
| 135 | PCXHR_STREAM_STATUS_STARTED, |
| 136 | PCXHR_STREAM_STATUS_RUNNING, |
| 137 | PCXHR_STREAM_STATUS_SCHEDULE_STOP, |
| 138 | PCXHR_STREAM_STATUS_STOPPED, |
| 139 | PCXHR_STREAM_STATUS_PAUSED |
| 140 | }; |
| 141 | |
| 142 | struct pcxhr_stream { |
| 143 | struct snd_pcm_substream *substream; |
| 144 | snd_pcm_format_t format; |
| 145 | struct pcxhr_pipe *pipe; |
| 146 | |
| 147 | enum pcxhr_stream_status status; /* free, open, running, draining, pause */ |
| 148 | |
| 149 | u_int64_t timer_abs_periods; /* timer: samples elapsed since TRIGGER_START (multiple of period_size) */ |
| 150 | u_int32_t timer_period_frag; /* timer: samples elapsed since last call to snd_pcm_period_elapsed (0..period_size) */ |
| 151 | u_int32_t timer_buf_periods; /* nb of periods in the buffer that have already elapsed */ |
| 152 | int timer_is_synced; /* if(0) : timer needs to be resynced with real hardware pointer */ |
| 153 | |
| 154 | int channels; |
| 155 | }; |
| 156 | |
| 157 | |
| 158 | enum pcxhr_pipe_status { |
| 159 | PCXHR_PIPE_UNDEFINED, |
| 160 | PCXHR_PIPE_DEFINED |
| 161 | }; |
| 162 | |
| 163 | struct pcxhr_pipe { |
| 164 | enum pcxhr_pipe_status status; |
| 165 | int is_capture; /* this is a capture pipe */ |
| 166 | int first_audio; /* first audio num */ |
| 167 | }; |
| 168 | |
| 169 | |
| 170 | struct snd_pcxhr { |
| 171 | struct snd_card *card; |
| 172 | struct pcxhr_mgr *mgr; |
| 173 | int chip_idx; /* zero based */ |
| 174 | |
| 175 | struct snd_pcm *pcm; /* PCM */ |
| 176 | |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 177 | struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */ |
| 178 | struct pcxhr_pipe capture_pipe[2]; /* 1 stereo or 2 mono pipes */ |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 179 | |
| 180 | struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS]; |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 181 | struct pcxhr_stream capture_stream[2]; /* 1 stereo or 2 mono streams */ |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 182 | int nb_streams_play; |
| 183 | int nb_streams_capt; |
| 184 | |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 185 | int analog_playback_active[2]; /* Mixer : Master Playback !mute */ |
| 186 | int analog_playback_volume[2]; /* Mixer : Master Playback Volume */ |
| 187 | int analog_capture_volume[2]; /* Mixer : Master Capture Volume */ |
| 188 | int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2]; |
| 189 | int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2]; |
| 190 | int digital_capture_volume[2]; /* Mixer : Digital Capture Volume */ |
| 191 | int monitoring_active[2]; /* Mixer : Monitoring Active */ |
| 192 | int monitoring_volume[2]; /* Mixer : Monitoring Volume */ |
| 193 | int audio_capture_source; /* Mixer : Audio Capture Source */ |
| 194 | int mic_volume; /* used by cards with MIC only */ |
| 195 | int mic_boost; /* used by cards with MIC only */ |
| 196 | int mic_active; /* used by cards with MIC only */ |
| 197 | int analog_capture_active; /* used by cards with MIC only */ |
| 198 | int phantom_power; /* used by cards with MIC only */ |
| 199 | |
| 200 | unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */ |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 201 | }; |
| 202 | |
| 203 | struct pcxhr_hostport |
| 204 | { |
| 205 | char purgebuffer[6]; |
| 206 | char reserved[2]; |
| 207 | }; |
| 208 | |
| 209 | /* exported */ |
| 210 | int pcxhr_create_pcm(struct snd_pcxhr *chip); |
| 211 | int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate); |
Markus Bollinger | 9d948d2 | 2008-11-25 12:24:54 +0100 | [diff] [blame] | 212 | int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, |
| 213 | enum pcxhr_clock_type clock_type, |
| 214 | int *sample_rate); |
Markus Bollinger | e12229b | 2005-12-06 13:55:26 +0100 | [diff] [blame] | 215 | |
| 216 | #endif /* __SOUND_PCXHR_H */ |