diff options
Diffstat (limited to 'sound/soc/codecs/wm8731.c')
-rw-r--r-- | sound/soc/codecs/wm8731.c | 245 |
1 files changed, 90 insertions, 155 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 0ab9b6355297..631385802eb4 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -32,9 +32,6 @@ | |||
32 | 32 | ||
33 | #include "wm8731.h" | 33 | #include "wm8731.h" |
34 | 34 | ||
35 | static struct snd_soc_codec *wm8731_codec; | ||
36 | struct snd_soc_codec_device soc_codec_dev_wm8731; | ||
37 | |||
38 | #define WM8731_NUM_SUPPLIES 4 | 35 | #define WM8731_NUM_SUPPLIES 4 |
39 | static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { | 36 | static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { |
40 | "AVDD", | 37 | "AVDD", |
@@ -45,10 +42,11 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { | |||
45 | 42 | ||
46 | /* codec private data */ | 43 | /* codec private data */ |
47 | struct wm8731_priv { | 44 | struct wm8731_priv { |
48 | struct snd_soc_codec codec; | 45 | enum snd_soc_control_type control_type; |
49 | struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; | 46 | struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; |
50 | u16 reg_cache[WM8731_CACHEREGNUM]; | 47 | u16 reg_cache[WM8731_CACHEREGNUM]; |
51 | unsigned int sysclk; | 48 | unsigned int sysclk; |
49 | int sysclk_type; | ||
52 | }; | 50 | }; |
53 | 51 | ||
54 | 52 | ||
@@ -113,6 +111,7 @@ static const struct snd_kcontrol_new wm8731_input_mux_controls = | |||
113 | SOC_DAPM_ENUM("Input Select", wm8731_enum[0]); | 111 | SOC_DAPM_ENUM("Input Select", wm8731_enum[0]); |
114 | 112 | ||
115 | static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { | 113 | static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { |
114 | SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0), | ||
116 | SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, | 115 | SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, |
117 | &wm8731_output_mixer_controls[0], | 116 | &wm8731_output_mixer_controls[0], |
118 | ARRAY_SIZE(wm8731_output_mixer_controls)), | 117 | ARRAY_SIZE(wm8731_output_mixer_controls)), |
@@ -130,7 +129,18 @@ SND_SOC_DAPM_INPUT("RLINEIN"), | |||
130 | SND_SOC_DAPM_INPUT("LLINEIN"), | 129 | SND_SOC_DAPM_INPUT("LLINEIN"), |
131 | }; | 130 | }; |
132 | 131 | ||
132 | static int wm8731_check_osc(struct snd_soc_dapm_widget *source, | ||
133 | struct snd_soc_dapm_widget *sink) | ||
134 | { | ||
135 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(source->codec); | ||
136 | |||
137 | return wm8731->sysclk_type == WM8731_SYSCLK_MCLK; | ||
138 | } | ||
139 | |||
133 | static const struct snd_soc_dapm_route intercon[] = { | 140 | static const struct snd_soc_dapm_route intercon[] = { |
141 | {"DAC", NULL, "OSC", wm8731_check_osc}, | ||
142 | {"ADC", NULL, "OSC", wm8731_check_osc}, | ||
143 | |||
134 | /* output mixer */ | 144 | /* output mixer */ |
135 | {"Output Mixer", "Line Bypass Switch", "Line Input"}, | 145 | {"Output Mixer", "Line Bypass Switch", "Line Input"}, |
136 | {"Output Mixer", "HiFi Playback Switch", "DAC"}, | 146 | {"Output Mixer", "HiFi Playback Switch", "DAC"}, |
@@ -222,9 +232,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream, | |||
222 | struct snd_pcm_hw_params *params, | 232 | struct snd_pcm_hw_params *params, |
223 | struct snd_soc_dai *dai) | 233 | struct snd_soc_dai *dai) |
224 | { | 234 | { |
225 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 235 | struct snd_soc_codec *codec = dai->codec; |
226 | struct snd_soc_device *socdev = rtd->socdev; | ||
227 | struct snd_soc_codec *codec = socdev->card->codec; | ||
228 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 236 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
229 | u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; | 237 | u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; |
230 | int i = get_coeff(wm8731->sysclk, params_rate(params)); | 238 | int i = get_coeff(wm8731->sysclk, params_rate(params)); |
@@ -252,9 +260,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream, | |||
252 | static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, | 260 | static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, |
253 | struct snd_soc_dai *dai) | 261 | struct snd_soc_dai *dai) |
254 | { | 262 | { |
255 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 263 | struct snd_soc_codec *codec = dai->codec; |
256 | struct snd_soc_device *socdev = rtd->socdev; | ||
257 | struct snd_soc_codec *codec = socdev->card->codec; | ||
258 | 264 | ||
259 | /* set active */ | 265 | /* set active */ |
260 | snd_soc_write(codec, WM8731_ACTIVE, 0x0001); | 266 | snd_soc_write(codec, WM8731_ACTIVE, 0x0001); |
@@ -265,9 +271,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, | |||
265 | static void wm8731_shutdown(struct snd_pcm_substream *substream, | 271 | static void wm8731_shutdown(struct snd_pcm_substream *substream, |
266 | struct snd_soc_dai *dai) | 272 | struct snd_soc_dai *dai) |
267 | { | 273 | { |
268 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 274 | struct snd_soc_codec *codec = dai->codec; |
269 | struct snd_soc_device *socdev = rtd->socdev; | ||
270 | struct snd_soc_codec *codec = socdev->card->codec; | ||
271 | 275 | ||
272 | /* deactivate */ | 276 | /* deactivate */ |
273 | if (!codec->active) { | 277 | if (!codec->active) { |
@@ -294,6 +298,15 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
294 | struct snd_soc_codec *codec = codec_dai->codec; | 298 | struct snd_soc_codec *codec = codec_dai->codec; |
295 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 299 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
296 | 300 | ||
301 | switch (clk_id) { | ||
302 | case WM8731_SYSCLK_XTAL: | ||
303 | case WM8731_SYSCLK_MCLK: | ||
304 | wm8731->sysclk_type = clk_id; | ||
305 | break; | ||
306 | default: | ||
307 | return -EINVAL; | ||
308 | } | ||
309 | |||
297 | switch (freq) { | 310 | switch (freq) { |
298 | case 11289600: | 311 | case 11289600: |
299 | case 12000000: | 312 | case 12000000: |
@@ -301,9 +314,14 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
301 | case 16934400: | 314 | case 16934400: |
302 | case 18432000: | 315 | case 18432000: |
303 | wm8731->sysclk = freq; | 316 | wm8731->sysclk = freq; |
304 | return 0; | 317 | break; |
318 | default: | ||
319 | return -EINVAL; | ||
305 | } | 320 | } |
306 | return -EINVAL; | 321 | |
322 | snd_soc_dapm_sync(codec); | ||
323 | |||
324 | return 0; | ||
307 | } | 325 | } |
308 | 326 | ||
309 | 327 | ||
@@ -428,8 +446,8 @@ static struct snd_soc_dai_ops wm8731_dai_ops = { | |||
428 | .set_fmt = wm8731_set_dai_fmt, | 446 | .set_fmt = wm8731_set_dai_fmt, |
429 | }; | 447 | }; |
430 | 448 | ||
431 | struct snd_soc_dai wm8731_dai = { | 449 | static struct snd_soc_dai_driver wm8731_dai = { |
432 | .name = "WM8731", | 450 | .name = "wm8731-hifi", |
433 | .playback = { | 451 | .playback = { |
434 | .stream_name = "Playback", | 452 | .stream_name = "Playback", |
435 | .channels_min = 1, | 453 | .channels_min = 1, |
@@ -445,24 +463,17 @@ struct snd_soc_dai wm8731_dai = { | |||
445 | .ops = &wm8731_dai_ops, | 463 | .ops = &wm8731_dai_ops, |
446 | .symmetric_rates = 1, | 464 | .symmetric_rates = 1, |
447 | }; | 465 | }; |
448 | EXPORT_SYMBOL_GPL(wm8731_dai); | ||
449 | 466 | ||
450 | #ifdef CONFIG_PM | 467 | #ifdef CONFIG_PM |
451 | static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) | 468 | static int wm8731_suspend(struct snd_soc_codec *codec, pm_message_t state) |
452 | { | 469 | { |
453 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
454 | struct snd_soc_codec *codec = socdev->card->codec; | ||
455 | |||
456 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); | 470 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); |
457 | 471 | ||
458 | return 0; | 472 | return 0; |
459 | } | 473 | } |
460 | 474 | ||
461 | static int wm8731_resume(struct platform_device *pdev) | 475 | static int wm8731_resume(struct snd_soc_codec *codec) |
462 | { | 476 | { |
463 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
464 | struct snd_soc_codec *codec = socdev->card->codec; | ||
465 | |||
466 | wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 477 | wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
467 | 478 | ||
468 | return 0; | 479 | return 0; |
@@ -472,88 +483,15 @@ static int wm8731_resume(struct platform_device *pdev) | |||
472 | #define wm8731_resume NULL | 483 | #define wm8731_resume NULL |
473 | #endif | 484 | #endif |
474 | 485 | ||
475 | static int wm8731_probe(struct platform_device *pdev) | 486 | static int wm8731_probe(struct snd_soc_codec *codec) |
476 | { | 487 | { |
477 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 488 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
478 | struct snd_soc_codec *codec; | 489 | int ret = 0, i; |
479 | int ret = 0; | ||
480 | |||
481 | if (wm8731_codec == NULL) { | ||
482 | dev_err(&pdev->dev, "Codec device not registered\n"); | ||
483 | return -ENODEV; | ||
484 | } | ||
485 | |||
486 | socdev->card->codec = wm8731_codec; | ||
487 | codec = wm8731_codec; | ||
488 | |||
489 | /* register pcms */ | ||
490 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
491 | if (ret < 0) { | ||
492 | dev_err(codec->dev, "failed to create pcms: %d\n", ret); | ||
493 | goto pcm_err; | ||
494 | } | ||
495 | |||
496 | snd_soc_add_controls(codec, wm8731_snd_controls, | ||
497 | ARRAY_SIZE(wm8731_snd_controls)); | ||
498 | wm8731_add_widgets(codec); | ||
499 | |||
500 | return ret; | ||
501 | |||
502 | pcm_err: | ||
503 | return ret; | ||
504 | } | ||
505 | |||
506 | /* power down chip */ | ||
507 | static int wm8731_remove(struct platform_device *pdev) | ||
508 | { | ||
509 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
510 | |||
511 | snd_soc_free_pcms(socdev); | ||
512 | snd_soc_dapm_free(socdev); | ||
513 | |||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | struct snd_soc_codec_device soc_codec_dev_wm8731 = { | ||
518 | .probe = wm8731_probe, | ||
519 | .remove = wm8731_remove, | ||
520 | .suspend = wm8731_suspend, | ||
521 | .resume = wm8731_resume, | ||
522 | }; | ||
523 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); | ||
524 | |||
525 | static int wm8731_register(struct wm8731_priv *wm8731, | ||
526 | enum snd_soc_control_type control) | ||
527 | { | ||
528 | int ret, i; | ||
529 | struct snd_soc_codec *codec = &wm8731->codec; | ||
530 | |||
531 | if (wm8731_codec) { | ||
532 | dev_err(codec->dev, "Another WM8731 is registered\n"); | ||
533 | ret = -EINVAL; | ||
534 | goto err; | ||
535 | } | ||
536 | |||
537 | mutex_init(&codec->mutex); | ||
538 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
539 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
540 | |||
541 | snd_soc_codec_set_drvdata(codec, wm8731); | ||
542 | codec->name = "WM8731"; | ||
543 | codec->owner = THIS_MODULE; | ||
544 | codec->bias_level = SND_SOC_BIAS_OFF; | ||
545 | codec->set_bias_level = wm8731_set_bias_level; | ||
546 | codec->dai = &wm8731_dai; | ||
547 | codec->num_dai = 1; | ||
548 | codec->reg_cache_size = WM8731_CACHEREGNUM; | ||
549 | codec->reg_cache = &wm8731->reg_cache; | ||
550 | |||
551 | memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg)); | ||
552 | 490 | ||
553 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); | 491 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type); |
554 | if (ret < 0) { | 492 | if (ret < 0) { |
555 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 493 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
556 | goto err; | 494 | return ret; |
557 | } | 495 | } |
558 | 496 | ||
559 | for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) | 497 | for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) |
@@ -563,7 +501,7 @@ static int wm8731_register(struct wm8731_priv *wm8731, | |||
563 | wm8731->supplies); | 501 | wm8731->supplies); |
564 | if (ret != 0) { | 502 | if (ret != 0) { |
565 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | 503 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); |
566 | goto err; | 504 | return ret; |
567 | } | 505 | } |
568 | 506 | ||
569 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), | 507 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), |
@@ -579,8 +517,6 @@ static int wm8731_register(struct wm8731_priv *wm8731, | |||
579 | goto err_regulator_enable; | 517 | goto err_regulator_enable; |
580 | } | 518 | } |
581 | 519 | ||
582 | wm8731_dai.dev = codec->dev; | ||
583 | |||
584 | wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 520 | wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
585 | 521 | ||
586 | /* Latch the update bits */ | 522 | /* Latch the update bits */ |
@@ -592,79 +528,78 @@ static int wm8731_register(struct wm8731_priv *wm8731, | |||
592 | /* Disable bypass path by default */ | 528 | /* Disable bypass path by default */ |
593 | snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0); | 529 | snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0); |
594 | 530 | ||
595 | wm8731_codec = codec; | 531 | snd_soc_add_controls(codec, wm8731_snd_controls, |
596 | 532 | ARRAY_SIZE(wm8731_snd_controls)); | |
597 | ret = snd_soc_register_codec(codec); | 533 | wm8731_add_widgets(codec); |
598 | if (ret != 0) { | ||
599 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | ||
600 | goto err_regulator_enable; | ||
601 | } | ||
602 | |||
603 | ret = snd_soc_register_dai(&wm8731_dai); | ||
604 | if (ret != 0) { | ||
605 | dev_err(codec->dev, "Failed to register DAI: %d\n", ret); | ||
606 | snd_soc_unregister_codec(codec); | ||
607 | goto err_codec; | ||
608 | } | ||
609 | 534 | ||
610 | /* Regulators will have been enabled by bias management */ | 535 | /* Regulators will have been enabled by bias management */ |
611 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | 536 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); |
612 | 537 | ||
613 | return 0; | 538 | return 0; |
614 | 539 | ||
615 | err_codec: | ||
616 | snd_soc_unregister_codec(codec); | ||
617 | err_regulator_enable: | 540 | err_regulator_enable: |
618 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | 541 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); |
619 | err_regulator_get: | 542 | err_regulator_get: |
620 | regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | 543 | regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); |
621 | err: | 544 | |
622 | kfree(wm8731); | 545 | kfree(wm8731); |
623 | return ret; | 546 | return ret; |
624 | } | 547 | } |
625 | 548 | ||
626 | static void wm8731_unregister(struct wm8731_priv *wm8731) | 549 | /* power down chip */ |
550 | static int wm8731_remove(struct snd_soc_codec *codec) | ||
627 | { | 551 | { |
628 | wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); | 552 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
629 | snd_soc_unregister_dai(&wm8731_dai); | 553 | |
630 | snd_soc_unregister_codec(&wm8731->codec); | 554 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); |
555 | |||
556 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | ||
631 | regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | 557 | regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); |
632 | kfree(wm8731); | 558 | |
633 | wm8731_codec = NULL; | 559 | return 0; |
634 | } | 560 | } |
635 | 561 | ||
562 | static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { | ||
563 | .probe = wm8731_probe, | ||
564 | .remove = wm8731_remove, | ||
565 | .suspend = wm8731_suspend, | ||
566 | .resume = wm8731_resume, | ||
567 | .set_bias_level = wm8731_set_bias_level, | ||
568 | .reg_cache_size = ARRAY_SIZE(wm8731_reg), | ||
569 | .reg_word_size = sizeof(u16), | ||
570 | .reg_cache_default = wm8731_reg, | ||
571 | }; | ||
572 | |||
636 | #if defined(CONFIG_SPI_MASTER) | 573 | #if defined(CONFIG_SPI_MASTER) |
637 | static int __devinit wm8731_spi_probe(struct spi_device *spi) | 574 | static int __devinit wm8731_spi_probe(struct spi_device *spi) |
638 | { | 575 | { |
639 | struct snd_soc_codec *codec; | ||
640 | struct wm8731_priv *wm8731; | 576 | struct wm8731_priv *wm8731; |
577 | int ret; | ||
641 | 578 | ||
642 | wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); | 579 | wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); |
643 | if (wm8731 == NULL) | 580 | if (wm8731 == NULL) |
644 | return -ENOMEM; | 581 | return -ENOMEM; |
645 | 582 | ||
646 | codec = &wm8731->codec; | 583 | wm8731->control_type = SND_SOC_SPI; |
647 | codec->control_data = spi; | 584 | spi_set_drvdata(spi, wm8731); |
648 | codec->dev = &spi->dev; | ||
649 | |||
650 | dev_set_drvdata(&spi->dev, wm8731); | ||
651 | 585 | ||
652 | return wm8731_register(wm8731, SND_SOC_SPI); | 586 | ret = snd_soc_register_codec(&spi->dev, |
587 | &soc_codec_dev_wm8731, &wm8731_dai, 1); | ||
588 | if (ret < 0) | ||
589 | kfree(wm8731); | ||
590 | return ret; | ||
653 | } | 591 | } |
654 | 592 | ||
655 | static int __devexit wm8731_spi_remove(struct spi_device *spi) | 593 | static int __devexit wm8731_spi_remove(struct spi_device *spi) |
656 | { | 594 | { |
657 | struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev); | 595 | snd_soc_unregister_codec(&spi->dev); |
658 | 596 | kfree(spi_get_drvdata(spi)); | |
659 | wm8731_unregister(wm8731); | ||
660 | |||
661 | return 0; | 597 | return 0; |
662 | } | 598 | } |
663 | 599 | ||
664 | static struct spi_driver wm8731_spi_driver = { | 600 | static struct spi_driver wm8731_spi_driver = { |
665 | .driver = { | 601 | .driver = { |
666 | .name = "wm8731", | 602 | .name = "wm8731-codec", |
667 | .bus = &spi_bus_type, | ||
668 | .owner = THIS_MODULE, | 603 | .owner = THIS_MODULE, |
669 | }, | 604 | }, |
670 | .probe = wm8731_spi_probe, | 605 | .probe = wm8731_spi_probe, |
@@ -677,26 +612,26 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c, | |||
677 | const struct i2c_device_id *id) | 612 | const struct i2c_device_id *id) |
678 | { | 613 | { |
679 | struct wm8731_priv *wm8731; | 614 | struct wm8731_priv *wm8731; |
680 | struct snd_soc_codec *codec; | 615 | int ret; |
681 | 616 | ||
682 | wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); | 617 | wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL); |
683 | if (wm8731 == NULL) | 618 | if (wm8731 == NULL) |
684 | return -ENOMEM; | 619 | return -ENOMEM; |
685 | 620 | ||
686 | codec = &wm8731->codec; | ||
687 | |||
688 | i2c_set_clientdata(i2c, wm8731); | 621 | i2c_set_clientdata(i2c, wm8731); |
689 | codec->control_data = i2c; | 622 | wm8731->control_type = SND_SOC_I2C; |
690 | |||
691 | codec->dev = &i2c->dev; | ||
692 | 623 | ||
693 | return wm8731_register(wm8731, SND_SOC_I2C); | 624 | ret = snd_soc_register_codec(&i2c->dev, |
625 | &soc_codec_dev_wm8731, &wm8731_dai, 1); | ||
626 | if (ret < 0) | ||
627 | kfree(wm8731); | ||
628 | return ret; | ||
694 | } | 629 | } |
695 | 630 | ||
696 | static __devexit int wm8731_i2c_remove(struct i2c_client *client) | 631 | static __devexit int wm8731_i2c_remove(struct i2c_client *client) |
697 | { | 632 | { |
698 | struct wm8731_priv *wm8731 = i2c_get_clientdata(client); | 633 | snd_soc_unregister_codec(&client->dev); |
699 | wm8731_unregister(wm8731); | 634 | kfree(i2c_get_clientdata(client)); |
700 | return 0; | 635 | return 0; |
701 | } | 636 | } |
702 | 637 | ||
@@ -708,7 +643,7 @@ MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); | |||
708 | 643 | ||
709 | static struct i2c_driver wm8731_i2c_driver = { | 644 | static struct i2c_driver wm8731_i2c_driver = { |
710 | .driver = { | 645 | .driver = { |
711 | .name = "wm8731", | 646 | .name = "wm8731-codec", |
712 | .owner = THIS_MODULE, | 647 | .owner = THIS_MODULE, |
713 | }, | 648 | }, |
714 | .probe = wm8731_i2c_probe, | 649 | .probe = wm8731_i2c_probe, |
@@ -719,7 +654,7 @@ static struct i2c_driver wm8731_i2c_driver = { | |||
719 | 654 | ||
720 | static int __init wm8731_modinit(void) | 655 | static int __init wm8731_modinit(void) |
721 | { | 656 | { |
722 | int ret; | 657 | int ret = 0; |
723 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 658 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
724 | ret = i2c_add_driver(&wm8731_i2c_driver); | 659 | ret = i2c_add_driver(&wm8731_i2c_driver); |
725 | if (ret != 0) { | 660 | if (ret != 0) { |
@@ -734,7 +669,7 @@ static int __init wm8731_modinit(void) | |||
734 | ret); | 669 | ret); |
735 | } | 670 | } |
736 | #endif | 671 | #endif |
737 | return 0; | 672 | return ret; |
738 | } | 673 | } |
739 | module_init(wm8731_modinit); | 674 | module_init(wm8731_modinit); |
740 | 675 | ||