Commit 33fa35ed authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - simplify hda_bus ops callbacks

The hda_bus ops callback take struct hda_bus pointer.
Also, the command callback takes the composed command word, instead of
each small bits in arguments.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c238b4f4
......@@ -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
......@@ -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;
}
......@@ -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;
}
......@@ -1886,10 +1910,14 @@ 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);
......@@ -1897,7 +1925,7 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
if (c)
c->val = parm;
}
mutex_unlock(&codec->bus->cmd_mutex);
mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec);
return err;
}
......@@ -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;
......@@ -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);
}
/**
......@@ -2628,6 +2657,7 @@ 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;
......@@ -2635,8 +2665,8 @@ static void hda_power_work(struct work_struct *work)
}
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)
......@@ -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;
......
......@@ -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
};
......
......@@ -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 */
......@@ -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:
......@@ -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);
......@@ -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--) {
......@@ -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--) {
......@@ -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 */
......@@ -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
......@@ -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;
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment