1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Socionext UniPhier AIO ALSA CPU DAI driver. 4 // 5 // Copyright (c) 2016-2018 Socionext Inc. 6 7 #include <linux/clk.h> 8 #include <linux/errno.h> 9 #include <linux/kernel.h> 10 #include <linux/mfd/syscon.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/of_platform.h> 14 #include <linux/platform_device.h> 15 #include <linux/reset.h> 16 #include <sound/core.h> 17 #include <sound/pcm.h> 18 #include <sound/pcm_params.h> 19 #include <sound/soc.h> 20 21 #include "aio.h" 22 23 static bool is_valid_pll(struct uniphier_aio_chip *chip, int pll_id) 24 { 25 struct device *dev = &chip->pdev->dev; 26 27 if (pll_id < 0 || chip->num_plls <= pll_id) { 28 dev_err(dev, "PLL(%d) is not supported\n", pll_id); 29 return false; 30 } 31 32 return chip->plls[pll_id].enable; 33 } 34 35 /** 36 * find_volume - find volume supported HW port by HW port number 37 * @chip: the AIO chip pointer 38 * @oport_hw: HW port number, one of AUD_HW_XXXX 39 * 40 * Find AIO device from device list by HW port number. Volume feature is 41 * available only in Output and PCM ports, this limitation comes from HW 42 * specifications. 43 * 44 * Return: The pointer of AIO substream if successful, otherwise NULL on error. 45 */ 46 static struct uniphier_aio_sub *find_volume(struct uniphier_aio_chip *chip, 47 int oport_hw) 48 { 49 int i; 50 51 for (i = 0; i < chip->num_aios; i++) { 52 struct uniphier_aio_sub *sub = &chip->aios[i].sub[0]; 53 54 if (!sub->swm) 55 continue; 56 57 if (sub->swm->oport.hw == oport_hw) 58 return sub; 59 } 60 61 return NULL; 62 } 63 64 static bool match_spec(const struct uniphier_aio_spec *spec, 65 const char *name, int dir) 66 { 67 if (dir == SNDRV_PCM_STREAM_PLAYBACK && 68 spec->swm.dir != PORT_DIR_OUTPUT) { 69 return false; 70 } 71 72 if (dir == SNDRV_PCM_STREAM_CAPTURE && 73 spec->swm.dir != PORT_DIR_INPUT) { 74 return false; 75 } 76 77 if (spec->name && strcmp(spec->name, name) == 0) 78 return true; 79 80 if (spec->gname && strcmp(spec->gname, name) == 0) 81 return true; 82 83 return false; 84 } 85 86 /** 87 * find_spec - find HW specification info by name 88 * @aio: the AIO device pointer 89 * @name: name of device 90 * @direction: the direction of substream, SNDRV_PCM_STREAM_* 91 * 92 * Find hardware specification information from list by device name. This 93 * information is used for telling the difference of SoCs to driver. 94 * 95 * Specification list is array of 'struct uniphier_aio_spec' which is defined 96 * in each drivers (see: aio-i2s.c). 97 * 98 * Return: The pointer of hardware specification of AIO if successful, 99 * otherwise NULL on error. 100 */ 101 static const struct uniphier_aio_spec *find_spec(struct uniphier_aio *aio, 102 const char *name, 103 int direction) 104 { 105 const struct uniphier_aio_chip_spec *chip_spec = aio->chip->chip_spec; 106 int i; 107 108 for (i = 0; i < chip_spec->num_specs; i++) { 109 const struct uniphier_aio_spec *spec = &chip_spec->specs[i]; 110 111 if (match_spec(spec, name, direction)) 112 return spec; 113 } 114 115 return NULL; 116 } 117 118 /** 119 * find_divider - find clock divider by frequency 120 * @aio: the AIO device pointer 121 * @pll_id: PLL ID, should be AUD_PLL_XX 122 * @freq: required frequency 123 * 124 * Find suitable clock divider by frequency. 125 * 126 * Return: The ID of PLL if successful, otherwise negative error value. 127 */ 128 static int find_divider(struct uniphier_aio *aio, int pll_id, unsigned int freq) 129 { 130 struct uniphier_aio_pll *pll; 131 int mul[] = { 1, 1, 1, 2, }; 132 int div[] = { 2, 3, 1, 3, }; 133 int i; 134 135 if (!is_valid_pll(aio->chip, pll_id)) 136 return -EINVAL; 137 138 pll = &aio->chip->plls[pll_id]; 139 for (i = 0; i < ARRAY_SIZE(mul); i++) 140 if (pll->freq * mul[i] / div[i] == freq) 141 return i; 142 143 return -ENOTSUPP; 144 } 145 146 static int uniphier_aio_set_sysclk(struct snd_soc_dai *dai, int clk_id, 147 unsigned int freq, int dir) 148 { 149 struct uniphier_aio *aio = uniphier_priv(dai); 150 struct device *dev = &aio->chip->pdev->dev; 151 bool pll_auto = false; 152 int pll_id, div_id; 153 154 switch (clk_id) { 155 case AUD_CLK_IO: 156 return -ENOTSUPP; 157 case AUD_CLK_A1: 158 pll_id = AUD_PLL_A1; 159 break; 160 case AUD_CLK_F1: 161 pll_id = AUD_PLL_F1; 162 break; 163 case AUD_CLK_A2: 164 pll_id = AUD_PLL_A2; 165 break; 166 case AUD_CLK_F2: 167 pll_id = AUD_PLL_F2; 168 break; 169 case AUD_CLK_A: 170 pll_id = AUD_PLL_A1; 171 pll_auto = true; 172 break; 173 case AUD_CLK_F: 174 pll_id = AUD_PLL_F1; 175 pll_auto = true; 176 break; 177 case AUD_CLK_APLL: 178 pll_id = AUD_PLL_APLL; 179 break; 180 case AUD_CLK_RX0: 181 pll_id = AUD_PLL_RX0; 182 break; 183 case AUD_CLK_USB0: 184 pll_id = AUD_PLL_USB0; 185 break; 186 case AUD_CLK_HSC0: 187 pll_id = AUD_PLL_HSC0; 188 break; 189 default: 190 dev_err(dev, "Sysclk(%d) is not supported\n", clk_id); 191 return -EINVAL; 192 } 193 194 if (pll_auto) { 195 for (pll_id = 0; pll_id < aio->chip->num_plls; pll_id++) { 196 div_id = find_divider(aio, pll_id, freq); 197 if (div_id >= 0) { 198 aio->plldiv = div_id; 199 break; 200 } 201 } 202 if (pll_id == aio->chip->num_plls) { 203 dev_err(dev, "Sysclk frequency is not supported(%d)\n", 204 freq); 205 return -EINVAL; 206 } 207 } 208 209 if (dir == SND_SOC_CLOCK_OUT) 210 aio->pll_out = pll_id; 211 else 212 aio->pll_in = pll_id; 213 214 return 0; 215 } 216 217 static int uniphier_aio_set_pll(struct snd_soc_dai *dai, int pll_id, 218 int source, unsigned int freq_in, 219 unsigned int freq_out) 220 { 221 struct uniphier_aio *aio = uniphier_priv(dai); 222 int ret; 223 224 if (!is_valid_pll(aio->chip, pll_id)) 225 return -EINVAL; 226 227 ret = aio_chip_set_pll(aio->chip, pll_id, freq_out); 228 if (ret < 0) 229 return ret; 230 231 return 0; 232 } 233 234 static int uniphier_aio_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 235 { 236 struct uniphier_aio *aio = uniphier_priv(dai); 237 struct device *dev = &aio->chip->pdev->dev; 238 239 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 240 case SND_SOC_DAIFMT_LEFT_J: 241 case SND_SOC_DAIFMT_RIGHT_J: 242 case SND_SOC_DAIFMT_I2S: 243 aio->fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 244 break; 245 default: 246 dev_err(dev, "Format is not supported(%d)\n", 247 fmt & SND_SOC_DAIFMT_FORMAT_MASK); 248 return -EINVAL; 249 } 250 251 return 0; 252 } 253 254 static int uniphier_aio_startup(struct snd_pcm_substream *substream, 255 struct snd_soc_dai *dai) 256 { 257 struct uniphier_aio *aio = uniphier_priv(dai); 258 struct uniphier_aio_sub *sub = &aio->sub[substream->stream]; 259 260 sub->substream = substream; 261 sub->pass_through = 0; 262 sub->use_mmap = true; 263 264 return aio_init(sub); 265 } 266 267 static void uniphier_aio_shutdown(struct snd_pcm_substream *substream, 268 struct snd_soc_dai *dai) 269 { 270 struct uniphier_aio *aio = uniphier_priv(dai); 271 struct uniphier_aio_sub *sub = &aio->sub[substream->stream]; 272 273 sub->substream = NULL; 274 } 275 276 static int uniphier_aio_hw_params(struct snd_pcm_substream *substream, 277 struct snd_pcm_hw_params *params, 278 struct snd_soc_dai *dai) 279 { 280 struct uniphier_aio *aio = uniphier_priv(dai); 281 struct uniphier_aio_sub *sub = &aio->sub[substream->stream]; 282 struct device *dev = &aio->chip->pdev->dev; 283 int freq, ret; 284 285 switch (params_rate(params)) { 286 case 48000: 287 case 32000: 288 case 24000: 289 freq = 12288000; 290 break; 291 case 44100: 292 case 22050: 293 freq = 11289600; 294 break; 295 default: 296 dev_err(dev, "Rate is not supported(%d)\n", 297 params_rate(params)); 298 return -EINVAL; 299 } 300 ret = snd_soc_dai_set_sysclk(dai, AUD_CLK_A, 301 freq, SND_SOC_CLOCK_OUT); 302 if (ret) 303 return ret; 304 305 sub->params = *params; 306 sub->setting = 1; 307 308 aio_port_reset(sub); 309 aio_port_set_volume(sub, sub->vol); 310 aio_src_reset(sub); 311 312 return 0; 313 } 314 315 static int uniphier_aio_hw_free(struct snd_pcm_substream *substream, 316 struct snd_soc_dai *dai) 317 { 318 struct uniphier_aio *aio = uniphier_priv(dai); 319 struct uniphier_aio_sub *sub = &aio->sub[substream->stream]; 320 321 sub->setting = 0; 322 323 return 0; 324 } 325 326 static int uniphier_aio_prepare(struct snd_pcm_substream *substream, 327 struct snd_soc_dai *dai) 328 { 329 struct uniphier_aio *aio = uniphier_priv(dai); 330 struct uniphier_aio_sub *sub = &aio->sub[substream->stream]; 331 int ret; 332 333 ret = aio_port_set_param(sub, sub->pass_through, &sub->params); 334 if (ret) 335 return ret; 336 ret = aio_src_set_param(sub, &sub->params); 337 if (ret) 338 return ret; 339 aio_port_set_enable(sub, 1); 340 341 ret = aio_if_set_param(sub, sub->pass_through); 342 if (ret) 343 return ret; 344 345 if (sub->swm->type == PORT_TYPE_CONV) { 346 ret = aio_srcif_set_param(sub); 347 if (ret) 348 return ret; 349 ret = aio_srcch_set_param(sub); 350 if (ret) 351 return ret; 352 aio_srcch_set_enable(sub, 1); 353 } 354 355 return 0; 356 } 357 358 const struct snd_soc_dai_ops uniphier_aio_i2s_ops = { 359 .set_sysclk = uniphier_aio_set_sysclk, 360 .set_pll = uniphier_aio_set_pll, 361 .set_fmt = uniphier_aio_set_fmt, 362 .startup = uniphier_aio_startup, 363 .shutdown = uniphier_aio_shutdown, 364 .hw_params = uniphier_aio_hw_params, 365 .hw_free = uniphier_aio_hw_free, 366 .prepare = uniphier_aio_prepare, 367 }; 368 EXPORT_SYMBOL_GPL(uniphier_aio_i2s_ops); 369 370 const struct snd_soc_dai_ops uniphier_aio_spdif_ops = { 371 .set_sysclk = uniphier_aio_set_sysclk, 372 .set_pll = uniphier_aio_set_pll, 373 .startup = uniphier_aio_startup, 374 .shutdown = uniphier_aio_shutdown, 375 .hw_params = uniphier_aio_hw_params, 376 .hw_free = uniphier_aio_hw_free, 377 .prepare = uniphier_aio_prepare, 378 }; 379 EXPORT_SYMBOL_GPL(uniphier_aio_spdif_ops); 380 381 int uniphier_aio_dai_probe(struct snd_soc_dai *dai) 382 { 383 struct uniphier_aio *aio = uniphier_priv(dai); 384 int i; 385 386 for (i = 0; i < ARRAY_SIZE(aio->sub); i++) { 387 struct uniphier_aio_sub *sub = &aio->sub[i]; 388 const struct uniphier_aio_spec *spec; 389 390 spec = find_spec(aio, dai->name, i); 391 if (!spec) 392 continue; 393 394 sub->swm = &spec->swm; 395 sub->spec = spec; 396 397 sub->vol = AUD_VOL_INIT; 398 } 399 400 aio_iecout_set_enable(aio->chip, true); 401 aio_chip_init(aio->chip); 402 aio->chip->active = 1; 403 404 return 0; 405 } 406 EXPORT_SYMBOL_GPL(uniphier_aio_dai_probe); 407 408 int uniphier_aio_dai_remove(struct snd_soc_dai *dai) 409 { 410 struct uniphier_aio *aio = uniphier_priv(dai); 411 412 aio->chip->active = 0; 413 414 return 0; 415 } 416 EXPORT_SYMBOL_GPL(uniphier_aio_dai_remove); 417 418 static void uniphier_aio_dai_suspend(struct snd_soc_dai *dai) 419 { 420 struct uniphier_aio *aio = uniphier_priv(dai); 421 422 if (!snd_soc_dai_active(dai)) 423 return; 424 425 aio->chip->num_wup_aios--; 426 if (!aio->chip->num_wup_aios) { 427 reset_control_assert(aio->chip->rst); 428 clk_disable_unprepare(aio->chip->clk); 429 } 430 } 431 432 static int uniphier_aio_suspend(struct snd_soc_component *component) 433 { 434 struct snd_soc_dai *dai; 435 436 for_each_component_dais(component, dai) 437 uniphier_aio_dai_suspend(dai); 438 return 0; 439 } 440 441 static int uniphier_aio_dai_resume(struct snd_soc_dai *dai) 442 { 443 struct uniphier_aio *aio = uniphier_priv(dai); 444 int ret, i; 445 446 if (!snd_soc_dai_active(dai)) 447 return 0; 448 449 if (!aio->chip->active) 450 return 0; 451 452 if (!aio->chip->num_wup_aios) { 453 ret = clk_prepare_enable(aio->chip->clk); 454 if (ret) 455 return ret; 456 457 ret = reset_control_deassert(aio->chip->rst); 458 if (ret) 459 goto err_out_clock; 460 } 461 462 aio_iecout_set_enable(aio->chip, true); 463 aio_chip_init(aio->chip); 464 465 for (i = 0; i < ARRAY_SIZE(aio->sub); i++) { 466 struct uniphier_aio_sub *sub = &aio->sub[i]; 467 468 if (!sub->spec || !sub->substream) 469 continue; 470 471 ret = aio_init(sub); 472 if (ret) 473 goto err_out_reset; 474 475 if (!sub->setting) 476 continue; 477 478 aio_port_reset(sub); 479 aio_src_reset(sub); 480 } 481 aio->chip->num_wup_aios++; 482 483 return 0; 484 485 err_out_reset: 486 if (!aio->chip->num_wup_aios) 487 reset_control_assert(aio->chip->rst); 488 err_out_clock: 489 if (!aio->chip->num_wup_aios) 490 clk_disable_unprepare(aio->chip->clk); 491 492 return ret; 493 } 494 495 static int uniphier_aio_resume(struct snd_soc_component *component) 496 { 497 struct snd_soc_dai *dai; 498 int ret = 0; 499 500 for_each_component_dais(component, dai) 501 ret |= uniphier_aio_dai_resume(dai); 502 return ret; 503 } 504 505 static int uniphier_aio_vol_info(struct snd_kcontrol *kcontrol, 506 struct snd_ctl_elem_info *uinfo) 507 { 508 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 509 uinfo->count = 1; 510 uinfo->value.integer.min = 0; 511 uinfo->value.integer.max = AUD_VOL_MAX; 512 513 return 0; 514 } 515 516 static int uniphier_aio_vol_get(struct snd_kcontrol *kcontrol, 517 struct snd_ctl_elem_value *ucontrol) 518 { 519 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 520 struct uniphier_aio_chip *chip = snd_soc_component_get_drvdata(comp); 521 struct uniphier_aio_sub *sub; 522 int oport_hw = kcontrol->private_value; 523 524 sub = find_volume(chip, oport_hw); 525 if (!sub) 526 return 0; 527 528 ucontrol->value.integer.value[0] = sub->vol; 529 530 return 0; 531 } 532 533 static int uniphier_aio_vol_put(struct snd_kcontrol *kcontrol, 534 struct snd_ctl_elem_value *ucontrol) 535 { 536 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 537 struct uniphier_aio_chip *chip = snd_soc_component_get_drvdata(comp); 538 struct uniphier_aio_sub *sub; 539 int oport_hw = kcontrol->private_value; 540 541 sub = find_volume(chip, oport_hw); 542 if (!sub) 543 return 0; 544 545 if (sub->vol == ucontrol->value.integer.value[0]) 546 return 0; 547 sub->vol = ucontrol->value.integer.value[0]; 548 549 aio_port_set_volume(sub, sub->vol); 550 551 return 0; 552 } 553 554 static const struct snd_kcontrol_new uniphier_aio_controls[] = { 555 { 556 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 557 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 558 .name = "HPCMOUT1 Volume", 559 .info = uniphier_aio_vol_info, 560 .get = uniphier_aio_vol_get, 561 .put = uniphier_aio_vol_put, 562 .private_value = AUD_HW_HPCMOUT1, 563 }, 564 { 565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 566 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 567 .name = "PCMOUT1 Volume", 568 .info = uniphier_aio_vol_info, 569 .get = uniphier_aio_vol_get, 570 .put = uniphier_aio_vol_put, 571 .private_value = AUD_HW_PCMOUT1, 572 }, 573 { 574 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 575 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 576 .name = "PCMOUT2 Volume", 577 .info = uniphier_aio_vol_info, 578 .get = uniphier_aio_vol_get, 579 .put = uniphier_aio_vol_put, 580 .private_value = AUD_HW_PCMOUT2, 581 }, 582 { 583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 584 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 585 .name = "PCMOUT3 Volume", 586 .info = uniphier_aio_vol_info, 587 .get = uniphier_aio_vol_get, 588 .put = uniphier_aio_vol_put, 589 .private_value = AUD_HW_PCMOUT3, 590 }, 591 { 592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 593 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 594 .name = "HIECOUT1 Volume", 595 .info = uniphier_aio_vol_info, 596 .get = uniphier_aio_vol_get, 597 .put = uniphier_aio_vol_put, 598 .private_value = AUD_HW_HIECOUT1, 599 }, 600 { 601 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 602 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 603 .name = "IECOUT1 Volume", 604 .info = uniphier_aio_vol_info, 605 .get = uniphier_aio_vol_get, 606 .put = uniphier_aio_vol_put, 607 .private_value = AUD_HW_IECOUT1, 608 }, 609 }; 610 611 static const struct snd_soc_component_driver uniphier_aio_component = { 612 .name = "uniphier-aio", 613 .controls = uniphier_aio_controls, 614 .num_controls = ARRAY_SIZE(uniphier_aio_controls), 615 .suspend = uniphier_aio_suspend, 616 .resume = uniphier_aio_resume, 617 }; 618 619 int uniphier_aio_probe(struct platform_device *pdev) 620 { 621 struct uniphier_aio_chip *chip; 622 struct device *dev = &pdev->dev; 623 int ret, i, j; 624 625 chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); 626 if (!chip) 627 return -ENOMEM; 628 629 chip->chip_spec = of_device_get_match_data(dev); 630 if (!chip->chip_spec) 631 return -EINVAL; 632 633 chip->regmap_sg = syscon_regmap_lookup_by_phandle(dev->of_node, 634 "socionext,syscon"); 635 if (IS_ERR(chip->regmap_sg)) { 636 if (PTR_ERR(chip->regmap_sg) == -EPROBE_DEFER) 637 return -EPROBE_DEFER; 638 chip->regmap_sg = NULL; 639 } 640 641 chip->clk = devm_clk_get(dev, "aio"); 642 if (IS_ERR(chip->clk)) 643 return PTR_ERR(chip->clk); 644 645 chip->rst = devm_reset_control_get_shared(dev, "aio"); 646 if (IS_ERR(chip->rst)) 647 return PTR_ERR(chip->rst); 648 649 chip->num_aios = chip->chip_spec->num_dais; 650 chip->num_wup_aios = chip->num_aios; 651 chip->aios = devm_kcalloc(dev, 652 chip->num_aios, sizeof(struct uniphier_aio), 653 GFP_KERNEL); 654 if (!chip->aios) 655 return -ENOMEM; 656 657 chip->num_plls = chip->chip_spec->num_plls; 658 chip->plls = devm_kcalloc(dev, 659 chip->num_plls, 660 sizeof(struct uniphier_aio_pll), 661 GFP_KERNEL); 662 if (!chip->plls) 663 return -ENOMEM; 664 memcpy(chip->plls, chip->chip_spec->plls, 665 sizeof(struct uniphier_aio_pll) * chip->num_plls); 666 667 for (i = 0; i < chip->num_aios; i++) { 668 struct uniphier_aio *aio = &chip->aios[i]; 669 670 aio->chip = chip; 671 aio->fmt = SND_SOC_DAIFMT_I2S; 672 673 for (j = 0; j < ARRAY_SIZE(aio->sub); j++) { 674 struct uniphier_aio_sub *sub = &aio->sub[j]; 675 676 sub->aio = aio; 677 spin_lock_init(&sub->lock); 678 } 679 } 680 681 chip->pdev = pdev; 682 platform_set_drvdata(pdev, chip); 683 684 ret = clk_prepare_enable(chip->clk); 685 if (ret) 686 return ret; 687 688 ret = reset_control_deassert(chip->rst); 689 if (ret) 690 goto err_out_clock; 691 692 ret = devm_snd_soc_register_component(dev, &uniphier_aio_component, 693 chip->chip_spec->dais, 694 chip->chip_spec->num_dais); 695 if (ret) { 696 dev_err(dev, "Register component failed.\n"); 697 goto err_out_reset; 698 } 699 700 ret = uniphier_aiodma_soc_register_platform(pdev); 701 if (ret) { 702 dev_err(dev, "Register platform failed.\n"); 703 goto err_out_reset; 704 } 705 706 return 0; 707 708 err_out_reset: 709 reset_control_assert(chip->rst); 710 711 err_out_clock: 712 clk_disable_unprepare(chip->clk); 713 714 return ret; 715 } 716 EXPORT_SYMBOL_GPL(uniphier_aio_probe); 717 718 int uniphier_aio_remove(struct platform_device *pdev) 719 { 720 struct uniphier_aio_chip *chip = platform_get_drvdata(pdev); 721 722 reset_control_assert(chip->rst); 723 clk_disable_unprepare(chip->clk); 724 725 return 0; 726 } 727 EXPORT_SYMBOL_GPL(uniphier_aio_remove); 728 729 MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>"); 730 MODULE_DESCRIPTION("UniPhier AIO CPU DAI driver."); 731 MODULE_LICENSE("GPL v2"); 732