Loading Documentation/devicetree/bindings/sound/ac97-bus.txt 0 → 100644 +32 −0 Original line number Diff line number Diff line 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"; } }; sound/ac97/bus.c +26 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading @@ -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); } Loading @@ -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) Loading @@ -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; Loading Loading
Documentation/devicetree/bindings/sound/ac97-bus.txt 0 → 100644 +32 −0 Original line number Diff line number Diff line 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"; } };
sound/ac97/bus.c +26 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading @@ -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); } Loading @@ -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) Loading @@ -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; Loading