1/* 2 * AD193X Audio Codec driver supporting AD1936/7/8/9 3 * 4 * Copyright 2010 Analog Devices Inc. 5 * 6 * Licensed under the GPL-2 or later. 7 */ 8 9#include <linux/init.h> 10#include <linux/module.h> 11#include <linux/kernel.h> 12#include <linux/device.h> 13#include <linux/i2c.h> 14#include <linux/spi/spi.h> 15#include <linux/slab.h> 16#include <sound/core.h> 17#include <sound/pcm.h> 18#include <sound/pcm_params.h> 19#include <sound/initval.h> 20#include <sound/soc.h> 21#include <sound/tlv.h> 22#include <sound/soc-dapm.h> 23#include "ad193x.h" 24 25/* codec private data */ 26struct ad193x_priv { 27 unsigned int sysclk; 28 struct snd_soc_codec codec; 29 u8 reg_cache[AD193X_NUM_REGS]; 30}; 31 32/* ad193x register cache & default register settings */ 33static const u8 ad193x_reg[AD193X_NUM_REGS] = { 34 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 35}; 36 37static struct snd_soc_codec *ad193x_codec; 38struct snd_soc_codec_device soc_codec_dev_ad193x; 39 40/* 41 * AD193X volume/mute/de-emphasis etc. controls 42 */ 43static const char *ad193x_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"}; 44 45static const struct soc_enum ad193x_deemp_enum = 46 SOC_ENUM_SINGLE(AD193X_DAC_CTRL2, 1, 4, ad193x_deemp); 47 48static const struct snd_kcontrol_new ad193x_snd_controls[] = { 49 /* DAC volume control */ 50 SOC_DOUBLE_R("DAC1 Volume", AD193X_DAC_L1_VOL, 51 AD193X_DAC_R1_VOL, 0, 0xFF, 1), 52 SOC_DOUBLE_R("DAC2 Volume", AD193X_DAC_L2_VOL, 53 AD193X_DAC_R2_VOL, 0, 0xFF, 1), 54 SOC_DOUBLE_R("DAC3 Volume", AD193X_DAC_L3_VOL, 55 AD193X_DAC_R3_VOL, 0, 0xFF, 1), 56 SOC_DOUBLE_R("DAC4 Volume", AD193X_DAC_L4_VOL, 57 AD193X_DAC_R4_VOL, 0, 0xFF, 1), 58 59 /* ADC switch control */ 60 SOC_DOUBLE("ADC1 Switch", AD193X_ADC_CTRL0, AD193X_ADCL1_MUTE, 61 AD193X_ADCR1_MUTE, 1, 1), 62 SOC_DOUBLE("ADC2 Switch", AD193X_ADC_CTRL0, AD193X_ADCL2_MUTE, 63 AD193X_ADCR2_MUTE, 1, 1), 64 65 /* DAC switch control */ 66 SOC_DOUBLE("DAC1 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL1_MUTE, 67 AD193X_DACR1_MUTE, 1, 1), 68 SOC_DOUBLE("DAC2 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL2_MUTE, 69 AD193X_DACR2_MUTE, 1, 1), 70 SOC_DOUBLE("DAC3 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL3_MUTE, 71 AD193X_DACR3_MUTE, 1, 1), 72 SOC_DOUBLE("DAC4 Switch", AD193X_DAC_CHNL_MUTE, AD193X_DACL4_MUTE, 73 AD193X_DACR4_MUTE, 1, 1), 74 75 /* ADC high-pass filter */ 76 SOC_SINGLE("ADC High Pass Filter Switch", AD193X_ADC_CTRL0, 77 AD193X_ADC_HIGHPASS_FILTER, 1, 0), 78 79 /* DAC de-emphasis */ 80 SOC_ENUM("Playback Deemphasis", ad193x_deemp_enum), 81}; 82 83static const struct snd_soc_dapm_widget ad193x_dapm_widgets[] = { 84 SND_SOC_DAPM_DAC("DAC", "Playback", AD193X_DAC_CTRL0, 0, 1), 85 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), 86 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD193X_PLL_CLK_CTRL0, 0, 1, NULL, 0), 87 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD193X_ADC_CTRL0, 0, 1, NULL, 0), 88 SND_SOC_DAPM_OUTPUT("DAC1OUT"), 89 SND_SOC_DAPM_OUTPUT("DAC2OUT"), 90 SND_SOC_DAPM_OUTPUT("DAC3OUT"), 91 SND_SOC_DAPM_OUTPUT("DAC4OUT"), 92 SND_SOC_DAPM_INPUT("ADC1IN"), 93 SND_SOC_DAPM_INPUT("ADC2IN"), 94}; 95 96static const struct snd_soc_dapm_route audio_paths[] = { 97 { "DAC", NULL, "PLL_PWR" }, 98 { "ADC", NULL, "PLL_PWR" }, 99 { "DAC", NULL, "ADC_PWR" }, 100 { "ADC", NULL, "ADC_PWR" }, 101 { "DAC1OUT", "DAC1 Switch", "DAC" }, 102 { "DAC2OUT", "DAC2 Switch", "DAC" }, 103 { "DAC3OUT", "DAC3 Switch", "DAC" }, 104 { "DAC4OUT", "DAC4 Switch", "DAC" }, 105 { "ADC", "ADC1 Switch", "ADC1IN" }, 106 { "ADC", "ADC2 Switch", "ADC2IN" }, 107}; 108 109/* 110 * DAI ops entries 111 */ 112 113static int ad193x_mute(struct snd_soc_dai *dai, int mute) 114{ 115 struct snd_soc_codec *codec = dai->codec; 116 int reg; 117 118 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 119 reg = (mute > 0) ? reg | AD193X_DAC_MASTER_MUTE : reg & 120 (~AD193X_DAC_MASTER_MUTE); 121 snd_soc_write(codec, AD193X_DAC_CTRL2, reg); 122 123 return 0; 124} 125 126static int ad193x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 127 unsigned int rx_mask, int slots, int width) 128{ 129 struct snd_soc_codec *codec = dai->codec; 130 int dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1); 131 int adc_reg = snd_soc_read(codec, AD193X_ADC_CTRL2); 132 133 dac_reg &= ~AD193X_DAC_CHAN_MASK; 134 adc_reg &= ~AD193X_ADC_CHAN_MASK; 135 136 switch (slots) { 137 case 2: 138 dac_reg |= AD193X_DAC_2_CHANNELS << AD193X_DAC_CHAN_SHFT; 139 adc_reg |= AD193X_ADC_2_CHANNELS << AD193X_ADC_CHAN_SHFT; 140 break; 141 case 4: 142 dac_reg |= AD193X_DAC_4_CHANNELS << AD193X_DAC_CHAN_SHFT; 143 adc_reg |= AD193X_ADC_4_CHANNELS << AD193X_ADC_CHAN_SHFT; 144 break; 145 case 8: 146 dac_reg |= AD193X_DAC_8_CHANNELS << AD193X_DAC_CHAN_SHFT; 147 adc_reg |= AD193X_ADC_8_CHANNELS << AD193X_ADC_CHAN_SHFT; 148 break; 149 case 16: 150 dac_reg |= AD193X_DAC_16_CHANNELS << AD193X_DAC_CHAN_SHFT; 151 adc_reg |= AD193X_ADC_16_CHANNELS << AD193X_ADC_CHAN_SHFT; 152 break; 153 default: 154 return -EINVAL; 155 } 156 157 snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg); 158 snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg); 159 160 return 0; 161} 162 163static int ad193x_set_dai_fmt(struct snd_soc_dai *codec_dai, 164 unsigned int fmt) 165{ 166 struct snd_soc_codec *codec = codec_dai->codec; 167 int adc_reg1, adc_reg2, dac_reg; 168 169 adc_reg1 = snd_soc_read(codec, AD193X_ADC_CTRL1); 170 adc_reg2 = snd_soc_read(codec, AD193X_ADC_CTRL2); 171 dac_reg = snd_soc_read(codec, AD193X_DAC_CTRL1); 172 173 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S 174 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) 175 */ 176 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 177 case SND_SOC_DAIFMT_I2S: 178 adc_reg1 &= ~AD193X_ADC_SERFMT_MASK; 179 adc_reg1 |= AD193X_ADC_SERFMT_TDM; 180 break; 181 case SND_SOC_DAIFMT_DSP_A: 182 adc_reg1 &= ~AD193X_ADC_SERFMT_MASK; 183 adc_reg1 |= AD193X_ADC_SERFMT_AUX; 184 break; 185 default: 186 return -EINVAL; 187 } 188 189 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 190 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */ 191 adc_reg2 &= ~AD193X_ADC_LEFT_HIGH; 192 adc_reg2 &= ~AD193X_ADC_BCLK_INV; 193 dac_reg &= ~AD193X_DAC_LEFT_HIGH; 194 dac_reg &= ~AD193X_DAC_BCLK_INV; 195 break; 196 case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */ 197 adc_reg2 |= AD193X_ADC_LEFT_HIGH; 198 adc_reg2 &= ~AD193X_ADC_BCLK_INV; 199 dac_reg |= AD193X_DAC_LEFT_HIGH; 200 dac_reg &= ~AD193X_DAC_BCLK_INV; 201 break; 202 case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */ 203 adc_reg2 &= ~AD193X_ADC_LEFT_HIGH; 204 adc_reg2 |= AD193X_ADC_BCLK_INV; 205 dac_reg &= ~AD193X_DAC_LEFT_HIGH; 206 dac_reg |= AD193X_DAC_BCLK_INV; 207 break; 208 209 case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */ 210 adc_reg2 |= AD193X_ADC_LEFT_HIGH; 211 adc_reg2 |= AD193X_ADC_BCLK_INV; 212 dac_reg |= AD193X_DAC_LEFT_HIGH; 213 dac_reg |= AD193X_DAC_BCLK_INV; 214 break; 215 default: 216 return -EINVAL; 217 } 218 219 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 220 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */ 221 adc_reg2 |= AD193X_ADC_LCR_MASTER; 222 adc_reg2 |= AD193X_ADC_BCLK_MASTER; 223 dac_reg |= AD193X_DAC_LCR_MASTER; 224 dac_reg |= AD193X_DAC_BCLK_MASTER; 225 break; 226 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */ 227 adc_reg2 |= AD193X_ADC_LCR_MASTER; 228 adc_reg2 &= ~AD193X_ADC_BCLK_MASTER; 229 dac_reg |= AD193X_DAC_LCR_MASTER; 230 dac_reg &= ~AD193X_DAC_BCLK_MASTER; 231 break; 232 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */ 233 adc_reg2 &= ~AD193X_ADC_LCR_MASTER; 234 adc_reg2 |= AD193X_ADC_BCLK_MASTER; 235 dac_reg &= ~AD193X_DAC_LCR_MASTER; 236 dac_reg |= AD193X_DAC_BCLK_MASTER; 237 break; 238 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */ 239 adc_reg2 &= ~AD193X_ADC_LCR_MASTER; 240 adc_reg2 &= ~AD193X_ADC_BCLK_MASTER; 241 dac_reg &= ~AD193X_DAC_LCR_MASTER; 242 dac_reg &= ~AD193X_DAC_BCLK_MASTER; 243 break; 244 default: 245 return -EINVAL; 246 } 247 248 snd_soc_write(codec, AD193X_ADC_CTRL1, adc_reg1); 249 snd_soc_write(codec, AD193X_ADC_CTRL2, adc_reg2); 250 snd_soc_write(codec, AD193X_DAC_CTRL1, dac_reg); 251 252 return 0; 253} 254 255static int ad193x_set_dai_sysclk(struct snd_soc_dai *codec_dai, 256 int clk_id, unsigned int freq, int dir) 257{ 258 struct snd_soc_codec *codec = codec_dai->codec; 259 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 260 switch (freq) { 261 case 12288000: 262 case 18432000: 263 case 24576000: 264 case 36864000: 265 ad193x->sysclk = freq; 266 return 0; 267 } 268 return -EINVAL; 269} 270 271static int ad193x_hw_params(struct snd_pcm_substream *substream, 272 struct snd_pcm_hw_params *params, 273 struct snd_soc_dai *dai) 274{ 275 int word_len = 0, reg = 0, master_rate = 0; 276 277 struct snd_soc_pcm_runtime *rtd = substream->private_data; 278 struct snd_soc_device *socdev = rtd->socdev; 279 struct snd_soc_codec *codec = socdev->card->codec; 280 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 281 282 /* bit size */ 283 switch (params_format(params)) { 284 case SNDRV_PCM_FORMAT_S16_LE: 285 word_len = 3; 286 break; 287 case SNDRV_PCM_FORMAT_S20_3LE: 288 word_len = 1; 289 break; 290 case SNDRV_PCM_FORMAT_S24_LE: 291 case SNDRV_PCM_FORMAT_S32_LE: 292 word_len = 0; 293 break; 294 } 295 296 switch (ad193x->sysclk) { 297 case 12288000: 298 master_rate = AD193X_PLL_INPUT_256; 299 break; 300 case 18432000: 301 master_rate = AD193X_PLL_INPUT_384; 302 break; 303 case 24576000: 304 master_rate = AD193X_PLL_INPUT_512; 305 break; 306 case 36864000: 307 master_rate = AD193X_PLL_INPUT_768; 308 break; 309 } 310 311 reg = snd_soc_read(codec, AD193X_PLL_CLK_CTRL0); 312 reg = (reg & AD193X_PLL_INPUT_MASK) | master_rate; 313 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg); 314 315 reg = snd_soc_read(codec, AD193X_DAC_CTRL2); 316 reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | word_len; 317 snd_soc_write(codec, AD193X_DAC_CTRL2, reg); 318 319 reg = snd_soc_read(codec, AD193X_ADC_CTRL1); 320 reg = (reg & (~AD193X_ADC_WORD_LEN_MASK)) | word_len; 321 snd_soc_write(codec, AD193X_ADC_CTRL1, reg); 322 323 return 0; 324} 325 326static int ad193x_bus_probe(struct device *dev, void *ctrl_data, int bus_type) 327{ 328 struct snd_soc_codec *codec; 329 struct ad193x_priv *ad193x; 330 int ret; 331 332 if (ad193x_codec) { 333 dev_err(dev, "Another ad193x is registered\n"); 334 return -EINVAL; 335 } 336 337 ad193x = kzalloc(sizeof(struct ad193x_priv), GFP_KERNEL); 338 if (ad193x == NULL) 339 return -ENOMEM; 340 341 dev_set_drvdata(dev, ad193x); 342 343 codec = &ad193x->codec; 344 mutex_init(&codec->mutex); 345 codec->control_data = ctrl_data; 346 codec->dev = dev; 347 snd_soc_codec_set_drvdata(codec, ad193x); 348 codec->reg_cache = ad193x->reg_cache; 349 codec->reg_cache_size = AD193X_NUM_REGS; 350 codec->name = "AD193X"; 351 codec->owner = THIS_MODULE; 352 codec->dai = &ad193x_dai; 353 codec->num_dai = 1; 354 INIT_LIST_HEAD(&codec->dapm_widgets); 355 INIT_LIST_HEAD(&codec->dapm_paths); 356 357 ad193x_dai.dev = codec->dev; 358 ad193x_codec = codec; 359 360 memcpy(codec->reg_cache, ad193x_reg, AD193X_NUM_REGS); 361 362 if (bus_type == SND_SOC_I2C) 363 ret = snd_soc_codec_set_cache_io(codec, 8, 8, bus_type); 364 else 365 ret = snd_soc_codec_set_cache_io(codec, 16, 8, bus_type); 366 if (ret < 0) { 367 dev_err(codec->dev, "failed to set cache I/O: %d\n", 368 ret); 369 kfree(ad193x); 370 return ret; 371 } 372 373 /* default setting for ad193x */ 374 375 /* unmute dac channels */ 376 snd_soc_write(codec, AD193X_DAC_CHNL_MUTE, 0x0); 377 /* de-emphasis: 48kHz, powedown dac */ 378 snd_soc_write(codec, AD193X_DAC_CTRL2, 0x1A); 379 /* powerdown dac, dac in tdm mode */ 380 snd_soc_write(codec, AD193X_DAC_CTRL0, 0x41); 381 /* high-pass filter enable */ 382 snd_soc_write(codec, AD193X_ADC_CTRL0, 0x3); 383 /* sata delay=1, adc aux mode */ 384 snd_soc_write(codec, AD193X_ADC_CTRL1, 0x43); 385 /* pll input: mclki/xi */ 386 snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, 0x99); /* mclk=24.576Mhz: 0x9D; mclk=12.288Mhz: 0x99 */ 387 snd_soc_write(codec, AD193X_PLL_CLK_CTRL1, 0x04); 388 ad193x->sysclk = 12288000; 389 390 ret = snd_soc_register_codec(codec); 391 if (ret != 0) { 392 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 393 kfree(ad193x); 394 return ret; 395 } 396 397 ret = snd_soc_register_dai(&ad193x_dai); 398 if (ret != 0) { 399 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 400 snd_soc_unregister_codec(codec); 401 kfree(ad193x); 402 return ret; 403 } 404 405 return 0; 406} 407 408static int ad193x_bus_remove(struct device *dev) 409{ 410 struct ad193x_priv *ad193x = dev_get_drvdata(dev); 411 412 snd_soc_unregister_dai(&ad193x_dai); 413 snd_soc_unregister_codec(&ad193x->codec); 414 kfree(ad193x); 415 ad193x_codec = NULL; 416 417 return 0; 418} 419 420static struct snd_soc_dai_ops ad193x_dai_ops = { 421 .hw_params = ad193x_hw_params, 422 .digital_mute = ad193x_mute, 423 .set_tdm_slot = ad193x_set_tdm_slot, 424 .set_sysclk = ad193x_set_dai_sysclk, 425 .set_fmt = ad193x_set_dai_fmt, 426}; 427 428/* codec DAI instance */ 429struct snd_soc_dai ad193x_dai = { 430 .name = "AD193X", 431 .playback = { 432 .stream_name = "Playback", 433 .channels_min = 2, 434 .channels_max = 8, 435 .rates = SNDRV_PCM_RATE_48000, 436 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | 437 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, 438 }, 439 .capture = { 440 .stream_name = "Capture", 441 .channels_min = 2, 442 .channels_max = 4, 443 .rates = SNDRV_PCM_RATE_48000, 444 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | 445 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, 446 }, 447 .ops = &ad193x_dai_ops, 448}; 449EXPORT_SYMBOL_GPL(ad193x_dai); 450 451static int ad193x_probe(struct platform_device *pdev) 452{ 453 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 454 struct snd_soc_codec *codec; 455 int ret = 0; 456 457 if (ad193x_codec == NULL) { 458 dev_err(&pdev->dev, "Codec device not registered\n"); 459 return -ENODEV; 460 } 461 462 socdev->card->codec = ad193x_codec; 463 codec = ad193x_codec; 464 465 /* register pcms */ 466 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 467 if (ret < 0) { 468 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 469 goto pcm_err; 470 } 471 472 snd_soc_add_controls(codec, ad193x_snd_controls, 473 ARRAY_SIZE(ad193x_snd_controls)); 474 snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets, 475 ARRAY_SIZE(ad193x_dapm_widgets)); 476 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 477 478pcm_err: 479 return ret; 480} 481 482/* power down chip */ 483static int ad193x_remove(struct platform_device *pdev) 484{ 485 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 486 487 snd_soc_free_pcms(socdev); 488 snd_soc_dapm_free(socdev); 489 490 return 0; 491} 492 493struct snd_soc_codec_device soc_codec_dev_ad193x = { 494 .probe = ad193x_probe, 495 .remove = ad193x_remove, 496}; 497EXPORT_SYMBOL_GPL(soc_codec_dev_ad193x); 498 499#if defined(CONFIG_SPI_MASTER) 500static int __devinit ad193x_spi_probe(struct spi_device *spi) 501{ 502 return ad193x_bus_probe(&spi->dev, spi, SND_SOC_SPI); 503} 504 505static int __devexit ad193x_spi_remove(struct spi_device *spi) 506{ 507 return ad193x_bus_remove(&spi->dev); 508} 509 510static struct spi_driver ad193x_spi_driver = { 511 .driver = { 512 .name = "ad193x", 513 .owner = THIS_MODULE, 514 }, 515 .probe = ad193x_spi_probe, 516 .remove = __devexit_p(ad193x_spi_remove), 517}; 518#endif 519 520#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 521static const struct i2c_device_id ad193x_id[] = { 522 { "ad1936", 0 }, 523 { "ad1937", 0 }, 524 { } 525}; 526MODULE_DEVICE_TABLE(i2c, ad193x_id); 527 528static int __devinit ad193x_i2c_probe(struct i2c_client *client, 529 const struct i2c_device_id *id) 530{ 531 return ad193x_bus_probe(&client->dev, client, SND_SOC_I2C); 532} 533 534static int __devexit ad193x_i2c_remove(struct i2c_client *client) 535{ 536 return ad193x_bus_remove(&client->dev); 537} 538 539static struct i2c_driver ad193x_i2c_driver = { 540 .driver = { 541 .name = "ad193x", 542 }, 543 .probe = ad193x_i2c_probe, 544 .remove = __devexit_p(ad193x_i2c_remove), 545 .id_table = ad193x_id, 546}; 547#endif 548 549static int __init ad193x_modinit(void) 550{ 551 int ret; 552 553#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 554 ret = i2c_add_driver(&ad193x_i2c_driver); 555 if (ret != 0) { 556 printk(KERN_ERR "Failed to register AD193X I2C driver: %d\n", 557 ret); 558 } 559#endif 560 561#if defined(CONFIG_SPI_MASTER) 562 ret = spi_register_driver(&ad193x_spi_driver); 563 if (ret != 0) { 564 printk(KERN_ERR "Failed to register AD193X SPI driver: %d\n", 565 ret); 566 } 567#endif 568 return ret; 569} 570module_init(ad193x_modinit); 571 572static void __exit ad193x_modexit(void) 573{ 574#if defined(CONFIG_SPI_MASTER) 575 spi_unregister_driver(&ad193x_spi_driver); 576#endif 577 578#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 579 i2c_del_driver(&ad193x_i2c_driver); 580#endif 581} 582module_exit(ad193x_modexit); 583 584MODULE_DESCRIPTION("ASoC ad193x driver"); 585MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 586MODULE_LICENSE("GPL"); 587