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: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
c238b4f403
commit
33fa35ed0d
@ -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;
|
||||
struct azx *chip = bus->private_data;
|
||||
|
||||
val = (u32)(codec->addr & 0x0f) << 28;
|
||||
val |= (u32)direct << 27;
|
||||
val |= (u32)nid << 20;
|
||||
val |= verb << 8;
|
||||
val |= para;
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user