Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+47 −15
Original line number Diff line number Diff line
@@ -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;
+5 −5
Original line number Diff line number Diff line
@@ -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
};

+27 −34
Original line number Diff line number Diff line
@@ -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;