wm8737.c (0cce284537fb42d9c28b9b31038ffc9b464555f5) | wm8737.c (840680dcc29e2d9b49aee0f2910e8e22cfdf0709) |
---|---|
1/* 2 * wm8737.c -- WM8737 ALSA SoC Audio driver 3 * 4 * Copyright 2010 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 60 unchanged lines hidden (view full) --- 69 switch (reg) { 70 case WM8737_RESET: 71 return true; 72 default: 73 return false; 74 } 75} 76 | 1/* 2 * wm8737.c -- WM8737 ALSA SoC Audio driver 3 * 4 * Copyright 2010 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 60 unchanged lines hidden (view full) --- 69 switch (reg) { 70 case WM8737_RESET: 71 return true; 72 default: 73 return false; 74 } 75} 76 |
77static int wm8737_reset(struct snd_soc_codec *codec) | 77static int wm8737_reset(struct snd_soc_component *component) |
78{ | 78{ |
79 return snd_soc_write(codec, WM8737_RESET, 0); | 79 return snd_soc_component_write(component, WM8737_RESET, 0); |
80} 81 82static const DECLARE_TLV_DB_RANGE(micboost_tlv, 83 0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0), 84 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0), 85 2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0), 86 3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0) 87); --- 235 unchanged lines hidden (view full) --- 323 { 12000000, 88200, 1, 0x1f }, 324 { 12000000, 96000, 1, 0xe }, 325}; 326 327static int wm8737_hw_params(struct snd_pcm_substream *substream, 328 struct snd_pcm_hw_params *params, 329 struct snd_soc_dai *dai) 330{ | 80} 81 82static const DECLARE_TLV_DB_RANGE(micboost_tlv, 83 0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0), 84 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0), 85 2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0), 86 3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0) 87); --- 235 unchanged lines hidden (view full) --- 323 { 12000000, 88200, 1, 0x1f }, 324 { 12000000, 96000, 1, 0xe }, 325}; 326 327static int wm8737_hw_params(struct snd_pcm_substream *substream, 328 struct snd_pcm_hw_params *params, 329 struct snd_soc_dai *dai) 330{ |
331 struct snd_soc_codec *codec = dai->codec; 332 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); | 331 struct snd_soc_component *component = dai->component; 332 struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component); |
333 int i; 334 u16 clocking = 0; 335 u16 af = 0; 336 337 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 338 if (coeff_div[i].rate != params_rate(params)) 339 continue; 340 341 if (coeff_div[i].mclk == wm8737->mclk) 342 break; 343 344 if (coeff_div[i].mclk == wm8737->mclk * 2) { 345 clocking |= WM8737_CLKDIV2; 346 break; 347 } 348 } 349 350 if (i == ARRAY_SIZE(coeff_div)) { | 333 int i; 334 u16 clocking = 0; 335 u16 af = 0; 336 337 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 338 if (coeff_div[i].rate != params_rate(params)) 339 continue; 340 341 if (coeff_div[i].mclk == wm8737->mclk) 342 break; 343 344 if (coeff_div[i].mclk == wm8737->mclk * 2) { 345 clocking |= WM8737_CLKDIV2; 346 break; 347 } 348 } 349 350 if (i == ARRAY_SIZE(coeff_div)) { |
351 dev_err(codec->dev, "%dHz MCLK can't support %dHz\n", | 351 dev_err(component->dev, "%dHz MCLK can't support %dHz\n", |
352 wm8737->mclk, params_rate(params)); 353 return -EINVAL; 354 } 355 356 clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT); 357 358 switch (params_width(params)) { 359 case 16: --- 6 unchanged lines hidden (view full) --- 366 break; 367 case 32: 368 af |= 0x18; 369 break; 370 default: 371 return -EINVAL; 372 } 373 | 352 wm8737->mclk, params_rate(params)); 353 return -EINVAL; 354 } 355 356 clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT); 357 358 switch (params_width(params)) { 359 case 16: --- 6 unchanged lines hidden (view full) --- 366 break; 367 case 32: 368 af |= 0x18; 369 break; 370 default: 371 return -EINVAL; 372 } 373 |
374 snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af); 375 snd_soc_update_bits(codec, WM8737_CLOCKING, | 374 snd_soc_component_update_bits(component, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af); 375 snd_soc_component_update_bits(component, WM8737_CLOCKING, |
376 WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK, 377 clocking); 378 379 return 0; 380} 381 382static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai, 383 int clk_id, unsigned int freq, int dir) 384{ | 376 WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK, 377 clocking); 378 379 return 0; 380} 381 382static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai, 383 int clk_id, unsigned int freq, int dir) 384{ |
385 struct snd_soc_codec *codec = codec_dai->codec; 386 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); | 385 struct snd_soc_component *component = codec_dai->component; 386 struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component); |
387 int i; 388 389 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 390 if (freq == coeff_div[i].mclk || 391 freq == coeff_div[i].mclk * 2) { 392 wm8737->mclk = freq; 393 return 0; 394 } 395 } 396 | 387 int i; 388 389 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { 390 if (freq == coeff_div[i].mclk || 391 freq == coeff_div[i].mclk * 2) { 392 wm8737->mclk = freq; 393 return 0; 394 } 395 } 396 |
397 dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq); | 397 dev_err(component->dev, "MCLK rate %dHz not supported\n", freq); |
398 399 return -EINVAL; 400} 401 402 403static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai, 404 unsigned int fmt) 405{ | 398 399 return -EINVAL; 400} 401 402 403static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai, 404 unsigned int fmt) 405{ |
406 struct snd_soc_codec *codec = codec_dai->codec; | 406 struct snd_soc_component *component = codec_dai->component; |
407 u16 af = 0; 408 409 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 410 case SND_SOC_DAIFMT_CBM_CFM: 411 af |= WM8737_MS; 412 break; 413 case SND_SOC_DAIFMT_CBS_CFS: 414 break; --- 25 unchanged lines hidden (view full) --- 440 break; 441 case SND_SOC_DAIFMT_NB_IF: 442 af |= WM8737_LRP; 443 break; 444 default: 445 return -EINVAL; 446 } 447 | 407 u16 af = 0; 408 409 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 410 case SND_SOC_DAIFMT_CBM_CFM: 411 af |= WM8737_MS; 412 break; 413 case SND_SOC_DAIFMT_CBS_CFS: 414 break; --- 25 unchanged lines hidden (view full) --- 440 break; 441 case SND_SOC_DAIFMT_NB_IF: 442 af |= WM8737_LRP; 443 break; 444 default: 445 return -EINVAL; 446 } 447 |
448 snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, | 448 snd_soc_component_update_bits(component, WM8737_AUDIO_FORMAT, |
449 WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af); 450 451 return 0; 452} 453 | 449 WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af); 450 451 return 0; 452} 453 |
454static int wm8737_set_bias_level(struct snd_soc_codec *codec, | 454static int wm8737_set_bias_level(struct snd_soc_component *component, |
455 enum snd_soc_bias_level level) 456{ | 455 enum snd_soc_bias_level level) 456{ |
457 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); | 457 struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component); |
458 int ret; 459 460 switch (level) { 461 case SND_SOC_BIAS_ON: 462 break; 463 464 case SND_SOC_BIAS_PREPARE: 465 /* VMID at 2*75k */ | 458 int ret; 459 460 switch (level) { 461 case SND_SOC_BIAS_ON: 462 break; 463 464 case SND_SOC_BIAS_PREPARE: 465 /* VMID at 2*75k */ |
466 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, | 466 snd_soc_component_update_bits(component, WM8737_MISC_BIAS_CONTROL, |
467 WM8737_VMIDSEL_MASK, 0); 468 break; 469 470 case SND_SOC_BIAS_STANDBY: | 467 WM8737_VMIDSEL_MASK, 0); 468 break; 469 470 case SND_SOC_BIAS_STANDBY: |
471 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | 471 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { |
472 ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), 473 wm8737->supplies); 474 if (ret != 0) { | 472 ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), 473 wm8737->supplies); 474 if (ret != 0) { |
475 dev_err(codec->dev, | 475 dev_err(component->dev, |
476 "Failed to enable supplies: %d\n", 477 ret); 478 return ret; 479 } 480 481 regcache_sync(wm8737->regmap); 482 483 /* Fast VMID ramp at 2*2.5k */ | 476 "Failed to enable supplies: %d\n", 477 ret); 478 return ret; 479 } 480 481 regcache_sync(wm8737->regmap); 482 483 /* Fast VMID ramp at 2*2.5k */ |
484 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, | 484 snd_soc_component_update_bits(component, WM8737_MISC_BIAS_CONTROL, |
485 WM8737_VMIDSEL_MASK, 486 2 << WM8737_VMIDSEL_SHIFT); 487 488 /* Bring VMID up */ | 485 WM8737_VMIDSEL_MASK, 486 2 << WM8737_VMIDSEL_SHIFT); 487 488 /* Bring VMID up */ |
489 snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT, | 489 snd_soc_component_update_bits(component, WM8737_POWER_MANAGEMENT, |
490 WM8737_VMID_MASK | 491 WM8737_VREF_MASK, 492 WM8737_VMID_MASK | 493 WM8737_VREF_MASK); 494 495 msleep(500); 496 } 497 498 /* VMID at 2*300k */ | 490 WM8737_VMID_MASK | 491 WM8737_VREF_MASK, 492 WM8737_VMID_MASK | 493 WM8737_VREF_MASK); 494 495 msleep(500); 496 } 497 498 /* VMID at 2*300k */ |
499 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, | 499 snd_soc_component_update_bits(component, WM8737_MISC_BIAS_CONTROL, |
500 WM8737_VMIDSEL_MASK, 501 1 << WM8737_VMIDSEL_SHIFT); 502 503 break; 504 505 case SND_SOC_BIAS_OFF: | 500 WM8737_VMIDSEL_MASK, 501 1 << WM8737_VMIDSEL_SHIFT); 502 503 break; 504 505 case SND_SOC_BIAS_OFF: |
506 snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT, | 506 snd_soc_component_update_bits(component, WM8737_POWER_MANAGEMENT, |
507 WM8737_VMID_MASK | WM8737_VREF_MASK, 0); 508 509 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), 510 wm8737->supplies); 511 break; 512 } 513 514 return 0; --- 17 unchanged lines hidden (view full) --- 532 .channels_min = 2, /* Mono modes not yet supported */ 533 .channels_max = 2, 534 .rates = WM8737_RATES, 535 .formats = WM8737_FORMATS, 536 }, 537 .ops = &wm8737_dai_ops, 538}; 539 | 507 WM8737_VMID_MASK | WM8737_VREF_MASK, 0); 508 509 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), 510 wm8737->supplies); 511 break; 512 } 513 514 return 0; --- 17 unchanged lines hidden (view full) --- 532 .channels_min = 2, /* Mono modes not yet supported */ 533 .channels_max = 2, 534 .rates = WM8737_RATES, 535 .formats = WM8737_FORMATS, 536 }, 537 .ops = &wm8737_dai_ops, 538}; 539 |
540static int wm8737_probe(struct snd_soc_codec *codec) | 540static int wm8737_probe(struct snd_soc_component *component) |
541{ | 541{ |
542 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); | 542 struct wm8737_priv *wm8737 = snd_soc_component_get_drvdata(component); |
543 int ret; 544 545 ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), 546 wm8737->supplies); 547 if (ret != 0) { | 543 int ret; 544 545 ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), 546 wm8737->supplies); 547 if (ret != 0) { |
548 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | 548 dev_err(component->dev, "Failed to enable supplies: %d\n", ret); |
549 goto err_get; 550 } 551 | 549 goto err_get; 550 } 551 |
552 ret = wm8737_reset(codec); | 552 ret = wm8737_reset(component); |
553 if (ret < 0) { | 553 if (ret < 0) { |
554 dev_err(codec->dev, "Failed to issue reset\n"); | 554 dev_err(component->dev, "Failed to issue reset\n"); |
555 goto err_enable; 556 } 557 | 555 goto err_enable; 556 } 557 |
558 snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU, | 558 snd_soc_component_update_bits(component, WM8737_LEFT_PGA_VOLUME, WM8737_LVU, |
559 WM8737_LVU); | 559 WM8737_LVU); |
560 snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU, | 560 snd_soc_component_update_bits(component, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU, |
561 WM8737_RVU); 562 | 561 WM8737_RVU); 562 |
563 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_STANDBY); | 563 snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); |
564 565 /* Bias level configuration will have done an extra enable */ 566 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); 567 568 return 0; 569 570err_enable: 571 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); 572err_get: 573 return ret; 574} 575 | 564 565 /* Bias level configuration will have done an extra enable */ 566 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); 567 568 return 0; 569 570err_enable: 571 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); 572err_get: 573 return ret; 574} 575 |
576static const struct snd_soc_codec_driver soc_codec_dev_wm8737 = { 577 .probe = wm8737_probe, 578 .set_bias_level = wm8737_set_bias_level, 579 .suspend_bias_off = true, 580 581 .component_driver = { 582 .controls = wm8737_snd_controls, 583 .num_controls = ARRAY_SIZE(wm8737_snd_controls), 584 .dapm_widgets = wm8737_dapm_widgets, 585 .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets), 586 .dapm_routes = intercon, 587 .num_dapm_routes = ARRAY_SIZE(intercon), 588 }, | 576static const struct snd_soc_component_driver soc_component_dev_wm8737 = { 577 .probe = wm8737_probe, 578 .set_bias_level = wm8737_set_bias_level, 579 .controls = wm8737_snd_controls, 580 .num_controls = ARRAY_SIZE(wm8737_snd_controls), 581 .dapm_widgets = wm8737_dapm_widgets, 582 .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets), 583 .dapm_routes = intercon, 584 .num_dapm_routes = ARRAY_SIZE(intercon), 585 .suspend_bias_off = 1, 586 .idle_bias_on = 1, 587 .use_pmdown_time = 1, 588 .endianness = 1, 589 .non_legacy_dai_naming = 1, |
589}; 590 591static const struct of_device_id wm8737_of_match[] = { 592 { .compatible = "wlf,wm8737", }, 593 { } 594}; 595 596MODULE_DEVICE_TABLE(of, wm8737_of_match); --- 33 unchanged lines hidden (view full) --- 630 } 631 632 wm8737->regmap = devm_regmap_init_i2c(i2c, &wm8737_regmap); 633 if (IS_ERR(wm8737->regmap)) 634 return PTR_ERR(wm8737->regmap); 635 636 i2c_set_clientdata(i2c, wm8737); 637 | 590}; 591 592static const struct of_device_id wm8737_of_match[] = { 593 { .compatible = "wlf,wm8737", }, 594 { } 595}; 596 597MODULE_DEVICE_TABLE(of, wm8737_of_match); --- 33 unchanged lines hidden (view full) --- 631 } 632 633 wm8737->regmap = devm_regmap_init_i2c(i2c, &wm8737_regmap); 634 if (IS_ERR(wm8737->regmap)) 635 return PTR_ERR(wm8737->regmap); 636 637 i2c_set_clientdata(i2c, wm8737); 638 |
638 ret = snd_soc_register_codec(&i2c->dev, 639 &soc_codec_dev_wm8737, &wm8737_dai, 1); | 639 ret = devm_snd_soc_register_component(&i2c->dev, 640 &soc_component_dev_wm8737, &wm8737_dai, 1); |
640 641 return ret; 642 643} 644 | 641 642 return ret; 643 644} 645 |
645static int wm8737_i2c_remove(struct i2c_client *client) 646{ 647 snd_soc_unregister_codec(&client->dev); 648 649 return 0; 650} 651 | |
652static const struct i2c_device_id wm8737_i2c_id[] = { 653 { "wm8737", 0 }, 654 { } 655}; 656MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id); 657 658static struct i2c_driver wm8737_i2c_driver = { 659 .driver = { 660 .name = "wm8737", 661 .of_match_table = wm8737_of_match, 662 }, 663 .probe = wm8737_i2c_probe, | 646static const struct i2c_device_id wm8737_i2c_id[] = { 647 { "wm8737", 0 }, 648 { } 649}; 650MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id); 651 652static struct i2c_driver wm8737_i2c_driver = { 653 .driver = { 654 .name = "wm8737", 655 .of_match_table = wm8737_of_match, 656 }, 657 .probe = wm8737_i2c_probe, |
664 .remove = wm8737_i2c_remove, | |
665 .id_table = wm8737_i2c_id, 666}; 667#endif 668 669#if defined(CONFIG_SPI_MASTER) 670static int wm8737_spi_probe(struct spi_device *spi) 671{ 672 struct wm8737_priv *wm8737; --- 15 unchanged lines hidden (view full) --- 688 } 689 690 wm8737->regmap = devm_regmap_init_spi(spi, &wm8737_regmap); 691 if (IS_ERR(wm8737->regmap)) 692 return PTR_ERR(wm8737->regmap); 693 694 spi_set_drvdata(spi, wm8737); 695 | 658 .id_table = wm8737_i2c_id, 659}; 660#endif 661 662#if defined(CONFIG_SPI_MASTER) 663static int wm8737_spi_probe(struct spi_device *spi) 664{ 665 struct wm8737_priv *wm8737; --- 15 unchanged lines hidden (view full) --- 681 } 682 683 wm8737->regmap = devm_regmap_init_spi(spi, &wm8737_regmap); 684 if (IS_ERR(wm8737->regmap)) 685 return PTR_ERR(wm8737->regmap); 686 687 spi_set_drvdata(spi, wm8737); 688 |
696 ret = snd_soc_register_codec(&spi->dev, 697 &soc_codec_dev_wm8737, &wm8737_dai, 1); | 689 ret = devm_snd_soc_register_component(&spi->dev, 690 &soc_component_dev_wm8737, &wm8737_dai, 1); |
698 699 return ret; 700} 701 | 691 692 return ret; 693} 694 |
702static int wm8737_spi_remove(struct spi_device *spi) 703{ 704 snd_soc_unregister_codec(&spi->dev); 705 706 return 0; 707} 708 | |
709static struct spi_driver wm8737_spi_driver = { 710 .driver = { 711 .name = "wm8737", 712 .of_match_table = wm8737_of_match, 713 }, 714 .probe = wm8737_spi_probe, | 695static struct spi_driver wm8737_spi_driver = { 696 .driver = { 697 .name = "wm8737", 698 .of_match_table = wm8737_of_match, 699 }, 700 .probe = wm8737_spi_probe, |
715 .remove = wm8737_spi_remove, | |
716}; 717#endif /* CONFIG_SPI_MASTER */ 718 719static int __init wm8737_modinit(void) 720{ 721 int ret; 722#if IS_ENABLED(CONFIG_I2C) 723 ret = i2c_add_driver(&wm8737_i2c_driver); --- 30 unchanged lines hidden --- | 701}; 702#endif /* CONFIG_SPI_MASTER */ 703 704static int __init wm8737_modinit(void) 705{ 706 int ret; 707#if IS_ENABLED(CONFIG_I2C) 708 ret = i2c_add_driver(&wm8737_i2c_driver); --- 30 unchanged lines hidden --- |