aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/fsi.c
diff options
context:
space:
mode:
authorKuninori Morimoto <morimoto.kuninori@renesas.com>2009-12-02 01:11:08 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-12-03 05:53:37 -0500
commit71f6e0645be42f93c0f90dfcc93b9d2d277c2ee6 (patch)
treeb7c6ef8098423f1f42627f132a587b25038aa07f /sound/soc/sh/fsi.c
parentefd9eb96d5604c2c133e500f7b8c7b3f3fbdece8 (diff)
ASoC: sh_fsi: avoid using global variable
Current FSI driver use global variable to access device data. But this style will be broken if SuperH come with multiple FSI blocks in future. To solve this problem, this patch use cpu_dai->private_data. Signed-off-by: Kuninori Morimoto <morimoto.kuninori@renesas.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r--sound/soc/sh/fsi.c115
1 files changed, 62 insertions, 53 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 9c49c11c43ce..7506ef6d287a 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -92,6 +92,7 @@
92struct fsi_priv { 92struct fsi_priv {
93 void __iomem *base; 93 void __iomem *base;
94 struct snd_pcm_substream *substream; 94 struct snd_pcm_substream *substream;
95 struct fsi_master *master;
95 96
96 int fifo_max; 97 int fifo_max;
97 int chan; 98 int chan;
@@ -110,8 +111,6 @@ struct fsi_master {
110 struct sh_fsi_platform_info *info; 111 struct sh_fsi_platform_info *info;
111}; 112};
112 113
113static struct fsi_master *master;
114
115/************************************************************************ 114/************************************************************************
116 115
117 116
@@ -166,7 +165,7 @@ static int fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
166 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); 165 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
167} 166}
168 167
169static int fsi_master_write(u32 reg, u32 data) 168static int fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
170{ 169{
171 if ((reg < MREG_START) || 170 if ((reg < MREG_START) ||
172 (reg > MREG_END)) 171 (reg > MREG_END))
@@ -175,7 +174,7 @@ static int fsi_master_write(u32 reg, u32 data)
175 return __fsi_reg_write((u32)(master->base + reg), data); 174 return __fsi_reg_write((u32)(master->base + reg), data);
176} 175}
177 176
178static u32 fsi_master_read(u32 reg) 177static u32 fsi_master_read(struct fsi_master *master, u32 reg)
179{ 178{
180 if ((reg < MREG_START) || 179 if ((reg < MREG_START) ||
181 (reg > MREG_END)) 180 (reg > MREG_END))
@@ -184,7 +183,8 @@ static u32 fsi_master_read(u32 reg)
184 return __fsi_reg_read((u32)(master->base + reg)); 183 return __fsi_reg_read((u32)(master->base + reg));
185} 184}
186 185
187static int fsi_master_mask_set(u32 reg, u32 mask, u32 data) 186static int fsi_master_mask_set(struct fsi_master *master,
187 u32 reg, u32 mask, u32 data)
188{ 188{
189 if ((reg < MREG_START) || 189 if ((reg < MREG_START) ||
190 (reg > MREG_END)) 190 (reg > MREG_END))
@@ -200,43 +200,29 @@ static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
200 200
201 201
202************************************************************************/ 202************************************************************************/
203static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream) 203static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
204{ 204{
205 struct snd_soc_pcm_runtime *rtd; 205 return fsi->master;
206 struct fsi_priv *fsi = NULL;
207
208 if (!substream || !master)
209 return NULL;
210
211 rtd = substream->private_data;
212 switch (rtd->dai->cpu_dai->id) {
213 case 0:
214 fsi = &master->fsia;
215 break;
216 case 1:
217 fsi = &master->fsib;
218 break;
219 }
220
221 return fsi;
222} 206}
223 207
224static int fsi_is_port_a(struct fsi_priv *fsi) 208static int fsi_is_port_a(struct fsi_priv *fsi)
225{ 209{
226 /* return 210 return fsi->master->base == fsi->base;
227 * 1 : port a 211}
228 * 0 : port b
229 */
230 212
231 if (fsi == &master->fsia) 213static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
232 return 1; 214{
215 struct snd_soc_pcm_runtime *rtd = substream->private_data;
216 struct snd_soc_dai_link *machine = rtd->dai;
217 struct snd_soc_dai *dai = machine->cpu_dai;
233 218
234 return 0; 219 return dai->private_data;
235} 220}
236 221
237static u32 fsi_get_info_flags(struct fsi_priv *fsi) 222static u32 fsi_get_info_flags(struct fsi_priv *fsi)
238{ 223{
239 int is_porta = fsi_is_port_a(fsi); 224 int is_porta = fsi_is_port_a(fsi);
225 struct fsi_master *master = fsi_get_master(fsi);
240 226
241 return is_porta ? master->info->porta_flags : 227 return is_porta ? master->info->porta_flags :
242 master->info->portb_flags; 228 master->info->portb_flags;
@@ -314,27 +300,30 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
314static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) 300static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
315{ 301{
316 u32 data = fsi_port_ab_io_bit(fsi, is_play); 302 u32 data = fsi_port_ab_io_bit(fsi, is_play);
303 struct fsi_master *master = fsi_get_master(fsi);
317 304
318 fsi_master_mask_set(IMSK, data, data); 305 fsi_master_mask_set(master, IMSK, data, data);
319 fsi_master_mask_set(IEMSK, data, data); 306 fsi_master_mask_set(master, IEMSK, data, data);
320} 307}
321 308
322static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 309static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
323{ 310{
324 u32 data = fsi_port_ab_io_bit(fsi, is_play); 311 u32 data = fsi_port_ab_io_bit(fsi, is_play);
312 struct fsi_master *master = fsi_get_master(fsi);
325 313
326 fsi_master_mask_set(IMSK, data, 0); 314 fsi_master_mask_set(master, IMSK, data, 0);
327 fsi_master_mask_set(IEMSK, data, 0); 315 fsi_master_mask_set(master, IEMSK, data, 0);
328} 316}
329 317
330static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 318static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
331{ 319{
332 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 320 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
321 struct fsi_master *master = fsi_get_master(fsi);
333 322
334 if (enable) 323 if (enable)
335 fsi_master_mask_set(CLK_RST, val, val); 324 fsi_master_mask_set(master, CLK_RST, val, val);
336 else 325 else
337 fsi_master_mask_set(CLK_RST, val, 0); 326 fsi_master_mask_set(master, CLK_RST, val, 0);
338} 327}
339 328
340static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 329static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
@@ -355,23 +344,23 @@ static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
355 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 344 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
356 345
357 /* clear interrupt factor */ 346 /* clear interrupt factor */
358 fsi_master_mask_set(INT_ST, data, 0); 347 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
359} 348}
360 349
361static void fsi_soft_all_reset(void) 350static void fsi_soft_all_reset(struct fsi_master *master)
362{ 351{
363 u32 status = fsi_master_read(SOFT_RST); 352 u32 status = fsi_master_read(master, SOFT_RST);
364 353
365 /* port AB reset */ 354 /* port AB reset */
366 status &= 0x000000ff; 355 status &= 0x000000ff;
367 fsi_master_write(SOFT_RST, status); 356 fsi_master_write(master, SOFT_RST, status);
368 mdelay(10); 357 mdelay(10);
369 358
370 /* soft reset */ 359 /* soft reset */
371 status &= 0x000000f0; 360 status &= 0x000000f0;
372 fsi_master_write(SOFT_RST, status); 361 fsi_master_write(master, SOFT_RST, status);
373 status |= 0x00000001; 362 status |= 0x00000001;
374 fsi_master_write(SOFT_RST, status); 363 fsi_master_write(master, SOFT_RST, status);
375 mdelay(10); 364 mdelay(10);
376} 365}
377 366
@@ -517,12 +506,13 @@ static int fsi_data_pop(struct fsi_priv *fsi)
517 506
518static irqreturn_t fsi_interrupt(int irq, void *data) 507static irqreturn_t fsi_interrupt(int irq, void *data)
519{ 508{
520 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; 509 struct fsi_master *master = data;
521 u32 int_st = fsi_master_read(INT_ST); 510 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010;
511 u32 int_st = fsi_master_read(master, INT_ST);
522 512
523 /* clear irq status */ 513 /* clear irq status */
524 fsi_master_write(SOFT_RST, status); 514 fsi_master_write(master, SOFT_RST, status);
525 fsi_master_write(SOFT_RST, status | 0x00000010); 515 fsi_master_write(master, SOFT_RST, status | 0x00000010);
526 516
527 if (int_st & INT_A_OUT) 517 if (int_st & INT_A_OUT)
528 fsi_data_push(&master->fsia); 518 fsi_data_push(&master->fsia);
@@ -533,7 +523,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
533 if (int_st & INT_B_IN) 523 if (int_st & INT_B_IN)
534 fsi_data_pop(&master->fsib); 524 fsi_data_pop(&master->fsib);
535 525
536 fsi_master_write(INT_ST, 0x0000000); 526 fsi_master_write(master, INT_ST, 0x0000000);
537 527
538 return IRQ_HANDLED; 528 return IRQ_HANDLED;
539} 529}
@@ -548,7 +538,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
548static int fsi_dai_startup(struct snd_pcm_substream *substream, 538static int fsi_dai_startup(struct snd_pcm_substream *substream,
549 struct snd_soc_dai *dai) 539 struct snd_soc_dai *dai)
550{ 540{
551 struct fsi_priv *fsi = fsi_get(substream); 541 struct fsi_priv *fsi = fsi_get_priv(substream);
552 const char *msg; 542 const char *msg;
553 u32 flags = fsi_get_info_flags(fsi); 543 u32 flags = fsi_get_info_flags(fsi);
554 u32 fmt; 544 u32 fmt;
@@ -667,7 +657,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
667static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 657static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
668 struct snd_soc_dai *dai) 658 struct snd_soc_dai *dai)
669{ 659{
670 struct fsi_priv *fsi = fsi_get(substream); 660 struct fsi_priv *fsi = fsi_get_priv(substream);
671 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 661 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
672 662
673 fsi_irq_disable(fsi, is_play); 663 fsi_irq_disable(fsi, is_play);
@@ -679,7 +669,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
679static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 669static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
680 struct snd_soc_dai *dai) 670 struct snd_soc_dai *dai)
681{ 671{
682 struct fsi_priv *fsi = fsi_get(substream); 672 struct fsi_priv *fsi = fsi_get_priv(substream);
683 struct snd_pcm_runtime *runtime = substream->runtime; 673 struct snd_pcm_runtime *runtime = substream->runtime;
684 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 674 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
685 int ret = 0; 675 int ret = 0;
@@ -760,7 +750,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
760static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) 750static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
761{ 751{
762 struct snd_pcm_runtime *runtime = substream->runtime; 752 struct snd_pcm_runtime *runtime = substream->runtime;
763 struct fsi_priv *fsi = fsi_get(substream); 753 struct fsi_priv *fsi = fsi_get_priv(substream);
764 long location; 754 long location;
765 755
766 location = (fsi->byte_offset - 1); 756 location = (fsi->byte_offset - 1);
@@ -870,10 +860,16 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
870************************************************************************/ 860************************************************************************/
871static int fsi_probe(struct platform_device *pdev) 861static int fsi_probe(struct platform_device *pdev)
872{ 862{
863 struct fsi_master *master;
873 struct resource *res; 864 struct resource *res;
874 unsigned int irq; 865 unsigned int irq;
875 int ret; 866 int ret;
876 867
868 if (0 != pdev->id) {
869 dev_err(&pdev->dev, "current fsi support id 0 only now\n");
870 return -ENODEV;
871 }
872
877 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 873 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
878 irq = platform_get_irq(pdev, 0); 874 irq = platform_get_irq(pdev, 0);
879 if (!res || !irq) { 875 if (!res || !irq) {
@@ -899,15 +895,19 @@ static int fsi_probe(struct platform_device *pdev)
899 master->irq = irq; 895 master->irq = irq;
900 master->info = pdev->dev.platform_data; 896 master->info = pdev->dev.platform_data;
901 master->fsia.base = master->base; 897 master->fsia.base = master->base;
898 master->fsia.master = master;
902 master->fsib.base = master->base + 0x40; 899 master->fsib.base = master->base + 0x40;
900 master->fsib.master = master;
903 901
904 pm_runtime_enable(&pdev->dev); 902 pm_runtime_enable(&pdev->dev);
905 pm_runtime_resume(&pdev->dev); 903 pm_runtime_resume(&pdev->dev);
906 904
907 fsi_soc_dai[0].dev = &pdev->dev; 905 fsi_soc_dai[0].dev = &pdev->dev;
906 fsi_soc_dai[0].private_data = &master->fsia;
908 fsi_soc_dai[1].dev = &pdev->dev; 907 fsi_soc_dai[1].dev = &pdev->dev;
908 fsi_soc_dai[1].private_data = &master->fsib;
909 909
910 fsi_soft_all_reset(); 910 fsi_soft_all_reset(master);
911 911
912 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 912 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
913 if (ret) { 913 if (ret) {
@@ -937,6 +937,10 @@ exit:
937 937
938static int fsi_remove(struct platform_device *pdev) 938static int fsi_remove(struct platform_device *pdev)
939{ 939{
940 struct fsi_master *master;
941
942 master = fsi_get_master(fsi_soc_dai[0].private_data);
943
940 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 944 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
941 snd_soc_unregister_platform(&fsi_soc_platform); 945 snd_soc_unregister_platform(&fsi_soc_platform);
942 946
@@ -946,7 +950,12 @@ static int fsi_remove(struct platform_device *pdev)
946 950
947 iounmap(master->base); 951 iounmap(master->base);
948 kfree(master); 952 kfree(master);
949 master = NULL; 953
954 fsi_soc_dai[0].dev = NULL;
955 fsi_soc_dai[0].private_data = NULL;
956 fsi_soc_dai[1].dev = NULL;
957 fsi_soc_dai[1].private_data = NULL;
958
950 return 0; 959 return 0;
951} 960}
952 961