Skip to content

Commit

Permalink
Merge branch 'topic/hda' into for-linus
Browse files Browse the repository at this point in the history
  • Loading branch information
Takashi Iwai committed Mar 1, 2010
2 parents 12c2a68 + 61c2d2b commit a91a4aa
Show file tree
Hide file tree
Showing 10 changed files with 876 additions and 484 deletions.
5 changes: 5 additions & 0 deletions Documentation/sound/alsa/HD-Audio-Models.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ ALC882/883/885/888/889
asus-a7m ASUS A7M
macpro MacPro support
mb5 Macbook 5,1
macmini3 Macmini 3,1
mba21 Macbook Air 2,1
mbp3 Macbook Pro rev3
imac24 iMac 24'' with jack detection
imac91 iMac 9,1
Expand Down Expand Up @@ -279,13 +281,16 @@ Conexant 5051
laptop Basic Laptop config (default)
hp HP Spartan laptop
hp-dv6736 HP dv6736
hp-f700 HP Compaq Presario F700
lenovo-x200 Lenovo X200 laptop
toshiba Toshiba Satellite M300

Conexant 5066
=============
laptop Basic Laptop config (default)
dell-laptop Dell laptops
olpc-xo-1_5 OLPC XO 1.5
ideapad Lenovo IdeaPad U150

STAC9200
========
Expand Down
27 changes: 27 additions & 0 deletions Documentation/sound/alsa/HD-Audio.txt
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,33 @@ Similarly, the lines after `[verb]` are parsed as `init_verbs`
sysfs entries, and the lines after `[hint]` are parsed as `hints`
sysfs entries, respectively.

Another example to override the codec vendor id from 0x12345678 to
0xdeadbeef is like below:
------------------------------------------------------------------------
[codec]
0x12345678 0xabcd1234 2

[vendor_id]
0xdeadbeef
------------------------------------------------------------------------

In the similar way, you can override the codec subsystem_id via
`[subsystem_id]`, the revision id via `[revision_id]` line.
Also, the codec chip name can be rewritten via `[chip_name]` line.
------------------------------------------------------------------------
[codec]
0x12345678 0xabcd1234 2

[subsystem_id]
0xffff1111

[revision_id]
0x10

[chip_name]
My-own NEWS-0002
------------------------------------------------------------------------

The hd-audio driver reads the file via request_firmware(). Thus,
a patch file has to be located on the appropriate firmware path,
typically, /lib/firmware. For example, when you pass the option
Expand Down
6 changes: 4 additions & 2 deletions sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2767,7 +2767,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
power_state);
/* partial workaround for "azx_get_response timeout" */
if (power_state == AC_PWRST_D0)
if (power_state == AC_PWRST_D0 &&
(codec->vendor_id & 0xffff0000) == 0x14f10000)
msleep(10);

nid = codec->start_nid;
Expand Down Expand Up @@ -2801,7 +2802,6 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
if (power_state == AC_PWRST_D0) {
unsigned long end_time;
int state;
msleep(10);
/* wait until the codec reachs to D0 */
end_time = jiffies + msecs_to_jiffies(500);
do {
Expand Down Expand Up @@ -3275,6 +3275,8 @@ const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {

/*
* get the empty PCM device number to assign
*
* note the max device number is limited by HDA_MAX_PCMS, currently 10
*/
static int get_empty_pcm_device(struct hda_bus *bus, int type)
{
Expand Down
3 changes: 3 additions & 0 deletions sound/pci/hda/hda_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,9 @@ enum {
/* max. codec address */
#define HDA_MAX_CODEC_ADDRESS 0x0f

/* max number of PCM devics per card */
#define HDA_MAX_PCMS 10

/*
* generic arrays
*/
Expand Down
53 changes: 38 additions & 15 deletions sound/pci/hda/hda_hwdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,10 @@ enum {
LINE_MODE_PINCFG,
LINE_MODE_VERB,
LINE_MODE_HINT,
LINE_MODE_VENDOR_ID,
LINE_MODE_SUBSYSTEM_ID,
LINE_MODE_REVISION_ID,
LINE_MODE_CHIP_NAME,
NUM_LINE_MODES,
};

Expand Down Expand Up @@ -654,53 +658,71 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus,
}

/* parse the contents after the other command tags, [pincfg], [verb],
* [hint] and [model]
* [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
* just pass to the sysfs helper (only when any codec was specified)
*/
static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
struct hda_codec **codecp)
{
if (!*codecp)
return;
parse_user_pin_configs(*codecp, buf);
}

static void parse_verb_mode(char *buf, struct hda_bus *bus,
struct hda_codec **codecp)
{
if (!*codecp)
return;
parse_init_verbs(*codecp, buf);
}

static void parse_hint_mode(char *buf, struct hda_bus *bus,
struct hda_codec **codecp)
{
if (!*codecp)
return;
parse_hints(*codecp, buf);
}

static void parse_model_mode(char *buf, struct hda_bus *bus,
struct hda_codec **codecp)
{
if (!*codecp)
return;
kfree((*codecp)->modelname);
(*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
}

static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
struct hda_codec **codecp)
{
kfree((*codecp)->chip_name);
(*codecp)->chip_name = kstrdup(buf, GFP_KERNEL);
}

#define DEFINE_PARSE_ID_MODE(name) \
static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
struct hda_codec **codecp) \
{ \
unsigned long val; \
if (!strict_strtoul(buf, 0, &val)) \
(*codecp)->name = val; \
}

DEFINE_PARSE_ID_MODE(vendor_id);
DEFINE_PARSE_ID_MODE(subsystem_id);
DEFINE_PARSE_ID_MODE(revision_id);


struct hda_patch_item {
const char *tag;
void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
int need_codec;
};

static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
[LINE_MODE_CODEC] = { "[codec]", parse_codec_mode },
[LINE_MODE_MODEL] = { "[model]", parse_model_mode },
[LINE_MODE_VERB] = { "[verb]", parse_verb_mode },
[LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode },
[LINE_MODE_HINT] = { "[hint]", parse_hint_mode },
[LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
[LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
[LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
[LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
[LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
[LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
[LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
[LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
[LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
};

/* check the line starting with '[' -- change the parser mode accodingly */
Expand Down Expand Up @@ -783,7 +805,8 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
continue;
if (*buf == '[')
line_mode = parse_line_mode(buf, bus);
else if (patch_items[line_mode].parser)
else if (patch_items[line_mode].parser &&
(codec || !patch_items[line_mode].need_codec))
patch_items[line_mode].parser(buf, bus, &codec);
}
release_firmware(fw);
Expand Down
28 changes: 17 additions & 11 deletions sound/pci/hda/hda_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
"{Intel, ICH9},"
"{Intel, ICH10},"
"{Intel, PCH},"
"{Intel, CPT},"
"{Intel, SCH},"
"{ATI, SB450},"
"{ATI, SB600},"
Expand Down Expand Up @@ -259,8 +260,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
#define AZX_MAX_FRAG 32
/* max buffer size - no h/w limit, you can increase as you like */
#define AZX_MAX_BUF_SIZE (1024*1024*1024)
/* max number of PCM devics per card */
#define AZX_MAX_PCMS 8

/* RIRB int mask: overrun[2], response[0] */
#define RIRB_INT_RESPONSE 0x01
Expand Down Expand Up @@ -408,7 +407,7 @@ struct azx {
struct azx_dev *azx_dev;

/* PCM */
struct snd_pcm *pcm[AZX_MAX_PCMS];
struct snd_pcm *pcm[HDA_MAX_PCMS];

/* HD codec */
unsigned short codec_mask;
Expand Down Expand Up @@ -449,6 +448,7 @@ struct azx {
/* driver types */
enum {
AZX_DRIVER_ICH,
AZX_DRIVER_PCH,
AZX_DRIVER_SCH,
AZX_DRIVER_ATI,
AZX_DRIVER_ATIHDMI,
Expand All @@ -463,6 +463,7 @@ enum {

static char *driver_short_names[] __devinitdata = {
[AZX_DRIVER_ICH] = "HDA Intel",
[AZX_DRIVER_PCH] = "HDA Intel PCH",
[AZX_DRIVER_SCH] = "HDA Intel MID",
[AZX_DRIVER_ATI] = "HDA ATI SB",
[AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
Expand Down Expand Up @@ -968,8 +969,8 @@ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
azx_dev->insufficient = 1;

/* enable SIE */
azx_writeb(chip, INTCTL,
azx_readb(chip, INTCTL) | (1 << azx_dev->index));
azx_writel(chip, INTCTL,
azx_readl(chip, INTCTL) | (1 << azx_dev->index));
/* set DMA start and interrupt mask */
azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
SD_CTL_DMA_START | SD_INT_MASK);
Expand All @@ -988,8 +989,8 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
{
azx_stream_clear(chip, azx_dev);
/* disable SIE */
azx_writeb(chip, INTCTL,
azx_readb(chip, INTCTL) & ~(1 << azx_dev->index));
azx_writel(chip, INTCTL,
azx_readl(chip, INTCTL) & ~(1 << azx_dev->index));
}


Expand Down Expand Up @@ -1065,6 +1066,7 @@ static void azx_init_pci(struct azx *chip)
0x01, NVIDIA_HDA_ENABLE_COHBIT);
break;
case AZX_DRIVER_SCH:
case AZX_DRIVER_PCH:
pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
Expand Down Expand Up @@ -1350,7 +1352,7 @@ static void azx_bus_reset(struct hda_bus *bus)
if (chip->initialized) {
int i;

for (i = 0; i < AZX_MAX_PCMS; i++)
for (i = 0; i < HDA_MAX_PCMS; i++)
snd_pcm_suspend_all(chip->pcm[i]);
snd_hda_suspend(chip->bus);
snd_hda_resume(chip->bus);
Expand Down Expand Up @@ -1412,7 +1414,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
chip->codec_mask &= ~(1 << c);
/* More badly, accessing to a non-existing
* codec often screws up the controller chip,
* and distrubs the further communications.
* and disturbs the further communications.
* Thus if an error occurs during probing,
* better to reset the controller chip to
* get back to the sanity state.
Expand Down Expand Up @@ -1983,7 +1985,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
int pcm_dev = cpcm->device;
int s, err;

if (pcm_dev >= AZX_MAX_PCMS) {
if (pcm_dev >= HDA_MAX_PCMS) {
snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
pcm_dev);
return -EINVAL;
Expand Down Expand Up @@ -2139,7 +2141,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)

snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
azx_clear_irq_pending(chip);
for (i = 0; i < AZX_MAX_PCMS; i++)
for (i = 0; i < HDA_MAX_PCMS; i++)
snd_pcm_suspend_all(chip->pcm[i]);
if (chip->initialized)
snd_hda_suspend(chip->bus);
Expand Down Expand Up @@ -2262,6 +2264,7 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
{}
Expand Down Expand Up @@ -2418,6 +2421,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
if (bdl_pos_adj[dev] < 0) {
switch (chip->driver_type) {
case AZX_DRIVER_ICH:
case AZX_DRIVER_PCH:
bdl_pos_adj[dev] = 1;
break;
default:
Expand Down Expand Up @@ -2696,6 +2700,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
{ PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
/* PCH */
{ PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
/* CPT */
{ PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
/* SCH */
{ PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
/* ATI SB 450/600 */
Expand Down
2 changes: 1 addition & 1 deletion sound/pci/hda/patch_analog.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD),
SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
Expand Down
Loading

0 comments on commit a91a4aa

Please sign in to comment.