~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to sound/pci/hda/hda_hwdep.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include <linux/compat.h>
25
25
#include <linux/mutex.h>
26
26
#include <linux/ctype.h>
 
27
#include <linux/string.h>
27
28
#include <linux/firmware.h>
28
29
#include <sound/core.h>
29
30
#include "hda_codec.h"
154
155
        return 0;
155
156
}
156
157
 
 
158
#ifdef CONFIG_SND_HDA_POWER_SAVE
 
159
static ssize_t power_on_acct_show(struct device *dev,
 
160
                                  struct device_attribute *attr,
 
161
                                  char *buf)
 
162
{
 
163
        struct snd_hwdep *hwdep = dev_get_drvdata(dev);
 
164
        struct hda_codec *codec = hwdep->private_data;
 
165
        snd_hda_update_power_acct(codec);
 
166
        return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_on_acct));
 
167
}
 
168
 
 
169
static ssize_t power_off_acct_show(struct device *dev,
 
170
                                   struct device_attribute *attr,
 
171
                                   char *buf)
 
172
{
 
173
        struct snd_hwdep *hwdep = dev_get_drvdata(dev);
 
174
        struct hda_codec *codec = hwdep->private_data;
 
175
        snd_hda_update_power_acct(codec);
 
176
        return sprintf(buf, "%u\n", jiffies_to_msecs(codec->power_off_acct));
 
177
}
 
178
 
 
179
static struct device_attribute power_attrs[] = {
 
180
        __ATTR_RO(power_on_acct),
 
181
        __ATTR_RO(power_off_acct),
 
182
};
 
183
 
 
184
int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
 
185
{
 
186
        struct snd_hwdep *hwdep = codec->hwdep;
 
187
        int i;
 
188
 
 
189
        for (i = 0; i < ARRAY_SIZE(power_attrs); i++)
 
190
                snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card,
 
191
                                          hwdep->device, &power_attrs[i]);
 
192
        return 0;
 
193
}
 
194
#endif /* CONFIG_SND_HDA_POWER_SAVE */
 
195
 
157
196
#ifdef CONFIG_SND_HDA_RECONFIG
158
197
 
159
198
/*
254
293
{                                                               \
255
294
        struct snd_hwdep *hwdep = dev_get_drvdata(dev);         \
256
295
        struct hda_codec *codec = hwdep->private_data;          \
257
 
        char *after;                                            \
258
 
        codec->type = simple_strtoul(buf, &after, 0);           \
 
296
        unsigned long val;                                      \
 
297
        int err = strict_strtoul(buf, 0, &val);                 \
 
298
        if (err < 0)                                            \
 
299
                return err;                                     \
 
300
        codec->type = val;                                      \
259
301
        return count;                                           \
260
302
}
261
303
 
390
432
        char *key, *val;
391
433
        struct hda_hint *hint;
392
434
 
393
 
        while (isspace(*buf))
394
 
                buf++;
 
435
        buf = skip_spaces(buf);
395
436
        if (!*buf || *buf == '#' || *buf == '\n')
396
437
                return 0;
397
438
        if (*buf == '=')
406
447
                return -EINVAL;
407
448
        }
408
449
        *val++ = 0;
409
 
        while (isspace(*val))
410
 
                val++;
 
450
        val = skip_spaces(val);
411
451
        remove_trail_spaces(key);
412
452
        remove_trail_spaces(val);
413
453
        hint = get_hint(codec, key);
585
625
        LINE_MODE_PINCFG,
586
626
        LINE_MODE_VERB,
587
627
        LINE_MODE_HINT,
 
628
        LINE_MODE_VENDOR_ID,
 
629
        LINE_MODE_SUBSYSTEM_ID,
 
630
        LINE_MODE_REVISION_ID,
 
631
        LINE_MODE_CHIP_NAME,
588
632
        NUM_LINE_MODES,
589
633
};
590
634
 
605
649
        *codecp = NULL;
606
650
        if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) {
607
651
                list_for_each_entry(codec, &bus->codec_list, list) {
608
 
                        if (codec->addr == caddr) {
 
652
                        if (codec->vendor_id == vendorid &&
 
653
                            codec->subsystem_id == subid &&
 
654
                            codec->addr == caddr) {
609
655
                                *codecp = codec;
610
656
                                break;
611
657
                        }
614
660
}
615
661
 
616
662
/* parse the contents after the other command tags, [pincfg], [verb],
617
 
 * [hint] and [model]
 
663
 * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
618
664
 * just pass to the sysfs helper (only when any codec was specified)
619
665
 */
620
666
static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
621
667
                              struct hda_codec **codecp)
622
668
{
623
 
        if (!*codecp)
624
 
                return;
625
669
        parse_user_pin_configs(*codecp, buf);
626
670
}
627
671
 
628
672
static void parse_verb_mode(char *buf, struct hda_bus *bus,
629
673
                            struct hda_codec **codecp)
630
674
{
631
 
        if (!*codecp)
632
 
                return;
633
675
        parse_init_verbs(*codecp, buf);
634
676
}
635
677
 
636
678
static void parse_hint_mode(char *buf, struct hda_bus *bus,
637
679
                            struct hda_codec **codecp)
638
680
{
639
 
        if (!*codecp)
640
 
                return;
641
681
        parse_hints(*codecp, buf);
642
682
}
643
683
 
644
684
static void parse_model_mode(char *buf, struct hda_bus *bus,
645
685
                             struct hda_codec **codecp)
646
686
{
647
 
        if (!*codecp)
648
 
                return;
649
687
        kfree((*codecp)->modelname);
650
688
        (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
651
689
}
652
690
 
 
691
static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
 
692
                                 struct hda_codec **codecp)
 
693
{
 
694
        kfree((*codecp)->chip_name);
 
695
        (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL);
 
696
}
 
697
 
 
698
#define DEFINE_PARSE_ID_MODE(name) \
 
699
static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
 
700
                                 struct hda_codec **codecp) \
 
701
{ \
 
702
        unsigned long val; \
 
703
        if (!strict_strtoul(buf, 0, &val)) \
 
704
                (*codecp)->name = val; \
 
705
}
 
706
 
 
707
DEFINE_PARSE_ID_MODE(vendor_id);
 
708
DEFINE_PARSE_ID_MODE(subsystem_id);
 
709
DEFINE_PARSE_ID_MODE(revision_id);
 
710
 
 
711
 
653
712
struct hda_patch_item {
654
713
        const char *tag;
655
714
        void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
 
715
        int need_codec;
656
716
};
657
717
 
658
718
static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
659
 
        [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode },
660
 
        [LINE_MODE_MODEL] = { "[model]", parse_model_mode },
661
 
        [LINE_MODE_VERB] = { "[verb]", parse_verb_mode },
662
 
        [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode },
663
 
        [LINE_MODE_HINT] = { "[hint]", parse_hint_mode },
 
719
        [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
 
720
        [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
 
721
        [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
 
722
        [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
 
723
        [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
 
724
        [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
 
725
        [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
 
726
        [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
 
727
        [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
664
728
};
665
729
 
666
730
/* check the line starting with '[' -- change the parser mode accodingly */
743
807
                        continue;
744
808
                if (*buf == '[')
745
809
                        line_mode = parse_line_mode(buf, bus);
746
 
                else if (patch_items[line_mode].parser)
 
810
                else if (patch_items[line_mode].parser &&
 
811
                         (codec || !patch_items[line_mode].need_codec))
747
812
                        patch_items[line_mode].parser(buf, bus, &codec);
748
813
        }
749
814
        release_firmware(fw);