[alsa-devel] Unregister a card from userspace?
Ricard Wanderlof
ricard.wanderlof at axis.com
Thu Nov 12 15:02:29 CET 2015
On Thu, 12 Nov 2015, Felipe Ferreri Tonello wrote:
> > What I was aiming for was that when I load this particular module, it
> > ultimately calls snd_soc_register_card in its probe function, so that the
> > device in question becomes available for ALSA once the module has been
> > loaded. And then if I want to remove the driver I simply unload the module
> > which allows it to go away.
>
> You said that the framework that handles the module had the counter to 2
> so your unregister card function was never been called, right? I don't
> understand that part, since it doesn't make sense to load your module
> into the kernel more then once.
No, I don't understand why the usage count goes to 2 either.
What the driver does is this:
At module_init time, it registers:
a) a platform driver for the actual hardware (in essence, codec)
b) a platform device representing the hardware itself, and
c) a platform driver which is the ALSA machine driver for the device in question.
The registering of a) and b) cause the device driver for the codec to be
initialized by it's probe function getting called. Apart from various
hardware initializations, it registers the corresponding PCM driver via
snd_soc_register_platform(), and then registers the codec using
snd_soc_register_codec() (registering both the codec itself and its DAI,
although the latter actually doesn't contain any implementation as the
communication is handled directly via DMA rather than over some link
like I2S).
In the case of c), there is a device tree entry which corresponds to the
device. This in turn causes the the machine driver probe function to be
called, which does snd_soc_register_card(), binding together the codec
driver, the PCM driver with its DAI, and a dummy CPU DAI.
The final outcome of this is that ALSA outputs a "<codec dai> <->
snd-soc-dummy-dai ampping ok" message in the kernel log.
The device now works as intended. I can arecord from it and get what I
expect in the resulting output file.
Doing an lsmod at this point shows a usage count ('Used by') of 2. I don't
know if that is just due to snd_soc_register_card, or there is some
internal usage count due to the fact that there are a couple of drivers
registered at the same time. Certainly there are two hardware devices: one
representing the ALSA machine driver, specified in the device tree, and
one representing the actual hardware, which is registered at the machine
driver probe time.
Unbinding the driver, which is done by doing
cd /sys/bus/platform/drivers/<machine-driver-name>
followed by
echo -n <device-name> > unbind
causes the machine driver 'remove' function to be called, which in turn
does snd_soc_unregister_card.
A lot of the complexity is done to fit into the ALSA SoC driver model,
where we have
ALSA <-> PCM (DMA) driver <-> CPU DAI <-> CODEC DAI <-> CODEC
even though in this case there are no actual DAI's and the PCM driver
simply reads the data directly from the CODEC in memory. In the past I've
tried simplifying the hierarchy for a similar system, but it seems all the
components have to be there in some form. The only simplification is that
the CPU DAI can be snd-soc-dummy-dai, and that the only implementation
needed for CODEC DAI is the specification of things like the limitation of
the number channels, rates, and formats.
> Try to write just a simple module that register/unregister a card on
> module_init/module_exit, respectively. That should work just fine.
Since the driver uses information from the device tree, it seems that I
would need to follow the paradigm of registering a driver, which the Linux
device framework then associates with the corresponding device specified
in the device tree, in turn calling the probe function. At the moment this
driver is the ALSA machine driver.
An alternative would be to let the device tree entry correspond to the
codec device, avoiding the need to explicitly create a codec device in the
initialization code. I don't know if that would buy much in the end, but
it would allow me to do snd_soc_register card() at module init rather than
at probe time.
The problem as I see it is that with a usage count != 0, rmmod will not
even attempt to unload the driver, hence the module exit function will
never be called.
/Ricard
--
Ricard Wolf Wanderlöf ricardw(at)axis.com
Axis Communications AB, Lund, Sweden www.axis.com
Phone +46 46 272 2016 Fax +46 46 13 61 30
More information about the Alsa-devel
mailing list