diff options
Diffstat (limited to 'sound/soc/fsl/imx-audmux.c')
-rw-r--r-- | sound/soc/fsl/imx-audmux.c | 78 |
1 files changed, 74 insertions, 4 deletions
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c index e260f1f899db..ab17381cc981 100644 --- a/sound/soc/fsl/imx-audmux.c +++ b/sound/soc/fsl/imx-audmux.c | |||
@@ -73,8 +73,11 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf, | |||
73 | if (!buf) | 73 | if (!buf) |
74 | return -ENOMEM; | 74 | return -ENOMEM; |
75 | 75 | ||
76 | if (audmux_clk) | 76 | if (audmux_clk) { |
77 | clk_prepare_enable(audmux_clk); | 77 | ret = clk_prepare_enable(audmux_clk); |
78 | if (ret) | ||
79 | return ret; | ||
80 | } | ||
78 | 81 | ||
79 | ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port)); | 82 | ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port)); |
80 | pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port)); | 83 | pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port)); |
@@ -224,14 +227,19 @@ EXPORT_SYMBOL_GPL(imx_audmux_v1_configure_port); | |||
224 | int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, | 227 | int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, |
225 | unsigned int pdcr) | 228 | unsigned int pdcr) |
226 | { | 229 | { |
230 | int ret; | ||
231 | |||
227 | if (audmux_type != IMX31_AUDMUX) | 232 | if (audmux_type != IMX31_AUDMUX) |
228 | return -EINVAL; | 233 | return -EINVAL; |
229 | 234 | ||
230 | if (!audmux_base) | 235 | if (!audmux_base) |
231 | return -ENOSYS; | 236 | return -ENOSYS; |
232 | 237 | ||
233 | if (audmux_clk) | 238 | if (audmux_clk) { |
234 | clk_prepare_enable(audmux_clk); | 239 | ret = clk_prepare_enable(audmux_clk); |
240 | if (ret) | ||
241 | return ret; | ||
242 | } | ||
235 | 243 | ||
236 | writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port)); | 244 | writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port)); |
237 | writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port)); | 245 | writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port)); |
@@ -243,6 +251,66 @@ int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, | |||
243 | } | 251 | } |
244 | EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); | 252 | EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); |
245 | 253 | ||
254 | static int imx_audmux_parse_dt_defaults(struct platform_device *pdev, | ||
255 | struct device_node *of_node) | ||
256 | { | ||
257 | struct device_node *child; | ||
258 | |||
259 | for_each_available_child_of_node(of_node, child) { | ||
260 | unsigned int port; | ||
261 | unsigned int ptcr = 0; | ||
262 | unsigned int pdcr = 0; | ||
263 | unsigned int pcr = 0; | ||
264 | unsigned int val; | ||
265 | int ret; | ||
266 | int i = 0; | ||
267 | |||
268 | ret = of_property_read_u32(child, "fsl,audmux-port", &port); | ||
269 | if (ret) { | ||
270 | dev_warn(&pdev->dev, "Failed to get fsl,audmux-port of child node \"%s\"\n", | ||
271 | child->full_name); | ||
272 | continue; | ||
273 | } | ||
274 | if (!of_property_read_bool(child, "fsl,port-config")) { | ||
275 | dev_warn(&pdev->dev, "child node \"%s\" does not have property fsl,port-config\n", | ||
276 | child->full_name); | ||
277 | continue; | ||
278 | } | ||
279 | |||
280 | for (i = 0; (ret = of_property_read_u32_index(child, | ||
281 | "fsl,port-config", i, &val)) == 0; | ||
282 | ++i) { | ||
283 | if (audmux_type == IMX31_AUDMUX) { | ||
284 | if (i % 2) | ||
285 | pdcr |= val; | ||
286 | else | ||
287 | ptcr |= val; | ||
288 | } else { | ||
289 | pcr |= val; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | if (ret != -EOVERFLOW) { | ||
294 | dev_err(&pdev->dev, "Failed to read u32 at index %d of child %s\n", | ||
295 | i, child->full_name); | ||
296 | continue; | ||
297 | } | ||
298 | |||
299 | if (audmux_type == IMX31_AUDMUX) { | ||
300 | if (i % 2) { | ||
301 | dev_err(&pdev->dev, "One pdcr value is missing in child node %s\n", | ||
302 | child->full_name); | ||
303 | continue; | ||
304 | } | ||
305 | imx_audmux_v2_configure_port(port, ptcr, pdcr); | ||
306 | } else { | ||
307 | imx_audmux_v1_configure_port(port, pcr); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
246 | static int imx_audmux_probe(struct platform_device *pdev) | 314 | static int imx_audmux_probe(struct platform_device *pdev) |
247 | { | 315 | { |
248 | struct resource *res; | 316 | struct resource *res; |
@@ -267,6 +335,8 @@ static int imx_audmux_probe(struct platform_device *pdev) | |||
267 | if (audmux_type == IMX31_AUDMUX) | 335 | if (audmux_type == IMX31_AUDMUX) |
268 | audmux_debugfs_init(); | 336 | audmux_debugfs_init(); |
269 | 337 | ||
338 | imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node); | ||
339 | |||
270 | return 0; | 340 | return 0; |
271 | } | 341 | } |
272 | 342 | ||