diff options
Diffstat (limited to 'sound/soc/codecs/cs4270.c')
| -rw-r--r-- | sound/soc/codecs/cs4270.c | 516 |
1 files changed, 165 insertions, 351 deletions
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 30d949239def..0206a17d7283 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
| @@ -31,8 +31,6 @@ | |||
| 31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
| 32 | #include <linux/regulator/consumer.h> | 32 | #include <linux/regulator/consumer.h> |
| 33 | 33 | ||
| 34 | #include "cs4270.h" | ||
| 35 | |||
| 36 | /* | 34 | /* |
| 37 | * The codec isn't really big-endian or little-endian, since the I2S | 35 | * The codec isn't really big-endian or little-endian, since the I2S |
| 38 | * interface requires data to be sent serially with the MSbit first. | 36 | * interface requires data to be sent serially with the MSbit first. |
| @@ -108,14 +106,29 @@ | |||
| 108 | #define CS4270_MUTE_DAC_A 0x01 | 106 | #define CS4270_MUTE_DAC_A 0x01 |
| 109 | #define CS4270_MUTE_DAC_B 0x02 | 107 | #define CS4270_MUTE_DAC_B 0x02 |
| 110 | 108 | ||
| 109 | /* Power-on default values for the registers | ||
| 110 | * | ||
| 111 | * This array contains the power-on default values of the registers, with the | ||
| 112 | * exception of the "CHIPID" register (01h). The lower four bits of that | ||
| 113 | * register contain the hardware revision, so it is treated as volatile. | ||
| 114 | * | ||
| 115 | * Also note that on the CS4270, the first readable register is 1, but ASoC | ||
| 116 | * assumes the first register is 0. Therfore, the array must have an entry for | ||
| 117 | * register 0, but we use cs4270_reg_is_readable() to tell ASoC that it can't | ||
| 118 | * be read. | ||
| 119 | */ | ||
| 120 | static const u8 cs4270_default_reg_cache[CS4270_LASTREG + 1] = { | ||
| 121 | 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x20, 0x00, 0x00 | ||
| 122 | }; | ||
| 123 | |||
| 111 | static const char *supply_names[] = { | 124 | static const char *supply_names[] = { |
| 112 | "va", "vd", "vlc" | 125 | "va", "vd", "vlc" |
| 113 | }; | 126 | }; |
| 114 | 127 | ||
| 115 | /* Private data for the CS4270 */ | 128 | /* Private data for the CS4270 */ |
| 116 | struct cs4270_private { | 129 | struct cs4270_private { |
| 117 | struct snd_soc_codec codec; | 130 | enum snd_soc_control_type control_type; |
| 118 | u8 reg_cache[CS4270_NUMREGS]; | 131 | void *control_data; |
| 119 | unsigned int mclk; /* Input frequency of the MCLK pin */ | 132 | unsigned int mclk; /* Input frequency of the MCLK pin */ |
| 120 | unsigned int mode; /* The mode (I2S or left-justified) */ | 133 | unsigned int mode; /* The mode (I2S or left-justified) */ |
| 121 | unsigned int slave_mode; | 134 | unsigned int slave_mode; |
| @@ -180,6 +193,20 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = { | |||
| 180 | /* The number of MCLK/LRCK ratios supported by the CS4270 */ | 193 | /* The number of MCLK/LRCK ratios supported by the CS4270 */ |
| 181 | #define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) | 194 | #define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) |
| 182 | 195 | ||
| 196 | static int cs4270_reg_is_readable(struct snd_soc_codec *codec, unsigned int reg) | ||
| 197 | { | ||
| 198 | return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG); | ||
| 199 | } | ||
| 200 | |||
| 201 | static int cs4270_reg_is_volatile(struct snd_soc_codec *codec, unsigned int reg) | ||
| 202 | { | ||
| 203 | /* Unreadable registers are considered volatile */ | ||
| 204 | if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) | ||
| 205 | return 1; | ||
| 206 | |||
| 207 | return reg == CS4270_CHIPID; | ||
| 208 | } | ||
| 209 | |||
| 183 | /** | 210 | /** |
| 184 | * cs4270_set_dai_sysclk - determine the CS4270 samples rates. | 211 | * cs4270_set_dai_sysclk - determine the CS4270 samples rates. |
| 185 | * @codec_dai: the codec DAI | 212 | * @codec_dai: the codec DAI |
| @@ -212,44 +239,8 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
| 212 | { | 239 | { |
| 213 | struct snd_soc_codec *codec = codec_dai->codec; | 240 | struct snd_soc_codec *codec = codec_dai->codec; |
| 214 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 241 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
| 215 | unsigned int rates = 0; | ||
| 216 | unsigned int rate_min = -1; | ||
| 217 | unsigned int rate_max = 0; | ||
| 218 | unsigned int i; | ||
| 219 | 242 | ||
| 220 | cs4270->mclk = freq; | 243 | cs4270->mclk = freq; |
| 221 | |||
| 222 | if (cs4270->mclk) { | ||
| 223 | for (i = 0; i < NUM_MCLK_RATIOS; i++) { | ||
| 224 | unsigned int rate = freq / cs4270_mode_ratios[i].ratio; | ||
| 225 | rates |= snd_pcm_rate_to_rate_bit(rate); | ||
| 226 | if (rate < rate_min) | ||
| 227 | rate_min = rate; | ||
| 228 | if (rate > rate_max) | ||
| 229 | rate_max = rate; | ||
| 230 | } | ||
| 231 | /* FIXME: soc should support a rate list */ | ||
| 232 | rates &= ~SNDRV_PCM_RATE_KNOT; | ||
| 233 | |||
| 234 | if (!rates) { | ||
| 235 | dev_err(codec->dev, "could not find a valid sample rate\n"); | ||
| 236 | return -EINVAL; | ||
| 237 | } | ||
| 238 | } else { | ||
| 239 | /* enable all possible rates */ | ||
| 240 | rates = SNDRV_PCM_RATE_8000_192000; | ||
| 241 | rate_min = 8000; | ||
| 242 | rate_max = 192000; | ||
| 243 | } | ||
| 244 | |||
| 245 | codec_dai->playback.rates = rates; | ||
| 246 | codec_dai->playback.rate_min = rate_min; | ||
| 247 | codec_dai->playback.rate_max = rate_max; | ||
| 248 | |||
| 249 | codec_dai->capture.rates = rates; | ||
| 250 | codec_dai->capture.rate_min = rate_min; | ||
| 251 | codec_dai->capture.rate_max = rate_max; | ||
| 252 | |||
| 253 | return 0; | 244 | return 0; |
| 254 | } | 245 | } |
| 255 | 246 | ||
| @@ -301,97 +292,6 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 301 | } | 292 | } |
| 302 | 293 | ||
| 303 | /** | 294 | /** |
| 304 | * cs4270_fill_cache - pre-fill the CS4270 register cache. | ||
| 305 | * @codec: the codec for this CS4270 | ||
| 306 | * | ||
| 307 | * This function fills in the CS4270 register cache by reading the register | ||
| 308 | * values from the hardware. | ||
| 309 | * | ||
| 310 | * This CS4270 registers are cached to avoid excessive I2C I/O operations. | ||
| 311 | * After the initial read to pre-fill the cache, the CS4270 never updates | ||
| 312 | * the register values, so we won't have a cache coherency problem. | ||
| 313 | * | ||
| 314 | * We use the auto-increment feature of the CS4270 to read all registers in | ||
| 315 | * one shot. | ||
| 316 | */ | ||
| 317 | static int cs4270_fill_cache(struct snd_soc_codec *codec) | ||
| 318 | { | ||
| 319 | u8 *cache = codec->reg_cache; | ||
| 320 | struct i2c_client *i2c_client = codec->control_data; | ||
| 321 | s32 length; | ||
| 322 | |||
| 323 | length = i2c_smbus_read_i2c_block_data(i2c_client, | ||
| 324 | CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache); | ||
| 325 | |||
| 326 | if (length != CS4270_NUMREGS) { | ||
| 327 | dev_err(codec->dev, "i2c read failure, addr=0x%x\n", | ||
| 328 | i2c_client->addr); | ||
| 329 | return -EIO; | ||
| 330 | } | ||
| 331 | |||
| 332 | return 0; | ||
| 333 | } | ||
| 334 | |||
| 335 | /** | ||
| 336 | * cs4270_read_reg_cache - read from the CS4270 register cache. | ||
| 337 | * @codec: the codec for this CS4270 | ||
| 338 | * @reg: the register to read | ||
| 339 | * | ||
| 340 | * This function returns the value for a given register. It reads only from | ||
| 341 | * the register cache, not the hardware itself. | ||
| 342 | * | ||
| 343 | * This CS4270 registers are cached to avoid excessive I2C I/O operations. | ||
| 344 | * After the initial read to pre-fill the cache, the CS4270 never updates | ||
| 345 | * the register values, so we won't have a cache coherency problem. | ||
| 346 | */ | ||
| 347 | static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec, | ||
| 348 | unsigned int reg) | ||
| 349 | { | ||
| 350 | u8 *cache = codec->reg_cache; | ||
| 351 | |||
| 352 | if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) | ||
| 353 | return -EIO; | ||
| 354 | |||
| 355 | return cache[reg - CS4270_FIRSTREG]; | ||
| 356 | } | ||
| 357 | |||
| 358 | /** | ||
| 359 | * cs4270_i2c_write - write to a CS4270 register via the I2C bus. | ||
| 360 | * @codec: the codec for this CS4270 | ||
| 361 | * @reg: the register to write | ||
| 362 | * @value: the value to write to the register | ||
| 363 | * | ||
| 364 | * This function writes the given value to the given CS4270 register, and | ||
| 365 | * also updates the register cache. | ||
| 366 | * | ||
| 367 | * Note that we don't use the hw_write function pointer of snd_soc_codec. | ||
| 368 | * That's because it's too clunky: the hw_write_t prototype does not match | ||
| 369 | * i2c_smbus_write_byte_data(), and it's just another layer of overhead. | ||
| 370 | */ | ||
| 371 | static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 372 | unsigned int value) | ||
| 373 | { | ||
| 374 | u8 *cache = codec->reg_cache; | ||
| 375 | |||
| 376 | if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG)) | ||
| 377 | return -EIO; | ||
| 378 | |||
| 379 | /* Only perform an I2C operation if the new value is different */ | ||
| 380 | if (cache[reg - CS4270_FIRSTREG] != value) { | ||
| 381 | struct i2c_client *client = codec->control_data; | ||
| 382 | if (i2c_smbus_write_byte_data(client, reg, value)) { | ||
| 383 | dev_err(codec->dev, "i2c write failed\n"); | ||
| 384 | return -EIO; | ||
| 385 | } | ||
| 386 | |||
| 387 | /* We've written to the hardware, so update the cache */ | ||
| 388 | cache[reg - CS4270_FIRSTREG] = value; | ||
| 389 | } | ||
| 390 | |||
| 391 | return 0; | ||
| 392 | } | ||
| 393 | |||
| 394 | /** | ||
| 395 | * cs4270_hw_params - program the CS4270 with the given hardware parameters. | 295 | * cs4270_hw_params - program the CS4270 with the given hardware parameters. |
| 396 | * @substream: the audio stream | 296 | * @substream: the audio stream |
| 397 | * @params: the hardware parameters to set | 297 | * @params: the hardware parameters to set |
| @@ -410,8 +310,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, | |||
| 410 | struct snd_soc_dai *dai) | 310 | struct snd_soc_dai *dai) |
| 411 | { | 311 | { |
| 412 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 312 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 413 | struct snd_soc_device *socdev = rtd->socdev; | 313 | struct snd_soc_codec *codec = rtd->codec; |
| 414 | struct snd_soc_codec *codec = socdev->card->codec; | ||
| 415 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 314 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
| 416 | int ret; | 315 | int ret; |
| 417 | unsigned int i; | 316 | unsigned int i; |
| @@ -549,19 +448,6 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = { | |||
| 549 | snd_soc_get_volsw, cs4270_soc_put_mute), | 448 | snd_soc_get_volsw, cs4270_soc_put_mute), |
| 550 | }; | 449 | }; |
| 551 | 450 | ||
| 552 | /* | ||
| 553 | * cs4270_codec - global variable to store codec for the ASoC probe function | ||
| 554 | * | ||
| 555 | * If struct i2c_driver had a private_data field, we wouldn't need to use | ||
| 556 | * cs4270_codec. This is the only way to pass the codec structure from | ||
| 557 | * cs4270_i2c_probe() to cs4270_probe(). Unfortunately, there is no good | ||
| 558 | * way to synchronize these two functions. cs4270_i2c_probe() can be called | ||
| 559 | * multiple times before cs4270_probe() is called even once. So for now, we | ||
| 560 | * also only allow cs4270_i2c_probe() to be run once. That means that we do | ||
| 561 | * not support more than one cs4270 device in the system, at least for now. | ||
| 562 | */ | ||
| 563 | static struct snd_soc_codec *cs4270_codec; | ||
| 564 | |||
| 565 | static struct snd_soc_dai_ops cs4270_dai_ops = { | 451 | static struct snd_soc_dai_ops cs4270_dai_ops = { |
| 566 | .hw_params = cs4270_hw_params, | 452 | .hw_params = cs4270_hw_params, |
| 567 | .set_sysclk = cs4270_set_dai_sysclk, | 453 | .set_sysclk = cs4270_set_dai_sysclk, |
| @@ -569,25 +455,28 @@ static struct snd_soc_dai_ops cs4270_dai_ops = { | |||
| 569 | .digital_mute = cs4270_dai_mute, | 455 | .digital_mute = cs4270_dai_mute, |
| 570 | }; | 456 | }; |
| 571 | 457 | ||
| 572 | struct snd_soc_dai cs4270_dai = { | 458 | static struct snd_soc_dai_driver cs4270_dai = { |
| 573 | .name = "cs4270", | 459 | .name = "cs4270-hifi", |
| 574 | .playback = { | 460 | .playback = { |
| 575 | .stream_name = "Playback", | 461 | .stream_name = "Playback", |
| 576 | .channels_min = 1, | 462 | .channels_min = 1, |
| 577 | .channels_max = 2, | 463 | .channels_max = 2, |
| 578 | .rates = 0, | 464 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
| 465 | .rate_min = 4000, | ||
| 466 | .rate_max = 216000, | ||
| 579 | .formats = CS4270_FORMATS, | 467 | .formats = CS4270_FORMATS, |
| 580 | }, | 468 | }, |
| 581 | .capture = { | 469 | .capture = { |
| 582 | .stream_name = "Capture", | 470 | .stream_name = "Capture", |
| 583 | .channels_min = 1, | 471 | .channels_min = 1, |
| 584 | .channels_max = 2, | 472 | .channels_max = 2, |
| 585 | .rates = 0, | 473 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
| 474 | .rate_min = 4000, | ||
| 475 | .rate_max = 216000, | ||
| 586 | .formats = CS4270_FORMATS, | 476 | .formats = CS4270_FORMATS, |
| 587 | }, | 477 | }, |
| 588 | .ops = &cs4270_dai_ops, | 478 | .ops = &cs4270_dai_ops, |
| 589 | }; | 479 | }; |
| 590 | EXPORT_SYMBOL_GPL(cs4270_dai); | ||
| 591 | 480 | ||
| 592 | /** | 481 | /** |
| 593 | * cs4270_probe - ASoC probe function | 482 | * cs4270_probe - ASoC probe function |
| @@ -596,20 +485,42 @@ EXPORT_SYMBOL_GPL(cs4270_dai); | |||
| 596 | * This function is called when ASoC has all the pieces it needs to | 485 | * This function is called when ASoC has all the pieces it needs to |
| 597 | * instantiate a sound driver. | 486 | * instantiate a sound driver. |
| 598 | */ | 487 | */ |
| 599 | static int cs4270_probe(struct platform_device *pdev) | 488 | static int cs4270_probe(struct snd_soc_codec *codec) |
| 600 | { | 489 | { |
| 601 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
| 602 | struct snd_soc_codec *codec = cs4270_codec; | ||
| 603 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 490 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
| 604 | int i, ret; | 491 | int i, ret; |
| 605 | 492 | ||
| 606 | /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ | 493 | codec->control_data = cs4270->control_data; |
| 607 | socdev->card->codec = codec; | ||
| 608 | 494 | ||
| 609 | /* Register PCMs */ | 495 | /* Tell ASoC what kind of I/O to use to read the registers. ASoC will |
| 610 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 496 | * then do the I2C transactions itself. |
| 497 | */ | ||
| 498 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs4270->control_type); | ||
| 499 | if (ret < 0) { | ||
| 500 | dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret); | ||
| 501 | return ret; | ||
| 502 | } | ||
| 503 | |||
| 504 | /* Disable auto-mute. This feature appears to be buggy. In some | ||
| 505 | * situations, auto-mute will not deactivate when it should, so we want | ||
| 506 | * this feature disabled by default. An application (e.g. alsactl) can | ||
| 507 | * re-enabled it by using the controls. | ||
| 508 | */ | ||
| 509 | ret = snd_soc_update_bits(codec, CS4270_MUTE, CS4270_MUTE_AUTO, 0); | ||
| 510 | if (ret < 0) { | ||
| 511 | dev_err(codec->dev, "i2c write failed\n"); | ||
| 512 | return ret; | ||
| 513 | } | ||
| 514 | |||
| 515 | /* Disable automatic volume control. The hardware enables, and it | ||
| 516 | * causes volume change commands to be delayed, sometimes until after | ||
| 517 | * playback has started. An application (e.g. alsactl) can | ||
| 518 | * re-enabled it by using the controls. | ||
| 519 | */ | ||
| 520 | ret = snd_soc_update_bits(codec, CS4270_TRANS, | ||
| 521 | CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0); | ||
| 611 | if (ret < 0) { | 522 | if (ret < 0) { |
| 612 | dev_err(codec->dev, "failed to create pcms\n"); | 523 | dev_err(codec->dev, "i2c write failed\n"); |
| 613 | return ret; | 524 | return ret; |
| 614 | } | 525 | } |
| 615 | 526 | ||
| @@ -618,7 +529,7 @@ static int cs4270_probe(struct platform_device *pdev) | |||
| 618 | ARRAY_SIZE(cs4270_snd_controls)); | 529 | ARRAY_SIZE(cs4270_snd_controls)); |
| 619 | if (ret < 0) { | 530 | if (ret < 0) { |
| 620 | dev_err(codec->dev, "failed to add controls\n"); | 531 | dev_err(codec->dev, "failed to add controls\n"); |
| 621 | goto error_free_pcms; | 532 | return ret; |
| 622 | } | 533 | } |
| 623 | 534 | ||
| 624 | /* get the power supply regulators */ | 535 | /* get the power supply regulators */ |
| @@ -628,7 +539,7 @@ static int cs4270_probe(struct platform_device *pdev) | |||
| 628 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies), | 539 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies), |
| 629 | cs4270->supplies); | 540 | cs4270->supplies); |
| 630 | if (ret < 0) | 541 | if (ret < 0) |
| 631 | goto error_free_pcms; | 542 | return ret; |
| 632 | 543 | ||
| 633 | ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), | 544 | ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), |
| 634 | cs4270->supplies); | 545 | cs4270->supplies); |
| @@ -641,9 +552,6 @@ error_free_regulators: | |||
| 641 | regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), | 552 | regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), |
| 642 | cs4270->supplies); | 553 | cs4270->supplies); |
| 643 | 554 | ||
| 644 | error_free_pcms: | ||
| 645 | snd_soc_free_pcms(socdev); | ||
| 646 | |||
| 647 | return ret; | 555 | return ret; |
| 648 | } | 556 | } |
| 649 | 557 | ||
| @@ -653,19 +561,98 @@ error_free_pcms: | |||
| 653 | * | 561 | * |
| 654 | * This function is the counterpart to cs4270_probe(). | 562 | * This function is the counterpart to cs4270_probe(). |
| 655 | */ | 563 | */ |
| 656 | static int cs4270_remove(struct platform_device *pdev) | 564 | static int cs4270_remove(struct snd_soc_codec *codec) |
| 657 | { | 565 | { |
| 658 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
| 659 | struct snd_soc_codec *codec = cs4270_codec; | ||
| 660 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 566 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
| 661 | 567 | ||
| 662 | snd_soc_free_pcms(socdev); | ||
| 663 | regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); | 568 | regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); |
| 664 | regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); | 569 | regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies); |
| 665 | 570 | ||
| 666 | return 0; | 571 | return 0; |
| 667 | }; | 572 | }; |
| 668 | 573 | ||
| 574 | #ifdef CONFIG_PM | ||
| 575 | |||
| 576 | /* This suspend/resume implementation can handle both - a simple standby | ||
| 577 | * where the codec remains powered, and a full suspend, where the voltage | ||
| 578 | * domain the codec is connected to is teared down and/or any other hardware | ||
| 579 | * reset condition is asserted. | ||
| 580 | * | ||
| 581 | * The codec's own power saving features are enabled in the suspend callback, | ||
| 582 | * and all registers are written back to the hardware when resuming. | ||
| 583 | */ | ||
| 584 | |||
| 585 | static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) | ||
| 586 | { | ||
| 587 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | ||
| 588 | int reg, ret; | ||
| 589 | |||
| 590 | reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; | ||
| 591 | if (reg < 0) | ||
| 592 | return reg; | ||
| 593 | |||
| 594 | ret = snd_soc_write(codec, CS4270_PWRCTL, reg); | ||
| 595 | if (ret < 0) | ||
| 596 | return ret; | ||
| 597 | |||
| 598 | regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), | ||
| 599 | cs4270->supplies); | ||
| 600 | |||
| 601 | return 0; | ||
| 602 | } | ||
| 603 | |||
| 604 | static int cs4270_soc_resume(struct snd_soc_codec *codec) | ||
| 605 | { | ||
| 606 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | ||
| 607 | struct i2c_client *i2c_client = codec->control_data; | ||
| 608 | int reg; | ||
| 609 | |||
| 610 | regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), | ||
| 611 | cs4270->supplies); | ||
| 612 | |||
| 613 | /* In case the device was put to hard reset during sleep, we need to | ||
| 614 | * wait 500ns here before any I2C communication. */ | ||
| 615 | ndelay(500); | ||
| 616 | |||
| 617 | /* first restore the entire register cache ... */ | ||
| 618 | for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) { | ||
| 619 | u8 val = snd_soc_read(codec, reg); | ||
| 620 | |||
| 621 | if (i2c_smbus_write_byte_data(i2c_client, reg, val)) { | ||
| 622 | dev_err(codec->dev, "i2c write failed\n"); | ||
| 623 | return -EIO; | ||
| 624 | } | ||
| 625 | } | ||
| 626 | |||
| 627 | /* ... then disable the power-down bits */ | ||
| 628 | reg = snd_soc_read(codec, CS4270_PWRCTL); | ||
| 629 | reg &= ~CS4270_PWRCTL_PDN_ALL; | ||
| 630 | |||
| 631 | return snd_soc_write(codec, CS4270_PWRCTL, reg); | ||
| 632 | } | ||
| 633 | #else | ||
| 634 | #define cs4270_soc_suspend NULL | ||
| 635 | #define cs4270_soc_resume NULL | ||
| 636 | #endif /* CONFIG_PM */ | ||
| 637 | |||
| 638 | /* | ||
| 639 | * ASoC codec device structure | ||
| 640 | * | ||
| 641 | * Assign this variable to the codec_dev field of the machine driver's | ||
| 642 | * snd_soc_device structure. | ||
| 643 | */ | ||
| 644 | static const struct snd_soc_codec_driver soc_codec_device_cs4270 = { | ||
| 645 | .probe = cs4270_probe, | ||
| 646 | .remove = cs4270_remove, | ||
| 647 | .suspend = cs4270_soc_suspend, | ||
| 648 | .resume = cs4270_soc_resume, | ||
| 649 | .volatile_register = cs4270_reg_is_volatile, | ||
| 650 | .readable_register = cs4270_reg_is_readable, | ||
| 651 | .reg_cache_size = CS4270_LASTREG + 1, | ||
| 652 | .reg_word_size = sizeof(u8), | ||
| 653 | .reg_cache_default = cs4270_default_reg_cache, | ||
| 654 | }; | ||
| 655 | |||
| 669 | /** | 656 | /** |
| 670 | * cs4270_i2c_probe - initialize the I2C interface of the CS4270 | 657 | * cs4270_i2c_probe - initialize the I2C interface of the CS4270 |
| 671 | * @i2c_client: the I2C client object | 658 | * @i2c_client: the I2C client object |
| @@ -677,22 +664,9 @@ static int cs4270_remove(struct platform_device *pdev) | |||
| 677 | static int cs4270_i2c_probe(struct i2c_client *i2c_client, | 664 | static int cs4270_i2c_probe(struct i2c_client *i2c_client, |
| 678 | const struct i2c_device_id *id) | 665 | const struct i2c_device_id *id) |
| 679 | { | 666 | { |
| 680 | struct snd_soc_codec *codec; | ||
| 681 | struct cs4270_private *cs4270; | 667 | struct cs4270_private *cs4270; |
| 682 | unsigned int reg; | ||
| 683 | int ret; | 668 | int ret; |
| 684 | 669 | ||
| 685 | /* For now, we only support one cs4270 device in the system. See the | ||
| 686 | * comment for cs4270_codec. | ||
| 687 | */ | ||
| 688 | if (cs4270_codec) { | ||
| 689 | dev_err(&i2c_client->dev, "ignoring CS4270 at addr %X\n", | ||
| 690 | i2c_client->addr); | ||
| 691 | dev_err(&i2c_client->dev, "only one per board allowed\n"); | ||
| 692 | /* Should we return something other than ENODEV here? */ | ||
| 693 | return -ENODEV; | ||
| 694 | } | ||
| 695 | |||
| 696 | /* Verify that we have a CS4270 */ | 670 | /* Verify that we have a CS4270 */ |
| 697 | 671 | ||
| 698 | ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); | 672 | ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID); |
| @@ -712,94 +686,20 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client, | |||
| 712 | i2c_client->addr); | 686 | i2c_client->addr); |
| 713 | dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF); | 687 | dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF); |
| 714 | 688 | ||
| 715 | /* Allocate enough space for the snd_soc_codec structure | ||
| 716 | and our private data together. */ | ||
| 717 | cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL); | 689 | cs4270 = kzalloc(sizeof(struct cs4270_private), GFP_KERNEL); |
| 718 | if (!cs4270) { | 690 | if (!cs4270) { |
| 719 | dev_err(&i2c_client->dev, "could not allocate codec\n"); | 691 | dev_err(&i2c_client->dev, "could not allocate codec\n"); |
| 720 | return -ENOMEM; | 692 | return -ENOMEM; |
| 721 | } | 693 | } |
| 722 | codec = &cs4270->codec; | ||
| 723 | |||
| 724 | mutex_init(&codec->mutex); | ||
| 725 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
| 726 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
| 727 | |||
| 728 | codec->dev = &i2c_client->dev; | ||
| 729 | codec->name = "CS4270"; | ||
| 730 | codec->owner = THIS_MODULE; | ||
| 731 | codec->dai = &cs4270_dai; | ||
| 732 | codec->num_dai = 1; | ||
| 733 | snd_soc_codec_set_drvdata(codec, cs4270); | ||
| 734 | codec->control_data = i2c_client; | ||
| 735 | codec->read = cs4270_read_reg_cache; | ||
| 736 | codec->write = cs4270_i2c_write; | ||
| 737 | codec->reg_cache = cs4270->reg_cache; | ||
| 738 | codec->reg_cache_size = CS4270_NUMREGS; | ||
| 739 | |||
| 740 | /* The I2C interface is set up, so pre-fill our register cache */ | ||
| 741 | |||
| 742 | ret = cs4270_fill_cache(codec); | ||
| 743 | if (ret < 0) { | ||
| 744 | dev_err(&i2c_client->dev, "failed to fill register cache\n"); | ||
| 745 | goto error_free_codec; | ||
| 746 | } | ||
| 747 | |||
| 748 | /* Disable auto-mute. This feature appears to be buggy. In some | ||
| 749 | * situations, auto-mute will not deactivate when it should, so we want | ||
| 750 | * this feature disabled by default. An application (e.g. alsactl) can | ||
| 751 | * re-enabled it by using the controls. | ||
| 752 | */ | ||
| 753 | |||
| 754 | reg = cs4270_read_reg_cache(codec, CS4270_MUTE); | ||
| 755 | reg &= ~CS4270_MUTE_AUTO; | ||
| 756 | ret = cs4270_i2c_write(codec, CS4270_MUTE, reg); | ||
| 757 | if (ret < 0) { | ||
| 758 | dev_err(&i2c_client->dev, "i2c write failed\n"); | ||
| 759 | return ret; | ||
| 760 | } | ||
| 761 | |||
| 762 | /* Disable automatic volume control. The hardware enables, and it | ||
| 763 | * causes volume change commands to be delayed, sometimes until after | ||
| 764 | * playback has started. An application (e.g. alsactl) can | ||
| 765 | * re-enabled it by using the controls. | ||
| 766 | */ | ||
| 767 | |||
| 768 | reg = cs4270_read_reg_cache(codec, CS4270_TRANS); | ||
| 769 | reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO); | ||
| 770 | ret = cs4270_i2c_write(codec, CS4270_TRANS, reg); | ||
| 771 | if (ret < 0) { | ||
| 772 | dev_err(&i2c_client->dev, "i2c write failed\n"); | ||
| 773 | return ret; | ||
| 774 | } | ||
| 775 | |||
| 776 | /* Initialize the DAI. Normally, we'd prefer to have a kmalloc'd DAI | ||
| 777 | * structure for each CS4270 device, but the machine driver needs to | ||
| 778 | * have a pointer to the DAI structure, so for now it must be a global | ||
| 779 | * variable. | ||
| 780 | */ | ||
| 781 | cs4270_dai.dev = &i2c_client->dev; | ||
| 782 | |||
| 783 | /* Register the DAI. If all the other ASoC driver have already | ||
| 784 | * registered, then this will call our probe function, so | ||
| 785 | * cs4270_codec needs to be ready. | ||
| 786 | */ | ||
| 787 | cs4270_codec = codec; | ||
| 788 | ret = snd_soc_register_dai(&cs4270_dai); | ||
| 789 | if (ret < 0) { | ||
| 790 | dev_err(&i2c_client->dev, "failed to register DAIe\n"); | ||
| 791 | goto error_free_codec; | ||
| 792 | } | ||
| 793 | 694 | ||
| 794 | i2c_set_clientdata(i2c_client, cs4270); | 695 | i2c_set_clientdata(i2c_client, cs4270); |
| 696 | cs4270->control_data = i2c_client; | ||
| 697 | cs4270->control_type = SND_SOC_I2C; | ||
| 795 | 698 | ||
| 796 | return 0; | 699 | ret = snd_soc_register_codec(&i2c_client->dev, |
| 797 | 700 | &soc_codec_device_cs4270, &cs4270_dai, 1); | |
| 798 | error_free_codec: | 701 | if (ret < 0) |
| 799 | kfree(cs4270); | 702 | kfree(cs4270); |
| 800 | cs4270_codec = NULL; | ||
| 801 | cs4270_dai.dev = NULL; | ||
| 802 | |||
| 803 | return ret; | 703 | return ret; |
| 804 | } | 704 | } |
| 805 | 705 | ||
| @@ -811,90 +711,20 @@ error_free_codec: | |||
| 811 | */ | 711 | */ |
| 812 | static int cs4270_i2c_remove(struct i2c_client *i2c_client) | 712 | static int cs4270_i2c_remove(struct i2c_client *i2c_client) |
| 813 | { | 713 | { |
| 814 | struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client); | 714 | snd_soc_unregister_codec(&i2c_client->dev); |
| 815 | 715 | kfree(i2c_get_clientdata(i2c_client)); | |
| 816 | kfree(cs4270); | ||
| 817 | cs4270_codec = NULL; | ||
| 818 | cs4270_dai.dev = NULL; | ||
| 819 | |||
| 820 | return 0; | 716 | return 0; |
| 821 | } | 717 | } |
| 822 | 718 | ||
| 823 | /* | 719 | /* |
| 824 | * cs4270_id - I2C device IDs supported by this driver | 720 | * cs4270_id - I2C device IDs supported by this driver |
| 825 | */ | 721 | */ |
| 826 | static struct i2c_device_id cs4270_id[] = { | 722 | static const struct i2c_device_id cs4270_id[] = { |
| 827 | {"cs4270", 0}, | 723 | {"cs4270", 0}, |
| 828 | {} | 724 | {} |
| 829 | }; | 725 | }; |
| 830 | MODULE_DEVICE_TABLE(i2c, cs4270_id); | 726 | MODULE_DEVICE_TABLE(i2c, cs4270_id); |
| 831 | 727 | ||
| 832 | #ifdef CONFIG_PM | ||
| 833 | |||
| 834 | /* This suspend/resume implementation can handle both - a simple standby | ||
| 835 | * where the codec remains powered, and a full suspend, where the voltage | ||
| 836 | * domain the codec is connected to is teared down and/or any other hardware | ||
| 837 | * reset condition is asserted. | ||
| 838 | * | ||
| 839 | * The codec's own power saving features are enabled in the suspend callback, | ||
| 840 | * and all registers are written back to the hardware when resuming. | ||
| 841 | */ | ||
| 842 | |||
| 843 | static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) | ||
| 844 | { | ||
| 845 | struct snd_soc_codec *codec = cs4270_codec; | ||
| 846 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | ||
| 847 | int reg, ret; | ||
| 848 | |||
| 849 | reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; | ||
| 850 | if (reg < 0) | ||
| 851 | return reg; | ||
| 852 | |||
| 853 | ret = snd_soc_write(codec, CS4270_PWRCTL, reg); | ||
| 854 | if (ret < 0) | ||
| 855 | return ret; | ||
| 856 | |||
| 857 | regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), | ||
| 858 | cs4270->supplies); | ||
| 859 | |||
| 860 | return 0; | ||
| 861 | } | ||
| 862 | |||
| 863 | static int cs4270_soc_resume(struct platform_device *pdev) | ||
| 864 | { | ||
| 865 | struct snd_soc_codec *codec = cs4270_codec; | ||
| 866 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | ||
| 867 | struct i2c_client *i2c_client = codec->control_data; | ||
| 868 | int reg; | ||
| 869 | |||
| 870 | regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), | ||
| 871 | cs4270->supplies); | ||
| 872 | |||
| 873 | /* In case the device was put to hard reset during sleep, we need to | ||
| 874 | * wait 500ns here before any I2C communication. */ | ||
| 875 | ndelay(500); | ||
| 876 | |||
| 877 | /* first restore the entire register cache ... */ | ||
| 878 | for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) { | ||
| 879 | u8 val = snd_soc_read(codec, reg); | ||
| 880 | |||
| 881 | if (i2c_smbus_write_byte_data(i2c_client, reg, val)) { | ||
| 882 | dev_err(codec->dev, "i2c write failed\n"); | ||
| 883 | return -EIO; | ||
| 884 | } | ||
| 885 | } | ||
| 886 | |||
| 887 | /* ... then disable the power-down bits */ | ||
| 888 | reg = snd_soc_read(codec, CS4270_PWRCTL); | ||
| 889 | reg &= ~CS4270_PWRCTL_PDN_ALL; | ||
| 890 | |||
| 891 | return snd_soc_write(codec, CS4270_PWRCTL, reg); | ||
| 892 | } | ||
| 893 | #else | ||
| 894 | #define cs4270_soc_suspend NULL | ||
| 895 | #define cs4270_soc_resume NULL | ||
| 896 | #endif /* CONFIG_PM */ | ||
| 897 | |||
| 898 | /* | 728 | /* |
| 899 | * cs4270_i2c_driver - I2C device identification | 729 | * cs4270_i2c_driver - I2C device identification |
| 900 | * | 730 | * |
| @@ -903,7 +733,7 @@ static int cs4270_soc_resume(struct platform_device *pdev) | |||
| 903 | */ | 733 | */ |
| 904 | static struct i2c_driver cs4270_i2c_driver = { | 734 | static struct i2c_driver cs4270_i2c_driver = { |
| 905 | .driver = { | 735 | .driver = { |
| 906 | .name = "cs4270", | 736 | .name = "cs4270-codec", |
| 907 | .owner = THIS_MODULE, | 737 | .owner = THIS_MODULE, |
| 908 | }, | 738 | }, |
| 909 | .id_table = cs4270_id, | 739 | .id_table = cs4270_id, |
| @@ -911,24 +741,8 @@ static struct i2c_driver cs4270_i2c_driver = { | |||
| 911 | .remove = cs4270_i2c_remove, | 741 | .remove = cs4270_i2c_remove, |
| 912 | }; | 742 | }; |
| 913 | 743 | ||
| 914 | /* | ||
| 915 | * ASoC codec device structure | ||
| 916 | * | ||
| 917 | * Assign this variable to the codec_dev field of the machine driver's | ||
| 918 | * snd_soc_device structure. | ||
| 919 | */ | ||
| 920 | struct snd_soc_codec_device soc_codec_device_cs4270 = { | ||
| 921 | .probe = cs4270_probe, | ||
| 922 | .remove = cs4270_remove, | ||
| 923 | .suspend = cs4270_soc_suspend, | ||
| 924 | .resume = cs4270_soc_resume, | ||
| 925 | }; | ||
| 926 | EXPORT_SYMBOL_GPL(soc_codec_device_cs4270); | ||
| 927 | |||
| 928 | static int __init cs4270_init(void) | 744 | static int __init cs4270_init(void) |
| 929 | { | 745 | { |
| 930 | pr_info("Cirrus Logic CS4270 ALSA SoC Codec Driver\n"); | ||
| 931 | |||
| 932 | return i2c_add_driver(&cs4270_i2c_driver); | 746 | return i2c_add_driver(&cs4270_i2c_driver); |
| 933 | } | 747 | } |
| 934 | module_init(cs4270_init); | 748 | module_init(cs4270_init); |
