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) ...@@ -157,6 +157,23 @@ const char *snd_hda_get_jack_type(u32 cfg)
>> AC_DEFCFG_DEVICE_SHIFT]; >> 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 * snd_hda_codec_read - send a command and get the response
* @codec: the HDA codec * @codec: the HDA codec
...@@ -173,14 +190,17 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, ...@@ -173,14 +190,17 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
int direct, int direct,
unsigned int verb, unsigned int parm) unsigned int verb, unsigned int parm)
{ {
struct hda_bus *bus = codec->bus;
unsigned int res; unsigned int res;
res = make_codec_cmd(codec, nid, direct, verb, parm);
snd_hda_power_up(codec); snd_hda_power_up(codec);
mutex_lock(&codec->bus->cmd_mutex); mutex_lock(&bus->cmd_mutex);
if (!codec->bus->ops.command(codec, nid, direct, verb, parm)) if (!bus->ops.command(bus, res))
res = codec->bus->ops.get_response(codec); res = bus->ops.get_response(bus);
else else
res = (unsigned int)-1; res = (unsigned int)-1;
mutex_unlock(&codec->bus->cmd_mutex); mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec); snd_hda_power_down(codec);
return res; return res;
} }
...@@ -200,11 +220,15 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, ...@@ -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, int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
unsigned int verb, unsigned int parm) unsigned int verb, unsigned int parm)
{ {
struct hda_bus *bus = codec->bus;
unsigned int res;
int err; int err;
res = make_codec_cmd(codec, nid, direct, verb, parm);
snd_hda_power_up(codec); snd_hda_power_up(codec);
mutex_lock(&codec->bus->cmd_mutex); mutex_lock(&bus->cmd_mutex);
err = codec->bus->ops.command(codec, nid, direct, verb, parm); err = bus->ops.command(bus, res);
mutex_unlock(&codec->bus->cmd_mutex); mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec); snd_hda_power_down(codec);
return err; return err;
} }
...@@ -1886,10 +1910,14 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) ...@@ -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 snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
int direct, unsigned int verb, unsigned int parm) int direct, unsigned int verb, unsigned int parm)
{ {
struct hda_bus *bus = codec->bus;
unsigned int res;
int err; int err;
res = make_codec_cmd(codec, nid, direct, verb, parm);
snd_hda_power_up(codec); snd_hda_power_up(codec);
mutex_lock(&codec->bus->cmd_mutex); mutex_lock(&bus->cmd_mutex);
err = codec->bus->ops.command(codec, nid, direct, verb, parm); err = bus->ops.command(bus, res);
if (!err) { if (!err) {
struct hda_cache_head *c; struct hda_cache_head *c;
u32 key = build_cmd_cache_key(nid, verb); 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, ...@@ -1897,7 +1925,7 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
if (c) if (c)
c->val = parm; c->val = parm;
} }
mutex_unlock(&codec->bus->cmd_mutex); mutex_unlock(&bus->cmd_mutex);
snd_hda_power_down(codec); snd_hda_power_down(codec);
return err; return err;
} }
...@@ -2414,6 +2442,7 @@ static int set_pcm_default_values(struct hda_codec *codec, ...@@ -2414,6 +2442,7 @@ static int set_pcm_default_values(struct hda_codec *codec,
static int __devinit static int __devinit
snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm) snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
{ {
struct hda_bus *bus = codec->bus;
struct hda_pcm_stream *info; struct hda_pcm_stream *info;
int stream, err; int stream, err;
...@@ -2427,7 +2456,7 @@ snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm) ...@@ -2427,7 +2456,7 @@ snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
return err; 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) ...@@ -2628,6 +2657,7 @@ static void hda_power_work(struct work_struct *work)
{ {
struct hda_codec *codec = struct hda_codec *codec =
container_of(work, struct hda_codec, power_work.work); container_of(work, struct hda_codec, power_work.work);
struct hda_bus *bus = codec->bus;
if (!codec->power_on || codec->power_count) { if (!codec->power_on || codec->power_count) {
codec->power_transition = 0; codec->power_transition = 0;
...@@ -2635,8 +2665,8 @@ static void hda_power_work(struct work_struct *work) ...@@ -2635,8 +2665,8 @@ static void hda_power_work(struct work_struct *work)
} }
hda_call_codec_suspend(codec); hda_call_codec_suspend(codec);
if (codec->bus->ops.pm_notify) if (bus->ops.pm_notify)
codec->bus->ops.pm_notify(codec); bus->ops.pm_notify(bus);
} }
static void hda_keep_power_on(struct hda_codec *codec) static void hda_keep_power_on(struct hda_codec *codec)
...@@ -2647,13 +2677,15 @@ 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) void snd_hda_power_up(struct hda_codec *codec)
{ {
struct hda_bus *bus = codec->bus;
codec->power_count++; codec->power_count++;
if (codec->power_on || codec->power_transition) if (codec->power_on || codec->power_transition)
return; return;
codec->power_on = 1; codec->power_on = 1;
if (codec->bus->ops.pm_notify) if (bus->ops.pm_notify)
codec->bus->ops.pm_notify(codec); bus->ops.pm_notify(bus);
hda_call_codec_resume(codec); hda_call_codec_resume(codec);
cancel_delayed_work(&codec->power_work); cancel_delayed_work(&codec->power_work);
codec->power_transition = 0; codec->power_transition = 0;
......
...@@ -556,17 +556,17 @@ typedef u16 hda_nid_t; ...@@ -556,17 +556,17 @@ typedef u16 hda_nid_t;
/* bus operators */ /* bus operators */
struct hda_bus_ops { struct hda_bus_ops {
/* send a single command */ /* send a single command */
int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct, int (*command)(struct hda_bus *bus, unsigned int cmd);
unsigned int verb, unsigned int parm);
/* get a response from the last command */ /* 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 */ /* free the private data */
void (*private_free)(struct hda_bus *); void (*private_free)(struct hda_bus *);
/* attach a PCM stream */ /* 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 #ifdef CONFIG_SND_HDA_POWER_SAVE
/* notify power-up/down from codec to controller */ /* notify power-up/down from codec to controller */
void (*pm_notify)(struct hda_codec *codec); void (*pm_notify)(struct hda_bus *bus);
#endif #endif
}; };
......
...@@ -527,9 +527,9 @@ static void azx_free_cmd_io(struct azx *chip) ...@@ -527,9 +527,9 @@ static void azx_free_cmd_io(struct azx *chip)
} }
/* send a command */ /* 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; unsigned int wp;
/* add command to corb */ /* add command to corb */
...@@ -577,9 +577,9 @@ static void azx_update_rirb(struct azx *chip) ...@@ -577,9 +577,9 @@ static void azx_update_rirb(struct azx *chip)
} }
/* receive a response */ /* 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; unsigned long timeout;
again: again:
...@@ -596,7 +596,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) ...@@ -596,7 +596,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
} }
if (time_after(jiffies, timeout)) if (time_after(jiffies, timeout))
break; break;
if (codec->bus->needs_damn_long_delay) if (bus->needs_damn_long_delay)
msleep(2); /* temporary workaround */ msleep(2); /* temporary workaround */
else { else {
udelay(10); udelay(10);
...@@ -646,9 +646,9 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) ...@@ -646,9 +646,9 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
*/ */
/* send a command */ /* 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; int timeout = 50;
while (timeout--) { while (timeout--) {
...@@ -671,9 +671,9 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val) ...@@ -671,9 +671,9 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
} }
/* receive a response */ /* 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; int timeout = 50;
while (timeout--) { while (timeout--) {
...@@ -696,38 +696,29 @@ static unsigned int azx_single_get_response(struct hda_codec *codec) ...@@ -696,38 +696,29 @@ static unsigned int azx_single_get_response(struct hda_codec *codec)
*/ */
/* send a command */ /* send a command */
static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
int direct, unsigned int verb,
unsigned int para)
{ {
struct azx *chip = codec->bus->private_data; struct azx *chip = 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;
chip->last_cmd = val;
if (chip->single_cmd) if (chip->single_cmd)
return azx_single_send_cmd(codec, val); return azx_single_send_cmd(bus, val);
else else
return azx_corb_send_cmd(codec, val); return azx_corb_send_cmd(bus, val);
} }
/* get a response */ /* 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) if (chip->single_cmd)
return azx_single_get_response(codec); return azx_single_get_response(bus);
else else
return azx_rirb_get_response(codec); return azx_rirb_get_response(bus);
} }
#ifdef CONFIG_SND_HDA_POWER_SAVE #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 #endif
/* reset codec link */ /* reset codec link */
...@@ -1184,7 +1175,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) ...@@ -1184,7 +1175,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
return 0; 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 * Codec initialization
...@@ -1707,9 +1699,10 @@ static void azx_pcm_free(struct snd_pcm *pcm) ...@@ -1707,9 +1699,10 @@ static void azx_pcm_free(struct snd_pcm *pcm)
} }
static int 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 snd_pcm *pcm;
struct azx_pcm *apcm; struct azx_pcm *apcm;
int pcm_dev = cpcm->device; int pcm_dev = cpcm->device;
...@@ -1827,13 +1820,13 @@ static void azx_stop_chip(struct azx *chip) ...@@ -1827,13 +1820,13 @@ static void azx_stop_chip(struct azx *chip)
#ifdef CONFIG_SND_HDA_POWER_SAVE #ifdef CONFIG_SND_HDA_POWER_SAVE
/* power-up/down the controller */ /* 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; struct hda_codec *c;
int power_on = 0; 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) { if (c->power_on) {
power_on = 1; power_on = 1;
break; 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