.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * da7219.c - DA7219 ALSA SoC Codec Driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (c) 2015 Dialog Semiconductor |
---|
5 | 6 | * |
---|
6 | 7 | * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com> |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify it |
---|
9 | | - * under the terms of the GNU General Public License as published by the |
---|
10 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
11 | | - * option) any later version. |
---|
12 | 8 | */ |
---|
13 | 9 | |
---|
14 | 10 | #include <linux/acpi.h> |
---|
.. | .. |
---|
317 | 313 | u8 mic_ctrl, mixin_ctrl, adc_ctrl, calib_ctrl; |
---|
318 | 314 | |
---|
319 | 315 | /* Save current state of mic control register */ |
---|
320 | | - mic_ctrl = snd_soc_component_read32(component, DA7219_MIC_1_CTRL); |
---|
| 316 | + mic_ctrl = snd_soc_component_read(component, DA7219_MIC_1_CTRL); |
---|
321 | 317 | |
---|
322 | 318 | /* Save current state of input mixer control register */ |
---|
323 | | - mixin_ctrl = snd_soc_component_read32(component, DA7219_MIXIN_L_CTRL); |
---|
| 319 | + mixin_ctrl = snd_soc_component_read(component, DA7219_MIXIN_L_CTRL); |
---|
324 | 320 | |
---|
325 | 321 | /* Save current state of input ADC control register */ |
---|
326 | | - adc_ctrl = snd_soc_component_read32(component, DA7219_ADC_L_CTRL); |
---|
| 322 | + adc_ctrl = snd_soc_component_read(component, DA7219_ADC_L_CTRL); |
---|
327 | 323 | |
---|
328 | 324 | /* Enable then Mute MIC PGAs */ |
---|
329 | 325 | snd_soc_component_update_bits(component, DA7219_MIC_1_CTRL, DA7219_MIC_1_AMP_EN_MASK, |
---|
.. | .. |
---|
348 | 344 | DA7219_ALC_AUTO_CALIB_EN_MASK, |
---|
349 | 345 | DA7219_ALC_AUTO_CALIB_EN_MASK); |
---|
350 | 346 | do { |
---|
351 | | - calib_ctrl = snd_soc_component_read32(component, DA7219_ALC_CTRL1); |
---|
| 347 | + calib_ctrl = snd_soc_component_read(component, DA7219_ALC_CTRL1); |
---|
352 | 348 | } while (calib_ctrl & DA7219_ALC_AUTO_CALIB_EN_MASK); |
---|
353 | 349 | |
---|
354 | 350 | /* If auto calibration fails, disable DC offset, hybrid ALC */ |
---|
.. | .. |
---|
423 | 419 | struct soc_mixer_control *mixer_ctrl = |
---|
424 | 420 | (struct soc_mixer_control *) kcontrol->private_value; |
---|
425 | 421 | unsigned int reg = mixer_ctrl->reg; |
---|
426 | | - u16 val; |
---|
| 422 | + __le16 val; |
---|
427 | 423 | int ret; |
---|
428 | 424 | |
---|
429 | 425 | mutex_lock(&da7219->ctrl_lock); |
---|
.. | .. |
---|
450 | 446 | struct soc_mixer_control *mixer_ctrl = |
---|
451 | 447 | (struct soc_mixer_control *) kcontrol->private_value; |
---|
452 | 448 | unsigned int reg = mixer_ctrl->reg; |
---|
453 | | - u16 val; |
---|
| 449 | + __le16 val_new, val_old; |
---|
454 | 450 | int ret; |
---|
455 | 451 | |
---|
456 | 452 | /* |
---|
.. | .. |
---|
458 | 454 | * Therefore we need to convert to little endian here to align with |
---|
459 | 455 | * HW registers. |
---|
460 | 456 | */ |
---|
461 | | - val = cpu_to_le16(ucontrol->value.integer.value[0]); |
---|
| 457 | + val_new = cpu_to_le16(ucontrol->value.integer.value[0]); |
---|
462 | 458 | |
---|
463 | 459 | mutex_lock(&da7219->ctrl_lock); |
---|
464 | | - ret = regmap_raw_write(da7219->regmap, reg, &val, sizeof(val)); |
---|
| 460 | + ret = regmap_raw_read(da7219->regmap, reg, &val_old, sizeof(val_old)); |
---|
| 461 | + if (ret == 0 && (val_old != val_new)) |
---|
| 462 | + ret = regmap_raw_write(da7219->regmap, reg, |
---|
| 463 | + &val_new, sizeof(val_new)); |
---|
465 | 464 | mutex_unlock(&da7219->ctrl_lock); |
---|
466 | 465 | |
---|
467 | | - return ret; |
---|
| 466 | + if (ret < 0) |
---|
| 467 | + return ret; |
---|
| 468 | + |
---|
| 469 | + return val_old != val_new; |
---|
468 | 470 | } |
---|
469 | 471 | |
---|
470 | 472 | |
---|
.. | .. |
---|
797 | 799 | { |
---|
798 | 800 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
---|
799 | 801 | struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
| 802 | + struct clk *bclk = da7219->dai_clks[DA7219_DAI_BCLK_IDX]; |
---|
800 | 803 | u8 pll_ctrl, pll_status; |
---|
801 | 804 | int i = 0, ret; |
---|
802 | 805 | bool srm_lock = false; |
---|
.. | .. |
---|
805 | 808 | case SND_SOC_DAPM_PRE_PMU: |
---|
806 | 809 | if (da7219->master) { |
---|
807 | 810 | /* Enable DAI clks for master mode */ |
---|
808 | | - if (da7219->dai_clks) { |
---|
809 | | - ret = clk_prepare_enable(da7219->dai_clks); |
---|
| 811 | + if (bclk) { |
---|
| 812 | + ret = clk_prepare_enable(bclk); |
---|
810 | 813 | if (ret) { |
---|
811 | 814 | dev_err(component->dev, |
---|
812 | | - "Failed to enable dai_clks\n"); |
---|
| 815 | + "Failed to enable DAI clks\n"); |
---|
813 | 816 | return ret; |
---|
814 | 817 | } |
---|
815 | 818 | } else { |
---|
.. | .. |
---|
825 | 828 | DA7219_PC_FREERUN_MASK, 0); |
---|
826 | 829 | |
---|
827 | 830 | /* Slave mode, if SRM not enabled no need for status checks */ |
---|
828 | | - pll_ctrl = snd_soc_component_read32(component, DA7219_PLL_CTRL); |
---|
| 831 | + pll_ctrl = snd_soc_component_read(component, DA7219_PLL_CTRL); |
---|
829 | 832 | if ((pll_ctrl & DA7219_PLL_MODE_MASK) != DA7219_PLL_MODE_SRM) |
---|
830 | 833 | return 0; |
---|
831 | 834 | |
---|
832 | 835 | /* Check SRM has locked */ |
---|
833 | 836 | do { |
---|
834 | | - pll_status = snd_soc_component_read32(component, DA7219_PLL_SRM_STS); |
---|
| 837 | + pll_status = snd_soc_component_read(component, DA7219_PLL_SRM_STS); |
---|
835 | 838 | if (pll_status & DA7219_PLL_SRM_STS_SRM_LOCK) { |
---|
836 | 839 | srm_lock = true; |
---|
837 | 840 | } else { |
---|
838 | 841 | ++i; |
---|
839 | 842 | msleep(50); |
---|
840 | 843 | } |
---|
841 | | - } while ((i < DA7219_SRM_CHECK_RETRIES) & (!srm_lock)); |
---|
| 844 | + } while ((i < DA7219_SRM_CHECK_RETRIES) && (!srm_lock)); |
---|
842 | 845 | |
---|
843 | 846 | if (!srm_lock) |
---|
844 | 847 | dev_warn(component->dev, "SRM failed to lock\n"); |
---|
.. | .. |
---|
852 | 855 | |
---|
853 | 856 | /* Disable DAI clks if in master mode */ |
---|
854 | 857 | if (da7219->master) { |
---|
855 | | - if (da7219->dai_clks) |
---|
856 | | - clk_disable_unprepare(da7219->dai_clks); |
---|
| 858 | + if (bclk) |
---|
| 859 | + clk_disable_unprepare(bclk); |
---|
857 | 860 | else |
---|
858 | 861 | snd_soc_component_update_bits(component, |
---|
859 | 862 | DA7219_DAI_CLK_MODE, |
---|
.. | .. |
---|
931 | 934 | case SND_SOC_DAPM_PRE_PMD: |
---|
932 | 935 | /* Ensure nominal gain ramping for DAPM sequence */ |
---|
933 | 936 | da7219->gain_ramp_ctrl = |
---|
934 | | - snd_soc_component_read32(component, DA7219_GAIN_RAMP_CTRL); |
---|
| 937 | + snd_soc_component_read(component, DA7219_GAIN_RAMP_CTRL); |
---|
935 | 938 | snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, |
---|
936 | 939 | DA7219_GAIN_RAMP_RATE_NOMINAL); |
---|
937 | 940 | break; |
---|
.. | .. |
---|
1376 | 1379 | return -EINVAL; |
---|
1377 | 1380 | } |
---|
1378 | 1381 | |
---|
1379 | | - /* By default 64 BCLKs per WCLK is supported */ |
---|
1380 | | - dai_clk_mode |= DA7219_DAI_BCLKS_PER_WCLK_64; |
---|
1381 | | - |
---|
1382 | 1382 | snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, |
---|
1383 | | - DA7219_DAI_BCLKS_PER_WCLK_MASK | |
---|
1384 | 1383 | DA7219_DAI_CLK_POL_MASK | DA7219_DAI_WCLK_POL_MASK, |
---|
1385 | 1384 | dai_clk_mode); |
---|
1386 | 1385 | snd_soc_component_update_bits(component, DA7219_DAI_CTRL, DA7219_DAI_FORMAT_MASK, |
---|
1387 | 1386 | dai_ctrl); |
---|
| 1387 | + |
---|
| 1388 | + return 0; |
---|
| 1389 | +} |
---|
| 1390 | + |
---|
| 1391 | +static int da7219_set_bclks_per_wclk(struct snd_soc_component *component, |
---|
| 1392 | + unsigned long factor) |
---|
| 1393 | +{ |
---|
| 1394 | + u8 bclks_per_wclk; |
---|
| 1395 | + |
---|
| 1396 | + switch (factor) { |
---|
| 1397 | + case 32: |
---|
| 1398 | + bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32; |
---|
| 1399 | + break; |
---|
| 1400 | + case 64: |
---|
| 1401 | + bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64; |
---|
| 1402 | + break; |
---|
| 1403 | + case 128: |
---|
| 1404 | + bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_128; |
---|
| 1405 | + break; |
---|
| 1406 | + case 256: |
---|
| 1407 | + bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256; |
---|
| 1408 | + break; |
---|
| 1409 | + default: |
---|
| 1410 | + return -EINVAL; |
---|
| 1411 | + } |
---|
| 1412 | + |
---|
| 1413 | + snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, |
---|
| 1414 | + DA7219_DAI_BCLKS_PER_WCLK_MASK, |
---|
| 1415 | + bclks_per_wclk); |
---|
1388 | 1416 | |
---|
1389 | 1417 | return 0; |
---|
1390 | 1418 | } |
---|
.. | .. |
---|
1395 | 1423 | { |
---|
1396 | 1424 | struct snd_soc_component *component = dai->component; |
---|
1397 | 1425 | struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
1398 | | - u8 dai_bclks_per_wclk; |
---|
| 1426 | + struct clk *wclk = da7219->dai_clks[DA7219_DAI_WCLK_IDX]; |
---|
| 1427 | + struct clk *bclk = da7219->dai_clks[DA7219_DAI_BCLK_IDX]; |
---|
| 1428 | + unsigned int ch_mask; |
---|
| 1429 | + unsigned long sr, bclk_rate; |
---|
| 1430 | + u8 slot_offset; |
---|
1399 | 1431 | u16 offset; |
---|
| 1432 | + __le16 dai_offset; |
---|
1400 | 1433 | u32 frame_size; |
---|
| 1434 | + int ret; |
---|
1401 | 1435 | |
---|
1402 | | - /* No channels enabled so disable TDM, revert to 64-bit frames */ |
---|
| 1436 | + /* No channels enabled so disable TDM */ |
---|
1403 | 1437 | if (!tx_mask) { |
---|
1404 | 1438 | snd_soc_component_update_bits(component, DA7219_DAI_TDM_CTRL, |
---|
1405 | 1439 | DA7219_DAI_TDM_CH_EN_MASK | |
---|
1406 | 1440 | DA7219_DAI_TDM_MODE_EN_MASK, 0); |
---|
1407 | | - snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, |
---|
1408 | | - DA7219_DAI_BCLKS_PER_WCLK_MASK, |
---|
1409 | | - DA7219_DAI_BCLKS_PER_WCLK_64); |
---|
| 1441 | + da7219->tdm_en = false; |
---|
1410 | 1442 | return 0; |
---|
1411 | 1443 | } |
---|
1412 | 1444 | |
---|
1413 | 1445 | /* Check we have valid slots */ |
---|
1414 | | - if (fls(tx_mask) > DA7219_DAI_TDM_MAX_SLOTS) { |
---|
1415 | | - dev_err(component->dev, "Invalid number of slots, max = %d\n", |
---|
| 1446 | + slot_offset = ffs(tx_mask) - 1; |
---|
| 1447 | + ch_mask = (tx_mask >> slot_offset); |
---|
| 1448 | + if (fls(ch_mask) > DA7219_DAI_TDM_MAX_SLOTS) { |
---|
| 1449 | + dev_err(component->dev, |
---|
| 1450 | + "Invalid number of slots, max = %d\n", |
---|
1416 | 1451 | DA7219_DAI_TDM_MAX_SLOTS); |
---|
1417 | 1452 | return -EINVAL; |
---|
1418 | 1453 | } |
---|
1419 | 1454 | |
---|
1420 | | - /* Check we have a valid offset given */ |
---|
1421 | | - if (rx_mask > DA7219_DAI_OFFSET_MAX) { |
---|
1422 | | - dev_err(component->dev, "Invalid slot offset, max = %d\n", |
---|
1423 | | - DA7219_DAI_OFFSET_MAX); |
---|
| 1455 | + /* |
---|
| 1456 | + * Ensure we have a valid offset into the frame, based on slot width |
---|
| 1457 | + * and slot offset of first slot we're interested in. |
---|
| 1458 | + */ |
---|
| 1459 | + offset = slot_offset * slot_width; |
---|
| 1460 | + if (offset > DA7219_DAI_OFFSET_MAX) { |
---|
| 1461 | + dev_err(component->dev, "Invalid frame offset %d\n", offset); |
---|
1424 | 1462 | return -EINVAL; |
---|
1425 | 1463 | } |
---|
1426 | 1464 | |
---|
1427 | | - /* Calculate & validate frame size based on slot info provided. */ |
---|
1428 | | - frame_size = slots * slot_width; |
---|
1429 | | - switch (frame_size) { |
---|
1430 | | - case 32: |
---|
1431 | | - dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_32; |
---|
1432 | | - break; |
---|
1433 | | - case 64: |
---|
1434 | | - dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_64; |
---|
1435 | | - break; |
---|
1436 | | - case 128: |
---|
1437 | | - dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_128; |
---|
1438 | | - break; |
---|
1439 | | - case 256: |
---|
1440 | | - dai_bclks_per_wclk = DA7219_DAI_BCLKS_PER_WCLK_256; |
---|
1441 | | - break; |
---|
1442 | | - default: |
---|
1443 | | - dev_err(component->dev, "Invalid frame size %d\n", frame_size); |
---|
1444 | | - return -EINVAL; |
---|
| 1465 | + /* |
---|
| 1466 | + * If we're master, calculate & validate frame size based on slot info |
---|
| 1467 | + * provided as we have a limited set of rates available. |
---|
| 1468 | + */ |
---|
| 1469 | + if (da7219->master) { |
---|
| 1470 | + frame_size = slots * slot_width; |
---|
| 1471 | + |
---|
| 1472 | + if (bclk) { |
---|
| 1473 | + sr = clk_get_rate(wclk); |
---|
| 1474 | + bclk_rate = sr * frame_size; |
---|
| 1475 | + ret = clk_set_rate(bclk, bclk_rate); |
---|
| 1476 | + if (ret) { |
---|
| 1477 | + dev_err(component->dev, |
---|
| 1478 | + "Failed to set TDM BCLK rate %lu: %d\n", |
---|
| 1479 | + bclk_rate, ret); |
---|
| 1480 | + return ret; |
---|
| 1481 | + } |
---|
| 1482 | + } else { |
---|
| 1483 | + ret = da7219_set_bclks_per_wclk(component, frame_size); |
---|
| 1484 | + if (ret) { |
---|
| 1485 | + dev_err(component->dev, |
---|
| 1486 | + "Failed to set TDM BCLKs per WCLK %d: %d\n", |
---|
| 1487 | + frame_size, ret); |
---|
| 1488 | + return ret; |
---|
| 1489 | + } |
---|
| 1490 | + } |
---|
1445 | 1491 | } |
---|
1446 | 1492 | |
---|
1447 | | - snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, |
---|
1448 | | - DA7219_DAI_BCLKS_PER_WCLK_MASK, |
---|
1449 | | - dai_bclks_per_wclk); |
---|
1450 | | - |
---|
1451 | | - offset = cpu_to_le16(rx_mask); |
---|
| 1493 | + dai_offset = cpu_to_le16(offset); |
---|
1452 | 1494 | regmap_bulk_write(da7219->regmap, DA7219_DAI_OFFSET_LOWER, |
---|
1453 | | - &offset, sizeof(offset)); |
---|
| 1495 | + &dai_offset, sizeof(dai_offset)); |
---|
1454 | 1496 | |
---|
1455 | 1497 | snd_soc_component_update_bits(component, DA7219_DAI_TDM_CTRL, |
---|
1456 | 1498 | DA7219_DAI_TDM_CH_EN_MASK | |
---|
1457 | 1499 | DA7219_DAI_TDM_MODE_EN_MASK, |
---|
1458 | | - (tx_mask << DA7219_DAI_TDM_CH_EN_SHIFT) | |
---|
| 1500 | + (ch_mask << DA7219_DAI_TDM_CH_EN_SHIFT) | |
---|
1459 | 1501 | DA7219_DAI_TDM_MODE_EN_MASK); |
---|
| 1502 | + |
---|
| 1503 | + da7219->tdm_en = true; |
---|
1460 | 1504 | |
---|
1461 | 1505 | return 0; |
---|
1462 | 1506 | } |
---|
1463 | 1507 | |
---|
1464 | | -static int da7219_hw_params(struct snd_pcm_substream *substream, |
---|
1465 | | - struct snd_pcm_hw_params *params, |
---|
1466 | | - struct snd_soc_dai *dai) |
---|
| 1508 | +static int da7219_set_sr(struct snd_soc_component *component, |
---|
| 1509 | + unsigned long rate) |
---|
1467 | 1510 | { |
---|
1468 | | - struct snd_soc_component *component = dai->component; |
---|
1469 | | - u8 dai_ctrl = 0, fs; |
---|
1470 | | - unsigned int channels; |
---|
| 1511 | + u8 fs; |
---|
1471 | 1512 | |
---|
1472 | | - switch (params_width(params)) { |
---|
1473 | | - case 16: |
---|
1474 | | - dai_ctrl |= DA7219_DAI_WORD_LENGTH_S16_LE; |
---|
1475 | | - break; |
---|
1476 | | - case 20: |
---|
1477 | | - dai_ctrl |= DA7219_DAI_WORD_LENGTH_S20_LE; |
---|
1478 | | - break; |
---|
1479 | | - case 24: |
---|
1480 | | - dai_ctrl |= DA7219_DAI_WORD_LENGTH_S24_LE; |
---|
1481 | | - break; |
---|
1482 | | - case 32: |
---|
1483 | | - dai_ctrl |= DA7219_DAI_WORD_LENGTH_S32_LE; |
---|
1484 | | - break; |
---|
1485 | | - default: |
---|
1486 | | - return -EINVAL; |
---|
1487 | | - } |
---|
1488 | | - |
---|
1489 | | - channels = params_channels(params); |
---|
1490 | | - if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) { |
---|
1491 | | - dev_err(component->dev, |
---|
1492 | | - "Invalid number of channels, only 1 to %d supported\n", |
---|
1493 | | - DA7219_DAI_CH_NUM_MAX); |
---|
1494 | | - return -EINVAL; |
---|
1495 | | - } |
---|
1496 | | - dai_ctrl |= channels << DA7219_DAI_CH_NUM_SHIFT; |
---|
1497 | | - |
---|
1498 | | - switch (params_rate(params)) { |
---|
| 1513 | + switch (rate) { |
---|
1499 | 1514 | case 8000: |
---|
1500 | 1515 | fs = DA7219_SR_8000; |
---|
1501 | 1516 | break; |
---|
.. | .. |
---|
1533 | 1548 | return -EINVAL; |
---|
1534 | 1549 | } |
---|
1535 | 1550 | |
---|
| 1551 | + snd_soc_component_write(component, DA7219_SR, fs); |
---|
| 1552 | + |
---|
| 1553 | + return 0; |
---|
| 1554 | +} |
---|
| 1555 | + |
---|
| 1556 | +static int da7219_hw_params(struct snd_pcm_substream *substream, |
---|
| 1557 | + struct snd_pcm_hw_params *params, |
---|
| 1558 | + struct snd_soc_dai *dai) |
---|
| 1559 | +{ |
---|
| 1560 | + struct snd_soc_component *component = dai->component; |
---|
| 1561 | + struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
| 1562 | + struct clk *wclk = da7219->dai_clks[DA7219_DAI_WCLK_IDX]; |
---|
| 1563 | + struct clk *bclk = da7219->dai_clks[DA7219_DAI_BCLK_IDX]; |
---|
| 1564 | + u8 dai_ctrl = 0; |
---|
| 1565 | + unsigned int channels; |
---|
| 1566 | + unsigned long sr, bclk_rate; |
---|
| 1567 | + int word_len = params_width(params); |
---|
| 1568 | + int frame_size, ret; |
---|
| 1569 | + |
---|
| 1570 | + switch (word_len) { |
---|
| 1571 | + case 16: |
---|
| 1572 | + dai_ctrl |= DA7219_DAI_WORD_LENGTH_S16_LE; |
---|
| 1573 | + break; |
---|
| 1574 | + case 20: |
---|
| 1575 | + dai_ctrl |= DA7219_DAI_WORD_LENGTH_S20_LE; |
---|
| 1576 | + break; |
---|
| 1577 | + case 24: |
---|
| 1578 | + dai_ctrl |= DA7219_DAI_WORD_LENGTH_S24_LE; |
---|
| 1579 | + break; |
---|
| 1580 | + case 32: |
---|
| 1581 | + dai_ctrl |= DA7219_DAI_WORD_LENGTH_S32_LE; |
---|
| 1582 | + break; |
---|
| 1583 | + default: |
---|
| 1584 | + return -EINVAL; |
---|
| 1585 | + } |
---|
| 1586 | + |
---|
| 1587 | + channels = params_channels(params); |
---|
| 1588 | + if ((channels < 1) || (channels > DA7219_DAI_CH_NUM_MAX)) { |
---|
| 1589 | + dev_err(component->dev, |
---|
| 1590 | + "Invalid number of channels, only 1 to %d supported\n", |
---|
| 1591 | + DA7219_DAI_CH_NUM_MAX); |
---|
| 1592 | + return -EINVAL; |
---|
| 1593 | + } |
---|
| 1594 | + dai_ctrl |= channels << DA7219_DAI_CH_NUM_SHIFT; |
---|
| 1595 | + |
---|
| 1596 | + sr = params_rate(params); |
---|
| 1597 | + if (da7219->master && wclk) { |
---|
| 1598 | + ret = clk_set_rate(wclk, sr); |
---|
| 1599 | + if (ret) { |
---|
| 1600 | + dev_err(component->dev, |
---|
| 1601 | + "Failed to set WCLK SR %lu: %d\n", sr, ret); |
---|
| 1602 | + return ret; |
---|
| 1603 | + } |
---|
| 1604 | + } else { |
---|
| 1605 | + ret = da7219_set_sr(component, sr); |
---|
| 1606 | + if (ret) { |
---|
| 1607 | + dev_err(component->dev, |
---|
| 1608 | + "Failed to set SR %lu: %d\n", sr, ret); |
---|
| 1609 | + return ret; |
---|
| 1610 | + } |
---|
| 1611 | + } |
---|
| 1612 | + |
---|
| 1613 | + /* |
---|
| 1614 | + * If we're master, then we have a limited set of BCLK rates we |
---|
| 1615 | + * support. For slave mode this isn't the case and the codec can detect |
---|
| 1616 | + * the BCLK rate automatically. |
---|
| 1617 | + */ |
---|
| 1618 | + if (da7219->master && !da7219->tdm_en) { |
---|
| 1619 | + if ((word_len * DA7219_DAI_CH_NUM_MAX) <= 32) |
---|
| 1620 | + frame_size = 32; |
---|
| 1621 | + else |
---|
| 1622 | + frame_size = 64; |
---|
| 1623 | + |
---|
| 1624 | + if (bclk) { |
---|
| 1625 | + bclk_rate = frame_size * sr; |
---|
| 1626 | + /* |
---|
| 1627 | + * Rounding the rate here avoids failure trying to set a |
---|
| 1628 | + * new rate on an already enabled bclk. In that |
---|
| 1629 | + * instance this will just set the same rate as is |
---|
| 1630 | + * currently in use, and so should continue without |
---|
| 1631 | + * problem, as long as the BCLK rate is suitable for the |
---|
| 1632 | + * desired frame size. |
---|
| 1633 | + */ |
---|
| 1634 | + bclk_rate = clk_round_rate(bclk, bclk_rate); |
---|
| 1635 | + if ((bclk_rate / sr) < frame_size) { |
---|
| 1636 | + dev_err(component->dev, |
---|
| 1637 | + "BCLK rate mismatch against frame size"); |
---|
| 1638 | + return -EINVAL; |
---|
| 1639 | + } |
---|
| 1640 | + |
---|
| 1641 | + ret = clk_set_rate(bclk, bclk_rate); |
---|
| 1642 | + if (ret) { |
---|
| 1643 | + dev_err(component->dev, |
---|
| 1644 | + "Failed to set BCLK rate %lu: %d\n", |
---|
| 1645 | + bclk_rate, ret); |
---|
| 1646 | + return ret; |
---|
| 1647 | + } |
---|
| 1648 | + } else { |
---|
| 1649 | + ret = da7219_set_bclks_per_wclk(component, frame_size); |
---|
| 1650 | + if (ret) { |
---|
| 1651 | + dev_err(component->dev, |
---|
| 1652 | + "Failed to set BCLKs per WCLK %d: %d\n", |
---|
| 1653 | + frame_size, ret); |
---|
| 1654 | + return ret; |
---|
| 1655 | + } |
---|
| 1656 | + } |
---|
| 1657 | + } |
---|
| 1658 | + |
---|
1536 | 1659 | snd_soc_component_update_bits(component, DA7219_DAI_CTRL, |
---|
1537 | 1660 | DA7219_DAI_WORD_LENGTH_MASK | |
---|
1538 | 1661 | DA7219_DAI_CH_NUM_MASK, |
---|
1539 | 1662 | dai_ctrl); |
---|
1540 | | - snd_soc_component_write(component, DA7219_SR, fs); |
---|
1541 | 1663 | |
---|
1542 | 1664 | return 0; |
---|
1543 | 1665 | } |
---|
.. | .. |
---|
1553 | 1675 | #define DA7219_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
---|
1554 | 1676 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
---|
1555 | 1677 | |
---|
| 1678 | +#define DA7219_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ |
---|
| 1679 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\ |
---|
| 1680 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ |
---|
| 1681 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ |
---|
| 1682 | + SNDRV_PCM_RATE_96000) |
---|
| 1683 | + |
---|
1556 | 1684 | static struct snd_soc_dai_driver da7219_dai = { |
---|
1557 | 1685 | .name = "da7219-hifi", |
---|
1558 | 1686 | .playback = { |
---|
1559 | 1687 | .stream_name = "Playback", |
---|
1560 | 1688 | .channels_min = 1, |
---|
1561 | 1689 | .channels_max = DA7219_DAI_CH_NUM_MAX, |
---|
1562 | | - .rates = SNDRV_PCM_RATE_8000_96000, |
---|
| 1690 | + .rates = DA7219_RATES, |
---|
1563 | 1691 | .formats = DA7219_FORMATS, |
---|
1564 | 1692 | }, |
---|
1565 | 1693 | .capture = { |
---|
1566 | 1694 | .stream_name = "Capture", |
---|
1567 | 1695 | .channels_min = 1, |
---|
1568 | 1696 | .channels_max = DA7219_DAI_CH_NUM_MAX, |
---|
1569 | | - .rates = SNDRV_PCM_RATE_8000_96000, |
---|
| 1697 | + .rates = DA7219_RATES, |
---|
1570 | 1698 | .formats = DA7219_FORMATS, |
---|
1571 | 1699 | }, |
---|
1572 | 1700 | .ops = &da7219_dai_ops, |
---|
.. | .. |
---|
1586 | 1714 | }; |
---|
1587 | 1715 | MODULE_DEVICE_TABLE(of, da7219_of_match); |
---|
1588 | 1716 | |
---|
| 1717 | +#ifdef CONFIG_ACPI |
---|
1589 | 1718 | static const struct acpi_device_id da7219_acpi_match[] = { |
---|
1590 | 1719 | { .id = "DLGS7219", }, |
---|
1591 | 1720 | { } |
---|
1592 | 1721 | }; |
---|
1593 | 1722 | MODULE_DEVICE_TABLE(acpi, da7219_acpi_match); |
---|
| 1723 | +#endif |
---|
1594 | 1724 | |
---|
1595 | 1725 | static enum da7219_micbias_voltage |
---|
1596 | 1726 | da7219_fw_micbias_lvl(struct device *dev, u32 val) |
---|
.. | .. |
---|
1629 | 1759 | } |
---|
1630 | 1760 | } |
---|
1631 | 1761 | |
---|
1632 | | -static struct da7219_pdata *da7219_fw_to_pdata(struct snd_soc_component *component) |
---|
| 1762 | +static struct da7219_pdata *da7219_fw_to_pdata(struct device *dev) |
---|
1633 | 1763 | { |
---|
1634 | | - struct device *dev = component->dev; |
---|
1635 | 1764 | struct da7219_pdata *pdata; |
---|
1636 | 1765 | const char *of_str; |
---|
1637 | 1766 | u32 of_val32; |
---|
.. | .. |
---|
1642 | 1771 | |
---|
1643 | 1772 | pdata->wakeup_source = device_property_read_bool(dev, "wakeup-source"); |
---|
1644 | 1773 | |
---|
1645 | | - pdata->dai_clks_name = "da7219-dai-clks"; |
---|
1646 | | - if (device_property_read_string(dev, "clock-output-names", |
---|
1647 | | - &pdata->dai_clks_name)) |
---|
1648 | | - dev_warn(dev, "Using default clk name: %s\n", |
---|
1649 | | - pdata->dai_clks_name); |
---|
| 1774 | + pdata->dai_clk_names[DA7219_DAI_WCLK_IDX] = "da7219-dai-wclk"; |
---|
| 1775 | + pdata->dai_clk_names[DA7219_DAI_BCLK_IDX] = "da7219-dai-bclk"; |
---|
| 1776 | + if (device_property_read_string_array(dev, "clock-output-names", |
---|
| 1777 | + pdata->dai_clk_names, |
---|
| 1778 | + DA7219_DAI_NUM_CLKS) < 0) |
---|
| 1779 | + dev_warn(dev, "Using default DAI clk names: %s, %s\n", |
---|
| 1780 | + pdata->dai_clk_names[DA7219_DAI_WCLK_IDX], |
---|
| 1781 | + pdata->dai_clk_names[DA7219_DAI_BCLK_IDX]); |
---|
1650 | 1782 | |
---|
1651 | 1783 | if (device_property_read_u32(dev, "dlg,micbias-lvl", &of_val32) >= 0) |
---|
1652 | 1784 | pdata->micbias_lvl = da7219_fw_micbias_lvl(dev, of_val32); |
---|
.. | .. |
---|
1720 | 1852 | [DA7219_SUPPLY_VDDIO] = "VDDIO", |
---|
1721 | 1853 | }; |
---|
1722 | 1854 | |
---|
1723 | | -static int da7219_handle_supplies(struct snd_soc_component *component) |
---|
| 1855 | +static int da7219_handle_supplies(struct snd_soc_component *component, |
---|
| 1856 | + u8 *io_voltage_lvl) |
---|
1724 | 1857 | { |
---|
1725 | 1858 | struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
1726 | 1859 | struct regulator *vddio; |
---|
1727 | | - u8 io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V; |
---|
1728 | 1860 | int i, ret; |
---|
1729 | 1861 | |
---|
1730 | 1862 | /* Get required supplies */ |
---|
1731 | 1863 | for (i = 0; i < DA7219_NUM_SUPPLIES; ++i) |
---|
1732 | 1864 | da7219->supplies[i].supply = da7219_supply_names[i]; |
---|
1733 | 1865 | |
---|
1734 | | - ret = devm_regulator_bulk_get(component->dev, DA7219_NUM_SUPPLIES, |
---|
1735 | | - da7219->supplies); |
---|
| 1866 | + ret = regulator_bulk_get(component->dev, DA7219_NUM_SUPPLIES, |
---|
| 1867 | + da7219->supplies); |
---|
1736 | 1868 | if (ret) { |
---|
1737 | 1869 | dev_err(component->dev, "Failed to get supplies"); |
---|
1738 | 1870 | return ret; |
---|
1739 | 1871 | } |
---|
| 1872 | + |
---|
| 1873 | + /* Default to upper range */ |
---|
| 1874 | + *io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_2_5V_3_6V; |
---|
1740 | 1875 | |
---|
1741 | 1876 | /* Determine VDDIO voltage provided */ |
---|
1742 | 1877 | vddio = da7219->supplies[DA7219_SUPPLY_VDDIO].consumer; |
---|
.. | .. |
---|
1744 | 1879 | if (ret < 1200000) |
---|
1745 | 1880 | dev_warn(component->dev, "Invalid VDDIO voltage\n"); |
---|
1746 | 1881 | else if (ret < 2800000) |
---|
1747 | | - io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V; |
---|
| 1882 | + *io_voltage_lvl = DA7219_IO_VOLTAGE_LEVEL_1_2V_2_8V; |
---|
1748 | 1883 | |
---|
1749 | 1884 | /* Enable main supplies */ |
---|
1750 | 1885 | ret = regulator_bulk_enable(DA7219_NUM_SUPPLIES, da7219->supplies); |
---|
1751 | 1886 | if (ret) { |
---|
1752 | 1887 | dev_err(component->dev, "Failed to enable supplies"); |
---|
| 1888 | + regulator_bulk_free(DA7219_NUM_SUPPLIES, da7219->supplies); |
---|
1753 | 1889 | return ret; |
---|
1754 | 1890 | } |
---|
1755 | | - |
---|
1756 | | - /* Ensure device in active mode */ |
---|
1757 | | - snd_soc_component_write(component, DA7219_SYSTEM_ACTIVE, DA7219_SYSTEM_ACTIVE_MASK); |
---|
1758 | | - |
---|
1759 | | - /* Update IO voltage level range */ |
---|
1760 | | - snd_soc_component_write(component, DA7219_IO_CTRL, io_voltage_lvl); |
---|
1761 | 1891 | |
---|
1762 | 1892 | return 0; |
---|
1763 | 1893 | } |
---|
1764 | 1894 | |
---|
1765 | 1895 | #ifdef CONFIG_COMMON_CLK |
---|
1766 | | -static int da7219_dai_clks_prepare(struct clk_hw *hw) |
---|
| 1896 | +static int da7219_wclk_prepare(struct clk_hw *hw) |
---|
1767 | 1897 | { |
---|
1768 | 1898 | struct da7219_priv *da7219 = |
---|
1769 | | - container_of(hw, struct da7219_priv, dai_clks_hw); |
---|
1770 | | - struct snd_soc_component *component = da7219->aad->component; |
---|
| 1899 | + container_of(hw, struct da7219_priv, |
---|
| 1900 | + dai_clks_hw[DA7219_DAI_WCLK_IDX]); |
---|
| 1901 | + struct snd_soc_component *component = da7219->component; |
---|
| 1902 | + |
---|
| 1903 | + if (!da7219->master) |
---|
| 1904 | + return -EINVAL; |
---|
1771 | 1905 | |
---|
1772 | 1906 | snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, |
---|
1773 | 1907 | DA7219_DAI_CLK_EN_MASK, |
---|
.. | .. |
---|
1776 | 1910 | return 0; |
---|
1777 | 1911 | } |
---|
1778 | 1912 | |
---|
1779 | | -static void da7219_dai_clks_unprepare(struct clk_hw *hw) |
---|
| 1913 | +static void da7219_wclk_unprepare(struct clk_hw *hw) |
---|
1780 | 1914 | { |
---|
1781 | 1915 | struct da7219_priv *da7219 = |
---|
1782 | | - container_of(hw, struct da7219_priv, dai_clks_hw); |
---|
1783 | | - struct snd_soc_component *component = da7219->aad->component; |
---|
| 1916 | + container_of(hw, struct da7219_priv, |
---|
| 1917 | + dai_clks_hw[DA7219_DAI_WCLK_IDX]); |
---|
| 1918 | + struct snd_soc_component *component = da7219->component; |
---|
| 1919 | + |
---|
| 1920 | + if (!da7219->master) |
---|
| 1921 | + return; |
---|
1784 | 1922 | |
---|
1785 | 1923 | snd_soc_component_update_bits(component, DA7219_DAI_CLK_MODE, |
---|
1786 | 1924 | DA7219_DAI_CLK_EN_MASK, 0); |
---|
1787 | 1925 | } |
---|
1788 | 1926 | |
---|
1789 | | -static int da7219_dai_clks_is_prepared(struct clk_hw *hw) |
---|
| 1927 | +static int da7219_wclk_is_prepared(struct clk_hw *hw) |
---|
1790 | 1928 | { |
---|
1791 | 1929 | struct da7219_priv *da7219 = |
---|
1792 | | - container_of(hw, struct da7219_priv, dai_clks_hw); |
---|
1793 | | - struct snd_soc_component *component = da7219->aad->component; |
---|
| 1930 | + container_of(hw, struct da7219_priv, |
---|
| 1931 | + dai_clks_hw[DA7219_DAI_WCLK_IDX]); |
---|
| 1932 | + struct snd_soc_component *component = da7219->component; |
---|
1794 | 1933 | u8 clk_reg; |
---|
1795 | 1934 | |
---|
1796 | | - clk_reg = snd_soc_component_read32(component, DA7219_DAI_CLK_MODE); |
---|
| 1935 | + if (!da7219->master) |
---|
| 1936 | + return -EINVAL; |
---|
| 1937 | + |
---|
| 1938 | + clk_reg = snd_soc_component_read(component, DA7219_DAI_CLK_MODE); |
---|
1797 | 1939 | |
---|
1798 | 1940 | return !!(clk_reg & DA7219_DAI_CLK_EN_MASK); |
---|
1799 | 1941 | } |
---|
1800 | 1942 | |
---|
1801 | | -static const struct clk_ops da7219_dai_clks_ops = { |
---|
1802 | | - .prepare = da7219_dai_clks_prepare, |
---|
1803 | | - .unprepare = da7219_dai_clks_unprepare, |
---|
1804 | | - .is_prepared = da7219_dai_clks_is_prepared, |
---|
1805 | | -}; |
---|
1806 | | - |
---|
1807 | | -static void da7219_register_dai_clks(struct snd_soc_component *component) |
---|
| 1943 | +static unsigned long da7219_wclk_recalc_rate(struct clk_hw *hw, |
---|
| 1944 | + unsigned long parent_rate) |
---|
1808 | 1945 | { |
---|
1809 | | - struct device *dev = component->dev; |
---|
1810 | | - struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
1811 | | - struct da7219_pdata *pdata = da7219->pdata; |
---|
1812 | | - struct clk_init_data init = {}; |
---|
1813 | | - struct clk *dai_clks; |
---|
1814 | | - struct clk_lookup *dai_clks_lookup; |
---|
| 1946 | + struct da7219_priv *da7219 = |
---|
| 1947 | + container_of(hw, struct da7219_priv, |
---|
| 1948 | + dai_clks_hw[DA7219_DAI_WCLK_IDX]); |
---|
| 1949 | + struct snd_soc_component *component = da7219->component; |
---|
| 1950 | + u8 fs = snd_soc_component_read(component, DA7219_SR); |
---|
1815 | 1951 | |
---|
1816 | | - init.parent_names = NULL; |
---|
1817 | | - init.num_parents = 0; |
---|
1818 | | - init.name = pdata->dai_clks_name; |
---|
1819 | | - init.ops = &da7219_dai_clks_ops; |
---|
1820 | | - da7219->dai_clks_hw.init = &init; |
---|
1821 | | - |
---|
1822 | | - dai_clks = devm_clk_register(dev, &da7219->dai_clks_hw); |
---|
1823 | | - if (IS_ERR(dai_clks)) { |
---|
1824 | | - dev_warn(dev, "Failed to register DAI clocks: %ld\n", |
---|
1825 | | - PTR_ERR(dai_clks)); |
---|
1826 | | - return; |
---|
1827 | | - } |
---|
1828 | | - da7219->dai_clks = dai_clks; |
---|
1829 | | - |
---|
1830 | | - /* If we're using DT, then register as provider accordingly */ |
---|
1831 | | - if (dev->of_node) { |
---|
1832 | | - devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, |
---|
1833 | | - &da7219->dai_clks_hw); |
---|
1834 | | - } else { |
---|
1835 | | - dai_clks_lookup = clkdev_create(dai_clks, pdata->dai_clks_name, |
---|
1836 | | - "%s", dev_name(dev)); |
---|
1837 | | - if (!dai_clks_lookup) |
---|
1838 | | - dev_warn(dev, "Failed to create DAI clkdev"); |
---|
1839 | | - else |
---|
1840 | | - da7219->dai_clks_lookup = dai_clks_lookup; |
---|
| 1952 | + switch (fs & DA7219_SR_MASK) { |
---|
| 1953 | + case DA7219_SR_8000: |
---|
| 1954 | + return 8000; |
---|
| 1955 | + case DA7219_SR_11025: |
---|
| 1956 | + return 11025; |
---|
| 1957 | + case DA7219_SR_12000: |
---|
| 1958 | + return 12000; |
---|
| 1959 | + case DA7219_SR_16000: |
---|
| 1960 | + return 16000; |
---|
| 1961 | + case DA7219_SR_22050: |
---|
| 1962 | + return 22050; |
---|
| 1963 | + case DA7219_SR_24000: |
---|
| 1964 | + return 24000; |
---|
| 1965 | + case DA7219_SR_32000: |
---|
| 1966 | + return 32000; |
---|
| 1967 | + case DA7219_SR_44100: |
---|
| 1968 | + return 44100; |
---|
| 1969 | + case DA7219_SR_48000: |
---|
| 1970 | + return 48000; |
---|
| 1971 | + case DA7219_SR_88200: |
---|
| 1972 | + return 88200; |
---|
| 1973 | + case DA7219_SR_96000: |
---|
| 1974 | + return 96000; |
---|
| 1975 | + default: |
---|
| 1976 | + return 0; |
---|
1841 | 1977 | } |
---|
1842 | 1978 | } |
---|
| 1979 | + |
---|
| 1980 | +static long da7219_wclk_round_rate(struct clk_hw *hw, unsigned long rate, |
---|
| 1981 | + unsigned long *parent_rate) |
---|
| 1982 | +{ |
---|
| 1983 | + struct da7219_priv *da7219 = |
---|
| 1984 | + container_of(hw, struct da7219_priv, |
---|
| 1985 | + dai_clks_hw[DA7219_DAI_WCLK_IDX]); |
---|
| 1986 | + |
---|
| 1987 | + if (!da7219->master) |
---|
| 1988 | + return -EINVAL; |
---|
| 1989 | + |
---|
| 1990 | + if (rate < 11025) |
---|
| 1991 | + return 8000; |
---|
| 1992 | + else if (rate < 12000) |
---|
| 1993 | + return 11025; |
---|
| 1994 | + else if (rate < 16000) |
---|
| 1995 | + return 12000; |
---|
| 1996 | + else if (rate < 22050) |
---|
| 1997 | + return 16000; |
---|
| 1998 | + else if (rate < 24000) |
---|
| 1999 | + return 22050; |
---|
| 2000 | + else if (rate < 32000) |
---|
| 2001 | + return 24000; |
---|
| 2002 | + else if (rate < 44100) |
---|
| 2003 | + return 32000; |
---|
| 2004 | + else if (rate < 48000) |
---|
| 2005 | + return 44100; |
---|
| 2006 | + else if (rate < 88200) |
---|
| 2007 | + return 48000; |
---|
| 2008 | + else if (rate < 96000) |
---|
| 2009 | + return 88200; |
---|
| 2010 | + else |
---|
| 2011 | + return 96000; |
---|
| 2012 | +} |
---|
| 2013 | + |
---|
| 2014 | +static int da7219_wclk_set_rate(struct clk_hw *hw, unsigned long rate, |
---|
| 2015 | + unsigned long parent_rate) |
---|
| 2016 | +{ |
---|
| 2017 | + struct da7219_priv *da7219 = |
---|
| 2018 | + container_of(hw, struct da7219_priv, |
---|
| 2019 | + dai_clks_hw[DA7219_DAI_WCLK_IDX]); |
---|
| 2020 | + struct snd_soc_component *component = da7219->component; |
---|
| 2021 | + |
---|
| 2022 | + if (!da7219->master) |
---|
| 2023 | + return -EINVAL; |
---|
| 2024 | + |
---|
| 2025 | + return da7219_set_sr(component, rate); |
---|
| 2026 | +} |
---|
| 2027 | + |
---|
| 2028 | +static unsigned long da7219_bclk_recalc_rate(struct clk_hw *hw, |
---|
| 2029 | + unsigned long parent_rate) |
---|
| 2030 | +{ |
---|
| 2031 | + struct da7219_priv *da7219 = |
---|
| 2032 | + container_of(hw, struct da7219_priv, |
---|
| 2033 | + dai_clks_hw[DA7219_DAI_BCLK_IDX]); |
---|
| 2034 | + struct snd_soc_component *component = da7219->component; |
---|
| 2035 | + u8 bclks_per_wclk = snd_soc_component_read(component, |
---|
| 2036 | + DA7219_DAI_CLK_MODE); |
---|
| 2037 | + |
---|
| 2038 | + switch (bclks_per_wclk & DA7219_DAI_BCLKS_PER_WCLK_MASK) { |
---|
| 2039 | + case DA7219_DAI_BCLKS_PER_WCLK_32: |
---|
| 2040 | + return parent_rate * 32; |
---|
| 2041 | + case DA7219_DAI_BCLKS_PER_WCLK_64: |
---|
| 2042 | + return parent_rate * 64; |
---|
| 2043 | + case DA7219_DAI_BCLKS_PER_WCLK_128: |
---|
| 2044 | + return parent_rate * 128; |
---|
| 2045 | + case DA7219_DAI_BCLKS_PER_WCLK_256: |
---|
| 2046 | + return parent_rate * 256; |
---|
| 2047 | + default: |
---|
| 2048 | + return 0; |
---|
| 2049 | + } |
---|
| 2050 | +} |
---|
| 2051 | + |
---|
| 2052 | +static unsigned long da7219_bclk_get_factor(unsigned long rate, |
---|
| 2053 | + unsigned long parent_rate) |
---|
| 2054 | +{ |
---|
| 2055 | + unsigned long factor; |
---|
| 2056 | + |
---|
| 2057 | + factor = rate / parent_rate; |
---|
| 2058 | + if (factor < 64) |
---|
| 2059 | + return 32; |
---|
| 2060 | + else if (factor < 128) |
---|
| 2061 | + return 64; |
---|
| 2062 | + else if (factor < 256) |
---|
| 2063 | + return 128; |
---|
| 2064 | + else |
---|
| 2065 | + return 256; |
---|
| 2066 | +} |
---|
| 2067 | + |
---|
| 2068 | +static long da7219_bclk_round_rate(struct clk_hw *hw, unsigned long rate, |
---|
| 2069 | + unsigned long *parent_rate) |
---|
| 2070 | +{ |
---|
| 2071 | + struct da7219_priv *da7219 = |
---|
| 2072 | + container_of(hw, struct da7219_priv, |
---|
| 2073 | + dai_clks_hw[DA7219_DAI_BCLK_IDX]); |
---|
| 2074 | + unsigned long factor; |
---|
| 2075 | + |
---|
| 2076 | + if (!*parent_rate || !da7219->master) |
---|
| 2077 | + return -EINVAL; |
---|
| 2078 | + |
---|
| 2079 | + /* |
---|
| 2080 | + * We don't allow changing the parent rate as some BCLK rates can be |
---|
| 2081 | + * derived from multiple parent WCLK rates (BCLK rates are set as a |
---|
| 2082 | + * multiplier of WCLK in HW). We just do some rounding down based on the |
---|
| 2083 | + * parent WCLK rate set and find the appropriate multiplier of BCLK to |
---|
| 2084 | + * get the rounded down BCLK value. |
---|
| 2085 | + */ |
---|
| 2086 | + factor = da7219_bclk_get_factor(rate, *parent_rate); |
---|
| 2087 | + |
---|
| 2088 | + return *parent_rate * factor; |
---|
| 2089 | +} |
---|
| 2090 | + |
---|
| 2091 | +static int da7219_bclk_set_rate(struct clk_hw *hw, unsigned long rate, |
---|
| 2092 | + unsigned long parent_rate) |
---|
| 2093 | +{ |
---|
| 2094 | + struct da7219_priv *da7219 = |
---|
| 2095 | + container_of(hw, struct da7219_priv, |
---|
| 2096 | + dai_clks_hw[DA7219_DAI_BCLK_IDX]); |
---|
| 2097 | + struct snd_soc_component *component = da7219->component; |
---|
| 2098 | + unsigned long factor; |
---|
| 2099 | + |
---|
| 2100 | + if (!da7219->master) |
---|
| 2101 | + return -EINVAL; |
---|
| 2102 | + |
---|
| 2103 | + factor = da7219_bclk_get_factor(rate, parent_rate); |
---|
| 2104 | + |
---|
| 2105 | + return da7219_set_bclks_per_wclk(component, factor); |
---|
| 2106 | +} |
---|
| 2107 | + |
---|
| 2108 | +static const struct clk_ops da7219_dai_clk_ops[DA7219_DAI_NUM_CLKS] = { |
---|
| 2109 | + [DA7219_DAI_WCLK_IDX] = { |
---|
| 2110 | + .prepare = da7219_wclk_prepare, |
---|
| 2111 | + .unprepare = da7219_wclk_unprepare, |
---|
| 2112 | + .is_prepared = da7219_wclk_is_prepared, |
---|
| 2113 | + .recalc_rate = da7219_wclk_recalc_rate, |
---|
| 2114 | + .round_rate = da7219_wclk_round_rate, |
---|
| 2115 | + .set_rate = da7219_wclk_set_rate, |
---|
| 2116 | + }, |
---|
| 2117 | + [DA7219_DAI_BCLK_IDX] = { |
---|
| 2118 | + .recalc_rate = da7219_bclk_recalc_rate, |
---|
| 2119 | + .round_rate = da7219_bclk_round_rate, |
---|
| 2120 | + .set_rate = da7219_bclk_set_rate, |
---|
| 2121 | + }, |
---|
| 2122 | +}; |
---|
| 2123 | + |
---|
| 2124 | +static int da7219_register_dai_clks(struct snd_soc_component *component) |
---|
| 2125 | +{ |
---|
| 2126 | + struct device *dev = component->dev; |
---|
| 2127 | + struct device_node *np = dev->of_node; |
---|
| 2128 | + struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
| 2129 | + struct da7219_pdata *pdata = da7219->pdata; |
---|
| 2130 | + const char *parent_name; |
---|
| 2131 | + struct clk_hw_onecell_data *clk_data; |
---|
| 2132 | + int i, ret; |
---|
| 2133 | + |
---|
| 2134 | + /* For DT platforms allocate onecell data for clock registration */ |
---|
| 2135 | + if (np) { |
---|
| 2136 | + clk_data = kzalloc(struct_size(clk_data, hws, DA7219_DAI_NUM_CLKS), |
---|
| 2137 | + GFP_KERNEL); |
---|
| 2138 | + if (!clk_data) |
---|
| 2139 | + return -ENOMEM; |
---|
| 2140 | + |
---|
| 2141 | + clk_data->num = DA7219_DAI_NUM_CLKS; |
---|
| 2142 | + da7219->clk_hw_data = clk_data; |
---|
| 2143 | + } |
---|
| 2144 | + |
---|
| 2145 | + for (i = 0; i < DA7219_DAI_NUM_CLKS; ++i) { |
---|
| 2146 | + struct clk_init_data init = {}; |
---|
| 2147 | + struct clk_lookup *dai_clk_lookup; |
---|
| 2148 | + struct clk_hw *dai_clk_hw = &da7219->dai_clks_hw[i]; |
---|
| 2149 | + |
---|
| 2150 | + switch (i) { |
---|
| 2151 | + case DA7219_DAI_WCLK_IDX: |
---|
| 2152 | + /* |
---|
| 2153 | + * If we can, make MCLK the parent of WCLK to ensure |
---|
| 2154 | + * it's enabled as required. |
---|
| 2155 | + */ |
---|
| 2156 | + if (da7219->mclk) { |
---|
| 2157 | + parent_name = __clk_get_name(da7219->mclk); |
---|
| 2158 | + init.parent_names = &parent_name; |
---|
| 2159 | + init.num_parents = 1; |
---|
| 2160 | + } else { |
---|
| 2161 | + init.parent_names = NULL; |
---|
| 2162 | + init.num_parents = 0; |
---|
| 2163 | + } |
---|
| 2164 | + break; |
---|
| 2165 | + case DA7219_DAI_BCLK_IDX: |
---|
| 2166 | + /* Make WCLK the parent of BCLK */ |
---|
| 2167 | + parent_name = __clk_get_name(da7219->dai_clks[DA7219_DAI_WCLK_IDX]); |
---|
| 2168 | + init.parent_names = &parent_name; |
---|
| 2169 | + init.num_parents = 1; |
---|
| 2170 | + break; |
---|
| 2171 | + default: |
---|
| 2172 | + dev_err(dev, "Invalid clock index\n"); |
---|
| 2173 | + ret = -EINVAL; |
---|
| 2174 | + goto err; |
---|
| 2175 | + } |
---|
| 2176 | + |
---|
| 2177 | + init.name = pdata->dai_clk_names[i]; |
---|
| 2178 | + init.ops = &da7219_dai_clk_ops[i]; |
---|
| 2179 | + init.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_GATE; |
---|
| 2180 | + dai_clk_hw->init = &init; |
---|
| 2181 | + |
---|
| 2182 | + ret = clk_hw_register(dev, dai_clk_hw); |
---|
| 2183 | + if (ret) { |
---|
| 2184 | + dev_warn(dev, "Failed to register %s: %d\n", init.name, |
---|
| 2185 | + ret); |
---|
| 2186 | + goto err; |
---|
| 2187 | + } |
---|
| 2188 | + da7219->dai_clks[i] = dai_clk_hw->clk; |
---|
| 2189 | + |
---|
| 2190 | + /* For DT setup onecell data, otherwise create lookup */ |
---|
| 2191 | + if (np) { |
---|
| 2192 | + da7219->clk_hw_data->hws[i] = dai_clk_hw; |
---|
| 2193 | + } else { |
---|
| 2194 | + dai_clk_lookup = clkdev_hw_create(dai_clk_hw, init.name, |
---|
| 2195 | + "%s", dev_name(dev)); |
---|
| 2196 | + if (!dai_clk_lookup) { |
---|
| 2197 | + clk_hw_unregister(dai_clk_hw); |
---|
| 2198 | + ret = -ENOMEM; |
---|
| 2199 | + goto err; |
---|
| 2200 | + } else { |
---|
| 2201 | + da7219->dai_clks_lookup[i] = dai_clk_lookup; |
---|
| 2202 | + } |
---|
| 2203 | + } |
---|
| 2204 | + } |
---|
| 2205 | + |
---|
| 2206 | + /* If we're using DT, then register as provider accordingly */ |
---|
| 2207 | + if (np) { |
---|
| 2208 | + ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, |
---|
| 2209 | + da7219->clk_hw_data); |
---|
| 2210 | + if (ret) { |
---|
| 2211 | + dev_err(dev, "Failed to register clock provider\n"); |
---|
| 2212 | + goto err; |
---|
| 2213 | + } |
---|
| 2214 | + } |
---|
| 2215 | + |
---|
| 2216 | + return 0; |
---|
| 2217 | + |
---|
| 2218 | +err: |
---|
| 2219 | + while (--i >= 0) { |
---|
| 2220 | + if (da7219->dai_clks_lookup[i]) |
---|
| 2221 | + clkdev_drop(da7219->dai_clks_lookup[i]); |
---|
| 2222 | + |
---|
| 2223 | + clk_hw_unregister(&da7219->dai_clks_hw[i]); |
---|
| 2224 | + } |
---|
| 2225 | + |
---|
| 2226 | + if (np) |
---|
| 2227 | + kfree(da7219->clk_hw_data); |
---|
| 2228 | + |
---|
| 2229 | + return ret; |
---|
| 2230 | +} |
---|
| 2231 | + |
---|
| 2232 | +static void da7219_free_dai_clks(struct snd_soc_component *component) |
---|
| 2233 | +{ |
---|
| 2234 | + struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
| 2235 | + struct device_node *np = component->dev->of_node; |
---|
| 2236 | + int i; |
---|
| 2237 | + |
---|
| 2238 | + if (np) |
---|
| 2239 | + of_clk_del_provider(np); |
---|
| 2240 | + |
---|
| 2241 | + for (i = DA7219_DAI_NUM_CLKS - 1; i >= 0; --i) { |
---|
| 2242 | + if (da7219->dai_clks_lookup[i]) |
---|
| 2243 | + clkdev_drop(da7219->dai_clks_lookup[i]); |
---|
| 2244 | + |
---|
| 2245 | + clk_hw_unregister(&da7219->dai_clks_hw[i]); |
---|
| 2246 | + } |
---|
| 2247 | + |
---|
| 2248 | + if (np) |
---|
| 2249 | + kfree(da7219->clk_hw_data); |
---|
| 2250 | +} |
---|
1843 | 2251 | #else |
---|
1844 | | -static inline void da7219_register_dai_clks(struct snd_soc_component *component) {} |
---|
| 2252 | +static inline int da7219_register_dai_clks(struct snd_soc_component *component) |
---|
| 2253 | +{ |
---|
| 2254 | + return 0; |
---|
| 2255 | +} |
---|
| 2256 | + |
---|
| 2257 | +static void da7219_free_dai_clks(struct snd_soc_component *component) {} |
---|
1845 | 2258 | #endif /* CONFIG_COMMON_CLK */ |
---|
1846 | 2259 | |
---|
1847 | 2260 | static void da7219_handle_pdata(struct snd_soc_component *component) |
---|
.. | .. |
---|
1853 | 2266 | u8 micbias_lvl = 0; |
---|
1854 | 2267 | |
---|
1855 | 2268 | da7219->wakeup_source = pdata->wakeup_source; |
---|
1856 | | - |
---|
1857 | | - da7219_register_dai_clks(component); |
---|
1858 | 2269 | |
---|
1859 | 2270 | /* Mic Bias voltages */ |
---|
1860 | 2271 | switch (pdata->micbias_lvl) { |
---|
.. | .. |
---|
1890 | 2301 | } |
---|
1891 | 2302 | } |
---|
1892 | 2303 | } |
---|
1893 | | - |
---|
1894 | | -static struct reg_sequence da7219_rev_aa_patch[] = { |
---|
1895 | | - { DA7219_REFERENCES, 0x08 }, |
---|
1896 | | -}; |
---|
1897 | | - |
---|
1898 | | -static int da7219_probe(struct snd_soc_component *component) |
---|
1899 | | -{ |
---|
1900 | | - struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
1901 | | - unsigned int rev; |
---|
1902 | | - int ret; |
---|
1903 | | - |
---|
1904 | | - mutex_init(&da7219->ctrl_lock); |
---|
1905 | | - mutex_init(&da7219->pll_lock); |
---|
1906 | | - |
---|
1907 | | - /* Regulator configuration */ |
---|
1908 | | - ret = da7219_handle_supplies(component); |
---|
1909 | | - if (ret) |
---|
1910 | | - return ret; |
---|
1911 | | - |
---|
1912 | | - ret = regmap_read(da7219->regmap, DA7219_CHIP_REVISION, &rev); |
---|
1913 | | - if (ret) { |
---|
1914 | | - dev_err(component->dev, "Failed to read chip revision: %d\n", ret); |
---|
1915 | | - goto err_disable_reg; |
---|
1916 | | - } |
---|
1917 | | - |
---|
1918 | | - switch (rev & DA7219_CHIP_MINOR_MASK) { |
---|
1919 | | - case 0: |
---|
1920 | | - ret = regmap_register_patch(da7219->regmap, da7219_rev_aa_patch, |
---|
1921 | | - ARRAY_SIZE(da7219_rev_aa_patch)); |
---|
1922 | | - if (ret) { |
---|
1923 | | - dev_err(component->dev, "Failed to register AA patch: %d\n", |
---|
1924 | | - ret); |
---|
1925 | | - goto err_disable_reg; |
---|
1926 | | - } |
---|
1927 | | - break; |
---|
1928 | | - default: |
---|
1929 | | - break; |
---|
1930 | | - } |
---|
1931 | | - |
---|
1932 | | - /* Handle DT/ACPI/Platform data */ |
---|
1933 | | - da7219->pdata = dev_get_platdata(component->dev); |
---|
1934 | | - if (!da7219->pdata) |
---|
1935 | | - da7219->pdata = da7219_fw_to_pdata(component); |
---|
1936 | | - |
---|
1937 | | - da7219_handle_pdata(component); |
---|
1938 | | - |
---|
1939 | | - /* Check if MCLK provided */ |
---|
1940 | | - da7219->mclk = devm_clk_get(component->dev, "mclk"); |
---|
1941 | | - if (IS_ERR(da7219->mclk)) { |
---|
1942 | | - if (PTR_ERR(da7219->mclk) != -ENOENT) { |
---|
1943 | | - ret = PTR_ERR(da7219->mclk); |
---|
1944 | | - goto err_disable_reg; |
---|
1945 | | - } else { |
---|
1946 | | - da7219->mclk = NULL; |
---|
1947 | | - } |
---|
1948 | | - } |
---|
1949 | | - |
---|
1950 | | - /* Default PC counter to free-running */ |
---|
1951 | | - snd_soc_component_update_bits(component, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK, |
---|
1952 | | - DA7219_PC_FREERUN_MASK); |
---|
1953 | | - |
---|
1954 | | - /* Default gain ramping */ |
---|
1955 | | - snd_soc_component_update_bits(component, DA7219_MIXIN_L_CTRL, |
---|
1956 | | - DA7219_MIXIN_L_AMP_RAMP_EN_MASK, |
---|
1957 | | - DA7219_MIXIN_L_AMP_RAMP_EN_MASK); |
---|
1958 | | - snd_soc_component_update_bits(component, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK, |
---|
1959 | | - DA7219_ADC_L_RAMP_EN_MASK); |
---|
1960 | | - snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK, |
---|
1961 | | - DA7219_DAC_L_RAMP_EN_MASK); |
---|
1962 | | - snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK, |
---|
1963 | | - DA7219_DAC_R_RAMP_EN_MASK); |
---|
1964 | | - snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, |
---|
1965 | | - DA7219_HP_L_AMP_RAMP_EN_MASK, |
---|
1966 | | - DA7219_HP_L_AMP_RAMP_EN_MASK); |
---|
1967 | | - snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, |
---|
1968 | | - DA7219_HP_R_AMP_RAMP_EN_MASK, |
---|
1969 | | - DA7219_HP_R_AMP_RAMP_EN_MASK); |
---|
1970 | | - |
---|
1971 | | - /* Default minimum gain on HP to avoid pops during DAPM sequencing */ |
---|
1972 | | - snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, |
---|
1973 | | - DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, |
---|
1974 | | - DA7219_HP_L_AMP_MIN_GAIN_EN_MASK); |
---|
1975 | | - snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, |
---|
1976 | | - DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, |
---|
1977 | | - DA7219_HP_R_AMP_MIN_GAIN_EN_MASK); |
---|
1978 | | - |
---|
1979 | | - /* Default infinite tone gen, start/stop by Kcontrol */ |
---|
1980 | | - snd_soc_component_write(component, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK); |
---|
1981 | | - |
---|
1982 | | - /* Initialise AAD block */ |
---|
1983 | | - ret = da7219_aad_init(component); |
---|
1984 | | - if (ret) |
---|
1985 | | - goto err_disable_reg; |
---|
1986 | | - |
---|
1987 | | - return 0; |
---|
1988 | | - |
---|
1989 | | -err_disable_reg: |
---|
1990 | | - regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies); |
---|
1991 | | - |
---|
1992 | | - return ret; |
---|
1993 | | -} |
---|
1994 | | - |
---|
1995 | | -static void da7219_remove(struct snd_soc_component *component) |
---|
1996 | | -{ |
---|
1997 | | - struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
1998 | | - |
---|
1999 | | - da7219_aad_exit(component); |
---|
2000 | | - |
---|
2001 | | -#ifdef CONFIG_COMMON_CLK |
---|
2002 | | - if (da7219->dai_clks_lookup) |
---|
2003 | | - clkdev_drop(da7219->dai_clks_lookup); |
---|
2004 | | -#endif |
---|
2005 | | - |
---|
2006 | | - /* Supplies */ |
---|
2007 | | - regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies); |
---|
2008 | | -} |
---|
2009 | | - |
---|
2010 | | -#ifdef CONFIG_PM |
---|
2011 | | -static int da7219_suspend(struct snd_soc_component *component) |
---|
2012 | | -{ |
---|
2013 | | - struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
2014 | | - |
---|
2015 | | - /* Suspend AAD if we're not a wake-up source */ |
---|
2016 | | - if (!da7219->wakeup_source) |
---|
2017 | | - da7219_aad_suspend(component); |
---|
2018 | | - |
---|
2019 | | - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); |
---|
2020 | | - |
---|
2021 | | - return 0; |
---|
2022 | | -} |
---|
2023 | | - |
---|
2024 | | -static int da7219_resume(struct snd_soc_component *component) |
---|
2025 | | -{ |
---|
2026 | | - struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
2027 | | - |
---|
2028 | | - snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); |
---|
2029 | | - |
---|
2030 | | - /* Resume AAD if previously suspended */ |
---|
2031 | | - if (!da7219->wakeup_source) |
---|
2032 | | - da7219_aad_resume(component); |
---|
2033 | | - |
---|
2034 | | - return 0; |
---|
2035 | | -} |
---|
2036 | | -#else |
---|
2037 | | -#define da7219_suspend NULL |
---|
2038 | | -#define da7219_resume NULL |
---|
2039 | | -#endif |
---|
2040 | | - |
---|
2041 | | -static const struct snd_soc_component_driver soc_component_dev_da7219 = { |
---|
2042 | | - .probe = da7219_probe, |
---|
2043 | | - .remove = da7219_remove, |
---|
2044 | | - .suspend = da7219_suspend, |
---|
2045 | | - .resume = da7219_resume, |
---|
2046 | | - .set_bias_level = da7219_set_bias_level, |
---|
2047 | | - .controls = da7219_snd_controls, |
---|
2048 | | - .num_controls = ARRAY_SIZE(da7219_snd_controls), |
---|
2049 | | - .dapm_widgets = da7219_dapm_widgets, |
---|
2050 | | - .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets), |
---|
2051 | | - .dapm_routes = da7219_audio_map, |
---|
2052 | | - .num_dapm_routes = ARRAY_SIZE(da7219_audio_map), |
---|
2053 | | - .idle_bias_on = 1, |
---|
2054 | | - .use_pmdown_time = 1, |
---|
2055 | | - .endianness = 1, |
---|
2056 | | - .non_legacy_dai_naming = 1, |
---|
2057 | | -}; |
---|
2058 | 2304 | |
---|
2059 | 2305 | |
---|
2060 | 2306 | /* |
---|
.. | .. |
---|
2192 | 2438 | .cache_type = REGCACHE_RBTREE, |
---|
2193 | 2439 | }; |
---|
2194 | 2440 | |
---|
| 2441 | +static struct reg_sequence da7219_rev_aa_patch[] = { |
---|
| 2442 | + { DA7219_REFERENCES, 0x08 }, |
---|
| 2443 | +}; |
---|
2195 | 2444 | |
---|
2196 | | -/* |
---|
2197 | | - * I2C layer |
---|
2198 | | - */ |
---|
2199 | | - |
---|
2200 | | -static int da7219_i2c_probe(struct i2c_client *i2c, |
---|
2201 | | - const struct i2c_device_id *id) |
---|
| 2445 | +static int da7219_probe(struct snd_soc_component *component) |
---|
2202 | 2446 | { |
---|
2203 | | - struct da7219_priv *da7219; |
---|
2204 | | - unsigned int system_active, system_status; |
---|
| 2447 | + struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
| 2448 | + unsigned int system_active, system_status, rev; |
---|
| 2449 | + u8 io_voltage_lvl; |
---|
2205 | 2450 | int i, ret; |
---|
2206 | 2451 | |
---|
2207 | | - da7219 = devm_kzalloc(&i2c->dev, sizeof(struct da7219_priv), |
---|
2208 | | - GFP_KERNEL); |
---|
2209 | | - if (!da7219) |
---|
2210 | | - return -ENOMEM; |
---|
| 2452 | + da7219->component = component; |
---|
| 2453 | + mutex_init(&da7219->ctrl_lock); |
---|
| 2454 | + mutex_init(&da7219->pll_lock); |
---|
2211 | 2455 | |
---|
2212 | | - i2c_set_clientdata(i2c, da7219); |
---|
2213 | | - |
---|
2214 | | - da7219->regmap = devm_regmap_init_i2c(i2c, &da7219_regmap_config); |
---|
2215 | | - if (IS_ERR(da7219->regmap)) { |
---|
2216 | | - ret = PTR_ERR(da7219->regmap); |
---|
2217 | | - dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); |
---|
| 2456 | + /* Regulator configuration */ |
---|
| 2457 | + ret = da7219_handle_supplies(component, &io_voltage_lvl); |
---|
| 2458 | + if (ret) |
---|
2218 | 2459 | return ret; |
---|
2219 | | - } |
---|
2220 | 2460 | |
---|
2221 | 2461 | regcache_cache_bypass(da7219->regmap, true); |
---|
2222 | 2462 | |
---|
.. | .. |
---|
2246 | 2486 | DA7219_CIF_REG_SOFT_RESET_MASK); |
---|
2247 | 2487 | regmap_write_bits(da7219->regmap, DA7219_SYSTEM_ACTIVE, |
---|
2248 | 2488 | DA7219_SYSTEM_ACTIVE_MASK, 0); |
---|
| 2489 | + regmap_write_bits(da7219->regmap, DA7219_SYSTEM_ACTIVE, |
---|
| 2490 | + DA7219_SYSTEM_ACTIVE_MASK, 1); |
---|
2249 | 2491 | |
---|
2250 | 2492 | regcache_cache_bypass(da7219->regmap, false); |
---|
| 2493 | + regmap_reinit_cache(da7219->regmap, &da7219_regmap_config); |
---|
2251 | 2494 | |
---|
2252 | | - ret = devm_snd_soc_register_component(&i2c->dev, |
---|
2253 | | - &soc_component_dev_da7219, |
---|
2254 | | - &da7219_dai, 1); |
---|
| 2495 | + /* Update IO voltage level range based on supply level */ |
---|
| 2496 | + snd_soc_component_write(component, DA7219_IO_CTRL, io_voltage_lvl); |
---|
| 2497 | + |
---|
| 2498 | + ret = regmap_read(da7219->regmap, DA7219_CHIP_REVISION, &rev); |
---|
| 2499 | + if (ret) { |
---|
| 2500 | + dev_err(component->dev, "Failed to read chip revision: %d\n", ret); |
---|
| 2501 | + goto err_disable_reg; |
---|
| 2502 | + } |
---|
| 2503 | + |
---|
| 2504 | + switch (rev & DA7219_CHIP_MINOR_MASK) { |
---|
| 2505 | + case 0: |
---|
| 2506 | + ret = regmap_register_patch(da7219->regmap, da7219_rev_aa_patch, |
---|
| 2507 | + ARRAY_SIZE(da7219_rev_aa_patch)); |
---|
| 2508 | + if (ret) { |
---|
| 2509 | + dev_err(component->dev, "Failed to register AA patch: %d\n", |
---|
| 2510 | + ret); |
---|
| 2511 | + goto err_disable_reg; |
---|
| 2512 | + } |
---|
| 2513 | + break; |
---|
| 2514 | + default: |
---|
| 2515 | + break; |
---|
| 2516 | + } |
---|
| 2517 | + |
---|
| 2518 | + /* Handle DT/ACPI/Platform data */ |
---|
| 2519 | + da7219_handle_pdata(component); |
---|
| 2520 | + |
---|
| 2521 | + /* Check if MCLK provided */ |
---|
| 2522 | + da7219->mclk = clk_get(component->dev, "mclk"); |
---|
| 2523 | + if (IS_ERR(da7219->mclk)) { |
---|
| 2524 | + if (PTR_ERR(da7219->mclk) != -ENOENT) { |
---|
| 2525 | + ret = PTR_ERR(da7219->mclk); |
---|
| 2526 | + goto err_disable_reg; |
---|
| 2527 | + } else { |
---|
| 2528 | + da7219->mclk = NULL; |
---|
| 2529 | + } |
---|
| 2530 | + } |
---|
| 2531 | + |
---|
| 2532 | + /* Register CCF DAI clock control */ |
---|
| 2533 | + ret = da7219_register_dai_clks(component); |
---|
| 2534 | + if (ret) |
---|
| 2535 | + goto err_put_clk; |
---|
| 2536 | + |
---|
| 2537 | + /* Default PC counter to free-running */ |
---|
| 2538 | + snd_soc_component_update_bits(component, DA7219_PC_COUNT, DA7219_PC_FREERUN_MASK, |
---|
| 2539 | + DA7219_PC_FREERUN_MASK); |
---|
| 2540 | + |
---|
| 2541 | + /* Default gain ramping */ |
---|
| 2542 | + snd_soc_component_update_bits(component, DA7219_MIXIN_L_CTRL, |
---|
| 2543 | + DA7219_MIXIN_L_AMP_RAMP_EN_MASK, |
---|
| 2544 | + DA7219_MIXIN_L_AMP_RAMP_EN_MASK); |
---|
| 2545 | + snd_soc_component_update_bits(component, DA7219_ADC_L_CTRL, DA7219_ADC_L_RAMP_EN_MASK, |
---|
| 2546 | + DA7219_ADC_L_RAMP_EN_MASK); |
---|
| 2547 | + snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL, DA7219_DAC_L_RAMP_EN_MASK, |
---|
| 2548 | + DA7219_DAC_L_RAMP_EN_MASK); |
---|
| 2549 | + snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL, DA7219_DAC_R_RAMP_EN_MASK, |
---|
| 2550 | + DA7219_DAC_R_RAMP_EN_MASK); |
---|
| 2551 | + snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, |
---|
| 2552 | + DA7219_HP_L_AMP_RAMP_EN_MASK, |
---|
| 2553 | + DA7219_HP_L_AMP_RAMP_EN_MASK); |
---|
| 2554 | + snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, |
---|
| 2555 | + DA7219_HP_R_AMP_RAMP_EN_MASK, |
---|
| 2556 | + DA7219_HP_R_AMP_RAMP_EN_MASK); |
---|
| 2557 | + |
---|
| 2558 | + /* Default minimum gain on HP to avoid pops during DAPM sequencing */ |
---|
| 2559 | + snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, |
---|
| 2560 | + DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, |
---|
| 2561 | + DA7219_HP_L_AMP_MIN_GAIN_EN_MASK); |
---|
| 2562 | + snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, |
---|
| 2563 | + DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, |
---|
| 2564 | + DA7219_HP_R_AMP_MIN_GAIN_EN_MASK); |
---|
| 2565 | + |
---|
| 2566 | + /* Default infinite tone gen, start/stop by Kcontrol */ |
---|
| 2567 | + snd_soc_component_write(component, DA7219_TONE_GEN_CYCLES, DA7219_BEEP_CYCLES_MASK); |
---|
| 2568 | + |
---|
| 2569 | + /* Initialise AAD block */ |
---|
| 2570 | + ret = da7219_aad_init(component); |
---|
| 2571 | + if (ret) |
---|
| 2572 | + goto err_free_dai_clks; |
---|
| 2573 | + |
---|
| 2574 | + return 0; |
---|
| 2575 | + |
---|
| 2576 | +err_free_dai_clks: |
---|
| 2577 | + da7219_free_dai_clks(component); |
---|
| 2578 | + |
---|
| 2579 | +err_put_clk: |
---|
| 2580 | + clk_put(da7219->mclk); |
---|
| 2581 | + |
---|
| 2582 | +err_disable_reg: |
---|
| 2583 | + regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies); |
---|
| 2584 | + regulator_bulk_free(DA7219_NUM_SUPPLIES, da7219->supplies); |
---|
| 2585 | + |
---|
| 2586 | + return ret; |
---|
| 2587 | +} |
---|
| 2588 | + |
---|
| 2589 | +static void da7219_remove(struct snd_soc_component *component) |
---|
| 2590 | +{ |
---|
| 2591 | + struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
| 2592 | + |
---|
| 2593 | + da7219_aad_exit(component); |
---|
| 2594 | + |
---|
| 2595 | + da7219_free_dai_clks(component); |
---|
| 2596 | + clk_put(da7219->mclk); |
---|
| 2597 | + |
---|
| 2598 | + /* Supplies */ |
---|
| 2599 | + regulator_bulk_disable(DA7219_NUM_SUPPLIES, da7219->supplies); |
---|
| 2600 | + regulator_bulk_free(DA7219_NUM_SUPPLIES, da7219->supplies); |
---|
| 2601 | +} |
---|
| 2602 | + |
---|
| 2603 | +#ifdef CONFIG_PM |
---|
| 2604 | +static int da7219_suspend(struct snd_soc_component *component) |
---|
| 2605 | +{ |
---|
| 2606 | + struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
| 2607 | + |
---|
| 2608 | + /* Suspend AAD if we're not a wake-up source */ |
---|
| 2609 | + if (!da7219->wakeup_source) |
---|
| 2610 | + da7219_aad_suspend(component); |
---|
| 2611 | + |
---|
| 2612 | + snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); |
---|
| 2613 | + |
---|
| 2614 | + return 0; |
---|
| 2615 | +} |
---|
| 2616 | + |
---|
| 2617 | +static int da7219_resume(struct snd_soc_component *component) |
---|
| 2618 | +{ |
---|
| 2619 | + struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); |
---|
| 2620 | + |
---|
| 2621 | + snd_soc_component_force_bias_level(component, SND_SOC_BIAS_STANDBY); |
---|
| 2622 | + |
---|
| 2623 | + /* Resume AAD if previously suspended */ |
---|
| 2624 | + if (!da7219->wakeup_source) |
---|
| 2625 | + da7219_aad_resume(component); |
---|
| 2626 | + |
---|
| 2627 | + return 0; |
---|
| 2628 | +} |
---|
| 2629 | +#else |
---|
| 2630 | +#define da7219_suspend NULL |
---|
| 2631 | +#define da7219_resume NULL |
---|
| 2632 | +#endif |
---|
| 2633 | + |
---|
| 2634 | +static const struct snd_soc_component_driver soc_component_dev_da7219 = { |
---|
| 2635 | + .probe = da7219_probe, |
---|
| 2636 | + .remove = da7219_remove, |
---|
| 2637 | + .suspend = da7219_suspend, |
---|
| 2638 | + .resume = da7219_resume, |
---|
| 2639 | + .set_bias_level = da7219_set_bias_level, |
---|
| 2640 | + .controls = da7219_snd_controls, |
---|
| 2641 | + .num_controls = ARRAY_SIZE(da7219_snd_controls), |
---|
| 2642 | + .dapm_widgets = da7219_dapm_widgets, |
---|
| 2643 | + .num_dapm_widgets = ARRAY_SIZE(da7219_dapm_widgets), |
---|
| 2644 | + .dapm_routes = da7219_audio_map, |
---|
| 2645 | + .num_dapm_routes = ARRAY_SIZE(da7219_audio_map), |
---|
| 2646 | + .idle_bias_on = 1, |
---|
| 2647 | + .use_pmdown_time = 1, |
---|
| 2648 | + .endianness = 1, |
---|
| 2649 | + .non_legacy_dai_naming = 1, |
---|
| 2650 | +}; |
---|
| 2651 | + |
---|
| 2652 | + |
---|
| 2653 | +/* |
---|
| 2654 | + * I2C layer |
---|
| 2655 | + */ |
---|
| 2656 | + |
---|
| 2657 | +static int da7219_i2c_probe(struct i2c_client *i2c, |
---|
| 2658 | + const struct i2c_device_id *id) |
---|
| 2659 | +{ |
---|
| 2660 | + struct device *dev = &i2c->dev; |
---|
| 2661 | + struct da7219_priv *da7219; |
---|
| 2662 | + int ret; |
---|
| 2663 | + |
---|
| 2664 | + da7219 = devm_kzalloc(dev, sizeof(struct da7219_priv), |
---|
| 2665 | + GFP_KERNEL); |
---|
| 2666 | + if (!da7219) |
---|
| 2667 | + return -ENOMEM; |
---|
| 2668 | + |
---|
| 2669 | + i2c_set_clientdata(i2c, da7219); |
---|
| 2670 | + |
---|
| 2671 | + da7219->regmap = devm_regmap_init_i2c(i2c, &da7219_regmap_config); |
---|
| 2672 | + if (IS_ERR(da7219->regmap)) { |
---|
| 2673 | + ret = PTR_ERR(da7219->regmap); |
---|
| 2674 | + dev_err(dev, "regmap_init() failed: %d\n", ret); |
---|
| 2675 | + return ret; |
---|
| 2676 | + } |
---|
| 2677 | + |
---|
| 2678 | + /* Retrieve DT/ACPI/Platform data */ |
---|
| 2679 | + da7219->pdata = dev_get_platdata(dev); |
---|
| 2680 | + if (!da7219->pdata) |
---|
| 2681 | + da7219->pdata = da7219_fw_to_pdata(dev); |
---|
| 2682 | + |
---|
| 2683 | + /* AAD */ |
---|
| 2684 | + ret = da7219_aad_probe(i2c); |
---|
| 2685 | + if (ret) |
---|
| 2686 | + return ret; |
---|
| 2687 | + |
---|
| 2688 | + ret = devm_snd_soc_register_component(dev, &soc_component_dev_da7219, |
---|
| 2689 | + &da7219_dai, 1); |
---|
2255 | 2690 | if (ret < 0) { |
---|
2256 | | - dev_err(&i2c->dev, "Failed to register da7219 component: %d\n", |
---|
2257 | | - ret); |
---|
| 2691 | + dev_err(dev, "Failed to register da7219 component: %d\n", ret); |
---|
2258 | 2692 | } |
---|
2259 | 2693 | return ret; |
---|
2260 | 2694 | } |
---|