1 /* 2 * Freescale SSI ALSA SoC Digital Audio Interface (DAI) driver 3 * 4 * Author: Timur Tabi <timur@freescale.com> 5 * 6 * Copyright 2007-2008 Freescale Semiconductor, Inc. This file is licensed 7 * under the terms of the GNU General Public License version 2. This 8 * program is licensed "as is" without any warranty of any kind, whether 9 * express or implied. 10 */ 11 12 #include <linux/init.h> 13 #include <linux/module.h> 14 #include <linux/interrupt.h> 15 #include <linux/device.h> 16 #include <linux/delay.h> 17 18 #include <sound/driver.h> 19 #include <sound/core.h> 20 #include <sound/pcm.h> 21 #include <sound/pcm_params.h> 22 #include <sound/initval.h> 23 #include <sound/soc.h> 24 25 #include <asm/immap_86xx.h> 26 27 #include "fsl_ssi.h" 28 29 /** 30 * FSLSSI_I2S_RATES: sample rates supported by the I2S 31 * 32 * This driver currently only supports the SSI running in I2S slave mode, 33 * which means the codec determines the sample rate. Therefore, we tell 34 * ALSA that we support all rates and let the codec driver decide what rates 35 * are really supported. 36 */ 37 #define FSLSSI_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ 38 SNDRV_PCM_RATE_CONTINUOUS) 39 40 /** 41 * FSLSSI_I2S_FORMATS: audio formats supported by the SSI 42 * 43 * This driver currently only supports the SSI running in I2S slave mode. 44 * 45 * The SSI has a limitation in that the samples must be in the same byte 46 * order as the host CPU. This is because when multiple bytes are written 47 * to the STX register, the bytes and bits must be written in the same 48 * order. The STX is a shift register, so all the bits need to be aligned 49 * (bit-endianness must match byte-endianness). Processors typically write 50 * the bits within a byte in the same order that the bytes of a word are 51 * written in. So if the host CPU is big-endian, then only big-endian 52 * samples will be written to STX properly. 53 */ 54 #ifdef __BIG_ENDIAN 55 #define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \ 56 SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_S20_3BE | \ 57 SNDRV_PCM_FMTBIT_S24_3BE | SNDRV_PCM_FMTBIT_S24_BE) 58 #else 59 #define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ 60 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 61 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE) 62 #endif 63 64 /** 65 * fsl_ssi_private: per-SSI private data 66 * 67 * @name: short name for this device ("SSI0", "SSI1", etc) 68 * @ssi: pointer to the SSI's registers 69 * @ssi_phys: physical address of the SSI registers 70 * @irq: IRQ of this SSI 71 * @dev: struct device pointer 72 * @playback: the number of playback streams opened 73 * @capture: the number of capture streams opened 74 * @cpu_dai: the CPU DAI for this device 75 * @dev_attr: the sysfs device attribute structure 76 * @stats: SSI statistics 77 */ 78 struct fsl_ssi_private { 79 char name[8]; 80 struct ccsr_ssi __iomem *ssi; 81 dma_addr_t ssi_phys; 82 unsigned int irq; 83 struct device *dev; 84 unsigned int playback; 85 unsigned int capture; 86 struct snd_soc_cpu_dai cpu_dai; 87 struct device_attribute dev_attr; 88 89 struct { 90 unsigned int rfrc; 91 unsigned int tfrc; 92 unsigned int cmdau; 93 unsigned int cmddu; 94 unsigned int rxt; 95 unsigned int rdr1; 96 unsigned int rdr0; 97 unsigned int tde1; 98 unsigned int tde0; 99 unsigned int roe1; 100 unsigned int roe0; 101 unsigned int tue1; 102 unsigned int tue0; 103 unsigned int tfs; 104 unsigned int rfs; 105 unsigned int tls; 106 unsigned int rls; 107 unsigned int rff1; 108 unsigned int rff0; 109 unsigned int tfe1; 110 unsigned int tfe0; 111 } stats; 112 }; 113 114 /** 115 * fsl_ssi_isr: SSI interrupt handler 116 * 117 * Although it's possible to use the interrupt handler to send and receive 118 * data to/from the SSI, we use the DMA instead. Programming is more 119 * complicated, but the performance is much better. 120 * 121 * This interrupt handler is used only to gather statistics. 122 * 123 * @irq: IRQ of the SSI device 124 * @dev_id: pointer to the ssi_private structure for this SSI device 125 */ 126 static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) 127 { 128 struct fsl_ssi_private *ssi_private = dev_id; 129 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 130 irqreturn_t ret = IRQ_NONE; 131 __be32 sisr; 132 __be32 sisr2 = 0; 133 134 /* We got an interrupt, so read the status register to see what we 135 were interrupted for. We mask it with the Interrupt Enable register 136 so that we only check for events that we're interested in. 137 */ 138 sisr = in_be32(&ssi->sisr) & in_be32(&ssi->sier); 139 140 if (sisr & CCSR_SSI_SISR_RFRC) { 141 ssi_private->stats.rfrc++; 142 sisr2 |= CCSR_SSI_SISR_RFRC; 143 ret = IRQ_HANDLED; 144 } 145 146 if (sisr & CCSR_SSI_SISR_TFRC) { 147 ssi_private->stats.tfrc++; 148 sisr2 |= CCSR_SSI_SISR_TFRC; 149 ret = IRQ_HANDLED; 150 } 151 152 if (sisr & CCSR_SSI_SISR_CMDAU) { 153 ssi_private->stats.cmdau++; 154 ret = IRQ_HANDLED; 155 } 156 157 if (sisr & CCSR_SSI_SISR_CMDDU) { 158 ssi_private->stats.cmddu++; 159 ret = IRQ_HANDLED; 160 } 161 162 if (sisr & CCSR_SSI_SISR_RXT) { 163 ssi_private->stats.rxt++; 164 ret = IRQ_HANDLED; 165 } 166 167 if (sisr & CCSR_SSI_SISR_RDR1) { 168 ssi_private->stats.rdr1++; 169 ret = IRQ_HANDLED; 170 } 171 172 if (sisr & CCSR_SSI_SISR_RDR0) { 173 ssi_private->stats.rdr0++; 174 ret = IRQ_HANDLED; 175 } 176 177 if (sisr & CCSR_SSI_SISR_TDE1) { 178 ssi_private->stats.tde1++; 179 ret = IRQ_HANDLED; 180 } 181 182 if (sisr & CCSR_SSI_SISR_TDE0) { 183 ssi_private->stats.tde0++; 184 ret = IRQ_HANDLED; 185 } 186 187 if (sisr & CCSR_SSI_SISR_ROE1) { 188 ssi_private->stats.roe1++; 189 sisr2 |= CCSR_SSI_SISR_ROE1; 190 ret = IRQ_HANDLED; 191 } 192 193 if (sisr & CCSR_SSI_SISR_ROE0) { 194 ssi_private->stats.roe0++; 195 sisr2 |= CCSR_SSI_SISR_ROE0; 196 ret = IRQ_HANDLED; 197 } 198 199 if (sisr & CCSR_SSI_SISR_TUE1) { 200 ssi_private->stats.tue1++; 201 sisr2 |= CCSR_SSI_SISR_TUE1; 202 ret = IRQ_HANDLED; 203 } 204 205 if (sisr & CCSR_SSI_SISR_TUE0) { 206 ssi_private->stats.tue0++; 207 sisr2 |= CCSR_SSI_SISR_TUE0; 208 ret = IRQ_HANDLED; 209 } 210 211 if (sisr & CCSR_SSI_SISR_TFS) { 212 ssi_private->stats.tfs++; 213 ret = IRQ_HANDLED; 214 } 215 216 if (sisr & CCSR_SSI_SISR_RFS) { 217 ssi_private->stats.rfs++; 218 ret = IRQ_HANDLED; 219 } 220 221 if (sisr & CCSR_SSI_SISR_TLS) { 222 ssi_private->stats.tls++; 223 ret = IRQ_HANDLED; 224 } 225 226 if (sisr & CCSR_SSI_SISR_RLS) { 227 ssi_private->stats.rls++; 228 ret = IRQ_HANDLED; 229 } 230 231 if (sisr & CCSR_SSI_SISR_RFF1) { 232 ssi_private->stats.rff1++; 233 ret = IRQ_HANDLED; 234 } 235 236 if (sisr & CCSR_SSI_SISR_RFF0) { 237 ssi_private->stats.rff0++; 238 ret = IRQ_HANDLED; 239 } 240 241 if (sisr & CCSR_SSI_SISR_TFE1) { 242 ssi_private->stats.tfe1++; 243 ret = IRQ_HANDLED; 244 } 245 246 if (sisr & CCSR_SSI_SISR_TFE0) { 247 ssi_private->stats.tfe0++; 248 ret = IRQ_HANDLED; 249 } 250 251 /* Clear the bits that we set */ 252 if (sisr2) 253 out_be32(&ssi->sisr, sisr2); 254 255 return ret; 256 } 257 258 /** 259 * fsl_ssi_startup: create a new substream 260 * 261 * This is the first function called when a stream is opened. 262 * 263 * If this is the first stream open, then grab the IRQ and program most of 264 * the SSI registers. 265 */ 266 static int fsl_ssi_startup(struct snd_pcm_substream *substream) 267 { 268 struct snd_soc_pcm_runtime *rtd = substream->private_data; 269 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 270 271 /* 272 * If this is the first stream opened, then request the IRQ 273 * and initialize the SSI registers. 274 */ 275 if (!ssi_private->playback && !ssi_private->capture) { 276 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 277 int ret; 278 279 ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, 280 ssi_private->name, ssi_private); 281 if (ret < 0) { 282 dev_err(substream->pcm->card->dev, 283 "could not claim irq %u\n", ssi_private->irq); 284 return ret; 285 } 286 287 /* 288 * Section 16.5 of the MPC8610 reference manual says that the 289 * SSI needs to be disabled before updating the registers we set 290 * here. 291 */ 292 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 293 294 /* 295 * Program the SSI into I2S Slave Non-Network Synchronous mode. 296 * Also enable the transmit and receive FIFO. 297 * 298 * FIXME: Little-endian samples require a different shift dir 299 */ 300 clrsetbits_be32(&ssi->scr, CCSR_SSI_SCR_I2S_MODE_MASK, 301 CCSR_SSI_SCR_TFR_CLK_DIS | 302 CCSR_SSI_SCR_I2S_MODE_SLAVE | CCSR_SSI_SCR_SYN); 303 304 out_be32(&ssi->stcr, 305 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | 306 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS | 307 CCSR_SSI_STCR_TSCKP); 308 309 out_be32(&ssi->srcr, 310 CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 | 311 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS | 312 CCSR_SSI_SRCR_RSCKP); 313 314 /* 315 * The DC and PM bits are only used if the SSI is the clock 316 * master. 317 */ 318 319 /* 4. Enable the interrupts and DMA requests */ 320 out_be32(&ssi->sier, 321 CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | 322 CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | 323 CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | 324 CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | 325 CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN); 326 327 /* 328 * Set the watermark for transmit FIFI 0 and receive FIFO 0. We 329 * don't use FIFO 1. Since the SSI only supports stereo, the 330 * watermark should never be an odd number. 331 */ 332 out_be32(&ssi->sfcsr, 333 CCSR_SSI_SFCSR_TFWM0(6) | CCSR_SSI_SFCSR_RFWM0(2)); 334 335 /* 336 * We keep the SSI disabled because if we enable it, then the 337 * DMA controller will start. It's not supposed to start until 338 * the SCR.TE (or SCR.RE) bit is set, but it does anyway. The 339 * DMA controller will transfer one "BWC" of data (i.e. the 340 * amount of data that the MR.BWC bits are set to). The reason 341 * this is bad is because at this point, the PCM driver has not 342 * finished initializing the DMA controller. 343 */ 344 } 345 346 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 347 ssi_private->playback++; 348 349 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 350 ssi_private->capture++; 351 352 return 0; 353 } 354 355 /** 356 * fsl_ssi_prepare: prepare the SSI. 357 * 358 * Most of the SSI registers have been programmed in the startup function, 359 * but the word length must be programmed here. Unfortunately, programming 360 * the SxCCR.WL bits requires the SSI to be temporarily disabled. This can 361 * cause a problem with supporting simultaneous playback and capture. If 362 * the SSI is already playing a stream, then that stream may be temporarily 363 * stopped when you start capture. 364 * 365 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the 366 * clock master. 367 */ 368 static int fsl_ssi_prepare(struct snd_pcm_substream *substream) 369 { 370 struct snd_pcm_runtime *runtime = substream->runtime; 371 struct snd_soc_pcm_runtime *rtd = substream->private_data; 372 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 373 374 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 375 u32 wl; 376 377 wl = CCSR_SSI_SxCCR_WL(snd_pcm_format_width(runtime->format)); 378 379 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 380 381 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 382 clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); 383 else 384 clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); 385 386 setbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 387 388 return 0; 389 } 390 391 /** 392 * fsl_ssi_trigger: start and stop the DMA transfer. 393 * 394 * This function is called by ALSA to start, stop, pause, and resume the DMA 395 * transfer of data. 396 * 397 * The DMA channel is in external master start and pause mode, which 398 * means the SSI completely controls the flow of data. 399 */ 400 static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd) 401 { 402 struct snd_soc_pcm_runtime *rtd = substream->private_data; 403 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 404 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 405 406 switch (cmd) { 407 case SNDRV_PCM_TRIGGER_START: 408 case SNDRV_PCM_TRIGGER_RESUME: 409 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 410 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 411 setbits32(&ssi->scr, CCSR_SSI_SCR_TE); 412 } else { 413 setbits32(&ssi->scr, CCSR_SSI_SCR_RE); 414 415 /* 416 * I think we need this delay to allow time for the SSI 417 * to put data into its FIFO. Without it, ALSA starts 418 * to complain about overruns. 419 */ 420 msleep(1); 421 } 422 break; 423 424 case SNDRV_PCM_TRIGGER_STOP: 425 case SNDRV_PCM_TRIGGER_SUSPEND: 426 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 427 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 428 clrbits32(&ssi->scr, CCSR_SSI_SCR_TE); 429 else 430 clrbits32(&ssi->scr, CCSR_SSI_SCR_RE); 431 break; 432 433 default: 434 return -EINVAL; 435 } 436 437 return 0; 438 } 439 440 /** 441 * fsl_ssi_shutdown: shutdown the SSI 442 * 443 * Shutdown the SSI if there are no other substreams open. 444 */ 445 static void fsl_ssi_shutdown(struct snd_pcm_substream *substream) 446 { 447 struct snd_soc_pcm_runtime *rtd = substream->private_data; 448 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 449 450 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 451 ssi_private->playback--; 452 453 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 454 ssi_private->capture--; 455 456 /* 457 * If this is the last active substream, disable the SSI and release 458 * the IRQ. 459 */ 460 if (!ssi_private->playback && !ssi_private->capture) { 461 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 462 463 clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); 464 465 free_irq(ssi_private->irq, ssi_private); 466 } 467 } 468 469 /** 470 * fsl_ssi_set_sysclk: set the clock frequency and direction 471 * 472 * This function is called by the machine driver to tell us what the clock 473 * frequency and direction are. 474 * 475 * Currently, we only support operating as a clock slave (SND_SOC_CLOCK_IN), 476 * and we don't care about the frequency. Return an error if the direction 477 * is not SND_SOC_CLOCK_IN. 478 * 479 * @clk_id: reserved, should be zero 480 * @freq: the frequency of the given clock ID, currently ignored 481 * @dir: SND_SOC_CLOCK_IN (clock slave) or SND_SOC_CLOCK_OUT (clock master) 482 */ 483 static int fsl_ssi_set_sysclk(struct snd_soc_cpu_dai *cpu_dai, 484 int clk_id, unsigned int freq, int dir) 485 { 486 487 return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL; 488 } 489 490 /** 491 * fsl_ssi_set_fmt: set the serial format. 492 * 493 * This function is called by the machine driver to tell us what serial 494 * format to use. 495 * 496 * Currently, we only support I2S mode. Return an error if the format is 497 * not SND_SOC_DAIFMT_I2S. 498 * 499 * @format: one of SND_SOC_DAIFMT_xxx 500 */ 501 static int fsl_ssi_set_fmt(struct snd_soc_cpu_dai *cpu_dai, unsigned int format) 502 { 503 return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL; 504 } 505 506 /** 507 * fsl_ssi_dai_template: template CPU DAI for the SSI 508 */ 509 static struct snd_soc_cpu_dai fsl_ssi_dai_template = { 510 .playback = { 511 /* The SSI does not support monaural audio. */ 512 .channels_min = 2, 513 .channels_max = 2, 514 .rates = FSLSSI_I2S_RATES, 515 .formats = FSLSSI_I2S_FORMATS, 516 }, 517 .capture = { 518 .channels_min = 2, 519 .channels_max = 2, 520 .rates = FSLSSI_I2S_RATES, 521 .formats = FSLSSI_I2S_FORMATS, 522 }, 523 .ops = { 524 .startup = fsl_ssi_startup, 525 .prepare = fsl_ssi_prepare, 526 .shutdown = fsl_ssi_shutdown, 527 .trigger = fsl_ssi_trigger, 528 }, 529 .dai_ops = { 530 .set_sysclk = fsl_ssi_set_sysclk, 531 .set_fmt = fsl_ssi_set_fmt, 532 }, 533 }; 534 535 /** 536 * fsl_sysfs_ssi_show: display SSI statistics 537 * 538 * Display the statistics for the current SSI device. 539 */ 540 static ssize_t fsl_sysfs_ssi_show(struct device *dev, 541 struct device_attribute *attr, char *buf) 542 { 543 struct fsl_ssi_private *ssi_private = 544 container_of(attr, struct fsl_ssi_private, dev_attr); 545 ssize_t length; 546 547 length = sprintf(buf, "rfrc=%u", ssi_private->stats.rfrc); 548 length += sprintf(buf + length, "\ttfrc=%u", ssi_private->stats.tfrc); 549 length += sprintf(buf + length, "\tcmdau=%u", ssi_private->stats.cmdau); 550 length += sprintf(buf + length, "\tcmddu=%u", ssi_private->stats.cmddu); 551 length += sprintf(buf + length, "\trxt=%u", ssi_private->stats.rxt); 552 length += sprintf(buf + length, "\trdr1=%u", ssi_private->stats.rdr1); 553 length += sprintf(buf + length, "\trdr0=%u", ssi_private->stats.rdr0); 554 length += sprintf(buf + length, "\ttde1=%u", ssi_private->stats.tde1); 555 length += sprintf(buf + length, "\ttde0=%u", ssi_private->stats.tde0); 556 length += sprintf(buf + length, "\troe1=%u", ssi_private->stats.roe1); 557 length += sprintf(buf + length, "\troe0=%u", ssi_private->stats.roe0); 558 length += sprintf(buf + length, "\ttue1=%u", ssi_private->stats.tue1); 559 length += sprintf(buf + length, "\ttue0=%u", ssi_private->stats.tue0); 560 length += sprintf(buf + length, "\ttfs=%u", ssi_private->stats.tfs); 561 length += sprintf(buf + length, "\trfs=%u", ssi_private->stats.rfs); 562 length += sprintf(buf + length, "\ttls=%u", ssi_private->stats.tls); 563 length += sprintf(buf + length, "\trls=%u", ssi_private->stats.rls); 564 length += sprintf(buf + length, "\trff1=%u", ssi_private->stats.rff1); 565 length += sprintf(buf + length, "\trff0=%u", ssi_private->stats.rff0); 566 length += sprintf(buf + length, "\ttfe1=%u", ssi_private->stats.tfe1); 567 length += sprintf(buf + length, "\ttfe0=%u\n", ssi_private->stats.tfe0); 568 569 return length; 570 } 571 572 /** 573 * fsl_ssi_create_dai: create a snd_soc_cpu_dai structure 574 * 575 * This function is called by the machine driver to create a snd_soc_cpu_dai 576 * structure. The function creates an ssi_private object, which contains 577 * the snd_soc_cpu_dai. It also creates the sysfs statistics device. 578 */ 579 struct snd_soc_cpu_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) 580 { 581 struct snd_soc_cpu_dai *fsl_ssi_dai; 582 struct fsl_ssi_private *ssi_private; 583 int ret = 0; 584 struct device_attribute *dev_attr; 585 586 ssi_private = kzalloc(sizeof(struct fsl_ssi_private), GFP_KERNEL); 587 if (!ssi_private) { 588 dev_err(ssi_info->dev, "could not allocate DAI object\n"); 589 return NULL; 590 } 591 memcpy(&ssi_private->cpu_dai, &fsl_ssi_dai_template, 592 sizeof(struct snd_soc_cpu_dai)); 593 594 fsl_ssi_dai = &ssi_private->cpu_dai; 595 dev_attr = &ssi_private->dev_attr; 596 597 sprintf(ssi_private->name, "ssi%u", (u8) ssi_info->id); 598 ssi_private->ssi = ssi_info->ssi; 599 ssi_private->ssi_phys = ssi_info->ssi_phys; 600 ssi_private->irq = ssi_info->irq; 601 ssi_private->dev = ssi_info->dev; 602 603 ssi_private->dev->driver_data = fsl_ssi_dai; 604 605 /* Initialize the the device_attribute structure */ 606 dev_attr->attr.name = "ssi-stats"; 607 dev_attr->attr.mode = S_IRUGO; 608 dev_attr->show = fsl_sysfs_ssi_show; 609 610 ret = device_create_file(ssi_private->dev, dev_attr); 611 if (ret) { 612 dev_err(ssi_info->dev, "could not create sysfs %s file\n", 613 ssi_private->dev_attr.attr.name); 614 kfree(fsl_ssi_dai); 615 return NULL; 616 } 617 618 fsl_ssi_dai->private_data = ssi_private; 619 fsl_ssi_dai->name = ssi_private->name; 620 fsl_ssi_dai->id = ssi_info->id; 621 622 return fsl_ssi_dai; 623 } 624 EXPORT_SYMBOL_GPL(fsl_ssi_create_dai); 625 626 /** 627 * fsl_ssi_destroy_dai: destroy the snd_soc_cpu_dai object 628 * 629 * This function undoes the operations of fsl_ssi_create_dai() 630 */ 631 void fsl_ssi_destroy_dai(struct snd_soc_cpu_dai *fsl_ssi_dai) 632 { 633 struct fsl_ssi_private *ssi_private = 634 container_of(fsl_ssi_dai, struct fsl_ssi_private, cpu_dai); 635 636 device_remove_file(ssi_private->dev, &ssi_private->dev_attr); 637 638 kfree(ssi_private); 639 } 640 EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai); 641 642 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 643 MODULE_DESCRIPTION("Freescale Synchronous Serial Interface (SSI) ASoC Driver"); 644 MODULE_LICENSE("GPL"); 645