aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorNicolin Chen <Guangyu.Chen@freescale.com>2014-05-15 06:53:25 -0400
committerNicolin Chen <Guangyu.Chen@freescale.com>2014-06-19 05:08:03 -0400
commit3f3781143ba2800f7e3e46dbecc0c7a76d22a146 (patch)
tree8c81c9532bfa52c183dcf6e1500d2e4a373a3a2b /sound/soc/fsl
parent34c50abd9df28580b367070bc20b8bca6cd7655c (diff)
ENGR00318773-10 ASoC: imx-audmux: Add driver suspend and resume to support MEGA Fast
For i.MX6 SoloX, there is a mode of the SoC to shutdown all power source of modules during system suspend and resume procedure. Thus, AUDMUX needs to save all the values of registers before the system suspend and restore them after the system resume. Acked-by: Wang Shengjiu <b02247@freescale.com> Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/imx-audmux.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 47f046a8fdab..3439232315df 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2012 Freescale Semiconductor, Inc. 2 * Copyright 2012-2014 Freescale Semiconductor, Inc.
3 * Copyright 2012 Linaro Ltd. 3 * Copyright 2012 Linaro Ltd.
4 * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> 4 * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
5 * 5 *
@@ -34,6 +34,8 @@
34 34
35static struct clk *audmux_clk; 35static struct clk *audmux_clk;
36static void __iomem *audmux_base; 36static void __iomem *audmux_base;
37static u32 *regcache;
38static u32 reg_max;
37 39
38#define IMX_AUDMUX_V2_PTCR(x) ((x) * 8) 40#define IMX_AUDMUX_V2_PTCR(x) ((x) * 8)
39#define IMX_AUDMUX_V2_PDCR(x) ((x) * 8 + 4) 41#define IMX_AUDMUX_V2_PDCR(x) ((x) * 8 + 4)
@@ -272,8 +274,22 @@ static int imx_audmux_probe(struct platform_device *pdev)
272 if (of_id) 274 if (of_id)
273 pdev->id_entry = of_id->data; 275 pdev->id_entry = of_id->data;
274 audmux_type = pdev->id_entry->driver_data; 276 audmux_type = pdev->id_entry->driver_data;
275 if (audmux_type == IMX31_AUDMUX) 277
278 switch (audmux_type) {
279 case IMX31_AUDMUX:
276 audmux_debugfs_init(); 280 audmux_debugfs_init();
281 reg_max = 14;
282 break;
283 case IMX21_AUDMUX:
284 reg_max = 6;
285 default:
286 dev_err(&pdev->dev, "unsupported version!\n");
287 return -EINVAL;
288 }
289
290 regcache = devm_kzalloc(&pdev->dev, sizeof(u32) * reg_max, GFP_KERNEL);
291 if (!regcache)
292 return -ENOMEM;
277 293
278 return 0; 294 return 0;
279} 295}
@@ -286,6 +302,40 @@ static int imx_audmux_remove(struct platform_device *pdev)
286 return 0; 302 return 0;
287} 303}
288 304
305#ifdef CONFIG_PM_SLEEP
306static int imx_audmux_suspend(struct device *dev)
307{
308 int i;
309
310 clk_prepare_enable(audmux_clk);
311
312 for (i = 0; i < reg_max; i++)
313 regcache[i] = readl(audmux_base + i * 4);
314
315 clk_disable_unprepare(audmux_clk);
316
317 return 0;
318}
319
320static int imx_audmux_resume(struct device *dev)
321{
322 int i;
323
324 clk_prepare_enable(audmux_clk);
325
326 for (i = 0; i < reg_max; i++)
327 writel(regcache[i], audmux_base + i * 4);
328
329 clk_disable_unprepare(audmux_clk);
330
331 return 0;
332}
333#endif /* CONFIG_PM_SLEEP */
334
335static const struct dev_pm_ops imx_audmux_pm = {
336 SET_SYSTEM_SLEEP_PM_OPS(imx_audmux_suspend, imx_audmux_resume)
337};
338
289static struct platform_driver imx_audmux_driver = { 339static struct platform_driver imx_audmux_driver = {
290 .probe = imx_audmux_probe, 340 .probe = imx_audmux_probe,
291 .remove = imx_audmux_remove, 341 .remove = imx_audmux_remove,
@@ -293,6 +343,7 @@ static struct platform_driver imx_audmux_driver = {
293 .driver = { 343 .driver = {
294 .name = DRIVER_NAME, 344 .name = DRIVER_NAME,
295 .owner = THIS_MODULE, 345 .owner = THIS_MODULE,
346 .pm = &imx_audmux_pm,
296 .of_match_table = imx_audmux_dt_ids, 347 .of_match_table = imx_audmux_dt_ids,
297 } 348 }
298}; 349};