Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 120435
b: refs/heads/master
c: 33fa35e
h: refs/heads/master
i:
  120433: 294f7f4
  120431: 67a98c0
v: v3
  • Loading branch information
Takashi Iwai committed Nov 6, 2008
1 parent bea1918 commit 53ce93f
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 55 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c238b4f4038e0e49bb241640610584a088b268b1
refs/heads/master: 33fa35ed0d7e8996cc68cc2ffc21f12b38fa03c1
62 changes: 47 additions & 15 deletions trunk/sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,23 @@ const char *snd_hda_get_jack_type(u32 cfg)
>> AC_DEFCFG_DEVICE_SHIFT];
}

/*
* Compose a 32bit command word to be sent to the HD-audio controller
*/
static inline unsigned int
make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
unsigned int verb, unsigned int parm)
{
u32 val;

val = (u32)(codec->addr & 0x0f) << 28;
val |= (u32)direct << 27;
val |= (u32)nid << 20;
val |= verb << 8;
val |= parm;
return val;
}

/**
* snd_hda_codec_read - send a command and get the response
* @codec: the HDA codec
Expand All @@ -173,14 +190,17 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
int direct,
unsigned int verb, unsigned int parm)
{
struct hda_bus *bus = codec->bus;
unsigned int res;

res = make_codec_cmd(codec, nid, direct, verb, parm);
snd_hda_power_up(codec);
mutex_lock(&codec->bus->cmd_mutex);
if (!codec->bus->ops.command(codec, nid, direct, verb, parm))
res = codec->bus->ops.get_response(codec);
mutex_lock(&bus->cmd_mutex);
if (!bus->ops.command(bus, res))
res = bus->ops.get_response(bus);
else
res = (unsigned int)-1;
mutex_unlock(&codec->bus->cmd_mutex);
mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec);
return res;
}
Expand All @@ -200,11 +220,15 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
unsigned int verb, unsigned int parm)
{
struct hda_bus *bus = codec->bus;
unsigned int res;
int err;

res = make_codec_cmd(codec, nid, direct, verb, parm);
snd_hda_power_up(codec);
mutex_lock(&codec->bus->cmd_mutex);
err = codec->bus->ops.command(codec, nid, direct, verb, parm);
mutex_unlock(&codec->bus->cmd_mutex);
mutex_lock(&bus->cmd_mutex);
err = bus->ops.command(bus, res);
mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec);
return err;
}
Expand Down Expand Up @@ -1886,18 +1910,22 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
int direct, unsigned int verb, unsigned int parm)
{
struct hda_bus *bus = codec->bus;
unsigned int res;
int err;

res = make_codec_cmd(codec, nid, direct, verb, parm);
snd_hda_power_up(codec);
mutex_lock(&codec->bus->cmd_mutex);
err = codec->bus->ops.command(codec, nid, direct, verb, parm);
mutex_lock(&bus->cmd_mutex);
err = bus->ops.command(bus, res);
if (!err) {
struct hda_cache_head *c;
u32 key = build_cmd_cache_key(nid, verb);
c = get_alloc_hash(&codec->cmd_cache, key);
if (c)
c->val = parm;
}
mutex_unlock(&codec->bus->cmd_mutex);
mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec);
return err;
}
Expand Down Expand Up @@ -2414,6 +2442,7 @@ static int set_pcm_default_values(struct hda_codec *codec,
static int __devinit
snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
{
struct hda_bus *bus = codec->bus;
struct hda_pcm_stream *info;
int stream, err;

Expand All @@ -2427,7 +2456,7 @@ snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
return err;
}
}
return codec->bus->ops.attach_pcm(codec, pcm);
return bus->ops.attach_pcm(bus, codec, pcm);
}

/**
Expand Down Expand Up @@ -2628,15 +2657,16 @@ static void hda_power_work(struct work_struct *work)
{
struct hda_codec *codec =
container_of(work, struct hda_codec, power_work.work);
struct hda_bus *bus = codec->bus;

if (!codec->power_on || codec->power_count) {
codec->power_transition = 0;
return;
}

hda_call_codec_suspend(codec);
if (codec->bus->ops.pm_notify)
codec->bus->ops.pm_notify(codec);
if (bus->ops.pm_notify)
bus->ops.pm_notify(bus);
}

static void hda_keep_power_on(struct hda_codec *codec)
Expand All @@ -2647,13 +2677,15 @@ static void hda_keep_power_on(struct hda_codec *codec)

void snd_hda_power_up(struct hda_codec *codec)
{
struct hda_bus *bus = codec->bus;

codec->power_count++;
if (codec->power_on || codec->power_transition)
return;

codec->power_on = 1;
if (codec->bus->ops.pm_notify)
codec->bus->ops.pm_notify(codec);
if (bus->ops.pm_notify)
bus->ops.pm_notify(bus);
hda_call_codec_resume(codec);
cancel_delayed_work(&codec->power_work);
codec->power_transition = 0;
Expand Down
10 changes: 5 additions & 5 deletions trunk/sound/pci/hda/hda_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -556,17 +556,17 @@ typedef u16 hda_nid_t;
/* bus operators */
struct hda_bus_ops {
/* send a single command */
int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct,
unsigned int verb, unsigned int parm);
int (*command)(struct hda_bus *bus, unsigned int cmd);
/* get a response from the last command */
unsigned int (*get_response)(struct hda_codec *codec);
unsigned int (*get_response)(struct hda_bus *bus);
/* free the private data */
void (*private_free)(struct hda_bus *);
/* attach a PCM stream */
int (*attach_pcm)(struct hda_codec *codec, struct hda_pcm *pcm);
int (*attach_pcm)(struct hda_bus *bus, struct hda_codec *codec,
struct hda_pcm *pcm);
#ifdef CONFIG_SND_HDA_POWER_SAVE
/* notify power-up/down from codec to controller */
void (*pm_notify)(struct hda_codec *codec);
void (*pm_notify)(struct hda_bus *bus);
#endif
};

Expand Down
61 changes: 27 additions & 34 deletions trunk/sound/pci/hda/hda_intel.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,9 +527,9 @@ static void azx_free_cmd_io(struct azx *chip)
}

/* send a command */
static int azx_corb_send_cmd(struct hda_codec *codec, u32 val)
static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
{
struct azx *chip = codec->bus->private_data;
struct azx *chip = bus->private_data;
unsigned int wp;

/* add command to corb */
Expand Down Expand Up @@ -577,9 +577,9 @@ static void azx_update_rirb(struct azx *chip)
}

/* receive a response */
static unsigned int azx_rirb_get_response(struct hda_codec *codec)
static unsigned int azx_rirb_get_response(struct hda_bus *bus)
{
struct azx *chip = codec->bus->private_data;
struct azx *chip = bus->private_data;
unsigned long timeout;

again:
Expand All @@ -596,7 +596,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
}
if (time_after(jiffies, timeout))
break;
if (codec->bus->needs_damn_long_delay)
if (bus->needs_damn_long_delay)
msleep(2); /* temporary workaround */
else {
udelay(10);
Expand Down Expand Up @@ -646,9 +646,9 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
*/

/* send a command */
static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
{
struct azx *chip = codec->bus->private_data;
struct azx *chip = bus->private_data;
int timeout = 50;

while (timeout--) {
Expand All @@ -671,9 +671,9 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
}

/* receive a response */
static unsigned int azx_single_get_response(struct hda_codec *codec)
static unsigned int azx_single_get_response(struct hda_bus *bus)
{
struct azx *chip = codec->bus->private_data;
struct azx *chip = bus->private_data;
int timeout = 50;

while (timeout--) {
Expand All @@ -696,38 +696,29 @@ static unsigned int azx_single_get_response(struct hda_codec *codec)
*/

/* send a command */
static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid,
int direct, unsigned int verb,
unsigned int para)
static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
{
struct azx *chip = codec->bus->private_data;
u32 val;

val = (u32)(codec->addr & 0x0f) << 28;
val |= (u32)direct << 27;
val |= (u32)nid << 20;
val |= verb << 8;
val |= para;
chip->last_cmd = val;
struct azx *chip = bus->private_data;

chip->last_cmd = val;
if (chip->single_cmd)
return azx_single_send_cmd(codec, val);
return azx_single_send_cmd(bus, val);
else
return azx_corb_send_cmd(codec, val);
return azx_corb_send_cmd(bus, val);
}

/* get a response */
static unsigned int azx_get_response(struct hda_codec *codec)
static unsigned int azx_get_response(struct hda_bus *bus)
{
struct azx *chip = codec->bus->private_data;
struct azx *chip = bus->private_data;
if (chip->single_cmd)
return azx_single_get_response(codec);
return azx_single_get_response(bus);
else
return azx_rirb_get_response(codec);
return azx_rirb_get_response(bus);
}

#ifdef CONFIG_SND_HDA_POWER_SAVE
static void azx_power_notify(struct hda_codec *codec);
static void azx_power_notify(struct hda_bus *bus);
#endif

/* reset codec link */
Expand Down Expand Up @@ -1184,7 +1175,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
return 0;
}

static int azx_attach_pcm_stream(struct hda_codec *codec, struct hda_pcm *cpcm);
static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
struct hda_pcm *cpcm);

/*
* Codec initialization
Expand Down Expand Up @@ -1707,9 +1699,10 @@ static void azx_pcm_free(struct snd_pcm *pcm)
}

static int
azx_attach_pcm_stream(struct hda_codec *codec, struct hda_pcm *cpcm)
azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
struct hda_pcm *cpcm)
{
struct azx *chip = codec->bus->private_data;
struct azx *chip = bus->private_data;
struct snd_pcm *pcm;
struct azx_pcm *apcm;
int pcm_dev = cpcm->device;
Expand Down Expand Up @@ -1827,13 +1820,13 @@ static void azx_stop_chip(struct azx *chip)

#ifdef CONFIG_SND_HDA_POWER_SAVE
/* power-up/down the controller */
static void azx_power_notify(struct hda_codec *codec)
static void azx_power_notify(struct hda_bus *bus)
{
struct azx *chip = codec->bus->private_data;
struct azx *chip = bus->private_data;
struct hda_codec *c;
int power_on = 0;

list_for_each_entry(c, &codec->bus->codec_list, list) {
list_for_each_entry(c, &bus->codec_list, list) {
if (c->power_on) {
power_on = 1;
break;
Expand Down

0 comments on commit 53ce93f

Please sign in to comment.