aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/fsi.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-05-23 07:46:35 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-05-24 06:42:02 -0400
commitcda828cafe9df9a8b0687f1b8a17be2cd9cf1950 (patch)
tree8d4d69c5444d5075b034d40a296d1749ddfec4e9 /sound/soc/sh/fsi.c
parent4c481253311dd5940ae7c26eaff6c6f63bd41fd8 (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.c97
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
196struct fsi_core { 189struct 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
376static 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
391static void fsi_stream_push(struct fsi_priv *fsi, 391static 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
1329static void __fsi_suspend(struct fsi_priv *fsi, 1327static 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
1342static void __fsi_resume(struct fsi_priv *fsi, 1338static 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
1355static int fsi_suspend(struct device *dev) 1354static 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)
1376static int fsi_resume(struct device *dev) 1369static 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}