1 /* 2 * ALSA SoC TLV320AIC23 codec driver 3 * 4 * Author: Arun KS, <arunks@mistralsolutions.com> 5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd., 6 * 7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 * Notes: 14 * The AIC23 is a driver for a low power stereo audio 15 * codec tlv320aic23 16 * 17 * The machine layer should disable unsupported inputs/outputs by 18 * snd_soc_dapm_disable_pin(codec, "LHPOUT"), etc. 19 */ 20 21 #include <linux/module.h> 22 #include <linux/moduleparam.h> 23 #include <linux/init.h> 24 #include <linux/delay.h> 25 #include <linux/pm.h> 26 #include <linux/i2c.h> 27 #include <linux/platform_device.h> 28 #include <sound/core.h> 29 #include <sound/pcm.h> 30 #include <sound/pcm_params.h> 31 #include <sound/soc.h> 32 #include <sound/soc-dapm.h> 33 #include <sound/tlv.h> 34 #include <sound/initval.h> 35 36 #include "tlv320aic23.h" 37 38 #define AUDIO_NAME "tlv320aic23" 39 #define AIC23_VERSION "0.1" 40 41 struct tlv320aic23_srate_reg_info { 42 u32 sample_rate; 43 u8 control; /* SR3, SR2, SR1, SR0 and BOSR */ 44 u8 divider; /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */ 45 }; 46 47 /* 48 * AIC23 register cache 49 */ 50 static const u16 tlv320aic23_reg[] = { 51 0x0097, 0x0097, 0x00F9, 0x00F9, /* 0 */ 52 0x001A, 0x0004, 0x0007, 0x0001, /* 4 */ 53 0x0020, 0x0000, 0x0000, 0x0000, /* 8 */ 54 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */ 55 }; 56 57 /* 58 * read tlv320aic23 register cache 59 */ 60 static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec 61 *codec, unsigned int reg) 62 { 63 u16 *cache = codec->reg_cache; 64 if (reg >= ARRAY_SIZE(tlv320aic23_reg)) 65 return -1; 66 return cache[reg]; 67 } 68 69 /* 70 * write tlv320aic23 register cache 71 */ 72 static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec, 73 u8 reg, u16 value) 74 { 75 u16 *cache = codec->reg_cache; 76 if (reg >= ARRAY_SIZE(tlv320aic23_reg)) 77 return; 78 cache[reg] = value; 79 } 80 81 /* 82 * write to the tlv320aic23 register space 83 */ 84 static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg, 85 unsigned int value) 86 { 87 88 u8 data; 89 90 /* TLV320AIC23 has 7 bit address and 9 bits of data 91 * so we need to switch one data bit into reg and rest 92 * of data into val 93 */ 94 95 if ((reg < 0 || reg > 9) && (reg != 15)) { 96 printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg); 97 return -1; 98 } 99 100 data = (reg << 1) | (value >> 8 & 0x01); 101 102 tlv320aic23_write_reg_cache(codec, reg, value); 103 104 if (codec->hw_write(codec->control_data, data, 105 (value & 0xff)) == 0) 106 return 0; 107 108 printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__, 109 value, reg); 110 111 return -EIO; 112 } 113 114 static const char *rec_src_text[] = { "Line", "Mic" }; 115 static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 116 static const char *sidetone_text[] = {"-6db", "-9db", "-12db", "-18db", "0db"}; 117 118 static const struct soc_enum rec_src_enum = 119 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); 120 121 static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls = 122 SOC_DAPM_ENUM("Input Select", rec_src_enum); 123 124 static const struct soc_enum tlv320aic23_rec_src = 125 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text); 126 static const struct soc_enum tlv320aic23_deemph = 127 SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text); 128 static const struct soc_enum tlv320aic23_sidetone = 129 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 6, 5, sidetone_text); 130 131 static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0); 132 static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0); 133 134 static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { 135 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL, 136 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv), 137 SOC_SINGLE("Digital Playback Switch", TLV320AIC23_DIGT, 3, 1, 1), 138 SOC_DOUBLE_R("Line Input Switch", TLV320AIC23_LINVOL, 139 TLV320AIC23_RINVOL, 7, 1, 0), 140 SOC_DOUBLE_R_TLV("Line Input Volume", TLV320AIC23_LINVOL, 141 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv), 142 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1), 143 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0), 144 SOC_ENUM("Sidetone Gain", tlv320aic23_sidetone), 145 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), 146 }; 147 148 /* add non dapm controls */ 149 static int tlv320aic23_add_controls(struct snd_soc_codec *codec) 150 { 151 152 int err, i; 153 154 for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) { 155 err = snd_ctl_add(codec->card, 156 snd_soc_cnew(&tlv320aic23_snd_controls[i], 157 codec, NULL)); 158 if (err < 0) 159 return err; 160 } 161 162 return 0; 163 164 } 165 166 /* PGA Mixer controls for Line and Mic switch */ 167 static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = { 168 SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0), 169 SOC_DAPM_SINGLE("Mic Sidetone Switch", TLV320AIC23_ANLG, 5, 1, 0), 170 SOC_DAPM_SINGLE("Playback Switch", TLV320AIC23_ANLG, 4, 1, 0), 171 }; 172 173 static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = { 174 SND_SOC_DAPM_DAC("DAC", "Playback", TLV320AIC23_PWR, 3, 1), 175 SND_SOC_DAPM_ADC("ADC", "Capture", TLV320AIC23_PWR, 2, 1), 176 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0, 177 &tlv320aic23_rec_src_mux_controls), 178 SND_SOC_DAPM_MIXER("Output Mixer", TLV320AIC23_PWR, 4, 1, 179 &tlv320aic23_output_mixer_controls[0], 180 ARRAY_SIZE(tlv320aic23_output_mixer_controls)), 181 SND_SOC_DAPM_PGA("Line Input", TLV320AIC23_PWR, 0, 1, NULL, 0), 182 SND_SOC_DAPM_PGA("Mic Input", TLV320AIC23_PWR, 1, 1, NULL, 0), 183 184 SND_SOC_DAPM_OUTPUT("LHPOUT"), 185 SND_SOC_DAPM_OUTPUT("RHPOUT"), 186 SND_SOC_DAPM_OUTPUT("LOUT"), 187 SND_SOC_DAPM_OUTPUT("ROUT"), 188 189 SND_SOC_DAPM_INPUT("LLINEIN"), 190 SND_SOC_DAPM_INPUT("RLINEIN"), 191 192 SND_SOC_DAPM_INPUT("MICIN"), 193 }; 194 195 static const struct snd_soc_dapm_route intercon[] = { 196 /* Output Mixer */ 197 {"Output Mixer", "Line Bypass Switch", "Line Input"}, 198 {"Output Mixer", "Playback Switch", "DAC"}, 199 {"Output Mixer", "Mic Sidetone Switch", "Mic Input"}, 200 201 /* Outputs */ 202 {"RHPOUT", NULL, "Output Mixer"}, 203 {"LHPOUT", NULL, "Output Mixer"}, 204 {"LOUT", NULL, "Output Mixer"}, 205 {"ROUT", NULL, "Output Mixer"}, 206 207 /* Inputs */ 208 {"Line Input", "NULL", "LLINEIN"}, 209 {"Line Input", "NULL", "RLINEIN"}, 210 211 {"Mic Input", "NULL", "MICIN"}, 212 213 /* input mux */ 214 {"Capture Source", "Line", "Line Input"}, 215 {"Capture Source", "Mic", "Mic Input"}, 216 {"ADC", NULL, "Capture Source"}, 217 218 }; 219 220 /* tlv320aic23 related */ 221 static const struct tlv320aic23_srate_reg_info srate_reg_info[] = { 222 {4000, 0x06, 1}, /* 4000 */ 223 {8000, 0x06, 0}, /* 8000 */ 224 {16000, 0x0C, 1}, /* 16000 */ 225 {22050, 0x11, 1}, /* 22050 */ 226 {24000, 0x00, 1}, /* 24000 */ 227 {32000, 0x0C, 0}, /* 32000 */ 228 {44100, 0x11, 0}, /* 44100 */ 229 {48000, 0x00, 0}, /* 48000 */ 230 {88200, 0x1F, 0}, /* 88200 */ 231 {96000, 0x0E, 0}, /* 96000 */ 232 }; 233 234 static int tlv320aic23_add_widgets(struct snd_soc_codec *codec) 235 { 236 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 237 ARRAY_SIZE(tlv320aic23_dapm_widgets)); 238 239 /* set up audio path interconnects */ 240 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 241 242 snd_soc_dapm_new_widgets(codec); 243 return 0; 244 } 245 246 static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, 247 struct snd_pcm_hw_params *params) 248 { 249 struct snd_soc_pcm_runtime *rtd = substream->private_data; 250 struct snd_soc_device *socdev = rtd->socdev; 251 struct snd_soc_codec *codec = socdev->codec; 252 u16 iface_reg, data; 253 u8 count = 0; 254 255 iface_reg = 256 tlv320aic23_read_reg_cache(codec, 257 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2); 258 259 /* Search for the right sample rate */ 260 /* Verify what happens if the rate is not supported 261 * now it goes to 96Khz */ 262 while ((srate_reg_info[count].sample_rate != params_rate(params)) && 263 (count < ARRAY_SIZE(srate_reg_info))) { 264 count++; 265 } 266 267 data = (srate_reg_info[count].divider << TLV320AIC23_CLKIN_SHIFT) | 268 (srate_reg_info[count]. control << TLV320AIC23_BOSR_SHIFT) | 269 TLV320AIC23_USB_CLK_ON; 270 271 tlv320aic23_write(codec, TLV320AIC23_SRATE, data); 272 273 switch (params_format(params)) { 274 case SNDRV_PCM_FORMAT_S16_LE: 275 break; 276 case SNDRV_PCM_FORMAT_S20_3LE: 277 iface_reg |= (0x01 << 2); 278 break; 279 case SNDRV_PCM_FORMAT_S24_LE: 280 iface_reg |= (0x02 << 2); 281 break; 282 case SNDRV_PCM_FORMAT_S32_LE: 283 iface_reg |= (0x03 << 2); 284 break; 285 } 286 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); 287 288 return 0; 289 } 290 291 static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream) 292 { 293 struct snd_soc_pcm_runtime *rtd = substream->private_data; 294 struct snd_soc_device *socdev = rtd->socdev; 295 struct snd_soc_codec *codec = socdev->codec; 296 297 /* set active */ 298 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); 299 300 return 0; 301 } 302 303 static void tlv320aic23_shutdown(struct snd_pcm_substream *substream) 304 { 305 struct snd_soc_pcm_runtime *rtd = substream->private_data; 306 struct snd_soc_device *socdev = rtd->socdev; 307 struct snd_soc_codec *codec = socdev->codec; 308 309 /* deactivate */ 310 if (!codec->active) { 311 udelay(50); 312 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 313 } 314 } 315 316 static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute) 317 { 318 struct snd_soc_codec *codec = dai->codec; 319 u16 reg; 320 321 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT); 322 if (mute) 323 reg |= TLV320AIC23_DACM_MUTE; 324 325 else 326 reg &= ~TLV320AIC23_DACM_MUTE; 327 328 tlv320aic23_write(codec, TLV320AIC23_DIGT, reg); 329 330 return 0; 331 } 332 333 static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, 334 unsigned int fmt) 335 { 336 struct snd_soc_codec *codec = codec_dai->codec; 337 u16 iface_reg; 338 339 iface_reg = 340 tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03); 341 342 /* set master/slave audio interface */ 343 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 344 case SND_SOC_DAIFMT_CBM_CFM: 345 iface_reg |= TLV320AIC23_MS_MASTER; 346 break; 347 case SND_SOC_DAIFMT_CBS_CFS: 348 break; 349 default: 350 return -EINVAL; 351 352 } 353 354 /* interface format */ 355 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 356 case SND_SOC_DAIFMT_I2S: 357 iface_reg |= TLV320AIC23_FOR_I2S; 358 break; 359 case SND_SOC_DAIFMT_DSP_A: 360 iface_reg |= TLV320AIC23_FOR_DSP; 361 break; 362 case SND_SOC_DAIFMT_RIGHT_J: 363 break; 364 case SND_SOC_DAIFMT_LEFT_J: 365 iface_reg |= TLV320AIC23_FOR_LJUST; 366 break; 367 default: 368 return -EINVAL; 369 370 } 371 372 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); 373 374 return 0; 375 } 376 377 static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai, 378 int clk_id, unsigned int freq, int dir) 379 { 380 struct snd_soc_codec *codec = codec_dai->codec; 381 382 switch (freq) { 383 case 12000000: 384 return 0; 385 } 386 return -EINVAL; 387 } 388 389 static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, 390 enum snd_soc_bias_level level) 391 { 392 u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f; 393 394 switch (level) { 395 case SND_SOC_BIAS_ON: 396 /* vref/mid, osc on, dac unmute */ 397 tlv320aic23_write(codec, TLV320AIC23_PWR, reg); 398 break; 399 case SND_SOC_BIAS_PREPARE: 400 break; 401 case SND_SOC_BIAS_STANDBY: 402 /* everything off except vref/vmid, */ 403 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | 0x0040); 404 break; 405 case SND_SOC_BIAS_OFF: 406 /* everything off, dac mute, inactive */ 407 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 408 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff); 409 break; 410 } 411 codec->bias_level = level; 412 return 0; 413 } 414 415 #define AIC23_RATES SNDRV_PCM_RATE_8000_96000 416 #define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 417 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 418 419 struct snd_soc_dai tlv320aic23_dai = { 420 .name = "tlv320aic23", 421 .playback = { 422 .stream_name = "Playback", 423 .channels_min = 2, 424 .channels_max = 2, 425 .rates = AIC23_RATES, 426 .formats = AIC23_FORMATS,}, 427 .capture = { 428 .stream_name = "Capture", 429 .channels_min = 2, 430 .channels_max = 2, 431 .rates = AIC23_RATES, 432 .formats = AIC23_FORMATS,}, 433 .ops = { 434 .prepare = tlv320aic23_pcm_prepare, 435 .hw_params = tlv320aic23_hw_params, 436 .shutdown = tlv320aic23_shutdown, 437 }, 438 .dai_ops = { 439 .digital_mute = tlv320aic23_mute, 440 .set_fmt = tlv320aic23_set_dai_fmt, 441 .set_sysclk = tlv320aic23_set_dai_sysclk, 442 } 443 }; 444 EXPORT_SYMBOL_GPL(tlv320aic23_dai); 445 446 static int tlv320aic23_suspend(struct platform_device *pdev, 447 pm_message_t state) 448 { 449 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 450 struct snd_soc_codec *codec = socdev->codec; 451 452 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 453 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); 454 455 return 0; 456 } 457 458 static int tlv320aic23_resume(struct platform_device *pdev) 459 { 460 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 461 struct snd_soc_codec *codec = socdev->codec; 462 int i; 463 u16 reg; 464 465 /* Sync reg_cache with the hardware */ 466 for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) { 467 u16 val = tlv320aic23_read_reg_cache(codec, reg); 468 tlv320aic23_write(codec, reg, val); 469 } 470 471 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 472 tlv320aic23_set_bias_level(codec, codec->suspend_bias_level); 473 474 return 0; 475 } 476 477 /* 478 * initialise the AIC23 driver 479 * register the mixer and dsp interfaces with the kernel 480 */ 481 static int tlv320aic23_init(struct snd_soc_device *socdev) 482 { 483 struct snd_soc_codec *codec = socdev->codec; 484 int ret = 0; 485 u16 reg; 486 487 codec->name = "tlv320aic23"; 488 codec->owner = THIS_MODULE; 489 codec->read = tlv320aic23_read_reg_cache; 490 codec->write = tlv320aic23_write; 491 codec->set_bias_level = tlv320aic23_set_bias_level; 492 codec->dai = &tlv320aic23_dai; 493 codec->num_dai = 1; 494 codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg); 495 codec->reg_cache = 496 kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL); 497 if (codec->reg_cache == NULL) 498 return -ENOMEM; 499 500 /* Reset codec */ 501 tlv320aic23_write(codec, TLV320AIC23_RESET, 0); 502 503 /* register pcms */ 504 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 505 if (ret < 0) { 506 printk(KERN_ERR "tlv320aic23: failed to create pcms\n"); 507 goto pcm_err; 508 } 509 510 /* power on device */ 511 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 512 513 tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K); 514 515 /* Unmute input */ 516 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL); 517 tlv320aic23_write(codec, TLV320AIC23_LINVOL, 518 (reg & (~TLV320AIC23_LIM_MUTED)) | 519 (TLV320AIC23_LRS_ENABLED)); 520 521 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL); 522 tlv320aic23_write(codec, TLV320AIC23_RINVOL, 523 (reg & (~TLV320AIC23_LIM_MUTED)) | 524 TLV320AIC23_LRS_ENABLED); 525 526 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG); 527 tlv320aic23_write(codec, TLV320AIC23_ANLG, 528 (reg) & (~TLV320AIC23_BYPASS_ON) & 529 (~TLV320AIC23_MICM_MUTED)); 530 531 /* Default output volume */ 532 tlv320aic23_write(codec, TLV320AIC23_LCHNVOL, 533 TLV320AIC23_DEFAULT_OUT_VOL & 534 TLV320AIC23_OUT_VOL_MASK); 535 tlv320aic23_write(codec, TLV320AIC23_RCHNVOL, 536 TLV320AIC23_DEFAULT_OUT_VOL & 537 TLV320AIC23_OUT_VOL_MASK); 538 539 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1); 540 541 tlv320aic23_add_controls(codec); 542 tlv320aic23_add_widgets(codec); 543 ret = snd_soc_register_card(socdev); 544 if (ret < 0) { 545 printk(KERN_ERR "tlv320aic23: failed to register card\n"); 546 goto card_err; 547 } 548 549 return ret; 550 551 card_err: 552 snd_soc_free_pcms(socdev); 553 snd_soc_dapm_free(socdev); 554 pcm_err: 555 kfree(codec->reg_cache); 556 return ret; 557 } 558 static struct snd_soc_device *tlv320aic23_socdev; 559 560 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 561 /* 562 * If the i2c layer weren't so broken, we could pass this kind of data 563 * around 564 */ 565 static int tlv320aic23_codec_probe(struct i2c_client *i2c, 566 const struct i2c_device_id *i2c_id) 567 { 568 struct snd_soc_device *socdev = tlv320aic23_socdev; 569 struct snd_soc_codec *codec = socdev->codec; 570 int ret; 571 572 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 573 return -EINVAL; 574 575 i2c_set_clientdata(i2c, codec); 576 codec->control_data = i2c; 577 578 ret = tlv320aic23_init(socdev); 579 if (ret < 0) { 580 printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n"); 581 goto err; 582 } 583 return ret; 584 585 err: 586 kfree(codec); 587 kfree(i2c); 588 return ret; 589 } 590 static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c) 591 { 592 put_device(&i2c->dev); 593 return 0; 594 } 595 596 static const struct i2c_device_id tlv320aic23_id[] = { 597 {"tlv320aic23", 0}, 598 {} 599 }; 600 601 MODULE_DEVICE_TABLE(i2c, tlv320aic23_id); 602 603 static struct i2c_driver tlv320aic23_i2c_driver = { 604 .driver = { 605 .name = "tlv320aic23", 606 }, 607 .probe = tlv320aic23_codec_probe, 608 .remove = __exit_p(tlv320aic23_i2c_remove), 609 .id_table = tlv320aic23_id, 610 }; 611 612 #endif 613 614 static int tlv320aic23_probe(struct platform_device *pdev) 615 { 616 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 617 struct snd_soc_codec *codec; 618 int ret = 0; 619 620 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION); 621 622 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 623 if (codec == NULL) 624 return -ENOMEM; 625 626 socdev->codec = codec; 627 mutex_init(&codec->mutex); 628 INIT_LIST_HEAD(&codec->dapm_widgets); 629 INIT_LIST_HEAD(&codec->dapm_paths); 630 631 tlv320aic23_socdev = socdev; 632 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 633 codec->hw_write = (hw_write_t) i2c_smbus_write_byte_data; 634 codec->hw_read = NULL; 635 ret = i2c_add_driver(&tlv320aic23_i2c_driver); 636 if (ret != 0) 637 printk(KERN_ERR "can't add i2c driver"); 638 #endif 639 return ret; 640 } 641 642 static int tlv320aic23_remove(struct platform_device *pdev) 643 { 644 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 645 struct snd_soc_codec *codec = socdev->codec; 646 647 if (codec->control_data) 648 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); 649 650 snd_soc_free_pcms(socdev); 651 snd_soc_dapm_free(socdev); 652 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 653 i2c_del_driver(&tlv320aic23_i2c_driver); 654 #endif 655 kfree(codec->reg_cache); 656 kfree(codec); 657 658 return 0; 659 } 660 struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = { 661 .probe = tlv320aic23_probe, 662 .remove = tlv320aic23_remove, 663 .suspend = tlv320aic23_suspend, 664 .resume = tlv320aic23_resume, 665 }; 666 EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23); 667 668 MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); 669 MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); 670 MODULE_LICENSE("GPL"); 671