| .. | .. |
|---|
| 123 | 123 | I2S_LRCLK_STRENGTH_HIGH, |
|---|
| 124 | 124 | }; |
|---|
| 125 | 125 | |
|---|
| 126 | +enum { |
|---|
| 127 | + I2S_SCLK_STRENGTH_DISABLE, |
|---|
| 128 | + I2S_SCLK_STRENGTH_LOW, |
|---|
| 129 | + I2S_SCLK_STRENGTH_MEDIUM, |
|---|
| 130 | + I2S_SCLK_STRENGTH_HIGH, |
|---|
| 131 | +}; |
|---|
| 132 | + |
|---|
| 126 | 133 | enum { |
|---|
| 127 | 134 | HP_POWER_EVENT, |
|---|
| 128 | 135 | DAC_POWER_EVENT, |
|---|
| .. | .. |
|---|
| 143 | 150 | u8 micbias_resistor; |
|---|
| 144 | 151 | u8 micbias_voltage; |
|---|
| 145 | 152 | u8 lrclk_strength; |
|---|
| 153 | + u8 sclk_strength; |
|---|
| 146 | 154 | u16 mute_state[LAST_POWER_EVENT + 1]; |
|---|
| 147 | 155 | }; |
|---|
| 148 | 156 | |
|---|
| 149 | 157 | static inline int hp_sel_input(struct snd_soc_component *component) |
|---|
| 150 | 158 | { |
|---|
| 151 | | - return (snd_soc_component_read32(component, SGTL5000_CHIP_ANA_CTRL) & |
|---|
| 159 | + return (snd_soc_component_read(component, SGTL5000_CHIP_ANA_CTRL) & |
|---|
| 152 | 160 | SGTL5000_HP_SEL_MASK) >> SGTL5000_HP_SEL_SHIFT; |
|---|
| 153 | 161 | } |
|---|
| 154 | 162 | |
|---|
| 155 | 163 | static inline u16 mute_output(struct snd_soc_component *component, |
|---|
| 156 | 164 | u16 mute_mask) |
|---|
| 157 | 165 | { |
|---|
| 158 | | - u16 mute_reg = snd_soc_component_read32(component, |
|---|
| 166 | + u16 mute_reg = snd_soc_component_read(component, |
|---|
| 159 | 167 | SGTL5000_CHIP_ANA_CTRL); |
|---|
| 160 | 168 | |
|---|
| 161 | 169 | snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL, |
|---|
| .. | .. |
|---|
| 172 | 180 | |
|---|
| 173 | 181 | static void vag_power_on(struct snd_soc_component *component, u32 source) |
|---|
| 174 | 182 | { |
|---|
| 175 | | - if (snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER) & |
|---|
| 183 | + if (snd_soc_component_read(component, SGTL5000_CHIP_ANA_POWER) & |
|---|
| 176 | 184 | SGTL5000_VAG_POWERUP) |
|---|
| 177 | 185 | return; |
|---|
| 178 | 186 | |
|---|
| .. | .. |
|---|
| 217 | 225 | |
|---|
| 218 | 226 | static void vag_power_off(struct snd_soc_component *component, u32 source) |
|---|
| 219 | 227 | { |
|---|
| 220 | | - u16 ana_pwr = snd_soc_component_read32(component, |
|---|
| 228 | + u16 ana_pwr = snd_soc_component_read(component, |
|---|
| 221 | 229 | SGTL5000_CHIP_ANA_POWER); |
|---|
| 222 | 230 | |
|---|
| 223 | 231 | if (!(ana_pwr & SGTL5000_VAG_POWERUP)) |
|---|
| .. | .. |
|---|
| 537 | 545 | int l; |
|---|
| 538 | 546 | int r; |
|---|
| 539 | 547 | |
|---|
| 540 | | - reg = snd_soc_component_read32(component, SGTL5000_CHIP_DAC_VOL); |
|---|
| 548 | + reg = snd_soc_component_read(component, SGTL5000_CHIP_DAC_VOL); |
|---|
| 541 | 549 | |
|---|
| 542 | 550 | /* get left channel volume */ |
|---|
| 543 | 551 | l = (reg & SGTL5000_DAC_VOL_LEFT_MASK) >> SGTL5000_DAC_VOL_LEFT_SHIFT; |
|---|
| .. | .. |
|---|
| 625 | 633 | { |
|---|
| 626 | 634 | struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
|---|
| 627 | 635 | int db, i; |
|---|
| 628 | | - u16 reg = snd_soc_component_read32(component, SGTL5000_DAP_AVC_THRESHOLD); |
|---|
| 636 | + u16 reg = snd_soc_component_read(component, SGTL5000_DAP_AVC_THRESHOLD); |
|---|
| 629 | 637 | |
|---|
| 630 | 638 | /* register value 0 => -96dB */ |
|---|
| 631 | 639 | if (!reg) { |
|---|
| .. | .. |
|---|
| 712 | 720 | SGTL5000_CHIP_ANA_ADC_CTRL, |
|---|
| 713 | 721 | 8, 1, 0, capture_6db_attenuate), |
|---|
| 714 | 722 | SOC_SINGLE("Capture ZC Switch", SGTL5000_CHIP_ANA_CTRL, 1, 1, 0), |
|---|
| 723 | + SOC_SINGLE("Capture Switch", SGTL5000_CHIP_ANA_CTRL, 0, 1, 1), |
|---|
| 715 | 724 | |
|---|
| 716 | 725 | SOC_DOUBLE_TLV("Headphone Playback Volume", |
|---|
| 717 | 726 | SGTL5000_CHIP_ANA_HP_CTRL, |
|---|
| .. | .. |
|---|
| 766 | 775 | }; |
|---|
| 767 | 776 | |
|---|
| 768 | 777 | /* mute the codec used by alsa core */ |
|---|
| 769 | | -static int sgtl5000_digital_mute(struct snd_soc_dai *codec_dai, int mute) |
|---|
| 778 | +static int sgtl5000_mute_stream(struct snd_soc_dai *codec_dai, int mute, int direction) |
|---|
| 770 | 779 | { |
|---|
| 771 | 780 | struct snd_soc_component *component = codec_dai->component; |
|---|
| 772 | 781 | u16 i2s_pwr = SGTL5000_I2S_IN_POWERUP; |
|---|
| .. | .. |
|---|
| 1151 | 1160 | |
|---|
| 1152 | 1161 | static const struct snd_soc_dai_ops sgtl5000_ops = { |
|---|
| 1153 | 1162 | .hw_params = sgtl5000_pcm_hw_params, |
|---|
| 1154 | | - .digital_mute = sgtl5000_digital_mute, |
|---|
| 1163 | + .mute_stream = sgtl5000_mute_stream, |
|---|
| 1155 | 1164 | .set_fmt = sgtl5000_set_dai_fmt, |
|---|
| 1156 | 1165 | .set_sysclk = sgtl5000_set_dai_sysclk, |
|---|
| 1166 | + .no_capture_mute = 1, |
|---|
| 1157 | 1167 | }; |
|---|
| 1158 | 1168 | |
|---|
| 1159 | 1169 | static struct snd_soc_dai_driver sgtl5000_dai = { |
|---|
| .. | .. |
|---|
| 1316 | 1326 | } |
|---|
| 1317 | 1327 | |
|---|
| 1318 | 1328 | /* reset value */ |
|---|
| 1319 | | - ana_pwr = snd_soc_component_read32(component, SGTL5000_CHIP_ANA_POWER); |
|---|
| 1329 | + ana_pwr = snd_soc_component_read(component, SGTL5000_CHIP_ANA_POWER); |
|---|
| 1320 | 1330 | ana_pwr |= SGTL5000_DAC_STEREO | |
|---|
| 1321 | 1331 | SGTL5000_ADC_STEREO | |
|---|
| 1322 | 1332 | SGTL5000_REFTOP_POWERUP; |
|---|
| 1323 | | - lreg_ctrl = snd_soc_component_read32(component, SGTL5000_CHIP_LINREG_CTRL); |
|---|
| 1333 | + lreg_ctrl = snd_soc_component_read(component, SGTL5000_CHIP_LINREG_CTRL); |
|---|
| 1324 | 1334 | |
|---|
| 1325 | 1335 | if (vddio < 3100 && vdda < 3100) { |
|---|
| 1326 | 1336 | /* enable internal oscillator used for charge pump */ |
|---|
| .. | .. |
|---|
| 1335 | 1345 | * if vddio == vdda the source of charge pump should be |
|---|
| 1336 | 1346 | * assigned manually to VDDIO |
|---|
| 1337 | 1347 | */ |
|---|
| 1338 | | - if (vddio == vdda) { |
|---|
| 1348 | + if (regulator_is_equal(sgtl5000->supplies[VDDA].consumer, |
|---|
| 1349 | + sgtl5000->supplies[VDDIO].consumer)) { |
|---|
| 1339 | 1350 | lreg_ctrl |= SGTL5000_VDDC_ASSN_OVRD; |
|---|
| 1340 | 1351 | lreg_ctrl |= SGTL5000_VDDC_MAN_ASSN_VDDIO << |
|---|
| 1341 | 1352 | SGTL5000_VDDC_MAN_ASSN_SHIFT; |
|---|
| .. | .. |
|---|
| 1458 | 1469 | |
|---|
| 1459 | 1470 | /* enable small pop, introduce 400ms delay in turning off */ |
|---|
| 1460 | 1471 | snd_soc_component_update_bits(component, SGTL5000_CHIP_REF_CTRL, |
|---|
| 1461 | | - SGTL5000_SMALL_POP, 1); |
|---|
| 1472 | + SGTL5000_SMALL_POP, SGTL5000_SMALL_POP); |
|---|
| 1462 | 1473 | |
|---|
| 1463 | 1474 | /* disable short cut detector */ |
|---|
| 1464 | 1475 | snd_soc_component_write(component, SGTL5000_CHIP_SHORT_CTRL, 0); |
|---|
| .. | .. |
|---|
| 1472 | 1483 | SGTL5000_DAC_MUTE_RIGHT | |
|---|
| 1473 | 1484 | SGTL5000_DAC_MUTE_LEFT); |
|---|
| 1474 | 1485 | |
|---|
| 1475 | | - reg = ((sgtl5000->lrclk_strength) << SGTL5000_PAD_I2S_LRCLK_SHIFT | 0x5f); |
|---|
| 1486 | + reg = ((sgtl5000->lrclk_strength) << SGTL5000_PAD_I2S_LRCLK_SHIFT | |
|---|
| 1487 | + (sgtl5000->sclk_strength) << SGTL5000_PAD_I2S_SCLK_SHIFT | |
|---|
| 1488 | + 0x1f); |
|---|
| 1476 | 1489 | snd_soc_component_write(component, SGTL5000_CHIP_PAD_STRENGTH, reg); |
|---|
| 1477 | 1490 | |
|---|
| 1478 | 1491 | snd_soc_component_update_bits(component, SGTL5000_CHIP_ANA_CTRL, |
|---|
| .. | .. |
|---|
| 1502 | 1515 | return ret; |
|---|
| 1503 | 1516 | } |
|---|
| 1504 | 1517 | |
|---|
| 1518 | +static int sgtl5000_of_xlate_dai_id(struct snd_soc_component *component, |
|---|
| 1519 | + struct device_node *endpoint) |
|---|
| 1520 | +{ |
|---|
| 1521 | + /* return dai id 0, whatever the endpoint index */ |
|---|
| 1522 | + return 0; |
|---|
| 1523 | +} |
|---|
| 1524 | + |
|---|
| 1505 | 1525 | static const struct snd_soc_component_driver sgtl5000_driver = { |
|---|
| 1506 | 1526 | .probe = sgtl5000_probe, |
|---|
| 1507 | 1527 | .set_bias_level = sgtl5000_set_bias_level, |
|---|
| .. | .. |
|---|
| 1511 | 1531 | .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets), |
|---|
| 1512 | 1532 | .dapm_routes = sgtl5000_dapm_routes, |
|---|
| 1513 | 1533 | .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), |
|---|
| 1534 | + .of_xlate_dai_id = sgtl5000_of_xlate_dai_id, |
|---|
| 1514 | 1535 | .suspend_bias_off = 1, |
|---|
| 1515 | 1536 | .idle_bias_on = 1, |
|---|
| 1516 | 1537 | .use_pmdown_time = 1, |
|---|
| .. | .. |
|---|
| 1745 | 1766 | sgtl5000->lrclk_strength = value; |
|---|
| 1746 | 1767 | } |
|---|
| 1747 | 1768 | |
|---|
| 1769 | + sgtl5000->sclk_strength = I2S_SCLK_STRENGTH_LOW; |
|---|
| 1770 | + if (!of_property_read_u32(np, "sclk-strength", &value)) { |
|---|
| 1771 | + if (value > I2S_SCLK_STRENGTH_HIGH) |
|---|
| 1772 | + value = I2S_SCLK_STRENGTH_LOW; |
|---|
| 1773 | + sgtl5000->sclk_strength = value; |
|---|
| 1774 | + } |
|---|
| 1775 | + |
|---|
| 1748 | 1776 | /* Ensure sgtl5000 will start with sane register values */ |
|---|
| 1749 | 1777 | sgtl5000_fill_defaults(client); |
|---|
| 1750 | 1778 | |
|---|
| .. | .. |
|---|
| 1769 | 1797 | { |
|---|
| 1770 | 1798 | struct sgtl5000_priv *sgtl5000 = i2c_get_clientdata(client); |
|---|
| 1771 | 1799 | |
|---|
| 1800 | + regmap_write(sgtl5000->regmap, SGTL5000_CHIP_CLK_CTRL, SGTL5000_CHIP_CLK_CTRL_DEFAULT); |
|---|
| 1801 | + regmap_write(sgtl5000->regmap, SGTL5000_CHIP_DIG_POWER, SGTL5000_DIG_POWER_DEFAULT); |
|---|
| 1802 | + regmap_write(sgtl5000->regmap, SGTL5000_CHIP_ANA_POWER, SGTL5000_ANA_POWER_DEFAULT); |
|---|
| 1803 | + |
|---|
| 1772 | 1804 | clk_disable_unprepare(sgtl5000->mclk); |
|---|
| 1773 | 1805 | regulator_bulk_disable(sgtl5000->num_supplies, sgtl5000->supplies); |
|---|
| 1774 | 1806 | regulator_bulk_free(sgtl5000->num_supplies, sgtl5000->supplies); |
|---|
| 1775 | 1807 | |
|---|
| 1776 | 1808 | return 0; |
|---|
| 1809 | +} |
|---|
| 1810 | + |
|---|
| 1811 | +static void sgtl5000_i2c_shutdown(struct i2c_client *client) |
|---|
| 1812 | +{ |
|---|
| 1813 | + sgtl5000_i2c_remove(client); |
|---|
| 1777 | 1814 | } |
|---|
| 1778 | 1815 | |
|---|
| 1779 | 1816 | static const struct i2c_device_id sgtl5000_id[] = { |
|---|
| .. | .. |
|---|
| 1796 | 1833 | }, |
|---|
| 1797 | 1834 | .probe = sgtl5000_i2c_probe, |
|---|
| 1798 | 1835 | .remove = sgtl5000_i2c_remove, |
|---|
| 1836 | + .shutdown = sgtl5000_i2c_shutdown, |
|---|
| 1799 | 1837 | .id_table = sgtl5000_id, |
|---|
| 1800 | 1838 | }; |
|---|
| 1801 | 1839 | |
|---|