brintos

brintos / linux-shallow public Read only

0
0
Text · 6.2 KiB · a166672 Raw
204 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *  Support for Digigram Lola PCI-e boards4 *5 *  Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>6 */7 8#include <linux/kernel.h>9#include <linux/init.h>10#include <linux/io.h>11#include <sound/core.h>12#include <sound/info.h>13#include <sound/pcm.h>14#include "lola.h"15 16static void print_audio_widget(struct snd_info_buffer *buffer,17			       struct lola *chip, int nid, const char *name)18{19	unsigned int val;20 21	lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);22	snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);23	lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val);24	snd_iprintf(buffer, "  Formats: 0x%x\n", val);25}26 27static void print_pin_widget(struct snd_info_buffer *buffer,28			     struct lola *chip, int nid, unsigned int ampcap,29			     const char *name)30{31	unsigned int val;32 33	lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);34	snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val);35	if (val == 0x00400200)36		return;37	lola_read_param(chip, nid, ampcap, &val);38	snd_iprintf(buffer, "  Amp-Caps: 0x%x\n", val);39	snd_iprintf(buffer, "    mute=%d, step-size=%d, steps=%d, ofs=%d\n",40		    LOLA_AMP_MUTE_CAPABLE(val),41		    LOLA_AMP_STEP_SIZE(val),42		    LOLA_AMP_NUM_STEPS(val),43		    LOLA_AMP_OFFSET(val));44	lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, NULL);45	snd_iprintf(buffer, "  Max-level: 0x%x\n", val);46}47 48static void print_clock_widget(struct snd_info_buffer *buffer,49			       struct lola *chip, int nid)50{51	int i, j, num_clocks;52	unsigned int val;53 54	lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);55	snd_iprintf(buffer, "Node 0x%02x [Clock] wcaps 0x%x\n", nid, val);56	num_clocks = val & 0xff;57	for (i = 0; i < num_clocks; i += 4) {58		unsigned int res_ex;59		unsigned short items[4];60		const char *name;61 62		lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST,63				i, 0, &val, &res_ex);64		items[0] = val & 0xfff;65		items[1] = (val >> 16) & 0xfff;66		items[2] = res_ex & 0xfff;67		items[3] = (res_ex >> 16) & 0xfff;68		for (j = 0; j < 4; j++) {69			unsigned char type = items[j] >> 8;70			unsigned int freq = items[j] & 0xff;71			if (i + j >= num_clocks)72				break;73			if (type == LOLA_CLOCK_TYPE_INTERNAL) {74				name = "Internal";75				freq = lola_sample_rate_convert(freq);76			} else if (type == LOLA_CLOCK_TYPE_VIDEO) {77				name = "Video";78				freq = lola_sample_rate_convert(freq);79			} else {80				name = "Other";81			}82			snd_iprintf(buffer, "  Clock %d: Type %d:%s, freq=%d\n",83				    i + j, type, name, freq);84		}85	}86}87 88static void print_mixer_widget(struct snd_info_buffer *buffer,89			       struct lola *chip, int nid)90{91	unsigned int val;92 93	lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val);94	snd_iprintf(buffer, "Node 0x%02x [Mixer] wcaps 0x%x\n", nid, val);95}96 97static void lola_proc_codec_read(struct snd_info_entry *entry,98				 struct snd_info_buffer *buffer)99{100	struct lola *chip = entry->private_data;101	unsigned int val;102	int i, nid;103 104	lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);105	snd_iprintf(buffer, "Vendor: 0x%08x\n", val);106	lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);107	snd_iprintf(buffer, "Function Type: %d\n", val);108	lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);109	snd_iprintf(buffer, "Specific-Caps: 0x%08x\n", val);110	snd_iprintf(buffer, "  Pins-In %d, Pins-Out %d\n",111		    chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);112	nid = 2;113	for (i = 0; i < chip->pcm[CAPT].num_streams; i++, nid++)114		print_audio_widget(buffer, chip, nid, "[Audio-In]");115	for (i = 0; i < chip->pcm[PLAY].num_streams; i++, nid++)116		print_audio_widget(buffer, chip, nid, "[Audio-Out]");117	for (i = 0; i < chip->pin[CAPT].num_pins; i++, nid++)118		print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_IN_CAP,119				 "[Pin-In]");120	for (i = 0; i < chip->pin[PLAY].num_pins; i++, nid++)121		print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_OUT_CAP,122				 "[Pin-Out]");123	if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {124		print_clock_widget(buffer, chip, nid);125		nid++;126	}127	if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {128		print_mixer_widget(buffer, chip, nid);129		nid++;130	}131}132 133/* direct codec access for debugging */134static void lola_proc_codec_rw_write(struct snd_info_entry *entry,135				     struct snd_info_buffer *buffer)136{137	struct lola *chip = entry->private_data;138	char line[64];139	unsigned int id, verb, data, extdata;140	while (!snd_info_get_line(buffer, line, sizeof(line))) {141		if (sscanf(line, "%u %u %u %u", &id, &verb, &data, &extdata) != 4)142			continue;143		lola_codec_read(chip, id, verb, data, extdata,144				&chip->debug_res,145				&chip->debug_res_ex);146	}147}148 149static void lola_proc_codec_rw_read(struct snd_info_entry *entry,150				    struct snd_info_buffer *buffer)151{152	struct lola *chip = entry->private_data;153	snd_iprintf(buffer, "0x%x 0x%x\n", chip->debug_res, chip->debug_res_ex);154}155 156/*157 * dump some registers158 */159static void lola_proc_regs_read(struct snd_info_entry *entry,160				struct snd_info_buffer *buffer)161{162	struct lola *chip = entry->private_data;163	int i;164 165	for (i = 0; i < 0x40; i += 4) {166		snd_iprintf(buffer, "BAR0 %02x: %08x\n", i,167			    readl(chip->bar[BAR0].remap_addr + i));168	}169	snd_iprintf(buffer, "\n");170	for (i = 0; i < 0x30; i += 4) {171		snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,172			    readl(chip->bar[BAR1].remap_addr + i));173	}174	snd_iprintf(buffer, "\n");175	for (i = 0x80; i < 0xa0; i += 4) {176		snd_iprintf(buffer, "BAR1 %02x: %08x\n", i,177			    readl(chip->bar[BAR1].remap_addr + i));178	}179	snd_iprintf(buffer, "\n");180	for (i = 0; i < 32; i++) {181		snd_iprintf(buffer, "DSD %02x STS  %08x\n", i,182			    lola_dsd_read(chip, i, STS));183		snd_iprintf(buffer, "DSD %02x LPIB %08x\n", i,184			    lola_dsd_read(chip, i, LPIB));185		snd_iprintf(buffer, "DSD %02x CTL  %08x\n", i,186			    lola_dsd_read(chip, i, CTL));187		snd_iprintf(buffer, "DSD %02x LVIL %08x\n", i,188			    lola_dsd_read(chip, i, LVI));189		snd_iprintf(buffer, "DSD %02x BDPL %08x\n", i,190			    lola_dsd_read(chip, i, BDPL));191		snd_iprintf(buffer, "DSD %02x BDPU %08x\n", i,192			    lola_dsd_read(chip, i, BDPU));193	}194}195 196void lola_proc_debug_new(struct lola *chip)197{198	snd_card_ro_proc_new(chip->card, "codec", chip, lola_proc_codec_read);199	snd_card_rw_proc_new(chip->card, "codec_rw", chip,200			     lola_proc_codec_rw_read,201			     lola_proc_codec_rw_write);202	snd_card_ro_proc_new(chip->card, "regs", chip, lola_proc_regs_read);203}204