0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 #include <linux/delay.h>
0050 #include <linux/init.h>
0051 #include <linux/interrupt.h>
0052 #include <linux/moduleparam.h>
0053 #include <linux/io.h>
0054 #include <sound/core.h>
0055 #include <sound/initval.h>
0056 #include <sound/pcm.h>
0057 #include <sound/ac97_codec.h>
0058 #include <sound/info.h>
0059 #include <sound/asoundef.h>
0060
0061 #include "ca0106.h"
0062
0063
0064 struct snd_ca0106_category_str {
0065 int val;
0066 const char *name;
0067 };
0068
0069 static const struct snd_ca0106_category_str snd_ca0106_con_category[] = {
0070 { IEC958_AES1_CON_DAT, "DAT" },
0071 { IEC958_AES1_CON_VCR, "VCR" },
0072 { IEC958_AES1_CON_MICROPHONE, "microphone" },
0073 { IEC958_AES1_CON_SYNTHESIZER, "synthesizer" },
0074 { IEC958_AES1_CON_RATE_CONVERTER, "rate converter" },
0075 { IEC958_AES1_CON_MIXER, "mixer" },
0076 { IEC958_AES1_CON_SAMPLER, "sampler" },
0077 { IEC958_AES1_CON_PCM_CODER, "PCM coder" },
0078 { IEC958_AES1_CON_IEC908_CD, "CD" },
0079 { IEC958_AES1_CON_NON_IEC908_CD, "non-IEC908 CD" },
0080 { IEC958_AES1_CON_GENERAL, "general" },
0081 };
0082
0083
0084 static void snd_ca0106_proc_dump_iec958( struct snd_info_buffer *buffer, u32 value)
0085 {
0086 int i;
0087 u32 status[4];
0088 status[0] = value & 0xff;
0089 status[1] = (value >> 8) & 0xff;
0090 status[2] = (value >> 16) & 0xff;
0091 status[3] = (value >> 24) & 0xff;
0092
0093 if (! (status[0] & IEC958_AES0_PROFESSIONAL)) {
0094
0095 snd_iprintf(buffer, "Mode: consumer\n");
0096 snd_iprintf(buffer, "Data: ");
0097 if (!(status[0] & IEC958_AES0_NONAUDIO)) {
0098 snd_iprintf(buffer, "audio\n");
0099 } else {
0100 snd_iprintf(buffer, "non-audio\n");
0101 }
0102 snd_iprintf(buffer, "Rate: ");
0103 switch (status[3] & IEC958_AES3_CON_FS) {
0104 case IEC958_AES3_CON_FS_44100:
0105 snd_iprintf(buffer, "44100 Hz\n");
0106 break;
0107 case IEC958_AES3_CON_FS_48000:
0108 snd_iprintf(buffer, "48000 Hz\n");
0109 break;
0110 case IEC958_AES3_CON_FS_32000:
0111 snd_iprintf(buffer, "32000 Hz\n");
0112 break;
0113 default:
0114 snd_iprintf(buffer, "unknown\n");
0115 break;
0116 }
0117 snd_iprintf(buffer, "Copyright: ");
0118 if (status[0] & IEC958_AES0_CON_NOT_COPYRIGHT) {
0119 snd_iprintf(buffer, "permitted\n");
0120 } else {
0121 snd_iprintf(buffer, "protected\n");
0122 }
0123 snd_iprintf(buffer, "Emphasis: ");
0124 if ((status[0] & IEC958_AES0_CON_EMPHASIS) != IEC958_AES0_CON_EMPHASIS_5015) {
0125 snd_iprintf(buffer, "none\n");
0126 } else {
0127 snd_iprintf(buffer, "50/15us\n");
0128 }
0129 snd_iprintf(buffer, "Category: ");
0130 for (i = 0; i < ARRAY_SIZE(snd_ca0106_con_category); i++) {
0131 if ((status[1] & IEC958_AES1_CON_CATEGORY) == snd_ca0106_con_category[i].val) {
0132 snd_iprintf(buffer, "%s\n", snd_ca0106_con_category[i].name);
0133 break;
0134 }
0135 }
0136 if (i >= ARRAY_SIZE(snd_ca0106_con_category)) {
0137 snd_iprintf(buffer, "unknown 0x%x\n", status[1] & IEC958_AES1_CON_CATEGORY);
0138 }
0139 snd_iprintf(buffer, "Original: ");
0140 if (status[1] & IEC958_AES1_CON_ORIGINAL) {
0141 snd_iprintf(buffer, "original\n");
0142 } else {
0143 snd_iprintf(buffer, "1st generation\n");
0144 }
0145 snd_iprintf(buffer, "Clock: ");
0146 switch (status[3] & IEC958_AES3_CON_CLOCK) {
0147 case IEC958_AES3_CON_CLOCK_1000PPM:
0148 snd_iprintf(buffer, "1000 ppm\n");
0149 break;
0150 case IEC958_AES3_CON_CLOCK_50PPM:
0151 snd_iprintf(buffer, "50 ppm\n");
0152 break;
0153 case IEC958_AES3_CON_CLOCK_VARIABLE:
0154 snd_iprintf(buffer, "variable pitch\n");
0155 break;
0156 default:
0157 snd_iprintf(buffer, "unknown\n");
0158 break;
0159 }
0160 } else {
0161 snd_iprintf(buffer, "Mode: professional\n");
0162 snd_iprintf(buffer, "Data: ");
0163 if (!(status[0] & IEC958_AES0_NONAUDIO)) {
0164 snd_iprintf(buffer, "audio\n");
0165 } else {
0166 snd_iprintf(buffer, "non-audio\n");
0167 }
0168 snd_iprintf(buffer, "Rate: ");
0169 switch (status[0] & IEC958_AES0_PRO_FS) {
0170 case IEC958_AES0_PRO_FS_44100:
0171 snd_iprintf(buffer, "44100 Hz\n");
0172 break;
0173 case IEC958_AES0_PRO_FS_48000:
0174 snd_iprintf(buffer, "48000 Hz\n");
0175 break;
0176 case IEC958_AES0_PRO_FS_32000:
0177 snd_iprintf(buffer, "32000 Hz\n");
0178 break;
0179 default:
0180 snd_iprintf(buffer, "unknown\n");
0181 break;
0182 }
0183 snd_iprintf(buffer, "Rate Locked: ");
0184 if (status[0] & IEC958_AES0_PRO_FREQ_UNLOCKED)
0185 snd_iprintf(buffer, "no\n");
0186 else
0187 snd_iprintf(buffer, "yes\n");
0188 snd_iprintf(buffer, "Emphasis: ");
0189 switch (status[0] & IEC958_AES0_PRO_EMPHASIS) {
0190 case IEC958_AES0_PRO_EMPHASIS_CCITT:
0191 snd_iprintf(buffer, "CCITT J.17\n");
0192 break;
0193 case IEC958_AES0_PRO_EMPHASIS_NONE:
0194 snd_iprintf(buffer, "none\n");
0195 break;
0196 case IEC958_AES0_PRO_EMPHASIS_5015:
0197 snd_iprintf(buffer, "50/15us\n");
0198 break;
0199 case IEC958_AES0_PRO_EMPHASIS_NOTID:
0200 default:
0201 snd_iprintf(buffer, "unknown\n");
0202 break;
0203 }
0204 snd_iprintf(buffer, "Stereophonic: ");
0205 if ((status[1] & IEC958_AES1_PRO_MODE) == IEC958_AES1_PRO_MODE_STEREOPHONIC) {
0206 snd_iprintf(buffer, "stereo\n");
0207 } else {
0208 snd_iprintf(buffer, "not indicated\n");
0209 }
0210 snd_iprintf(buffer, "Userbits: ");
0211 switch (status[1] & IEC958_AES1_PRO_USERBITS) {
0212 case IEC958_AES1_PRO_USERBITS_192:
0213 snd_iprintf(buffer, "192bit\n");
0214 break;
0215 case IEC958_AES1_PRO_USERBITS_UDEF:
0216 snd_iprintf(buffer, "user-defined\n");
0217 break;
0218 default:
0219 snd_iprintf(buffer, "unknown\n");
0220 break;
0221 }
0222 snd_iprintf(buffer, "Sample Bits: ");
0223 switch (status[2] & IEC958_AES2_PRO_SBITS) {
0224 case IEC958_AES2_PRO_SBITS_20:
0225 snd_iprintf(buffer, "20 bit\n");
0226 break;
0227 case IEC958_AES2_PRO_SBITS_24:
0228 snd_iprintf(buffer, "24 bit\n");
0229 break;
0230 case IEC958_AES2_PRO_SBITS_UDEF:
0231 snd_iprintf(buffer, "user defined\n");
0232 break;
0233 default:
0234 snd_iprintf(buffer, "unknown\n");
0235 break;
0236 }
0237 snd_iprintf(buffer, "Word Length: ");
0238 switch (status[2] & IEC958_AES2_PRO_WORDLEN) {
0239 case IEC958_AES2_PRO_WORDLEN_22_18:
0240 snd_iprintf(buffer, "22 bit or 18 bit\n");
0241 break;
0242 case IEC958_AES2_PRO_WORDLEN_23_19:
0243 snd_iprintf(buffer, "23 bit or 19 bit\n");
0244 break;
0245 case IEC958_AES2_PRO_WORDLEN_24_20:
0246 snd_iprintf(buffer, "24 bit or 20 bit\n");
0247 break;
0248 case IEC958_AES2_PRO_WORDLEN_20_16:
0249 snd_iprintf(buffer, "20 bit or 16 bit\n");
0250 break;
0251 default:
0252 snd_iprintf(buffer, "unknown\n");
0253 break;
0254 }
0255 }
0256 }
0257
0258 static void snd_ca0106_proc_iec958(struct snd_info_entry *entry,
0259 struct snd_info_buffer *buffer)
0260 {
0261 struct snd_ca0106 *emu = entry->private_data;
0262 u32 value;
0263
0264 value = snd_ca0106_ptr_read(emu, SAMPLE_RATE_TRACKER_STATUS, 0);
0265 snd_iprintf(buffer, "Status: %s, %s, %s\n",
0266 (value & 0x100000) ? "Rate Locked" : "Not Rate Locked",
0267 (value & 0x200000) ? "SPDIF Locked" : "No SPDIF Lock",
0268 (value & 0x400000) ? "Audio Valid" : "No valid audio" );
0269 snd_iprintf(buffer, "Estimated sample rate: %u\n",
0270 ((value & 0xfffff) * 48000) / 0x8000 );
0271 if (value & 0x200000) {
0272 snd_iprintf(buffer, "IEC958/SPDIF input status:\n");
0273 value = snd_ca0106_ptr_read(emu, SPDIF_INPUT_STATUS, 0);
0274 snd_ca0106_proc_dump_iec958(buffer, value);
0275 }
0276
0277 snd_iprintf(buffer, "\n");
0278 }
0279
0280 static void snd_ca0106_proc_reg_write32(struct snd_info_entry *entry,
0281 struct snd_info_buffer *buffer)
0282 {
0283 struct snd_ca0106 *emu = entry->private_data;
0284 unsigned long flags;
0285 char line[64];
0286 u32 reg, val;
0287 while (!snd_info_get_line(buffer, line, sizeof(line))) {
0288 if (sscanf(line, "%x %x", ®, &val) != 2)
0289 continue;
0290 if (reg < 0x40 && val <= 0xffffffff) {
0291 spin_lock_irqsave(&emu->emu_lock, flags);
0292 outl(val, emu->port + (reg & 0xfffffffc));
0293 spin_unlock_irqrestore(&emu->emu_lock, flags);
0294 }
0295 }
0296 }
0297
0298 static void snd_ca0106_proc_reg_read32(struct snd_info_entry *entry,
0299 struct snd_info_buffer *buffer)
0300 {
0301 struct snd_ca0106 *emu = entry->private_data;
0302 unsigned long value;
0303 unsigned long flags;
0304 int i;
0305 snd_iprintf(buffer, "Registers:\n\n");
0306 for(i = 0; i < 0x20; i+=4) {
0307 spin_lock_irqsave(&emu->emu_lock, flags);
0308 value = inl(emu->port + i);
0309 spin_unlock_irqrestore(&emu->emu_lock, flags);
0310 snd_iprintf(buffer, "Register %02X: %08lX\n", i, value);
0311 }
0312 }
0313
0314 static void snd_ca0106_proc_reg_read16(struct snd_info_entry *entry,
0315 struct snd_info_buffer *buffer)
0316 {
0317 struct snd_ca0106 *emu = entry->private_data;
0318 unsigned int value;
0319 unsigned long flags;
0320 int i;
0321 snd_iprintf(buffer, "Registers:\n\n");
0322 for(i = 0; i < 0x20; i+=2) {
0323 spin_lock_irqsave(&emu->emu_lock, flags);
0324 value = inw(emu->port + i);
0325 spin_unlock_irqrestore(&emu->emu_lock, flags);
0326 snd_iprintf(buffer, "Register %02X: %04X\n", i, value);
0327 }
0328 }
0329
0330 static void snd_ca0106_proc_reg_read8(struct snd_info_entry *entry,
0331 struct snd_info_buffer *buffer)
0332 {
0333 struct snd_ca0106 *emu = entry->private_data;
0334 unsigned int value;
0335 unsigned long flags;
0336 int i;
0337 snd_iprintf(buffer, "Registers:\n\n");
0338 for(i = 0; i < 0x20; i+=1) {
0339 spin_lock_irqsave(&emu->emu_lock, flags);
0340 value = inb(emu->port + i);
0341 spin_unlock_irqrestore(&emu->emu_lock, flags);
0342 snd_iprintf(buffer, "Register %02X: %02X\n", i, value);
0343 }
0344 }
0345
0346 static void snd_ca0106_proc_reg_read1(struct snd_info_entry *entry,
0347 struct snd_info_buffer *buffer)
0348 {
0349 struct snd_ca0106 *emu = entry->private_data;
0350 unsigned long value;
0351 int i,j;
0352
0353 snd_iprintf(buffer, "Registers\n");
0354 for(i = 0; i < 0x40; i++) {
0355 snd_iprintf(buffer, "%02X: ",i);
0356 for (j = 0; j < 4; j++) {
0357 value = snd_ca0106_ptr_read(emu, i, j);
0358 snd_iprintf(buffer, "%08lX ", value);
0359 }
0360 snd_iprintf(buffer, "\n");
0361 }
0362 }
0363
0364 static void snd_ca0106_proc_reg_read2(struct snd_info_entry *entry,
0365 struct snd_info_buffer *buffer)
0366 {
0367 struct snd_ca0106 *emu = entry->private_data;
0368 unsigned long value;
0369 int i,j;
0370
0371 snd_iprintf(buffer, "Registers\n");
0372 for(i = 0x40; i < 0x80; i++) {
0373 snd_iprintf(buffer, "%02X: ",i);
0374 for (j = 0; j < 4; j++) {
0375 value = snd_ca0106_ptr_read(emu, i, j);
0376 snd_iprintf(buffer, "%08lX ", value);
0377 }
0378 snd_iprintf(buffer, "\n");
0379 }
0380 }
0381
0382 static void snd_ca0106_proc_reg_write(struct snd_info_entry *entry,
0383 struct snd_info_buffer *buffer)
0384 {
0385 struct snd_ca0106 *emu = entry->private_data;
0386 char line[64];
0387 unsigned int reg, channel_id , val;
0388 while (!snd_info_get_line(buffer, line, sizeof(line))) {
0389 if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3)
0390 continue;
0391 if (reg < 0x80 && val <= 0xffffffff && channel_id <= 3)
0392 snd_ca0106_ptr_write(emu, reg, channel_id, val);
0393 }
0394 }
0395
0396 static void snd_ca0106_proc_i2c_write(struct snd_info_entry *entry,
0397 struct snd_info_buffer *buffer)
0398 {
0399 struct snd_ca0106 *emu = entry->private_data;
0400 char line[64];
0401 unsigned int reg, val;
0402 while (!snd_info_get_line(buffer, line, sizeof(line))) {
0403 if (sscanf(line, "%x %x", ®, &val) != 2)
0404 continue;
0405 if ((reg <= 0x7f) || (val <= 0x1ff)) {
0406 snd_ca0106_i2c_write(emu, reg, val);
0407 }
0408 }
0409 }
0410
0411 int snd_ca0106_proc_init(struct snd_ca0106 *emu)
0412 {
0413 snd_card_ro_proc_new(emu->card, "iec958", emu, snd_ca0106_proc_iec958);
0414 snd_card_rw_proc_new(emu->card, "ca0106_reg32", emu,
0415 snd_ca0106_proc_reg_read32,
0416 snd_ca0106_proc_reg_write32);
0417 snd_card_ro_proc_new(emu->card, "ca0106_reg16", emu,
0418 snd_ca0106_proc_reg_read16);
0419 snd_card_ro_proc_new(emu->card, "ca0106_reg8", emu,
0420 snd_ca0106_proc_reg_read8);
0421 snd_card_rw_proc_new(emu->card, "ca0106_regs1", emu,
0422 snd_ca0106_proc_reg_read1,
0423 snd_ca0106_proc_reg_write);
0424 snd_card_rw_proc_new(emu->card, "ca0106_i2c", emu, NULL,
0425 snd_ca0106_proc_i2c_write);
0426 snd_card_ro_proc_new(emu->card, "ca0106_regs2", emu,
0427 snd_ca0106_proc_reg_read2);
0428 return 0;
0429 }