cs42l42.c (bdfa75ad70e93633e18b1ed2b3866c01aa9bf9d2) | cs42l42.c (2003c44e28ac9759200a78dda20c5f695949e3f4) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * cs42l42.c -- CS42L42 ALSA SoC audio driver 4 * 5 * Copyright 2016 Cirrus Logic, Inc. 6 * 7 * Author: James Schulman <james.schulman@cirrus.com> 8 * Author: Brian Austin <brian.austin@cirrus.com> --- 11 unchanged lines hidden (view full) --- 20#include <linux/regmap.h> 21#include <linux/slab.h> 22#include <linux/acpi.h> 23#include <linux/platform_device.h> 24#include <linux/property.h> 25#include <linux/regulator/consumer.h> 26#include <linux/gpio/consumer.h> 27#include <linux/of_device.h> | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * cs42l42.c -- CS42L42 ALSA SoC audio driver 4 * 5 * Copyright 2016 Cirrus Logic, Inc. 6 * 7 * Author: James Schulman <james.schulman@cirrus.com> 8 * Author: Brian Austin <brian.austin@cirrus.com> --- 11 unchanged lines hidden (view full) --- 20#include <linux/regmap.h> 21#include <linux/slab.h> 22#include <linux/acpi.h> 23#include <linux/platform_device.h> 24#include <linux/property.h> 25#include <linux/regulator/consumer.h> 26#include <linux/gpio/consumer.h> 27#include <linux/of_device.h> |
28#include <linux/pm_runtime.h> | |
29#include <sound/core.h> 30#include <sound/pcm.h> 31#include <sound/pcm_params.h> 32#include <sound/soc.h> 33#include <sound/soc-dapm.h> 34#include <sound/initval.h> 35#include <sound/tlv.h> 36#include <dt-bindings/sound/cs42l42.h> 37 38#include "cs42l42.h" 39#include "cirrus_legacy.h" 40 41static const struct reg_default cs42l42_reg_defaults[] = { 42 { CS42L42_FRZ_CTL, 0x00 }, 43 { CS42L42_SRC_CTL, 0x10 }, | 28#include <sound/core.h> 29#include <sound/pcm.h> 30#include <sound/pcm_params.h> 31#include <sound/soc.h> 32#include <sound/soc-dapm.h> 33#include <sound/initval.h> 34#include <sound/tlv.h> 35#include <dt-bindings/sound/cs42l42.h> 36 37#include "cs42l42.h" 38#include "cirrus_legacy.h" 39 40static const struct reg_default cs42l42_reg_defaults[] = { 41 { CS42L42_FRZ_CTL, 0x00 }, 42 { CS42L42_SRC_CTL, 0x10 }, |
44 { CS42L42_MCLK_STATUS, 0x02 }, | |
45 { CS42L42_MCLK_CTL, 0x02 }, 46 { CS42L42_SFTRAMP_RATE, 0xA4 }, 47 { CS42L42_I2C_DEBOUNCE, 0x88 }, 48 { CS42L42_I2C_STRETCH, 0x03 }, 49 { CS42L42_I2C_TIMEOUT, 0xB7 }, 50 { CS42L42_PWR_CTL1, 0xFF }, 51 { CS42L42_PWR_CTL2, 0x84 }, 52 { CS42L42_PWR_CTL3, 0x20 }, 53 { CS42L42_RSENSE_CTL1, 0x40 }, 54 { CS42L42_RSENSE_CTL2, 0x00 }, 55 { CS42L42_OSC_SWITCH, 0x00 }, | 43 { CS42L42_MCLK_CTL, 0x02 }, 44 { CS42L42_SFTRAMP_RATE, 0xA4 }, 45 { CS42L42_I2C_DEBOUNCE, 0x88 }, 46 { CS42L42_I2C_STRETCH, 0x03 }, 47 { CS42L42_I2C_TIMEOUT, 0xB7 }, 48 { CS42L42_PWR_CTL1, 0xFF }, 49 { CS42L42_PWR_CTL2, 0x84 }, 50 { CS42L42_PWR_CTL3, 0x20 }, 51 { CS42L42_RSENSE_CTL1, 0x40 }, 52 { CS42L42_RSENSE_CTL2, 0x00 }, 53 { CS42L42_OSC_SWITCH, 0x00 }, |
56 { CS42L42_OSC_SWITCH_STATUS, 0x05 }, | |
57 { CS42L42_RSENSE_CTL3, 0x1B }, 58 { CS42L42_TSENSE_CTL, 0x1B }, 59 { CS42L42_TSRS_INT_DISABLE, 0x00 }, | 54 { CS42L42_RSENSE_CTL3, 0x1B }, 55 { CS42L42_TSENSE_CTL, 0x1B }, 56 { CS42L42_TSRS_INT_DISABLE, 0x00 }, |
60 { CS42L42_TRSENSE_STATUS, 0x00 }, | |
61 { CS42L42_HSDET_CTL1, 0x77 }, 62 { CS42L42_HSDET_CTL2, 0x00 }, 63 { CS42L42_HS_SWITCH_CTL, 0xF3 }, | 57 { CS42L42_HSDET_CTL1, 0x77 }, 58 { CS42L42_HSDET_CTL2, 0x00 }, 59 { CS42L42_HS_SWITCH_CTL, 0xF3 }, |
64 { CS42L42_HS_DET_STATUS, 0x00 }, | |
65 { CS42L42_HS_CLAMP_DISABLE, 0x00 }, 66 { CS42L42_MCLK_SRC_SEL, 0x00 }, 67 { CS42L42_SPDIF_CLK_CFG, 0x00 }, 68 { CS42L42_FSYNC_PW_LOWER, 0x00 }, 69 { CS42L42_FSYNC_PW_UPPER, 0x00 }, 70 { CS42L42_FSYNC_P_LOWER, 0xF9 }, 71 { CS42L42_FSYNC_P_UPPER, 0x00 }, 72 { CS42L42_ASP_CLK_CFG, 0x00 }, 73 { CS42L42_ASP_FRM_CFG, 0x10 }, 74 { CS42L42_FS_RATE_EN, 0x00 }, 75 { CS42L42_IN_ASRC_CLK, 0x00 }, 76 { CS42L42_OUT_ASRC_CLK, 0x00 }, 77 { CS42L42_PLL_DIV_CFG1, 0x00 }, | 60 { CS42L42_HS_CLAMP_DISABLE, 0x00 }, 61 { CS42L42_MCLK_SRC_SEL, 0x00 }, 62 { CS42L42_SPDIF_CLK_CFG, 0x00 }, 63 { CS42L42_FSYNC_PW_LOWER, 0x00 }, 64 { CS42L42_FSYNC_PW_UPPER, 0x00 }, 65 { CS42L42_FSYNC_P_LOWER, 0xF9 }, 66 { CS42L42_FSYNC_P_UPPER, 0x00 }, 67 { CS42L42_ASP_CLK_CFG, 0x00 }, 68 { CS42L42_ASP_FRM_CFG, 0x10 }, 69 { CS42L42_FS_RATE_EN, 0x00 }, 70 { CS42L42_IN_ASRC_CLK, 0x00 }, 71 { CS42L42_OUT_ASRC_CLK, 0x00 }, 72 { CS42L42_PLL_DIV_CFG1, 0x00 }, |
78 { CS42L42_ADC_OVFL_STATUS, 0x00 }, 79 { CS42L42_MIXER_STATUS, 0x00 }, 80 { CS42L42_SRC_STATUS, 0x00 }, 81 { CS42L42_ASP_RX_STATUS, 0x00 }, 82 { CS42L42_ASP_TX_STATUS, 0x00 }, 83 { CS42L42_CODEC_STATUS, 0x00 }, 84 { CS42L42_DET_INT_STATUS1, 0x00 }, 85 { CS42L42_DET_INT_STATUS2, 0x00 }, 86 { CS42L42_SRCPL_INT_STATUS, 0x00 }, 87 { CS42L42_VPMON_STATUS, 0x00 }, 88 { CS42L42_PLL_LOCK_STATUS, 0x00 }, 89 { CS42L42_TSRS_PLUG_STATUS, 0x00 }, | |
90 { CS42L42_ADC_OVFL_INT_MASK, 0x01 }, 91 { CS42L42_MIXER_INT_MASK, 0x0F }, 92 { CS42L42_SRC_INT_MASK, 0x0F }, 93 { CS42L42_ASP_RX_INT_MASK, 0x1F }, 94 { CS42L42_ASP_TX_INT_MASK, 0x0F }, 95 { CS42L42_CODEC_INT_MASK, 0x03 }, | 73 { CS42L42_ADC_OVFL_INT_MASK, 0x01 }, 74 { CS42L42_MIXER_INT_MASK, 0x0F }, 75 { CS42L42_SRC_INT_MASK, 0x0F }, 76 { CS42L42_ASP_RX_INT_MASK, 0x1F }, 77 { CS42L42_ASP_TX_INT_MASK, 0x0F }, 78 { CS42L42_CODEC_INT_MASK, 0x03 }, |
96 { CS42L42_SRCPL_INT_MASK, 0xFF }, | 79 { CS42L42_SRCPL_INT_MASK, 0x7F }, |
97 { CS42L42_VPMON_INT_MASK, 0x01 }, 98 { CS42L42_PLL_LOCK_INT_MASK, 0x01 }, 99 { CS42L42_TSRS_PLUG_INT_MASK, 0x0F }, 100 { CS42L42_PLL_CTL1, 0x00 }, 101 { CS42L42_PLL_DIV_FRAC0, 0x00 }, 102 { CS42L42_PLL_DIV_FRAC1, 0x00 }, 103 { CS42L42_PLL_DIV_FRAC2, 0x00 }, 104 { CS42L42_PLL_DIV_INT, 0x40 }, 105 { CS42L42_PLL_CTL3, 0x10 }, 106 { CS42L42_PLL_CAL_RATIO, 0x80 }, 107 { CS42L42_PLL_CTL4, 0x03 }, | 80 { CS42L42_VPMON_INT_MASK, 0x01 }, 81 { CS42L42_PLL_LOCK_INT_MASK, 0x01 }, 82 { CS42L42_TSRS_PLUG_INT_MASK, 0x0F }, 83 { CS42L42_PLL_CTL1, 0x00 }, 84 { CS42L42_PLL_DIV_FRAC0, 0x00 }, 85 { CS42L42_PLL_DIV_FRAC1, 0x00 }, 86 { CS42L42_PLL_DIV_FRAC2, 0x00 }, 87 { CS42L42_PLL_DIV_INT, 0x40 }, 88 { CS42L42_PLL_CTL3, 0x10 }, 89 { CS42L42_PLL_CAL_RATIO, 0x80 }, 90 { CS42L42_PLL_CTL4, 0x03 }, |
108 { CS42L42_LOAD_DET_RCSTAT, 0x00 }, 109 { CS42L42_LOAD_DET_DONE, 0x00 }, | |
110 { CS42L42_LOAD_DET_EN, 0x00 }, 111 { CS42L42_HSBIAS_SC_AUTOCTL, 0x03 }, 112 { CS42L42_WAKE_CTL, 0xC0 }, 113 { CS42L42_ADC_DISABLE_MUTE, 0x00 }, 114 { CS42L42_TIPSENSE_CTL, 0x02 }, 115 { CS42L42_MISC_DET_CTL, 0x03 }, 116 { CS42L42_MIC_DET_CTL1, 0x1F }, 117 { CS42L42_MIC_DET_CTL2, 0x2F }, | 91 { CS42L42_LOAD_DET_EN, 0x00 }, 92 { CS42L42_HSBIAS_SC_AUTOCTL, 0x03 }, 93 { CS42L42_WAKE_CTL, 0xC0 }, 94 { CS42L42_ADC_DISABLE_MUTE, 0x00 }, 95 { CS42L42_TIPSENSE_CTL, 0x02 }, 96 { CS42L42_MISC_DET_CTL, 0x03 }, 97 { CS42L42_MIC_DET_CTL1, 0x1F }, 98 { CS42L42_MIC_DET_CTL2, 0x2F }, |
118 { CS42L42_DET_STATUS1, 0x00 }, 119 { CS42L42_DET_STATUS2, 0x00 }, | |
120 { CS42L42_DET_INT1_MASK, 0xE0 }, 121 { CS42L42_DET_INT2_MASK, 0xFF }, 122 { CS42L42_HS_BIAS_CTL, 0xC2 }, 123 { CS42L42_ADC_CTL, 0x00 }, 124 { CS42L42_ADC_VOLUME, 0x00 }, 125 { CS42L42_ADC_WNF_HPF_CTL, 0x71 }, 126 { CS42L42_DAC_CTL1, 0x00 }, 127 { CS42L42_DAC_CTL2, 0x02 }, 128 { CS42L42_HP_CTL, 0x0D }, 129 { CS42L42_CLASSH_CTL, 0x07 }, 130 { CS42L42_MIXER_CHA_VOL, 0x3F }, 131 { CS42L42_MIXER_ADC_VOL, 0x3F }, 132 { CS42L42_MIXER_CHB_VOL, 0x3F }, | 99 { CS42L42_DET_INT1_MASK, 0xE0 }, 100 { CS42L42_DET_INT2_MASK, 0xFF }, 101 { CS42L42_HS_BIAS_CTL, 0xC2 }, 102 { CS42L42_ADC_CTL, 0x00 }, 103 { CS42L42_ADC_VOLUME, 0x00 }, 104 { CS42L42_ADC_WNF_HPF_CTL, 0x71 }, 105 { CS42L42_DAC_CTL1, 0x00 }, 106 { CS42L42_DAC_CTL2, 0x02 }, 107 { CS42L42_HP_CTL, 0x0D }, 108 { CS42L42_CLASSH_CTL, 0x07 }, 109 { CS42L42_MIXER_CHA_VOL, 0x3F }, 110 { CS42L42_MIXER_ADC_VOL, 0x3F }, 111 { CS42L42_MIXER_CHB_VOL, 0x3F }, |
133 { CS42L42_EQ_COEF_IN0, 0x22 }, | 112 { CS42L42_EQ_COEF_IN0, 0x00 }, |
134 { CS42L42_EQ_COEF_IN1, 0x00 }, 135 { CS42L42_EQ_COEF_IN2, 0x00 }, 136 { CS42L42_EQ_COEF_IN3, 0x00 }, 137 { CS42L42_EQ_COEF_RW, 0x00 }, 138 { CS42L42_EQ_COEF_OUT0, 0x00 }, 139 { CS42L42_EQ_COEF_OUT1, 0x00 }, 140 { CS42L42_EQ_COEF_OUT2, 0x00 }, 141 { CS42L42_EQ_COEF_OUT3, 0x00 }, --- 35 unchanged lines hidden (view full) --- 177 { CS42L42_ASP_RX_DAI0_CH4_BIT_MSB, 0x00 }, 178 { CS42L42_ASP_RX_DAI0_CH4_BIT_LSB, 0x00 }, 179 { CS42L42_ASP_RX_DAI1_CH1_AP_RES, 0x03 }, 180 { CS42L42_ASP_RX_DAI1_CH1_BIT_MSB, 0x00 }, 181 { CS42L42_ASP_RX_DAI1_CH1_BIT_LSB, 0x00 }, 182 { CS42L42_ASP_RX_DAI1_CH2_AP_RES, 0x03 }, 183 { CS42L42_ASP_RX_DAI1_CH2_BIT_MSB, 0x00 }, 184 { CS42L42_ASP_RX_DAI1_CH2_BIT_LSB, 0x00 }, | 113 { CS42L42_EQ_COEF_IN1, 0x00 }, 114 { CS42L42_EQ_COEF_IN2, 0x00 }, 115 { CS42L42_EQ_COEF_IN3, 0x00 }, 116 { CS42L42_EQ_COEF_RW, 0x00 }, 117 { CS42L42_EQ_COEF_OUT0, 0x00 }, 118 { CS42L42_EQ_COEF_OUT1, 0x00 }, 119 { CS42L42_EQ_COEF_OUT2, 0x00 }, 120 { CS42L42_EQ_COEF_OUT3, 0x00 }, --- 35 unchanged lines hidden (view full) --- 156 { CS42L42_ASP_RX_DAI0_CH4_BIT_MSB, 0x00 }, 157 { CS42L42_ASP_RX_DAI0_CH4_BIT_LSB, 0x00 }, 158 { CS42L42_ASP_RX_DAI1_CH1_AP_RES, 0x03 }, 159 { CS42L42_ASP_RX_DAI1_CH1_BIT_MSB, 0x00 }, 160 { CS42L42_ASP_RX_DAI1_CH1_BIT_LSB, 0x00 }, 161 { CS42L42_ASP_RX_DAI1_CH2_AP_RES, 0x03 }, 162 { CS42L42_ASP_RX_DAI1_CH2_BIT_MSB, 0x00 }, 163 { CS42L42_ASP_RX_DAI1_CH2_BIT_LSB, 0x00 }, |
185 { CS42L42_SUB_REVID, 0x03 }, | |
186}; 187 188static bool cs42l42_readable_register(struct device *dev, unsigned int reg) 189{ 190 switch (reg) { 191 case CS42L42_PAGE_REGISTER: 192 case CS42L42_DEVID_AB: 193 case CS42L42_DEVID_CD: --- 152 unchanged lines hidden (view full) --- 346 347static bool cs42l42_volatile_register(struct device *dev, unsigned int reg) 348{ 349 switch (reg) { 350 case CS42L42_DEVID_AB: 351 case CS42L42_DEVID_CD: 352 case CS42L42_DEVID_E: 353 case CS42L42_MCLK_STATUS: | 164}; 165 166static bool cs42l42_readable_register(struct device *dev, unsigned int reg) 167{ 168 switch (reg) { 169 case CS42L42_PAGE_REGISTER: 170 case CS42L42_DEVID_AB: 171 case CS42L42_DEVID_CD: --- 152 unchanged lines hidden (view full) --- 324 325static bool cs42l42_volatile_register(struct device *dev, unsigned int reg) 326{ 327 switch (reg) { 328 case CS42L42_DEVID_AB: 329 case CS42L42_DEVID_CD: 330 case CS42L42_DEVID_E: 331 case CS42L42_MCLK_STATUS: |
332 case CS42L42_OSC_SWITCH_STATUS: |
|
354 case CS42L42_TRSENSE_STATUS: 355 case CS42L42_HS_DET_STATUS: 356 case CS42L42_ADC_OVFL_STATUS: 357 case CS42L42_MIXER_STATUS: 358 case CS42L42_SRC_STATUS: 359 case CS42L42_ASP_RX_STATUS: 360 case CS42L42_ASP_TX_STATUS: 361 case CS42L42_CODEC_STATUS: --- 88 unchanged lines hidden (view full) --- 450 CS42L42_DACB_INV_SHIFT, true, false), 451 SOC_SINGLE("DAC HPF Switch", CS42L42_DAC_CTL2, 452 CS42L42_DAC_HPF_EN_SHIFT, true, false), 453 SOC_DOUBLE_R_TLV("Mixer Volume", CS42L42_MIXER_CHA_VOL, 454 CS42L42_MIXER_CHB_VOL, CS42L42_MIXER_CH_VOL_SHIFT, 455 0x3f, 1, mixer_tlv) 456}; 457 | 333 case CS42L42_TRSENSE_STATUS: 334 case CS42L42_HS_DET_STATUS: 335 case CS42L42_ADC_OVFL_STATUS: 336 case CS42L42_MIXER_STATUS: 337 case CS42L42_SRC_STATUS: 338 case CS42L42_ASP_RX_STATUS: 339 case CS42L42_ASP_TX_STATUS: 340 case CS42L42_CODEC_STATUS: --- 88 unchanged lines hidden (view full) --- 429 CS42L42_DACB_INV_SHIFT, true, false), 430 SOC_SINGLE("DAC HPF Switch", CS42L42_DAC_CTL2, 431 CS42L42_DAC_HPF_EN_SHIFT, true, false), 432 SOC_DOUBLE_R_TLV("Mixer Volume", CS42L42_MIXER_CHA_VOL, 433 CS42L42_MIXER_CHB_VOL, CS42L42_MIXER_CH_VOL_SHIFT, 434 0x3f, 1, mixer_tlv) 435}; 436 |
437static int cs42l42_hp_adc_ev(struct snd_soc_dapm_widget *w, 438 struct snd_kcontrol *kcontrol, int event) 439{ 440 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); 441 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 442 443 switch (event) { 444 case SND_SOC_DAPM_PRE_PMU: 445 cs42l42->hp_adc_up_pending = true; 446 break; 447 case SND_SOC_DAPM_POST_PMU: 448 /* Only need one delay if HP and ADC are both powering-up */ 449 if (cs42l42->hp_adc_up_pending) { 450 usleep_range(CS42L42_HP_ADC_EN_TIME_US, 451 CS42L42_HP_ADC_EN_TIME_US + 1000); 452 cs42l42->hp_adc_up_pending = false; 453 } 454 break; 455 default: 456 break; 457 } 458 459 return 0; 460} 461 |
|
458static const struct snd_soc_dapm_widget cs42l42_dapm_widgets[] = { 459 /* Playback Path */ 460 SND_SOC_DAPM_OUTPUT("HP"), | 462static const struct snd_soc_dapm_widget cs42l42_dapm_widgets[] = { 463 /* Playback Path */ 464 SND_SOC_DAPM_OUTPUT("HP"), |
461 SND_SOC_DAPM_DAC("DAC", NULL, CS42L42_PWR_CTL1, CS42L42_HP_PDN_SHIFT, 1), | 465 SND_SOC_DAPM_DAC_E("DAC", NULL, CS42L42_PWR_CTL1, CS42L42_HP_PDN_SHIFT, 1, 466 cs42l42_hp_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), |
462 SND_SOC_DAPM_MIXER("MIXER", CS42L42_PWR_CTL1, CS42L42_MIXER_PDN_SHIFT, 1, NULL, 0), 463 SND_SOC_DAPM_AIF_IN("SDIN1", NULL, 0, SND_SOC_NOPM, 0, 0), 464 SND_SOC_DAPM_AIF_IN("SDIN2", NULL, 1, SND_SOC_NOPM, 0, 0), 465 466 /* Playback Requirements */ 467 SND_SOC_DAPM_SUPPLY("ASP DAI0", CS42L42_PWR_CTL1, CS42L42_ASP_DAI_PDN_SHIFT, 1, NULL, 0), 468 469 /* Capture Path */ 470 SND_SOC_DAPM_INPUT("HS"), | 467 SND_SOC_DAPM_MIXER("MIXER", CS42L42_PWR_CTL1, CS42L42_MIXER_PDN_SHIFT, 1, NULL, 0), 468 SND_SOC_DAPM_AIF_IN("SDIN1", NULL, 0, SND_SOC_NOPM, 0, 0), 469 SND_SOC_DAPM_AIF_IN("SDIN2", NULL, 1, SND_SOC_NOPM, 0, 0), 470 471 /* Playback Requirements */ 472 SND_SOC_DAPM_SUPPLY("ASP DAI0", CS42L42_PWR_CTL1, CS42L42_ASP_DAI_PDN_SHIFT, 1, NULL, 0), 473 474 /* Capture Path */ 475 SND_SOC_DAPM_INPUT("HS"), |
471 SND_SOC_DAPM_ADC("ADC", NULL, CS42L42_PWR_CTL1, CS42L42_ADC_PDN_SHIFT, 1), | 476 SND_SOC_DAPM_ADC_E("ADC", NULL, CS42L42_PWR_CTL1, CS42L42_ADC_PDN_SHIFT, 1, 477 cs42l42_hp_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU), |
472 SND_SOC_DAPM_AIF_OUT("SDOUT1", NULL, 0, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH1_SHIFT, 0), 473 SND_SOC_DAPM_AIF_OUT("SDOUT2", NULL, 1, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH2_SHIFT, 0), 474 475 /* Capture Requirements */ 476 SND_SOC_DAPM_SUPPLY("ASP DAO0", CS42L42_PWR_CTL1, CS42L42_ASP_DAO_PDN_SHIFT, 1, NULL, 0), 477 SND_SOC_DAPM_SUPPLY("ASP TX EN", CS42L42_ASP_TX_SZ_EN, CS42L42_ASP_TX_EN_SHIFT, 0, NULL, 0), 478 479 /* Playback/Capture Requirements */ --- 32 unchanged lines hidden (view full) --- 512}; 513 514static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_jack *jk, void *d) 515{ 516 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 517 518 cs42l42->jack = jk; 519 | 478 SND_SOC_DAPM_AIF_OUT("SDOUT1", NULL, 0, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH1_SHIFT, 0), 479 SND_SOC_DAPM_AIF_OUT("SDOUT2", NULL, 1, CS42L42_ASP_TX_CH_EN, CS42L42_ASP_TX0_CH2_SHIFT, 0), 480 481 /* Capture Requirements */ 482 SND_SOC_DAPM_SUPPLY("ASP DAO0", CS42L42_PWR_CTL1, CS42L42_ASP_DAO_PDN_SHIFT, 1, NULL, 0), 483 SND_SOC_DAPM_SUPPLY("ASP TX EN", CS42L42_ASP_TX_SZ_EN, CS42L42_ASP_TX_EN_SHIFT, 0, NULL, 0), 484 485 /* Playback/Capture Requirements */ --- 32 unchanged lines hidden (view full) --- 518}; 519 520static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_jack *jk, void *d) 521{ 522 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 523 524 cs42l42->jack = jk; 525 |
520 regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, 521 CS42L42_RS_PLUG_MASK | CS42L42_RS_UNPLUG_MASK | 522 CS42L42_TS_PLUG_MASK | CS42L42_TS_UNPLUG_MASK, 523 (1 << CS42L42_RS_PLUG_SHIFT) | (1 << CS42L42_RS_UNPLUG_SHIFT) | 524 (0 << CS42L42_TS_PLUG_SHIFT) | (0 << CS42L42_TS_UNPLUG_SHIFT)); 525 | |
526 return 0; 527} 528 | 526 return 0; 527} 528 |
529static int cs42l42_component_probe(struct snd_soc_component *component) 530{ 531 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 532 533 cs42l42->component = component; 534 535 return 0; 536} 537 | |
538static const struct snd_soc_component_driver soc_component_dev_cs42l42 = { | 529static const struct snd_soc_component_driver soc_component_dev_cs42l42 = { |
539 .probe = cs42l42_component_probe, | |
540 .set_jack = cs42l42_set_jack, 541 .dapm_widgets = cs42l42_dapm_widgets, 542 .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets), 543 .dapm_routes = cs42l42_audio_map, 544 .num_dapm_routes = ARRAY_SIZE(cs42l42_audio_map), 545 .controls = cs42l42_snd_controls, 546 .num_controls = ARRAY_SIZE(cs42l42_snd_controls), 547 .idle_bias_on = 1, --- 16 unchanged lines hidden (view full) --- 564 .reg = CS42L42_OSC_SWITCH, 565 .def = 0, 566 .delay_us = CS42L42_CLOCK_SWITCH_DELAY_US, 567 }, 568}; 569 570struct cs42l42_pll_params { 571 u32 sclk; | 530 .set_jack = cs42l42_set_jack, 531 .dapm_widgets = cs42l42_dapm_widgets, 532 .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets), 533 .dapm_routes = cs42l42_audio_map, 534 .num_dapm_routes = ARRAY_SIZE(cs42l42_audio_map), 535 .controls = cs42l42_snd_controls, 536 .num_controls = ARRAY_SIZE(cs42l42_snd_controls), 537 .idle_bias_on = 1, --- 16 unchanged lines hidden (view full) --- 554 .reg = CS42L42_OSC_SWITCH, 555 .def = 0, 556 .delay_us = CS42L42_CLOCK_SWITCH_DELAY_US, 557 }, 558}; 559 560struct cs42l42_pll_params { 561 u32 sclk; |
572 u8 mclk_div; | |
573 u8 mclk_src_sel; 574 u8 sclk_prediv; 575 u8 pll_div_int; 576 u32 pll_div_frac; 577 u8 pll_mode; 578 u8 pll_divout; 579 u32 mclk_int; 580 u8 pll_cal_ratio; 581 u8 n; 582}; 583 584/* 585 * Common PLL Settings for given SCLK 586 * Table 4-5 from the Datasheet 587 */ 588static const struct cs42l42_pll_params pll_ratio_table[] = { | 562 u8 mclk_src_sel; 563 u8 sclk_prediv; 564 u8 pll_div_int; 565 u32 pll_div_frac; 566 u8 pll_mode; 567 u8 pll_divout; 568 u32 mclk_int; 569 u8 pll_cal_ratio; 570 u8 n; 571}; 572 573/* 574 * Common PLL Settings for given SCLK 575 * Table 4-5 from the Datasheet 576 */ 577static const struct cs42l42_pll_params pll_ratio_table[] = { |
589 { 1411200, 0, 1, 0x00, 0x80, 0x000000, 0x03, 0x10, 11289600, 128, 2}, 590 { 1536000, 0, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2}, 591 { 2304000, 0, 1, 0x00, 0x55, 0xC00000, 0x02, 0x10, 12288000, 85, 2}, 592 { 2400000, 0, 1, 0x00, 0x50, 0x000000, 0x03, 0x10, 12000000, 80, 2}, 593 { 2822400, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, 594 { 3000000, 0, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, 595 { 3072000, 0, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1}, 596 { 4000000, 0, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96, 1}, 597 { 4096000, 0, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94, 1}, 598 { 5644800, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, 599 { 6000000, 0, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, 600 { 6144000, 0, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1}, 601 { 11289600, 0, 0, 0, 0, 0, 0, 0, 11289600, 0, 1}, 602 { 12000000, 0, 0, 0, 0, 0, 0, 0, 12000000, 0, 1}, 603 { 12288000, 0, 0, 0, 0, 0, 0, 0, 12288000, 0, 1}, 604 { 22579200, 1, 0, 0, 0, 0, 0, 0, 22579200, 0, 1}, 605 { 24000000, 1, 0, 0, 0, 0, 0, 0, 24000000, 0, 1}, 606 { 24576000, 1, 0, 0, 0, 0, 0, 0, 24576000, 0, 1} | 578 { 1411200, 1, 0x00, 0x80, 0x000000, 0x03, 0x10, 11289600, 128, 2}, 579 { 1536000, 1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2}, 580 { 2304000, 1, 0x00, 0x55, 0xC00000, 0x02, 0x10, 12288000, 85, 2}, 581 { 2400000, 1, 0x00, 0x50, 0x000000, 0x03, 0x10, 12000000, 80, 2}, 582 { 2822400, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, 583 { 3000000, 1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, 584 { 3072000, 1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1}, 585 { 4000000, 1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000, 96, 1}, 586 { 4096000, 1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000, 94, 1}, 587 { 5644800, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, 588 { 6000000, 1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, 589 { 6144000, 1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1}, 590 { 11289600, 0, 0, 0, 0, 0, 0, 11289600, 0, 1}, 591 { 12000000, 0, 0, 0, 0, 0, 0, 12000000, 0, 1}, 592 { 12288000, 0, 0, 0, 0, 0, 0, 12288000, 0, 1}, 593 { 22579200, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1}, 594 { 24000000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1}, 595 { 24576000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1} |
607}; 608 609static int cs42l42_pll_config(struct snd_soc_component *component) 610{ 611 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 612 int i; 613 u32 clk; 614 u32 fsync; 615 616 if (!cs42l42->sclk) 617 clk = cs42l42->bclk; 618 else 619 clk = cs42l42->sclk; 620 | 596}; 597 598static int cs42l42_pll_config(struct snd_soc_component *component) 599{ 600 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 601 int i; 602 u32 clk; 603 u32 fsync; 604 605 if (!cs42l42->sclk) 606 clk = cs42l42->bclk; 607 else 608 clk = cs42l42->sclk; 609 |
610 /* Don't reconfigure if there is an audio stream running */ 611 if (cs42l42->stream_use) { 612 if (pll_ratio_table[cs42l42->pll_config].sclk == clk) 613 return 0; 614 else 615 return -EBUSY; 616 } 617 |
|
621 for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) { 622 if (pll_ratio_table[i].sclk == clk) { 623 cs42l42->pll_config = i; 624 625 /* Configure the internal sample rate */ 626 snd_soc_component_update_bits(component, CS42L42_MCLK_CTL, 627 CS42L42_INTERNAL_FS_MASK, 628 ((pll_ratio_table[i].mclk_int != 629 12000000) && 630 (pll_ratio_table[i].mclk_int != 631 24000000)) << 632 CS42L42_INTERNAL_FS_SHIFT); 633 | 618 for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) { 619 if (pll_ratio_table[i].sclk == clk) { 620 cs42l42->pll_config = i; 621 622 /* Configure the internal sample rate */ 623 snd_soc_component_update_bits(component, CS42L42_MCLK_CTL, 624 CS42L42_INTERNAL_FS_MASK, 625 ((pll_ratio_table[i].mclk_int != 626 12000000) && 627 (pll_ratio_table[i].mclk_int != 628 24000000)) << 629 CS42L42_INTERNAL_FS_SHIFT); 630 |
634 snd_soc_component_update_bits(component, CS42L42_MCLK_SRC_SEL, 635 CS42L42_MCLKDIV_MASK, 636 (pll_ratio_table[i].mclk_div << 637 CS42L42_MCLKDIV_SHIFT)); | |
638 /* Set up the LRCLK */ 639 fsync = clk / cs42l42->srate; 640 if (((fsync * cs42l42->srate) != clk) 641 || ((fsync % 2) != 0)) { 642 dev_err(component->dev, 643 "Unsupported sclk %d/sample rate %d\n", 644 clk, 645 cs42l42->srate); --- 17 unchanged lines hidden (view full) --- 663 CS42L42_FSYNC_PULSE_WIDTH_MASK, 664 CS42L42_FRAC0_VAL(fsync - 1) << 665 CS42L42_FSYNC_PULSE_WIDTH_SHIFT); 666 snd_soc_component_update_bits(component, 667 CS42L42_FSYNC_PW_UPPER, 668 CS42L42_FSYNC_PULSE_WIDTH_MASK, 669 CS42L42_FRAC1_VAL(fsync - 1) << 670 CS42L42_FSYNC_PULSE_WIDTH_SHIFT); | 631 /* Set up the LRCLK */ 632 fsync = clk / cs42l42->srate; 633 if (((fsync * cs42l42->srate) != clk) 634 || ((fsync % 2) != 0)) { 635 dev_err(component->dev, 636 "Unsupported sclk %d/sample rate %d\n", 637 clk, 638 cs42l42->srate); --- 17 unchanged lines hidden (view full) --- 656 CS42L42_FSYNC_PULSE_WIDTH_MASK, 657 CS42L42_FRAC0_VAL(fsync - 1) << 658 CS42L42_FSYNC_PULSE_WIDTH_SHIFT); 659 snd_soc_component_update_bits(component, 660 CS42L42_FSYNC_PW_UPPER, 661 CS42L42_FSYNC_PULSE_WIDTH_MASK, 662 CS42L42_FRAC1_VAL(fsync - 1) << 663 CS42L42_FSYNC_PULSE_WIDTH_SHIFT); |
671 /* Set the sample rates (96k or lower) */ 672 snd_soc_component_update_bits(component, CS42L42_FS_RATE_EN, 673 CS42L42_FS_EN_MASK, 674 (CS42L42_FS_EN_IASRC_96K | 675 CS42L42_FS_EN_OASRC_96K) << 676 CS42L42_FS_EN_SHIFT); 677 /* Set the input/output internal MCLK clock ~12 MHz */ 678 snd_soc_component_update_bits(component, CS42L42_IN_ASRC_CLK, 679 CS42L42_CLK_IASRC_SEL_MASK, 680 CS42L42_CLK_IASRC_SEL_12 << 681 CS42L42_CLK_IASRC_SEL_SHIFT); 682 snd_soc_component_update_bits(component, 683 CS42L42_OUT_ASRC_CLK, 684 CS42L42_CLK_OASRC_SEL_MASK, 685 CS42L42_CLK_OASRC_SEL_12 << 686 CS42L42_CLK_OASRC_SEL_SHIFT); | |
687 if (pll_ratio_table[i].mclk_src_sel == 0) { 688 /* Pass the clock straight through */ 689 snd_soc_component_update_bits(component, 690 CS42L42_PLL_CTL1, 691 CS42L42_PLL_START_MASK, 0); 692 } else { 693 /* Configure PLL per table 4-5 */ 694 snd_soc_component_update_bits(component, --- 46 unchanged lines hidden (view full) --- 741 } 742 return 0; 743 } 744 } 745 746 return -EINVAL; 747} 748 | 664 if (pll_ratio_table[i].mclk_src_sel == 0) { 665 /* Pass the clock straight through */ 666 snd_soc_component_update_bits(component, 667 CS42L42_PLL_CTL1, 668 CS42L42_PLL_START_MASK, 0); 669 } else { 670 /* Configure PLL per table 4-5 */ 671 snd_soc_component_update_bits(component, --- 46 unchanged lines hidden (view full) --- 718 } 719 return 0; 720 } 721 } 722 723 return -EINVAL; 724} 725 |
726static void cs42l42_src_config(struct snd_soc_component *component, unsigned int sample_rate) 727{ 728 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 729 unsigned int fs; 730 731 /* Don't reconfigure if there is an audio stream running */ 732 if (cs42l42->stream_use) 733 return; 734 735 /* SRC MCLK must be as close as possible to 125 * sample rate */ 736 if (sample_rate <= 48000) 737 fs = CS42L42_CLK_IASRC_SEL_6; 738 else 739 fs = CS42L42_CLK_IASRC_SEL_12; 740 741 /* Set the sample rates (96k or lower) */ 742 snd_soc_component_update_bits(component, 743 CS42L42_FS_RATE_EN, 744 CS42L42_FS_EN_MASK, 745 (CS42L42_FS_EN_IASRC_96K | 746 CS42L42_FS_EN_OASRC_96K) << 747 CS42L42_FS_EN_SHIFT); 748 749 snd_soc_component_update_bits(component, 750 CS42L42_IN_ASRC_CLK, 751 CS42L42_CLK_IASRC_SEL_MASK, 752 fs << CS42L42_CLK_IASRC_SEL_SHIFT); 753 snd_soc_component_update_bits(component, 754 CS42L42_OUT_ASRC_CLK, 755 CS42L42_CLK_OASRC_SEL_MASK, 756 fs << CS42L42_CLK_OASRC_SEL_SHIFT); 757} 758 |
|
749static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 750{ 751 struct snd_soc_component *component = codec_dai->component; 752 u32 asp_cfg_val = 0; 753 754 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 755 case SND_SOC_DAIFMT_CBS_CFM: 756 asp_cfg_val |= CS42L42_ASP_MASTER_MODE << --- 62 unchanged lines hidden (view full) --- 819 * legal. 820 */ 821 if (cs42l42->sclk) 822 return 0; 823 824 /* Machine driver has not set a SCLK, limit bottom end to 44.1 kHz */ 825 return snd_pcm_hw_constraint_minmax(substream->runtime, 826 SNDRV_PCM_HW_PARAM_RATE, | 759static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) 760{ 761 struct snd_soc_component *component = codec_dai->component; 762 u32 asp_cfg_val = 0; 763 764 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 765 case SND_SOC_DAIFMT_CBS_CFM: 766 asp_cfg_val |= CS42L42_ASP_MASTER_MODE << --- 62 unchanged lines hidden (view full) --- 829 * legal. 830 */ 831 if (cs42l42->sclk) 832 return 0; 833 834 /* Machine driver has not set a SCLK, limit bottom end to 44.1 kHz */ 835 return snd_pcm_hw_constraint_minmax(substream->runtime, 836 SNDRV_PCM_HW_PARAM_RATE, |
827 44100, 192000); | 837 44100, 96000); |
828} 829 830static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, 831 struct snd_pcm_hw_params *params, 832 struct snd_soc_dai *dai) 833{ 834 struct snd_soc_component *component = dai->component; 835 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 836 unsigned int channels = params_channels(params); 837 unsigned int width = (params_width(params) / 8) - 1; 838 unsigned int val = 0; | 838} 839 840static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, 841 struct snd_pcm_hw_params *params, 842 struct snd_soc_dai *dai) 843{ 844 struct snd_soc_component *component = dai->component; 845 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 846 unsigned int channels = params_channels(params); 847 unsigned int width = (params_width(params) / 8) - 1; 848 unsigned int val = 0; |
849 int ret; |
|
839 840 cs42l42->srate = params_rate(params); 841 cs42l42->bclk = snd_soc_params_to_bclk(params); 842 843 /* I2S frame always has 2 channels even for mono audio */ 844 if (channels == 1) 845 cs42l42->bclk *= 2; 846 847 /* 848 * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being 849 * more than assumed (which would result in overclocking). 850 */ 851 if (params_width(params) == 24) 852 cs42l42->bclk = (cs42l42->bclk / 3) * 4; 853 | 850 851 cs42l42->srate = params_rate(params); 852 cs42l42->bclk = snd_soc_params_to_bclk(params); 853 854 /* I2S frame always has 2 channels even for mono audio */ 855 if (channels == 1) 856 cs42l42->bclk *= 2; 857 858 /* 859 * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being 860 * more than assumed (which would result in overclocking). 861 */ 862 if (params_width(params) == 24) 863 cs42l42->bclk = (cs42l42->bclk / 3) * 4; 864 |
854 switch(substream->stream) { | 865 switch (substream->stream) { |
855 case SNDRV_PCM_STREAM_CAPTURE: | 866 case SNDRV_PCM_STREAM_CAPTURE: |
856 if (channels == 2) { 857 val |= CS42L42_ASP_TX_CH2_AP_MASK; 858 val |= width << CS42L42_ASP_TX_CH2_RES_SHIFT; 859 } 860 val |= width << CS42L42_ASP_TX_CH1_RES_SHIFT; | 867 /* channel 2 on high LRCLK */ 868 val = CS42L42_ASP_TX_CH2_AP_MASK | 869 (width << CS42L42_ASP_TX_CH2_RES_SHIFT) | 870 (width << CS42L42_ASP_TX_CH1_RES_SHIFT); |
861 862 snd_soc_component_update_bits(component, CS42L42_ASP_TX_CH_AP_RES, 863 CS42L42_ASP_TX_CH1_AP_MASK | CS42L42_ASP_TX_CH2_AP_MASK | 864 CS42L42_ASP_TX_CH2_RES_MASK | CS42L42_ASP_TX_CH1_RES_MASK, val); 865 break; 866 case SNDRV_PCM_STREAM_PLAYBACK: 867 val |= width << CS42L42_ASP_RX_CH_RES_SHIFT; 868 /* channel 1 on low LRCLK */ --- 16 unchanged lines hidden (view full) --- 885 CS42L42_ASP_RX0_CH_EN_MASK, 886 BIT(CS42L42_ASP_RX0_CH1_SHIFT) | 887 BIT(CS42L42_ASP_RX0_CH2_SHIFT)); 888 break; 889 default: 890 break; 891 } 892 | 871 872 snd_soc_component_update_bits(component, CS42L42_ASP_TX_CH_AP_RES, 873 CS42L42_ASP_TX_CH1_AP_MASK | CS42L42_ASP_TX_CH2_AP_MASK | 874 CS42L42_ASP_TX_CH2_RES_MASK | CS42L42_ASP_TX_CH1_RES_MASK, val); 875 break; 876 case SNDRV_PCM_STREAM_PLAYBACK: 877 val |= width << CS42L42_ASP_RX_CH_RES_SHIFT; 878 /* channel 1 on low LRCLK */ --- 16 unchanged lines hidden (view full) --- 895 CS42L42_ASP_RX0_CH_EN_MASK, 896 BIT(CS42L42_ASP_RX0_CH1_SHIFT) | 897 BIT(CS42L42_ASP_RX0_CH2_SHIFT)); 898 break; 899 default: 900 break; 901 } 902 |
893 return cs42l42_pll_config(component); | 903 ret = cs42l42_pll_config(component); 904 if (ret) 905 return ret; 906 907 cs42l42_src_config(component, params_rate(params)); 908 909 return 0; |
894} 895 896static int cs42l42_set_sysclk(struct snd_soc_dai *dai, 897 int clk_id, unsigned int freq, int dir) 898{ 899 struct snd_soc_component *component = dai->component; 900 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 901 int i; --- 27 unchanged lines hidden (view full) --- 929 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 930 snd_soc_component_update_bits(component, CS42L42_HP_CTL, 931 CS42L42_HP_ANA_AMUTE_MASK | 932 CS42L42_HP_ANA_BMUTE_MASK, 933 CS42L42_HP_ANA_AMUTE_MASK | 934 CS42L42_HP_ANA_BMUTE_MASK); 935 936 cs42l42->stream_use &= ~(1 << stream); | 910} 911 912static int cs42l42_set_sysclk(struct snd_soc_dai *dai, 913 int clk_id, unsigned int freq, int dir) 914{ 915 struct snd_soc_component *component = dai->component; 916 struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); 917 int i; --- 27 unchanged lines hidden (view full) --- 945 if (stream == SNDRV_PCM_STREAM_PLAYBACK) 946 snd_soc_component_update_bits(component, CS42L42_HP_CTL, 947 CS42L42_HP_ANA_AMUTE_MASK | 948 CS42L42_HP_ANA_BMUTE_MASK, 949 CS42L42_HP_ANA_AMUTE_MASK | 950 CS42L42_HP_ANA_BMUTE_MASK); 951 952 cs42l42->stream_use &= ~(1 << stream); |
937 if(!cs42l42->stream_use) { | 953 if (!cs42l42->stream_use) { |
938 /* 939 * Switch to the internal oscillator. 940 * SCLK must remain running until after this clock switch. 941 * Without a source of clock the I2C bus doesn't work. 942 */ 943 regmap_multi_reg_write(cs42l42->regmap, cs42l42_to_osc_seq, 944 ARRAY_SIZE(cs42l42_to_osc_seq)); 945 --- 54 unchanged lines hidden (view full) --- 1000 } 1001 } 1002 1003 return 0; 1004} 1005 1006#define CS42L42_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 1007 SNDRV_PCM_FMTBIT_S24_LE |\ | 954 /* 955 * Switch to the internal oscillator. 956 * SCLK must remain running until after this clock switch. 957 * Without a source of clock the I2C bus doesn't work. 958 */ 959 regmap_multi_reg_write(cs42l42->regmap, cs42l42_to_osc_seq, 960 ARRAY_SIZE(cs42l42_to_osc_seq)); 961 --- 54 unchanged lines hidden (view full) --- 1016 } 1017 } 1018 1019 return 0; 1020} 1021 1022#define CS42L42_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 1023 SNDRV_PCM_FMTBIT_S24_LE |\ |
1008 SNDRV_PCM_FMTBIT_S32_LE ) | 1024 SNDRV_PCM_FMTBIT_S32_LE) |
1009 1010static const struct snd_soc_dai_ops cs42l42_ops = { 1011 .startup = cs42l42_dai_startup, 1012 .hw_params = cs42l42_pcm_hw_params, 1013 .set_fmt = cs42l42_set_dai_fmt, 1014 .set_sysclk = cs42l42_set_sysclk, 1015 .mute_stream = cs42l42_mute_stream, 1016}; 1017 1018static struct snd_soc_dai_driver cs42l42_dai = { 1019 .name = "cs42l42", 1020 .playback = { 1021 .stream_name = "Playback", 1022 .channels_min = 1, 1023 .channels_max = 2, | 1025 1026static const struct snd_soc_dai_ops cs42l42_ops = { 1027 .startup = cs42l42_dai_startup, 1028 .hw_params = cs42l42_pcm_hw_params, 1029 .set_fmt = cs42l42_set_dai_fmt, 1030 .set_sysclk = cs42l42_set_sysclk, 1031 .mute_stream = cs42l42_mute_stream, 1032}; 1033 1034static struct snd_soc_dai_driver cs42l42_dai = { 1035 .name = "cs42l42", 1036 .playback = { 1037 .stream_name = "Playback", 1038 .channels_min = 1, 1039 .channels_max = 2, |
1024 .rates = SNDRV_PCM_RATE_8000_192000, | 1040 .rates = SNDRV_PCM_RATE_8000_96000, |
1025 .formats = CS42L42_FORMATS, 1026 }, 1027 .capture = { 1028 .stream_name = "Capture", 1029 .channels_min = 1, 1030 .channels_max = 2, | 1041 .formats = CS42L42_FORMATS, 1042 }, 1043 .capture = { 1044 .stream_name = "Capture", 1045 .channels_min = 1, 1046 .channels_max = 2, |
1031 .rates = SNDRV_PCM_RATE_8000_192000, | 1047 .rates = SNDRV_PCM_RATE_8000_96000, |
1032 .formats = CS42L42_FORMATS, 1033 }, 1034 .symmetric_rate = 1, 1035 .symmetric_sample_bits = 1, 1036 .ops = &cs42l42_ops, 1037}; 1038 | 1048 .formats = CS42L42_FORMATS, 1049 }, 1050 .symmetric_rate = 1, 1051 .symmetric_sample_bits = 1, 1052 .ops = &cs42l42_ops, 1053}; 1054 |
1055static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42) 1056{ 1057 unsigned int hs_det_status; 1058 unsigned int hs_det_comp1; 1059 unsigned int hs_det_comp2; 1060 unsigned int hs_det_sw; 1061 1062 /* Set hs detect to manual, active mode */ 1063 regmap_update_bits(cs42l42->regmap, 1064 CS42L42_HSDET_CTL2, 1065 CS42L42_HSDET_CTRL_MASK | 1066 CS42L42_HSDET_SET_MASK | 1067 CS42L42_HSBIAS_REF_MASK | 1068 CS42L42_HSDET_AUTO_TIME_MASK, 1069 (1 << CS42L42_HSDET_CTRL_SHIFT) | 1070 (0 << CS42L42_HSDET_SET_SHIFT) | 1071 (0 << CS42L42_HSBIAS_REF_SHIFT) | 1072 (0 << CS42L42_HSDET_AUTO_TIME_SHIFT)); 1073 1074 /* Configure HS DET comparator reference levels. */ 1075 regmap_update_bits(cs42l42->regmap, 1076 CS42L42_HSDET_CTL1, 1077 CS42L42_HSDET_COMP1_LVL_MASK | 1078 CS42L42_HSDET_COMP2_LVL_MASK, 1079 (CS42L42_HSDET_COMP1_LVL_VAL << CS42L42_HSDET_COMP1_LVL_SHIFT) | 1080 (CS42L42_HSDET_COMP2_LVL_VAL << CS42L42_HSDET_COMP2_LVL_SHIFT)); 1081 1082 /* Open the SW_HSB_HS3 switch and close SW_HSB_HS4 for a Type 1 headset. */ 1083 regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP1); 1084 1085 msleep(100); 1086 1087 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status); 1088 1089 hs_det_comp1 = (hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >> 1090 CS42L42_HSDET_COMP1_OUT_SHIFT; 1091 hs_det_comp2 = (hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >> 1092 CS42L42_HSDET_COMP2_OUT_SHIFT; 1093 1094 /* Close the SW_HSB_HS3 switch for a Type 2 headset. */ 1095 regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP2); 1096 1097 msleep(100); 1098 1099 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status); 1100 1101 hs_det_comp1 |= ((hs_det_status & CS42L42_HSDET_COMP1_OUT_MASK) >> 1102 CS42L42_HSDET_COMP1_OUT_SHIFT) << 1; 1103 hs_det_comp2 |= ((hs_det_status & CS42L42_HSDET_COMP2_OUT_MASK) >> 1104 CS42L42_HSDET_COMP2_OUT_SHIFT) << 1; 1105 1106 /* Use Comparator 1 with 1.25V Threshold. */ 1107 switch (hs_det_comp1) { 1108 case CS42L42_HSDET_COMP_TYPE1: 1109 cs42l42->hs_type = CS42L42_PLUG_CTIA; 1110 hs_det_sw = CS42L42_HSDET_SW_TYPE1; 1111 break; 1112 case CS42L42_HSDET_COMP_TYPE2: 1113 cs42l42->hs_type = CS42L42_PLUG_OMTP; 1114 hs_det_sw = CS42L42_HSDET_SW_TYPE2; 1115 break; 1116 default: 1117 /* Fallback to Comparator 2 with 1.75V Threshold. */ 1118 switch (hs_det_comp2) { 1119 case CS42L42_HSDET_COMP_TYPE1: 1120 cs42l42->hs_type = CS42L42_PLUG_CTIA; 1121 hs_det_sw = CS42L42_HSDET_SW_TYPE1; 1122 break; 1123 case CS42L42_HSDET_COMP_TYPE2: 1124 cs42l42->hs_type = CS42L42_PLUG_OMTP; 1125 hs_det_sw = CS42L42_HSDET_SW_TYPE2; 1126 break; 1127 case CS42L42_HSDET_COMP_TYPE3: 1128 cs42l42->hs_type = CS42L42_PLUG_HEADPHONE; 1129 hs_det_sw = CS42L42_HSDET_SW_TYPE3; 1130 break; 1131 default: 1132 cs42l42->hs_type = CS42L42_PLUG_INVALID; 1133 hs_det_sw = CS42L42_HSDET_SW_TYPE4; 1134 break; 1135 } 1136 } 1137 1138 /* Set Switches */ 1139 regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, hs_det_sw); 1140 1141 /* Set HSDET mode to Manual—Disabled */ 1142 regmap_update_bits(cs42l42->regmap, 1143 CS42L42_HSDET_CTL2, 1144 CS42L42_HSDET_CTRL_MASK | 1145 CS42L42_HSDET_SET_MASK | 1146 CS42L42_HSBIAS_REF_MASK | 1147 CS42L42_HSDET_AUTO_TIME_MASK, 1148 (0 << CS42L42_HSDET_CTRL_SHIFT) | 1149 (0 << CS42L42_HSDET_SET_SHIFT) | 1150 (0 << CS42L42_HSBIAS_REF_SHIFT) | 1151 (0 << CS42L42_HSDET_AUTO_TIME_SHIFT)); 1152 1153 /* Configure HS DET comparator reference levels. */ 1154 regmap_update_bits(cs42l42->regmap, 1155 CS42L42_HSDET_CTL1, 1156 CS42L42_HSDET_COMP1_LVL_MASK | 1157 CS42L42_HSDET_COMP2_LVL_MASK, 1158 (CS42L42_HSDET_COMP1_LVL_DEFAULT << CS42L42_HSDET_COMP1_LVL_SHIFT) | 1159 (CS42L42_HSDET_COMP2_LVL_DEFAULT << CS42L42_HSDET_COMP2_LVL_SHIFT)); 1160} 1161 |
|
1039static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) 1040{ 1041 unsigned int hs_det_status; 1042 unsigned int int_status; 1043 | 1162static void cs42l42_process_hs_type_detect(struct cs42l42_private *cs42l42) 1163{ 1164 unsigned int hs_det_status; 1165 unsigned int int_status; 1166 |
1167 /* Read and save the hs detection result */ 1168 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status); 1169 |
|
1044 /* Mask the auto detect interrupt */ 1045 regmap_update_bits(cs42l42->regmap, 1046 CS42L42_CODEC_INT_MASK, 1047 CS42L42_PDN_DONE_MASK | 1048 CS42L42_HSDET_AUTO_DONE_MASK, 1049 (1 << CS42L42_PDN_DONE_SHIFT) | 1050 (1 << CS42L42_HSDET_AUTO_DONE_SHIFT)); 1051 | 1170 /* Mask the auto detect interrupt */ 1171 regmap_update_bits(cs42l42->regmap, 1172 CS42L42_CODEC_INT_MASK, 1173 CS42L42_PDN_DONE_MASK | 1174 CS42L42_HSDET_AUTO_DONE_MASK, 1175 (1 << CS42L42_PDN_DONE_SHIFT) | 1176 (1 << CS42L42_HSDET_AUTO_DONE_SHIFT)); 1177 |
1178 1179 cs42l42->hs_type = (hs_det_status & CS42L42_HSDET_TYPE_MASK) >> 1180 CS42L42_HSDET_TYPE_SHIFT; 1181 |
|
1052 /* Set hs detect to automatic, disabled mode */ 1053 regmap_update_bits(cs42l42->regmap, 1054 CS42L42_HSDET_CTL2, 1055 CS42L42_HSDET_CTRL_MASK | 1056 CS42L42_HSDET_SET_MASK | 1057 CS42L42_HSBIAS_REF_MASK | 1058 CS42L42_HSDET_AUTO_TIME_MASK, 1059 (2 << CS42L42_HSDET_CTRL_SHIFT) | 1060 (2 << CS42L42_HSDET_SET_SHIFT) | 1061 (0 << CS42L42_HSBIAS_REF_SHIFT) | 1062 (3 << CS42L42_HSDET_AUTO_TIME_SHIFT)); 1063 | 1182 /* Set hs detect to automatic, disabled mode */ 1183 regmap_update_bits(cs42l42->regmap, 1184 CS42L42_HSDET_CTL2, 1185 CS42L42_HSDET_CTRL_MASK | 1186 CS42L42_HSDET_SET_MASK | 1187 CS42L42_HSBIAS_REF_MASK | 1188 CS42L42_HSDET_AUTO_TIME_MASK, 1189 (2 << CS42L42_HSDET_CTRL_SHIFT) | 1190 (2 << CS42L42_HSDET_SET_SHIFT) | 1191 (0 << CS42L42_HSBIAS_REF_SHIFT) | 1192 (3 << CS42L42_HSDET_AUTO_TIME_SHIFT)); 1193 |
1064 /* Read and save the hs detection result */ 1065 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status); | 1194 /* Run Manual detection if auto detect has not found a headset. 1195 * We Re-Run with Manual Detection if the original detection was invalid or headphones, 1196 * to ensure that a headset mic is detected in all cases. 1197 */ 1198 if (cs42l42->hs_type == CS42L42_PLUG_INVALID || 1199 cs42l42->hs_type == CS42L42_PLUG_HEADPHONE) { 1200 dev_dbg(cs42l42->dev, "Running Manual Detection Fallback\n"); 1201 cs42l42_manual_hs_type_detect(cs42l42); 1202 } |
1066 | 1203 |
1067 cs42l42->hs_type = (hs_det_status & CS42L42_HSDET_TYPE_MASK) >> 1068 CS42L42_HSDET_TYPE_SHIFT; 1069 | |
1070 /* Set up button detection */ 1071 if ((cs42l42->hs_type == CS42L42_PLUG_CTIA) || 1072 (cs42l42->hs_type == CS42L42_PLUG_OMTP)) { 1073 /* Set auto HS bias settings to default */ 1074 regmap_update_bits(cs42l42->regmap, 1075 CS42L42_HSBIAS_SC_AUTOCTL, 1076 CS42L42_HSBIAS_SENSE_EN_MASK | 1077 CS42L42_AUTO_HSBIAS_HIZ_MASK | --- 279 unchanged lines hidden (view full) --- 1357 regmap_read(cs42l42->regmap, CS42L42_DET_STATUS2, 1358 &detect_status); 1359 } while ((detect_status & CS42L42_HS_TRUE_MASK) && 1360 (++bias_level < CS42L42_NUM_BIASES)); 1361 1362 switch (bias_level) { 1363 case 1: /* Function C button press */ 1364 bias_level = SND_JACK_BTN_2; | 1204 /* Set up button detection */ 1205 if ((cs42l42->hs_type == CS42L42_PLUG_CTIA) || 1206 (cs42l42->hs_type == CS42L42_PLUG_OMTP)) { 1207 /* Set auto HS bias settings to default */ 1208 regmap_update_bits(cs42l42->regmap, 1209 CS42L42_HSBIAS_SC_AUTOCTL, 1210 CS42L42_HSBIAS_SENSE_EN_MASK | 1211 CS42L42_AUTO_HSBIAS_HIZ_MASK | --- 279 unchanged lines hidden (view full) --- 1491 regmap_read(cs42l42->regmap, CS42L42_DET_STATUS2, 1492 &detect_status); 1493 } while ((detect_status & CS42L42_HS_TRUE_MASK) && 1494 (++bias_level < CS42L42_NUM_BIASES)); 1495 1496 switch (bias_level) { 1497 case 1: /* Function C button press */ 1498 bias_level = SND_JACK_BTN_2; |
1365 dev_dbg(cs42l42->component->dev, "Function C button press\n"); | 1499 dev_dbg(cs42l42->dev, "Function C button press\n"); |
1366 break; 1367 case 2: /* Function B button press */ 1368 bias_level = SND_JACK_BTN_1; | 1500 break; 1501 case 2: /* Function B button press */ 1502 bias_level = SND_JACK_BTN_1; |
1369 dev_dbg(cs42l42->component->dev, "Function B button press\n"); | 1503 dev_dbg(cs42l42->dev, "Function B button press\n"); |
1370 break; 1371 case 3: /* Function D button press */ 1372 bias_level = SND_JACK_BTN_3; | 1504 break; 1505 case 3: /* Function D button press */ 1506 bias_level = SND_JACK_BTN_3; |
1373 dev_dbg(cs42l42->component->dev, "Function D button press\n"); | 1507 dev_dbg(cs42l42->dev, "Function D button press\n"); |
1374 break; 1375 case 4: /* Function A button press */ 1376 bias_level = SND_JACK_BTN_0; | 1508 break; 1509 case 4: /* Function A button press */ 1510 bias_level = SND_JACK_BTN_0; |
1377 dev_dbg(cs42l42->component->dev, "Function A button press\n"); | 1511 dev_dbg(cs42l42->dev, "Function A button press\n"); |
1378 break; 1379 default: 1380 bias_level = 0; 1381 break; 1382 } 1383 1384 /* Set button detect level sensitivity back to default */ 1385 regmap_update_bits(cs42l42->regmap, --- 57 unchanged lines hidden (view full) --- 1443 CS42L42_PLL_LOCK_VAL_MASK}, 1444 {CS42L42_TSRS_PLUG_STATUS, CS42L42_TSRS_PLUG_INT_MASK, 1445 CS42L42_TSRS_PLUG_VAL_MASK} 1446}; 1447 1448static irqreturn_t cs42l42_irq_thread(int irq, void *data) 1449{ 1450 struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data; | 1512 break; 1513 default: 1514 bias_level = 0; 1515 break; 1516 } 1517 1518 /* Set button detect level sensitivity back to default */ 1519 regmap_update_bits(cs42l42->regmap, --- 57 unchanged lines hidden (view full) --- 1577 CS42L42_PLL_LOCK_VAL_MASK}, 1578 {CS42L42_TSRS_PLUG_STATUS, CS42L42_TSRS_PLUG_INT_MASK, 1579 CS42L42_TSRS_PLUG_VAL_MASK} 1580}; 1581 1582static irqreturn_t cs42l42_irq_thread(int irq, void *data) 1583{ 1584 struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data; |
1451 struct snd_soc_component *component = cs42l42->component; | |
1452 unsigned int stickies[12]; 1453 unsigned int masks[12]; 1454 unsigned int current_plug_status; 1455 unsigned int current_button_status; 1456 unsigned int i; 1457 int report = 0; 1458 1459 --- 17 unchanged lines hidden (view full) --- 1477 (CS42L42_M_DETECT_TF_MASK | 1478 CS42L42_M_DETECT_FT_MASK | 1479 CS42L42_M_HSBIAS_HIZ_MASK); 1480 1481 /* Check auto-detect status */ 1482 if ((~masks[5]) & irq_params_table[5].mask) { 1483 if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) { 1484 cs42l42_process_hs_type_detect(cs42l42); | 1585 unsigned int stickies[12]; 1586 unsigned int masks[12]; 1587 unsigned int current_plug_status; 1588 unsigned int current_button_status; 1589 unsigned int i; 1590 int report = 0; 1591 1592 --- 17 unchanged lines hidden (view full) --- 1610 (CS42L42_M_DETECT_TF_MASK | 1611 CS42L42_M_DETECT_FT_MASK | 1612 CS42L42_M_HSBIAS_HIZ_MASK); 1613 1614 /* Check auto-detect status */ 1615 if ((~masks[5]) & irq_params_table[5].mask) { 1616 if (stickies[5] & CS42L42_HSDET_AUTO_DONE_MASK) { 1617 cs42l42_process_hs_type_detect(cs42l42); |
1485 switch(cs42l42->hs_type){ | 1618 switch (cs42l42->hs_type) { |
1486 case CS42L42_PLUG_CTIA: 1487 case CS42L42_PLUG_OMTP: 1488 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADSET, 1489 SND_JACK_HEADSET); 1490 break; 1491 case CS42L42_PLUG_HEADPHONE: 1492 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADPHONE, 1493 SND_JACK_HEADPHONE); 1494 break; 1495 default: 1496 break; 1497 } | 1619 case CS42L42_PLUG_CTIA: 1620 case CS42L42_PLUG_OMTP: 1621 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADSET, 1622 SND_JACK_HEADSET); 1623 break; 1624 case CS42L42_PLUG_HEADPHONE: 1625 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADPHONE, 1626 SND_JACK_HEADPHONE); 1627 break; 1628 default: 1629 break; 1630 } |
1498 dev_dbg(component->dev, "Auto detect done (%d)\n", cs42l42->hs_type); | 1631 dev_dbg(cs42l42->dev, "Auto detect done (%d)\n", cs42l42->hs_type); |
1499 } 1500 } 1501 1502 /* Check tip sense status */ 1503 if ((~masks[11]) & irq_params_table[11].mask) { 1504 switch (current_plug_status) { 1505 case CS42L42_TS_PLUG: 1506 if (cs42l42->plug_state != CS42L42_TS_PLUG) { 1507 cs42l42->plug_state = CS42L42_TS_PLUG; 1508 cs42l42_init_hs_type_detect(cs42l42); 1509 } 1510 break; 1511 1512 case CS42L42_TS_UNPLUG: 1513 if (cs42l42->plug_state != CS42L42_TS_UNPLUG) { 1514 cs42l42->plug_state = CS42L42_TS_UNPLUG; 1515 cs42l42_cancel_hs_type_detect(cs42l42); 1516 | 1632 } 1633 } 1634 1635 /* Check tip sense status */ 1636 if ((~masks[11]) & irq_params_table[11].mask) { 1637 switch (current_plug_status) { 1638 case CS42L42_TS_PLUG: 1639 if (cs42l42->plug_state != CS42L42_TS_PLUG) { 1640 cs42l42->plug_state = CS42L42_TS_PLUG; 1641 cs42l42_init_hs_type_detect(cs42l42); 1642 } 1643 break; 1644 1645 case CS42L42_TS_UNPLUG: 1646 if (cs42l42->plug_state != CS42L42_TS_UNPLUG) { 1647 cs42l42->plug_state = CS42L42_TS_UNPLUG; 1648 cs42l42_cancel_hs_type_detect(cs42l42); 1649 |
1517 switch(cs42l42->hs_type){ | 1650 switch (cs42l42->hs_type) { |
1518 case CS42L42_PLUG_CTIA: 1519 case CS42L42_PLUG_OMTP: 1520 snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADSET); 1521 break; 1522 case CS42L42_PLUG_HEADPHONE: 1523 snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADPHONE); 1524 break; 1525 default: 1526 break; 1527 } 1528 snd_soc_jack_report(cs42l42->jack, 0, 1529 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 1530 SND_JACK_BTN_2 | SND_JACK_BTN_3); 1531 | 1651 case CS42L42_PLUG_CTIA: 1652 case CS42L42_PLUG_OMTP: 1653 snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADSET); 1654 break; 1655 case CS42L42_PLUG_HEADPHONE: 1656 snd_soc_jack_report(cs42l42->jack, 0, SND_JACK_HEADPHONE); 1657 break; 1658 default: 1659 break; 1660 } 1661 snd_soc_jack_report(cs42l42->jack, 0, 1662 SND_JACK_BTN_0 | SND_JACK_BTN_1 | 1663 SND_JACK_BTN_2 | SND_JACK_BTN_3); 1664 |
1532 dev_dbg(component->dev, "Unplug event\n"); | 1665 dev_dbg(cs42l42->dev, "Unplug event\n"); |
1533 } 1534 break; 1535 1536 default: 1537 if (cs42l42->plug_state != CS42L42_TS_TRANS) 1538 cs42l42->plug_state = CS42L42_TS_TRANS; 1539 } 1540 } 1541 1542 /* Check button detect status */ 1543 if (cs42l42->plug_state == CS42L42_TS_PLUG && ((~masks[7]) & irq_params_table[7].mask)) { 1544 if (!(current_button_status & 1545 CS42L42_M_HSBIAS_HIZ_MASK)) { 1546 1547 if (current_button_status & CS42L42_M_DETECT_TF_MASK) { | 1666 } 1667 break; 1668 1669 default: 1670 if (cs42l42->plug_state != CS42L42_TS_TRANS) 1671 cs42l42->plug_state = CS42L42_TS_TRANS; 1672 } 1673 } 1674 1675 /* Check button detect status */ 1676 if (cs42l42->plug_state == CS42L42_TS_PLUG && ((~masks[7]) & irq_params_table[7].mask)) { 1677 if (!(current_button_status & 1678 CS42L42_M_HSBIAS_HIZ_MASK)) { 1679 1680 if (current_button_status & CS42L42_M_DETECT_TF_MASK) { |
1548 dev_dbg(component->dev, "Button released\n"); | 1681 dev_dbg(cs42l42->dev, "Button released\n"); |
1549 report = 0; 1550 } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) { 1551 report = cs42l42_handle_button_press(cs42l42); 1552 1553 } 1554 snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 | 1555 SND_JACK_BTN_2 | SND_JACK_BTN_3); 1556 } --- 96 unchanged lines hidden (view full) --- 1653 1654 regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, 1655 CS42L42_RS_PLUG_MASK | 1656 CS42L42_RS_UNPLUG_MASK | 1657 CS42L42_TS_PLUG_MASK | 1658 CS42L42_TS_UNPLUG_MASK, 1659 (1 << CS42L42_RS_PLUG_SHIFT) | 1660 (1 << CS42L42_RS_UNPLUG_SHIFT) | | 1682 report = 0; 1683 } else if (current_button_status & CS42L42_M_DETECT_FT_MASK) { 1684 report = cs42l42_handle_button_press(cs42l42); 1685 1686 } 1687 snd_soc_jack_report(cs42l42->jack, report, SND_JACK_BTN_0 | SND_JACK_BTN_1 | 1688 SND_JACK_BTN_2 | SND_JACK_BTN_3); 1689 } --- 96 unchanged lines hidden (view full) --- 1786 1787 regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, 1788 CS42L42_RS_PLUG_MASK | 1789 CS42L42_RS_UNPLUG_MASK | 1790 CS42L42_TS_PLUG_MASK | 1791 CS42L42_TS_UNPLUG_MASK, 1792 (1 << CS42L42_RS_PLUG_SHIFT) | 1793 (1 << CS42L42_RS_UNPLUG_SHIFT) | |
1661 (1 << CS42L42_TS_PLUG_SHIFT) | 1662 (1 << CS42L42_TS_UNPLUG_SHIFT)); | 1794 (0 << CS42L42_TS_PLUG_SHIFT) | 1795 (0 << CS42L42_TS_UNPLUG_SHIFT)); |
1663} 1664 1665static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42) 1666{ 1667 unsigned int reg; 1668 1669 cs42l42->hs_type = CS42L42_PLUG_INVALID; 1670 --- 223 unchanged lines hidden (view full) --- 1894 int ret, i, devid; 1895 unsigned int reg; 1896 1897 cs42l42 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l42_private), 1898 GFP_KERNEL); 1899 if (!cs42l42) 1900 return -ENOMEM; 1901 | 1796} 1797 1798static void cs42l42_setup_hs_type_detect(struct cs42l42_private *cs42l42) 1799{ 1800 unsigned int reg; 1801 1802 cs42l42->hs_type = CS42L42_PLUG_INVALID; 1803 --- 223 unchanged lines hidden (view full) --- 2027 int ret, i, devid; 2028 unsigned int reg; 2029 2030 cs42l42 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l42_private), 2031 GFP_KERNEL); 2032 if (!cs42l42) 2033 return -ENOMEM; 2034 |
2035 cs42l42->dev = &i2c_client->dev; |
|
1902 i2c_set_clientdata(i2c_client, cs42l42); 1903 1904 cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); 1905 if (IS_ERR(cs42l42->regmap)) { 1906 ret = PTR_ERR(cs42l42->regmap); 1907 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); 1908 return ret; 1909 } --- 27 unchanged lines hidden (view full) --- 1937 } 1938 1939 if (cs42l42->reset_gpio) { 1940 dev_dbg(&i2c_client->dev, "Found reset GPIO\n"); 1941 gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); 1942 } 1943 usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); 1944 | 2036 i2c_set_clientdata(i2c_client, cs42l42); 2037 2038 cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); 2039 if (IS_ERR(cs42l42->regmap)) { 2040 ret = PTR_ERR(cs42l42->regmap); 2041 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); 2042 return ret; 2043 } --- 27 unchanged lines hidden (view full) --- 2071 } 2072 2073 if (cs42l42->reset_gpio) { 2074 dev_dbg(&i2c_client->dev, "Found reset GPIO\n"); 2075 gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); 2076 } 2077 usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); 2078 |
1945 /* Request IRQ */ 1946 ret = devm_request_threaded_irq(&i2c_client->dev, 1947 i2c_client->irq, 1948 NULL, cs42l42_irq_thread, 1949 IRQF_ONESHOT | IRQF_TRIGGER_LOW, 1950 "cs42l42", cs42l42); | 2079 /* Request IRQ if one was specified */ 2080 if (i2c_client->irq) { 2081 ret = devm_request_threaded_irq(&i2c_client->dev, 2082 i2c_client->irq, 2083 NULL, cs42l42_irq_thread, 2084 IRQF_ONESHOT | IRQF_TRIGGER_LOW, 2085 "cs42l42", cs42l42); 2086 if (ret == -EPROBE_DEFER) { 2087 goto err_disable; 2088 } else if (ret != 0) { 2089 dev_err(&i2c_client->dev, 2090 "Failed to request IRQ: %d\n", ret); 2091 goto err_disable; 2092 } 2093 } |
1951 | 2094 |
1952 if (ret != 0) 1953 dev_err(&i2c_client->dev, 1954 "Failed to request IRQ: %d\n", ret); 1955 | |
1956 /* initialize codec */ 1957 devid = cirrus_read_device_id(cs42l42->regmap, CS42L42_DEVID_AB); 1958 if (devid < 0) { 1959 ret = devid; 1960 dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret); 1961 goto err_disable; 1962 } 1963 --- 53 unchanged lines hidden (view full) --- 2017 cs42l42->supplies); 2018 return ret; 2019} 2020 2021static int cs42l42_i2c_remove(struct i2c_client *i2c_client) 2022{ 2023 struct cs42l42_private *cs42l42 = i2c_get_clientdata(i2c_client); 2024 | 2095 /* initialize codec */ 2096 devid = cirrus_read_device_id(cs42l42->regmap, CS42L42_DEVID_AB); 2097 if (devid < 0) { 2098 ret = devid; 2099 dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret); 2100 goto err_disable; 2101 } 2102 --- 53 unchanged lines hidden (view full) --- 2156 cs42l42->supplies); 2157 return ret; 2158} 2159 2160static int cs42l42_i2c_remove(struct i2c_client *i2c_client) 2161{ 2162 struct cs42l42_private *cs42l42 = i2c_get_clientdata(i2c_client); 2163 |
2025 devm_free_irq(&i2c_client->dev, i2c_client->irq, cs42l42); 2026 pm_runtime_suspend(&i2c_client->dev); 2027 pm_runtime_disable(&i2c_client->dev); | 2164 if (i2c_client->irq) 2165 devm_free_irq(&i2c_client->dev, i2c_client->irq, cs42l42); |
2028 | 2166 |
2029 return 0; 2030} 2031 2032#ifdef CONFIG_PM 2033static int cs42l42_runtime_suspend(struct device *dev) 2034{ 2035 struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); 2036 2037 regcache_cache_only(cs42l42->regmap, true); 2038 regcache_mark_dirty(cs42l42->regmap); 2039 2040 /* Hold down reset */ | |
2041 gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); | 2167 gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); |
2168 regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); |
|
2042 | 2169 |
2043 /* remove power */ 2044 regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), 2045 cs42l42->supplies); 2046 | |
2047 return 0; 2048} 2049 | 2170 return 0; 2171} 2172 |
2050static int cs42l42_runtime_resume(struct device *dev) 2051{ 2052 struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); 2053 int ret; 2054 2055 /* Enable power */ 2056 ret = regulator_bulk_enable(ARRAY_SIZE(cs42l42->supplies), 2057 cs42l42->supplies); 2058 if (ret != 0) { 2059 dev_err(dev, "Failed to enable supplies: %d\n", 2060 ret); 2061 return ret; 2062 } 2063 2064 gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); 2065 usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); 2066 2067 regcache_cache_only(cs42l42->regmap, false); 2068 regcache_sync(cs42l42->regmap); 2069 2070 return 0; 2071} 2072#endif 2073 2074static const struct dev_pm_ops cs42l42_runtime_pm = { 2075 SET_RUNTIME_PM_OPS(cs42l42_runtime_suspend, cs42l42_runtime_resume, 2076 NULL) 2077}; 2078 | |
2079#ifdef CONFIG_OF 2080static const struct of_device_id cs42l42_of_match[] = { 2081 { .compatible = "cirrus,cs42l42", }, 2082 {} 2083}; 2084MODULE_DEVICE_TABLE(of, cs42l42_of_match); 2085#endif 2086 --- 10 unchanged lines hidden (view full) --- 2097 {} 2098}; 2099 2100MODULE_DEVICE_TABLE(i2c, cs42l42_id); 2101 2102static struct i2c_driver cs42l42_i2c_driver = { 2103 .driver = { 2104 .name = "cs42l42", | 2173#ifdef CONFIG_OF 2174static const struct of_device_id cs42l42_of_match[] = { 2175 { .compatible = "cirrus,cs42l42", }, 2176 {} 2177}; 2178MODULE_DEVICE_TABLE(of, cs42l42_of_match); 2179#endif 2180 --- 10 unchanged lines hidden (view full) --- 2191 {} 2192}; 2193 2194MODULE_DEVICE_TABLE(i2c, cs42l42_id); 2195 2196static struct i2c_driver cs42l42_i2c_driver = { 2197 .driver = { 2198 .name = "cs42l42", |
2105 .pm = &cs42l42_runtime_pm, | |
2106 .of_match_table = of_match_ptr(cs42l42_of_match), 2107 .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), 2108 }, 2109 .id_table = cs42l42_id, 2110 .probe = cs42l42_i2c_probe, 2111 .remove = cs42l42_i2c_remove, 2112}; 2113 2114module_i2c_driver(cs42l42_i2c_driver); 2115 2116MODULE_DESCRIPTION("ASoC CS42L42 driver"); 2117MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>"); 2118MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); 2119MODULE_AUTHOR("Michael White, Cirrus Logic Inc, <michael.white@cirrus.com>"); 2120MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>"); 2121MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); 2122MODULE_AUTHOR("Vitaly Rodionov <vitalyr@opensource.cirrus.com>"); 2123MODULE_LICENSE("GPL"); | 2199 .of_match_table = of_match_ptr(cs42l42_of_match), 2200 .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), 2201 }, 2202 .id_table = cs42l42_id, 2203 .probe = cs42l42_i2c_probe, 2204 .remove = cs42l42_i2c_remove, 2205}; 2206 2207module_i2c_driver(cs42l42_i2c_driver); 2208 2209MODULE_DESCRIPTION("ASoC CS42L42 driver"); 2210MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, <james.schulman@cirrus.com>"); 2211MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); 2212MODULE_AUTHOR("Michael White, Cirrus Logic Inc, <michael.white@cirrus.com>"); 2213MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>"); 2214MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); 2215MODULE_AUTHOR("Vitaly Rodionov <vitalyr@opensource.cirrus.com>"); 2216MODULE_LICENSE("GPL"); |