Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef _NM256_H_ |
| 2 | #define _NM256_H_ |
| 3 | |
| 4 | #include <linux/spinlock.h> |
| 5 | #include <linux/interrupt.h> |
| 6 | |
| 7 | #include "ac97.h" |
| 8 | |
| 9 | /* The revisions that we currently handle. */ |
| 10 | enum nm256rev { |
| 11 | REV_NM256AV, REV_NM256ZX |
| 12 | }; |
| 13 | |
| 14 | /* Per-card structure. */ |
| 15 | struct nm256_info |
| 16 | { |
| 17 | /* Magic number used to verify that this struct is valid. */ |
| 18 | #define NM_MAGIC_SIG 0x55aa00ff |
| 19 | int magsig; |
| 20 | |
| 21 | /* Revision number */ |
| 22 | enum nm256rev rev; |
| 23 | |
| 24 | struct ac97_hwint mdev; |
| 25 | |
| 26 | /* Our audio device numbers. */ |
| 27 | int dev[2]; |
| 28 | |
| 29 | /* The # of times each device has been opened. (Should only be |
| 30 | 0 or 1). */ |
| 31 | int opencnt[2]; |
| 32 | |
| 33 | /* We use two devices, because we can do simultaneous play and record. |
| 34 | This keeps track of which device is being used for what purpose; |
| 35 | these are the actual device numbers. */ |
| 36 | int dev_for_play; |
| 37 | int dev_for_record; |
| 38 | |
| 39 | spinlock_t lock; |
| 40 | |
| 41 | /* The mixer device. */ |
| 42 | int mixer_oss_dev; |
| 43 | |
| 44 | /* |
| 45 | * Can only be opened once for each operation. These aren't set |
| 46 | * until an actual I/O operation is performed; this allows one |
| 47 | * device to be open for read/write without inhibiting I/O to |
| 48 | * the other device. |
| 49 | */ |
| 50 | int is_open_play; |
| 51 | int is_open_record; |
| 52 | |
| 53 | /* Non-zero if we're currently playing a sample. */ |
| 54 | int playing; |
| 55 | /* Ditto for recording a sample. */ |
| 56 | int recording; |
| 57 | |
| 58 | /* The two memory ports. */ |
| 59 | struct nm256_ports { |
| 60 | /* Physical address of the port. */ |
| 61 | u32 physaddr; |
| 62 | /* Our mapped-in pointer. */ |
| 63 | char __iomem *ptr; |
| 64 | /* PTR's offset within the physical port. */ |
| 65 | u32 start_offset; |
| 66 | /* And the offset of the end of the buffer. */ |
| 67 | u32 end_offset; |
| 68 | } port[2]; |
| 69 | |
| 70 | /* The following are offsets within memory port 1. */ |
| 71 | u32 coeffBuf; |
| 72 | u32 allCoeffBuf; |
| 73 | |
| 74 | /* Record and playback buffers. */ |
| 75 | u32 abuf1, abuf2; |
| 76 | |
| 77 | /* Offset of the AC97 mixer in memory port 2. */ |
| 78 | u32 mixer; |
| 79 | |
| 80 | /* Offset of the mixer status register in memory port 2. */ |
| 81 | u32 mixer_status_offset; |
| 82 | |
| 83 | /* Non-zero if we have written initial values to the mixer. */ |
| 84 | u8 mixer_values_init; |
| 85 | |
| 86 | /* |
| 87 | * Status mask bit; (*mixer_status_loc & mixer_status_mask) == 0 means |
| 88 | * it's ready. |
| 89 | */ |
| 90 | u16 mixer_status_mask; |
| 91 | |
| 92 | /* The sizes of the playback and record ring buffers. */ |
| 93 | u32 playbackBufferSize; |
| 94 | u32 recordBufferSize; |
| 95 | |
| 96 | /* Are the coefficient values in the memory cache current? */ |
| 97 | u8 coeffsCurrent; |
| 98 | |
| 99 | /* For writes, the amount we last wrote. */ |
| 100 | u32 requested_amt; |
| 101 | /* The start of the block currently playing. */ |
| 102 | u32 curPlayPos; |
| 103 | |
| 104 | /* The amount of data we were requested to record. */ |
| 105 | u32 requestedRecAmt; |
| 106 | /* The offset of the currently-recording block. */ |
| 107 | u32 curRecPos; |
| 108 | /* The destination buffer. */ |
| 109 | char *recBuf; |
| 110 | |
| 111 | /* Our IRQ number. */ |
| 112 | int irq; |
| 113 | |
| 114 | /* A flag indicating how many times we've grabbed the IRQ. */ |
| 115 | int has_irq; |
| 116 | |
| 117 | /* The card interrupt service routine. */ |
| 118 | irqreturn_t (*introutine) (int, void *, struct pt_regs *); |
| 119 | |
| 120 | /* Current audio config, cached. */ |
| 121 | struct sinfo { |
| 122 | u32 samplerate; |
| 123 | u8 bits; |
| 124 | u8 stereo; |
| 125 | } sinfo[2]; /* goes with each device */ |
| 126 | |
| 127 | /* The cards are stored in a chain; this is the next card. */ |
| 128 | struct nm256_info *next_card; |
| 129 | }; |
| 130 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 131 | /* The BIOS signature. */ |
| 132 | #define NM_SIGNATURE 0x4e4d0000 |
| 133 | /* Signature mask. */ |
| 134 | #define NM_SIG_MASK 0xffff0000 |
| 135 | |
| 136 | /* Size of the second memory area. */ |
| 137 | #define NM_PORT2_SIZE 4096 |
| 138 | |
| 139 | /* The base offset of the mixer in the second memory area. */ |
| 140 | #define NM_MIXER_OFFSET 0x600 |
| 141 | |
| 142 | /* The maximum size of a coefficient entry. */ |
| 143 | #define NM_MAX_COEFFICIENT 0x5000 |
| 144 | |
| 145 | /* The interrupt register. */ |
| 146 | #define NM_INT_REG 0xa04 |
| 147 | /* And its bits. */ |
| 148 | #define NM_PLAYBACK_INT 0x40 |
| 149 | #define NM_RECORD_INT 0x100 |
| 150 | #define NM_MISC_INT_1 0x4000 |
| 151 | #define NM_MISC_INT_2 0x1 |
| 152 | #define NM_ACK_INT(CARD, X) nm256_writePort16((CARD), 2, NM_INT_REG, (X) << 1) |
| 153 | |
| 154 | /* The AV's "mixer ready" status bit and location. */ |
| 155 | #define NM_MIXER_STATUS_OFFSET 0xa04 |
| 156 | #define NM_MIXER_READY_MASK 0x0800 |
| 157 | #define NM_MIXER_PRESENCE 0xa06 |
| 158 | #define NM_PRESENCE_MASK 0x0050 |
| 159 | #define NM_PRESENCE_VALUE 0x0040 |
| 160 | |
| 161 | /* |
| 162 | * For the ZX. It uses the same interrupt register, but it holds 32 |
| 163 | * bits instead of 16. |
| 164 | */ |
| 165 | #define NM2_PLAYBACK_INT 0x10000 |
| 166 | #define NM2_RECORD_INT 0x80000 |
| 167 | #define NM2_MISC_INT_1 0x8 |
| 168 | #define NM2_MISC_INT_2 0x2 |
| 169 | #define NM2_ACK_INT(CARD, X) nm256_writePort32((CARD), 2, NM_INT_REG, (X)) |
| 170 | |
| 171 | /* The ZX's "mixer ready" status bit and location. */ |
| 172 | #define NM2_MIXER_STATUS_OFFSET 0xa06 |
| 173 | #define NM2_MIXER_READY_MASK 0x0800 |
| 174 | |
| 175 | /* The playback registers start from here. */ |
| 176 | #define NM_PLAYBACK_REG_OFFSET 0x0 |
| 177 | /* The record registers start from here. */ |
| 178 | #define NM_RECORD_REG_OFFSET 0x200 |
| 179 | |
| 180 | /* The rate register is located 2 bytes from the start of the register area. */ |
| 181 | #define NM_RATE_REG_OFFSET 2 |
| 182 | |
| 183 | /* Mono/stereo flag, number of bits on playback, and rate mask. */ |
| 184 | #define NM_RATE_STEREO 1 |
| 185 | #define NM_RATE_BITS_16 2 |
| 186 | #define NM_RATE_MASK 0xf0 |
| 187 | |
| 188 | /* Playback enable register. */ |
| 189 | #define NM_PLAYBACK_ENABLE_REG (NM_PLAYBACK_REG_OFFSET + 0x1) |
| 190 | #define NM_PLAYBACK_ENABLE_FLAG 1 |
| 191 | #define NM_PLAYBACK_ONESHOT 2 |
| 192 | #define NM_PLAYBACK_FREERUN 4 |
| 193 | |
| 194 | /* Mutes the audio output. */ |
| 195 | #define NM_AUDIO_MUTE_REG (NM_PLAYBACK_REG_OFFSET + 0x18) |
| 196 | #define NM_AUDIO_MUTE_LEFT 0x8000 |
| 197 | #define NM_AUDIO_MUTE_RIGHT 0x0080 |
| 198 | |
| 199 | /* Recording enable register. */ |
| 200 | #define NM_RECORD_ENABLE_REG (NM_RECORD_REG_OFFSET + 0) |
| 201 | #define NM_RECORD_ENABLE_FLAG 1 |
| 202 | #define NM_RECORD_FREERUN 2 |
| 203 | |
| 204 | #define NM_RBUFFER_START (NM_RECORD_REG_OFFSET + 0x4) |
| 205 | #define NM_RBUFFER_END (NM_RECORD_REG_OFFSET + 0x10) |
| 206 | #define NM_RBUFFER_WMARK (NM_RECORD_REG_OFFSET + 0xc) |
| 207 | #define NM_RBUFFER_CURRP (NM_RECORD_REG_OFFSET + 0x8) |
| 208 | |
| 209 | #define NM_PBUFFER_START (NM_PLAYBACK_REG_OFFSET + 0x4) |
| 210 | #define NM_PBUFFER_END (NM_PLAYBACK_REG_OFFSET + 0x14) |
| 211 | #define NM_PBUFFER_WMARK (NM_PLAYBACK_REG_OFFSET + 0xc) |
| 212 | #define NM_PBUFFER_CURRP (NM_PLAYBACK_REG_OFFSET + 0x8) |
| 213 | |
| 214 | /* A few trivial routines to make it easier to work with the registers |
| 215 | on the chip. */ |
| 216 | |
| 217 | /* This is a common code portion used to fix up the port offsets. */ |
| 218 | #define NM_FIX_PORT \ |
| 219 | if (port < 1 || port > 2 || card == NULL) \ |
| 220 | return -1; \ |
| 221 | \ |
| 222 | if (offset < card->port[port - 1].start_offset \ |
| 223 | || offset >= card->port[port - 1].end_offset) { \ |
| 224 | printk (KERN_ERR "Bad access: port %d, offset 0x%x\n", port, offset); \ |
| 225 | return -1; \ |
| 226 | } \ |
| 227 | offset -= card->port[port - 1].start_offset; |
| 228 | |
| 229 | #define DEFwritePortX(X, func) \ |
| 230 | static inline int nm256_writePort##X (struct nm256_info *card,\ |
| 231 | int port, int offset, int value)\ |
| 232 | {\ |
| 233 | u##X __iomem *addr;\ |
| 234 | \ |
| 235 | if (nm256_debug > 1)\ |
| 236 | printk (KERN_DEBUG "Writing 0x%x to %d:0x%x\n", value, port, offset);\ |
| 237 | \ |
| 238 | NM_FIX_PORT;\ |
| 239 | \ |
| 240 | addr = (u##X __iomem *)(card->port[port - 1].ptr + offset);\ |
| 241 | func (value, addr);\ |
| 242 | return 0;\ |
| 243 | } |
| 244 | |
| 245 | DEFwritePortX (8, writeb) |
| 246 | DEFwritePortX (16, writew) |
| 247 | DEFwritePortX (32, writel) |
| 248 | |
| 249 | #define DEFreadPortX(X, func) \ |
| 250 | static inline u##X nm256_readPort##X (struct nm256_info *card,\ |
| 251 | int port, int offset)\ |
| 252 | {\ |
| 253 | u##X __iomem *addr;\ |
| 254 | \ |
| 255 | NM_FIX_PORT\ |
| 256 | \ |
| 257 | addr = (u##X __iomem *)(card->port[port - 1].ptr + offset);\ |
| 258 | return func(addr);\ |
| 259 | } |
| 260 | |
| 261 | DEFreadPortX (8, readb) |
| 262 | DEFreadPortX (16, readw) |
| 263 | DEFreadPortX (32, readl) |
| 264 | |
| 265 | static inline int |
| 266 | nm256_writeBuffer8 (struct nm256_info *card, u8 *src, int port, int offset, |
| 267 | int amt) |
| 268 | { |
| 269 | NM_FIX_PORT; |
| 270 | memcpy_toio (card->port[port - 1].ptr + offset, src, amt); |
| 271 | return 0; |
| 272 | } |
| 273 | |
| 274 | static inline int |
| 275 | nm256_readBuffer8 (struct nm256_info *card, u8 *dst, int port, int offset, |
| 276 | int amt) |
| 277 | { |
| 278 | NM_FIX_PORT; |
| 279 | memcpy_fromio (dst, card->port[port - 1].ptr + offset, amt); |
| 280 | return 0; |
| 281 | } |
| 282 | |
| 283 | /* Returns a non-zero value if we should use the coefficient cache. */ |
Adrian Bunk | 155542c | 2005-06-25 14:58:53 -0700 | [diff] [blame] | 284 | static int nm256_cachedCoefficients (struct nm256_info *card); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 285 | |
| 286 | #endif |
| 287 | |
| 288 | /* |
| 289 | * Local variables: |
| 290 | * c-basic-offset: 4 |
| 291 | * End: |
| 292 | */ |