2019-05-27 08:55:05 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2011-05-03 16:14:46 +02:00
/*
* Support for Digigram Lola PCI - e boards
*
* Copyright ( c ) 2011 Takashi Iwai < tiwai @ suse . de >
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/io.h>
# include <sound/core.h>
# include <sound/info.h>
# include <sound/pcm.h>
# include "lola.h"
2011-05-03 16:32:48 +02:00
static void print_audio_widget ( struct snd_info_buffer * buffer ,
struct lola * chip , int nid , const char * name )
{
unsigned int val ;
lola_read_param ( chip , nid , LOLA_PAR_AUDIO_WIDGET_CAP , & val ) ;
snd_iprintf ( buffer , " Node 0x%02x %s wcaps 0x%x \n " , nid , name , val ) ;
lola_read_param ( chip , nid , LOLA_PAR_STREAM_FORMATS , & val ) ;
snd_iprintf ( buffer , " Formats: 0x%x \n " , val ) ;
}
static void print_pin_widget ( struct snd_info_buffer * buffer ,
struct lola * chip , int nid , unsigned int ampcap ,
const char * name )
{
unsigned int val ;
lola_read_param ( chip , nid , LOLA_PAR_AUDIO_WIDGET_CAP , & val ) ;
snd_iprintf ( buffer , " Node 0x%02x %s wcaps 0x%x \n " , nid , name , val ) ;
if ( val = = 0x00400200 )
return ;
lola_read_param ( chip , nid , ampcap , & val ) ;
snd_iprintf ( buffer , " Amp-Caps: 0x%x \n " , val ) ;
snd_iprintf ( buffer , " mute=%d, step-size=%d, steps=%d, ofs=%d \n " ,
LOLA_AMP_MUTE_CAPABLE ( val ) ,
LOLA_AMP_STEP_SIZE ( val ) ,
LOLA_AMP_NUM_STEPS ( val ) ,
LOLA_AMP_OFFSET ( val ) ) ;
lola_codec_read ( chip , nid , LOLA_VERB_GET_MAX_LEVEL , 0 , 0 , & val , NULL ) ;
snd_iprintf ( buffer , " Max-level: 0x%x \n " , val ) ;
}
static void print_clock_widget ( struct snd_info_buffer * buffer ,
struct lola * chip , int nid )
{
int i , j , num_clocks ;
unsigned int val ;
lola_read_param ( chip , nid , LOLA_PAR_AUDIO_WIDGET_CAP , & val ) ;
snd_iprintf ( buffer , " Node 0x%02x [Clock] wcaps 0x%x \n " , nid , val ) ;
num_clocks = val & 0xff ;
for ( i = 0 ; i < num_clocks ; i + = 4 ) {
unsigned int res_ex ;
unsigned short items [ 4 ] ;
const char * name ;
lola_codec_read ( chip , nid , LOLA_VERB_GET_CLOCK_LIST ,
i , 0 , & val , & res_ex ) ;
items [ 0 ] = val & 0xfff ;
items [ 1 ] = ( val > > 16 ) & 0xfff ;
items [ 2 ] = res_ex & 0xfff ;
items [ 3 ] = ( res_ex > > 16 ) & 0xfff ;
for ( j = 0 ; j < 4 ; j + + ) {
unsigned char type = items [ j ] > > 8 ;
unsigned int freq = items [ j ] & 0xff ;
if ( i + j > = num_clocks )
break ;
if ( type = = LOLA_CLOCK_TYPE_INTERNAL ) {
name = " Internal " ;
freq = lola_sample_rate_convert ( freq ) ;
} else if ( type = = LOLA_CLOCK_TYPE_VIDEO ) {
name = " Video " ;
freq = lola_sample_rate_convert ( freq ) ;
} else {
name = " Other " ;
}
snd_iprintf ( buffer , " Clock %d: Type %d:%s, freq=%d \n " ,
i + j , type , name , freq ) ;
}
}
}
static void print_mixer_widget ( struct snd_info_buffer * buffer ,
struct lola * chip , int nid )
{
unsigned int val ;
lola_read_param ( chip , nid , LOLA_PAR_AUDIO_WIDGET_CAP , & val ) ;
snd_iprintf ( buffer , " Node 0x%02x [Mixer] wcaps 0x%x \n " , nid , val ) ;
}
static void lola_proc_codec_read ( struct snd_info_entry * entry ,
struct snd_info_buffer * buffer )
{
struct lola * chip = entry - > private_data ;
unsigned int val ;
int i , nid ;
lola_read_param ( chip , 0 , LOLA_PAR_VENDOR_ID , & val ) ;
snd_iprintf ( buffer , " Vendor: 0x%08x \n " , val ) ;
lola_read_param ( chip , 1 , LOLA_PAR_FUNCTION_TYPE , & val ) ;
snd_iprintf ( buffer , " Function Type: %d \n " , val ) ;
lola_read_param ( chip , 1 , LOLA_PAR_SPECIFIC_CAPS , & val ) ;
snd_iprintf ( buffer , " Specific-Caps: 0x%08x \n " , val ) ;
snd_iprintf ( buffer , " Pins-In %d, Pins-Out %d \n " ,
chip - > pin [ CAPT ] . num_pins , chip - > pin [ PLAY ] . num_pins ) ;
nid = 2 ;
for ( i = 0 ; i < chip - > pcm [ CAPT ] . num_streams ; i + + , nid + + )
print_audio_widget ( buffer , chip , nid , " [Audio-In] " ) ;
for ( i = 0 ; i < chip - > pcm [ PLAY ] . num_streams ; i + + , nid + + )
print_audio_widget ( buffer , chip , nid , " [Audio-Out] " ) ;
for ( i = 0 ; i < chip - > pin [ CAPT ] . num_pins ; i + + , nid + + )
print_pin_widget ( buffer , chip , nid , LOLA_PAR_AMP_IN_CAP ,
" [Pin-In] " ) ;
for ( i = 0 ; i < chip - > pin [ PLAY ] . num_pins ; i + + , nid + + )
print_pin_widget ( buffer , chip , nid , LOLA_PAR_AMP_OUT_CAP ,
" [Pin-Out] " ) ;
if ( LOLA_AFG_CLOCK_WIDGET_PRESENT ( chip - > lola_caps ) ) {
print_clock_widget ( buffer , chip , nid ) ;
nid + + ;
}
if ( LOLA_AFG_MIXER_WIDGET_PRESENT ( chip - > lola_caps ) ) {
print_mixer_widget ( buffer , chip , nid ) ;
nid + + ;
}
}
2011-05-03 16:14:46 +02:00
/* direct codec access for debugging */
2011-05-03 16:32:48 +02:00
static void lola_proc_codec_rw_write ( struct snd_info_entry * entry ,
struct snd_info_buffer * buffer )
2011-05-03 16:14:46 +02:00
{
struct lola * chip = entry - > private_data ;
char line [ 64 ] ;
unsigned int id , verb , data , extdata ;
while ( ! snd_info_get_line ( buffer , line , sizeof ( line ) ) ) {
2014-05-20 19:22:17 +02:00
if ( sscanf ( line , " %u %u %u %u " , & id , & verb , & data , & extdata ) ! = 4 )
2011-05-03 16:14:46 +02:00
continue ;
lola_codec_read ( chip , id , verb , data , extdata ,
& chip - > debug_res ,
& chip - > debug_res_ex ) ;
}
}
2011-05-03 16:32:48 +02:00
static void lola_proc_codec_rw_read ( struct snd_info_entry * entry ,
struct snd_info_buffer * buffer )
2011-05-03 16:14:46 +02:00
{
struct lola * chip = entry - > private_data ;
snd_iprintf ( buffer , " 0x%x 0x%x \n " , chip - > debug_res , chip - > debug_res_ex ) ;
}
/*
* dump some registers
*/
static void lola_proc_regs_read ( struct snd_info_entry * entry ,
struct snd_info_buffer * buffer )
{
struct lola * chip = entry - > private_data ;
int i ;
for ( i = 0 ; i < 0x40 ; i + = 4 ) {
snd_iprintf ( buffer , " BAR0 %02x: %08x \n " , i ,
readl ( chip - > bar [ BAR0 ] . remap_addr + i ) ) ;
}
2011-05-03 16:32:48 +02:00
snd_iprintf ( buffer , " \n " ) ;
2011-05-03 16:14:46 +02:00
for ( i = 0 ; i < 0x30 ; i + = 4 ) {
snd_iprintf ( buffer , " BAR1 %02x: %08x \n " , i ,
readl ( chip - > bar [ BAR1 ] . remap_addr + i ) ) ;
}
2011-05-03 16:32:48 +02:00
snd_iprintf ( buffer , " \n " ) ;
2011-05-03 16:14:46 +02:00
for ( i = 0x80 ; i < 0xa0 ; i + = 4 ) {
snd_iprintf ( buffer , " BAR1 %02x: %08x \n " , i ,
readl ( chip - > bar [ BAR1 ] . remap_addr + i ) ) ;
}
2011-05-03 16:32:48 +02:00
snd_iprintf ( buffer , " \n " ) ;
for ( i = 0 ; i < 32 ; i + + ) {
snd_iprintf ( buffer , " DSD %02x STS %08x \n " , i ,
lola_dsd_read ( chip , i , STS ) ) ;
snd_iprintf ( buffer , " DSD %02x LPIB %08x \n " , i ,
lola_dsd_read ( chip , i , LPIB ) ) ;
snd_iprintf ( buffer , " DSD %02x CTL %08x \n " , i ,
lola_dsd_read ( chip , i , CTL ) ) ;
snd_iprintf ( buffer , " DSD %02x LVIL %08x \n " , i ,
lola_dsd_read ( chip , i , LVI ) ) ;
snd_iprintf ( buffer , " DSD %02x BDPL %08x \n " , i ,
lola_dsd_read ( chip , i , BDPL ) ) ;
snd_iprintf ( buffer , " DSD %02x BDPU %08x \n " , i ,
lola_dsd_read ( chip , i , BDPU ) ) ;
}
2011-05-03 16:14:46 +02:00
}
2012-12-06 12:35:10 -05:00
void lola_proc_debug_new ( struct lola * chip )
2011-05-03 16:14:46 +02:00
{
2019-02-04 16:01:39 +01:00
snd_card_ro_proc_new ( chip - > card , " codec " , chip , lola_proc_codec_read ) ;
snd_card_rw_proc_new ( chip - > card , " codec_rw " , chip ,
lola_proc_codec_rw_read ,
lola_proc_codec_rw_write ) ;
snd_card_ro_proc_new ( chip - > card , " regs " , chip , lola_proc_regs_read ) ;
2011-05-03 16:14:46 +02:00
}