Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: add rt298 codec driver

It is the initial version of ALC298 codec driver.

Signed-off-by: Bard Liao <bardliao@realtek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Bard Liao and committed by
Mark Brown
6adcafae d770e558

+1509
+20
include/sound/rt298.h
··· 1 + /* 2 + * linux/sound/rt286.h -- Platform data for RT286 3 + * 4 + * Copyright 2013 Realtek Microelectronics 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License version 2 as 8 + * published by the Free Software Foundation. 9 + */ 10 + 11 + #ifndef __LINUX_SND_RT298_H 12 + #define __LINUX_SND_RT298_H 13 + 14 + struct rt298_platform_data { 15 + bool cbj_en; /*combo jack enable*/ 16 + bool gpio2_en; /*GPIO2 enable*/ 17 + bool suspend_power_off; /* power is off during suspend */ 18 + }; 19 + 20 + #endif
+7
sound/soc/codecs/Kconfig
··· 83 83 select SND_SOC_PCM512x_I2C if I2C 84 84 select SND_SOC_PCM512x_SPI if SPI_MASTER 85 85 select SND_SOC_RT286 if I2C 86 + select SND_SOC_RT298 if I2C 86 87 select SND_SOC_RT5631 if I2C 87 88 select SND_SOC_RT5640 if I2C 88 89 select SND_SOC_RT5645 if I2C ··· 513 512 config SND_SOC_RL6347A 514 513 tristate 515 514 default y if SND_SOC_RT286=y 515 + default y if SND_SOC_RT298=y 516 516 default m if SND_SOC_RT286=m 517 + default m if SND_SOC_RT298=m 517 518 518 519 config SND_SOC_RT286 520 + tristate 521 + depends on I2C 522 + 523 + config SND_SOC_RT298 519 524 tristate 520 525 depends on I2C 521 526
+2
sound/soc/codecs/Makefile
··· 79 79 snd-soc-rl6231-objs := rl6231.o 80 80 snd-soc-rl6347a-objs := rl6347a.o 81 81 snd-soc-rt286-objs := rt286.o 82 + snd-soc-rt298-objs := rt298.o 82 83 snd-soc-rt5631-objs := rt5631.o 83 84 snd-soc-rt5640-objs := rt5640.o 84 85 snd-soc-rt5645-objs := rt5645.o ··· 267 266 obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o 268 267 obj-$(CONFIG_SND_SOC_RL6347A) += snd-soc-rl6347a.o 269 268 obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o 269 + obj-$(CONFIG_SND_SOC_RT298) += snd-soc-rt298.o 270 270 obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 271 271 obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o 272 272 obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
+1274
sound/soc/codecs/rt298.c
··· 1 + /* 2 + * rt298.c -- RT298 ALSA SoC audio codec driver 3 + * 4 + * Copyright 2015 Realtek Semiconductor Corp. 5 + * Author: Bard Liao <bardliao@realtek.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #include <linux/module.h> 13 + #include <linux/moduleparam.h> 14 + #include <linux/init.h> 15 + #include <linux/delay.h> 16 + #include <linux/pm.h> 17 + #include <linux/i2c.h> 18 + #include <linux/platform_device.h> 19 + #include <linux/spi/spi.h> 20 + #include <linux/acpi.h> 21 + #include <sound/core.h> 22 + #include <sound/pcm.h> 23 + #include <sound/pcm_params.h> 24 + #include <sound/soc.h> 25 + #include <sound/soc-dapm.h> 26 + #include <sound/initval.h> 27 + #include <sound/tlv.h> 28 + #include <sound/jack.h> 29 + #include <linux/workqueue.h> 30 + #include <sound/rt298.h> 31 + #include <sound/hda_verbs.h> 32 + 33 + #include "rl6347a.h" 34 + #include "rt298.h" 35 + 36 + #define RT298_VENDOR_ID 0x10ec0298 37 + 38 + struct rt298_priv { 39 + struct reg_default *index_cache; 40 + int index_cache_size; 41 + struct regmap *regmap; 42 + struct snd_soc_codec *codec; 43 + struct rt298_platform_data pdata; 44 + struct i2c_client *i2c; 45 + struct snd_soc_jack *jack; 46 + struct delayed_work jack_detect_work; 47 + int sys_clk; 48 + int clk_id; 49 + int is_hp_in; 50 + }; 51 + 52 + static struct reg_default rt298_index_def[] = { 53 + { 0x01, 0xaaaa }, 54 + { 0x02, 0x8aaa }, 55 + { 0x03, 0x0002 }, 56 + { 0x04, 0xaf01 }, 57 + { 0x08, 0x000d }, 58 + { 0x09, 0xd810 }, 59 + { 0x0a, 0x0120 }, 60 + { 0x0b, 0x0000 }, 61 + { 0x0d, 0x2800 }, 62 + { 0x0f, 0x0000 }, 63 + { 0x19, 0x0a17 }, 64 + { 0x20, 0x0020 }, 65 + { 0x33, 0x0208 }, 66 + { 0x46, 0x0300 }, 67 + { 0x49, 0x0004 }, 68 + { 0x4f, 0x50e9 }, 69 + { 0x50, 0x2000 }, 70 + { 0x63, 0x2902 }, 71 + { 0x67, 0x1111 }, 72 + { 0x68, 0x1016 }, 73 + { 0x69, 0x273f }, 74 + }; 75 + #define INDEX_CACHE_SIZE ARRAY_SIZE(rt298_index_def) 76 + 77 + static const struct reg_default rt298_reg[] = { 78 + { 0x00170500, 0x00000400 }, 79 + { 0x00220000, 0x00000031 }, 80 + { 0x00239000, 0x0000007f }, 81 + { 0x0023a000, 0x0000007f }, 82 + { 0x00270500, 0x00000400 }, 83 + { 0x00370500, 0x00000400 }, 84 + { 0x00870500, 0x00000400 }, 85 + { 0x00920000, 0x00000031 }, 86 + { 0x00935000, 0x000000c3 }, 87 + { 0x00936000, 0x000000c3 }, 88 + { 0x00970500, 0x00000400 }, 89 + { 0x00b37000, 0x00000097 }, 90 + { 0x00b37200, 0x00000097 }, 91 + { 0x00b37300, 0x00000097 }, 92 + { 0x00c37000, 0x00000000 }, 93 + { 0x00c37100, 0x00000080 }, 94 + { 0x01270500, 0x00000400 }, 95 + { 0x01370500, 0x00000400 }, 96 + { 0x01371f00, 0x411111f0 }, 97 + { 0x01439000, 0x00000080 }, 98 + { 0x0143a000, 0x00000080 }, 99 + { 0x01470700, 0x00000000 }, 100 + { 0x01470500, 0x00000400 }, 101 + { 0x01470c00, 0x00000000 }, 102 + { 0x01470100, 0x00000000 }, 103 + { 0x01837000, 0x00000000 }, 104 + { 0x01870500, 0x00000400 }, 105 + { 0x02050000, 0x00000000 }, 106 + { 0x02139000, 0x00000080 }, 107 + { 0x0213a000, 0x00000080 }, 108 + { 0x02170100, 0x00000000 }, 109 + { 0x02170500, 0x00000400 }, 110 + { 0x02170700, 0x00000000 }, 111 + { 0x02270100, 0x00000000 }, 112 + { 0x02370100, 0x00000000 }, 113 + { 0x01870700, 0x00000020 }, 114 + { 0x00830000, 0x000000c3 }, 115 + { 0x00930000, 0x000000c3 }, 116 + { 0x01270700, 0x00000000 }, 117 + }; 118 + 119 + static bool rt298_volatile_register(struct device *dev, unsigned int reg) 120 + { 121 + switch (reg) { 122 + case 0 ... 0xff: 123 + case RT298_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): 124 + case RT298_GET_HP_SENSE: 125 + case RT298_GET_MIC1_SENSE: 126 + case RT298_PROC_COEF: 127 + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_MIC1, 0): 128 + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_SPK_OUT, 0): 129 + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_HP_OUT, 0): 130 + return true; 131 + default: 132 + return true; 133 + } 134 + 135 + 136 + } 137 + 138 + static bool rt298_readable_register(struct device *dev, unsigned int reg) 139 + { 140 + switch (reg) { 141 + case 0 ... 0xff: 142 + case RT298_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): 143 + case RT298_GET_HP_SENSE: 144 + case RT298_GET_MIC1_SENSE: 145 + case RT298_SET_AUDIO_POWER: 146 + case RT298_SET_HPO_POWER: 147 + case RT298_SET_SPK_POWER: 148 + case RT298_SET_DMIC1_POWER: 149 + case RT298_SPK_MUX: 150 + case RT298_HPO_MUX: 151 + case RT298_ADC0_MUX: 152 + case RT298_ADC1_MUX: 153 + case RT298_SET_MIC1: 154 + case RT298_SET_PIN_HPO: 155 + case RT298_SET_PIN_SPK: 156 + case RT298_SET_PIN_DMIC1: 157 + case RT298_SPK_EAPD: 158 + case RT298_SET_AMP_GAIN_HPO: 159 + case RT298_SET_DMIC2_DEFAULT: 160 + case RT298_DACL_GAIN: 161 + case RT298_DACR_GAIN: 162 + case RT298_ADCL_GAIN: 163 + case RT298_ADCR_GAIN: 164 + case RT298_MIC_GAIN: 165 + case RT298_SPOL_GAIN: 166 + case RT298_SPOR_GAIN: 167 + case RT298_HPOL_GAIN: 168 + case RT298_HPOR_GAIN: 169 + case RT298_F_DAC_SWITCH: 170 + case RT298_F_RECMIX_SWITCH: 171 + case RT298_REC_MIC_SWITCH: 172 + case RT298_REC_I2S_SWITCH: 173 + case RT298_REC_LINE_SWITCH: 174 + case RT298_REC_BEEP_SWITCH: 175 + case RT298_DAC_FORMAT: 176 + case RT298_ADC_FORMAT: 177 + case RT298_COEF_INDEX: 178 + case RT298_PROC_COEF: 179 + case RT298_SET_AMP_GAIN_ADC_IN1: 180 + case RT298_SET_AMP_GAIN_ADC_IN2: 181 + case RT298_SET_POWER(RT298_DAC_OUT1): 182 + case RT298_SET_POWER(RT298_DAC_OUT2): 183 + case RT298_SET_POWER(RT298_ADC_IN1): 184 + case RT298_SET_POWER(RT298_ADC_IN2): 185 + case RT298_SET_POWER(RT298_DMIC2): 186 + case RT298_SET_POWER(RT298_MIC1): 187 + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_MIC1, 0): 188 + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_SPK_OUT, 0): 189 + case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_HP_OUT, 0): 190 + return true; 191 + default: 192 + return false; 193 + } 194 + } 195 + 196 + #ifdef CONFIG_PM 197 + static void rt298_index_sync(struct snd_soc_codec *codec) 198 + { 199 + struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec); 200 + int i; 201 + 202 + for (i = 0; i < INDEX_CACHE_SIZE; i++) { 203 + snd_soc_write(codec, rt298->index_cache[i].reg, 204 + rt298->index_cache[i].def); 205 + } 206 + } 207 + #endif 208 + 209 + static int rt298_support_power_controls[] = { 210 + RT298_DAC_OUT1, 211 + RT298_DAC_OUT2, 212 + RT298_ADC_IN1, 213 + RT298_ADC_IN2, 214 + RT298_MIC1, 215 + RT298_DMIC1, 216 + RT298_DMIC2, 217 + RT298_SPK_OUT, 218 + RT298_HP_OUT, 219 + }; 220 + #define RT298_POWER_REG_LEN ARRAY_SIZE(rt298_support_power_controls) 221 + 222 + static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic) 223 + { 224 + struct snd_soc_dapm_context *dapm; 225 + unsigned int val, buf; 226 + 227 + *hp = false; 228 + *mic = false; 229 + 230 + if (!rt298->codec) 231 + return -EINVAL; 232 + 233 + dapm = snd_soc_codec_get_dapm(rt298->codec); 234 + 235 + if (rt298->pdata.cbj_en) { 236 + regmap_read(rt298->regmap, RT298_GET_HP_SENSE, &buf); 237 + *hp = buf & 0x80000000; 238 + if (*hp == rt298->is_hp_in) 239 + return -1; 240 + rt298->is_hp_in = *hp; 241 + if (*hp) { 242 + /* power on HV,VERF */ 243 + regmap_update_bits(rt298->regmap, 244 + RT298_DC_GAIN, 0x200, 0x200); 245 + 246 + snd_soc_dapm_force_enable_pin(dapm, "HV"); 247 + snd_soc_dapm_force_enable_pin(dapm, "VREF"); 248 + /* power LDO1 */ 249 + snd_soc_dapm_force_enable_pin(dapm, "LDO1"); 250 + snd_soc_dapm_sync(dapm); 251 + 252 + regmap_write(rt298->regmap, RT298_SET_MIC1, 0x24); 253 + msleep(50); 254 + 255 + regmap_update_bits(rt298->regmap, 256 + RT298_CBJ_CTRL1, 0xfcc0, 0xd400); 257 + msleep(300); 258 + regmap_read(rt298->regmap, RT298_CBJ_CTRL2, &val); 259 + 260 + if (0x0070 == (val & 0x0070)) { 261 + *mic = true; 262 + } else { 263 + regmap_update_bits(rt298->regmap, 264 + RT298_CBJ_CTRL1, 0xfcc0, 0xe400); 265 + msleep(300); 266 + regmap_read(rt298->regmap, 267 + RT298_CBJ_CTRL2, &val); 268 + if (0x0070 == (val & 0x0070)) 269 + *mic = true; 270 + else 271 + *mic = false; 272 + } 273 + regmap_update_bits(rt298->regmap, 274 + RT298_DC_GAIN, 0x200, 0x0); 275 + 276 + } else { 277 + *mic = false; 278 + regmap_write(rt298->regmap, RT298_SET_MIC1, 0x20); 279 + } 280 + } else { 281 + regmap_read(rt298->regmap, RT298_GET_HP_SENSE, &buf); 282 + *hp = buf & 0x80000000; 283 + regmap_read(rt298->regmap, RT298_GET_MIC1_SENSE, &buf); 284 + *mic = buf & 0x80000000; 285 + } 286 + 287 + snd_soc_dapm_disable_pin(dapm, "HV"); 288 + snd_soc_dapm_disable_pin(dapm, "VREF"); 289 + if (!*hp) 290 + snd_soc_dapm_disable_pin(dapm, "LDO1"); 291 + snd_soc_dapm_sync(dapm); 292 + 293 + pr_debug("*hp = %d *mic = %d\n", *hp, *mic); 294 + 295 + return 0; 296 + } 297 + 298 + static void rt298_jack_detect_work(struct work_struct *work) 299 + { 300 + struct rt298_priv *rt298 = 301 + container_of(work, struct rt298_priv, jack_detect_work.work); 302 + int status = 0; 303 + bool hp = false; 304 + bool mic = false; 305 + 306 + if (rt298_jack_detect(rt298, &hp, &mic) < 0) 307 + return; 308 + 309 + if (hp == true) 310 + status |= SND_JACK_HEADPHONE; 311 + 312 + if (mic == true) 313 + status |= SND_JACK_MICROPHONE; 314 + 315 + snd_soc_jack_report(rt298->jack, status, 316 + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); 317 + } 318 + 319 + int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) 320 + { 321 + struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec); 322 + 323 + rt298->jack = jack; 324 + 325 + /* Send an initial empty report */ 326 + snd_soc_jack_report(rt298->jack, 0, 327 + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); 328 + 329 + return 0; 330 + } 331 + EXPORT_SYMBOL_GPL(rt298_mic_detect); 332 + 333 + static int is_mclk_mode(struct snd_soc_dapm_widget *source, 334 + struct snd_soc_dapm_widget *sink) 335 + { 336 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); 337 + struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec); 338 + 339 + if (rt298->clk_id == RT298_SCLK_S_MCLK) 340 + return 1; 341 + else 342 + return 0; 343 + } 344 + 345 + static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); 346 + static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); 347 + 348 + static const struct snd_kcontrol_new rt298_snd_controls[] = { 349 + SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT298_DACL_GAIN, 350 + RT298_DACR_GAIN, 0, 0x7f, 0, out_vol_tlv), 351 + SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT298_ADCL_GAIN, 352 + RT298_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv), 353 + SOC_SINGLE_TLV("AMIC Volume", RT298_MIC_GAIN, 354 + 0, 0x3, 0, mic_vol_tlv), 355 + SOC_DOUBLE_R("Speaker Playback Switch", RT298_SPOL_GAIN, 356 + RT298_SPOR_GAIN, RT298_MUTE_SFT, 1, 1), 357 + }; 358 + 359 + /* Digital Mixer */ 360 + static const struct snd_kcontrol_new rt298_front_mix[] = { 361 + SOC_DAPM_SINGLE("DAC Switch", RT298_F_DAC_SWITCH, 362 + RT298_MUTE_SFT, 1, 1), 363 + SOC_DAPM_SINGLE("RECMIX Switch", RT298_F_RECMIX_SWITCH, 364 + RT298_MUTE_SFT, 1, 1), 365 + }; 366 + 367 + /* Analog Input Mixer */ 368 + static const struct snd_kcontrol_new rt298_rec_mix[] = { 369 + SOC_DAPM_SINGLE("Mic1 Switch", RT298_REC_MIC_SWITCH, 370 + RT298_MUTE_SFT, 1, 1), 371 + SOC_DAPM_SINGLE("I2S Switch", RT298_REC_I2S_SWITCH, 372 + RT298_MUTE_SFT, 1, 1), 373 + SOC_DAPM_SINGLE("Line1 Switch", RT298_REC_LINE_SWITCH, 374 + RT298_MUTE_SFT, 1, 1), 375 + SOC_DAPM_SINGLE("Beep Switch", RT298_REC_BEEP_SWITCH, 376 + RT298_MUTE_SFT, 1, 1), 377 + }; 378 + 379 + static const struct snd_kcontrol_new spo_enable_control = 380 + SOC_DAPM_SINGLE("Switch", RT298_SET_PIN_SPK, 381 + RT298_SET_PIN_SFT, 1, 0); 382 + 383 + static const struct snd_kcontrol_new hpol_enable_control = 384 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT298_HPOL_GAIN, 385 + RT298_MUTE_SFT, 1, 1); 386 + 387 + static const struct snd_kcontrol_new hpor_enable_control = 388 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT298_HPOR_GAIN, 389 + RT298_MUTE_SFT, 1, 1); 390 + 391 + /* ADC0 source */ 392 + static const char * const rt298_adc_src[] = { 393 + "Mic", "RECMIX", "Dmic" 394 + }; 395 + 396 + static const int rt298_adc_values[] = { 397 + 0, 4, 5, 398 + }; 399 + 400 + static SOC_VALUE_ENUM_SINGLE_DECL( 401 + rt298_adc0_enum, RT298_ADC0_MUX, RT298_ADC_SEL_SFT, 402 + RT298_ADC_SEL_MASK, rt298_adc_src, rt298_adc_values); 403 + 404 + static const struct snd_kcontrol_new rt298_adc0_mux = 405 + SOC_DAPM_ENUM("ADC 0 source", rt298_adc0_enum); 406 + 407 + static SOC_VALUE_ENUM_SINGLE_DECL( 408 + rt298_adc1_enum, RT298_ADC1_MUX, RT298_ADC_SEL_SFT, 409 + RT298_ADC_SEL_MASK, rt298_adc_src, rt298_adc_values); 410 + 411 + static const struct snd_kcontrol_new rt298_adc1_mux = 412 + SOC_DAPM_ENUM("ADC 1 source", rt298_adc1_enum); 413 + 414 + static const char * const rt298_dac_src[] = { 415 + "Front", "Surround" 416 + }; 417 + /* HP-OUT source */ 418 + static SOC_ENUM_SINGLE_DECL(rt298_hpo_enum, RT298_HPO_MUX, 419 + 0, rt298_dac_src); 420 + 421 + static const struct snd_kcontrol_new rt298_hpo_mux = 422 + SOC_DAPM_ENUM("HPO source", rt298_hpo_enum); 423 + 424 + /* SPK-OUT source */ 425 + static SOC_ENUM_SINGLE_DECL(rt298_spo_enum, RT298_SPK_MUX, 426 + 0, rt298_dac_src); 427 + 428 + static const struct snd_kcontrol_new rt298_spo_mux = 429 + SOC_DAPM_ENUM("SPO source", rt298_spo_enum); 430 + 431 + static int rt298_spk_event(struct snd_soc_dapm_widget *w, 432 + struct snd_kcontrol *kcontrol, int event) 433 + { 434 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 435 + 436 + switch (event) { 437 + case SND_SOC_DAPM_POST_PMU: 438 + snd_soc_write(codec, 439 + RT298_SPK_EAPD, RT298_SET_EAPD_HIGH); 440 + break; 441 + case SND_SOC_DAPM_PRE_PMD: 442 + snd_soc_write(codec, 443 + RT298_SPK_EAPD, RT298_SET_EAPD_LOW); 444 + break; 445 + 446 + default: 447 + return 0; 448 + } 449 + 450 + return 0; 451 + } 452 + 453 + static int rt298_set_dmic1_event(struct snd_soc_dapm_widget *w, 454 + struct snd_kcontrol *kcontrol, int event) 455 + { 456 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 457 + 458 + switch (event) { 459 + case SND_SOC_DAPM_POST_PMU: 460 + snd_soc_write(codec, RT298_SET_PIN_DMIC1, 0x20); 461 + break; 462 + case SND_SOC_DAPM_PRE_PMD: 463 + snd_soc_write(codec, RT298_SET_PIN_DMIC1, 0); 464 + break; 465 + default: 466 + return 0; 467 + } 468 + 469 + return 0; 470 + } 471 + 472 + static int rt298_adc_event(struct snd_soc_dapm_widget *w, 473 + struct snd_kcontrol *kcontrol, int event) 474 + { 475 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 476 + unsigned int nid; 477 + 478 + nid = (w->reg >> 20) & 0xff; 479 + 480 + switch (event) { 481 + case SND_SOC_DAPM_POST_PMU: 482 + snd_soc_update_bits(codec, 483 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0), 484 + 0x7080, 0x7000); 485 + break; 486 + case SND_SOC_DAPM_PRE_PMD: 487 + snd_soc_update_bits(codec, 488 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0), 489 + 0x7080, 0x7080); 490 + break; 491 + default: 492 + return 0; 493 + } 494 + 495 + return 0; 496 + } 497 + 498 + static int rt298_mic1_event(struct snd_soc_dapm_widget *w, 499 + struct snd_kcontrol *kcontrol, int event) 500 + { 501 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 502 + 503 + switch (event) { 504 + case SND_SOC_DAPM_PRE_PMU: 505 + snd_soc_update_bits(codec, 506 + RT298_A_BIAS_CTRL3, 0xc000, 0x8000); 507 + snd_soc_update_bits(codec, 508 + RT298_A_BIAS_CTRL2, 0xc000, 0x8000); 509 + break; 510 + case SND_SOC_DAPM_POST_PMD: 511 + snd_soc_update_bits(codec, 512 + RT298_A_BIAS_CTRL3, 0xc000, 0x0000); 513 + snd_soc_update_bits(codec, 514 + RT298_A_BIAS_CTRL2, 0xc000, 0x0000); 515 + break; 516 + default: 517 + return 0; 518 + } 519 + 520 + return 0; 521 + } 522 + 523 + static int rt298_vref_event(struct snd_soc_dapm_widget *w, 524 + struct snd_kcontrol *kcontrol, int event) 525 + { 526 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 527 + 528 + switch (event) { 529 + case SND_SOC_DAPM_PRE_PMU: 530 + snd_soc_update_bits(codec, 531 + RT298_CBJ_CTRL1, 0x0400, 0x0000); 532 + mdelay(50); 533 + break; 534 + default: 535 + return 0; 536 + } 537 + 538 + return 0; 539 + } 540 + 541 + static const struct snd_soc_dapm_widget rt298_dapm_widgets[] = { 542 + 543 + SND_SOC_DAPM_SUPPLY_S("HV", 1, RT298_POWER_CTRL1, 544 + 12, 1, NULL, 0), 545 + SND_SOC_DAPM_SUPPLY("VREF", RT298_POWER_CTRL1, 546 + 0, 1, rt298_vref_event, SND_SOC_DAPM_PRE_PMU), 547 + SND_SOC_DAPM_SUPPLY_S("BG_MBIAS", 1, RT298_POWER_CTRL2, 548 + 1, 0, NULL, 0), 549 + SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT298_POWER_CTRL2, 550 + 2, 0, NULL, 0), 551 + SND_SOC_DAPM_SUPPLY_S("LDO2", 1, RT298_POWER_CTRL2, 552 + 3, 0, NULL, 0), 553 + SND_SOC_DAPM_SUPPLY_S("VREF1", 1, RT298_POWER_CTRL2, 554 + 4, 1, NULL, 0), 555 + SND_SOC_DAPM_SUPPLY_S("LV", 2, RT298_POWER_CTRL1, 556 + 13, 1, NULL, 0), 557 + 558 + 559 + SND_SOC_DAPM_SUPPLY("MCLK MODE", RT298_PLL_CTRL1, 560 + 5, 0, NULL, 0), 561 + SND_SOC_DAPM_SUPPLY("MIC1 Input Buffer", SND_SOC_NOPM, 562 + 0, 0, rt298_mic1_event, SND_SOC_DAPM_PRE_PMU | 563 + SND_SOC_DAPM_POST_PMD), 564 + 565 + /* Input Lines */ 566 + SND_SOC_DAPM_INPUT("DMIC1 Pin"), 567 + SND_SOC_DAPM_INPUT("DMIC2 Pin"), 568 + SND_SOC_DAPM_INPUT("MIC1"), 569 + SND_SOC_DAPM_INPUT("LINE1"), 570 + SND_SOC_DAPM_INPUT("Beep"), 571 + 572 + /* DMIC */ 573 + SND_SOC_DAPM_PGA_E("DMIC1", RT298_SET_POWER(RT298_DMIC1), 0, 1, 574 + NULL, 0, rt298_set_dmic1_event, 575 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 576 + SND_SOC_DAPM_PGA("DMIC2", RT298_SET_POWER(RT298_DMIC2), 0, 1, 577 + NULL, 0), 578 + SND_SOC_DAPM_SUPPLY("DMIC Receiver", SND_SOC_NOPM, 579 + 0, 0, NULL, 0), 580 + 581 + /* REC Mixer */ 582 + SND_SOC_DAPM_MIXER("RECMIX", SND_SOC_NOPM, 0, 0, 583 + rt298_rec_mix, ARRAY_SIZE(rt298_rec_mix)), 584 + 585 + /* ADCs */ 586 + SND_SOC_DAPM_ADC("ADC 0", NULL, SND_SOC_NOPM, 0, 0), 587 + SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM, 0, 0), 588 + 589 + /* ADC Mux */ 590 + SND_SOC_DAPM_MUX_E("ADC 0 Mux", RT298_SET_POWER(RT298_ADC_IN1), 0, 1, 591 + &rt298_adc0_mux, rt298_adc_event, SND_SOC_DAPM_PRE_PMD | 592 + SND_SOC_DAPM_POST_PMU), 593 + SND_SOC_DAPM_MUX_E("ADC 1 Mux", RT298_SET_POWER(RT298_ADC_IN2), 0, 1, 594 + &rt298_adc1_mux, rt298_adc_event, SND_SOC_DAPM_PRE_PMD | 595 + SND_SOC_DAPM_POST_PMU), 596 + 597 + /* Audio Interface */ 598 + SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 599 + SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), 600 + SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), 601 + SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), 602 + 603 + /* Output Side */ 604 + /* DACs */ 605 + SND_SOC_DAPM_DAC("DAC 0", NULL, SND_SOC_NOPM, 0, 0), 606 + SND_SOC_DAPM_DAC("DAC 1", NULL, SND_SOC_NOPM, 0, 0), 607 + 608 + /* Output Mux */ 609 + SND_SOC_DAPM_MUX("SPK Mux", SND_SOC_NOPM, 0, 0, &rt298_spo_mux), 610 + SND_SOC_DAPM_MUX("HPO Mux", SND_SOC_NOPM, 0, 0, &rt298_hpo_mux), 611 + 612 + SND_SOC_DAPM_SUPPLY("HP Power", RT298_SET_PIN_HPO, 613 + RT298_SET_PIN_SFT, 0, NULL, 0), 614 + 615 + /* Output Mixer */ 616 + SND_SOC_DAPM_MIXER("Front", RT298_SET_POWER(RT298_DAC_OUT1), 0, 1, 617 + rt298_front_mix, ARRAY_SIZE(rt298_front_mix)), 618 + SND_SOC_DAPM_PGA("Surround", RT298_SET_POWER(RT298_DAC_OUT2), 0, 1, 619 + NULL, 0), 620 + 621 + /* Output Pga */ 622 + SND_SOC_DAPM_SWITCH_E("SPO", SND_SOC_NOPM, 0, 0, 623 + &spo_enable_control, rt298_spk_event, 624 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 625 + SND_SOC_DAPM_SWITCH("HPO L", SND_SOC_NOPM, 0, 0, 626 + &hpol_enable_control), 627 + SND_SOC_DAPM_SWITCH("HPO R", SND_SOC_NOPM, 0, 0, 628 + &hpor_enable_control), 629 + 630 + /* Output Lines */ 631 + SND_SOC_DAPM_OUTPUT("SPOL"), 632 + SND_SOC_DAPM_OUTPUT("SPOR"), 633 + SND_SOC_DAPM_OUTPUT("HPO Pin"), 634 + SND_SOC_DAPM_OUTPUT("SPDIF"), 635 + }; 636 + 637 + static const struct snd_soc_dapm_route rt298_dapm_routes[] = { 638 + 639 + {"ADC 0", NULL, "MCLK MODE", is_mclk_mode}, 640 + {"ADC 1", NULL, "MCLK MODE", is_mclk_mode}, 641 + {"Front", NULL, "MCLK MODE", is_mclk_mode}, 642 + {"Surround", NULL, "MCLK MODE", is_mclk_mode}, 643 + 644 + {"HP Power", NULL, "LDO1"}, 645 + {"HP Power", NULL, "LDO2"}, 646 + {"HP Power", NULL, "LV"}, 647 + {"HP Power", NULL, "VREF1"}, 648 + {"HP Power", NULL, "BG_MBIAS"}, 649 + 650 + {"MIC1", NULL, "LDO1"}, 651 + {"MIC1", NULL, "LDO2"}, 652 + {"MIC1", NULL, "HV"}, 653 + {"MIC1", NULL, "LV"}, 654 + {"MIC1", NULL, "VREF"}, 655 + {"MIC1", NULL, "VREF1"}, 656 + {"MIC1", NULL, "BG_MBIAS"}, 657 + {"MIC1", NULL, "MIC1 Input Buffer"}, 658 + 659 + {"SPO", NULL, "LDO1"}, 660 + {"SPO", NULL, "LDO2"}, 661 + {"SPO", NULL, "HV"}, 662 + {"SPO", NULL, "LV"}, 663 + {"SPO", NULL, "VREF"}, 664 + {"SPO", NULL, "VREF1"}, 665 + {"SPO", NULL, "BG_MBIAS"}, 666 + 667 + {"DMIC1", NULL, "DMIC1 Pin"}, 668 + {"DMIC2", NULL, "DMIC2 Pin"}, 669 + {"DMIC1", NULL, "DMIC Receiver"}, 670 + {"DMIC2", NULL, "DMIC Receiver"}, 671 + 672 + {"RECMIX", "Beep Switch", "Beep"}, 673 + {"RECMIX", "Line1 Switch", "LINE1"}, 674 + {"RECMIX", "Mic1 Switch", "MIC1"}, 675 + 676 + {"ADC 0 Mux", "Dmic", "DMIC1"}, 677 + {"ADC 0 Mux", "RECMIX", "RECMIX"}, 678 + {"ADC 0 Mux", "Mic", "MIC1"}, 679 + {"ADC 1 Mux", "Dmic", "DMIC2"}, 680 + {"ADC 1 Mux", "RECMIX", "RECMIX"}, 681 + {"ADC 1 Mux", "Mic", "MIC1"}, 682 + 683 + {"ADC 0", NULL, "ADC 0 Mux"}, 684 + {"ADC 1", NULL, "ADC 1 Mux"}, 685 + 686 + {"AIF1TX", NULL, "ADC 0"}, 687 + {"AIF2TX", NULL, "ADC 1"}, 688 + 689 + {"DAC 0", NULL, "AIF1RX"}, 690 + {"DAC 1", NULL, "AIF2RX"}, 691 + 692 + {"Front", "DAC Switch", "DAC 0"}, 693 + {"Front", "RECMIX Switch", "RECMIX"}, 694 + 695 + {"Surround", NULL, "DAC 1"}, 696 + 697 + {"SPK Mux", "Front", "Front"}, 698 + {"SPK Mux", "Surround", "Surround"}, 699 + 700 + {"HPO Mux", "Front", "Front"}, 701 + {"HPO Mux", "Surround", "Surround"}, 702 + 703 + {"SPO", "Switch", "SPK Mux"}, 704 + {"HPO L", "Switch", "HPO Mux"}, 705 + {"HPO R", "Switch", "HPO Mux"}, 706 + {"HPO L", NULL, "HP Power"}, 707 + {"HPO R", NULL, "HP Power"}, 708 + 709 + {"SPOL", NULL, "SPO"}, 710 + {"SPOR", NULL, "SPO"}, 711 + {"HPO Pin", NULL, "HPO L"}, 712 + {"HPO Pin", NULL, "HPO R"}, 713 + }; 714 + 715 + static int rt298_hw_params(struct snd_pcm_substream *substream, 716 + struct snd_pcm_hw_params *params, 717 + struct snd_soc_dai *dai) 718 + { 719 + struct snd_soc_codec *codec = dai->codec; 720 + struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec); 721 + unsigned int val = 0; 722 + int d_len_code; 723 + 724 + switch (params_rate(params)) { 725 + /* bit 14 0:48K 1:44.1K */ 726 + case 44100: 727 + case 48000: 728 + break; 729 + default: 730 + dev_err(codec->dev, "Unsupported sample rate %d\n", 731 + params_rate(params)); 732 + return -EINVAL; 733 + } 734 + switch (rt298->sys_clk) { 735 + case 12288000: 736 + case 24576000: 737 + if (params_rate(params) != 48000) { 738 + dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n", 739 + params_rate(params), rt298->sys_clk); 740 + return -EINVAL; 741 + } 742 + break; 743 + case 11289600: 744 + case 22579200: 745 + if (params_rate(params) != 44100) { 746 + dev_err(codec->dev, "Sys_clk is not matched (%d %d)\n", 747 + params_rate(params), rt298->sys_clk); 748 + return -EINVAL; 749 + } 750 + break; 751 + } 752 + 753 + if (params_channels(params) <= 16) { 754 + /* bit 3:0 Number of Channel */ 755 + val |= (params_channels(params) - 1); 756 + } else { 757 + dev_err(codec->dev, "Unsupported channels %d\n", 758 + params_channels(params)); 759 + return -EINVAL; 760 + } 761 + 762 + d_len_code = 0; 763 + switch (params_width(params)) { 764 + /* bit 6:4 Bits per Sample */ 765 + case 16: 766 + d_len_code = 0; 767 + val |= (0x1 << 4); 768 + break; 769 + case 32: 770 + d_len_code = 2; 771 + val |= (0x4 << 4); 772 + break; 773 + case 20: 774 + d_len_code = 1; 775 + val |= (0x2 << 4); 776 + break; 777 + case 24: 778 + d_len_code = 2; 779 + val |= (0x3 << 4); 780 + break; 781 + case 8: 782 + d_len_code = 3; 783 + break; 784 + default: 785 + return -EINVAL; 786 + } 787 + 788 + snd_soc_update_bits(codec, 789 + RT298_I2S_CTRL1, 0x0018, d_len_code << 3); 790 + dev_dbg(codec->dev, "format val = 0x%x\n", val); 791 + 792 + snd_soc_update_bits(codec, RT298_DAC_FORMAT, 0x407f, val); 793 + snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x407f, val); 794 + 795 + return 0; 796 + } 797 + 798 + static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 799 + { 800 + struct snd_soc_codec *codec = dai->codec; 801 + 802 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 803 + case SND_SOC_DAIFMT_CBM_CFM: 804 + snd_soc_update_bits(codec, 805 + RT298_I2S_CTRL1, 0x800, 0x800); 806 + break; 807 + case SND_SOC_DAIFMT_CBS_CFS: 808 + snd_soc_update_bits(codec, 809 + RT298_I2S_CTRL1, 0x800, 0x0); 810 + break; 811 + default: 812 + return -EINVAL; 813 + } 814 + 815 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 816 + case SND_SOC_DAIFMT_I2S: 817 + snd_soc_update_bits(codec, 818 + RT298_I2S_CTRL1, 0x300, 0x0); 819 + break; 820 + case SND_SOC_DAIFMT_LEFT_J: 821 + snd_soc_update_bits(codec, 822 + RT298_I2S_CTRL1, 0x300, 0x1 << 8); 823 + break; 824 + case SND_SOC_DAIFMT_DSP_A: 825 + snd_soc_update_bits(codec, 826 + RT298_I2S_CTRL1, 0x300, 0x2 << 8); 827 + break; 828 + case SND_SOC_DAIFMT_DSP_B: 829 + snd_soc_update_bits(codec, 830 + RT298_I2S_CTRL1, 0x300, 0x3 << 8); 831 + break; 832 + default: 833 + return -EINVAL; 834 + } 835 + /* bit 15 Stream Type 0:PCM 1:Non-PCM */ 836 + snd_soc_update_bits(codec, RT298_DAC_FORMAT, 0x8000, 0); 837 + snd_soc_update_bits(codec, RT298_ADC_FORMAT, 0x8000, 0); 838 + 839 + return 0; 840 + } 841 + 842 + static int rt298_set_dai_sysclk(struct snd_soc_dai *dai, 843 + int clk_id, unsigned int freq, int dir) 844 + { 845 + struct snd_soc_codec *codec = dai->codec; 846 + struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec); 847 + 848 + dev_dbg(codec->dev, "%s freq=%d\n", __func__, freq); 849 + 850 + if (RT298_SCLK_S_MCLK == clk_id) { 851 + snd_soc_update_bits(codec, 852 + RT298_I2S_CTRL2, 0x0100, 0x0); 853 + snd_soc_update_bits(codec, 854 + RT298_PLL_CTRL1, 0x20, 0x20); 855 + } else { 856 + snd_soc_update_bits(codec, 857 + RT298_I2S_CTRL2, 0x0100, 0x0100); 858 + snd_soc_update_bits(codec, 859 + RT298_PLL_CTRL, 0x4, 0x4); 860 + snd_soc_update_bits(codec, 861 + RT298_PLL_CTRL1, 0x20, 0x0); 862 + } 863 + 864 + switch (freq) { 865 + case 19200000: 866 + if (RT298_SCLK_S_MCLK == clk_id) { 867 + dev_err(codec->dev, "Should not use MCLK\n"); 868 + return -EINVAL; 869 + } 870 + snd_soc_update_bits(codec, 871 + RT298_I2S_CTRL2, 0x40, 0x40); 872 + break; 873 + case 24000000: 874 + if (RT298_SCLK_S_MCLK == clk_id) { 875 + dev_err(codec->dev, "Should not use MCLK\n"); 876 + return -EINVAL; 877 + } 878 + snd_soc_update_bits(codec, 879 + RT298_I2S_CTRL2, 0x40, 0x0); 880 + break; 881 + case 12288000: 882 + case 11289600: 883 + snd_soc_update_bits(codec, 884 + RT298_I2S_CTRL2, 0x8, 0x0); 885 + snd_soc_update_bits(codec, 886 + RT298_CLK_DIV, 0xfc1e, 0x0004); 887 + break; 888 + case 24576000: 889 + case 22579200: 890 + snd_soc_update_bits(codec, 891 + RT298_I2S_CTRL2, 0x8, 0x8); 892 + snd_soc_update_bits(codec, 893 + RT298_CLK_DIV, 0xfc1e, 0x5406); 894 + break; 895 + default: 896 + dev_err(codec->dev, "Unsupported system clock\n"); 897 + return -EINVAL; 898 + } 899 + 900 + rt298->sys_clk = freq; 901 + rt298->clk_id = clk_id; 902 + 903 + return 0; 904 + } 905 + 906 + static int rt298_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) 907 + { 908 + struct snd_soc_codec *codec = dai->codec; 909 + 910 + dev_dbg(codec->dev, "%s ratio=%d\n", __func__, ratio); 911 + if (50 == ratio) 912 + snd_soc_update_bits(codec, 913 + RT298_I2S_CTRL1, 0x1000, 0x1000); 914 + else 915 + snd_soc_update_bits(codec, 916 + RT298_I2S_CTRL1, 0x1000, 0x0); 917 + 918 + 919 + return 0; 920 + } 921 + 922 + static int rt298_set_bias_level(struct snd_soc_codec *codec, 923 + enum snd_soc_bias_level level) 924 + { 925 + switch (level) { 926 + case SND_SOC_BIAS_PREPARE: 927 + if (SND_SOC_BIAS_STANDBY == 928 + snd_soc_codec_get_bias_level(codec)) { 929 + snd_soc_write(codec, 930 + RT298_SET_AUDIO_POWER, AC_PWRST_D0); 931 + snd_soc_update_bits(codec, 0x0d, 0x200, 0x200); 932 + snd_soc_update_bits(codec, 0x52, 0x80, 0x0); 933 + mdelay(20); 934 + snd_soc_update_bits(codec, 0x0d, 0x200, 0x0); 935 + snd_soc_update_bits(codec, 0x52, 0x80, 0x80); 936 + } 937 + break; 938 + 939 + case SND_SOC_BIAS_ON: 940 + mdelay(30); 941 + snd_soc_update_bits(codec, 942 + RT298_CBJ_CTRL1, 0x0400, 0x0400); 943 + 944 + break; 945 + 946 + case SND_SOC_BIAS_STANDBY: 947 + snd_soc_write(codec, 948 + RT298_SET_AUDIO_POWER, AC_PWRST_D3); 949 + snd_soc_update_bits(codec, 950 + RT298_CBJ_CTRL1, 0x0400, 0x0000); 951 + break; 952 + 953 + default: 954 + break; 955 + } 956 + 957 + return 0; 958 + } 959 + 960 + static irqreturn_t rt298_irq(int irq, void *data) 961 + { 962 + struct rt298_priv *rt298 = data; 963 + bool hp = false; 964 + bool mic = false; 965 + int ret, status = 0; 966 + 967 + ret = rt298_jack_detect(rt298, &hp, &mic); 968 + 969 + /* Clear IRQ */ 970 + regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x1, 0x1); 971 + 972 + if (ret == 0) { 973 + if (hp == true) 974 + status |= SND_JACK_HEADPHONE; 975 + 976 + if (mic == true) 977 + status |= SND_JACK_MICROPHONE; 978 + 979 + snd_soc_jack_report(rt298->jack, status, 980 + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); 981 + 982 + pm_wakeup_event(&rt298->i2c->dev, 300); 983 + } 984 + 985 + return IRQ_HANDLED; 986 + } 987 + 988 + static int rt298_probe(struct snd_soc_codec *codec) 989 + { 990 + struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec); 991 + 992 + rt298->codec = codec; 993 + 994 + if (rt298->i2c->irq) { 995 + regmap_update_bits(rt298->regmap, 996 + RT298_IRQ_CTRL, 0x2, 0x2); 997 + 998 + INIT_DELAYED_WORK(&rt298->jack_detect_work, 999 + rt298_jack_detect_work); 1000 + schedule_delayed_work(&rt298->jack_detect_work, 1001 + msecs_to_jiffies(1250)); 1002 + } 1003 + 1004 + return 0; 1005 + } 1006 + 1007 + static int rt298_remove(struct snd_soc_codec *codec) 1008 + { 1009 + struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec); 1010 + 1011 + cancel_delayed_work_sync(&rt298->jack_detect_work); 1012 + 1013 + return 0; 1014 + } 1015 + 1016 + #ifdef CONFIG_PM 1017 + static int rt298_suspend(struct snd_soc_codec *codec) 1018 + { 1019 + struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec); 1020 + 1021 + rt298->is_hp_in = -1; 1022 + regcache_cache_only(rt298->regmap, true); 1023 + regcache_mark_dirty(rt298->regmap); 1024 + 1025 + return 0; 1026 + } 1027 + 1028 + static int rt298_resume(struct snd_soc_codec *codec) 1029 + { 1030 + struct rt298_priv *rt298 = snd_soc_codec_get_drvdata(codec); 1031 + 1032 + regcache_cache_only(rt298->regmap, false); 1033 + rt298_index_sync(codec); 1034 + regcache_sync(rt298->regmap); 1035 + 1036 + return 0; 1037 + } 1038 + #else 1039 + #define rt298_suspend NULL 1040 + #define rt298_resume NULL 1041 + #endif 1042 + 1043 + #define RT298_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 1044 + #define RT298_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1045 + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) 1046 + 1047 + static const struct snd_soc_dai_ops rt298_aif_dai_ops = { 1048 + .hw_params = rt298_hw_params, 1049 + .set_fmt = rt298_set_dai_fmt, 1050 + .set_sysclk = rt298_set_dai_sysclk, 1051 + .set_bclk_ratio = rt298_set_bclk_ratio, 1052 + }; 1053 + 1054 + static struct snd_soc_dai_driver rt298_dai[] = { 1055 + { 1056 + .name = "rt298-aif1", 1057 + .id = RT298_AIF1, 1058 + .playback = { 1059 + .stream_name = "AIF1 Playback", 1060 + .channels_min = 1, 1061 + .channels_max = 2, 1062 + .rates = RT298_STEREO_RATES, 1063 + .formats = RT298_FORMATS, 1064 + }, 1065 + .capture = { 1066 + .stream_name = "AIF1 Capture", 1067 + .channels_min = 1, 1068 + .channels_max = 2, 1069 + .rates = RT298_STEREO_RATES, 1070 + .formats = RT298_FORMATS, 1071 + }, 1072 + .ops = &rt298_aif_dai_ops, 1073 + .symmetric_rates = 1, 1074 + }, 1075 + { 1076 + .name = "rt298-aif2", 1077 + .id = RT298_AIF2, 1078 + .playback = { 1079 + .stream_name = "AIF2 Playback", 1080 + .channels_min = 1, 1081 + .channels_max = 2, 1082 + .rates = RT298_STEREO_RATES, 1083 + .formats = RT298_FORMATS, 1084 + }, 1085 + .capture = { 1086 + .stream_name = "AIF2 Capture", 1087 + .channels_min = 1, 1088 + .channels_max = 2, 1089 + .rates = RT298_STEREO_RATES, 1090 + .formats = RT298_FORMATS, 1091 + }, 1092 + .ops = &rt298_aif_dai_ops, 1093 + .symmetric_rates = 1, 1094 + }, 1095 + 1096 + }; 1097 + 1098 + static struct snd_soc_codec_driver soc_codec_dev_rt298 = { 1099 + .probe = rt298_probe, 1100 + .remove = rt298_remove, 1101 + .suspend = rt298_suspend, 1102 + .resume = rt298_resume, 1103 + .set_bias_level = rt298_set_bias_level, 1104 + .idle_bias_off = true, 1105 + .controls = rt298_snd_controls, 1106 + .num_controls = ARRAY_SIZE(rt298_snd_controls), 1107 + .dapm_widgets = rt298_dapm_widgets, 1108 + .num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets), 1109 + .dapm_routes = rt298_dapm_routes, 1110 + .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), 1111 + }; 1112 + 1113 + static const struct regmap_config rt298_regmap = { 1114 + .reg_bits = 32, 1115 + .val_bits = 32, 1116 + .max_register = 0x02370100, 1117 + .volatile_reg = rt298_volatile_register, 1118 + .readable_reg = rt298_readable_register, 1119 + .reg_write = rl6347a_hw_write, 1120 + .reg_read = rl6347a_hw_read, 1121 + .cache_type = REGCACHE_RBTREE, 1122 + .reg_defaults = rt298_reg, 1123 + .num_reg_defaults = ARRAY_SIZE(rt298_reg), 1124 + }; 1125 + 1126 + static const struct i2c_device_id rt298_i2c_id[] = { 1127 + {"rt298", 0}, 1128 + {} 1129 + }; 1130 + MODULE_DEVICE_TABLE(i2c, rt298_i2c_id); 1131 + 1132 + static const struct acpi_device_id rt298_acpi_match[] = { 1133 + { "INT343A", 0 }, 1134 + {}, 1135 + }; 1136 + MODULE_DEVICE_TABLE(acpi, rt298_acpi_match); 1137 + 1138 + static int rt298_i2c_probe(struct i2c_client *i2c, 1139 + const struct i2c_device_id *id) 1140 + { 1141 + struct rt298_platform_data *pdata = dev_get_platdata(&i2c->dev); 1142 + struct rt298_priv *rt298; 1143 + struct device *dev = &i2c->dev; 1144 + const struct acpi_device_id *acpiid; 1145 + int i, ret; 1146 + 1147 + pr_info("%s\n", __func__); 1148 + 1149 + rt298 = devm_kzalloc(&i2c->dev, sizeof(*rt298), 1150 + GFP_KERNEL); 1151 + if (NULL == rt298) 1152 + return -ENOMEM; 1153 + 1154 + rt298->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt298_regmap); 1155 + if (IS_ERR(rt298->regmap)) { 1156 + ret = PTR_ERR(rt298->regmap); 1157 + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 1158 + ret); 1159 + return ret; 1160 + } 1161 + 1162 + regmap_read(rt298->regmap, 1163 + RT298_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret); 1164 + if (ret != RT298_VENDOR_ID) { 1165 + dev_err(&i2c->dev, 1166 + "Device with ID register %#x is not rt298\n", ret); 1167 + return -ENODEV; 1168 + } 1169 + 1170 + rt298->index_cache = rt298_index_def; 1171 + rt298->index_cache_size = INDEX_CACHE_SIZE; 1172 + rt298->i2c = i2c; 1173 + i2c_set_clientdata(i2c, rt298); 1174 + 1175 + /* restore codec default */ 1176 + for (i = 0; i < INDEX_CACHE_SIZE; i++) 1177 + regmap_write(rt298->regmap, rt298->index_cache[i].reg, 1178 + rt298->index_cache[i].def); 1179 + for (i = 0; i < ARRAY_SIZE(rt298_reg); i++) 1180 + regmap_write(rt298->regmap, rt298_reg[i].reg, 1181 + rt298_reg[i].def); 1182 + 1183 + if (pdata) 1184 + rt298->pdata = *pdata; 1185 + 1186 + /* enable jack combo mode on supported devices */ 1187 + acpiid = acpi_match_device(dev->driver->acpi_match_table, dev); 1188 + if (acpiid) { 1189 + rt298->pdata = *(struct rt298_platform_data *) 1190 + acpiid->driver_data; 1191 + } 1192 + 1193 + /* VREF Charging */ 1194 + regmap_update_bits(rt298->regmap, 0x04, 0x80, 0x80); 1195 + regmap_update_bits(rt298->regmap, 0x1b, 0x860, 0x860); 1196 + /* Vref2 */ 1197 + regmap_update_bits(rt298->regmap, 0x08, 0x20, 0x20); 1198 + 1199 + regmap_write(rt298->regmap, RT298_SET_AUDIO_POWER, AC_PWRST_D3); 1200 + 1201 + for (i = 0; i < RT298_POWER_REG_LEN; i++) 1202 + regmap_write(rt298->regmap, 1203 + RT298_SET_POWER(rt298_support_power_controls[i]), 1204 + AC_PWRST_D1); 1205 + 1206 + if (!rt298->pdata.cbj_en) { 1207 + regmap_write(rt298->regmap, RT298_CBJ_CTRL2, 0x0000); 1208 + regmap_write(rt298->regmap, RT298_MIC1_DET_CTRL, 0x0816); 1209 + regmap_update_bits(rt298->regmap, 1210 + RT298_CBJ_CTRL1, 0xf000, 0xb000); 1211 + } else { 1212 + regmap_update_bits(rt298->regmap, 1213 + RT298_CBJ_CTRL1, 0xf000, 0x5000); 1214 + } 1215 + 1216 + mdelay(10); 1217 + 1218 + if (!rt298->pdata.gpio2_en) 1219 + regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0x4000); 1220 + else 1221 + regmap_write(rt298->regmap, RT298_SET_DMIC2_DEFAULT, 0); 1222 + 1223 + mdelay(10); 1224 + 1225 + regmap_write(rt298->regmap, RT298_MISC_CTRL1, 0x0000); 1226 + regmap_update_bits(rt298->regmap, 1227 + RT298_WIND_FILTER_CTRL, 0x0082, 0x0082); 1228 + regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x2); 1229 + rt298->is_hp_in = -1; 1230 + 1231 + if (rt298->i2c->irq) { 1232 + ret = request_threaded_irq(rt298->i2c->irq, NULL, rt298_irq, 1233 + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt298", rt298); 1234 + if (ret != 0) { 1235 + dev_err(&i2c->dev, 1236 + "Failed to reguest IRQ: %d\n", ret); 1237 + return ret; 1238 + } 1239 + } 1240 + 1241 + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt298, 1242 + rt298_dai, ARRAY_SIZE(rt298_dai)); 1243 + 1244 + return ret; 1245 + } 1246 + 1247 + static int rt298_i2c_remove(struct i2c_client *i2c) 1248 + { 1249 + struct rt298_priv *rt298 = i2c_get_clientdata(i2c); 1250 + 1251 + if (i2c->irq) 1252 + free_irq(i2c->irq, rt298); 1253 + snd_soc_unregister_codec(&i2c->dev); 1254 + 1255 + return 0; 1256 + } 1257 + 1258 + 1259 + static struct i2c_driver rt298_i2c_driver = { 1260 + .driver = { 1261 + .name = "rt298", 1262 + .owner = THIS_MODULE, 1263 + .acpi_match_table = ACPI_PTR(rt298_acpi_match), 1264 + }, 1265 + .probe = rt298_i2c_probe, 1266 + .remove = rt298_i2c_remove, 1267 + .id_table = rt298_i2c_id, 1268 + }; 1269 + 1270 + module_i2c_driver(rt298_i2c_driver); 1271 + 1272 + MODULE_DESCRIPTION("ASoC RT298 driver"); 1273 + MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>"); 1274 + MODULE_LICENSE("GPL");
+206
sound/soc/codecs/rt298.h
··· 1 + /* 2 + * rt298.h -- RT298 ALSA SoC audio driver 3 + * 4 + * Copyright 2011 Realtek Microelectronics 5 + * Author: Johnny Hsu <johnnyhsu@realtek.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #ifndef __RT298_H__ 13 + #define __RT298_H__ 14 + 15 + #define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D) 16 + 17 + #define RT298_AUDIO_FUNCTION_GROUP 0x01 18 + #define RT298_DAC_OUT1 0x02 19 + #define RT298_DAC_OUT2 0x03 20 + #define RT298_DIG_CVT 0x06 21 + #define RT298_ADC_IN1 0x09 22 + #define RT298_ADC_IN2 0x08 23 + #define RT298_MIXER_IN 0x0b 24 + #define RT298_MIXER_OUT1 0x0c 25 + #define RT298_MIXER_OUT2 0x0d 26 + #define RT298_DMIC1 0x12 27 + #define RT298_DMIC2 0x13 28 + #define RT298_SPK_OUT 0x14 29 + #define RT298_MIC1 0x18 30 + #define RT298_LINE1 0x1a 31 + #define RT298_BEEP 0x1d 32 + #define RT298_SPDIF 0x1e 33 + #define RT298_VENDOR_REGISTERS 0x20 34 + #define RT298_HP_OUT 0x21 35 + #define RT298_MIXER_IN1 0x22 36 + #define RT298_MIXER_IN2 0x23 37 + 38 + #define RT298_SET_PIN_SFT 6 39 + #define RT298_SET_PIN_ENABLE 0x40 40 + #define RT298_SET_PIN_DISABLE 0 41 + #define RT298_SET_EAPD_HIGH 0x2 42 + #define RT298_SET_EAPD_LOW 0 43 + 44 + #define RT298_MUTE_SFT 7 45 + 46 + /* Verb commands */ 47 + #define RT298_GET_PARAM(NID, PARAM) VERB_CMD(AC_VERB_PARAMETERS, NID, PARAM) 48 + #define RT298_SET_POWER(NID) VERB_CMD(AC_VERB_SET_POWER_STATE, NID, 0) 49 + #define RT298_SET_AUDIO_POWER RT298_SET_POWER(RT298_AUDIO_FUNCTION_GROUP) 50 + #define RT298_SET_HPO_POWER RT298_SET_POWER(RT298_HP_OUT) 51 + #define RT298_SET_SPK_POWER RT298_SET_POWER(RT298_SPK_OUT) 52 + #define RT298_SET_DMIC1_POWER RT298_SET_POWER(RT298_DMIC1) 53 + #define RT298_SPK_MUX\ 54 + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT298_SPK_OUT, 0) 55 + #define RT298_HPO_MUX\ 56 + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT298_HP_OUT, 0) 57 + #define RT298_ADC0_MUX\ 58 + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT298_MIXER_IN1, 0) 59 + #define RT298_ADC1_MUX\ 60 + VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT298_MIXER_IN2, 0) 61 + #define RT298_SET_MIC1\ 62 + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT298_MIC1, 0) 63 + #define RT298_SET_PIN_HPO\ 64 + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT298_HP_OUT, 0) 65 + #define RT298_SET_PIN_SPK\ 66 + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT298_SPK_OUT, 0) 67 + #define RT298_SET_PIN_DMIC1\ 68 + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT298_DMIC1, 0) 69 + #define RT298_SET_PIN_SPDIF\ 70 + VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT298_SPDIF, 0) 71 + #define RT298_SET_PIN_DIG_CVT\ 72 + VERB_CMD(AC_VERB_SET_DIGI_CONVERT_1, RT298_DIG_CVT, 0) 73 + #define RT298_SPK_EAPD\ 74 + VERB_CMD(AC_VERB_SET_EAPD_BTLENABLE, RT298_SPK_OUT, 0) 75 + #define RT298_SET_AMP_GAIN_HPO\ 76 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_HP_OUT, 0) 77 + #define RT298_SET_AMP_GAIN_ADC_IN1\ 78 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_ADC_IN1, 0) 79 + #define RT298_SET_AMP_GAIN_ADC_IN2\ 80 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_ADC_IN2, 0) 81 + #define RT298_GET_HP_SENSE\ 82 + VERB_CMD(AC_VERB_GET_PIN_SENSE, RT298_HP_OUT, 0) 83 + #define RT298_GET_MIC1_SENSE\ 84 + VERB_CMD(AC_VERB_GET_PIN_SENSE, RT298_MIC1, 0) 85 + #define RT298_SET_DMIC2_DEFAULT\ 86 + VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT298_DMIC2, 0) 87 + #define RT298_SET_SPDIF_DEFAULT\ 88 + VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT298_SPDIF, 0) 89 + #define RT298_DACL_GAIN\ 90 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_DAC_OUT1, 0xa000) 91 + #define RT298_DACR_GAIN\ 92 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_DAC_OUT1, 0x9000) 93 + #define RT298_ADCL_GAIN\ 94 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_ADC_IN1, 0x6000) 95 + #define RT298_ADCR_GAIN\ 96 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_ADC_IN1, 0x5000) 97 + #define RT298_MIC_GAIN\ 98 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_MIC1, 0x7000) 99 + #define RT298_SPOL_GAIN\ 100 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_SPK_OUT, 0xa000) 101 + #define RT298_SPOR_GAIN\ 102 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_SPK_OUT, 0x9000) 103 + #define RT298_HPOL_GAIN\ 104 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_HP_OUT, 0xa000) 105 + #define RT298_HPOR_GAIN\ 106 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_HP_OUT, 0x9000) 107 + #define RT298_F_DAC_SWITCH\ 108 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_MIXER_OUT1, 0x7000) 109 + #define RT298_F_RECMIX_SWITCH\ 110 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_MIXER_OUT1, 0x7100) 111 + #define RT298_REC_MIC_SWITCH\ 112 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_MIXER_IN, 0x7000) 113 + #define RT298_REC_I2S_SWITCH\ 114 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_MIXER_IN, 0x7100) 115 + #define RT298_REC_LINE_SWITCH\ 116 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_MIXER_IN, 0x7200) 117 + #define RT298_REC_BEEP_SWITCH\ 118 + VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT298_MIXER_IN, 0x7300) 119 + #define RT298_DAC_FORMAT\ 120 + VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT298_DAC_OUT1, 0) 121 + #define RT298_ADC_FORMAT\ 122 + VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT298_ADC_IN1, 0) 123 + #define RT298_COEF_INDEX\ 124 + VERB_CMD(AC_VERB_SET_COEF_INDEX, RT298_VENDOR_REGISTERS, 0) 125 + #define RT298_PROC_COEF\ 126 + VERB_CMD(AC_VERB_SET_PROC_COEF, RT298_VENDOR_REGISTERS, 0) 127 + 128 + /* Index registers */ 129 + #define RT298_A_BIAS_CTRL1 0x01 130 + #define RT298_A_BIAS_CTRL2 0x02 131 + #define RT298_POWER_CTRL1 0x03 132 + #define RT298_A_BIAS_CTRL3 0x04 133 + #define RT298_POWER_CTRL2 0x08 134 + #define RT298_I2S_CTRL1 0x09 135 + #define RT298_I2S_CTRL2 0x0a 136 + #define RT298_CLK_DIV 0x0b 137 + #define RT298_DC_GAIN 0x0d 138 + #define RT298_POWER_CTRL3 0x0f 139 + #define RT298_MIC1_DET_CTRL 0x19 140 + #define RT298_MISC_CTRL1 0x20 141 + #define RT298_IRQ_CTRL 0x33 142 + #define RT298_WIND_FILTER_CTRL 0x46 143 + #define RT298_PLL_CTRL1 0x49 144 + #define RT298_CBJ_CTRL1 0x4f 145 + #define RT298_CBJ_CTRL2 0x50 146 + #define RT298_PLL_CTRL 0x63 147 + #define RT298_DEPOP_CTRL1 0x66 148 + #define RT298_DEPOP_CTRL2 0x67 149 + #define RT298_DEPOP_CTRL3 0x68 150 + #define RT298_DEPOP_CTRL4 0x69 151 + 152 + /* SPDIF (0x06) */ 153 + #define RT298_SPDIF_SEL_SFT 0 154 + #define RT298_SPDIF_SEL_PCM0 0 155 + #define RT298_SPDIF_SEL_PCM1 1 156 + #define RT298_SPDIF_SEL_SPOUT 2 157 + #define RT298_SPDIF_SEL_PP 3 158 + 159 + /* RECMIX (0x0b) */ 160 + #define RT298_M_REC_BEEP_SFT 0 161 + #define RT298_M_REC_LINE1_SFT 1 162 + #define RT298_M_REC_MIC1_SFT 2 163 + #define RT298_M_REC_I2S_SFT 3 164 + 165 + /* Front (0x0c) */ 166 + #define RT298_M_FRONT_DAC_SFT 0 167 + #define RT298_M_FRONT_REC_SFT 1 168 + 169 + /* SPK-OUT (0x14) */ 170 + #define RT298_M_SPK_MUX_SFT 14 171 + #define RT298_SPK_SEL_MASK 0x1 172 + #define RT298_SPK_SEL_SFT 0 173 + #define RT298_SPK_SEL_F 0 174 + #define RT298_SPK_SEL_S 1 175 + 176 + /* HP-OUT (0x21) */ 177 + #define RT298_M_HP_MUX_SFT 14 178 + #define RT298_HP_SEL_MASK 0x1 179 + #define RT298_HP_SEL_SFT 0 180 + #define RT298_HP_SEL_F 0 181 + #define RT298_HP_SEL_S 1 182 + 183 + /* ADC (0x22) (0x23) */ 184 + #define RT298_ADC_SEL_MASK 0x7 185 + #define RT298_ADC_SEL_SFT 0 186 + #define RT298_ADC_SEL_SURR 0 187 + #define RT298_ADC_SEL_FRONT 1 188 + #define RT298_ADC_SEL_DMIC 2 189 + #define RT298_ADC_SEL_BEEP 4 190 + #define RT298_ADC_SEL_LINE1 5 191 + #define RT298_ADC_SEL_I2S 6 192 + #define RT298_ADC_SEL_MIC1 7 193 + 194 + #define RT298_SCLK_S_MCLK 0 195 + #define RT298_SCLK_S_PLL 1 196 + 197 + enum { 198 + RT298_AIF1, 199 + RT298_AIF2, 200 + RT298_AIFS, 201 + }; 202 + 203 + int rt298_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); 204 + 205 + #endif /* __RT298_H__ */ 206 +