diff options
Diffstat (limited to 'sound/soc/codecs/ak4535.c')
| -rw-r--r-- | sound/soc/codecs/ak4535.c | 261 |
1 files changed, 69 insertions, 192 deletions
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index d4253675b2d3..e1a214ee757f 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
| @@ -24,18 +24,17 @@ | |||
| 24 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
| 25 | #include <sound/pcm_params.h> | 25 | #include <sound/pcm_params.h> |
| 26 | #include <sound/soc.h> | 26 | #include <sound/soc.h> |
| 27 | #include <sound/soc-dapm.h> | ||
| 28 | #include <sound/initval.h> | 27 | #include <sound/initval.h> |
| 29 | 28 | ||
| 30 | #include "ak4535.h" | 29 | #include "ak4535.h" |
| 31 | 30 | ||
| 32 | #define AK4535_VERSION "0.3" | 31 | #define AK4535_VERSION "0.3" |
| 33 | 32 | ||
| 34 | struct snd_soc_codec_device soc_codec_dev_ak4535; | ||
| 35 | |||
| 36 | /* codec private data */ | 33 | /* codec private data */ |
| 37 | struct ak4535_priv { | 34 | struct ak4535_priv { |
| 38 | unsigned int sysclk; | 35 | unsigned int sysclk; |
| 36 | enum snd_soc_control_type control_type; | ||
| 37 | void *control_data; | ||
| 39 | }; | 38 | }; |
| 40 | 39 | ||
| 41 | /* | 40 | /* |
| @@ -231,7 +230,7 @@ static const struct snd_soc_dapm_widget ak4535_dapm_widgets[] = { | |||
| 231 | SND_SOC_DAPM_INPUT("AIN"), | 230 | SND_SOC_DAPM_INPUT("AIN"), |
| 232 | }; | 231 | }; |
| 233 | 232 | ||
| 234 | static const struct snd_soc_dapm_route audio_map[] = { | 233 | static const struct snd_soc_dapm_route ak4535_audio_map[] = { |
| 235 | /*stereo mixer */ | 234 | /*stereo mixer */ |
| 236 | {"Stereo Mixer", "Playback Switch", "DAC"}, | 235 | {"Stereo Mixer", "Playback Switch", "DAC"}, |
| 237 | {"Stereo Mixer", "Mic Sidetone Switch", "Mic"}, | 236 | {"Stereo Mixer", "Mic Sidetone Switch", "Mic"}, |
| @@ -288,16 +287,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
| 288 | {"Input Mixer", "Aux Capture Switch", "Aux In"}, | 287 | {"Input Mixer", "Aux Capture Switch", "Aux In"}, |
| 289 | }; | 288 | }; |
| 290 | 289 | ||
| 291 | static int ak4535_add_widgets(struct snd_soc_codec *codec) | ||
| 292 | { | ||
| 293 | snd_soc_dapm_new_controls(codec, ak4535_dapm_widgets, | ||
| 294 | ARRAY_SIZE(ak4535_dapm_widgets)); | ||
| 295 | |||
| 296 | snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | ||
| 297 | |||
| 298 | return 0; | ||
| 299 | } | ||
| 300 | |||
| 301 | static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai, | 290 | static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai, |
| 302 | int clk_id, unsigned int freq, int dir) | 291 | int clk_id, unsigned int freq, int dir) |
| 303 | { | 292 | { |
| @@ -313,8 +302,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream, | |||
| 313 | struct snd_soc_dai *dai) | 302 | struct snd_soc_dai *dai) |
| 314 | { | 303 | { |
| 315 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 304 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 316 | struct snd_soc_device *socdev = rtd->socdev; | 305 | struct snd_soc_codec *codec = rtd->codec; |
| 317 | struct snd_soc_codec *codec = socdev->card->codec; | ||
| 318 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); | 306 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); |
| 319 | u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); | 307 | u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); |
| 320 | int rate = params_rate(params), fs = 256; | 308 | int rate = params_rate(params), fs = 256; |
| @@ -367,9 +355,9 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 367 | static int ak4535_mute(struct snd_soc_dai *dai, int mute) | 355 | static int ak4535_mute(struct snd_soc_dai *dai, int mute) |
| 368 | { | 356 | { |
| 369 | struct snd_soc_codec *codec = dai->codec; | 357 | struct snd_soc_codec *codec = dai->codec; |
| 370 | u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf; | 358 | u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); |
| 371 | if (!mute) | 359 | if (!mute) |
| 372 | ak4535_write(codec, AK4535_DAC, mute_reg); | 360 | ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); |
| 373 | else | 361 | else |
| 374 | ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); | 362 | ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); |
| 375 | return 0; | 363 | return 0; |
| @@ -378,14 +366,16 @@ static int ak4535_mute(struct snd_soc_dai *dai, int mute) | |||
| 378 | static int ak4535_set_bias_level(struct snd_soc_codec *codec, | 366 | static int ak4535_set_bias_level(struct snd_soc_codec *codec, |
| 379 | enum snd_soc_bias_level level) | 367 | enum snd_soc_bias_level level) |
| 380 | { | 368 | { |
| 381 | u16 i; | 369 | u16 i, mute_reg; |
| 382 | 370 | ||
| 383 | switch (level) { | 371 | switch (level) { |
| 384 | case SND_SOC_BIAS_ON: | 372 | case SND_SOC_BIAS_ON: |
| 385 | ak4535_mute(codec->dai, 0); | 373 | mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); |
| 374 | ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); | ||
| 386 | break; | 375 | break; |
| 387 | case SND_SOC_BIAS_PREPARE: | 376 | case SND_SOC_BIAS_PREPARE: |
| 388 | ak4535_mute(codec->dai, 1); | 377 | mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); |
| 378 | ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); | ||
| 389 | break; | 379 | break; |
| 390 | case SND_SOC_BIAS_STANDBY: | 380 | case SND_SOC_BIAS_STANDBY: |
| 391 | i = ak4535_read_reg_cache(codec, AK4535_PM1); | 381 | i = ak4535_read_reg_cache(codec, AK4535_PM1); |
| @@ -398,7 +388,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec, | |||
| 398 | ak4535_write(codec, AK4535_PM1, i & (~0x80)); | 388 | ak4535_write(codec, AK4535_PM1, i & (~0x80)); |
| 399 | break; | 389 | break; |
| 400 | } | 390 | } |
| 401 | codec->bias_level = level; | 391 | codec->dapm.bias_level = level; |
| 402 | return 0; | 392 | return 0; |
| 403 | } | 393 | } |
| 404 | 394 | ||
| @@ -413,8 +403,8 @@ static struct snd_soc_dai_ops ak4535_dai_ops = { | |||
| 413 | .set_sysclk = ak4535_set_dai_sysclk, | 403 | .set_sysclk = ak4535_set_dai_sysclk, |
| 414 | }; | 404 | }; |
| 415 | 405 | ||
| 416 | struct snd_soc_dai ak4535_dai = { | 406 | static struct snd_soc_dai_driver ak4535_dai = { |
| 417 | .name = "AK4535", | 407 | .name = "ak4535-hifi", |
| 418 | .playback = { | 408 | .playback = { |
| 419 | .stream_name = "Playback", | 409 | .stream_name = "Playback", |
| 420 | .channels_min = 1, | 410 | .channels_min = 1, |
| @@ -429,95 +419,86 @@ struct snd_soc_dai ak4535_dai = { | |||
| 429 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 419 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
| 430 | .ops = &ak4535_dai_ops, | 420 | .ops = &ak4535_dai_ops, |
| 431 | }; | 421 | }; |
| 432 | EXPORT_SYMBOL_GPL(ak4535_dai); | ||
| 433 | 422 | ||
| 434 | static int ak4535_suspend(struct platform_device *pdev, pm_message_t state) | 423 | static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state) |
| 435 | { | 424 | { |
| 436 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
| 437 | struct snd_soc_codec *codec = socdev->card->codec; | ||
| 438 | |||
| 439 | ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); | 425 | ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); |
| 440 | return 0; | 426 | return 0; |
| 441 | } | 427 | } |
| 442 | 428 | ||
| 443 | static int ak4535_resume(struct platform_device *pdev) | 429 | static int ak4535_resume(struct snd_soc_codec *codec) |
| 444 | { | 430 | { |
| 445 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
| 446 | struct snd_soc_codec *codec = socdev->card->codec; | ||
| 447 | ak4535_sync(codec); | 431 | ak4535_sync(codec); |
| 448 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 432 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 449 | return 0; | 433 | return 0; |
| 450 | } | 434 | } |
| 451 | 435 | ||
| 452 | /* | 436 | static int ak4535_probe(struct snd_soc_codec *codec) |
| 453 | * initialise the AK4535 driver | ||
| 454 | * register the mixer and dsp interfaces with the kernel | ||
| 455 | */ | ||
| 456 | static int ak4535_init(struct snd_soc_device *socdev) | ||
| 457 | { | 437 | { |
| 458 | struct snd_soc_codec *codec = socdev->card->codec; | 438 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); |
| 459 | int ret = 0; | ||
| 460 | 439 | ||
| 461 | codec->name = "AK4535"; | 440 | printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); |
| 462 | codec->owner = THIS_MODULE; | ||
| 463 | codec->read = ak4535_read_reg_cache; | ||
| 464 | codec->write = ak4535_write; | ||
| 465 | codec->set_bias_level = ak4535_set_bias_level; | ||
| 466 | codec->dai = &ak4535_dai; | ||
| 467 | codec->num_dai = 1; | ||
| 468 | codec->reg_cache_size = ARRAY_SIZE(ak4535_reg); | ||
| 469 | codec->reg_cache = kmemdup(ak4535_reg, sizeof(ak4535_reg), GFP_KERNEL); | ||
| 470 | |||
| 471 | if (codec->reg_cache == NULL) | ||
| 472 | return -ENOMEM; | ||
| 473 | 441 | ||
| 474 | /* register pcms */ | 442 | codec->control_data = ak4535->control_data; |
| 475 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
| 476 | if (ret < 0) { | ||
| 477 | printk(KERN_ERR "ak4535: failed to create pcms\n"); | ||
| 478 | goto pcm_err; | ||
| 479 | } | ||
| 480 | 443 | ||
| 481 | /* power on device */ | 444 | /* power on device */ |
| 482 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 445 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 483 | 446 | ||
| 484 | snd_soc_add_controls(codec, ak4535_snd_controls, | 447 | snd_soc_add_controls(codec, ak4535_snd_controls, |
| 485 | ARRAY_SIZE(ak4535_snd_controls)); | 448 | ARRAY_SIZE(ak4535_snd_controls)); |
| 486 | ak4535_add_widgets(codec); | 449 | return 0; |
| 487 | 450 | } | |
| 488 | return ret; | ||
| 489 | |||
| 490 | pcm_err: | ||
| 491 | kfree(codec->reg_cache); | ||
| 492 | 451 | ||
| 493 | return ret; | 452 | /* power down chip */ |
| 453 | static int ak4535_remove(struct snd_soc_codec *codec) | ||
| 454 | { | ||
| 455 | ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
| 456 | return 0; | ||
| 494 | } | 457 | } |
| 495 | 458 | ||
| 496 | static struct snd_soc_device *ak4535_socdev; | 459 | static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { |
| 460 | .probe = ak4535_probe, | ||
| 461 | .remove = ak4535_remove, | ||
| 462 | .suspend = ak4535_suspend, | ||
| 463 | .resume = ak4535_resume, | ||
| 464 | .read = ak4535_read_reg_cache, | ||
| 465 | .write = ak4535_write, | ||
| 466 | .set_bias_level = ak4535_set_bias_level, | ||
| 467 | .reg_cache_size = ARRAY_SIZE(ak4535_reg), | ||
| 468 | .reg_word_size = sizeof(u8), | ||
| 469 | .reg_cache_default = ak4535_reg, | ||
| 470 | .dapm_widgets = ak4535_dapm_widgets, | ||
| 471 | .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), | ||
| 472 | .dapm_routes = ak4535_audio_map, | ||
| 473 | .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), | ||
| 474 | }; | ||
| 497 | 475 | ||
| 498 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 476 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 499 | 477 | static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, | |
| 500 | static int ak4535_i2c_probe(struct i2c_client *i2c, | 478 | const struct i2c_device_id *id) |
| 501 | const struct i2c_device_id *id) | ||
| 502 | { | 479 | { |
| 503 | struct snd_soc_device *socdev = ak4535_socdev; | 480 | struct ak4535_priv *ak4535; |
| 504 | struct snd_soc_codec *codec = socdev->card->codec; | ||
| 505 | int ret; | 481 | int ret; |
| 506 | 482 | ||
| 507 | i2c_set_clientdata(i2c, codec); | 483 | ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL); |
| 508 | codec->control_data = i2c; | 484 | if (ak4535 == NULL) |
| 485 | return -ENOMEM; | ||
| 509 | 486 | ||
| 510 | ret = ak4535_init(socdev); | 487 | i2c_set_clientdata(i2c, ak4535); |
| 511 | if (ret < 0) | 488 | ak4535->control_data = i2c; |
| 512 | printk(KERN_ERR "failed to initialise AK4535\n"); | 489 | ak4535->control_type = SND_SOC_I2C; |
| 513 | 490 | ||
| 491 | ret = snd_soc_register_codec(&i2c->dev, | ||
| 492 | &soc_codec_dev_ak4535, &ak4535_dai, 1); | ||
| 493 | if (ret < 0) | ||
| 494 | kfree(ak4535); | ||
| 514 | return ret; | 495 | return ret; |
| 515 | } | 496 | } |
| 516 | 497 | ||
| 517 | static int ak4535_i2c_remove(struct i2c_client *client) | 498 | static __devexit int ak4535_i2c_remove(struct i2c_client *client) |
| 518 | { | 499 | { |
| 519 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 500 | snd_soc_unregister_codec(&client->dev); |
| 520 | kfree(codec->reg_cache); | 501 | kfree(i2c_get_clientdata(client)); |
| 521 | return 0; | 502 | return 0; |
| 522 | } | 503 | } |
| 523 | 504 | ||
| @@ -529,138 +510,34 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id); | |||
| 529 | 510 | ||
| 530 | static struct i2c_driver ak4535_i2c_driver = { | 511 | static struct i2c_driver ak4535_i2c_driver = { |
| 531 | .driver = { | 512 | .driver = { |
| 532 | .name = "AK4535 I2C Codec", | 513 | .name = "ak4535-codec", |
| 533 | .owner = THIS_MODULE, | 514 | .owner = THIS_MODULE, |
| 534 | }, | 515 | }, |
| 535 | .probe = ak4535_i2c_probe, | 516 | .probe = ak4535_i2c_probe, |
| 536 | .remove = ak4535_i2c_remove, | 517 | .remove = __devexit_p(ak4535_i2c_remove), |
| 537 | .id_table = ak4535_i2c_id, | 518 | .id_table = ak4535_i2c_id, |
| 538 | }; | 519 | }; |
| 539 | |||
| 540 | static int ak4535_add_i2c_device(struct platform_device *pdev, | ||
| 541 | const struct ak4535_setup_data *setup) | ||
| 542 | { | ||
| 543 | struct i2c_board_info info; | ||
| 544 | struct i2c_adapter *adapter; | ||
| 545 | struct i2c_client *client; | ||
| 546 | int ret; | ||
| 547 | |||
| 548 | ret = i2c_add_driver(&ak4535_i2c_driver); | ||
| 549 | if (ret != 0) { | ||
| 550 | dev_err(&pdev->dev, "can't add i2c driver\n"); | ||
| 551 | return ret; | ||
| 552 | } | ||
| 553 | |||
| 554 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
| 555 | info.addr = setup->i2c_address; | ||
| 556 | strlcpy(info.type, "ak4535", I2C_NAME_SIZE); | ||
| 557 | |||
| 558 | adapter = i2c_get_adapter(setup->i2c_bus); | ||
| 559 | if (!adapter) { | ||
| 560 | dev_err(&pdev->dev, "can't get i2c adapter %d\n", | ||
| 561 | setup->i2c_bus); | ||
| 562 | goto err_driver; | ||
| 563 | } | ||
| 564 | |||
| 565 | client = i2c_new_device(adapter, &info); | ||
| 566 | i2c_put_adapter(adapter); | ||
| 567 | if (!client) { | ||
| 568 | dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", | ||
| 569 | (unsigned int)info.addr); | ||
| 570 | goto err_driver; | ||
| 571 | } | ||
| 572 | |||
| 573 | return 0; | ||
| 574 | |||
| 575 | err_driver: | ||
| 576 | i2c_del_driver(&ak4535_i2c_driver); | ||
| 577 | return -ENODEV; | ||
| 578 | } | ||
| 579 | #endif | 520 | #endif |
| 580 | 521 | ||
| 581 | static int ak4535_probe(struct platform_device *pdev) | 522 | static int __init ak4535_modinit(void) |
| 582 | { | 523 | { |
| 583 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 524 | int ret = 0; |
| 584 | struct ak4535_setup_data *setup; | ||
| 585 | struct snd_soc_codec *codec; | ||
| 586 | struct ak4535_priv *ak4535; | ||
| 587 | int ret; | ||
| 588 | |||
| 589 | printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); | ||
| 590 | |||
| 591 | setup = socdev->codec_data; | ||
| 592 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | ||
| 593 | if (codec == NULL) | ||
| 594 | return -ENOMEM; | ||
| 595 | |||
| 596 | ak4535 = kzalloc(sizeof(struct ak4535_priv), GFP_KERNEL); | ||
| 597 | if (ak4535 == NULL) { | ||
| 598 | kfree(codec); | ||
| 599 | return -ENOMEM; | ||
| 600 | } | ||
| 601 | |||
| 602 | snd_soc_codec_set_drvdata(codec, ak4535); | ||
| 603 | socdev->card->codec = codec; | ||
| 604 | mutex_init(&codec->mutex); | ||
| 605 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
| 606 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
| 607 | |||
| 608 | ak4535_socdev = socdev; | ||
| 609 | ret = -ENODEV; | ||
| 610 | |||
| 611 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 525 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 612 | if (setup->i2c_address) { | 526 | ret = i2c_add_driver(&ak4535_i2c_driver); |
| 613 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
| 614 | ret = ak4535_add_i2c_device(pdev, setup); | ||
| 615 | } | ||
| 616 | #endif | ||
| 617 | |||
| 618 | if (ret != 0) { | 527 | if (ret != 0) { |
| 619 | kfree(snd_soc_codec_get_drvdata(codec)); | 528 | printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n", |
| 620 | kfree(codec); | 529 | ret); |
| 621 | } | 530 | } |
| 531 | #endif | ||
| 622 | return ret; | 532 | return ret; |
| 623 | } | 533 | } |
| 534 | module_init(ak4535_modinit); | ||
| 624 | 535 | ||
| 625 | /* power down chip */ | 536 | static void __exit ak4535_exit(void) |
| 626 | static int ak4535_remove(struct platform_device *pdev) | ||
| 627 | { | 537 | { |
| 628 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
| 629 | struct snd_soc_codec *codec = socdev->card->codec; | ||
| 630 | |||
| 631 | if (codec->control_data) | ||
| 632 | ak4535_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
| 633 | |||
| 634 | snd_soc_free_pcms(socdev); | ||
| 635 | snd_soc_dapm_free(socdev); | ||
| 636 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 538 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 637 | if (codec->control_data) | ||
| 638 | i2c_unregister_device(codec->control_data); | ||
| 639 | i2c_del_driver(&ak4535_i2c_driver); | 539 | i2c_del_driver(&ak4535_i2c_driver); |
| 640 | #endif | 540 | #endif |
| 641 | kfree(snd_soc_codec_get_drvdata(codec)); | ||
| 642 | kfree(codec); | ||
| 643 | |||
| 644 | return 0; | ||
| 645 | } | ||
| 646 | |||
| 647 | struct snd_soc_codec_device soc_codec_dev_ak4535 = { | ||
| 648 | .probe = ak4535_probe, | ||
| 649 | .remove = ak4535_remove, | ||
| 650 | .suspend = ak4535_suspend, | ||
| 651 | .resume = ak4535_resume, | ||
| 652 | }; | ||
| 653 | EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535); | ||
| 654 | |||
| 655 | static int __init ak4535_modinit(void) | ||
| 656 | { | ||
| 657 | return snd_soc_register_dai(&ak4535_dai); | ||
| 658 | } | ||
| 659 | module_init(ak4535_modinit); | ||
| 660 | |||
| 661 | static void __exit ak4535_exit(void) | ||
| 662 | { | ||
| 663 | snd_soc_unregister_dai(&ak4535_dai); | ||
| 664 | } | 541 | } |
| 665 | module_exit(ak4535_exit); | 542 | module_exit(ak4535_exit); |
| 666 | 543 | ||
