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 ---