Merge branch 'topic/ac97-bus' into for-next
This commit is contained in:
Коммит
ab1bcc93b7
|
@ -0,0 +1,32 @@
|
|||
Generic AC97 Device Properties
|
||||
|
||||
This documents describes the devicetree bindings for an ac97 controller child
|
||||
node describing ac97 codecs.
|
||||
|
||||
Required properties:
|
||||
-compatible : Must be "ac97,vendor_id1,vendor_id2
|
||||
The ids shall be the 4 characters hexadecimal encoding, such as
|
||||
given by "%04x" formatting of printf
|
||||
-reg : Must be the ac97 codec number, between 0 and 3
|
||||
|
||||
Example:
|
||||
ac97: sound@40500000 {
|
||||
compatible = "marvell,pxa270-ac97";
|
||||
reg = < 0x40500000 0x1000 >;
|
||||
interrupts = <14>;
|
||||
reset-gpios = <&gpio 95 GPIO_ACTIVE_HIGH>;
|
||||
#sound-dai-cells = <1>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = < &pinctrl_ac97_default >;
|
||||
clocks = <&clks CLK_AC97>, <&clks CLK_AC97CONF>;
|
||||
clock-names = "AC97CLK", "AC97CONFCLK";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
audio-codec@0 {
|
||||
reg = <0>;
|
||||
compatible = "ac97,574d,4c13";
|
||||
clocks = <&fixed_wm9713_clock>;
|
||||
clock-names = "ac97_clk";
|
||||
}
|
||||
};
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/idr.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -68,6 +69,27 @@ ac97_codec_find(struct ac97_controller *ac97_ctrl, unsigned int codec_num)
|
|||
return ac97_ctrl->codecs[codec_num];
|
||||
}
|
||||
|
||||
static struct device_node *
|
||||
ac97_of_get_child_device(struct ac97_controller *ac97_ctrl, int idx,
|
||||
unsigned int vendor_id)
|
||||
{
|
||||
struct device_node *node;
|
||||
u32 reg;
|
||||
char compat[] = "ac97,0000,0000";
|
||||
|
||||
snprintf(compat, sizeof(compat), "ac97,%04x,%04x",
|
||||
vendor_id >> 16, vendor_id & 0xffff);
|
||||
|
||||
for_each_child_of_node(ac97_ctrl->parent->of_node, node) {
|
||||
if ((idx != of_property_read_u32(node, "reg", ®)) ||
|
||||
!of_device_is_compatible(node, compat))
|
||||
continue;
|
||||
return of_node_get(node);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ac97_codec_release(struct device *dev)
|
||||
{
|
||||
struct ac97_codec_device *adev;
|
||||
|
@ -76,6 +98,7 @@ static void ac97_codec_release(struct device *dev)
|
|||
adev = to_ac97_device(dev);
|
||||
ac97_ctrl = adev->ac97_ctrl;
|
||||
ac97_ctrl->codecs[adev->num] = NULL;
|
||||
of_node_put(dev->of_node);
|
||||
kfree(adev);
|
||||
}
|
||||
|
||||
|
@ -98,6 +121,8 @@ static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
|
|||
|
||||
device_initialize(&codec->dev);
|
||||
dev_set_name(&codec->dev, "%s:%u", dev_name(ac97_ctrl->parent), idx);
|
||||
codec->dev.of_node = ac97_of_get_child_device(ac97_ctrl, idx,
|
||||
vendor_id);
|
||||
|
||||
ret = device_add(&codec->dev);
|
||||
if (ret)
|
||||
|
@ -105,6 +130,7 @@ static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
|
|||
|
||||
return 0;
|
||||
err_free_codec:
|
||||
of_node_put(codec->dev.of_node);
|
||||
put_device(&codec->dev);
|
||||
kfree(codec);
|
||||
ac97_ctrl->codecs[idx] = NULL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче