aboutsummaryrefslogtreecommitdiffstats
path: root/sound/drivers/dummy.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-09-08 08:30:49 -0400
committerTakashi Iwai <tiwai@suse.de>2009-09-08 08:46:49 -0400
commit9b151fec139d32ab3acce5da5761d868e205fadd (patch)
tree2793cabf9420d2a3b8f8026cab4cc1386f0f04b6 /sound/drivers/dummy.c
parent4f7454a9970fa0f3e9f1a68201520e3df1bb5224 (diff)
ALSA: dummy - Add debug proc file
Added the debug proc file to see or change the snd_pcm_hardware fields to emulate. The parameters can be changed by writing to a proc file like: # echo periods_min 4 > /proc/asound/card1/dummy_pcm Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/drivers/dummy.c')
-rw-r--r--sound/drivers/dummy.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 2ee6c8ebe25a..ccfbdfa75511 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -33,6 +33,7 @@
33#include <sound/tlv.h> 33#include <sound/tlv.h>
34#include <sound/pcm.h> 34#include <sound/pcm.h>
35#include <sound/rawmidi.h> 35#include <sound/rawmidi.h>
36#include <sound/info.h>
36#include <sound/initval.h> 37#include <sound/initval.h>
37 38
38MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 39MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -686,6 +687,10 @@ static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
686 return 0; 687 return 0;
687} 688}
688 689
690/*
691 * mixer interface
692 */
693
689#define DUMMY_VOLUME(xname, xindex, addr) \ 694#define DUMMY_VOLUME(xname, xindex, addr) \
690{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 695{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
691 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ 696 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
@@ -816,6 +821,131 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
816 return 0; 821 return 0;
817} 822}
818 823
824#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_PROC_FS)
825/*
826 * proc interface
827 */
828static void print_formats(struct snd_info_buffer *buffer)
829{
830 int i;
831
832 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
833 if (dummy_pcm_hardware.formats & (1ULL << i))
834 snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
835 }
836}
837
838static void print_rates(struct snd_info_buffer *buffer)
839{
840 static int rates[] = {
841 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
842 64000, 88200, 96000, 176400, 192000,
843 };
844 int i;
845
846 if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_CONTINUOUS)
847 snd_iprintf(buffer, " continuous");
848 if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_KNOT)
849 snd_iprintf(buffer, " knot");
850 for (i = 0; i < ARRAY_SIZE(rates); i++)
851 if (dummy_pcm_hardware.rates & (1 << i))
852 snd_iprintf(buffer, " %d", rates[i]);
853}
854
855#define get_dummy_int_ptr(ofs) \
856 (unsigned int *)((char *)&dummy_pcm_hardware + (ofs))
857#define get_dummy_ll_ptr(ofs) \
858 (unsigned long long *)((char *)&dummy_pcm_hardware + (ofs))
859
860struct dummy_hw_field {
861 const char *name;
862 const char *format;
863 unsigned int offset;
864 unsigned int size;
865};
866#define FIELD_ENTRY(item, fmt) { \
867 .name = #item, \
868 .format = fmt, \
869 .offset = offsetof(struct snd_pcm_hardware, item), \
870 .size = sizeof(dummy_pcm_hardware.item) }
871
872static struct dummy_hw_field fields[] = {
873 FIELD_ENTRY(formats, "%#llx"),
874 FIELD_ENTRY(rates, "%#x"),
875 FIELD_ENTRY(rate_min, "%d"),
876 FIELD_ENTRY(rate_max, "%d"),
877 FIELD_ENTRY(channels_min, "%d"),
878 FIELD_ENTRY(channels_max, "%d"),
879 FIELD_ENTRY(buffer_bytes_max, "%ld"),
880 FIELD_ENTRY(period_bytes_min, "%ld"),
881 FIELD_ENTRY(period_bytes_max, "%ld"),
882 FIELD_ENTRY(periods_min, "%d"),
883 FIELD_ENTRY(periods_max, "%d"),
884};
885
886static void dummy_proc_read(struct snd_info_entry *entry,
887 struct snd_info_buffer *buffer)
888{
889 int i;
890
891 for (i = 0; i < ARRAY_SIZE(fields); i++) {
892 snd_iprintf(buffer, "%s ", fields[i].name);
893 if (fields[i].size == sizeof(int))
894 snd_iprintf(buffer, fields[i].format,
895 *get_dummy_int_ptr(fields[i].offset));
896 else
897 snd_iprintf(buffer, fields[i].format,
898 *get_dummy_ll_ptr(fields[i].offset));
899 if (!strcmp(fields[i].name, "formats"))
900 print_formats(buffer);
901 else if (!strcmp(fields[i].name, "rates"))
902 print_rates(buffer);
903 snd_iprintf(buffer, "\n");
904 }
905}
906
907static void dummy_proc_write(struct snd_info_entry *entry,
908 struct snd_info_buffer *buffer)
909{
910 char line[64];
911
912 while (!snd_info_get_line(buffer, line, sizeof(line))) {
913 char item[20];
914 const char *ptr;
915 unsigned long long val;
916 int i;
917
918 ptr = snd_info_get_str(item, line, sizeof(item));
919 for (i = 0; i < ARRAY_SIZE(fields); i++) {
920 if (!strcmp(item, fields[i].name))
921 break;
922 }
923 if (i >= ARRAY_SIZE(fields))
924 continue;
925 snd_info_get_str(item, ptr, sizeof(item));
926 if (strict_strtoull(item, 0, &val))
927 continue;
928 if (fields[i].size == sizeof(int))
929 *get_dummy_int_ptr(fields[i].offset) = val;
930 else
931 *get_dummy_ll_ptr(fields[i].offset) = val;
932 }
933}
934
935static void __devinit dummy_proc_init(struct snd_dummy *chip)
936{
937 struct snd_info_entry *entry;
938
939 if (!snd_card_proc_new(chip->card, "dummy_pcm", &entry)) {
940 snd_info_set_text_ops(entry, chip, dummy_proc_read);
941 entry->c.text.write = dummy_proc_write;
942 entry->mode |= S_IWUSR;
943 }
944}
945#else
946#define dummy_proc_init(x)
947#endif /* CONFIG_SND_DEBUG && CONFIG_PROC_FS */
948
819static int __devinit snd_dummy_probe(struct platform_device *devptr) 949static int __devinit snd_dummy_probe(struct platform_device *devptr)
820{ 950{
821 struct snd_card *card; 951 struct snd_card *card;
@@ -845,6 +975,8 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
845 strcpy(card->shortname, "Dummy"); 975 strcpy(card->shortname, "Dummy");
846 sprintf(card->longname, "Dummy %i", dev + 1); 976 sprintf(card->longname, "Dummy %i", dev + 1);
847 977
978 dummy_proc_init(dummy);
979
848 snd_card_set_dev(card, &devptr->dev); 980 snd_card_set_dev(card, &devptr->dev);
849 981
850 err = snd_card_register(card); 982 err = snd_card_register(card);