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