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