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> |
| 27 | #include <sound/pcm.h> |
| 28 | |
| 29 | #define PCXHR_DRIVER_VERSION 0x000804 /* 0.8.4 */ |
| 30 | #define PCXHR_DRIVER_VERSION_STRING "0.8.4" /* 0.8.4 */ |
| 31 | |
| 32 | |
| 33 | #define PCXHR_MAX_CARDS 6 |
| 34 | #define PCXHR_PLAYBACK_STREAMS 4 |
| 35 | |
| 36 | #define PCXHR_GRANULARITY 96 /* transfer granularity (should be min 96 and multiple of 48) */ |
| 37 | #define PCXHR_GRANULARITY_MIN 96 /* transfer granularity of pipes and the dsp time (MBOX4) */ |
| 38 | |
| 39 | struct snd_pcxhr; |
| 40 | struct pcxhr_mgr; |
| 41 | |
| 42 | struct pcxhr_stream; |
| 43 | struct pcxhr_pipe; |
| 44 | |
| 45 | enum pcxhr_clock_type { |
| 46 | PCXHR_CLOCK_TYPE_INTERNAL = 0, |
| 47 | PCXHR_CLOCK_TYPE_WORD_CLOCK, |
| 48 | PCXHR_CLOCK_TYPE_AES_SYNC, |
| 49 | PCXHR_CLOCK_TYPE_AES_1, |
| 50 | PCXHR_CLOCK_TYPE_AES_2, |
| 51 | PCXHR_CLOCK_TYPE_AES_3, |
| 52 | PCXHR_CLOCK_TYPE_AES_4, |
| 53 | }; |
| 54 | |
| 55 | struct pcxhr_mgr { |
| 56 | unsigned int num_cards; |
| 57 | struct snd_pcxhr *chip[PCXHR_MAX_CARDS]; |
| 58 | |
| 59 | struct pci_dev *pci; |
| 60 | |
| 61 | int irq; |
| 62 | |
| 63 | /* card access with 1 mem bar and 2 io bar's */ |
| 64 | unsigned long port[3]; |
| 65 | |
| 66 | /* share the name */ |
| 67 | char shortname[32]; /* short name of this soundcard */ |
| 68 | char longname[96]; /* name of this soundcard */ |
| 69 | |
| 70 | /* message tasklet */ |
| 71 | struct tasklet_struct msg_taskq; |
| 72 | struct pcxhr_rmh *prmh; |
| 73 | /* trigger tasklet */ |
| 74 | struct tasklet_struct trigger_taskq; |
| 75 | |
| 76 | spinlock_t lock; /* interrupt spinlock */ |
| 77 | spinlock_t msg_lock; /* message spinlock */ |
| 78 | |
| 79 | struct semaphore setup_mutex; /* mutex used in hw_params, open and close */ |
| 80 | struct semaphore mixer_mutex; /* mutex for mixer */ |
| 81 | |
| 82 | /* hardware interface */ |
| 83 | unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ |
| 84 | unsigned int dsp_version; /* read from embedded once firmware is loaded */ |
| 85 | int board_has_analog; /* if 0 the board is digital only */ |
| 86 | int mono_capture; /* if 1 the board does mono capture */ |
| 87 | int playback_chips; /* 4 or 6 */ |
| 88 | int capture_chips; /* 4 or 1 */ |
| 89 | int firmware_num; /* 41 or 42 */ |
| 90 | |
| 91 | struct snd_dma_buffer hostport; |
| 92 | |
| 93 | enum pcxhr_clock_type use_clock_type; /* clock type selected by mixer */ |
| 94 | enum pcxhr_clock_type cur_clock_type; /* current clock type synced */ |
| 95 | int sample_rate; |
| 96 | int ref_count_rate; |
| 97 | int timer_toggle; /* timer interrupt toggles between the two values 0x200 and 0x300 */ |
| 98 | int dsp_time_last; /* the last dsp time (read by interrupt) */ |
| 99 | int dsp_time_err; /* dsp time errors */ |
| 100 | unsigned int src_it_dsp; /* dsp interrupt source */ |
| 101 | unsigned int io_num_reg_cont; /* backup of IO_NUM_REG_CONT */ |
| 102 | unsigned int codec_speed; /* speed mode of the codecs */ |
| 103 | unsigned int sample_rate_real; /* current real sample rate */ |
| 104 | int last_reg_stat; |
| 105 | int async_err_stream_xrun; |
| 106 | int async_err_pipe_xrun; |
| 107 | int async_err_other_last; |
| 108 | }; |
| 109 | |
| 110 | |
| 111 | enum pcxhr_stream_status { |
| 112 | PCXHR_STREAM_STATUS_FREE, |
| 113 | PCXHR_STREAM_STATUS_OPEN, |
| 114 | PCXHR_STREAM_STATUS_SCHEDULE_RUN, |
| 115 | PCXHR_STREAM_STATUS_STARTED, |
| 116 | PCXHR_STREAM_STATUS_RUNNING, |
| 117 | PCXHR_STREAM_STATUS_SCHEDULE_STOP, |
| 118 | PCXHR_STREAM_STATUS_STOPPED, |
| 119 | PCXHR_STREAM_STATUS_PAUSED |
| 120 | }; |
| 121 | |
| 122 | struct pcxhr_stream { |
| 123 | struct snd_pcm_substream *substream; |
| 124 | snd_pcm_format_t format; |
| 125 | struct pcxhr_pipe *pipe; |
| 126 | |
| 127 | enum pcxhr_stream_status status; /* free, open, running, draining, pause */ |
| 128 | |
| 129 | u_int64_t timer_abs_periods; /* timer: samples elapsed since TRIGGER_START (multiple of period_size) */ |
| 130 | u_int32_t timer_period_frag; /* timer: samples elapsed since last call to snd_pcm_period_elapsed (0..period_size) */ |
| 131 | u_int32_t timer_buf_periods; /* nb of periods in the buffer that have already elapsed */ |
| 132 | int timer_is_synced; /* if(0) : timer needs to be resynced with real hardware pointer */ |
| 133 | |
| 134 | int channels; |
| 135 | }; |
| 136 | |
| 137 | |
| 138 | enum pcxhr_pipe_status { |
| 139 | PCXHR_PIPE_UNDEFINED, |
| 140 | PCXHR_PIPE_DEFINED |
| 141 | }; |
| 142 | |
| 143 | struct pcxhr_pipe { |
| 144 | enum pcxhr_pipe_status status; |
| 145 | int is_capture; /* this is a capture pipe */ |
| 146 | int first_audio; /* first audio num */ |
| 147 | }; |
| 148 | |
| 149 | |
| 150 | struct snd_pcxhr { |
| 151 | struct snd_card *card; |
| 152 | struct pcxhr_mgr *mgr; |
| 153 | int chip_idx; /* zero based */ |
| 154 | |
| 155 | struct snd_pcm *pcm; /* PCM */ |
| 156 | |
| 157 | struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */ |
| 158 | struct pcxhr_pipe capture_pipe[2]; /* 1 stereo pipe or 2 mono pipes */ |
| 159 | |
| 160 | struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS]; |
| 161 | struct pcxhr_stream capture_stream[2]; /* 1 stereo stream or 2 mono streams */ |
| 162 | int nb_streams_play; |
| 163 | int nb_streams_capt; |
| 164 | |
| 165 | int analog_playback_active[2]; /* Mixer : Master Playback active (!mute) */ |
| 166 | int analog_playback_volume[2]; /* Mixer : Master Playback Volume */ |
| 167 | int analog_capture_volume[2]; /* Mixer : Master Capture Volume */ |
| 168 | int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Active [streams][stereo]*/ |
| 169 | int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Volume [streams][stereo]*/ |
| 170 | int digital_capture_volume[2]; /* Mixer : Digital Capture Volume [stereo] */ |
| 171 | int monitoring_active[2]; /* Mixer : Monitoring Active */ |
| 172 | int monitoring_volume[2]; /* Mixer : Monitoring Volume */ |
| 173 | int audio_capture_source; /* Mixer : Audio Capture Source */ |
| 174 | unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */ |
| 175 | }; |
| 176 | |
| 177 | struct pcxhr_hostport |
| 178 | { |
| 179 | char purgebuffer[6]; |
| 180 | char reserved[2]; |
| 181 | }; |
| 182 | |
| 183 | /* exported */ |
| 184 | int pcxhr_create_pcm(struct snd_pcxhr *chip); |
| 185 | int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate); |
| 186 | int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_type, int *sample_rate); |
| 187 | |
| 188 | #endif /* __SOUND_PCXHR_H */ |