1 /* 2 * cs42l51.c 3 * 4 * ASoC Driver for Cirrus Logic CS42L51 codecs 5 * 6 * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com> 7 * 8 * Based on cs4270.c - Copyright (c) Freescale Semiconductor 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * For now: 20 * - Only I2C is support. Not SPI 21 * - master mode *NOT* supported 22 */ 23 24 #include <linux/module.h> 25 #include <linux/platform_device.h> 26 #include <linux/slab.h> 27 #include <sound/core.h> 28 #include <sound/soc.h> 29 #include <sound/soc-dapm.h> 30 #include <sound/tlv.h> 31 #include <sound/initval.h> 32 #include <sound/pcm_params.h> 33 #include <sound/pcm.h> 34 #include <linux/i2c.h> 35 36 #include "cs42l51.h" 37 38 enum master_slave_mode { 39 MODE_SLAVE, 40 MODE_SLAVE_AUTO, 41 MODE_MASTER, 42 }; 43 44 struct cs42l51_private { 45 enum snd_soc_control_type control_type; 46 void *control_data; 47 unsigned int mclk; 48 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 49 enum master_slave_mode func; 50 u8 reg_cache[CS42L51_NUMREGS]; 51 }; 52 53 #define CS42L51_FORMATS ( \ 54 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ 55 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ 56 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ 57 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) 58 59 static int cs42l51_fill_cache(struct snd_soc_codec *codec) 60 { 61 u8 *cache = codec->reg_cache + 1; 62 struct i2c_client *i2c_client = codec->control_data; 63 s32 length; 64 65 length = i2c_smbus_read_i2c_block_data(i2c_client, 66 CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache); 67 if (length != CS42L51_NUMREGS) { 68 dev_err(&i2c_client->dev, 69 "I2C read failure, addr=0x%x (ret=%d vs %d)\n", 70 i2c_client->addr, length, CS42L51_NUMREGS); 71 return -EIO; 72 } 73 74 return 0; 75 } 76 77 static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, 78 struct snd_ctl_elem_value *ucontrol) 79 { 80 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 81 unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3; 82 83 switch (value) { 84 default: 85 case 0: 86 ucontrol->value.integer.value[0] = 0; 87 break; 88 /* same value : (L+R)/2 and (R+L)/2 */ 89 case 1: 90 case 2: 91 ucontrol->value.integer.value[0] = 1; 92 break; 93 case 3: 94 ucontrol->value.integer.value[0] = 2; 95 break; 96 } 97 98 return 0; 99 } 100 101 #define CHAN_MIX_NORMAL 0x00 102 #define CHAN_MIX_BOTH 0x55 103 #define CHAN_MIX_SWAP 0xFF 104 105 static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol, 106 struct snd_ctl_elem_value *ucontrol) 107 { 108 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 109 unsigned char val; 110 111 switch (ucontrol->value.integer.value[0]) { 112 default: 113 case 0: 114 val = CHAN_MIX_NORMAL; 115 break; 116 case 1: 117 val = CHAN_MIX_BOTH; 118 break; 119 case 2: 120 val = CHAN_MIX_SWAP; 121 break; 122 } 123 124 snd_soc_write(codec, CS42L51_PCM_MIXER, val); 125 126 return 1; 127 } 128 129 static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0); 130 static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0); 131 /* This is a lie. after -102 db, it stays at -102 */ 132 /* maybe a range would be better */ 133 static const DECLARE_TLV_DB_SCALE(aout_tlv, -11550, 50, 0); 134 135 static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0); 136 static const char *chan_mix[] = { 137 "L R", 138 "L+R", 139 "R L", 140 }; 141 142 static const struct soc_enum cs42l51_chan_mix = 143 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(chan_mix), chan_mix); 144 145 static const struct snd_kcontrol_new cs42l51_snd_controls[] = { 146 SOC_DOUBLE_R_SX_TLV("PCM Playback Volume", 147 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 148 7, 0xffffff99, 0x18, adc_pcm_tlv), 149 SOC_DOUBLE_R("PCM Playback Switch", 150 CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1), 151 SOC_DOUBLE_R_SX_TLV("Analog Playback Volume", 152 CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL, 153 8, 0xffffff19, 0x18, aout_tlv), 154 SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", 155 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 156 7, 0xffffff99, 0x18, adc_pcm_tlv), 157 SOC_DOUBLE_R("ADC Mixer Switch", 158 CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1), 159 SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0), 160 SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0), 161 SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0), 162 SOC_SINGLE("Zero Cross Switch", CS42L51_DAC_CTL, 0, 0, 0), 163 SOC_DOUBLE_TLV("Mic Boost Volume", 164 CS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv), 165 SOC_SINGLE_TLV("Bass Volume", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv), 166 SOC_SINGLE_TLV("Treble Volume", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv), 167 SOC_ENUM_EXT("PCM channel mixer", 168 cs42l51_chan_mix, 169 cs42l51_get_chan_mix, cs42l51_set_chan_mix), 170 }; 171 172 /* 173 * to power down, one must: 174 * 1.) Enable the PDN bit 175 * 2.) enable power-down for the select channels 176 * 3.) disable the PDN bit. 177 */ 178 static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w, 179 struct snd_kcontrol *kcontrol, int event) 180 { 181 unsigned long value; 182 183 value = snd_soc_read(w->codec, CS42L51_POWER_CTL1); 184 value &= ~CS42L51_POWER_CTL1_PDN; 185 186 switch (event) { 187 case SND_SOC_DAPM_PRE_PMD: 188 value |= CS42L51_POWER_CTL1_PDN; 189 break; 190 default: 191 case SND_SOC_DAPM_POST_PMD: 192 break; 193 } 194 snd_soc_update_bits(w->codec, CS42L51_POWER_CTL1, 195 CS42L51_POWER_CTL1_PDN, value); 196 197 return 0; 198 } 199 200 static const char *cs42l51_dac_names[] = {"Direct PCM", 201 "DSP PCM", "ADC"}; 202 static const struct soc_enum cs42l51_dac_mux_enum = 203 SOC_ENUM_SINGLE(CS42L51_DAC_CTL, 6, 3, cs42l51_dac_names); 204 static const struct snd_kcontrol_new cs42l51_dac_mux_controls = 205 SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum); 206 207 static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left", 208 "MIC Left", "MIC+preamp Left"}; 209 static const struct soc_enum cs42l51_adcl_mux_enum = 210 SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 4, 4, cs42l51_adcl_names); 211 static const struct snd_kcontrol_new cs42l51_adcl_mux_controls = 212 SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum); 213 214 static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right", 215 "MIC Right", "MIC+preamp Right"}; 216 static const struct soc_enum cs42l51_adcr_mux_enum = 217 SOC_ENUM_SINGLE(CS42L51_ADC_INPUT, 6, 4, cs42l51_adcr_names); 218 static const struct snd_kcontrol_new cs42l51_adcr_mux_controls = 219 SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum); 220 221 static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = { 222 SND_SOC_DAPM_MICBIAS("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1), 223 SND_SOC_DAPM_PGA_E("Left PGA", CS42L51_POWER_CTL1, 3, 1, NULL, 0, 224 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 225 SND_SOC_DAPM_PGA_E("Right PGA", CS42L51_POWER_CTL1, 4, 1, NULL, 0, 226 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 227 SND_SOC_DAPM_ADC_E("Left ADC", "Left HiFi Capture", 228 CS42L51_POWER_CTL1, 1, 1, 229 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 230 SND_SOC_DAPM_ADC_E("Right ADC", "Right HiFi Capture", 231 CS42L51_POWER_CTL1, 2, 1, 232 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 233 SND_SOC_DAPM_DAC_E("Left DAC", "Left HiFi Playback", 234 CS42L51_POWER_CTL1, 5, 1, 235 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 236 SND_SOC_DAPM_DAC_E("Right DAC", "Right HiFi Playback", 237 CS42L51_POWER_CTL1, 6, 1, 238 cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD), 239 240 /* analog/mic */ 241 SND_SOC_DAPM_INPUT("AIN1L"), 242 SND_SOC_DAPM_INPUT("AIN1R"), 243 SND_SOC_DAPM_INPUT("AIN2L"), 244 SND_SOC_DAPM_INPUT("AIN2R"), 245 SND_SOC_DAPM_INPUT("MICL"), 246 SND_SOC_DAPM_INPUT("MICR"), 247 248 SND_SOC_DAPM_MIXER("Mic Preamp Left", 249 CS42L51_MIC_POWER_CTL, 2, 1, NULL, 0), 250 SND_SOC_DAPM_MIXER("Mic Preamp Right", 251 CS42L51_MIC_POWER_CTL, 3, 1, NULL, 0), 252 253 /* HP */ 254 SND_SOC_DAPM_OUTPUT("HPL"), 255 SND_SOC_DAPM_OUTPUT("HPR"), 256 257 /* mux */ 258 SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0, 259 &cs42l51_dac_mux_controls), 260 SND_SOC_DAPM_MUX("PGA-ADC Mux Left", SND_SOC_NOPM, 0, 0, 261 &cs42l51_adcl_mux_controls), 262 SND_SOC_DAPM_MUX("PGA-ADC Mux Right", SND_SOC_NOPM, 0, 0, 263 &cs42l51_adcr_mux_controls), 264 }; 265 266 static const struct snd_soc_dapm_route cs42l51_routes[] = { 267 {"HPL", NULL, "Left DAC"}, 268 {"HPR", NULL, "Right DAC"}, 269 270 {"Left ADC", NULL, "Left PGA"}, 271 {"Right ADC", NULL, "Right PGA"}, 272 273 {"Mic Preamp Left", NULL, "MICL"}, 274 {"Mic Preamp Right", NULL, "MICR"}, 275 276 {"PGA-ADC Mux Left", "AIN1 Left", "AIN1L" }, 277 {"PGA-ADC Mux Left", "AIN2 Left", "AIN2L" }, 278 {"PGA-ADC Mux Left", "MIC Left", "MICL" }, 279 {"PGA-ADC Mux Left", "MIC+preamp Left", "Mic Preamp Left" }, 280 {"PGA-ADC Mux Right", "AIN1 Right", "AIN1R" }, 281 {"PGA-ADC Mux Right", "AIN2 Right", "AIN2R" }, 282 {"PGA-ADC Mux Right", "MIC Right", "MICR" }, 283 {"PGA-ADC Mux Right", "MIC+preamp Right", "Mic Preamp Right" }, 284 285 {"Left PGA", NULL, "PGA-ADC Mux Left"}, 286 {"Right PGA", NULL, "PGA-ADC Mux Right"}, 287 }; 288 289 static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai, 290 unsigned int format) 291 { 292 struct snd_soc_codec *codec = codec_dai->codec; 293 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 294 int ret = 0; 295 296 switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { 297 case SND_SOC_DAIFMT_I2S: 298 case SND_SOC_DAIFMT_LEFT_J: 299 case SND_SOC_DAIFMT_RIGHT_J: 300 cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK; 301 break; 302 default: 303 dev_err(codec->dev, "invalid DAI format\n"); 304 ret = -EINVAL; 305 } 306 307 switch (format & SND_SOC_DAIFMT_MASTER_MASK) { 308 case SND_SOC_DAIFMT_CBM_CFM: 309 cs42l51->func = MODE_MASTER; 310 break; 311 case SND_SOC_DAIFMT_CBS_CFS: 312 cs42l51->func = MODE_SLAVE_AUTO; 313 break; 314 default: 315 ret = -EINVAL; 316 break; 317 } 318 319 return ret; 320 } 321 322 struct cs42l51_ratios { 323 unsigned int ratio; 324 unsigned char speed_mode; 325 unsigned char mclk; 326 }; 327 328 static struct cs42l51_ratios slave_ratios[] = { 329 { 512, CS42L51_QSM_MODE, 0 }, { 768, CS42L51_QSM_MODE, 0 }, 330 { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 }, 331 { 2048, CS42L51_QSM_MODE, 0 }, { 3072, CS42L51_QSM_MODE, 0 }, 332 { 256, CS42L51_HSM_MODE, 0 }, { 384, CS42L51_HSM_MODE, 0 }, 333 { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 }, 334 { 1024, CS42L51_HSM_MODE, 0 }, { 1536, CS42L51_HSM_MODE, 0 }, 335 { 128, CS42L51_SSM_MODE, 0 }, { 192, CS42L51_SSM_MODE, 0 }, 336 { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 }, 337 { 512, CS42L51_SSM_MODE, 0 }, { 768, CS42L51_SSM_MODE, 0 }, 338 { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 }, 339 { 256, CS42L51_DSM_MODE, 0 }, { 384, CS42L51_DSM_MODE, 0 }, 340 }; 341 342 static struct cs42l51_ratios slave_auto_ratios[] = { 343 { 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 }, 344 { 2048, CS42L51_QSM_MODE, 1 }, { 3072, CS42L51_QSM_MODE, 1 }, 345 { 512, CS42L51_HSM_MODE, 0 }, { 768, CS42L51_HSM_MODE, 0 }, 346 { 1024, CS42L51_HSM_MODE, 1 }, { 1536, CS42L51_HSM_MODE, 1 }, 347 { 256, CS42L51_SSM_MODE, 0 }, { 384, CS42L51_SSM_MODE, 0 }, 348 { 512, CS42L51_SSM_MODE, 1 }, { 768, CS42L51_SSM_MODE, 1 }, 349 { 128, CS42L51_DSM_MODE, 0 }, { 192, CS42L51_DSM_MODE, 0 }, 350 { 256, CS42L51_DSM_MODE, 1 }, { 384, CS42L51_DSM_MODE, 1 }, 351 }; 352 353 static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai, 354 int clk_id, unsigned int freq, int dir) 355 { 356 struct snd_soc_codec *codec = codec_dai->codec; 357 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 358 359 cs42l51->mclk = freq; 360 return 0; 361 } 362 363 static int cs42l51_hw_params(struct snd_pcm_substream *substream, 364 struct snd_pcm_hw_params *params, 365 struct snd_soc_dai *dai) 366 { 367 struct snd_soc_pcm_runtime *rtd = substream->private_data; 368 struct snd_soc_codec *codec = rtd->codec; 369 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 370 int ret; 371 unsigned int i; 372 unsigned int rate; 373 unsigned int ratio; 374 struct cs42l51_ratios *ratios = NULL; 375 int nr_ratios = 0; 376 int intf_ctl, power_ctl, fmt; 377 378 switch (cs42l51->func) { 379 case MODE_MASTER: 380 return -EINVAL; 381 case MODE_SLAVE: 382 ratios = slave_ratios; 383 nr_ratios = ARRAY_SIZE(slave_ratios); 384 break; 385 case MODE_SLAVE_AUTO: 386 ratios = slave_auto_ratios; 387 nr_ratios = ARRAY_SIZE(slave_auto_ratios); 388 break; 389 } 390 391 /* Figure out which MCLK/LRCK ratio to use */ 392 rate = params_rate(params); /* Sampling rate, in Hz */ 393 ratio = cs42l51->mclk / rate; /* MCLK/LRCK ratio */ 394 for (i = 0; i < nr_ratios; i++) { 395 if (ratios[i].ratio == ratio) 396 break; 397 } 398 399 if (i == nr_ratios) { 400 /* We did not find a matching ratio */ 401 dev_err(codec->dev, "could not find matching ratio\n"); 402 return -EINVAL; 403 } 404 405 intf_ctl = snd_soc_read(codec, CS42L51_INTF_CTL); 406 power_ctl = snd_soc_read(codec, CS42L51_MIC_POWER_CTL); 407 408 intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S 409 | CS42L51_INTF_CTL_DAC_FORMAT(7)); 410 power_ctl &= ~(CS42L51_MIC_POWER_CTL_SPEED(3) 411 | CS42L51_MIC_POWER_CTL_MCLK_DIV2); 412 413 switch (cs42l51->func) { 414 case MODE_MASTER: 415 intf_ctl |= CS42L51_INTF_CTL_MASTER; 416 power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode); 417 break; 418 case MODE_SLAVE: 419 power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode); 420 break; 421 case MODE_SLAVE_AUTO: 422 power_ctl |= CS42L51_MIC_POWER_CTL_AUTO; 423 break; 424 } 425 426 switch (cs42l51->audio_mode) { 427 case SND_SOC_DAIFMT_I2S: 428 intf_ctl |= CS42L51_INTF_CTL_ADC_I2S; 429 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_I2S); 430 break; 431 case SND_SOC_DAIFMT_LEFT_J: 432 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24); 433 break; 434 case SND_SOC_DAIFMT_RIGHT_J: 435 switch (params_format(params)) { 436 case SNDRV_PCM_FORMAT_S16_LE: 437 case SNDRV_PCM_FORMAT_S16_BE: 438 fmt = CS42L51_DAC_DIF_RJ16; 439 break; 440 case SNDRV_PCM_FORMAT_S18_3LE: 441 case SNDRV_PCM_FORMAT_S18_3BE: 442 fmt = CS42L51_DAC_DIF_RJ18; 443 break; 444 case SNDRV_PCM_FORMAT_S20_3LE: 445 case SNDRV_PCM_FORMAT_S20_3BE: 446 fmt = CS42L51_DAC_DIF_RJ20; 447 break; 448 case SNDRV_PCM_FORMAT_S24_LE: 449 case SNDRV_PCM_FORMAT_S24_BE: 450 fmt = CS42L51_DAC_DIF_RJ24; 451 break; 452 default: 453 dev_err(codec->dev, "unknown format\n"); 454 return -EINVAL; 455 } 456 intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt); 457 break; 458 default: 459 dev_err(codec->dev, "unknown format\n"); 460 return -EINVAL; 461 } 462 463 if (ratios[i].mclk) 464 power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2; 465 466 ret = snd_soc_write(codec, CS42L51_INTF_CTL, intf_ctl); 467 if (ret < 0) 468 return ret; 469 470 ret = snd_soc_write(codec, CS42L51_MIC_POWER_CTL, power_ctl); 471 if (ret < 0) 472 return ret; 473 474 return 0; 475 } 476 477 static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute) 478 { 479 struct snd_soc_codec *codec = dai->codec; 480 int reg; 481 int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE; 482 483 reg = snd_soc_read(codec, CS42L51_DAC_OUT_CTL); 484 485 if (mute) 486 reg |= mask; 487 else 488 reg &= ~mask; 489 490 return snd_soc_write(codec, CS42L51_DAC_OUT_CTL, reg); 491 } 492 493 static struct snd_soc_dai_ops cs42l51_dai_ops = { 494 .hw_params = cs42l51_hw_params, 495 .set_sysclk = cs42l51_set_dai_sysclk, 496 .set_fmt = cs42l51_set_dai_fmt, 497 .digital_mute = cs42l51_dai_mute, 498 }; 499 500 static struct snd_soc_dai_driver cs42l51_dai = { 501 .name = "cs42l51-hifi", 502 .playback = { 503 .stream_name = "Playback", 504 .channels_min = 1, 505 .channels_max = 2, 506 .rates = SNDRV_PCM_RATE_8000_96000, 507 .formats = CS42L51_FORMATS, 508 }, 509 .capture = { 510 .stream_name = "Capture", 511 .channels_min = 1, 512 .channels_max = 2, 513 .rates = SNDRV_PCM_RATE_8000_96000, 514 .formats = CS42L51_FORMATS, 515 }, 516 .ops = &cs42l51_dai_ops, 517 }; 518 519 static int cs42l51_probe(struct snd_soc_codec *codec) 520 { 521 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 522 int ret, reg; 523 524 codec->control_data = cs42l51->control_data; 525 526 ret = cs42l51_fill_cache(codec); 527 if (ret < 0) { 528 dev_err(codec->dev, "failed to fill register cache\n"); 529 return ret; 530 } 531 532 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type); 533 if (ret < 0) { 534 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 535 return ret; 536 } 537 538 /* 539 * DAC configuration 540 * - Use signal processor 541 * - auto mute 542 * - vol changes immediate 543 * - no de-emphasize 544 */ 545 reg = CS42L51_DAC_CTL_DATA_SEL(1) 546 | CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0); 547 ret = snd_soc_write(codec, CS42L51_DAC_CTL, reg); 548 if (ret < 0) 549 return ret; 550 551 snd_soc_add_controls(codec, cs42l51_snd_controls, 552 ARRAY_SIZE(cs42l51_snd_controls)); 553 snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets, 554 ARRAY_SIZE(cs42l51_dapm_widgets)); 555 snd_soc_dapm_add_routes(codec, cs42l51_routes, 556 ARRAY_SIZE(cs42l51_routes)); 557 558 return 0; 559 } 560 561 static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { 562 .probe = cs42l51_probe, 563 .reg_cache_size = CS42L51_NUMREGS, 564 .reg_word_size = sizeof(u8), 565 }; 566 567 static int cs42l51_i2c_probe(struct i2c_client *i2c_client, 568 const struct i2c_device_id *id) 569 { 570 struct cs42l51_private *cs42l51; 571 int ret; 572 573 /* Verify that we have a CS42L51 */ 574 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID); 575 if (ret < 0) { 576 dev_err(&i2c_client->dev, "failed to read I2C\n"); 577 goto error; 578 } 579 580 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && 581 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { 582 dev_err(&i2c_client->dev, "Invalid chip id\n"); 583 ret = -ENODEV; 584 goto error; 585 } 586 587 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", 588 ret & 7); 589 590 cs42l51 = kzalloc(sizeof(struct cs42l51_private), GFP_KERNEL); 591 if (!cs42l51) { 592 dev_err(&i2c_client->dev, "could not allocate codec\n"); 593 return -ENOMEM; 594 } 595 596 i2c_set_clientdata(i2c_client, cs42l51); 597 cs42l51->control_data = i2c_client; 598 cs42l51->control_type = SND_SOC_I2C; 599 600 ret = snd_soc_register_codec(&i2c_client->dev, 601 &soc_codec_device_cs42l51, &cs42l51_dai, 1); 602 if (ret < 0) 603 kfree(cs42l51); 604 error: 605 return ret; 606 } 607 608 static int cs42l51_i2c_remove(struct i2c_client *client) 609 { 610 struct cs42l51_private *cs42l51 = i2c_get_clientdata(client); 611 612 snd_soc_unregister_codec(&client->dev); 613 kfree(cs42l51); 614 return 0; 615 } 616 617 static const struct i2c_device_id cs42l51_id[] = { 618 {"cs42l51", 0}, 619 {} 620 }; 621 MODULE_DEVICE_TABLE(i2c, cs42l51_id); 622 623 static struct i2c_driver cs42l51_i2c_driver = { 624 .driver = { 625 .name = "cs42l51-codec", 626 .owner = THIS_MODULE, 627 }, 628 .id_table = cs42l51_id, 629 .probe = cs42l51_i2c_probe, 630 .remove = cs42l51_i2c_remove, 631 }; 632 633 static int __init cs42l51_init(void) 634 { 635 int ret; 636 637 ret = i2c_add_driver(&cs42l51_i2c_driver); 638 if (ret != 0) { 639 printk(KERN_ERR "%s: can't add i2c driver\n", __func__); 640 return ret; 641 } 642 return 0; 643 } 644 module_init(cs42l51_init); 645 646 static void __exit cs42l51_exit(void) 647 { 648 i2c_del_driver(&cs42l51_i2c_driver); 649 } 650 module_exit(cs42l51_exit); 651 652 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); 653 MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); 654 MODULE_LICENSE("GPL"); 655