diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-05-23 07:46:35 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-05-24 06:42:02 -0400 |
commit | cda828cafe9df9a8b0687f1b8a17be2cd9cf1950 (patch) | |
tree | 8d4d69c5444d5075b034d40a296d1749ddfec4e9 /sound/soc/sh/fsi.c | |
parent | 4c481253311dd5940ae7c26eaff6c6f63bd41fd8 (diff) |
ASoC: sh: fsi: cleanup suspend/resume
Current FSI driver was using saved_xxx variable for suspend/resume.
OTOH, the start and stop of power/clock are controlled by
fsi_hw_startup/fsi_hw_shutdown in current FSI driver.
The all necessary registers value are set by fsi_hw_startup.
So, if fsi_hw_shutdown is called when "suspend" is generated,
and fsi_hw_startup is called at "resume",
the saved_xxx are not needed.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Acked-by: Liam Girdwood <lrg@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r-- | sound/soc/sh/fsi.c | 97 |
1 files changed, 42 insertions, 55 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index c60854607b8e..507c02b1c809 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -184,13 +184,6 @@ struct fsi_priv { | |||
184 | int spdif:1; | 184 | int spdif:1; |
185 | 185 | ||
186 | long rate; | 186 | long rate; |
187 | |||
188 | /* for suspend/resume */ | ||
189 | u32 saved_do_fmt; | ||
190 | u32 saved_di_fmt; | ||
191 | u32 saved_ckg1; | ||
192 | u32 saved_ckg2; | ||
193 | u32 saved_out_sel; | ||
194 | }; | 187 | }; |
195 | 188 | ||
196 | struct fsi_core { | 189 | struct fsi_core { |
@@ -211,14 +204,6 @@ struct fsi_master { | |||
211 | struct fsi_core *core; | 204 | struct fsi_core *core; |
212 | struct sh_fsi_platform_info *info; | 205 | struct sh_fsi_platform_info *info; |
213 | spinlock_t lock; | 206 | spinlock_t lock; |
214 | |||
215 | /* for suspend/resume */ | ||
216 | u32 saved_a_mclk; | ||
217 | u32 saved_b_mclk; | ||
218 | u32 saved_iemsk; | ||
219 | u32 saved_imsk; | ||
220 | u32 saved_clk_rst; | ||
221 | u32 saved_soft_rst; | ||
222 | }; | 207 | }; |
223 | 208 | ||
224 | /* | 209 | /* |
@@ -388,6 +373,21 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples) | |||
388 | return samples / fsi->chan_num; | 373 | return samples / fsi->chan_num; |
389 | } | 374 | } |
390 | 375 | ||
376 | static int fsi_stream_is_working(struct fsi_priv *fsi, | ||
377 | int is_play) | ||
378 | { | ||
379 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | ||
380 | struct fsi_master *master = fsi_get_master(fsi); | ||
381 | unsigned long flags; | ||
382 | int ret; | ||
383 | |||
384 | spin_lock_irqsave(&master->lock, flags); | ||
385 | ret = !!io->substream; | ||
386 | spin_unlock_irqrestore(&master->lock, flags); | ||
387 | |||
388 | return ret; | ||
389 | } | ||
390 | |||
391 | static void fsi_stream_push(struct fsi_priv *fsi, | 391 | static void fsi_stream_push(struct fsi_priv *fsi, |
392 | int is_play, | 392 | int is_play, |
393 | struct snd_pcm_substream *substream) | 393 | struct snd_pcm_substream *substream) |
@@ -666,7 +666,6 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | |||
666 | } | 666 | } |
667 | 667 | ||
668 | return ret; | 668 | return ret; |
669 | |||
670 | } | 669 | } |
671 | 670 | ||
672 | #define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1) | 671 | #define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1) |
@@ -675,14 +674,13 @@ static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable) | |||
675 | { | 674 | { |
676 | struct fsi_master *master = fsi_get_master(fsi); | 675 | struct fsi_master *master = fsi_get_master(fsi); |
677 | u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; | 676 | u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; |
678 | int is_master = fsi_is_clk_master(fsi); | ||
679 | 677 | ||
680 | if (enable) | 678 | if (enable) |
681 | fsi_irq_enable(fsi, is_play); | 679 | fsi_irq_enable(fsi, is_play); |
682 | else | 680 | else |
683 | fsi_irq_disable(fsi, is_play); | 681 | fsi_irq_disable(fsi, is_play); |
684 | 682 | ||
685 | if (is_master) | 683 | if (fsi_is_clk_master(fsi)) |
686 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); | 684 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); |
687 | } | 685 | } |
688 | 686 | ||
@@ -1327,48 +1325,43 @@ static int fsi_remove(struct platform_device *pdev) | |||
1327 | } | 1325 | } |
1328 | 1326 | ||
1329 | static void __fsi_suspend(struct fsi_priv *fsi, | 1327 | static void __fsi_suspend(struct fsi_priv *fsi, |
1328 | int is_play, | ||
1330 | struct device *dev) | 1329 | struct device *dev) |
1331 | { | 1330 | { |
1332 | fsi->saved_do_fmt = fsi_reg_read(fsi, DO_FMT); | 1331 | if (!fsi_stream_is_working(fsi, is_play)) |
1333 | fsi->saved_di_fmt = fsi_reg_read(fsi, DI_FMT); | 1332 | return; |
1334 | fsi->saved_ckg1 = fsi_reg_read(fsi, CKG1); | ||
1335 | fsi->saved_ckg2 = fsi_reg_read(fsi, CKG2); | ||
1336 | fsi->saved_out_sel = fsi_reg_read(fsi, OUT_SEL); | ||
1337 | 1333 | ||
1338 | if (fsi_is_clk_master(fsi)) | 1334 | fsi_port_stop(fsi, is_play); |
1339 | fsi_set_master_clk(dev, fsi, fsi->rate, 0); | 1335 | fsi_hw_shutdown(fsi, is_play, dev); |
1340 | } | 1336 | } |
1341 | 1337 | ||
1342 | static void __fsi_resume(struct fsi_priv *fsi, | 1338 | static void __fsi_resume(struct fsi_priv *fsi, |
1339 | int is_play, | ||
1343 | struct device *dev) | 1340 | struct device *dev) |
1344 | { | 1341 | { |
1345 | fsi_reg_write(fsi, DO_FMT, fsi->saved_do_fmt); | 1342 | if (!fsi_stream_is_working(fsi, is_play)) |
1346 | fsi_reg_write(fsi, DI_FMT, fsi->saved_di_fmt); | 1343 | return; |
1347 | fsi_reg_write(fsi, CKG1, fsi->saved_ckg1); | ||
1348 | fsi_reg_write(fsi, CKG2, fsi->saved_ckg2); | ||
1349 | fsi_reg_write(fsi, OUT_SEL, fsi->saved_out_sel); | ||
1350 | 1344 | ||
1351 | if (fsi_is_clk_master(fsi)) | 1345 | fsi_hw_startup(fsi, is_play, dev); |
1346 | |||
1347 | if (fsi_is_clk_master(fsi) && fsi->rate) | ||
1352 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); | 1348 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); |
1349 | |||
1350 | fsi_port_start(fsi, is_play); | ||
1351 | |||
1353 | } | 1352 | } |
1354 | 1353 | ||
1355 | static int fsi_suspend(struct device *dev) | 1354 | static int fsi_suspend(struct device *dev) |
1356 | { | 1355 | { |
1357 | struct fsi_master *master = dev_get_drvdata(dev); | 1356 | struct fsi_master *master = dev_get_drvdata(dev); |
1357 | struct fsi_priv *fsia = &master->fsia; | ||
1358 | struct fsi_priv *fsib = &master->fsib; | ||
1358 | 1359 | ||
1359 | pm_runtime_get_sync(dev); | 1360 | __fsi_suspend(fsia, 1, dev); |
1360 | 1361 | __fsi_suspend(fsia, 0, dev); | |
1361 | __fsi_suspend(&master->fsia, dev); | ||
1362 | __fsi_suspend(&master->fsib, dev); | ||
1363 | 1362 | ||
1364 | master->saved_a_mclk = fsi_core_read(master, a_mclk); | 1363 | __fsi_suspend(fsib, 1, dev); |
1365 | master->saved_b_mclk = fsi_core_read(master, b_mclk); | 1364 | __fsi_suspend(fsib, 0, dev); |
1366 | master->saved_iemsk = fsi_core_read(master, iemsk); | ||
1367 | master->saved_imsk = fsi_core_read(master, imsk); | ||
1368 | master->saved_clk_rst = fsi_master_read(master, CLK_RST); | ||
1369 | master->saved_soft_rst = fsi_master_read(master, SOFT_RST); | ||
1370 | |||
1371 | pm_runtime_put_sync(dev); | ||
1372 | 1365 | ||
1373 | return 0; | 1366 | return 0; |
1374 | } | 1367 | } |
@@ -1376,20 +1369,14 @@ static int fsi_suspend(struct device *dev) | |||
1376 | static int fsi_resume(struct device *dev) | 1369 | static int fsi_resume(struct device *dev) |
1377 | { | 1370 | { |
1378 | struct fsi_master *master = dev_get_drvdata(dev); | 1371 | struct fsi_master *master = dev_get_drvdata(dev); |
1372 | struct fsi_priv *fsia = &master->fsia; | ||
1373 | struct fsi_priv *fsib = &master->fsib; | ||
1379 | 1374 | ||
1380 | pm_runtime_get_sync(dev); | 1375 | __fsi_resume(fsia, 1, dev); |
1381 | 1376 | __fsi_resume(fsia, 0, dev); | |
1382 | fsi_master_mask_set(master, SOFT_RST, 0xffff, master->saved_soft_rst); | ||
1383 | fsi_master_mask_set(master, CLK_RST, 0xffff, master->saved_clk_rst); | ||
1384 | fsi_core_mask_set(master, a_mclk, 0xffff, master->saved_a_mclk); | ||
1385 | fsi_core_mask_set(master, b_mclk, 0xffff, master->saved_b_mclk); | ||
1386 | fsi_core_mask_set(master, iemsk, 0xffff, master->saved_iemsk); | ||
1387 | fsi_core_mask_set(master, imsk, 0xffff, master->saved_imsk); | ||
1388 | |||
1389 | __fsi_resume(&master->fsia, dev); | ||
1390 | __fsi_resume(&master->fsib, dev); | ||
1391 | 1377 | ||
1392 | pm_runtime_put_sync(dev); | 1378 | __fsi_resume(fsib, 1, dev); |
1379 | __fsi_resume(fsib, 0, dev); | ||
1393 | 1380 | ||
1394 | return 0; | 1381 | return 0; |
1395 | } | 1382 | } |