1 /* 2 * File: sound/soc/codecs/ssm2602.c 3 * Author: Cliff Cai <Cliff.Cai@analog.com> 4 * 5 * Created: Tue June 06 2008 6 * Description: Driver for ssm2602 sound chip 7 * 8 * Modified: 9 * Copyright 2008 Analog Devices Inc. 10 * 11 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of the GNU General Public License as published by 15 * the Free Software Foundation; either version 2 of the License, or 16 * (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 * GNU General Public License for more details. 22 * 23 * You should have received a copy of the GNU General Public License 24 * along with this program; if not, see the file COPYING, or write 25 * to the Free Software Foundation, Inc., 26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 */ 28 29 #include <linux/module.h> 30 #include <linux/moduleparam.h> 31 #include <linux/init.h> 32 #include <linux/delay.h> 33 #include <linux/pm.h> 34 #include <linux/i2c.h> 35 #include <linux/spi/spi.h> 36 #include <linux/regmap.h> 37 #include <linux/slab.h> 38 #include <sound/core.h> 39 #include <sound/pcm.h> 40 #include <sound/pcm_params.h> 41 #include <sound/soc.h> 42 #include <sound/initval.h> 43 #include <sound/tlv.h> 44 45 #include "ssm2602.h" 46 47 enum ssm2602_type { 48 SSM2602, 49 SSM2604, 50 }; 51 52 /* codec private data */ 53 struct ssm2602_priv { 54 unsigned int sysclk; 55 struct snd_pcm_hw_constraint_list *sysclk_constraints; 56 struct snd_pcm_substream *master_substream; 57 struct snd_pcm_substream *slave_substream; 58 59 struct regmap *regmap; 60 61 enum ssm2602_type type; 62 unsigned int clk_out_pwr; 63 }; 64 65 /* 66 * ssm2602 register cache 67 * We can't read the ssm2602 register space when we are 68 * using 2 wire for device control, so we cache them instead. 69 * There is no point in caching the reset register 70 */ 71 static const u16 ssm2602_reg[SSM2602_CACHEREGNUM] = { 72 0x0097, 0x0097, 0x0079, 0x0079, 73 0x000a, 0x0008, 0x009f, 0x000a, 74 0x0000, 0x0000 75 }; 76 77 78 /*Appending several "None"s just for OSS mixer use*/ 79 static const char *ssm2602_input_select[] = { 80 "Line", "Mic", "None", "None", "None", 81 "None", "None", "None", 82 }; 83 84 static const char *ssm2602_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 85 86 static const struct soc_enum ssm2602_enum[] = { 87 SOC_ENUM_SINGLE(SSM2602_APANA, 2, 2, ssm2602_input_select), 88 SOC_ENUM_SINGLE(SSM2602_APDIGI, 1, 4, ssm2602_deemph), 89 }; 90 91 static const unsigned int ssm260x_outmix_tlv[] = { 92 TLV_DB_RANGE_HEAD(2), 93 0, 47, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), 94 48, 127, TLV_DB_SCALE_ITEM(-7400, 100, 0), 95 }; 96 97 static const DECLARE_TLV_DB_SCALE(ssm260x_inpga_tlv, -3450, 150, 0); 98 static const DECLARE_TLV_DB_SCALE(ssm260x_sidetone_tlv, -1500, 300, 0); 99 100 static const struct snd_kcontrol_new ssm260x_snd_controls[] = { 101 SOC_DOUBLE_R_TLV("Capture Volume", SSM2602_LINVOL, SSM2602_RINVOL, 0, 45, 0, 102 ssm260x_inpga_tlv), 103 SOC_DOUBLE_R("Capture Switch", SSM2602_LINVOL, SSM2602_RINVOL, 7, 1, 1), 104 105 SOC_SINGLE("ADC High Pass Filter Switch", SSM2602_APDIGI, 0, 1, 1), 106 SOC_SINGLE("Store DC Offset Switch", SSM2602_APDIGI, 4, 1, 0), 107 108 SOC_ENUM("Playback De-emphasis", ssm2602_enum[1]), 109 }; 110 111 static const struct snd_kcontrol_new ssm2602_snd_controls[] = { 112 SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2602_LOUT1V, SSM2602_ROUT1V, 113 0, 127, 0, ssm260x_outmix_tlv), 114 SOC_DOUBLE_R("Master Playback ZC Switch", SSM2602_LOUT1V, SSM2602_ROUT1V, 115 7, 1, 0), 116 SOC_SINGLE_TLV("Sidetone Playback Volume", SSM2602_APANA, 6, 3, 1, 117 ssm260x_sidetone_tlv), 118 119 SOC_SINGLE("Mic Boost (+20dB)", SSM2602_APANA, 0, 1, 0), 120 SOC_SINGLE("Mic Boost2 (+20dB)", SSM2602_APANA, 8, 1, 0), 121 SOC_SINGLE("Mic Switch", SSM2602_APANA, 1, 1, 1), 122 }; 123 124 /* Output Mixer */ 125 static const struct snd_kcontrol_new ssm260x_output_mixer_controls[] = { 126 SOC_DAPM_SINGLE("Line Bypass Switch", SSM2602_APANA, 3, 1, 0), 127 SOC_DAPM_SINGLE("HiFi Playback Switch", SSM2602_APANA, 4, 1, 0), 128 SOC_DAPM_SINGLE("Mic Sidetone Switch", SSM2602_APANA, 5, 1, 0), 129 }; 130 131 /* Input mux */ 132 static const struct snd_kcontrol_new ssm2602_input_mux_controls = 133 SOC_DAPM_ENUM("Input Select", ssm2602_enum[0]); 134 135 static const struct snd_soc_dapm_widget ssm260x_dapm_widgets[] = { 136 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SSM2602_PWR, 3, 1), 137 SND_SOC_DAPM_ADC("ADC", "HiFi Capture", SSM2602_PWR, 2, 1), 138 SND_SOC_DAPM_PGA("Line Input", SSM2602_PWR, 0, 1, NULL, 0), 139 140 SND_SOC_DAPM_SUPPLY("Digital Core Power", SSM2602_ACTIVE, 0, 0, NULL, 0), 141 142 SND_SOC_DAPM_OUTPUT("LOUT"), 143 SND_SOC_DAPM_OUTPUT("ROUT"), 144 SND_SOC_DAPM_INPUT("RLINEIN"), 145 SND_SOC_DAPM_INPUT("LLINEIN"), 146 }; 147 148 static const struct snd_soc_dapm_widget ssm2602_dapm_widgets[] = { 149 SND_SOC_DAPM_MIXER("Output Mixer", SSM2602_PWR, 4, 1, 150 ssm260x_output_mixer_controls, 151 ARRAY_SIZE(ssm260x_output_mixer_controls)), 152 153 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &ssm2602_input_mux_controls), 154 SND_SOC_DAPM_MICBIAS("Mic Bias", SSM2602_PWR, 1, 1), 155 156 SND_SOC_DAPM_OUTPUT("LHPOUT"), 157 SND_SOC_DAPM_OUTPUT("RHPOUT"), 158 SND_SOC_DAPM_INPUT("MICIN"), 159 }; 160 161 static const struct snd_soc_dapm_widget ssm2604_dapm_widgets[] = { 162 SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0, 163 ssm260x_output_mixer_controls, 164 ARRAY_SIZE(ssm260x_output_mixer_controls) - 1), /* Last element is the mic */ 165 }; 166 167 static const struct snd_soc_dapm_route ssm260x_routes[] = { 168 {"DAC", NULL, "Digital Core Power"}, 169 {"ADC", NULL, "Digital Core Power"}, 170 171 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 172 {"Output Mixer", "HiFi Playback Switch", "DAC"}, 173 174 {"ROUT", NULL, "Output Mixer"}, 175 {"LOUT", NULL, "Output Mixer"}, 176 177 {"Line Input", NULL, "LLINEIN"}, 178 {"Line Input", NULL, "RLINEIN"}, 179 }; 180 181 static const struct snd_soc_dapm_route ssm2602_routes[] = { 182 {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"}, 183 184 {"RHPOUT", NULL, "Output Mixer"}, 185 {"LHPOUT", NULL, "Output Mixer"}, 186 187 {"Input Mux", "Line", "Line Input"}, 188 {"Input Mux", "Mic", "Mic Bias"}, 189 {"ADC", NULL, "Input Mux"}, 190 191 {"Mic Bias", NULL, "MICIN"}, 192 }; 193 194 static const struct snd_soc_dapm_route ssm2604_routes[] = { 195 {"ADC", NULL, "Line Input"}, 196 }; 197 198 static const unsigned int ssm2602_rates_12288000[] = { 199 8000, 32000, 48000, 96000, 200 }; 201 202 static struct snd_pcm_hw_constraint_list ssm2602_constraints_12288000 = { 203 .list = ssm2602_rates_12288000, 204 .count = ARRAY_SIZE(ssm2602_rates_12288000), 205 }; 206 207 static const unsigned int ssm2602_rates_11289600[] = { 208 8000, 44100, 88200, 209 }; 210 211 static struct snd_pcm_hw_constraint_list ssm2602_constraints_11289600 = { 212 .list = ssm2602_rates_11289600, 213 .count = ARRAY_SIZE(ssm2602_rates_11289600), 214 }; 215 216 struct ssm2602_coeff { 217 u32 mclk; 218 u32 rate; 219 u8 srate; 220 }; 221 222 #define SSM2602_COEFF_SRATE(sr, bosr, usb) (((sr) << 2) | ((bosr) << 1) | (usb)) 223 224 /* codec mclk clock coefficients */ 225 static const struct ssm2602_coeff ssm2602_coeff_table[] = { 226 /* 48k */ 227 {12288000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x0)}, 228 {18432000, 48000, SSM2602_COEFF_SRATE(0x0, 0x1, 0x0)}, 229 {12000000, 48000, SSM2602_COEFF_SRATE(0x0, 0x0, 0x1)}, 230 231 /* 32k */ 232 {12288000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x0)}, 233 {18432000, 32000, SSM2602_COEFF_SRATE(0x6, 0x1, 0x0)}, 234 {12000000, 32000, SSM2602_COEFF_SRATE(0x6, 0x0, 0x1)}, 235 236 /* 8k */ 237 {12288000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x0)}, 238 {18432000, 8000, SSM2602_COEFF_SRATE(0x3, 0x1, 0x0)}, 239 {11289600, 8000, SSM2602_COEFF_SRATE(0xb, 0x0, 0x0)}, 240 {16934400, 8000, SSM2602_COEFF_SRATE(0xb, 0x1, 0x0)}, 241 {12000000, 8000, SSM2602_COEFF_SRATE(0x3, 0x0, 0x1)}, 242 243 /* 96k */ 244 {12288000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x0)}, 245 {18432000, 96000, SSM2602_COEFF_SRATE(0x7, 0x1, 0x0)}, 246 {12000000, 96000, SSM2602_COEFF_SRATE(0x7, 0x0, 0x1)}, 247 248 /* 44.1k */ 249 {11289600, 44100, SSM2602_COEFF_SRATE(0x8, 0x0, 0x0)}, 250 {16934400, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x0)}, 251 {12000000, 44100, SSM2602_COEFF_SRATE(0x8, 0x1, 0x1)}, 252 253 /* 88.2k */ 254 {11289600, 88200, SSM2602_COEFF_SRATE(0xf, 0x0, 0x0)}, 255 {16934400, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x0)}, 256 {12000000, 88200, SSM2602_COEFF_SRATE(0xf, 0x1, 0x1)}, 257 }; 258 259 static inline int ssm2602_get_coeff(int mclk, int rate) 260 { 261 int i; 262 263 for (i = 0; i < ARRAY_SIZE(ssm2602_coeff_table); i++) { 264 if (ssm2602_coeff_table[i].rate == rate && 265 ssm2602_coeff_table[i].mclk == mclk) 266 return ssm2602_coeff_table[i].srate; 267 } 268 return -EINVAL; 269 } 270 271 static int ssm2602_hw_params(struct snd_pcm_substream *substream, 272 struct snd_pcm_hw_params *params, 273 struct snd_soc_dai *dai) 274 { 275 struct snd_soc_codec *codec = dai->codec; 276 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 277 int srate = ssm2602_get_coeff(ssm2602->sysclk, params_rate(params)); 278 unsigned int iface; 279 280 if (substream == ssm2602->slave_substream) { 281 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n"); 282 return 0; 283 } 284 285 if (srate < 0) 286 return srate; 287 288 regmap_write(ssm2602->regmap, SSM2602_SRATE, srate); 289 290 /* bit size */ 291 switch (params_format(params)) { 292 case SNDRV_PCM_FORMAT_S16_LE: 293 iface = 0x0; 294 break; 295 case SNDRV_PCM_FORMAT_S20_3LE: 296 iface = 0x4; 297 break; 298 case SNDRV_PCM_FORMAT_S24_LE: 299 iface = 0x8; 300 break; 301 case SNDRV_PCM_FORMAT_S32_LE: 302 iface = 0xc; 303 break; 304 default: 305 return -EINVAL; 306 } 307 regmap_update_bits(ssm2602->regmap, SSM2602_IFACE, 308 IFACE_AUDIO_DATA_LEN, iface); 309 return 0; 310 } 311 312 static int ssm2602_startup(struct snd_pcm_substream *substream, 313 struct snd_soc_dai *dai) 314 { 315 struct snd_soc_codec *codec = dai->codec; 316 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 317 struct snd_pcm_runtime *master_runtime; 318 319 /* The DAI has shared clocks so if we already have a playback or 320 * capture going then constrain this substream to match it. 321 * TODO: the ssm2602 allows pairs of non-matching PB/REC rates 322 */ 323 if (ssm2602->master_substream) { 324 master_runtime = ssm2602->master_substream->runtime; 325 dev_dbg(codec->dev, "Constraining to %d bits at %dHz\n", 326 master_runtime->sample_bits, 327 master_runtime->rate); 328 329 if (master_runtime->rate != 0) 330 snd_pcm_hw_constraint_minmax(substream->runtime, 331 SNDRV_PCM_HW_PARAM_RATE, 332 master_runtime->rate, 333 master_runtime->rate); 334 335 if (master_runtime->sample_bits != 0) 336 snd_pcm_hw_constraint_minmax(substream->runtime, 337 SNDRV_PCM_HW_PARAM_SAMPLE_BITS, 338 master_runtime->sample_bits, 339 master_runtime->sample_bits); 340 341 ssm2602->slave_substream = substream; 342 } else 343 ssm2602->master_substream = substream; 344 345 if (ssm2602->sysclk_constraints) { 346 snd_pcm_hw_constraint_list(substream->runtime, 0, 347 SNDRV_PCM_HW_PARAM_RATE, 348 ssm2602->sysclk_constraints); 349 } 350 351 return 0; 352 } 353 354 static void ssm2602_shutdown(struct snd_pcm_substream *substream, 355 struct snd_soc_dai *dai) 356 { 357 struct snd_soc_codec *codec = dai->codec; 358 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 359 360 if (ssm2602->master_substream == substream) 361 ssm2602->master_substream = ssm2602->slave_substream; 362 363 ssm2602->slave_substream = NULL; 364 } 365 366 367 static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 368 { 369 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(dai->codec); 370 371 if (mute) 372 regmap_update_bits(ssm2602->regmap, SSM2602_APDIGI, 373 APDIGI_ENABLE_DAC_MUTE, 374 APDIGI_ENABLE_DAC_MUTE); 375 else 376 regmap_update_bits(ssm2602->regmap, SSM2602_APDIGI, 377 APDIGI_ENABLE_DAC_MUTE, 0); 378 return 0; 379 } 380 381 static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai, 382 int clk_id, unsigned int freq, int dir) 383 { 384 struct snd_soc_codec *codec = codec_dai->codec; 385 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 386 387 if (dir == SND_SOC_CLOCK_IN) { 388 if (clk_id != SSM2602_SYSCLK) 389 return -EINVAL; 390 391 switch (freq) { 392 case 12288000: 393 case 18432000: 394 ssm2602->sysclk_constraints = &ssm2602_constraints_12288000; 395 break; 396 case 11289600: 397 case 16934400: 398 ssm2602->sysclk_constraints = &ssm2602_constraints_11289600; 399 break; 400 case 12000000: 401 ssm2602->sysclk_constraints = NULL; 402 break; 403 default: 404 return -EINVAL; 405 } 406 ssm2602->sysclk = freq; 407 } else { 408 unsigned int mask; 409 410 switch (clk_id) { 411 case SSM2602_CLK_CLKOUT: 412 mask = PWR_CLK_OUT_PDN; 413 break; 414 case SSM2602_CLK_XTO: 415 mask = PWR_OSC_PDN; 416 break; 417 default: 418 return -EINVAL; 419 } 420 421 if (freq == 0) 422 ssm2602->clk_out_pwr |= mask; 423 else 424 ssm2602->clk_out_pwr &= ~mask; 425 426 regmap_update_bits(ssm2602->regmap, SSM2602_PWR, 427 PWR_CLK_OUT_PDN | PWR_OSC_PDN, ssm2602->clk_out_pwr); 428 } 429 430 return 0; 431 } 432 433 static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, 434 unsigned int fmt) 435 { 436 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec_dai->codec); 437 unsigned int iface = 0; 438 439 /* set master/slave audio interface */ 440 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 441 case SND_SOC_DAIFMT_CBM_CFM: 442 iface |= 0x0040; 443 break; 444 case SND_SOC_DAIFMT_CBS_CFS: 445 break; 446 default: 447 return -EINVAL; 448 } 449 450 /* interface format */ 451 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 452 case SND_SOC_DAIFMT_I2S: 453 iface |= 0x0002; 454 break; 455 case SND_SOC_DAIFMT_RIGHT_J: 456 break; 457 case SND_SOC_DAIFMT_LEFT_J: 458 iface |= 0x0001; 459 break; 460 case SND_SOC_DAIFMT_DSP_A: 461 iface |= 0x0013; 462 break; 463 case SND_SOC_DAIFMT_DSP_B: 464 iface |= 0x0003; 465 break; 466 default: 467 return -EINVAL; 468 } 469 470 /* clock inversion */ 471 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 472 case SND_SOC_DAIFMT_NB_NF: 473 break; 474 case SND_SOC_DAIFMT_IB_IF: 475 iface |= 0x0090; 476 break; 477 case SND_SOC_DAIFMT_IB_NF: 478 iface |= 0x0080; 479 break; 480 case SND_SOC_DAIFMT_NB_IF: 481 iface |= 0x0010; 482 break; 483 default: 484 return -EINVAL; 485 } 486 487 /* set iface */ 488 regmap_write(ssm2602->regmap, SSM2602_IFACE, iface); 489 return 0; 490 } 491 492 static int ssm2602_set_bias_level(struct snd_soc_codec *codec, 493 enum snd_soc_bias_level level) 494 { 495 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 496 497 switch (level) { 498 case SND_SOC_BIAS_ON: 499 /* vref/mid on, osc and clkout on if enabled */ 500 regmap_update_bits(ssm2602->regmap, SSM2602_PWR, 501 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN, 502 ssm2602->clk_out_pwr); 503 break; 504 case SND_SOC_BIAS_PREPARE: 505 break; 506 case SND_SOC_BIAS_STANDBY: 507 /* everything off except vref/vmid, */ 508 regmap_update_bits(ssm2602->regmap, SSM2602_PWR, 509 PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN, 510 PWR_CLK_OUT_PDN | PWR_OSC_PDN); 511 break; 512 case SND_SOC_BIAS_OFF: 513 /* everything off */ 514 regmap_update_bits(ssm2602->regmap, SSM2602_PWR, 515 PWR_POWER_OFF, PWR_POWER_OFF); 516 break; 517 518 } 519 codec->dapm.bias_level = level; 520 return 0; 521 } 522 523 #define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\ 524 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ 525 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 526 527 #define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 528 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 529 530 static const struct snd_soc_dai_ops ssm2602_dai_ops = { 531 .startup = ssm2602_startup, 532 .hw_params = ssm2602_hw_params, 533 .shutdown = ssm2602_shutdown, 534 .digital_mute = ssm2602_mute, 535 .set_sysclk = ssm2602_set_dai_sysclk, 536 .set_fmt = ssm2602_set_dai_fmt, 537 }; 538 539 static struct snd_soc_dai_driver ssm2602_dai = { 540 .name = "ssm2602-hifi", 541 .playback = { 542 .stream_name = "Playback", 543 .channels_min = 2, 544 .channels_max = 2, 545 .rates = SSM2602_RATES, 546 .formats = SSM2602_FORMATS,}, 547 .capture = { 548 .stream_name = "Capture", 549 .channels_min = 2, 550 .channels_max = 2, 551 .rates = SSM2602_RATES, 552 .formats = SSM2602_FORMATS,}, 553 .ops = &ssm2602_dai_ops, 554 }; 555 556 static int ssm2602_suspend(struct snd_soc_codec *codec) 557 { 558 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); 559 return 0; 560 } 561 562 static int ssm2602_resume(struct snd_soc_codec *codec) 563 { 564 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 565 566 regcache_sync(ssm2602->regmap); 567 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 568 569 return 0; 570 } 571 572 static int ssm2602_probe(struct snd_soc_codec *codec) 573 { 574 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 575 struct snd_soc_dapm_context *dapm = &codec->dapm; 576 int ret; 577 578 regmap_update_bits(ssm2602->regmap, SSM2602_LOUT1V, 579 LOUT1V_LRHP_BOTH, LOUT1V_LRHP_BOTH); 580 regmap_update_bits(ssm2602->regmap, SSM2602_ROUT1V, 581 ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH); 582 583 ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls, 584 ARRAY_SIZE(ssm2602_snd_controls)); 585 if (ret) 586 return ret; 587 588 ret = snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets, 589 ARRAY_SIZE(ssm2602_dapm_widgets)); 590 if (ret) 591 return ret; 592 593 return snd_soc_dapm_add_routes(dapm, ssm2602_routes, 594 ARRAY_SIZE(ssm2602_routes)); 595 } 596 597 static int ssm2604_probe(struct snd_soc_codec *codec) 598 { 599 struct snd_soc_dapm_context *dapm = &codec->dapm; 600 int ret; 601 602 ret = snd_soc_dapm_new_controls(dapm, ssm2604_dapm_widgets, 603 ARRAY_SIZE(ssm2604_dapm_widgets)); 604 if (ret) 605 return ret; 606 607 return snd_soc_dapm_add_routes(dapm, ssm2604_routes, 608 ARRAY_SIZE(ssm2604_routes)); 609 } 610 611 static int ssm260x_probe(struct snd_soc_codec *codec) 612 { 613 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 614 int ret; 615 616 codec->control_data = ssm2602->regmap; 617 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); 618 if (ret < 0) { 619 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 620 return ret; 621 } 622 623 ret = regmap_write(ssm2602->regmap, SSM2602_RESET, 0); 624 if (ret < 0) { 625 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 626 return ret; 627 } 628 629 /* set the update bits */ 630 regmap_update_bits(ssm2602->regmap, SSM2602_LINVOL, 631 LINVOL_LRIN_BOTH, LINVOL_LRIN_BOTH); 632 regmap_update_bits(ssm2602->regmap, SSM2602_RINVOL, 633 RINVOL_RLIN_BOTH, RINVOL_RLIN_BOTH); 634 /*select Line in as default input*/ 635 regmap_write(ssm2602->regmap, SSM2602_APANA, APANA_SELECT_DAC | 636 APANA_ENABLE_MIC_BOOST); 637 638 switch (ssm2602->type) { 639 case SSM2602: 640 ret = ssm2602_probe(codec); 641 break; 642 case SSM2604: 643 ret = ssm2604_probe(codec); 644 break; 645 } 646 647 if (ret) 648 return ret; 649 650 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 651 652 return 0; 653 } 654 655 /* remove everything here */ 656 static int ssm2602_remove(struct snd_soc_codec *codec) 657 { 658 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF); 659 return 0; 660 } 661 662 static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { 663 .probe = ssm260x_probe, 664 .remove = ssm2602_remove, 665 .suspend = ssm2602_suspend, 666 .resume = ssm2602_resume, 667 .set_bias_level = ssm2602_set_bias_level, 668 669 .controls = ssm260x_snd_controls, 670 .num_controls = ARRAY_SIZE(ssm260x_snd_controls), 671 .dapm_widgets = ssm260x_dapm_widgets, 672 .num_dapm_widgets = ARRAY_SIZE(ssm260x_dapm_widgets), 673 .dapm_routes = ssm260x_routes, 674 .num_dapm_routes = ARRAY_SIZE(ssm260x_routes), 675 }; 676 677 static bool ssm2602_register_volatile(struct device *dev, unsigned int reg) 678 { 679 return reg == SSM2602_RESET; 680 } 681 682 static const struct regmap_config ssm2602_regmap_config = { 683 .val_bits = 9, 684 .reg_bits = 7, 685 686 .max_register = SSM2602_RESET, 687 .volatile_reg = ssm2602_register_volatile, 688 689 .cache_type = REGCACHE_RBTREE, 690 .reg_defaults_raw = ssm2602_reg, 691 .num_reg_defaults_raw = ARRAY_SIZE(ssm2602_reg), 692 }; 693 694 #if defined(CONFIG_SPI_MASTER) 695 static int ssm2602_spi_probe(struct spi_device *spi) 696 { 697 struct ssm2602_priv *ssm2602; 698 int ret; 699 700 ssm2602 = devm_kzalloc(&spi->dev, sizeof(struct ssm2602_priv), 701 GFP_KERNEL); 702 if (ssm2602 == NULL) 703 return -ENOMEM; 704 705 spi_set_drvdata(spi, ssm2602); 706 ssm2602->type = SSM2602; 707 708 ssm2602->regmap = devm_regmap_init_spi(spi, &ssm2602_regmap_config); 709 if (IS_ERR(ssm2602->regmap)) 710 return PTR_ERR(ssm2602->regmap); 711 712 ret = snd_soc_register_codec(&spi->dev, 713 &soc_codec_dev_ssm2602, &ssm2602_dai, 1); 714 return ret; 715 } 716 717 static int ssm2602_spi_remove(struct spi_device *spi) 718 { 719 snd_soc_unregister_codec(&spi->dev); 720 return 0; 721 } 722 723 static struct spi_driver ssm2602_spi_driver = { 724 .driver = { 725 .name = "ssm2602", 726 .owner = THIS_MODULE, 727 }, 728 .probe = ssm2602_spi_probe, 729 .remove = ssm2602_spi_remove, 730 }; 731 #endif 732 733 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 734 /* 735 * ssm2602 2 wire address is determined by GPIO5 736 * state during powerup. 737 * low = 0x1a 738 * high = 0x1b 739 */ 740 static int ssm2602_i2c_probe(struct i2c_client *i2c, 741 const struct i2c_device_id *id) 742 { 743 struct ssm2602_priv *ssm2602; 744 int ret; 745 746 ssm2602 = devm_kzalloc(&i2c->dev, sizeof(struct ssm2602_priv), 747 GFP_KERNEL); 748 if (ssm2602 == NULL) 749 return -ENOMEM; 750 751 i2c_set_clientdata(i2c, ssm2602); 752 ssm2602->type = id->driver_data; 753 754 ssm2602->regmap = devm_regmap_init_i2c(i2c, &ssm2602_regmap_config); 755 if (IS_ERR(ssm2602->regmap)) 756 return PTR_ERR(ssm2602->regmap); 757 758 ret = snd_soc_register_codec(&i2c->dev, 759 &soc_codec_dev_ssm2602, &ssm2602_dai, 1); 760 return ret; 761 } 762 763 static int ssm2602_i2c_remove(struct i2c_client *client) 764 { 765 snd_soc_unregister_codec(&client->dev); 766 return 0; 767 } 768 769 static const struct i2c_device_id ssm2602_i2c_id[] = { 770 { "ssm2602", SSM2602 }, 771 { "ssm2603", SSM2602 }, 772 { "ssm2604", SSM2604 }, 773 { } 774 }; 775 MODULE_DEVICE_TABLE(i2c, ssm2602_i2c_id); 776 777 /* corgi i2c codec control layer */ 778 static struct i2c_driver ssm2602_i2c_driver = { 779 .driver = { 780 .name = "ssm2602", 781 .owner = THIS_MODULE, 782 }, 783 .probe = ssm2602_i2c_probe, 784 .remove = ssm2602_i2c_remove, 785 .id_table = ssm2602_i2c_id, 786 }; 787 #endif 788 789 790 static int __init ssm2602_modinit(void) 791 { 792 int ret = 0; 793 794 #if defined(CONFIG_SPI_MASTER) 795 ret = spi_register_driver(&ssm2602_spi_driver); 796 if (ret) 797 return ret; 798 #endif 799 800 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 801 ret = i2c_add_driver(&ssm2602_i2c_driver); 802 if (ret) 803 return ret; 804 #endif 805 806 return ret; 807 } 808 module_init(ssm2602_modinit); 809 810 static void __exit ssm2602_exit(void) 811 { 812 #if defined(CONFIG_SPI_MASTER) 813 spi_unregister_driver(&ssm2602_spi_driver); 814 #endif 815 816 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 817 i2c_del_driver(&ssm2602_i2c_driver); 818 #endif 819 } 820 module_exit(ssm2602_exit); 821 822 MODULE_DESCRIPTION("ASoC SSM2602/SSM2603/SSM2604 driver"); 823 MODULE_AUTHOR("Cliff Cai"); 824 MODULE_LICENSE("GPL"); 825