aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-04-20 21:33:47 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-04-26 06:42:06 -0400
commit106c79ecf2db141fcd6073de55ebeb3f041e0509 (patch)
tree22229bae75826537efbcd2cac23cf60159f01384
parent6a9ebad8214bba404255d1b209a038dc739c37b7 (diff)
ASoC: sh: fsi: add dev_pm_ops :: suspend/resume
Current FSI driver sets important settings when probing. And it are not set again as long as driver is not bind again. This mean FSI driver will lost it from register if suspend/resume are happen. This patch save important settings for suspend/resume. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Reviewed-by: Simon Horman <simon@horms.net> Acked-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/sh/fsi.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 5a2fdf3b84b9..1029a03c618e 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -153,6 +153,13 @@ struct fsi_priv {
153 int clk_master:1; 153 int clk_master:1;
154 154
155 long rate; 155 long rate;
156
157 /* for suspend/resume */
158 u32 saved_do_fmt;
159 u32 saved_di_fmt;
160 u32 saved_ckg1;
161 u32 saved_ckg2;
162 u32 saved_out_sel;
156}; 163};
157 164
158struct fsi_core { 165struct fsi_core {
@@ -173,6 +180,13 @@ struct fsi_master {
173 struct fsi_core *core; 180 struct fsi_core *core;
174 struct sh_fsi_platform_info *info; 181 struct sh_fsi_platform_info *info;
175 spinlock_t lock; 182 spinlock_t lock;
183
184 /* for suspend/resume */
185 u32 saved_a_mclk;
186 u32 saved_b_mclk;
187 u32 saved_iemsk;
188 u32 saved_imsk;
189 u32 saved_clk_rst;
176}; 190};
177 191
178/* 192/*
@@ -1277,6 +1291,76 @@ static int fsi_remove(struct platform_device *pdev)
1277 return 0; 1291 return 0;
1278} 1292}
1279 1293
1294static void __fsi_suspend(struct fsi_priv *fsi,
1295 struct device *dev,
1296 set_rate_func set_rate)
1297{
1298 fsi->saved_do_fmt = fsi_reg_read(fsi, DO_FMT);
1299 fsi->saved_di_fmt = fsi_reg_read(fsi, DI_FMT);
1300 fsi->saved_ckg1 = fsi_reg_read(fsi, CKG1);
1301 fsi->saved_ckg2 = fsi_reg_read(fsi, CKG2);
1302 fsi->saved_out_sel = fsi_reg_read(fsi, OUT_SEL);
1303
1304 if (fsi_is_clk_master(fsi))
1305 set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 0);
1306}
1307
1308static void __fsi_resume(struct fsi_priv *fsi,
1309 struct device *dev,
1310 set_rate_func set_rate)
1311{
1312 fsi_reg_write(fsi, DO_FMT, fsi->saved_do_fmt);
1313 fsi_reg_write(fsi, DI_FMT, fsi->saved_di_fmt);
1314 fsi_reg_write(fsi, CKG1, fsi->saved_ckg1);
1315 fsi_reg_write(fsi, CKG2, fsi->saved_ckg2);
1316 fsi_reg_write(fsi, OUT_SEL, fsi->saved_out_sel);
1317
1318 if (fsi_is_clk_master(fsi))
1319 set_rate(dev, fsi_is_port_a(fsi), fsi->rate, 1);
1320}
1321
1322static int fsi_suspend(struct device *dev)
1323{
1324 struct fsi_master *master = dev_get_drvdata(dev);
1325 set_rate_func set_rate = fsi_get_info_set_rate(master);
1326
1327 pm_runtime_get_sync(dev);
1328
1329 __fsi_suspend(&master->fsia, dev, set_rate);
1330 __fsi_suspend(&master->fsib, dev, set_rate);
1331
1332 master->saved_a_mclk = fsi_core_read(master, a_mclk);
1333 master->saved_b_mclk = fsi_core_read(master, b_mclk);
1334 master->saved_iemsk = fsi_core_read(master, iemsk);
1335 master->saved_imsk = fsi_core_read(master, imsk);
1336 master->saved_clk_rst = fsi_master_read(master, CLK_RST);
1337
1338 pm_runtime_put_sync(dev);
1339
1340 return 0;
1341}
1342
1343static int fsi_resume(struct device *dev)
1344{
1345 struct fsi_master *master = dev_get_drvdata(dev);
1346 set_rate_func set_rate = fsi_get_info_set_rate(master);
1347
1348 pm_runtime_get_sync(dev);
1349
1350 __fsi_resume(&master->fsia, dev, set_rate);
1351 __fsi_resume(&master->fsib, dev, set_rate);
1352
1353 fsi_core_mask_set(master, a_mclk, 0xffff, master->saved_a_mclk);
1354 fsi_core_mask_set(master, b_mclk, 0xffff, master->saved_b_mclk);
1355 fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk);
1356 fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk);
1357 fsi_master_mask_set(master, CLK_RST, 0xffff, master->saved_clk_rst);
1358
1359 pm_runtime_put_sync(dev);
1360
1361 return 0;
1362}
1363
1280static int fsi_runtime_nop(struct device *dev) 1364static int fsi_runtime_nop(struct device *dev)
1281{ 1365{
1282 /* Runtime PM callback shared between ->runtime_suspend() 1366 /* Runtime PM callback shared between ->runtime_suspend()
@@ -1290,6 +1374,8 @@ static int fsi_runtime_nop(struct device *dev)
1290} 1374}
1291 1375
1292static struct dev_pm_ops fsi_pm_ops = { 1376static struct dev_pm_ops fsi_pm_ops = {
1377 .suspend = fsi_suspend,
1378 .resume = fsi_resume,
1293 .runtime_suspend = fsi_runtime_nop, 1379 .runtime_suspend = fsi_runtime_nop,
1294 .runtime_resume = fsi_runtime_nop, 1380 .runtime_resume = fsi_runtime_nop,
1295}; 1381};