root/sound/soc/sh/siu_dai.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. siu_dai_start
  2. siu_dai_stop
  3. siu_dai_spbAselect
  4. siu_dai_spbBselect
  5. siu_dai_open
  6. siu_dai_pcmdatapack
  7. siu_dai_spbstart
  8. siu_dai_spbstop
  9. siu_dai_info_volume
  10. siu_dai_get_volume
  11. siu_dai_put_volume
  12. siu_init_port
  13. siu_free_port
  14. siu_dai_startup
  15. siu_dai_shutdown
  16. siu_dai_prepare
  17. siu_dai_set_fmt
  18. siu_dai_set_sysclk
  19. siu_probe
  20. siu_remove

   1 // SPDX-License-Identifier: GPL-2.0+
   2 //
   3 // siu_dai.c - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
   4 //
   5 // Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
   6 // Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
   7 
   8 #include <linux/delay.h>
   9 #include <linux/firmware.h>
  10 #include <linux/pm_runtime.h>
  11 #include <linux/slab.h>
  12 #include <linux/module.h>
  13 
  14 #include <asm/clock.h>
  15 #include <asm/siu.h>
  16 
  17 #include <sound/control.h>
  18 #include <sound/soc.h>
  19 
  20 #include "siu.h"
  21 
  22 /* Board specifics */
  23 #if defined(CONFIG_CPU_SUBTYPE_SH7722)
  24 # define SIU_MAX_VOLUME         0x1000
  25 #else
  26 # define SIU_MAX_VOLUME         0x7fff
  27 #endif
  28 
  29 #define PRAM_SIZE       0x2000
  30 #define XRAM_SIZE       0x800
  31 #define YRAM_SIZE       0x800
  32 
  33 #define XRAM_OFFSET     0x4000
  34 #define YRAM_OFFSET     0x6000
  35 #define REG_OFFSET      0xc000
  36 
  37 #define PLAYBACK_ENABLED        1
  38 #define CAPTURE_ENABLED         2
  39 
  40 #define VOLUME_CAPTURE          0
  41 #define VOLUME_PLAYBACK         1
  42 #define DFLT_VOLUME_LEVEL       0x08000800
  43 
  44 /*
  45  * SPDIF is only available on port A and on some SIU implementations it is only
  46  * available for input. Due to the lack of hardware to test it, SPDIF is left
  47  * disabled in this driver version
  48  */
  49 struct format_flag {
  50         u32     i2s;
  51         u32     pcm;
  52         u32     spdif;
  53         u32     mask;
  54 };
  55 
  56 struct port_flag {
  57         struct format_flag      playback;
  58         struct format_flag      capture;
  59 };
  60 
  61 struct siu_info *siu_i2s_data;
  62 
  63 static struct port_flag siu_flags[SIU_PORT_NUM] = {
  64         [SIU_PORT_A] = {
  65                 .playback = {
  66                         .i2s    = 0x50000000,
  67                         .pcm    = 0x40000000,
  68                         .spdif  = 0x80000000,   /* not on all SIU versions */
  69                         .mask   = 0xd0000000,
  70                 },
  71                 .capture = {
  72                         .i2s    = 0x05000000,
  73                         .pcm    = 0x04000000,
  74                         .spdif  = 0x08000000,
  75                         .mask   = 0x0d000000,
  76                 },
  77         },
  78         [SIU_PORT_B] = {
  79                 .playback = {
  80                         .i2s    = 0x00500000,
  81                         .pcm    = 0x00400000,
  82                         .spdif  = 0,            /* impossible - turn off */
  83                         .mask   = 0x00500000,
  84                 },
  85                 .capture = {
  86                         .i2s    = 0x00050000,
  87                         .pcm    = 0x00040000,
  88                         .spdif  = 0,            /* impossible - turn off */
  89                         .mask   = 0x00050000,
  90                 },
  91         },
  92 };
  93 
  94 static void siu_dai_start(struct siu_port *port_info)
  95 {
  96         struct siu_info *info = siu_i2s_data;
  97         u32 __iomem *base = info->reg;
  98 
  99         dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
 100 
 101         /* Issue software reset to siu */
 102         siu_write32(base + SIU_SRCTL, 0);
 103 
 104         /* Wait for the reset to take effect */
 105         udelay(1);
 106 
 107         port_info->stfifo = 0;
 108         port_info->trdat = 0;
 109 
 110         /* portA, portB, SIU operate */
 111         siu_write32(base + SIU_SRCTL, 0x301);
 112 
 113         /* portA=256fs, portB=256fs */
 114         siu_write32(base + SIU_CKCTL, 0x40400000);
 115 
 116         /* portA's BRG does not divide SIUCKA */
 117         siu_write32(base + SIU_BRGASEL, 0);
 118         siu_write32(base + SIU_BRRA, 0);
 119 
 120         /* portB's BRG divides SIUCKB by half */
 121         siu_write32(base + SIU_BRGBSEL, 1);
 122         siu_write32(base + SIU_BRRB, 0);
 123 
 124         siu_write32(base + SIU_IFCTL, 0x44440000);
 125 
 126         /* portA: 32 bit/fs, master; portB: 32 bit/fs, master */
 127         siu_write32(base + SIU_SFORM, 0x0c0c0000);
 128 
 129         /*
 130          * Volume levels: looks like the DSP firmware implements volume controls
 131          * differently from what's described in the datasheet
 132          */
 133         siu_write32(base + SIU_SBDVCA, port_info->playback.volume);
 134         siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
 135 }
 136 
 137 static void siu_dai_stop(struct siu_port *port_info)
 138 {
 139         struct siu_info *info = siu_i2s_data;
 140         u32 __iomem *base = info->reg;
 141 
 142         /* SIU software reset */
 143         siu_write32(base + SIU_SRCTL, 0);
 144 }
 145 
 146 static void siu_dai_spbAselect(struct siu_port *port_info)
 147 {
 148         struct siu_info *info = siu_i2s_data;
 149         struct siu_firmware *fw = &info->fw;
 150         u32 *ydef = fw->yram0;
 151         u32 idx;
 152 
 153         /* path A use */
 154         if (!info->port_id)
 155                 idx = 1;                /* portA */
 156         else
 157                 idx = 2;                /* portB */
 158 
 159         ydef[0] = (fw->spbpar[idx].ab1a << 16) |
 160                 (fw->spbpar[idx].ab0a << 8) |
 161                 (fw->spbpar[idx].dir << 7) | 3;
 162         ydef[1] = fw->yram0[1]; /* 0x03000300 */
 163         ydef[2] = (16 / 2) << 24;
 164         ydef[3] = fw->yram0[3]; /* 0 */
 165         ydef[4] = fw->yram0[4]; /* 0 */
 166         ydef[7] = fw->spbpar[idx].event;
 167         port_info->stfifo |= fw->spbpar[idx].stfifo;
 168         port_info->trdat |= fw->spbpar[idx].trdat;
 169 }
 170 
 171 static void siu_dai_spbBselect(struct siu_port *port_info)
 172 {
 173         struct siu_info *info = siu_i2s_data;
 174         struct siu_firmware *fw = &info->fw;
 175         u32 *ydef = fw->yram0;
 176         u32 idx;
 177 
 178         /* path B use */
 179         if (!info->port_id)
 180                 idx = 7;                /* portA */
 181         else
 182                 idx = 8;                /* portB */
 183 
 184         ydef[5] = (fw->spbpar[idx].ab1a << 16) |
 185                 (fw->spbpar[idx].ab0a << 8) | 1;
 186         ydef[6] = fw->spbpar[idx].event;
 187         port_info->stfifo |= fw->spbpar[idx].stfifo;
 188         port_info->trdat |= fw->spbpar[idx].trdat;
 189 }
 190 
 191 static void siu_dai_open(struct siu_stream *siu_stream)
 192 {
 193         struct siu_info *info = siu_i2s_data;
 194         u32 __iomem *base = info->reg;
 195         u32 srctl, ifctl;
 196 
 197         srctl = siu_read32(base + SIU_SRCTL);
 198         ifctl = siu_read32(base + SIU_IFCTL);
 199 
 200         switch (info->port_id) {
 201         case SIU_PORT_A:
 202                 /* portA operates */
 203                 srctl |= 0x200;
 204                 ifctl &= ~0xc2;
 205                 break;
 206         case SIU_PORT_B:
 207                 /* portB operates */
 208                 srctl |= 0x100;
 209                 ifctl &= ~0x31;
 210                 break;
 211         }
 212 
 213         siu_write32(base + SIU_SRCTL, srctl);
 214         /* Unmute and configure portA */
 215         siu_write32(base + SIU_IFCTL, ifctl);
 216 }
 217 
 218 /*
 219  * At the moment only fixed Left-upper, Left-lower, Right-upper, Right-lower
 220  * packing is supported
 221  */
 222 static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
 223 {
 224         struct siu_info *info = siu_i2s_data;
 225         u32 __iomem *base = info->reg;
 226         u32 dpak;
 227 
 228         dpak = siu_read32(base + SIU_DPAK);
 229 
 230         switch (info->port_id) {
 231         case SIU_PORT_A:
 232                 dpak &= ~0xc0000000;
 233                 break;
 234         case SIU_PORT_B:
 235                 dpak &= ~0x00c00000;
 236                 break;
 237         }
 238 
 239         siu_write32(base + SIU_DPAK, dpak);
 240 }
 241 
 242 static int siu_dai_spbstart(struct siu_port *port_info)
 243 {
 244         struct siu_info *info = siu_i2s_data;
 245         u32 __iomem *base = info->reg;
 246         struct siu_firmware *fw = &info->fw;
 247         u32 *ydef = fw->yram0;
 248         int cnt;
 249         u32 __iomem *add;
 250         u32 *ptr;
 251 
 252         /* Load SPB Program in PRAM */
 253         ptr = fw->pram0;
 254         add = info->pram;
 255         for (cnt = 0; cnt < PRAM0_SIZE; cnt++, add++, ptr++)
 256                 siu_write32(add, *ptr);
 257 
 258         ptr = fw->pram1;
 259         add = info->pram + (0x0100 / sizeof(u32));
 260         for (cnt = 0; cnt < PRAM1_SIZE; cnt++, add++, ptr++)
 261                 siu_write32(add, *ptr);
 262 
 263         /* XRAM initialization */
 264         add = info->xram;
 265         for (cnt = 0; cnt < XRAM0_SIZE + XRAM1_SIZE + XRAM2_SIZE; cnt++, add++)
 266                 siu_write32(add, 0);
 267 
 268         /* YRAM variable area initialization */
 269         add = info->yram;
 270         for (cnt = 0; cnt < YRAM_DEF_SIZE; cnt++, add++)
 271                 siu_write32(add, ydef[cnt]);
 272 
 273         /* YRAM FIR coefficient area initialization */
 274         add = info->yram + (0x0200 / sizeof(u32));
 275         for (cnt = 0; cnt < YRAM_FIR_SIZE; cnt++, add++)
 276                 siu_write32(add, fw->yram_fir_coeff[cnt]);
 277 
 278         /* YRAM IIR coefficient area initialization */
 279         add = info->yram + (0x0600 / sizeof(u32));
 280         for (cnt = 0; cnt < YRAM_IIR_SIZE; cnt++, add++)
 281                 siu_write32(add, 0);
 282 
 283         siu_write32(base + SIU_TRDAT, port_info->trdat);
 284         port_info->trdat = 0x0;
 285 
 286 
 287         /* SPB start condition: software */
 288         siu_write32(base + SIU_SBACTIV, 0);
 289         /* Start SPB */
 290         siu_write32(base + SIU_SBCTL, 0xc0000000);
 291         /* Wait for program to halt */
 292         cnt = 0x10000;
 293         while (--cnt && siu_read32(base + SIU_SBCTL) != 0x80000000)
 294                 cpu_relax();
 295 
 296         if (!cnt)
 297                 return -EBUSY;
 298 
 299         /* SPB program start address setting */
 300         siu_write32(base + SIU_SBPSET, 0x00400000);
 301         /* SPB hardware start(FIFOCTL source) */
 302         siu_write32(base + SIU_SBACTIV, 0xc0000000);
 303 
 304         return 0;
 305 }
 306 
 307 static void siu_dai_spbstop(struct siu_port *port_info)
 308 {
 309         struct siu_info *info = siu_i2s_data;
 310         u32 __iomem *base = info->reg;
 311 
 312         siu_write32(base + SIU_SBACTIV, 0);
 313         /* SPB stop */
 314         siu_write32(base + SIU_SBCTL, 0);
 315 
 316         port_info->stfifo = 0;
 317 }
 318 
 319 /*              API functions           */
 320 
 321 /* Playback and capture hardware properties are identical */
 322 static const struct snd_pcm_hardware siu_dai_pcm_hw = {
 323         .info                   = SNDRV_PCM_INFO_INTERLEAVED,
 324         .formats                = SNDRV_PCM_FMTBIT_S16,
 325         .rates                  = SNDRV_PCM_RATE_8000_48000,
 326         .rate_min               = 8000,
 327         .rate_max               = 48000,
 328         .channels_min           = 2,
 329         .channels_max           = 2,
 330         .buffer_bytes_max       = SIU_BUFFER_BYTES_MAX,
 331         .period_bytes_min       = SIU_PERIOD_BYTES_MIN,
 332         .period_bytes_max       = SIU_PERIOD_BYTES_MAX,
 333         .periods_min            = SIU_PERIODS_MIN,
 334         .periods_max            = SIU_PERIODS_MAX,
 335 };
 336 
 337 static int siu_dai_info_volume(struct snd_kcontrol *kctrl,
 338                                struct snd_ctl_elem_info *uinfo)
 339 {
 340         struct siu_port *port_info = snd_kcontrol_chip(kctrl);
 341 
 342         dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
 343 
 344         uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 345         uinfo->count = 2;
 346         uinfo->value.integer.min = 0;
 347         uinfo->value.integer.max = SIU_MAX_VOLUME;
 348 
 349         return 0;
 350 }
 351 
 352 static int siu_dai_get_volume(struct snd_kcontrol *kctrl,
 353                               struct snd_ctl_elem_value *ucontrol)
 354 {
 355         struct siu_port *port_info = snd_kcontrol_chip(kctrl);
 356         struct device *dev = port_info->pcm->card->dev;
 357         u32 vol;
 358 
 359         dev_dbg(dev, "%s\n", __func__);
 360 
 361         switch (kctrl->private_value) {
 362         case VOLUME_PLAYBACK:
 363                 /* Playback is always on port 0 */
 364                 vol = port_info->playback.volume;
 365                 ucontrol->value.integer.value[0] = vol & 0xffff;
 366                 ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
 367                 break;
 368         case VOLUME_CAPTURE:
 369                 /* Capture is always on port 1 */
 370                 vol = port_info->capture.volume;
 371                 ucontrol->value.integer.value[0] = vol & 0xffff;
 372                 ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
 373                 break;
 374         default:
 375                 dev_err(dev, "%s() invalid private_value=%ld\n",
 376                         __func__, kctrl->private_value);
 377                 return -EINVAL;
 378         }
 379 
 380         return 0;
 381 }
 382 
 383 static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
 384                               struct snd_ctl_elem_value *ucontrol)
 385 {
 386         struct siu_port *port_info = snd_kcontrol_chip(kctrl);
 387         struct device *dev = port_info->pcm->card->dev;
 388         struct siu_info *info = siu_i2s_data;
 389         u32 __iomem *base = info->reg;
 390         u32 new_vol;
 391         u32 cur_vol;
 392 
 393         dev_dbg(dev, "%s\n", __func__);
 394 
 395         if (ucontrol->value.integer.value[0] < 0 ||
 396             ucontrol->value.integer.value[0] > SIU_MAX_VOLUME ||
 397             ucontrol->value.integer.value[1] < 0 ||
 398             ucontrol->value.integer.value[1] > SIU_MAX_VOLUME)
 399                 return -EINVAL;
 400 
 401         new_vol = ucontrol->value.integer.value[0] |
 402                 ucontrol->value.integer.value[1] << 16;
 403 
 404         /* See comment above - DSP firmware implementation */
 405         switch (kctrl->private_value) {
 406         case VOLUME_PLAYBACK:
 407                 /* Playback is always on port 0 */
 408                 cur_vol = port_info->playback.volume;
 409                 siu_write32(base + SIU_SBDVCA, new_vol);
 410                 port_info->playback.volume = new_vol;
 411                 break;
 412         case VOLUME_CAPTURE:
 413                 /* Capture is always on port 1 */
 414                 cur_vol = port_info->capture.volume;
 415                 siu_write32(base + SIU_SBDVCB, new_vol);
 416                 port_info->capture.volume = new_vol;
 417                 break;
 418         default:
 419                 dev_err(dev, "%s() invalid private_value=%ld\n",
 420                         __func__, kctrl->private_value);
 421                 return -EINVAL;
 422         }
 423 
 424         if (cur_vol != new_vol)
 425                 return 1;
 426 
 427         return 0;
 428 }
 429 
 430 static const struct snd_kcontrol_new playback_controls = {
 431         .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 432         .name           = "PCM Playback Volume",
 433         .index          = 0,
 434         .info           = siu_dai_info_volume,
 435         .get            = siu_dai_get_volume,
 436         .put            = siu_dai_put_volume,
 437         .private_value  = VOLUME_PLAYBACK,
 438 };
 439 
 440 static const struct snd_kcontrol_new capture_controls = {
 441         .iface          = SNDRV_CTL_ELEM_IFACE_MIXER,
 442         .name           = "PCM Capture Volume",
 443         .index          = 0,
 444         .info           = siu_dai_info_volume,
 445         .get            = siu_dai_get_volume,
 446         .put            = siu_dai_put_volume,
 447         .private_value  = VOLUME_CAPTURE,
 448 };
 449 
 450 int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card)
 451 {
 452         struct device *dev = card->dev;
 453         struct snd_kcontrol *kctrl;
 454         int ret;
 455 
 456         *port_info = kzalloc(sizeof(**port_info), GFP_KERNEL);
 457         if (!*port_info)
 458                 return -ENOMEM;
 459 
 460         dev_dbg(dev, "%s: port #%d@%p\n", __func__, port, *port_info);
 461 
 462         (*port_info)->playback.volume = DFLT_VOLUME_LEVEL;
 463         (*port_info)->capture.volume = DFLT_VOLUME_LEVEL;
 464 
 465         /*
 466          * Add mixer support. The SPB is used to change the volume. Both
 467          * ports use the same SPB. Therefore, we only register one
 468          * control instance since it will be used by both channels.
 469          * In error case we continue without controls.
 470          */
 471         kctrl = snd_ctl_new1(&playback_controls, *port_info);
 472         ret = snd_ctl_add(card, kctrl);
 473         if (ret < 0)
 474                 dev_err(dev,
 475                         "failed to add playback controls %p port=%d err=%d\n",
 476                         kctrl, port, ret);
 477 
 478         kctrl = snd_ctl_new1(&capture_controls, *port_info);
 479         ret = snd_ctl_add(card, kctrl);
 480         if (ret < 0)
 481                 dev_err(dev,
 482                         "failed to add capture controls %p port=%d err=%d\n",
 483                         kctrl, port, ret);
 484 
 485         return 0;
 486 }
 487 
 488 void siu_free_port(struct siu_port *port_info)
 489 {
 490         kfree(port_info);
 491 }
 492 
 493 static int siu_dai_startup(struct snd_pcm_substream *substream,
 494                            struct snd_soc_dai *dai)
 495 {
 496         struct siu_info *info = snd_soc_dai_get_drvdata(dai);
 497         struct snd_pcm_runtime *rt = substream->runtime;
 498         struct siu_port *port_info = siu_port_info(substream);
 499         int ret;
 500 
 501         dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
 502                 info->port_id, port_info);
 503 
 504         snd_soc_set_runtime_hwparams(substream, &siu_dai_pcm_hw);
 505 
 506         ret = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
 507         if (unlikely(ret < 0))
 508                 return ret;
 509 
 510         siu_dai_start(port_info);
 511 
 512         return 0;
 513 }
 514 
 515 static void siu_dai_shutdown(struct snd_pcm_substream *substream,
 516                              struct snd_soc_dai *dai)
 517 {
 518         struct siu_info *info = snd_soc_dai_get_drvdata(dai);
 519         struct siu_port *port_info = siu_port_info(substream);
 520 
 521         dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
 522                 info->port_id, port_info);
 523 
 524         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 525                 port_info->play_cap &= ~PLAYBACK_ENABLED;
 526         else
 527                 port_info->play_cap &= ~CAPTURE_ENABLED;
 528 
 529         /* Stop the siu if the other stream is not using it */
 530         if (!port_info->play_cap) {
 531                 /* during stmread or stmwrite ? */
 532                 if (WARN_ON(port_info->playback.rw_flg || port_info->capture.rw_flg))
 533                         return;
 534                 siu_dai_spbstop(port_info);
 535                 siu_dai_stop(port_info);
 536         }
 537 }
 538 
 539 /* PCM part of siu_dai_playback_prepare() / siu_dai_capture_prepare() */
 540 static int siu_dai_prepare(struct snd_pcm_substream *substream,
 541                            struct snd_soc_dai *dai)
 542 {
 543         struct siu_info *info = snd_soc_dai_get_drvdata(dai);
 544         struct snd_pcm_runtime *rt = substream->runtime;
 545         struct siu_port *port_info = siu_port_info(substream);
 546         struct siu_stream *siu_stream;
 547         int self, ret;
 548 
 549         dev_dbg(substream->pcm->card->dev,
 550                 "%s: port %d, active streams %lx, %d channels\n",
 551                 __func__, info->port_id, port_info->play_cap, rt->channels);
 552 
 553         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 554                 self = PLAYBACK_ENABLED;
 555                 siu_stream = &port_info->playback;
 556         } else {
 557                 self = CAPTURE_ENABLED;
 558                 siu_stream = &port_info->capture;
 559         }
 560 
 561         /* Set up the siu if not already done */
 562         if (!port_info->play_cap) {
 563                 siu_stream->rw_flg = 0; /* stream-data transfer flag */
 564 
 565                 siu_dai_spbAselect(port_info);
 566                 siu_dai_spbBselect(port_info);
 567 
 568                 siu_dai_open(siu_stream);
 569 
 570                 siu_dai_pcmdatapack(siu_stream);
 571 
 572                 ret = siu_dai_spbstart(port_info);
 573                 if (ret < 0)
 574                         goto fail;
 575         } else {
 576                 ret = 0;
 577         }
 578 
 579         port_info->play_cap |= self;
 580 
 581 fail:
 582         return ret;
 583 }
 584 
 585 /*
 586  * SIU can set bus format to I2S / PCM / SPDIF independently for playback and
 587  * capture, however, the current API sets the bus format globally for a DAI.
 588  */
 589 static int siu_dai_set_fmt(struct snd_soc_dai *dai,
 590                            unsigned int fmt)
 591 {
 592         struct siu_info *info = snd_soc_dai_get_drvdata(dai);
 593         u32 __iomem *base = info->reg;
 594         u32 ifctl;
 595 
 596         dev_dbg(dai->dev, "%s: fmt 0x%x on port %d\n",
 597                 __func__, fmt, info->port_id);
 598 
 599         if (info->port_id < 0)
 600                 return -ENODEV;
 601 
 602         /* Here select between I2S / PCM / SPDIF */
 603         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 604         case SND_SOC_DAIFMT_I2S:
 605                 ifctl = siu_flags[info->port_id].playback.i2s |
 606                         siu_flags[info->port_id].capture.i2s;
 607                 break;
 608         case SND_SOC_DAIFMT_LEFT_J:
 609                 ifctl = siu_flags[info->port_id].playback.pcm |
 610                         siu_flags[info->port_id].capture.pcm;
 611                 break;
 612         /* SPDIF disabled - see comment at the top */
 613         default:
 614                 return -EINVAL;
 615         }
 616 
 617         ifctl |= ~(siu_flags[info->port_id].playback.mask |
 618                    siu_flags[info->port_id].capture.mask) &
 619                 siu_read32(base + SIU_IFCTL);
 620         siu_write32(base + SIU_IFCTL, ifctl);
 621 
 622         return 0;
 623 }
 624 
 625 static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 626                               unsigned int freq, int dir)
 627 {
 628         struct clk *siu_clk, *parent_clk;
 629         char *siu_name, *parent_name;
 630         int ret;
 631 
 632         if (dir != SND_SOC_CLOCK_IN)
 633                 return -EINVAL;
 634 
 635         dev_dbg(dai->dev, "%s: using clock %d\n", __func__, clk_id);
 636 
 637         switch (clk_id) {
 638         case SIU_CLKA_PLL:
 639                 siu_name = "siua_clk";
 640                 parent_name = "pll_clk";
 641                 break;
 642         case SIU_CLKA_EXT:
 643                 siu_name = "siua_clk";
 644                 parent_name = "siumcka_clk";
 645                 break;
 646         case SIU_CLKB_PLL:
 647                 siu_name = "siub_clk";
 648                 parent_name = "pll_clk";
 649                 break;
 650         case SIU_CLKB_EXT:
 651                 siu_name = "siub_clk";
 652                 parent_name = "siumckb_clk";
 653                 break;
 654         default:
 655                 return -EINVAL;
 656         }
 657 
 658         siu_clk = clk_get(dai->dev, siu_name);
 659         if (IS_ERR(siu_clk)) {
 660                 dev_err(dai->dev, "%s: cannot get a SIU clock: %ld\n", __func__,
 661                         PTR_ERR(siu_clk));
 662                 return PTR_ERR(siu_clk);
 663         }
 664 
 665         parent_clk = clk_get(dai->dev, parent_name);
 666         if (IS_ERR(parent_clk)) {
 667                 ret = PTR_ERR(parent_clk);
 668                 dev_err(dai->dev, "cannot get a SIU clock parent: %d\n", ret);
 669                 goto epclkget;
 670         }
 671 
 672         ret = clk_set_parent(siu_clk, parent_clk);
 673         if (ret < 0) {
 674                 dev_err(dai->dev, "cannot reparent the SIU clock: %d\n", ret);
 675                 goto eclksetp;
 676         }
 677 
 678         ret = clk_set_rate(siu_clk, freq);
 679         if (ret < 0)
 680                 dev_err(dai->dev, "cannot set SIU clock rate: %d\n", ret);
 681 
 682         /* TODO: when clkdev gets reference counting we'll move these to siu_dai_shutdown() */
 683 eclksetp:
 684         clk_put(parent_clk);
 685 epclkget:
 686         clk_put(siu_clk);
 687 
 688         return ret;
 689 }
 690 
 691 static const struct snd_soc_dai_ops siu_dai_ops = {
 692         .startup        = siu_dai_startup,
 693         .shutdown       = siu_dai_shutdown,
 694         .prepare        = siu_dai_prepare,
 695         .set_sysclk     = siu_dai_set_sysclk,
 696         .set_fmt        = siu_dai_set_fmt,
 697 };
 698 
 699 static struct snd_soc_dai_driver siu_i2s_dai = {
 700         .name   = "siu-i2s-dai",
 701         .playback = {
 702                 .channels_min = 2,
 703                 .channels_max = 2,
 704                 .formats = SNDRV_PCM_FMTBIT_S16,
 705                 .rates = SNDRV_PCM_RATE_8000_48000,
 706         },
 707         .capture = {
 708                 .channels_min = 2,
 709                 .channels_max = 2,
 710                 .formats = SNDRV_PCM_FMTBIT_S16,
 711                 .rates = SNDRV_PCM_RATE_8000_48000,
 712          },
 713         .ops = &siu_dai_ops,
 714 };
 715 
 716 static int siu_probe(struct platform_device *pdev)
 717 {
 718         const struct firmware *fw_entry;
 719         struct resource *res, *region;
 720         struct siu_info *info;
 721         int ret;
 722 
 723         info = devm_kmalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 724         if (!info)
 725                 return -ENOMEM;
 726         siu_i2s_data = info;
 727         info->dev = &pdev->dev;
 728 
 729         ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
 730         if (ret)
 731                 return ret;
 732 
 733         /*
 734          * Loaded firmware is "const" - read only, but we have to modify it in
 735          * snd_siu_sh7343_spbAselect() and snd_siu_sh7343_spbBselect()
 736          */
 737         memcpy(&info->fw, fw_entry->data, fw_entry->size);
 738 
 739         release_firmware(fw_entry);
 740 
 741         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 742         if (!res)
 743                 return -ENODEV;
 744 
 745         region = devm_request_mem_region(&pdev->dev, res->start,
 746                                          resource_size(res), pdev->name);
 747         if (!region) {
 748                 dev_err(&pdev->dev, "SIU region already claimed\n");
 749                 return -EBUSY;
 750         }
 751 
 752         info->pram = devm_ioremap(&pdev->dev, res->start, PRAM_SIZE);
 753         if (!info->pram)
 754                 return -ENOMEM;
 755         info->xram = devm_ioremap(&pdev->dev, res->start + XRAM_OFFSET,
 756                                   XRAM_SIZE);
 757         if (!info->xram)
 758                 return -ENOMEM;
 759         info->yram = devm_ioremap(&pdev->dev, res->start + YRAM_OFFSET,
 760                                   YRAM_SIZE);
 761         if (!info->yram)
 762                 return -ENOMEM;
 763         info->reg = devm_ioremap(&pdev->dev, res->start + REG_OFFSET,
 764                             resource_size(res) - REG_OFFSET);
 765         if (!info->reg)
 766                 return -ENOMEM;
 767 
 768         dev_set_drvdata(&pdev->dev, info);
 769 
 770         /* register using ARRAY version so we can keep dai name */
 771         ret = devm_snd_soc_register_component(&pdev->dev, &siu_component,
 772                                               &siu_i2s_dai, 1);
 773         if (ret < 0)
 774                 return ret;
 775 
 776         pm_runtime_enable(&pdev->dev);
 777 
 778         return 0;
 779 }
 780 
 781 static int siu_remove(struct platform_device *pdev)
 782 {
 783         pm_runtime_disable(&pdev->dev);
 784         return 0;
 785 }
 786 
 787 static struct platform_driver siu_driver = {
 788         .driver         = {
 789                 .name   = "siu-pcm-audio",
 790         },
 791         .probe          = siu_probe,
 792         .remove         = siu_remove,
 793 };
 794 
 795 module_platform_driver(siu_driver);
 796 
 797 MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>");
 798 MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver");
 799 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */