|
23 | 23 | #include <linux/soundwire/sdw.h>
|
24 | 24 | #include <linux/types.h>
|
25 | 25 | #include <linux/workqueue.h>
|
| 26 | +#include <sound/cs-amp-lib.h> |
26 | 27 | #include <sound/pcm.h>
|
27 | 28 | #include <sound/pcm_params.h>
|
28 | 29 | #include <sound/soc.h>
|
@@ -802,16 +803,44 @@ static struct snd_soc_dai_driver cs35l56_dai[] = {
|
802 | 803 | }
|
803 | 804 | };
|
804 | 805 |
|
| 806 | +static int cs35l56_write_cal(struct cs35l56_private *cs35l56) |
| 807 | +{ |
| 808 | + int ret; |
| 809 | + |
| 810 | + if (cs35l56->base.secured || !cs35l56->base.cal_data_valid) |
| 811 | + return -ENODATA; |
| 812 | + |
| 813 | + ret = wm_adsp_run(&cs35l56->dsp); |
| 814 | + if (ret) |
| 815 | + return ret; |
| 816 | + |
| 817 | + ret = cs_amp_write_cal_coeffs(&cs35l56->dsp.cs_dsp, |
| 818 | + &cs35l56_calibration_controls, |
| 819 | + &cs35l56->base.cal_data); |
| 820 | + |
| 821 | + wm_adsp_stop(&cs35l56->dsp); |
| 822 | + |
| 823 | + if (ret == 0) |
| 824 | + dev_info(cs35l56->base.dev, "Calibration applied\n"); |
| 825 | + |
| 826 | + return ret; |
| 827 | +} |
| 828 | + |
805 | 829 | static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56)
|
806 | 830 | {
|
807 | 831 | int ret;
|
808 | 832 |
|
809 | 833 | /* Use wm_adsp to load and apply the firmware patch and coefficient files */
|
810 | 834 | ret = wm_adsp_power_up(&cs35l56->dsp, true);
|
811 |
| - if (ret) |
| 835 | + if (ret) { |
812 | 836 | dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret);
|
813 |
| - else |
814 |
| - cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); |
| 837 | + return; |
| 838 | + } |
| 839 | + |
| 840 | + cs35l56_write_cal(cs35l56); |
| 841 | + |
| 842 | + /* Always REINIT after applying patch or coefficients */ |
| 843 | + cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); |
815 | 844 | }
|
816 | 845 |
|
817 | 846 | static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing)
|
@@ -874,6 +903,9 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing
|
874 | 903 | CS35L56_FIRMWARE_MISSING);
|
875 | 904 | cs35l56->base.fw_patched = true;
|
876 | 905 |
|
| 906 | + if (cs35l56_write_cal(cs35l56) == 0) |
| 907 | + cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT); |
| 908 | + |
877 | 909 | err_unlock:
|
878 | 910 | mutex_unlock(&cs35l56->base.irq_lock);
|
879 | 911 | err:
|
@@ -1356,6 +1388,7 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
|
1356 | 1388 |
|
1357 | 1389 | init_completion(&cs35l56->init_completion);
|
1358 | 1390 | mutex_init(&cs35l56->base.irq_lock);
|
| 1391 | + cs35l56->base.cal_index = -1; |
1359 | 1392 | cs35l56->speaker_id = -ENOENT;
|
1360 | 1393 |
|
1361 | 1394 | dev_set_drvdata(cs35l56->base.dev, cs35l56);
|
@@ -1457,6 +1490,10 @@ int cs35l56_init(struct cs35l56_private *cs35l56)
|
1457 | 1490 | if (ret)
|
1458 | 1491 | return ret;
|
1459 | 1492 |
|
| 1493 | + ret = cs35l56_get_calibration(&cs35l56->base); |
| 1494 | + if (ret) |
| 1495 | + return ret; |
| 1496 | + |
1460 | 1497 | if (!cs35l56->base.reset_gpio) {
|
1461 | 1498 | dev_dbg(cs35l56->base.dev, "No reset gpio: using soft reset\n");
|
1462 | 1499 | cs35l56->soft_resetting = true;
|
@@ -1541,6 +1578,7 @@ EXPORT_NS_GPL_DEV_PM_OPS(cs35l56_pm_ops_i2c_spi, SND_SOC_CS35L56_CORE) = {
|
1541 | 1578 |
|
1542 | 1579 | MODULE_DESCRIPTION("ASoC CS35L56 driver");
|
1543 | 1580 | MODULE_IMPORT_NS(SND_SOC_CS35L56_SHARED);
|
| 1581 | +MODULE_IMPORT_NS(SND_SOC_CS_AMP_LIB); |
1544 | 1582 | MODULE_AUTHOR( "Richard Fitzgerald <[email protected]>");
|
1545 | 1583 | MODULE_AUTHOR( "Simon Trimmer <[email protected]>");
|
1546 | 1584 | MODULE_LICENSE("GPL");
|
0 commit comments