At Thu, 13 Nov 2008 10:21:53 +0800, Wu Fengguang wrote:
Create hda_eld.c for ELD routines and proc interface.
Thanks for the patch!
ELD handling routines can be shared by all HDMI codecs, and they are large enough to make a standalone source file.
Some notes on the code:
- Shall we show an empty file if the ELD content is not valid? Well it's not that simple. There could be partially populated ELD, and there may be malformed ELD provided by buggy drivers/monitors. So I tend to expose ELD as it is.
Fair enough.
- hdmi_show_eld() and hdmi_print_eld_info() are somehow duplicated The plan is to shrink hdmi_show_eld()/hdmi_show_short_audio_desc(), and to show a compact message at monitor hotplug and driver initialization time.
You can create a common print function to accept the callback, such as,
static void hdmi_print(void (*print)(void *, const char *line), void *data, const char *fmt, ...) { char line[80]; va_list ap; va_start(fp, fmt); vsnprintf(line, sizeof(line), fmt, ap); va_end(ap); print(data, line); }
static void hdmi_print_eld(void (*print)(void *, const char *), void *data, struct sink_eld *e) { hdmi_print(print, data, "monitor name\t\t%s\n", e->monitor_name); ... } static void print_proc(void *data, const char *line) { snd_iprintf(data, "%s", line); }
static void hdmi_print_eld_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { hdmi_print_eld(print_proc, buffer, entry->private_data); }
static void print_console(void *data, const char *line) { printk(KERN_DEBUG "%s", line); }
void snd_hdmi_show_eld(struct sink_eld *e) { hdmi_print_eld(print_console, NULL, e); }
Just an idea, though.
The ELD retrieval routines rely on the Intel HDA interface, others are/could be universal and independent ones.
The ELD proc interface code could be moved to hda_proc.c if necessary.
- How do we name the proc file? If there are going to be two HDMI pins per codec, then the current naming scheme (eld#<codec no>) will fail.
In theory, yes, but I don't think this would happen. If this is needed, the currently existing codec#* proc must be fixed, too. So, we can use eld#codec as the simplest way.
Some review comments below:
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c
...
@@ -880,6 +410,11 @@ static int intel_hdmi_build_controls(str
static int intel_hdmi_init(struct hda_codec *codec) {
- struct intel_hdmi_spec *spec = codec->spec;
- struct sink_eld *eld = &spec->sink;
- snd_hda_eld_proc_new(codec, eld);
The proc creation should be rather in patch_intelhdmi(). The init callback is called also at suspend/resume usually.
/* disable audio output as early as possible */ hdmi_disable_output(codec);
@@ -927,3 +462,4 @@ struct hda_codec_preset snd_hda_preset_i { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, {} /* terminator */ };
Useless space addition.
--- /dev/null +++ sound-2.6/sound/pci/hda/hda_eld.c +static inline unsigned char grab_bits(const unsigned char *buf,
int byte, int lowbit, int bits)
+{
- BUG_ON(lowbit > 7);
- BUG_ON(bits > 8);
- BUG_ON(bits <= 0);
Can it be rather BUILD_BUG_ON(), BTW? Or, hmm, doesn't work if it's an inline function?
+int hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
I prefer snd_ prefix for global functions to avoid any potential name crashes.
+int hdmi_get_eld(struct sink_eld *eld,
struct hda_codec *codec, hda_nid_t nid)
Ditto.
+void hdmi_show_eld(struct sink_eld *e)
Ditto.
--- sound-2.6.orig/sound/pci/hda/Makefile +++ sound-2.6/sound/pci/hda/Makefile @@ -4,6 +4,7 @@ snd-hda-intel-y := hda_intel.o # designed to be individual modules snd-hda-intel-y += hda_codec.o snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o +snd-hda-intel-$(CONFIG_SND_HDA_ELD) += hda_eld.o snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o snd-hda-intel-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o --- sound-2.6.orig/sound/pci/hda/hda_local.h +++ sound-2.6/sound/pci/hda/hda_local.h @@ -276,15 +276,6 @@ static inline int snd_hda_parse_generic_ #endif
/*
- generic proc interface
- */
-#ifdef CONFIG_PROC_FS -int snd_hda_codec_proc_new(struct hda_codec *codec); -#else -static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } -#endif
...
+/*
- generic proc interface
- */
+#ifdef CONFIG_PROC_FS +int snd_hda_codec_proc_new(struct hda_codec *codec); +int snd_hda_eld_proc_new(struct hda_codec *codec, struct sink_eld *eld);
I'd put these two declarations rather separately, since snd_hda_proc_new() has nothing to do with ELD. Keep it in the original place.
thanks,
Takashi