0001
0002
0003
0004
0005 #include <linux/init.h>
0006 #include <linux/usb.h>
0007
0008 #include <sound/core.h>
0009 #include <sound/info.h>
0010 #include <sound/pcm.h>
0011
0012 #include "usbaudio.h"
0013 #include "helper.h"
0014 #include "card.h"
0015 #include "endpoint.h"
0016 #include "proc.h"
0017
0018
0019 static inline unsigned get_full_speed_hz(unsigned int usb_rate)
0020 {
0021 return (usb_rate * 125 + (1 << 12)) >> 13;
0022 }
0023
0024
0025 static inline unsigned get_high_speed_hz(unsigned int usb_rate)
0026 {
0027 return (usb_rate * 125 + (1 << 9)) >> 10;
0028 }
0029
0030
0031
0032
0033 static void proc_audio_usbbus_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
0034 {
0035 struct snd_usb_audio *chip = entry->private_data;
0036 if (!atomic_read(&chip->shutdown))
0037 snd_iprintf(buffer, "%03d/%03d\n", chip->dev->bus->busnum, chip->dev->devnum);
0038 }
0039
0040 static void proc_audio_usbid_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
0041 {
0042 struct snd_usb_audio *chip = entry->private_data;
0043 if (!atomic_read(&chip->shutdown))
0044 snd_iprintf(buffer, "%04x:%04x\n",
0045 USB_ID_VENDOR(chip->usb_id),
0046 USB_ID_PRODUCT(chip->usb_id));
0047 }
0048
0049 void snd_usb_audio_create_proc(struct snd_usb_audio *chip)
0050 {
0051 snd_card_ro_proc_new(chip->card, "usbbus", chip,
0052 proc_audio_usbbus_read);
0053 snd_card_ro_proc_new(chip->card, "usbid", chip,
0054 proc_audio_usbid_read);
0055 }
0056
0057 static const char * const channel_labels[] = {
0058 [SNDRV_CHMAP_NA] = "N/A",
0059 [SNDRV_CHMAP_MONO] = "MONO",
0060 [SNDRV_CHMAP_FL] = "FL",
0061 [SNDRV_CHMAP_FR] = "FR",
0062 [SNDRV_CHMAP_FC] = "FC",
0063 [SNDRV_CHMAP_LFE] = "LFE",
0064 [SNDRV_CHMAP_RL] = "RL",
0065 [SNDRV_CHMAP_RR] = "RR",
0066 [SNDRV_CHMAP_FLC] = "FLC",
0067 [SNDRV_CHMAP_FRC] = "FRC",
0068 [SNDRV_CHMAP_RC] = "RC",
0069 [SNDRV_CHMAP_SL] = "SL",
0070 [SNDRV_CHMAP_SR] = "SR",
0071 [SNDRV_CHMAP_TC] = "TC",
0072 [SNDRV_CHMAP_TFL] = "TFL",
0073 [SNDRV_CHMAP_TFC] = "TFC",
0074 [SNDRV_CHMAP_TFR] = "TFR",
0075 [SNDRV_CHMAP_TRL] = "TRL",
0076 [SNDRV_CHMAP_TRC] = "TRC",
0077 [SNDRV_CHMAP_TRR] = "TRR",
0078 [SNDRV_CHMAP_TFLC] = "TFLC",
0079 [SNDRV_CHMAP_TFRC] = "TFRC",
0080 [SNDRV_CHMAP_LLFE] = "LLFE",
0081 [SNDRV_CHMAP_RLFE] = "RLFE",
0082 [SNDRV_CHMAP_TSL] = "TSL",
0083 [SNDRV_CHMAP_TSR] = "TSR",
0084 [SNDRV_CHMAP_BC] = "BC",
0085 [SNDRV_CHMAP_RLC] = "RLC",
0086 [SNDRV_CHMAP_RRC] = "RRC",
0087 };
0088
0089
0090
0091
0092 static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct snd_info_buffer *buffer)
0093 {
0094 struct audioformat *fp;
0095 static const char * const sync_types[4] = {
0096 "NONE", "ASYNC", "ADAPTIVE", "SYNC"
0097 };
0098
0099 list_for_each_entry(fp, &subs->fmt_list, list) {
0100 snd_pcm_format_t fmt;
0101
0102 snd_iprintf(buffer, " Interface %d\n", fp->iface);
0103 snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
0104 snd_iprintf(buffer, " Format:");
0105 pcm_for_each_format(fmt)
0106 if (fp->formats & pcm_format_to_bits(fmt))
0107 snd_iprintf(buffer, " %s",
0108 snd_pcm_format_name(fmt));
0109 snd_iprintf(buffer, "\n");
0110 snd_iprintf(buffer, " Channels: %d\n", fp->channels);
0111 snd_iprintf(buffer, " Endpoint: 0x%02x (%d %s) (%s)\n",
0112 fp->endpoint,
0113 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,
0114 fp->endpoint & USB_DIR_IN ? "IN" : "OUT",
0115 sync_types[(fp->ep_attr & USB_ENDPOINT_SYNCTYPE) >> 2]);
0116 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
0117 snd_iprintf(buffer, " Rates: %d - %d (continuous)\n",
0118 fp->rate_min, fp->rate_max);
0119 } else {
0120 unsigned int i;
0121 snd_iprintf(buffer, " Rates: ");
0122 for (i = 0; i < fp->nr_rates; i++) {
0123 if (i > 0)
0124 snd_iprintf(buffer, ", ");
0125 snd_iprintf(buffer, "%d", fp->rate_table[i]);
0126 }
0127 snd_iprintf(buffer, "\n");
0128 }
0129 if (subs->speed != USB_SPEED_FULL)
0130 snd_iprintf(buffer, " Data packet interval: %d us\n",
0131 125 * (1 << fp->datainterval));
0132 snd_iprintf(buffer, " Bits: %d\n", fp->fmt_bits);
0133
0134 if (fp->dsd_raw)
0135 snd_iprintf(buffer, " DSD raw: DOP=%d, bitrev=%d\n",
0136 fp->dsd_dop, fp->dsd_bitrev);
0137
0138 if (fp->chmap) {
0139 const struct snd_pcm_chmap_elem *map = fp->chmap;
0140 int c;
0141
0142 snd_iprintf(buffer, " Channel map:");
0143 for (c = 0; c < map->channels; c++) {
0144 if (map->map[c] >= ARRAY_SIZE(channel_labels) ||
0145 !channel_labels[map->map[c]])
0146 snd_iprintf(buffer, " --");
0147 else
0148 snd_iprintf(buffer, " %s",
0149 channel_labels[map->map[c]]);
0150 }
0151 snd_iprintf(buffer, "\n");
0152 }
0153
0154 if (fp->sync_ep) {
0155 snd_iprintf(buffer, " Sync Endpoint: 0x%02x (%d %s)\n",
0156 fp->sync_ep,
0157 fp->sync_ep & USB_ENDPOINT_NUMBER_MASK,
0158 fp->sync_ep & USB_DIR_IN ? "IN" : "OUT");
0159 snd_iprintf(buffer, " Sync EP Interface: %d\n",
0160 fp->sync_iface);
0161 snd_iprintf(buffer, " Sync EP Altset: %d\n",
0162 fp->sync_altsetting);
0163 snd_iprintf(buffer, " Implicit Feedback Mode: %s\n",
0164 fp->implicit_fb ? "Yes" : "No");
0165 }
0166
0167
0168
0169 }
0170 }
0171
0172 static void proc_dump_ep_status(struct snd_usb_substream *subs,
0173 struct snd_usb_endpoint *data_ep,
0174 struct snd_usb_endpoint *sync_ep,
0175 struct snd_info_buffer *buffer)
0176 {
0177 if (!data_ep)
0178 return;
0179 snd_iprintf(buffer, " Packet Size = %d\n", data_ep->curpacksize);
0180 snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n",
0181 subs->speed == USB_SPEED_FULL
0182 ? get_full_speed_hz(data_ep->freqm)
0183 : get_high_speed_hz(data_ep->freqm),
0184 data_ep->freqm >> 16, data_ep->freqm & 0xffff);
0185 if (sync_ep && data_ep->freqshift != INT_MIN) {
0186 int res = 16 - data_ep->freqshift;
0187 snd_iprintf(buffer, " Feedback Format = %d.%d\n",
0188 (sync_ep->syncmaxsize > 3 ? 32 : 24) - res, res);
0189 }
0190 }
0191
0192 static void proc_dump_substream_status(struct snd_usb_audio *chip,
0193 struct snd_usb_substream *subs,
0194 struct snd_info_buffer *buffer)
0195 {
0196 mutex_lock(&chip->mutex);
0197 if (subs->running) {
0198 snd_iprintf(buffer, " Status: Running\n");
0199 if (subs->cur_audiofmt) {
0200 snd_iprintf(buffer, " Interface = %d\n", subs->cur_audiofmt->iface);
0201 snd_iprintf(buffer, " Altset = %d\n", subs->cur_audiofmt->altsetting);
0202 }
0203 proc_dump_ep_status(subs, subs->data_endpoint, subs->sync_endpoint, buffer);
0204 } else {
0205 snd_iprintf(buffer, " Status: Stop\n");
0206 }
0207 mutex_unlock(&chip->mutex);
0208 }
0209
0210 static void proc_pcm_format_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
0211 {
0212 struct snd_usb_stream *stream = entry->private_data;
0213 struct snd_usb_audio *chip = stream->chip;
0214
0215 snd_iprintf(buffer, "%s : %s\n", chip->card->longname, stream->pcm->name);
0216
0217 if (stream->substream[SNDRV_PCM_STREAM_PLAYBACK].num_formats) {
0218 snd_iprintf(buffer, "\nPlayback:\n");
0219 proc_dump_substream_status(chip, &stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
0220 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_PLAYBACK], buffer);
0221 }
0222 if (stream->substream[SNDRV_PCM_STREAM_CAPTURE].num_formats) {
0223 snd_iprintf(buffer, "\nCapture:\n");
0224 proc_dump_substream_status(chip, &stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
0225 proc_dump_substream_formats(&stream->substream[SNDRV_PCM_STREAM_CAPTURE], buffer);
0226 }
0227 }
0228
0229 void snd_usb_proc_pcm_format_add(struct snd_usb_stream *stream)
0230 {
0231 char name[32];
0232 struct snd_card *card = stream->chip->card;
0233
0234 sprintf(name, "stream%d", stream->pcm_index);
0235 snd_card_ro_proc_new(card, name, stream, proc_pcm_format_read);
0236 }
0237