All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Jarzmik <robert.jarzmik@free.fr>
To: Takashi Iwai <tiwai@suse.de>
Cc: "Haojian Zhuang" <haojian.zhuang@gmail.com>,
	"Liam Girdwood" <lgirdwood@gmail.com>,
	"Mark Brown" <broonie@kernel.org>,
	"Jaroslav Kysela" <perex@perex.cz>,
	"Daniel Mack" <daniel@zonque.org>, <alsa-devel@alsa-project.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<patches@opensource.wolfsonmicro.com>,
	<linux-kernel@vger.kernel.org>
Subject: Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
Date: Sat, 14 May 2016 11:50:50 +0200	[thread overview]
Message-ID: <87twi1hssl.fsf@belgarion.home> (raw)
In-Reply-To: <s5hk2j38tmf.wl-tiwai@suse.de> (Takashi Iwai's message of "Mon, 09 May 2016 11:31:52 +0200")

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 30 Apr 2016 23:15:34 +0200,
> Robert Jarzmik wrote:
>> 
>> diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
>> new file mode 100644
>> index 000000000000..4b8b3e570892
>> --- /dev/null
>> +++ b/include/sound/ac97/codec.h
>> @@ -0,0 +1,98 @@
>> +/*
>> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#ifndef AC97_CODEC_H
>> +#define AC97_CODEC_H
>
> Let's be careful about the choice of the guard.
Ok, would _SND_AC97_CODEC_H be better ?

>> +#define AC97_ID(vendor_id1, vendor_id2) \
>> +	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
>> +#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
>> +	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
>> +	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
>> +	  .data = _data }
>
> Give parentheses around the macro arguments.
Right, for RFC v2.

>> +struct ac97_codec_device {
>> +	struct device		dev;	/* Must stay first member */
>
> This doesn't have to be the first element as long as you use container_of().
Ah yes, that's a leftover from a former idea, I'll remove that comment.

In the initial code I'd done "struct ac97_codec_device" was hidden from this
file (ie. there was only a "struct ac97_codec_device;" statement), the body of
the struct was contained in sound/ac97/ac97_core.h.

The only provided macro to access the "struct device" inside "struct
ac97_codec_device" was relying on this "trick" (that's a bit like in the
video4linux area).

Anyway, good point, I'll remove that.

>> +struct ac97_codec_driver {
>> +	struct device_driver	driver;
>> +	int			(*probe)(struct ac97_codec_device *);
>> +	int			(*remove)(struct ac97_codec_device *);
>> +	int			(*suspend)(struct ac97_codec_device *);
>> +	int			(*resume)(struct ac97_codec_device *);
>> +	void			(*shutdown)(struct ac97_codec_device *);
>> +	struct ac97_id		*id_table;
>
> Missing const?
Ah no, unfortunately not, or rather not yet.

I tried that one, not very hard, but at least ac97_bus_match() with the pair
"struct ac97_id *id = adrv->id_table" and "do { } while (++id->id);" is not
possible AFAIK with a const.

I will see if I can come up with something better for ac97_bus_match, such as
array usage instead of pointer arithmetics.

>> +};
>> +
>> +int ac97_codec_driver_register(struct ac97_codec_driver *drv);
>> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
>> +
>> +static inline struct device *
>> +ac97_codec_dev2dev(const struct ac97_codec_device *adev)
>> +{
>> +	return (struct device *)(adev);
>
> What's wrong with the simple &adev->dev ?  Cast looks scary.
The same leftover than above, I'll change that for RFC v2.

>> +struct ac97_controller {
>> +	const struct ac97_controller_ops *ops;
>> +	struct list_head controllers;
>> +	struct device *dev;
>> +	int bus_idx;
>
> What is this bus_idx for?
Initially it was to distinguish 2 different AC97 controllers. In the current
patchset state, it's not usefull anymore AFAICS.
So let's remove it.

>> +	int bound_codecs;
The same comment would apply here. I don't think that information is important
anymore. I thought I would use that to prevent AC97 controler removal while
codecs are still bound.

In a second thought what would be better is to have get_device() called for each
bound codec which will prevent ac97_digital_controller_unregister() to succeed
(-EBUSY).

>> +	struct list_head codecs;
>> +};
>> +
>> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
>> +				     struct device *dev);
>> +int ac97_digital_controller_unregister(const struct device *dev);
>> +
>> +#endif
>> diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
>> new file mode 100644
>> index 000000000000..fd2c2d031e62
>> --- /dev/null
>> +++ b/sound/ac97/Kconfig
>> @@ -0,0 +1,9 @@
>> +#
>> +# PCI configuration
>> +#
>  
> Still only for PCI? :)
Ouch ;) I'll amend that for RFC v2.
>
>> +
>> +config AC97
>> +	bool "AC97 bus"
>> +	help
>> +	   Say Y here if you want to have AC97 devices, which are sound oriented
>> +	   devices around an AC-Link.
>> diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
>> new file mode 100644
>> index 000000000000..5575909d46e2
>> --- /dev/null
>> +++ b/sound/ac97/Makefile
>> @@ -0,0 +1,5 @@
>> +#
>> +# make for AC97 bus drivers
>> +#
>> +
>> +obj-y	+= bus.o codec.o snd_ac97_compat.o
>
> No possibility for modules?
There should be, so I'll put that on my TODO list for RFC v2.

>> +static struct ac97_codec_device *
>> +ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
>> +{
>> +	struct ac97_codec_device *codec;
>> +
>> +	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
>> +		if (codec->num == codec_num)
>> +			return codec;
>> +
>> +	return NULL;
>> +}
>
> It's a question whether we need to manage the codecs in the linked
> list.  There can be at most 4 codecs, so it fits in an array well,
> too.  Then some codes like this would be simpler. (And it'll even
> reduce the footprint, too.)
Agreed. For RFC v2.

>> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
>> +				      int codec_num)
>> +{
>> +	struct ac97_codec_device codec;
>> +	unsigned short vid1, vid2;
>> +	int ret;
>> +
>> +	codec.dev = *ac97->dev;
>> +	codec.num = codec_num;
>> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
>> +	vid1 = (ret & 0xffff);
>> +	if (ret < 0)
>> +		return 0;
>
> Hmm.  This looks pretty hackish and dangerous.
You mean returning 0 even if the read failed, right ?
A better prototype would probably be (for RFC v2):
  int ac97_bus_scan_one(struct ac97_controller *ac97, int codec_num,
                        unsigned int *vendor_id);

>> +static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
>> +{
>> +	int ret, i;
>> +	unsigned int vendor_id;
>> +
>> +	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
>> +		if (ac97_codec_find(ac97_ctrl, i))
>> +			continue;
>> +		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
>> +		if (!vendor_id)
>> +			continue;
>> +
>> +		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
>> +		if (ret < 0)
>> +			return ret;
>
> This is one of concerns: we don't know whether the device really
> reacts well if you access to a non-existing slot.  At least, it'd be
> safer to have the masks for the devices we already know the slots.

Ah you mean upon ac97 controller registration, the
ac97_digital_controller_register() should provide the information for each of
the 4 slots :
 - does the controller enable this slot (default yes)
 - does the controller support auto-scan for this slot (default yes)
   I'm not sure this "feature" is required, it looks a bit over-engineered.

That could be a matter of 1 or 2 masks as input parameters to
ac97_digital_controller_register().

>> +static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
>> +{
>> +	struct ac97_codec_device codec;
>> +
>> +	memset(&codec, 0, sizeof(codec));
>> +	codec.dev = *ac97_ctrl->dev;
>> +
>> +	ac97_ctrl->ops->reset(&codec);
>
> So, this assumes that reset ops is mandatory?  Then document it at
> least.
Ok, for RFC v2.

Thanks for your review and feedbacks Takashi, I'll work on both Mark and your
comments in the next weeks.

Cheers.

-- 
Robert

WARNING: multiple messages have this Message-ID (diff)
From: Robert Jarzmik <robert.jarzmik@free.fr>
To: Takashi Iwai <tiwai@suse.de>
Cc: alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org,
	patches@opensource.wolfsonmicro.com,
	Liam Girdwood <lgirdwood@gmail.com>,
	Haojian Zhuang <haojian.zhuang@gmail.com>,
	Mark Brown <broonie@kernel.org>,
	linux-arm-kernel@lists.infradead.org,
	Daniel Mack <daniel@zonque.org>
Subject: Re: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
Date: Sat, 14 May 2016 11:50:50 +0200	[thread overview]
Message-ID: <87twi1hssl.fsf@belgarion.home> (raw)
In-Reply-To: <s5hk2j38tmf.wl-tiwai@suse.de> (Takashi Iwai's message of "Mon, 09 May 2016 11:31:52 +0200")

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 30 Apr 2016 23:15:34 +0200,
> Robert Jarzmik wrote:
>> 
>> diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
>> new file mode 100644
>> index 000000000000..4b8b3e570892
>> --- /dev/null
>> +++ b/include/sound/ac97/codec.h
>> @@ -0,0 +1,98 @@
>> +/*
>> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#ifndef AC97_CODEC_H
>> +#define AC97_CODEC_H
>
> Let's be careful about the choice of the guard.
Ok, would _SND_AC97_CODEC_H be better ?

>> +#define AC97_ID(vendor_id1, vendor_id2) \
>> +	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
>> +#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
>> +	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
>> +	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
>> +	  .data = _data }
>
> Give parentheses around the macro arguments.
Right, for RFC v2.

>> +struct ac97_codec_device {
>> +	struct device		dev;	/* Must stay first member */
>
> This doesn't have to be the first element as long as you use container_of().
Ah yes, that's a leftover from a former idea, I'll remove that comment.

In the initial code I'd done "struct ac97_codec_device" was hidden from this
file (ie. there was only a "struct ac97_codec_device;" statement), the body of
the struct was contained in sound/ac97/ac97_core.h.

The only provided macro to access the "struct device" inside "struct
ac97_codec_device" was relying on this "trick" (that's a bit like in the
video4linux area).

Anyway, good point, I'll remove that.

>> +struct ac97_codec_driver {
>> +	struct device_driver	driver;
>> +	int			(*probe)(struct ac97_codec_device *);
>> +	int			(*remove)(struct ac97_codec_device *);
>> +	int			(*suspend)(struct ac97_codec_device *);
>> +	int			(*resume)(struct ac97_codec_device *);
>> +	void			(*shutdown)(struct ac97_codec_device *);
>> +	struct ac97_id		*id_table;
>
> Missing const?
Ah no, unfortunately not, or rather not yet.

I tried that one, not very hard, but at least ac97_bus_match() with the pair
"struct ac97_id *id = adrv->id_table" and "do { } while (++id->id);" is not
possible AFAIK with a const.

I will see if I can come up with something better for ac97_bus_match, such as
array usage instead of pointer arithmetics.

>> +};
>> +
>> +int ac97_codec_driver_register(struct ac97_codec_driver *drv);
>> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
>> +
>> +static inline struct device *
>> +ac97_codec_dev2dev(const struct ac97_codec_device *adev)
>> +{
>> +	return (struct device *)(adev);
>
> What's wrong with the simple &adev->dev ?  Cast looks scary.
The same leftover than above, I'll change that for RFC v2.

>> +struct ac97_controller {
>> +	const struct ac97_controller_ops *ops;
>> +	struct list_head controllers;
>> +	struct device *dev;
>> +	int bus_idx;
>
> What is this bus_idx for?
Initially it was to distinguish 2 different AC97 controllers. In the current
patchset state, it's not usefull anymore AFAICS.
So let's remove it.

>> +	int bound_codecs;
The same comment would apply here. I don't think that information is important
anymore. I thought I would use that to prevent AC97 controler removal while
codecs are still bound.

In a second thought what would be better is to have get_device() called for each
bound codec which will prevent ac97_digital_controller_unregister() to succeed
(-EBUSY).

>> +	struct list_head codecs;
>> +};
>> +
>> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
>> +				     struct device *dev);
>> +int ac97_digital_controller_unregister(const struct device *dev);
>> +
>> +#endif
>> diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
>> new file mode 100644
>> index 000000000000..fd2c2d031e62
>> --- /dev/null
>> +++ b/sound/ac97/Kconfig
>> @@ -0,0 +1,9 @@
>> +#
>> +# PCI configuration
>> +#
>  
> Still only for PCI? :)
Ouch ;) I'll amend that for RFC v2.
>
>> +
>> +config AC97
>> +	bool "AC97 bus"
>> +	help
>> +	   Say Y here if you want to have AC97 devices, which are sound oriented
>> +	   devices around an AC-Link.
>> diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
>> new file mode 100644
>> index 000000000000..5575909d46e2
>> --- /dev/null
>> +++ b/sound/ac97/Makefile
>> @@ -0,0 +1,5 @@
>> +#
>> +# make for AC97 bus drivers
>> +#
>> +
>> +obj-y	+= bus.o codec.o snd_ac97_compat.o
>
> No possibility for modules?
There should be, so I'll put that on my TODO list for RFC v2.

>> +static struct ac97_codec_device *
>> +ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
>> +{
>> +	struct ac97_codec_device *codec;
>> +
>> +	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
>> +		if (codec->num == codec_num)
>> +			return codec;
>> +
>> +	return NULL;
>> +}
>
> It's a question whether we need to manage the codecs in the linked
> list.  There can be at most 4 codecs, so it fits in an array well,
> too.  Then some codes like this would be simpler. (And it'll even
> reduce the footprint, too.)
Agreed. For RFC v2.

>> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
>> +				      int codec_num)
>> +{
>> +	struct ac97_codec_device codec;
>> +	unsigned short vid1, vid2;
>> +	int ret;
>> +
>> +	codec.dev = *ac97->dev;
>> +	codec.num = codec_num;
>> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
>> +	vid1 = (ret & 0xffff);
>> +	if (ret < 0)
>> +		return 0;
>
> Hmm.  This looks pretty hackish and dangerous.
You mean returning 0 even if the read failed, right ?
A better prototype would probably be (for RFC v2):
  int ac97_bus_scan_one(struct ac97_controller *ac97, int codec_num,
                        unsigned int *vendor_id);

>> +static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
>> +{
>> +	int ret, i;
>> +	unsigned int vendor_id;
>> +
>> +	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
>> +		if (ac97_codec_find(ac97_ctrl, i))
>> +			continue;
>> +		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
>> +		if (!vendor_id)
>> +			continue;
>> +
>> +		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
>> +		if (ret < 0)
>> +			return ret;
>
> This is one of concerns: we don't know whether the device really
> reacts well if you access to a non-existing slot.  At least, it'd be
> safer to have the masks for the devices we already know the slots.

Ah you mean upon ac97 controller registration, the
ac97_digital_controller_register() should provide the information for each of
the 4 slots :
 - does the controller enable this slot (default yes)
 - does the controller support auto-scan for this slot (default yes)
   I'm not sure this "feature" is required, it looks a bit over-engineered.

That could be a matter of 1 or 2 masks as input parameters to
ac97_digital_controller_register().

>> +static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
>> +{
>> +	struct ac97_codec_device codec;
>> +
>> +	memset(&codec, 0, sizeof(codec));
>> +	codec.dev = *ac97_ctrl->dev;
>> +
>> +	ac97_ctrl->ops->reset(&codec);
>
> So, this assumes that reset ops is mandatory?  Then document it at
> least.
Ok, for RFC v2.

Thanks for your review and feedbacks Takashi, I'll work on both Mark and your
comments in the next weeks.

Cheers.

-- 
Robert

WARNING: multiple messages have this Message-ID (diff)
From: robert.jarzmik@free.fr (Robert Jarzmik)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus
Date: Sat, 14 May 2016 11:50:50 +0200	[thread overview]
Message-ID: <87twi1hssl.fsf@belgarion.home> (raw)
In-Reply-To: <s5hk2j38tmf.wl-tiwai@suse.de> (Takashi Iwai's message of "Mon, 09 May 2016 11:31:52 +0200")

Takashi Iwai <tiwai@suse.de> writes:

> On Sat, 30 Apr 2016 23:15:34 +0200,
> Robert Jarzmik wrote:
>> 
>> diff --git a/include/sound/ac97/codec.h b/include/sound/ac97/codec.h
>> new file mode 100644
>> index 000000000000..4b8b3e570892
>> --- /dev/null
>> +++ b/include/sound/ac97/codec.h
>> @@ -0,0 +1,98 @@
>> +/*
>> + *  Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +#ifndef AC97_CODEC_H
>> +#define AC97_CODEC_H
>
> Let's be careful about the choice of the guard.
Ok, would _SND_AC97_CODEC_H be better ?

>> +#define AC97_ID(vendor_id1, vendor_id2) \
>> +	(((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff))
>> +#define AC97_DRIVER_ID(vendor_id1, vendor_id2, mask_id1, mask_id2, _data) \
>> +	{ .id = ((vendor_id1 & 0xffff) << 16) | (vendor_id2 & 0xffff), \
>> +	  .mask = ((mask_id1 & 0xffff) << 16) | (mask_id2 & 0xffff), \
>> +	  .data = _data }
>
> Give parentheses around the macro arguments.
Right, for RFC v2.

>> +struct ac97_codec_device {
>> +	struct device		dev;	/* Must stay first member */
>
> This doesn't have to be the first element as long as you use container_of().
Ah yes, that's a leftover from a former idea, I'll remove that comment.

In the initial code I'd done "struct ac97_codec_device" was hidden from this
file (ie. there was only a "struct ac97_codec_device;" statement), the body of
the struct was contained in sound/ac97/ac97_core.h.

The only provided macro to access the "struct device" inside "struct
ac97_codec_device" was relying on this "trick" (that's a bit like in the
video4linux area).

Anyway, good point, I'll remove that.

>> +struct ac97_codec_driver {
>> +	struct device_driver	driver;
>> +	int			(*probe)(struct ac97_codec_device *);
>> +	int			(*remove)(struct ac97_codec_device *);
>> +	int			(*suspend)(struct ac97_codec_device *);
>> +	int			(*resume)(struct ac97_codec_device *);
>> +	void			(*shutdown)(struct ac97_codec_device *);
>> +	struct ac97_id		*id_table;
>
> Missing const?
Ah no, unfortunately not, or rather not yet.

I tried that one, not very hard, but at least ac97_bus_match() with the pair
"struct ac97_id *id = adrv->id_table" and "do { } while (++id->id);" is not
possible AFAIK with a const.

I will see if I can come up with something better for ac97_bus_match, such as
array usage instead of pointer arithmetics.

>> +};
>> +
>> +int ac97_codec_driver_register(struct ac97_codec_driver *drv);
>> +void ac97_codec_driver_unregister(struct ac97_codec_driver *drv);
>> +
>> +static inline struct device *
>> +ac97_codec_dev2dev(const struct ac97_codec_device *adev)
>> +{
>> +	return (struct device *)(adev);
>
> What's wrong with the simple &adev->dev ?  Cast looks scary.
The same leftover than above, I'll change that for RFC v2.

>> +struct ac97_controller {
>> +	const struct ac97_controller_ops *ops;
>> +	struct list_head controllers;
>> +	struct device *dev;
>> +	int bus_idx;
>
> What is this bus_idx for?
Initially it was to distinguish 2 different AC97 controllers. In the current
patchset state, it's not usefull anymore AFAICS.
So let's remove it.

>> +	int bound_codecs;
The same comment would apply here. I don't think that information is important
anymore. I thought I would use that to prevent AC97 controler removal while
codecs are still bound.

In a second thought what would be better is to have get_device() called for each
bound codec which will prevent ac97_digital_controller_unregister() to succeed
(-EBUSY).

>> +	struct list_head codecs;
>> +};
>> +
>> +int ac97_digital_controller_register(const struct ac97_controller_ops *ops,
>> +				     struct device *dev);
>> +int ac97_digital_controller_unregister(const struct device *dev);
>> +
>> +#endif
>> diff --git a/sound/ac97/Kconfig b/sound/ac97/Kconfig
>> new file mode 100644
>> index 000000000000..fd2c2d031e62
>> --- /dev/null
>> +++ b/sound/ac97/Kconfig
>> @@ -0,0 +1,9 @@
>> +#
>> +# PCI configuration
>> +#
>  
> Still only for PCI? :)
Ouch ;) I'll amend that for RFC v2.
>
>> +
>> +config AC97
>> +	bool "AC97 bus"
>> +	help
>> +	   Say Y here if you want to have AC97 devices, which are sound oriented
>> +	   devices around an AC-Link.
>> diff --git a/sound/ac97/Makefile b/sound/ac97/Makefile
>> new file mode 100644
>> index 000000000000..5575909d46e2
>> --- /dev/null
>> +++ b/sound/ac97/Makefile
>> @@ -0,0 +1,5 @@
>> +#
>> +# make for AC97 bus drivers
>> +#
>> +
>> +obj-y	+= bus.o codec.o snd_ac97_compat.o
>
> No possibility for modules?
There should be, so I'll put that on my TODO list for RFC v2.

>> +static struct ac97_codec_device *
>> +ac97_codec_find(struct ac97_controller *ac97_ctrl, int codec_num)
>> +{
>> +	struct ac97_codec_device *codec;
>> +
>> +	list_for_each_entry(codec, &ac97_ctrl->codecs, list)
>> +		if (codec->num == codec_num)
>> +			return codec;
>> +
>> +	return NULL;
>> +}
>
> It's a question whether we need to manage the codecs in the linked
> list.  There can be at most 4 codecs, so it fits in an array well,
> too.  Then some codes like this would be simpler. (And it'll even
> reduce the footprint, too.)
Agreed. For RFC v2.

>> +unsigned int ac97_bus_scan_one(struct ac97_controller *ac97,
>> +				      int codec_num)
>> +{
>> +	struct ac97_codec_device codec;
>> +	unsigned short vid1, vid2;
>> +	int ret;
>> +
>> +	codec.dev = *ac97->dev;
>> +	codec.num = codec_num;
>> +	ret = ac97->ops->read(&codec, AC97_VENDOR_ID1);
>> +	vid1 = (ret & 0xffff);
>> +	if (ret < 0)
>> +		return 0;
>
> Hmm.  This looks pretty hackish and dangerous.
You mean returning 0 even if the read failed, right ?
A better prototype would probably be (for RFC v2):
  int ac97_bus_scan_one(struct ac97_controller *ac97, int codec_num,
                        unsigned int *vendor_id);

>> +static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
>> +{
>> +	int ret, i;
>> +	unsigned int vendor_id;
>> +
>> +	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
>> +		if (ac97_codec_find(ac97_ctrl, i))
>> +			continue;
>> +		vendor_id = ac97_bus_scan_one(ac97_ctrl, i);
>> +		if (!vendor_id)
>> +			continue;
>> +
>> +		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
>> +		if (ret < 0)
>> +			return ret;
>
> This is one of concerns: we don't know whether the device really
> reacts well if you access to a non-existing slot.  At least, it'd be
> safer to have the masks for the devices we already know the slots.

Ah you mean upon ac97 controller registration, the
ac97_digital_controller_register() should provide the information for each of
the 4 slots :
 - does the controller enable this slot (default yes)
 - does the controller support auto-scan for this slot (default yes)
   I'm not sure this "feature" is required, it looks a bit over-engineered.

That could be a matter of 1 or 2 masks as input parameters to
ac97_digital_controller_register().

>> +static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
>> +{
>> +	struct ac97_codec_device codec;
>> +
>> +	memset(&codec, 0, sizeof(codec));
>> +	codec.dev = *ac97_ctrl->dev;
>> +
>> +	ac97_ctrl->ops->reset(&codec);
>
> So, this assumes that reset ops is mandatory?  Then document it at
> least.
Ok, for RFC v2.

Thanks for your review and feedbacks Takashi, I'll work on both Mark and your
comments in the next weeks.

Cheers.

-- 
Robert

  reply	other threads:[~2016-05-14  9:50 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-30 21:15 [RFC PATCH 0/7] AC97 device/driver model revamp Robert Jarzmik
2016-04-30 21:15 ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 1/7] ALSA: ac97: split out the generic ac97 registers Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-05-03 11:51   ` Mark Brown
2016-05-03 11:51     ` Mark Brown
2016-05-03 19:22     ` Robert Jarzmik
2016-05-03 19:22       ` Robert Jarzmik
2016-05-03 19:22       ` Robert Jarzmik
2016-05-04  9:07       ` Mark Brown
2016-05-04  9:07         ` Mark Brown
2016-05-05 19:06         ` Robert Jarzmik
2016-05-05 19:06           ` Robert Jarzmik
2016-05-05 19:06           ` Robert Jarzmik
2016-05-05 19:17           ` Mark Brown
2016-05-05 19:17             ` Mark Brown
2016-05-05 19:46             ` Robert Jarzmik
2016-05-05 19:46               ` Robert Jarzmik
2016-05-06 17:17               ` Mark Brown
2016-05-06 17:17                 ` Mark Brown
2017-09-04 17:25   ` Applied "ALSA: ac97: split out the generic ac97 registers" to the asoc tree Mark Brown
2017-09-04 17:25     ` Mark Brown
2017-09-04 17:25     ` Mark Brown
2016-04-30 21:15 ` [RFC PATCH 2/7] ALSA: ac97: add an ac97 bus Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-05-03 16:29   ` Mark Brown
2016-05-03 16:29     ` Mark Brown
2016-05-03 19:43     ` Robert Jarzmik
2016-05-03 19:43       ` Robert Jarzmik
2016-05-04 16:22       ` Mark Brown
2016-05-04 16:22         ` Mark Brown
2016-05-05 19:14         ` Robert Jarzmik
2016-05-05 19:14           ` Robert Jarzmik
2016-05-09  9:31   ` Takashi Iwai
2016-05-09  9:31     ` Takashi Iwai
2016-05-09  9:31     ` Takashi Iwai
2016-05-14  9:50     ` Robert Jarzmik [this message]
2016-05-14  9:50       ` Robert Jarzmik
2016-05-14  9:50       ` Robert Jarzmik
2016-05-14 15:13       ` Takashi Iwai
2016-05-14 15:13         ` Takashi Iwai
2016-05-14 15:13         ` Takashi Iwai
2016-05-15 21:29         ` Robert Jarzmik
2016-05-15 21:29           ` Robert Jarzmik
2016-05-15 21:29           ` Robert Jarzmik
2016-05-16  5:40           ` Takashi Iwai
2016-05-16  5:40             ` Takashi Iwai
2016-05-16  5:40             ` Takashi Iwai
2016-05-16  8:53             ` Robert Jarzmik
2016-05-16  8:53               ` Robert Jarzmik
2016-05-16  8:53               ` Robert Jarzmik
2016-05-16 12:58               ` Takashi Iwai
2016-05-16 12:58                 ` Takashi Iwai
2016-05-16 12:58                 ` Takashi Iwai
2016-05-16 13:12                 ` Mark Brown
2016-05-16 13:12                   ` Mark Brown
2016-04-30 21:15 ` [RFC PATCH 3/7] ASoC: wm9713: add ac97 new bus support Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 4/7] ASoC: pxa: switch to new ac97 " Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 5/7] ARM: pxa: mioa701 remove wm9713 from platform devices Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 6/7] ASoC: mioa701_wm9713: convert to new ac97 bus Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-04-30 21:15 ` [RFC PATCH 7/7] ASoC: add new ac97 bus support Robert Jarzmik
2016-04-30 21:15   ` Robert Jarzmik
2016-05-09  9:04 ` [RFC PATCH 0/7] AC97 device/driver model revamp Takashi Iwai
2016-05-09  9:04   ` Takashi Iwai
2016-05-09  9:04   ` Takashi Iwai
2016-05-14  8:13   ` Robert Jarzmik
2016-05-14  8:13     ` Robert Jarzmik
2016-05-14  8:13     ` Robert Jarzmik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87twi1hssl.fsf@belgarion.home \
    --to=robert.jarzmik@free.fr \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=daniel@zonque.org \
    --cc=haojian.zhuang@gmail.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=patches@opensource.wolfsonmicro.com \
    --cc=perex@perex.cz \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.