static int get_hardware_info(struct snd_efw *efw) { struct fw_device *fw_dev = fw_parent_device(efw->unit); struct snd_efw_hwinfo *hwinfo; char version[12] = {0}; int err; hwinfo = kzalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL); if (hwinfo == NULL) return -ENOMEM; err = snd_efw_command_get_hwinfo(efw, hwinfo); if (err < 0) goto end; /* firmware version for communication chipset */ snprintf(version, sizeof(version), "%u.%u", (hwinfo->arm_version >> 24) & 0xff, (hwinfo->arm_version >> 16) & 0xff); efw->firmware_version = hwinfo->arm_version; strcpy(efw->card->driver, "Fireworks"); strcpy(efw->card->shortname, hwinfo->model_name); strcpy(efw->card->mixername, hwinfo->model_name); snprintf(efw->card->longname, sizeof(efw->card->longname), "%s %s v%s, GUID %08x%08x at %s, S%d", hwinfo->vendor_name, hwinfo->model_name, version, hwinfo->guid_hi, hwinfo->guid_lo, dev_name(&efw->unit->device), 100 << fw_dev->max_speed); if (hwinfo->flags & BIT(FLAG_RESP_ADDR_CHANGABLE)) efw->resp_addr_changable = true; efw->supported_sampling_rate = 0; if ((hwinfo->min_sample_rate <= 22050) && (22050 <= hwinfo->max_sample_rate)) efw->supported_sampling_rate |= SNDRV_PCM_RATE_22050; if ((hwinfo->min_sample_rate <= 32000) && (32000 <= hwinfo->max_sample_rate)) efw->supported_sampling_rate |= SNDRV_PCM_RATE_32000; if ((hwinfo->min_sample_rate <= 44100) && (44100 <= hwinfo->max_sample_rate)) efw->supported_sampling_rate |= SNDRV_PCM_RATE_44100; if ((hwinfo->min_sample_rate <= 48000) && (48000 <= hwinfo->max_sample_rate)) efw->supported_sampling_rate |= SNDRV_PCM_RATE_48000; if ((hwinfo->min_sample_rate <= 88200) && (88200 <= hwinfo->max_sample_rate)) efw->supported_sampling_rate |= SNDRV_PCM_RATE_88200; if ((hwinfo->min_sample_rate <= 96000) && (96000 <= hwinfo->max_sample_rate)) efw->supported_sampling_rate |= SNDRV_PCM_RATE_96000; if ((hwinfo->min_sample_rate <= 176400) && (176400 <= hwinfo->max_sample_rate)) efw->supported_sampling_rate |= SNDRV_PCM_RATE_176400; if ((hwinfo->min_sample_rate <= 192000) && (192000 <= hwinfo->max_sample_rate)) efw->supported_sampling_rate |= SNDRV_PCM_RATE_192000; /* the number of MIDI ports, not of MIDI conformant data channels */ if (hwinfo->midi_out_ports > SND_EFW_MAX_MIDI_OUT_PORTS || hwinfo->midi_in_ports > SND_EFW_MAX_MIDI_IN_PORTS) { err = -EIO; goto end; } efw->midi_out_ports = hwinfo->midi_out_ports; efw->midi_in_ports = hwinfo->midi_in_ports; if (hwinfo->amdtp_tx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM || hwinfo->amdtp_tx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM || hwinfo->amdtp_tx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM || hwinfo->amdtp_rx_pcm_channels > AMDTP_MAX_CHANNELS_FOR_PCM || hwinfo->amdtp_rx_pcm_channels_2x > AMDTP_MAX_CHANNELS_FOR_PCM || hwinfo->amdtp_rx_pcm_channels_4x > AMDTP_MAX_CHANNELS_FOR_PCM) { err = -ENOSYS; goto end; } efw->pcm_capture_channels[0] = hwinfo->amdtp_tx_pcm_channels; efw->pcm_capture_channels[1] = hwinfo->amdtp_tx_pcm_channels_2x; efw->pcm_capture_channels[2] = hwinfo->amdtp_tx_pcm_channels_4x; efw->pcm_playback_channels[0] = hwinfo->amdtp_rx_pcm_channels; efw->pcm_playback_channels[1] = hwinfo->amdtp_rx_pcm_channels_2x; efw->pcm_playback_channels[2] = hwinfo->amdtp_rx_pcm_channels_4x; /* Hardware metering. */ if (hwinfo->phys_in_grp_count > HWINFO_MAX_CAPS_GROUPS || hwinfo->phys_out_grp_count > HWINFO_MAX_CAPS_GROUPS) { err = -EIO; goto end; } efw->phys_in = hwinfo->phys_in; efw->phys_out = hwinfo->phys_out; efw->phys_in_grp_count = hwinfo->phys_in_grp_count; efw->phys_out_grp_count = hwinfo->phys_out_grp_count; memcpy(&efw->phys_in_grps, hwinfo->phys_in_grps, sizeof(struct snd_efw_phys_grp) * hwinfo->phys_in_grp_count); memcpy(&efw->phys_out_grps, hwinfo->phys_out_grps, sizeof(struct snd_efw_phys_grp) * hwinfo->phys_out_grp_count); end: kfree(hwinfo); return err; }
static void proc_read_hwinfo(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct snd_efw *efw = entry->private_data; unsigned short i; struct snd_efw_hwinfo *hwinfo; hwinfo = kmalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL); if (hwinfo == NULL) return; if (snd_efw_command_get_hwinfo(efw, hwinfo) < 0) goto end; snd_iprintf(buffer, "guid_hi: 0x%X\n", hwinfo->guid_hi); snd_iprintf(buffer, "guid_lo: 0x%X\n", hwinfo->guid_lo); snd_iprintf(buffer, "type: 0x%X\n", hwinfo->type); snd_iprintf(buffer, "version: 0x%X\n", hwinfo->version); snd_iprintf(buffer, "vendor_name: %s\n", hwinfo->vendor_name); snd_iprintf(buffer, "model_name: %s\n", hwinfo->model_name); snd_iprintf(buffer, "dsp_version: 0x%X\n", hwinfo->dsp_version); snd_iprintf(buffer, "arm_version: 0x%X\n", hwinfo->arm_version); snd_iprintf(buffer, "fpga_version: 0x%X\n", hwinfo->fpga_version); snd_iprintf(buffer, "flags: 0x%X\n", hwinfo->flags); snd_iprintf(buffer, "max_sample_rate: 0x%X\n", hwinfo->max_sample_rate); snd_iprintf(buffer, "min_sample_rate: 0x%X\n", hwinfo->min_sample_rate); snd_iprintf(buffer, "supported_clock: 0x%X\n", hwinfo->supported_clocks); snd_iprintf(buffer, "phys out: 0x%X\n", hwinfo->phys_out); snd_iprintf(buffer, "phys in: 0x%X\n", hwinfo->phys_in); snd_iprintf(buffer, "phys in grps: 0x%X\n", hwinfo->phys_in_grp_count); for (i = 0; i < hwinfo->phys_in_grp_count; i++) { snd_iprintf(buffer, "phys in grp[%d]: type 0x%X, count 0x%X\n", i, hwinfo->phys_out_grps[i].type, hwinfo->phys_out_grps[i].count); } snd_iprintf(buffer, "phys out grps: 0x%X\n", hwinfo->phys_out_grp_count); for (i = 0; i < hwinfo->phys_out_grp_count; i++) { snd_iprintf(buffer, "phys out grps[%d]: type 0x%X, count 0x%X\n", i, hwinfo->phys_out_grps[i].type, hwinfo->phys_out_grps[i].count); } snd_iprintf(buffer, "amdtp rx pcm channels 1x: 0x%X\n", hwinfo->amdtp_rx_pcm_channels); snd_iprintf(buffer, "amdtp tx pcm channels 1x: 0x%X\n", hwinfo->amdtp_tx_pcm_channels); snd_iprintf(buffer, "amdtp rx pcm channels 2x: 0x%X\n", hwinfo->amdtp_rx_pcm_channels_2x); snd_iprintf(buffer, "amdtp tx pcm channels 2x: 0x%X\n", hwinfo->amdtp_tx_pcm_channels_2x); snd_iprintf(buffer, "amdtp rx pcm channels 4x: 0x%X\n", hwinfo->amdtp_rx_pcm_channels_4x); snd_iprintf(buffer, "amdtp tx pcm channels 4x: 0x%X\n", hwinfo->amdtp_tx_pcm_channels_4x); snd_iprintf(buffer, "midi out ports: 0x%X\n", hwinfo->midi_out_ports); snd_iprintf(buffer, "midi in ports: 0x%X\n", hwinfo->midi_in_ports); snd_iprintf(buffer, "mixer playback channels: 0x%X\n", hwinfo->mixer_playback_channels); snd_iprintf(buffer, "mixer capture channels: 0x%X\n", hwinfo->mixer_capture_channels); end: kfree(hwinfo); }