1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // ALSA SoC CX20721/CX20723 codec driver 4 // 5 // Copyright: (C) 2017 Conexant Systems, Inc. 6 // Author: Simon Ho, <Simon.ho@conexant.com> 7 // 8 // TODO: add support for TDM mode. 9 // 10 11 #include <linux/acpi.h> 12 #include <linux/clk.h> 13 #include <linux/delay.h> 14 #include <linux/gpio.h> 15 #include <linux/init.h> 16 #include <linux/i2c.h> 17 #include <linux/module.h> 18 #include <linux/platform_device.h> 19 #include <linux/pm.h> 20 #include <linux/pm_runtime.h> 21 #include <linux/regmap.h> 22 #include <linux/slab.h> 23 #include <sound/core.h> 24 #include <sound/initval.h> 25 #include <sound/jack.h> 26 #include <sound/pcm.h> 27 #include <sound/pcm_params.h> 28 #include <sound/tlv.h> 29 #include <sound/soc.h> 30 #include <sound/soc-dapm.h> 31 #include "cx2072x.h" 32 33 #define PLL_OUT_HZ_48 (1024 * 3 * 48000) 34 #define BITS_PER_SLOT 8 35 36 /* codec private data */ 37 struct cx2072x_priv { 38 struct regmap *regmap; 39 struct clk *mclk; 40 unsigned int mclk_rate; 41 struct device *dev; 42 struct snd_soc_component *codec; 43 struct snd_soc_jack_gpio jack_gpio; 44 struct mutex lock; 45 unsigned int bclk_ratio; 46 bool pll_changed; 47 bool i2spcm_changed; 48 int sample_size; 49 int frame_size; 50 int sample_rate; 51 unsigned int dai_fmt; 52 bool en_aec_ref; 53 }; 54 55 /* 56 * DAC/ADC Volume 57 * 58 * max : 74 : 0 dB 59 * ( in 1 dB step ) 60 * min : 0 : -74 dB 61 */ 62 static const DECLARE_TLV_DB_SCALE(adc_tlv, -7400, 100, 0); 63 static const DECLARE_TLV_DB_SCALE(dac_tlv, -7400, 100, 0); 64 static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 1200, 0); 65 66 static const DECLARE_TLV_DB_RANGE(hpf_tlv, 67 0, 0, TLV_DB_SCALE_ITEM(120, 0, 0), 68 1, 63, TLV_DB_SCALE_ITEM(30, 30, 0) 69 ); 70 71 /* Lookup table for PRE_DIV */ 72 static const struct { 73 unsigned int mclk; 74 unsigned int div; 75 } mclk_pre_div[] = { 76 { 6144000, 1 }, 77 { 12288000, 2 }, 78 { 19200000, 3 }, 79 { 26000000, 4 }, 80 { 28224000, 5 }, 81 { 36864000, 6 }, 82 { 36864000, 7 }, 83 { 48000000, 8 }, 84 { 49152000, 8 }, 85 }; 86 87 /* 88 * cx2072x register cache. 89 */ 90 static const struct reg_default cx2072x_reg_defaults[] = { 91 { CX2072X_AFG_POWER_STATE, 0x00000003 }, 92 { CX2072X_UM_RESPONSE, 0x00000000 }, 93 { CX2072X_GPIO_DATA, 0x00000000 }, 94 { CX2072X_GPIO_ENABLE, 0x00000000 }, 95 { CX2072X_GPIO_DIRECTION, 0x00000000 }, 96 { CX2072X_GPIO_WAKE, 0x00000000 }, 97 { CX2072X_GPIO_UM_ENABLE, 0x00000000 }, 98 { CX2072X_GPIO_STICKY_MASK, 0x00000000 }, 99 { CX2072X_DAC1_CONVERTER_FORMAT, 0x00000031 }, 100 { CX2072X_DAC1_AMP_GAIN_RIGHT, 0x0000004a }, 101 { CX2072X_DAC1_AMP_GAIN_LEFT, 0x0000004a }, 102 { CX2072X_DAC1_POWER_STATE, 0x00000433 }, 103 { CX2072X_DAC1_CONVERTER_STREAM_CHANNEL, 0x00000000 }, 104 { CX2072X_DAC1_EAPD_ENABLE, 0x00000000 }, 105 { CX2072X_DAC2_CONVERTER_FORMAT, 0x00000031 }, 106 { CX2072X_DAC2_AMP_GAIN_RIGHT, 0x0000004a }, 107 { CX2072X_DAC2_AMP_GAIN_LEFT, 0x0000004a }, 108 { CX2072X_DAC2_POWER_STATE, 0x00000433 }, 109 { CX2072X_DAC2_CONVERTER_STREAM_CHANNEL, 0x00000000 }, 110 { CX2072X_ADC1_CONVERTER_FORMAT, 0x00000031 }, 111 { CX2072X_ADC1_AMP_GAIN_RIGHT_0, 0x0000004a }, 112 { CX2072X_ADC1_AMP_GAIN_LEFT_0, 0x0000004a }, 113 { CX2072X_ADC1_AMP_GAIN_RIGHT_1, 0x0000004a }, 114 { CX2072X_ADC1_AMP_GAIN_LEFT_1, 0x0000004a }, 115 { CX2072X_ADC1_AMP_GAIN_RIGHT_2, 0x0000004a }, 116 { CX2072X_ADC1_AMP_GAIN_LEFT_2, 0x0000004a }, 117 { CX2072X_ADC1_AMP_GAIN_RIGHT_3, 0x0000004a }, 118 { CX2072X_ADC1_AMP_GAIN_LEFT_3, 0x0000004a }, 119 { CX2072X_ADC1_AMP_GAIN_RIGHT_4, 0x0000004a }, 120 { CX2072X_ADC1_AMP_GAIN_LEFT_4, 0x0000004a }, 121 { CX2072X_ADC1_AMP_GAIN_RIGHT_5, 0x0000004a }, 122 { CX2072X_ADC1_AMP_GAIN_LEFT_5, 0x0000004a }, 123 { CX2072X_ADC1_AMP_GAIN_RIGHT_6, 0x0000004a }, 124 { CX2072X_ADC1_AMP_GAIN_LEFT_6, 0x0000004a }, 125 { CX2072X_ADC1_CONNECTION_SELECT_CONTROL, 0x00000000 }, 126 { CX2072X_ADC1_POWER_STATE, 0x00000433 }, 127 { CX2072X_ADC1_CONVERTER_STREAM_CHANNEL, 0x00000000 }, 128 { CX2072X_ADC2_CONVERTER_FORMAT, 0x00000031 }, 129 { CX2072X_ADC2_AMP_GAIN_RIGHT_0, 0x0000004a }, 130 { CX2072X_ADC2_AMP_GAIN_LEFT_0, 0x0000004a }, 131 { CX2072X_ADC2_AMP_GAIN_RIGHT_1, 0x0000004a }, 132 { CX2072X_ADC2_AMP_GAIN_LEFT_1, 0x0000004a }, 133 { CX2072X_ADC2_AMP_GAIN_RIGHT_2, 0x0000004a }, 134 { CX2072X_ADC2_AMP_GAIN_LEFT_2, 0x0000004a }, 135 { CX2072X_ADC2_CONNECTION_SELECT_CONTROL, 0x00000000 }, 136 { CX2072X_ADC2_POWER_STATE, 0x00000433 }, 137 { CX2072X_ADC2_CONVERTER_STREAM_CHANNEL, 0x00000000 }, 138 { CX2072X_PORTA_CONNECTION_SELECT_CTRL, 0x00000000 }, 139 { CX2072X_PORTA_POWER_STATE, 0x00000433 }, 140 { CX2072X_PORTA_PIN_CTRL, 0x000000c0 }, 141 { CX2072X_PORTA_UNSOLICITED_RESPONSE, 0x00000000 }, 142 { CX2072X_PORTA_PIN_SENSE, 0x00000000 }, 143 { CX2072X_PORTA_EAPD_BTL, 0x00000002 }, 144 { CX2072X_PORTB_POWER_STATE, 0x00000433 }, 145 { CX2072X_PORTB_PIN_CTRL, 0x00000000 }, 146 { CX2072X_PORTB_UNSOLICITED_RESPONSE, 0x00000000 }, 147 { CX2072X_PORTB_PIN_SENSE, 0x00000000 }, 148 { CX2072X_PORTB_EAPD_BTL, 0x00000002 }, 149 { CX2072X_PORTB_GAIN_RIGHT, 0x00000000 }, 150 { CX2072X_PORTB_GAIN_LEFT, 0x00000000 }, 151 { CX2072X_PORTC_POWER_STATE, 0x00000433 }, 152 { CX2072X_PORTC_PIN_CTRL, 0x00000000 }, 153 { CX2072X_PORTC_GAIN_RIGHT, 0x00000000 }, 154 { CX2072X_PORTC_GAIN_LEFT, 0x00000000 }, 155 { CX2072X_PORTD_POWER_STATE, 0x00000433 }, 156 { CX2072X_PORTD_PIN_CTRL, 0x00000020 }, 157 { CX2072X_PORTD_UNSOLICITED_RESPONSE, 0x00000000 }, 158 { CX2072X_PORTD_PIN_SENSE, 0x00000000 }, 159 { CX2072X_PORTD_GAIN_RIGHT, 0x00000000 }, 160 { CX2072X_PORTD_GAIN_LEFT, 0x00000000 }, 161 { CX2072X_PORTE_CONNECTION_SELECT_CTRL, 0x00000000 }, 162 { CX2072X_PORTE_POWER_STATE, 0x00000433 }, 163 { CX2072X_PORTE_PIN_CTRL, 0x00000040 }, 164 { CX2072X_PORTE_UNSOLICITED_RESPONSE, 0x00000000 }, 165 { CX2072X_PORTE_PIN_SENSE, 0x00000000 }, 166 { CX2072X_PORTE_EAPD_BTL, 0x00000002 }, 167 { CX2072X_PORTE_GAIN_RIGHT, 0x00000000 }, 168 { CX2072X_PORTE_GAIN_LEFT, 0x00000000 }, 169 { CX2072X_PORTF_POWER_STATE, 0x00000433 }, 170 { CX2072X_PORTF_PIN_CTRL, 0x00000000 }, 171 { CX2072X_PORTF_UNSOLICITED_RESPONSE, 0x00000000 }, 172 { CX2072X_PORTF_PIN_SENSE, 0x00000000 }, 173 { CX2072X_PORTF_GAIN_RIGHT, 0x00000000 }, 174 { CX2072X_PORTF_GAIN_LEFT, 0x00000000 }, 175 { CX2072X_PORTG_POWER_STATE, 0x00000433 }, 176 { CX2072X_PORTG_PIN_CTRL, 0x00000040 }, 177 { CX2072X_PORTG_CONNECTION_SELECT_CTRL, 0x00000000 }, 178 { CX2072X_PORTG_EAPD_BTL, 0x00000002 }, 179 { CX2072X_PORTM_POWER_STATE, 0x00000433 }, 180 { CX2072X_PORTM_PIN_CTRL, 0x00000000 }, 181 { CX2072X_PORTM_CONNECTION_SELECT_CTRL, 0x00000000 }, 182 { CX2072X_PORTM_EAPD_BTL, 0x00000002 }, 183 { CX2072X_MIXER_POWER_STATE, 0x00000433 }, 184 { CX2072X_MIXER_GAIN_RIGHT_0, 0x0000004a }, 185 { CX2072X_MIXER_GAIN_LEFT_0, 0x0000004a }, 186 { CX2072X_MIXER_GAIN_RIGHT_1, 0x0000004a }, 187 { CX2072X_MIXER_GAIN_LEFT_1, 0x0000004a }, 188 { CX2072X_SPKR_DRC_ENABLE_STEP, 0x040065a4 }, 189 { CX2072X_SPKR_DRC_CONTROL, 0x007b0024 }, 190 { CX2072X_SPKR_DRC_TEST, 0x00000000 }, 191 { CX2072X_DIGITAL_BIOS_TEST0, 0x001f008a }, 192 { CX2072X_DIGITAL_BIOS_TEST2, 0x00990026 }, 193 { CX2072X_I2SPCM_CONTROL1, 0x00010001 }, 194 { CX2072X_I2SPCM_CONTROL2, 0x00000000 }, 195 { CX2072X_I2SPCM_CONTROL3, 0x00000000 }, 196 { CX2072X_I2SPCM_CONTROL4, 0x00000000 }, 197 { CX2072X_I2SPCM_CONTROL5, 0x00000000 }, 198 { CX2072X_I2SPCM_CONTROL6, 0x00000000 }, 199 { CX2072X_UM_INTERRUPT_CRTL_E, 0x00000000 }, 200 { CX2072X_CODEC_TEST2, 0x00000000 }, 201 { CX2072X_CODEC_TEST9, 0x00000004 }, 202 { CX2072X_CODEC_TEST20, 0x00000600 }, 203 { CX2072X_CODEC_TEST26, 0x00000208 }, 204 { CX2072X_ANALOG_TEST4, 0x00000000 }, 205 { CX2072X_ANALOG_TEST5, 0x00000000 }, 206 { CX2072X_ANALOG_TEST6, 0x0000059a }, 207 { CX2072X_ANALOG_TEST7, 0x000000a7 }, 208 { CX2072X_ANALOG_TEST8, 0x00000017 }, 209 { CX2072X_ANALOG_TEST9, 0x00000000 }, 210 { CX2072X_ANALOG_TEST10, 0x00000285 }, 211 { CX2072X_ANALOG_TEST11, 0x00000000 }, 212 { CX2072X_ANALOG_TEST12, 0x00000000 }, 213 { CX2072X_ANALOG_TEST13, 0x00000000 }, 214 { CX2072X_DIGITAL_TEST1, 0x00000242 }, 215 { CX2072X_DIGITAL_TEST11, 0x00000000 }, 216 { CX2072X_DIGITAL_TEST12, 0x00000084 }, 217 { CX2072X_DIGITAL_TEST15, 0x00000077 }, 218 { CX2072X_DIGITAL_TEST16, 0x00000021 }, 219 { CX2072X_DIGITAL_TEST17, 0x00000018 }, 220 { CX2072X_DIGITAL_TEST18, 0x00000024 }, 221 { CX2072X_DIGITAL_TEST19, 0x00000001 }, 222 { CX2072X_DIGITAL_TEST20, 0x00000002 }, 223 }; 224 225 /* 226 * register initialization 227 */ 228 static const struct reg_sequence cx2072x_reg_init[] = { 229 { CX2072X_ANALOG_TEST9, 0x080 }, /* DC offset Calibration */ 230 { CX2072X_CODEC_TEST26, 0x65f }, /* Disable the PA */ 231 { CX2072X_ANALOG_TEST10, 0x289 }, /* Set the speaker output gain */ 232 { CX2072X_CODEC_TEST20, 0xf05 }, 233 { CX2072X_CODEC_TESTXX, 0x380 }, 234 { CX2072X_CODEC_TEST26, 0xb90 }, 235 { CX2072X_CODEC_TEST9, 0x001 }, /* Enable 30 Hz High pass filter */ 236 { CX2072X_ANALOG_TEST3, 0x300 }, /* Disable PCBEEP pad */ 237 { CX2072X_CODEC_TEST24, 0x100 }, /* Disable SnM mode */ 238 { CX2072X_PORTD_PIN_CTRL, 0x020 }, /* Enable PortD input */ 239 { CX2072X_GPIO_ENABLE, 0x040 }, /* Enable GPIO7 pin for button */ 240 { CX2072X_GPIO_UM_ENABLE, 0x040 }, /* Enable UM for GPIO7 */ 241 { CX2072X_UM_RESPONSE, 0x080 }, /* Enable button response */ 242 { CX2072X_DIGITAL_TEST12, 0x0c4 }, /* Enable headset button */ 243 { CX2072X_DIGITAL_TEST0, 0x415 }, /* Power down class-D during idle */ 244 { CX2072X_I2SPCM_CONTROL2, 0x00f }, /* Enable I2S TX */ 245 { CX2072X_I2SPCM_CONTROL3, 0x00f }, /* Enable I2S RX */ 246 }; 247 248 static unsigned int cx2072x_register_size(unsigned int reg) 249 { 250 switch (reg) { 251 case CX2072X_VENDOR_ID: 252 case CX2072X_REVISION_ID: 253 case CX2072X_PORTA_PIN_SENSE: 254 case CX2072X_PORTB_PIN_SENSE: 255 case CX2072X_PORTD_PIN_SENSE: 256 case CX2072X_PORTE_PIN_SENSE: 257 case CX2072X_PORTF_PIN_SENSE: 258 case CX2072X_I2SPCM_CONTROL1: 259 case CX2072X_I2SPCM_CONTROL2: 260 case CX2072X_I2SPCM_CONTROL3: 261 case CX2072X_I2SPCM_CONTROL4: 262 case CX2072X_I2SPCM_CONTROL5: 263 case CX2072X_I2SPCM_CONTROL6: 264 case CX2072X_UM_INTERRUPT_CRTL_E: 265 case CX2072X_EQ_G_COEFF: 266 case CX2072X_SPKR_DRC_CONTROL: 267 case CX2072X_SPKR_DRC_TEST: 268 case CX2072X_DIGITAL_BIOS_TEST0: 269 case CX2072X_DIGITAL_BIOS_TEST2: 270 return 4; 271 case CX2072X_EQ_ENABLE_BYPASS: 272 case CX2072X_EQ_B0_COEFF: 273 case CX2072X_EQ_B1_COEFF: 274 case CX2072X_EQ_B2_COEFF: 275 case CX2072X_EQ_A1_COEFF: 276 case CX2072X_EQ_A2_COEFF: 277 case CX2072X_DAC1_CONVERTER_FORMAT: 278 case CX2072X_DAC2_CONVERTER_FORMAT: 279 case CX2072X_ADC1_CONVERTER_FORMAT: 280 case CX2072X_ADC2_CONVERTER_FORMAT: 281 case CX2072X_CODEC_TEST2: 282 case CX2072X_CODEC_TEST9: 283 case CX2072X_CODEC_TEST20: 284 case CX2072X_CODEC_TEST26: 285 case CX2072X_ANALOG_TEST3: 286 case CX2072X_ANALOG_TEST4: 287 case CX2072X_ANALOG_TEST5: 288 case CX2072X_ANALOG_TEST6: 289 case CX2072X_ANALOG_TEST7: 290 case CX2072X_ANALOG_TEST8: 291 case CX2072X_ANALOG_TEST9: 292 case CX2072X_ANALOG_TEST10: 293 case CX2072X_ANALOG_TEST11: 294 case CX2072X_ANALOG_TEST12: 295 case CX2072X_ANALOG_TEST13: 296 case CX2072X_DIGITAL_TEST0: 297 case CX2072X_DIGITAL_TEST1: 298 case CX2072X_DIGITAL_TEST11: 299 case CX2072X_DIGITAL_TEST12: 300 case CX2072X_DIGITAL_TEST15: 301 case CX2072X_DIGITAL_TEST16: 302 case CX2072X_DIGITAL_TEST17: 303 case CX2072X_DIGITAL_TEST18: 304 case CX2072X_DIGITAL_TEST19: 305 case CX2072X_DIGITAL_TEST20: 306 return 2; 307 default: 308 return 1; 309 } 310 } 311 312 static bool cx2072x_readable_register(struct device *dev, unsigned int reg) 313 { 314 switch (reg) { 315 case CX2072X_VENDOR_ID: 316 case CX2072X_REVISION_ID: 317 case CX2072X_CURRENT_BCLK_FREQUENCY: 318 case CX2072X_AFG_POWER_STATE: 319 case CX2072X_UM_RESPONSE: 320 case CX2072X_GPIO_DATA: 321 case CX2072X_GPIO_ENABLE: 322 case CX2072X_GPIO_DIRECTION: 323 case CX2072X_GPIO_WAKE: 324 case CX2072X_GPIO_UM_ENABLE: 325 case CX2072X_GPIO_STICKY_MASK: 326 case CX2072X_DAC1_CONVERTER_FORMAT: 327 case CX2072X_DAC1_AMP_GAIN_RIGHT: 328 case CX2072X_DAC1_AMP_GAIN_LEFT: 329 case CX2072X_DAC1_POWER_STATE: 330 case CX2072X_DAC1_CONVERTER_STREAM_CHANNEL: 331 case CX2072X_DAC1_EAPD_ENABLE: 332 case CX2072X_DAC2_CONVERTER_FORMAT: 333 case CX2072X_DAC2_AMP_GAIN_RIGHT: 334 case CX2072X_DAC2_AMP_GAIN_LEFT: 335 case CX2072X_DAC2_POWER_STATE: 336 case CX2072X_DAC2_CONVERTER_STREAM_CHANNEL: 337 case CX2072X_ADC1_CONVERTER_FORMAT: 338 case CX2072X_ADC1_AMP_GAIN_RIGHT_0: 339 case CX2072X_ADC1_AMP_GAIN_LEFT_0: 340 case CX2072X_ADC1_AMP_GAIN_RIGHT_1: 341 case CX2072X_ADC1_AMP_GAIN_LEFT_1: 342 case CX2072X_ADC1_AMP_GAIN_RIGHT_2: 343 case CX2072X_ADC1_AMP_GAIN_LEFT_2: 344 case CX2072X_ADC1_AMP_GAIN_RIGHT_3: 345 case CX2072X_ADC1_AMP_GAIN_LEFT_3: 346 case CX2072X_ADC1_AMP_GAIN_RIGHT_4: 347 case CX2072X_ADC1_AMP_GAIN_LEFT_4: 348 case CX2072X_ADC1_AMP_GAIN_RIGHT_5: 349 case CX2072X_ADC1_AMP_GAIN_LEFT_5: 350 case CX2072X_ADC1_AMP_GAIN_RIGHT_6: 351 case CX2072X_ADC1_AMP_GAIN_LEFT_6: 352 case CX2072X_ADC1_CONNECTION_SELECT_CONTROL: 353 case CX2072X_ADC1_POWER_STATE: 354 case CX2072X_ADC1_CONVERTER_STREAM_CHANNEL: 355 case CX2072X_ADC2_CONVERTER_FORMAT: 356 case CX2072X_ADC2_AMP_GAIN_RIGHT_0: 357 case CX2072X_ADC2_AMP_GAIN_LEFT_0: 358 case CX2072X_ADC2_AMP_GAIN_RIGHT_1: 359 case CX2072X_ADC2_AMP_GAIN_LEFT_1: 360 case CX2072X_ADC2_AMP_GAIN_RIGHT_2: 361 case CX2072X_ADC2_AMP_GAIN_LEFT_2: 362 case CX2072X_ADC2_CONNECTION_SELECT_CONTROL: 363 case CX2072X_ADC2_POWER_STATE: 364 case CX2072X_ADC2_CONVERTER_STREAM_CHANNEL: 365 case CX2072X_PORTA_CONNECTION_SELECT_CTRL: 366 case CX2072X_PORTA_POWER_STATE: 367 case CX2072X_PORTA_PIN_CTRL: 368 case CX2072X_PORTA_UNSOLICITED_RESPONSE: 369 case CX2072X_PORTA_PIN_SENSE: 370 case CX2072X_PORTA_EAPD_BTL: 371 case CX2072X_PORTB_POWER_STATE: 372 case CX2072X_PORTB_PIN_CTRL: 373 case CX2072X_PORTB_UNSOLICITED_RESPONSE: 374 case CX2072X_PORTB_PIN_SENSE: 375 case CX2072X_PORTB_EAPD_BTL: 376 case CX2072X_PORTB_GAIN_RIGHT: 377 case CX2072X_PORTB_GAIN_LEFT: 378 case CX2072X_PORTC_POWER_STATE: 379 case CX2072X_PORTC_PIN_CTRL: 380 case CX2072X_PORTC_GAIN_RIGHT: 381 case CX2072X_PORTC_GAIN_LEFT: 382 case CX2072X_PORTD_POWER_STATE: 383 case CX2072X_PORTD_PIN_CTRL: 384 case CX2072X_PORTD_UNSOLICITED_RESPONSE: 385 case CX2072X_PORTD_PIN_SENSE: 386 case CX2072X_PORTD_GAIN_RIGHT: 387 case CX2072X_PORTD_GAIN_LEFT: 388 case CX2072X_PORTE_CONNECTION_SELECT_CTRL: 389 case CX2072X_PORTE_POWER_STATE: 390 case CX2072X_PORTE_PIN_CTRL: 391 case CX2072X_PORTE_UNSOLICITED_RESPONSE: 392 case CX2072X_PORTE_PIN_SENSE: 393 case CX2072X_PORTE_EAPD_BTL: 394 case CX2072X_PORTE_GAIN_RIGHT: 395 case CX2072X_PORTE_GAIN_LEFT: 396 case CX2072X_PORTF_POWER_STATE: 397 case CX2072X_PORTF_PIN_CTRL: 398 case CX2072X_PORTF_UNSOLICITED_RESPONSE: 399 case CX2072X_PORTF_PIN_SENSE: 400 case CX2072X_PORTF_GAIN_RIGHT: 401 case CX2072X_PORTF_GAIN_LEFT: 402 case CX2072X_PORTG_POWER_STATE: 403 case CX2072X_PORTG_PIN_CTRL: 404 case CX2072X_PORTG_CONNECTION_SELECT_CTRL: 405 case CX2072X_PORTG_EAPD_BTL: 406 case CX2072X_PORTM_POWER_STATE: 407 case CX2072X_PORTM_PIN_CTRL: 408 case CX2072X_PORTM_CONNECTION_SELECT_CTRL: 409 case CX2072X_PORTM_EAPD_BTL: 410 case CX2072X_MIXER_POWER_STATE: 411 case CX2072X_MIXER_GAIN_RIGHT_0: 412 case CX2072X_MIXER_GAIN_LEFT_0: 413 case CX2072X_MIXER_GAIN_RIGHT_1: 414 case CX2072X_MIXER_GAIN_LEFT_1: 415 case CX2072X_EQ_ENABLE_BYPASS: 416 case CX2072X_EQ_B0_COEFF: 417 case CX2072X_EQ_B1_COEFF: 418 case CX2072X_EQ_B2_COEFF: 419 case CX2072X_EQ_A1_COEFF: 420 case CX2072X_EQ_A2_COEFF: 421 case CX2072X_EQ_G_COEFF: 422 case CX2072X_SPKR_DRC_ENABLE_STEP: 423 case CX2072X_SPKR_DRC_CONTROL: 424 case CX2072X_SPKR_DRC_TEST: 425 case CX2072X_DIGITAL_BIOS_TEST0: 426 case CX2072X_DIGITAL_BIOS_TEST2: 427 case CX2072X_I2SPCM_CONTROL1: 428 case CX2072X_I2SPCM_CONTROL2: 429 case CX2072X_I2SPCM_CONTROL3: 430 case CX2072X_I2SPCM_CONTROL4: 431 case CX2072X_I2SPCM_CONTROL5: 432 case CX2072X_I2SPCM_CONTROL6: 433 case CX2072X_UM_INTERRUPT_CRTL_E: 434 case CX2072X_CODEC_TEST2: 435 case CX2072X_CODEC_TEST9: 436 case CX2072X_CODEC_TEST20: 437 case CX2072X_CODEC_TEST26: 438 case CX2072X_ANALOG_TEST4: 439 case CX2072X_ANALOG_TEST5: 440 case CX2072X_ANALOG_TEST6: 441 case CX2072X_ANALOG_TEST7: 442 case CX2072X_ANALOG_TEST8: 443 case CX2072X_ANALOG_TEST9: 444 case CX2072X_ANALOG_TEST10: 445 case CX2072X_ANALOG_TEST11: 446 case CX2072X_ANALOG_TEST12: 447 case CX2072X_ANALOG_TEST13: 448 case CX2072X_DIGITAL_TEST0: 449 case CX2072X_DIGITAL_TEST1: 450 case CX2072X_DIGITAL_TEST11: 451 case CX2072X_DIGITAL_TEST12: 452 case CX2072X_DIGITAL_TEST15: 453 case CX2072X_DIGITAL_TEST16: 454 case CX2072X_DIGITAL_TEST17: 455 case CX2072X_DIGITAL_TEST18: 456 case CX2072X_DIGITAL_TEST19: 457 case CX2072X_DIGITAL_TEST20: 458 return true; 459 default: 460 return false; 461 } 462 } 463 464 static bool cx2072x_volatile_register(struct device *dev, unsigned int reg) 465 { 466 switch (reg) { 467 case CX2072X_VENDOR_ID: 468 case CX2072X_REVISION_ID: 469 case CX2072X_UM_INTERRUPT_CRTL_E: 470 case CX2072X_DIGITAL_TEST11: 471 case CX2072X_PORTA_PIN_SENSE: 472 case CX2072X_PORTB_PIN_SENSE: 473 case CX2072X_PORTD_PIN_SENSE: 474 case CX2072X_PORTE_PIN_SENSE: 475 case CX2072X_PORTF_PIN_SENSE: 476 case CX2072X_EQ_G_COEFF: 477 case CX2072X_EQ_BAND: 478 return true; 479 default: 480 return false; 481 } 482 } 483 484 static int cx2072x_reg_raw_write(struct i2c_client *client, 485 unsigned int reg, 486 const void *val, size_t val_count) 487 { 488 struct device *dev = &client->dev; 489 u8 buf[2 + CX2072X_MAX_EQ_COEFF]; 490 int ret; 491 492 if (WARN_ON(val_count + 2 > sizeof(buf))) 493 return -EINVAL; 494 495 buf[0] = reg >> 8; 496 buf[1] = reg & 0xff; 497 498 memcpy(buf + 2, val, val_count); 499 500 ret = i2c_master_send(client, buf, val_count + 2); 501 if (ret != val_count + 2) { 502 dev_err(dev, "I2C write failed, ret = %d\n", ret); 503 return ret < 0 ? ret : -EIO; 504 } 505 return 0; 506 } 507 508 static int cx2072x_reg_write(void *context, unsigned int reg, 509 unsigned int value) 510 { 511 __le32 raw_value; 512 unsigned int size; 513 514 size = cx2072x_register_size(reg); 515 516 if (reg == CX2072X_UM_INTERRUPT_CRTL_E) { 517 /* Update the MSB byte only */ 518 reg += 3; 519 size = 1; 520 value >>= 24; 521 } 522 523 raw_value = cpu_to_le32(value); 524 return cx2072x_reg_raw_write(context, reg, &raw_value, size); 525 } 526 527 static int cx2072x_reg_read(void *context, unsigned int reg, 528 unsigned int *value) 529 { 530 struct i2c_client *client = context; 531 struct device *dev = &client->dev; 532 __le32 recv_buf = 0; 533 struct i2c_msg msgs[2]; 534 unsigned int size; 535 u8 send_buf[2]; 536 int ret; 537 538 size = cx2072x_register_size(reg); 539 540 send_buf[0] = reg >> 8; 541 send_buf[1] = reg & 0xff; 542 543 msgs[0].addr = client->addr; 544 msgs[0].len = sizeof(send_buf); 545 msgs[0].buf = send_buf; 546 msgs[0].flags = 0; 547 548 msgs[1].addr = client->addr; 549 msgs[1].len = size; 550 msgs[1].buf = (u8 *)&recv_buf; 551 msgs[1].flags = I2C_M_RD; 552 553 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 554 if (ret != ARRAY_SIZE(msgs)) { 555 dev_err(dev, "Failed to read register, ret = %d\n", ret); 556 return ret < 0 ? ret : -EIO; 557 } 558 559 *value = le32_to_cpu(recv_buf); 560 return 0; 561 } 562 563 /* get suggested pre_div valuce from mclk frequency */ 564 static unsigned int get_div_from_mclk(unsigned int mclk) 565 { 566 unsigned int div = 8; 567 int i; 568 569 for (i = 0; i < ARRAY_SIZE(mclk_pre_div); i++) { 570 if (mclk <= mclk_pre_div[i].mclk) { 571 div = mclk_pre_div[i].div; 572 break; 573 } 574 } 575 return div; 576 } 577 578 static int cx2072x_config_pll(struct cx2072x_priv *cx2072x) 579 { 580 struct device *dev = cx2072x->dev; 581 unsigned int pre_div; 582 unsigned int pre_div_val; 583 unsigned int pll_input; 584 unsigned int pll_output; 585 unsigned int int_div; 586 unsigned int frac_div; 587 u64 frac_num; 588 unsigned int frac; 589 unsigned int sample_rate = cx2072x->sample_rate; 590 int pt_sample_per_sync = 2; 591 int pt_clock_per_sample = 96; 592 593 switch (sample_rate) { 594 case 48000: 595 case 32000: 596 case 24000: 597 case 16000: 598 break; 599 600 case 96000: 601 pt_sample_per_sync = 1; 602 pt_clock_per_sample = 48; 603 break; 604 605 case 192000: 606 pt_sample_per_sync = 0; 607 pt_clock_per_sample = 24; 608 break; 609 610 default: 611 dev_err(dev, "Unsupported sample rate %d\n", sample_rate); 612 return -EINVAL; 613 } 614 615 /* Configure PLL settings */ 616 pre_div = get_div_from_mclk(cx2072x->mclk_rate); 617 pll_input = cx2072x->mclk_rate / pre_div; 618 pll_output = sample_rate * 3072; 619 int_div = pll_output / pll_input; 620 frac_div = pll_output - (int_div * pll_input); 621 622 if (frac_div) { 623 frac_div *= 1000; 624 frac_div /= pll_input; 625 frac_num = (u64)(4000 + frac_div) * ((1 << 20) - 4); 626 do_div(frac_num, 7); 627 frac = ((u32)frac_num + 499) / 1000; 628 } 629 pre_div_val = (pre_div - 1) * 2; 630 631 regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST4, 632 0x40 | (pre_div_val << 8)); 633 if (frac_div == 0) { 634 /* Int mode */ 635 regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST7, 0x100); 636 } else { 637 /* frac mode */ 638 regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST6, 639 frac & 0xfff); 640 regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST7, 641 (u8)(frac >> 12)); 642 } 643 644 int_div--; 645 regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST8, int_div); 646 647 /* configure PLL tracking */ 648 if (frac_div == 0) { 649 /* disable PLL tracking */ 650 regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST16, 0x00); 651 } else { 652 /* configure and enable PLL tracking */ 653 regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST16, 654 (pt_sample_per_sync << 4) & 0xf0); 655 regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST17, 656 pt_clock_per_sample); 657 regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST18, 658 pt_clock_per_sample * 3 / 2); 659 regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST19, 0x01); 660 regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST20, 0x02); 661 regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_TEST16, 662 0x01, 0x01); 663 } 664 665 return 0; 666 } 667 668 static int cx2072x_config_i2spcm(struct cx2072x_priv *cx2072x) 669 { 670 struct device *dev = cx2072x->dev; 671 unsigned int bclk_rate = 0; 672 int is_i2s = 0; 673 int has_one_bit_delay = 0; 674 int is_frame_inv = 0; 675 int is_bclk_inv = 0; 676 int pulse_len; 677 int frame_len = cx2072x->frame_size; 678 int sample_size = cx2072x->sample_size; 679 int i2s_right_slot; 680 int i2s_right_pause_interval = 0; 681 int i2s_right_pause_pos; 682 int is_big_endian = 1; 683 u64 div; 684 unsigned int mod; 685 union cx2072x_reg_i2spcm_ctrl_reg1 reg1; 686 union cx2072x_reg_i2spcm_ctrl_reg2 reg2; 687 union cx2072x_reg_i2spcm_ctrl_reg3 reg3; 688 union cx2072x_reg_i2spcm_ctrl_reg4 reg4; 689 union cx2072x_reg_i2spcm_ctrl_reg5 reg5; 690 union cx2072x_reg_i2spcm_ctrl_reg6 reg6; 691 union cx2072x_reg_digital_bios_test2 regdbt2; 692 const unsigned int fmt = cx2072x->dai_fmt; 693 694 if (frame_len <= 0) { 695 dev_err(dev, "Incorrect frame len %d\n", frame_len); 696 return -EINVAL; 697 } 698 699 if (sample_size <= 0) { 700 dev_err(dev, "Incorrect sample size %d\n", sample_size); 701 return -EINVAL; 702 } 703 704 dev_dbg(dev, "config_i2spcm set_dai_fmt- %08x\n", fmt); 705 706 regdbt2.ulval = 0xac; 707 708 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 709 case SND_SOC_DAIFMT_CBP_CFP: 710 reg2.r.tx_master = 1; 711 reg3.r.rx_master = 1; 712 break; 713 714 case SND_SOC_DAIFMT_CBC_CFC: 715 reg2.r.tx_master = 0; 716 reg3.r.rx_master = 0; 717 break; 718 719 default: 720 dev_err(dev, "Unsupported DAI clocking mode\n"); 721 return -EINVAL; 722 } 723 724 /* set format */ 725 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 726 case SND_SOC_DAIFMT_I2S: 727 is_i2s = 1; 728 has_one_bit_delay = 1; 729 pulse_len = frame_len / 2; 730 break; 731 732 case SND_SOC_DAIFMT_RIGHT_J: 733 is_i2s = 1; 734 pulse_len = frame_len / 2; 735 break; 736 737 case SND_SOC_DAIFMT_LEFT_J: 738 is_i2s = 1; 739 pulse_len = frame_len / 2; 740 break; 741 742 default: 743 dev_err(dev, "Unsupported DAI format\n"); 744 return -EINVAL; 745 } 746 747 /* clock inversion */ 748 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 749 case SND_SOC_DAIFMT_NB_NF: 750 is_frame_inv = is_i2s; 751 is_bclk_inv = is_i2s; 752 break; 753 754 case SND_SOC_DAIFMT_IB_IF: 755 is_frame_inv = !is_i2s; 756 is_bclk_inv = !is_i2s; 757 break; 758 759 case SND_SOC_DAIFMT_IB_NF: 760 is_frame_inv = is_i2s; 761 is_bclk_inv = !is_i2s; 762 break; 763 764 case SND_SOC_DAIFMT_NB_IF: 765 is_frame_inv = !is_i2s; 766 is_bclk_inv = is_i2s; 767 break; 768 769 default: 770 dev_err(dev, "Unsupported DAI clock inversion\n"); 771 return -EINVAL; 772 } 773 774 reg1.r.rx_data_one_line = 1; 775 reg1.r.tx_data_one_line = 1; 776 777 if (is_i2s) { 778 i2s_right_slot = (frame_len / 2) / BITS_PER_SLOT; 779 i2s_right_pause_interval = (frame_len / 2) % BITS_PER_SLOT; 780 i2s_right_pause_pos = i2s_right_slot * BITS_PER_SLOT; 781 } 782 783 reg1.r.rx_ws_pol = is_frame_inv; 784 reg1.r.rx_ws_wid = pulse_len - 1; 785 786 reg1.r.rx_frm_len = frame_len / BITS_PER_SLOT - 1; 787 reg1.r.rx_sa_size = (sample_size / BITS_PER_SLOT) - 1; 788 789 reg1.r.tx_ws_pol = reg1.r.rx_ws_pol; 790 reg1.r.tx_ws_wid = pulse_len - 1; 791 reg1.r.tx_frm_len = reg1.r.rx_frm_len; 792 reg1.r.tx_sa_size = reg1.r.rx_sa_size; 793 794 reg2.r.tx_endian_sel = !is_big_endian; 795 reg2.r.tx_dstart_dly = has_one_bit_delay; 796 if (cx2072x->en_aec_ref) 797 reg2.r.tx_dstart_dly = 0; 798 799 reg3.r.rx_endian_sel = !is_big_endian; 800 reg3.r.rx_dstart_dly = has_one_bit_delay; 801 802 reg4.ulval = 0; 803 804 if (is_i2s) { 805 reg2.r.tx_slot_1 = 0; 806 reg2.r.tx_slot_2 = i2s_right_slot; 807 reg3.r.rx_slot_1 = 0; 808 if (cx2072x->en_aec_ref) 809 reg3.r.rx_slot_2 = 0; 810 else 811 reg3.r.rx_slot_2 = i2s_right_slot; 812 reg6.r.rx_pause_start_pos = i2s_right_pause_pos; 813 reg6.r.rx_pause_cycles = i2s_right_pause_interval; 814 reg6.r.tx_pause_start_pos = i2s_right_pause_pos; 815 reg6.r.tx_pause_cycles = i2s_right_pause_interval; 816 } else { 817 dev_err(dev, "TDM mode is not implemented yet\n"); 818 return -EINVAL; 819 } 820 regdbt2.r.i2s_bclk_invert = is_bclk_inv; 821 822 /* Configures the BCLK output */ 823 bclk_rate = cx2072x->sample_rate * frame_len; 824 reg5.r.i2s_pcm_clk_div_chan_en = 0; 825 826 /* Disables bclk output before setting new value */ 827 regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL5, 0); 828 829 if (reg2.r.tx_master) { 830 /* Configures BCLK rate */ 831 div = PLL_OUT_HZ_48; 832 mod = do_div(div, bclk_rate); 833 if (mod) { 834 dev_err(dev, "Unsupported BCLK %dHz\n", bclk_rate); 835 return -EINVAL; 836 } 837 dev_dbg(dev, "enables BCLK %dHz output\n", bclk_rate); 838 reg5.r.i2s_pcm_clk_div = (u32)div - 1; 839 reg5.r.i2s_pcm_clk_div_chan_en = 1; 840 } 841 842 regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL1, reg1.ulval); 843 regmap_update_bits(cx2072x->regmap, CX2072X_I2SPCM_CONTROL2, 0xffffffc0, 844 reg2.ulval); 845 regmap_update_bits(cx2072x->regmap, CX2072X_I2SPCM_CONTROL3, 0xffffffc0, 846 reg3.ulval); 847 regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL4, reg4.ulval); 848 regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL6, reg6.ulval); 849 regmap_write(cx2072x->regmap, CX2072X_I2SPCM_CONTROL5, reg5.ulval); 850 851 regmap_write(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST2, 852 regdbt2.ulval); 853 854 return 0; 855 } 856 857 static int afg_power_ev(struct snd_soc_dapm_widget *w, 858 struct snd_kcontrol *kcontrol, int event) 859 { 860 struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm); 861 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 862 863 switch (event) { 864 case SND_SOC_DAPM_POST_PMU: 865 regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST0, 866 0x00, 0x10); 867 break; 868 869 case SND_SOC_DAPM_PRE_PMD: 870 regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST0, 871 0x10, 0x10); 872 break; 873 } 874 875 return 0; 876 } 877 878 static const struct snd_kcontrol_new cx2072x_snd_controls[] = { 879 SOC_DOUBLE_R_TLV("PortD Boost Volume", CX2072X_PORTD_GAIN_LEFT, 880 CX2072X_PORTD_GAIN_RIGHT, 0, 3, 0, boost_tlv), 881 SOC_DOUBLE_R_TLV("PortC Boost Volume", CX2072X_PORTC_GAIN_LEFT, 882 CX2072X_PORTC_GAIN_RIGHT, 0, 3, 0, boost_tlv), 883 SOC_DOUBLE_R_TLV("PortB Boost Volume", CX2072X_PORTB_GAIN_LEFT, 884 CX2072X_PORTB_GAIN_RIGHT, 0, 3, 0, boost_tlv), 885 SOC_DOUBLE_R_TLV("PortD ADC1 Volume", CX2072X_ADC1_AMP_GAIN_LEFT_1, 886 CX2072X_ADC1_AMP_GAIN_RIGHT_1, 0, 0x4a, 0, adc_tlv), 887 SOC_DOUBLE_R_TLV("PortC ADC1 Volume", CX2072X_ADC1_AMP_GAIN_LEFT_2, 888 CX2072X_ADC1_AMP_GAIN_RIGHT_2, 0, 0x4a, 0, adc_tlv), 889 SOC_DOUBLE_R_TLV("PortB ADC1 Volume", CX2072X_ADC1_AMP_GAIN_LEFT_0, 890 CX2072X_ADC1_AMP_GAIN_RIGHT_0, 0, 0x4a, 0, adc_tlv), 891 SOC_DOUBLE_R_TLV("DAC1 Volume", CX2072X_DAC1_AMP_GAIN_LEFT, 892 CX2072X_DAC1_AMP_GAIN_RIGHT, 0, 0x4a, 0, dac_tlv), 893 SOC_DOUBLE_R("DAC1 Switch", CX2072X_DAC1_AMP_GAIN_LEFT, 894 CX2072X_DAC1_AMP_GAIN_RIGHT, 7, 1, 0), 895 SOC_DOUBLE_R_TLV("DAC2 Volume", CX2072X_DAC2_AMP_GAIN_LEFT, 896 CX2072X_DAC2_AMP_GAIN_RIGHT, 0, 0x4a, 0, dac_tlv), 897 SOC_SINGLE_TLV("HPF Freq", CX2072X_CODEC_TEST9, 0, 0x3f, 0, hpf_tlv), 898 SOC_DOUBLE("HPF Switch", CX2072X_CODEC_TEST9, 8, 9, 1, 1), 899 SOC_SINGLE("PortA HP Amp Switch", CX2072X_PORTA_PIN_CTRL, 7, 1, 0), 900 }; 901 902 static int cx2072x_hw_params(struct snd_pcm_substream *substream, 903 struct snd_pcm_hw_params *params, 904 struct snd_soc_dai *dai) 905 { 906 struct snd_soc_component *codec = dai->component; 907 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 908 struct device *dev = codec->dev; 909 const unsigned int sample_rate = params_rate(params); 910 int sample_size, frame_size; 911 912 /* Data sizes if not using TDM */ 913 sample_size = params_width(params); 914 915 if (sample_size < 0) 916 return sample_size; 917 918 frame_size = snd_soc_params_to_frame_size(params); 919 if (frame_size < 0) 920 return frame_size; 921 922 if (cx2072x->mclk_rate == 0) { 923 dev_err(dev, "Master clock rate is not configured\n"); 924 return -EINVAL; 925 } 926 927 if (cx2072x->bclk_ratio) 928 frame_size = cx2072x->bclk_ratio; 929 930 switch (sample_rate) { 931 case 48000: 932 case 32000: 933 case 24000: 934 case 16000: 935 case 96000: 936 case 192000: 937 break; 938 939 default: 940 dev_err(dev, "Unsupported sample rate %d\n", sample_rate); 941 return -EINVAL; 942 } 943 944 dev_dbg(dev, "Sample size %d bits, frame = %d bits, rate = %d Hz\n", 945 sample_size, frame_size, sample_rate); 946 947 cx2072x->frame_size = frame_size; 948 cx2072x->sample_size = sample_size; 949 cx2072x->sample_rate = sample_rate; 950 951 if (dai->id == CX2072X_DAI_DSP) { 952 cx2072x->en_aec_ref = true; 953 dev_dbg(cx2072x->dev, "enables aec reference\n"); 954 regmap_write(cx2072x->regmap, 955 CX2072X_ADC1_CONNECTION_SELECT_CONTROL, 3); 956 } 957 958 if (cx2072x->pll_changed) { 959 cx2072x_config_pll(cx2072x); 960 cx2072x->pll_changed = false; 961 } 962 963 if (cx2072x->i2spcm_changed) { 964 cx2072x_config_i2spcm(cx2072x); 965 cx2072x->i2spcm_changed = false; 966 } 967 968 return 0; 969 } 970 971 static int cx2072x_set_dai_bclk_ratio(struct snd_soc_dai *dai, 972 unsigned int ratio) 973 { 974 struct snd_soc_component *codec = dai->component; 975 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 976 977 cx2072x->bclk_ratio = ratio; 978 return 0; 979 } 980 981 static int cx2072x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, 982 unsigned int freq, int dir) 983 { 984 struct snd_soc_component *codec = dai->component; 985 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 986 987 if (clk_set_rate(cx2072x->mclk, freq)) { 988 dev_err(codec->dev, "set clk rate failed\n"); 989 return -EINVAL; 990 } 991 992 cx2072x->mclk_rate = freq; 993 return 0; 994 } 995 996 static int cx2072x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 997 { 998 struct snd_soc_component *codec = dai->component; 999 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 1000 struct device *dev = codec->dev; 1001 1002 dev_dbg(dev, "set_dai_fmt- %08x\n", fmt); 1003 /* set master/slave */ 1004 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { 1005 case SND_SOC_DAIFMT_CBP_CFP: 1006 case SND_SOC_DAIFMT_CBC_CFC: 1007 break; 1008 1009 default: 1010 dev_err(dev, "Unsupported DAI master mode\n"); 1011 return -EINVAL; 1012 } 1013 1014 /* set format */ 1015 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1016 case SND_SOC_DAIFMT_I2S: 1017 case SND_SOC_DAIFMT_RIGHT_J: 1018 case SND_SOC_DAIFMT_LEFT_J: 1019 break; 1020 1021 default: 1022 dev_err(dev, "Unsupported DAI format\n"); 1023 return -EINVAL; 1024 } 1025 1026 /* clock inversion */ 1027 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1028 case SND_SOC_DAIFMT_NB_NF: 1029 case SND_SOC_DAIFMT_IB_IF: 1030 case SND_SOC_DAIFMT_IB_NF: 1031 case SND_SOC_DAIFMT_NB_IF: 1032 break; 1033 1034 default: 1035 dev_err(dev, "Unsupported DAI clock inversion\n"); 1036 return -EINVAL; 1037 } 1038 1039 cx2072x->dai_fmt = fmt; 1040 return 0; 1041 } 1042 1043 static const struct snd_kcontrol_new portaouten_ctl = 1044 SOC_DAPM_SINGLE("Switch", CX2072X_PORTA_PIN_CTRL, 6, 1, 0); 1045 1046 static const struct snd_kcontrol_new porteouten_ctl = 1047 SOC_DAPM_SINGLE("Switch", CX2072X_PORTE_PIN_CTRL, 6, 1, 0); 1048 1049 static const struct snd_kcontrol_new portgouten_ctl = 1050 SOC_DAPM_SINGLE("Switch", CX2072X_PORTG_PIN_CTRL, 6, 1, 0); 1051 1052 static const struct snd_kcontrol_new portmouten_ctl = 1053 SOC_DAPM_SINGLE("Switch", CX2072X_PORTM_PIN_CTRL, 6, 1, 0); 1054 1055 static const struct snd_kcontrol_new portbinen_ctl = 1056 SOC_DAPM_SINGLE("Switch", CX2072X_PORTB_PIN_CTRL, 5, 1, 0); 1057 1058 static const struct snd_kcontrol_new portcinen_ctl = 1059 SOC_DAPM_SINGLE("Switch", CX2072X_PORTC_PIN_CTRL, 5, 1, 0); 1060 1061 static const struct snd_kcontrol_new portdinen_ctl = 1062 SOC_DAPM_SINGLE("Switch", CX2072X_PORTD_PIN_CTRL, 5, 1, 0); 1063 1064 static const struct snd_kcontrol_new porteinen_ctl = 1065 SOC_DAPM_SINGLE("Switch", CX2072X_PORTE_PIN_CTRL, 5, 1, 0); 1066 1067 static const struct snd_kcontrol_new i2sadc1l_ctl = 1068 SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL2, 0, 1, 0); 1069 1070 static const struct snd_kcontrol_new i2sadc1r_ctl = 1071 SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL2, 1, 1, 0); 1072 1073 static const struct snd_kcontrol_new i2sadc2l_ctl = 1074 SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL2, 2, 1, 0); 1075 1076 static const struct snd_kcontrol_new i2sadc2r_ctl = 1077 SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL2, 3, 1, 0); 1078 1079 static const struct snd_kcontrol_new i2sdac1l_ctl = 1080 SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL3, 0, 1, 0); 1081 1082 static const struct snd_kcontrol_new i2sdac1r_ctl = 1083 SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL3, 1, 1, 0); 1084 1085 static const struct snd_kcontrol_new i2sdac2l_ctl = 1086 SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL3, 2, 1, 0); 1087 1088 static const struct snd_kcontrol_new i2sdac2r_ctl = 1089 SOC_DAPM_SINGLE("Switch", CX2072X_I2SPCM_CONTROL3, 3, 1, 0); 1090 1091 static const char * const dac_enum_text[] = { 1092 "DAC1 Switch", "DAC2 Switch", 1093 }; 1094 1095 static const struct soc_enum porta_dac_enum = 1096 SOC_ENUM_SINGLE(CX2072X_PORTA_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text); 1097 1098 static const struct snd_kcontrol_new porta_mux = 1099 SOC_DAPM_ENUM("PortA Mux", porta_dac_enum); 1100 1101 static const struct soc_enum portg_dac_enum = 1102 SOC_ENUM_SINGLE(CX2072X_PORTG_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text); 1103 1104 static const struct snd_kcontrol_new portg_mux = 1105 SOC_DAPM_ENUM("PortG Mux", portg_dac_enum); 1106 1107 static const struct soc_enum porte_dac_enum = 1108 SOC_ENUM_SINGLE(CX2072X_PORTE_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text); 1109 1110 static const struct snd_kcontrol_new porte_mux = 1111 SOC_DAPM_ENUM("PortE Mux", porte_dac_enum); 1112 1113 static const struct soc_enum portm_dac_enum = 1114 SOC_ENUM_SINGLE(CX2072X_PORTM_CONNECTION_SELECT_CTRL, 0, 2, dac_enum_text); 1115 1116 static const struct snd_kcontrol_new portm_mux = 1117 SOC_DAPM_ENUM("PortM Mux", portm_dac_enum); 1118 1119 static const char * const adc1in_sel_text[] = { 1120 "PortB Switch", "PortD Switch", "PortC Switch", "Widget15 Switch", 1121 "PortE Switch", "PortF Switch", "PortH Switch" 1122 }; 1123 1124 static const struct soc_enum adc1in_sel_enum = 1125 SOC_ENUM_SINGLE(CX2072X_ADC1_CONNECTION_SELECT_CONTROL, 0, 7, adc1in_sel_text); 1126 1127 static const struct snd_kcontrol_new adc1_mux = 1128 SOC_DAPM_ENUM("ADC1 Mux", adc1in_sel_enum); 1129 1130 static const char * const adc2in_sel_text[] = { 1131 "PortC Switch", "Widget15 Switch", "PortH Switch" 1132 }; 1133 1134 static const struct soc_enum adc2in_sel_enum = 1135 SOC_ENUM_SINGLE(CX2072X_ADC2_CONNECTION_SELECT_CONTROL, 0, 3, adc2in_sel_text); 1136 1137 static const struct snd_kcontrol_new adc2_mux = 1138 SOC_DAPM_ENUM("ADC2 Mux", adc2in_sel_enum); 1139 1140 static const struct snd_kcontrol_new wid15_mix[] = { 1141 SOC_DAPM_SINGLE("DAC1L Switch", CX2072X_MIXER_GAIN_LEFT_0, 7, 1, 1), 1142 SOC_DAPM_SINGLE("DAC1R Switch", CX2072X_MIXER_GAIN_RIGHT_0, 7, 1, 1), 1143 SOC_DAPM_SINGLE("DAC2L Switch", CX2072X_MIXER_GAIN_LEFT_1, 7, 1, 1), 1144 SOC_DAPM_SINGLE("DAC2R Switch", CX2072X_MIXER_GAIN_RIGHT_1, 7, 1, 1), 1145 }; 1146 1147 #define CX2072X_DAPM_SUPPLY_S(wname, wsubseq, wreg, wshift, wmask, won_val, \ 1148 woff_val, wevent, wflags) \ 1149 {.id = snd_soc_dapm_supply, .name = wname, .kcontrol_news = NULL, \ 1150 .num_kcontrols = 0, .reg = wreg, .shift = wshift, .mask = wmask, \ 1151 .on_val = won_val, .off_val = woff_val, \ 1152 .subseq = wsubseq, .event = wevent, .event_flags = wflags} 1153 1154 #define CX2072X_DAPM_SWITCH(wname, wreg, wshift, wmask, won_val, woff_val, \ 1155 wevent, wflags) \ 1156 {.id = snd_soc_dapm_switch, .name = wname, .kcontrol_news = NULL, \ 1157 .num_kcontrols = 0, .reg = wreg, .shift = wshift, .mask = wmask, \ 1158 .on_val = won_val, .off_val = woff_val, \ 1159 .event = wevent, .event_flags = wflags} 1160 1161 #define CX2072X_DAPM_SWITCH(wname, wreg, wshift, wmask, won_val, woff_val, \ 1162 wevent, wflags) \ 1163 {.id = snd_soc_dapm_switch, .name = wname, .kcontrol_news = NULL, \ 1164 .num_kcontrols = 0, .reg = wreg, .shift = wshift, .mask = wmask, \ 1165 .on_val = won_val, .off_val = woff_val, \ 1166 .event = wevent, .event_flags = wflags} 1167 1168 #define CX2072X_DAPM_REG_E(wid, wname, wreg, wshift, wmask, won_val, woff_val, \ 1169 wevent, wflags) \ 1170 {.id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \ 1171 .reg = wreg, .shift = wshift, .mask = wmask, \ 1172 .on_val = won_val, .off_val = woff_val, \ 1173 .event = wevent, .event_flags = wflags} 1174 1175 static const struct snd_soc_dapm_widget cx2072x_dapm_widgets[] = { 1176 /*Playback*/ 1177 SND_SOC_DAPM_AIF_IN("In AIF", "Playback", 0, SND_SOC_NOPM, 0, 0), 1178 1179 SND_SOC_DAPM_SWITCH("I2S DAC1L", SND_SOC_NOPM, 0, 0, &i2sdac1l_ctl), 1180 SND_SOC_DAPM_SWITCH("I2S DAC1R", SND_SOC_NOPM, 0, 0, &i2sdac1r_ctl), 1181 SND_SOC_DAPM_SWITCH("I2S DAC2L", SND_SOC_NOPM, 0, 0, &i2sdac2l_ctl), 1182 SND_SOC_DAPM_SWITCH("I2S DAC2R", SND_SOC_NOPM, 0, 0, &i2sdac2r_ctl), 1183 1184 SND_SOC_DAPM_REG(snd_soc_dapm_dac, "DAC1", CX2072X_DAC1_POWER_STATE, 1185 0, 0xfff, 0x00, 0x03), 1186 1187 SND_SOC_DAPM_REG(snd_soc_dapm_dac, "DAC2", CX2072X_DAC2_POWER_STATE, 1188 0, 0xfff, 0x00, 0x03), 1189 1190 SND_SOC_DAPM_MUX("PortA Mux", SND_SOC_NOPM, 0, 0, &porta_mux), 1191 SND_SOC_DAPM_MUX("PortG Mux", SND_SOC_NOPM, 0, 0, &portg_mux), 1192 SND_SOC_DAPM_MUX("PortE Mux", SND_SOC_NOPM, 0, 0, &porte_mux), 1193 SND_SOC_DAPM_MUX("PortM Mux", SND_SOC_NOPM, 0, 0, &portm_mux), 1194 1195 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortA Power", 1196 CX2072X_PORTA_POWER_STATE, 0, 0xfff, 0x00, 0x03), 1197 1198 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortM Power", 1199 CX2072X_PORTM_POWER_STATE, 0, 0xfff, 0x00, 0x03), 1200 1201 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortG Power", 1202 CX2072X_PORTG_POWER_STATE, 0, 0xfff, 0x00, 0x03), 1203 1204 CX2072X_DAPM_SUPPLY_S("AFG Power", 0, CX2072X_AFG_POWER_STATE, 1205 0, 0xfff, 0x00, 0x03, afg_power_ev, 1206 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 1207 1208 SND_SOC_DAPM_SWITCH("PortA Out En", SND_SOC_NOPM, 0, 0, 1209 &portaouten_ctl), 1210 SND_SOC_DAPM_SWITCH("PortE Out En", SND_SOC_NOPM, 0, 0, 1211 &porteouten_ctl), 1212 SND_SOC_DAPM_SWITCH("PortG Out En", SND_SOC_NOPM, 0, 0, 1213 &portgouten_ctl), 1214 SND_SOC_DAPM_SWITCH("PortM Out En", SND_SOC_NOPM, 0, 0, 1215 &portmouten_ctl), 1216 1217 SND_SOC_DAPM_OUTPUT("PORTA"), 1218 SND_SOC_DAPM_OUTPUT("PORTG"), 1219 SND_SOC_DAPM_OUTPUT("PORTE"), 1220 SND_SOC_DAPM_OUTPUT("PORTM"), 1221 SND_SOC_DAPM_OUTPUT("AEC REF"), 1222 1223 /*Capture*/ 1224 SND_SOC_DAPM_AIF_OUT("Out AIF", "Capture", 0, SND_SOC_NOPM, 0, 0), 1225 1226 SND_SOC_DAPM_SWITCH("I2S ADC1L", SND_SOC_NOPM, 0, 0, &i2sadc1l_ctl), 1227 SND_SOC_DAPM_SWITCH("I2S ADC1R", SND_SOC_NOPM, 0, 0, &i2sadc1r_ctl), 1228 SND_SOC_DAPM_SWITCH("I2S ADC2L", SND_SOC_NOPM, 0, 0, &i2sadc2l_ctl), 1229 SND_SOC_DAPM_SWITCH("I2S ADC2R", SND_SOC_NOPM, 0, 0, &i2sadc2r_ctl), 1230 1231 SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC1", CX2072X_ADC1_POWER_STATE, 1232 0, 0xff, 0x00, 0x03), 1233 SND_SOC_DAPM_REG(snd_soc_dapm_adc, "ADC2", CX2072X_ADC2_POWER_STATE, 1234 0, 0xff, 0x00, 0x03), 1235 1236 SND_SOC_DAPM_MUX("ADC1 Mux", SND_SOC_NOPM, 0, 0, &adc1_mux), 1237 SND_SOC_DAPM_MUX("ADC2 Mux", SND_SOC_NOPM, 0, 0, &adc2_mux), 1238 1239 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortB Power", 1240 CX2072X_PORTB_POWER_STATE, 0, 0xfff, 0x00, 0x03), 1241 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortC Power", 1242 CX2072X_PORTC_POWER_STATE, 0, 0xfff, 0x00, 0x03), 1243 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortD Power", 1244 CX2072X_PORTD_POWER_STATE, 0, 0xfff, 0x00, 0x03), 1245 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "PortE Power", 1246 CX2072X_PORTE_POWER_STATE, 0, 0xfff, 0x00, 0x03), 1247 SND_SOC_DAPM_REG(snd_soc_dapm_supply, "Widget15 Power", 1248 CX2072X_MIXER_POWER_STATE, 0, 0xfff, 0x00, 0x03), 1249 1250 SND_SOC_DAPM_MIXER("Widget15 Mixer", SND_SOC_NOPM, 0, 0, 1251 wid15_mix, ARRAY_SIZE(wid15_mix)), 1252 SND_SOC_DAPM_SWITCH("PortB In En", SND_SOC_NOPM, 0, 0, &portbinen_ctl), 1253 SND_SOC_DAPM_SWITCH("PortC In En", SND_SOC_NOPM, 0, 0, &portcinen_ctl), 1254 SND_SOC_DAPM_SWITCH("PortD In En", SND_SOC_NOPM, 0, 0, &portdinen_ctl), 1255 SND_SOC_DAPM_SWITCH("PortE In En", SND_SOC_NOPM, 0, 0, &porteinen_ctl), 1256 1257 SND_SOC_DAPM_MICBIAS("Headset Bias", CX2072X_ANALOG_TEST11, 1, 0), 1258 SND_SOC_DAPM_MICBIAS("PortB Mic Bias", CX2072X_PORTB_PIN_CTRL, 2, 0), 1259 SND_SOC_DAPM_MICBIAS("PortD Mic Bias", CX2072X_PORTD_PIN_CTRL, 2, 0), 1260 SND_SOC_DAPM_MICBIAS("PortE Mic Bias", CX2072X_PORTE_PIN_CTRL, 2, 0), 1261 SND_SOC_DAPM_INPUT("PORTB"), 1262 SND_SOC_DAPM_INPUT("PORTC"), 1263 SND_SOC_DAPM_INPUT("PORTD"), 1264 SND_SOC_DAPM_INPUT("PORTEIN"), 1265 1266 }; 1267 1268 static const struct snd_soc_dapm_route cx2072x_intercon[] = { 1269 /* Playback */ 1270 {"In AIF", NULL, "AFG Power"}, 1271 {"I2S DAC1L", "Switch", "In AIF"}, 1272 {"I2S DAC1R", "Switch", "In AIF"}, 1273 {"I2S DAC2L", "Switch", "In AIF"}, 1274 {"I2S DAC2R", "Switch", "In AIF"}, 1275 {"DAC1", NULL, "I2S DAC1L"}, 1276 {"DAC1", NULL, "I2S DAC1R"}, 1277 {"DAC2", NULL, "I2S DAC2L"}, 1278 {"DAC2", NULL, "I2S DAC2R"}, 1279 {"PortA Mux", "DAC1 Switch", "DAC1"}, 1280 {"PortA Mux", "DAC2 Switch", "DAC2"}, 1281 {"PortG Mux", "DAC1 Switch", "DAC1"}, 1282 {"PortG Mux", "DAC2 Switch", "DAC2"}, 1283 {"PortE Mux", "DAC1 Switch", "DAC1"}, 1284 {"PortE Mux", "DAC2 Switch", "DAC2"}, 1285 {"PortM Mux", "DAC1 Switch", "DAC1"}, 1286 {"PortM Mux", "DAC2 Switch", "DAC2"}, 1287 {"Widget15 Mixer", "DAC1L Switch", "DAC1"}, 1288 {"Widget15 Mixer", "DAC1R Switch", "DAC2"}, 1289 {"Widget15 Mixer", "DAC2L Switch", "DAC1"}, 1290 {"Widget15 Mixer", "DAC2R Switch", "DAC2"}, 1291 {"Widget15 Mixer", NULL, "Widget15 Power"}, 1292 {"PortA Out En", "Switch", "PortA Mux"}, 1293 {"PortG Out En", "Switch", "PortG Mux"}, 1294 {"PortE Out En", "Switch", "PortE Mux"}, 1295 {"PortM Out En", "Switch", "PortM Mux"}, 1296 {"PortA Mux", NULL, "PortA Power"}, 1297 {"PortG Mux", NULL, "PortG Power"}, 1298 {"PortE Mux", NULL, "PortE Power"}, 1299 {"PortM Mux", NULL, "PortM Power"}, 1300 {"PortA Out En", NULL, "PortA Power"}, 1301 {"PortG Out En", NULL, "PortG Power"}, 1302 {"PortE Out En", NULL, "PortE Power"}, 1303 {"PortM Out En", NULL, "PortM Power"}, 1304 {"PORTA", NULL, "PortA Out En"}, 1305 {"PORTG", NULL, "PortG Out En"}, 1306 {"PORTE", NULL, "PortE Out En"}, 1307 {"PORTM", NULL, "PortM Out En"}, 1308 1309 /* Capture */ 1310 {"PORTD", NULL, "Headset Bias"}, 1311 {"PortB In En", "Switch", "PORTB"}, 1312 {"PortC In En", "Switch", "PORTC"}, 1313 {"PortD In En", "Switch", "PORTD"}, 1314 {"PortE In En", "Switch", "PORTEIN"}, 1315 {"ADC1 Mux", "PortB Switch", "PortB In En"}, 1316 {"ADC1 Mux", "PortC Switch", "PortC In En"}, 1317 {"ADC1 Mux", "PortD Switch", "PortD In En"}, 1318 {"ADC1 Mux", "PortE Switch", "PortE In En"}, 1319 {"ADC1 Mux", "Widget15 Switch", "Widget15 Mixer"}, 1320 {"ADC2 Mux", "PortC Switch", "PortC In En"}, 1321 {"ADC2 Mux", "Widget15 Switch", "Widget15 Mixer"}, 1322 {"ADC1", NULL, "ADC1 Mux"}, 1323 {"ADC2", NULL, "ADC2 Mux"}, 1324 {"I2S ADC1L", "Switch", "ADC1"}, 1325 {"I2S ADC1R", "Switch", "ADC1"}, 1326 {"I2S ADC2L", "Switch", "ADC2"}, 1327 {"I2S ADC2R", "Switch", "ADC2"}, 1328 {"Out AIF", NULL, "I2S ADC1L"}, 1329 {"Out AIF", NULL, "I2S ADC1R"}, 1330 {"Out AIF", NULL, "I2S ADC2L"}, 1331 {"Out AIF", NULL, "I2S ADC2R"}, 1332 {"Out AIF", NULL, "AFG Power"}, 1333 {"AEC REF", NULL, "Out AIF"}, 1334 {"PortB In En", NULL, "PortB Power"}, 1335 {"PortC In En", NULL, "PortC Power"}, 1336 {"PortD In En", NULL, "PortD Power"}, 1337 {"PortE In En", NULL, "PortE Power"}, 1338 }; 1339 1340 static int cx2072x_set_bias_level(struct snd_soc_component *codec, 1341 enum snd_soc_bias_level level) 1342 { 1343 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 1344 const enum snd_soc_bias_level old_level = 1345 snd_soc_component_get_bias_level(codec); 1346 1347 if (level == SND_SOC_BIAS_STANDBY && old_level == SND_SOC_BIAS_OFF) 1348 regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 0); 1349 else if (level == SND_SOC_BIAS_OFF && old_level != SND_SOC_BIAS_OFF) 1350 regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 3); 1351 1352 return 0; 1353 } 1354 1355 /* 1356 * FIXME: the whole jack detection code below is pretty platform-specific; 1357 * it has lots of implicit assumptions about the pins, etc. 1358 * However, since we have no other code and reference, take this hard-coded 1359 * setup for now. Once when we have different platform implementations, 1360 * this needs to be rewritten in a more generic form, or moving into the 1361 * platform data. 1362 */ 1363 static void cx2072x_enable_jack_detect(struct snd_soc_component *codec) 1364 { 1365 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 1366 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(codec); 1367 1368 /* No-sticky input type */ 1369 regmap_write(cx2072x->regmap, CX2072X_GPIO_STICKY_MASK, 0x1f); 1370 1371 /* Use GPOI0 as interrupt pin */ 1372 regmap_write(cx2072x->regmap, CX2072X_UM_INTERRUPT_CRTL_E, 0x12 << 24); 1373 1374 /* Enables unsolitited message on PortA */ 1375 regmap_write(cx2072x->regmap, CX2072X_PORTA_UNSOLICITED_RESPONSE, 0x80); 1376 1377 /* support both nokia and apple headset set. Monitor time = 275 ms */ 1378 regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST15, 0x73); 1379 1380 /* Disable TIP detection */ 1381 regmap_write(cx2072x->regmap, CX2072X_ANALOG_TEST12, 0x300); 1382 1383 /* Switch MusicD3Live pin to GPIO */ 1384 regmap_write(cx2072x->regmap, CX2072X_DIGITAL_TEST1, 0); 1385 1386 snd_soc_dapm_mutex_lock(dapm); 1387 1388 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PORTD"); 1389 snd_soc_dapm_force_enable_pin_unlocked(dapm, "Headset Bias"); 1390 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PortD Mic Bias"); 1391 1392 snd_soc_dapm_mutex_unlock(dapm); 1393 } 1394 1395 static void cx2072x_disable_jack_detect(struct snd_soc_component *codec) 1396 { 1397 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 1398 1399 regmap_write(cx2072x->regmap, CX2072X_UM_INTERRUPT_CRTL_E, 0); 1400 regmap_write(cx2072x->regmap, CX2072X_PORTA_UNSOLICITED_RESPONSE, 0); 1401 } 1402 1403 static int cx2072x_jack_status_check(void *data) 1404 { 1405 struct snd_soc_component *codec = data; 1406 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 1407 unsigned int jack; 1408 unsigned int type = 0; 1409 int state = 0; 1410 1411 mutex_lock(&cx2072x->lock); 1412 1413 regmap_read(cx2072x->regmap, CX2072X_PORTA_PIN_SENSE, &jack); 1414 jack = jack >> 24; 1415 regmap_read(cx2072x->regmap, CX2072X_DIGITAL_TEST11, &type); 1416 1417 if (jack == 0x80) { 1418 type = type >> 8; 1419 1420 if (type & 0x8) { 1421 /* Apple headset */ 1422 state |= SND_JACK_HEADSET; 1423 if (type & 0x2) 1424 state |= SND_JACK_BTN_0; 1425 } else { 1426 /* 1427 * Nokia headset (type & 0x4) and 1428 * regular Headphone 1429 */ 1430 state |= SND_JACK_HEADPHONE; 1431 } 1432 } 1433 1434 /* clear interrupt */ 1435 regmap_write(cx2072x->regmap, CX2072X_UM_INTERRUPT_CRTL_E, 0x12 << 24); 1436 1437 mutex_unlock(&cx2072x->lock); 1438 1439 dev_dbg(codec->dev, "CX2072X_HSDETECT type=0x%X,Jack state = %x\n", 1440 type, state); 1441 return state; 1442 } 1443 1444 static const struct snd_soc_jack_gpio cx2072x_jack_gpio = { 1445 .name = "headset", 1446 .report = SND_JACK_HEADSET | SND_JACK_BTN_0, 1447 .debounce_time = 150, 1448 .wake = true, 1449 .jack_status_check = cx2072x_jack_status_check, 1450 }; 1451 1452 static int cx2072x_set_jack(struct snd_soc_component *codec, 1453 struct snd_soc_jack *jack, void *data) 1454 { 1455 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 1456 int err; 1457 1458 if (!jack) { 1459 cx2072x_disable_jack_detect(codec); 1460 return 0; 1461 } 1462 1463 if (!cx2072x->jack_gpio.gpiod_dev) { 1464 cx2072x->jack_gpio = cx2072x_jack_gpio; 1465 cx2072x->jack_gpio.gpiod_dev = codec->dev; 1466 cx2072x->jack_gpio.data = codec; 1467 err = snd_soc_jack_add_gpios(jack, 1, &cx2072x->jack_gpio); 1468 if (err) { 1469 cx2072x->jack_gpio.gpiod_dev = NULL; 1470 return err; 1471 } 1472 } 1473 1474 cx2072x_enable_jack_detect(codec); 1475 return 0; 1476 } 1477 1478 static int cx2072x_probe(struct snd_soc_component *codec) 1479 { 1480 struct cx2072x_priv *cx2072x = snd_soc_component_get_drvdata(codec); 1481 1482 cx2072x->codec = codec; 1483 1484 /* 1485 * FIXME: below is, again, a very platform-specific init sequence, 1486 * but we keep the code here just for simplicity. It seems that all 1487 * existing hardware implementations require this, so there is no very 1488 * much reason to move this out of the codec driver to the platform 1489 * data. 1490 * But of course it's no "right" thing; if you are a good boy, don't 1491 * read and follow the code like this! 1492 */ 1493 pm_runtime_get_sync(codec->dev); 1494 regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 0); 1495 1496 regmap_multi_reg_write(cx2072x->regmap, cx2072x_reg_init, 1497 ARRAY_SIZE(cx2072x_reg_init)); 1498 1499 /* configure PortC as input device */ 1500 regmap_update_bits(cx2072x->regmap, CX2072X_PORTC_PIN_CTRL, 1501 0x20, 0x20); 1502 1503 regmap_update_bits(cx2072x->regmap, CX2072X_DIGITAL_BIOS_TEST2, 1504 0x84, 0xff); 1505 1506 regmap_write(cx2072x->regmap, CX2072X_AFG_POWER_STATE, 3); 1507 pm_runtime_put(codec->dev); 1508 1509 return 0; 1510 } 1511 1512 static const struct snd_soc_component_driver soc_codec_driver_cx2072x = { 1513 .probe = cx2072x_probe, 1514 .set_bias_level = cx2072x_set_bias_level, 1515 .set_jack = cx2072x_set_jack, 1516 .controls = cx2072x_snd_controls, 1517 .num_controls = ARRAY_SIZE(cx2072x_snd_controls), 1518 .dapm_widgets = cx2072x_dapm_widgets, 1519 .num_dapm_widgets = ARRAY_SIZE(cx2072x_dapm_widgets), 1520 .dapm_routes = cx2072x_intercon, 1521 .num_dapm_routes = ARRAY_SIZE(cx2072x_intercon), 1522 .endianness = 1, 1523 }; 1524 1525 /* 1526 * DAI ops 1527 */ 1528 static const struct snd_soc_dai_ops cx2072x_dai_ops = { 1529 .set_sysclk = cx2072x_set_dai_sysclk, 1530 .set_fmt = cx2072x_set_dai_fmt, 1531 .hw_params = cx2072x_hw_params, 1532 .set_bclk_ratio = cx2072x_set_dai_bclk_ratio, 1533 }; 1534 1535 static int cx2072x_dsp_dai_probe(struct snd_soc_dai *dai) 1536 { 1537 struct cx2072x_priv *cx2072x = 1538 snd_soc_component_get_drvdata(dai->component); 1539 1540 cx2072x->en_aec_ref = true; 1541 return 0; 1542 } 1543 1544 static const struct snd_soc_dai_ops cx2072x_dai_ops2 = { 1545 .probe = cx2072x_dsp_dai_probe, 1546 .set_sysclk = cx2072x_set_dai_sysclk, 1547 .set_fmt = cx2072x_set_dai_fmt, 1548 .hw_params = cx2072x_hw_params, 1549 .set_bclk_ratio = cx2072x_set_dai_bclk_ratio, 1550 }; 1551 1552 #define CX2072X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 1553 1554 static struct snd_soc_dai_driver soc_codec_cx2072x_dai[] = { 1555 { /* playback and capture */ 1556 .name = "cx2072x-hifi", 1557 .id = CX2072X_DAI_HIFI, 1558 .playback = { 1559 .stream_name = "Playback", 1560 .channels_min = 1, 1561 .channels_max = 2, 1562 .rates = CX2072X_RATES_DSP, 1563 .formats = CX2072X_FORMATS, 1564 }, 1565 .capture = { 1566 .stream_name = "Capture", 1567 .channels_min = 1, 1568 .channels_max = 2, 1569 .rates = CX2072X_RATES_DSP, 1570 .formats = CX2072X_FORMATS, 1571 }, 1572 .ops = &cx2072x_dai_ops, 1573 .symmetric_rate = 1, 1574 }, 1575 { /* plabayck only, return echo reference to Conexant DSP chip */ 1576 .name = "cx2072x-dsp", 1577 .id = CX2072X_DAI_DSP, 1578 .playback = { 1579 .stream_name = "DSP Playback", 1580 .channels_min = 2, 1581 .channels_max = 2, 1582 .rates = CX2072X_RATES_DSP, 1583 .formats = CX2072X_FORMATS, 1584 }, 1585 .ops = &cx2072x_dai_ops2, 1586 }, 1587 { /* plabayck only, return echo reference through I2S TX */ 1588 .name = "cx2072x-aec", 1589 .id = 3, 1590 .capture = { 1591 .stream_name = "AEC Capture", 1592 .channels_min = 2, 1593 .channels_max = 2, 1594 .rates = CX2072X_RATES_DSP, 1595 .formats = CX2072X_FORMATS, 1596 }, 1597 }, 1598 }; 1599 1600 static const struct regmap_config cx2072x_regmap = { 1601 .reg_bits = 16, 1602 .val_bits = 32, 1603 .max_register = CX2072X_REG_MAX, 1604 .reg_defaults = cx2072x_reg_defaults, 1605 .num_reg_defaults = ARRAY_SIZE(cx2072x_reg_defaults), 1606 .cache_type = REGCACHE_RBTREE, 1607 .readable_reg = cx2072x_readable_register, 1608 .volatile_reg = cx2072x_volatile_register, 1609 /* Needs custom read/write functions for various register lengths */ 1610 .reg_read = cx2072x_reg_read, 1611 .reg_write = cx2072x_reg_write, 1612 }; 1613 1614 static int __maybe_unused cx2072x_runtime_suspend(struct device *dev) 1615 { 1616 struct cx2072x_priv *cx2072x = dev_get_drvdata(dev); 1617 1618 clk_disable_unprepare(cx2072x->mclk); 1619 return 0; 1620 } 1621 1622 static int __maybe_unused cx2072x_runtime_resume(struct device *dev) 1623 { 1624 struct cx2072x_priv *cx2072x = dev_get_drvdata(dev); 1625 1626 return clk_prepare_enable(cx2072x->mclk); 1627 } 1628 1629 static int cx2072x_i2c_probe(struct i2c_client *i2c) 1630 { 1631 struct cx2072x_priv *cx2072x; 1632 unsigned int ven_id, rev_id; 1633 int ret; 1634 1635 cx2072x = devm_kzalloc(&i2c->dev, sizeof(struct cx2072x_priv), 1636 GFP_KERNEL); 1637 if (!cx2072x) 1638 return -ENOMEM; 1639 1640 cx2072x->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, 1641 &cx2072x_regmap); 1642 if (IS_ERR(cx2072x->regmap)) 1643 return PTR_ERR(cx2072x->regmap); 1644 1645 mutex_init(&cx2072x->lock); 1646 1647 i2c_set_clientdata(i2c, cx2072x); 1648 1649 cx2072x->dev = &i2c->dev; 1650 cx2072x->pll_changed = true; 1651 cx2072x->i2spcm_changed = true; 1652 cx2072x->bclk_ratio = 0; 1653 1654 cx2072x->mclk = devm_clk_get(cx2072x->dev, "mclk"); 1655 if (IS_ERR(cx2072x->mclk)) { 1656 dev_err(cx2072x->dev, "Failed to get MCLK\n"); 1657 return PTR_ERR(cx2072x->mclk); 1658 } 1659 1660 regmap_read(cx2072x->regmap, CX2072X_VENDOR_ID, &ven_id); 1661 regmap_read(cx2072x->regmap, CX2072X_REVISION_ID, &rev_id); 1662 1663 dev_info(cx2072x->dev, "codec version: %08x,%08x\n", ven_id, rev_id); 1664 1665 ret = devm_snd_soc_register_component(cx2072x->dev, 1666 &soc_codec_driver_cx2072x, 1667 soc_codec_cx2072x_dai, 1668 ARRAY_SIZE(soc_codec_cx2072x_dai)); 1669 if (ret < 0) 1670 return ret; 1671 1672 pm_runtime_use_autosuspend(cx2072x->dev); 1673 pm_runtime_enable(cx2072x->dev); 1674 1675 return 0; 1676 } 1677 1678 static void cx2072x_i2c_remove(struct i2c_client *i2c) 1679 { 1680 pm_runtime_disable(&i2c->dev); 1681 } 1682 1683 static const struct i2c_device_id cx2072x_i2c_id[] = { 1684 { "cx20721" }, 1685 { "cx20723" }, 1686 {} 1687 }; 1688 MODULE_DEVICE_TABLE(i2c, cx2072x_i2c_id); 1689 1690 #ifdef CONFIG_ACPI 1691 static struct acpi_device_id cx2072x_acpi_match[] = { 1692 { "14F10720", 0 }, 1693 {}, 1694 }; 1695 MODULE_DEVICE_TABLE(acpi, cx2072x_acpi_match); 1696 #endif 1697 1698 static const struct dev_pm_ops cx2072x_runtime_pm = { 1699 SET_RUNTIME_PM_OPS(cx2072x_runtime_suspend, cx2072x_runtime_resume, 1700 NULL) 1701 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1702 pm_runtime_force_resume) 1703 }; 1704 1705 static struct i2c_driver cx2072x_i2c_driver = { 1706 .driver = { 1707 .name = "cx2072x", 1708 .acpi_match_table = ACPI_PTR(cx2072x_acpi_match), 1709 .pm = &cx2072x_runtime_pm, 1710 }, 1711 .probe = cx2072x_i2c_probe, 1712 .remove = cx2072x_i2c_remove, 1713 .id_table = cx2072x_i2c_id, 1714 }; 1715 1716 module_i2c_driver(cx2072x_i2c_driver); 1717 1718 MODULE_DESCRIPTION("ASoC cx2072x Codec Driver"); 1719 MODULE_AUTHOR("Simon Ho <simon.ho@conexant.com>"); 1720 MODULE_LICENSE("GPL"); 1721
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.