aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl/imx-audmux.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl/imx-audmux.c')
-rw-r--r--sound/soc/fsl/imx-audmux.c78
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);
224int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, 227int 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}
244EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); 252EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port);
245 253
254static 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
246static int imx_audmux_probe(struct platform_device *pdev) 314static 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