aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/cs42l51.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/cs42l51.c')
-rw-r--r--sound/soc/codecs/cs42l51.c71
1 files changed, 33 insertions, 38 deletions
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 6e9ea8379a91..3eab46020a30 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -30,6 +30,7 @@
30#include <sound/pcm_params.h> 30#include <sound/pcm_params.h>
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <linux/i2c.h> 32#include <linux/i2c.h>
33#include <linux/regmap.h>
33 34
34#include "cs42l51.h" 35#include "cs42l51.h"
35 36
@@ -40,7 +41,6 @@ enum master_slave_mode {
40}; 41};
41 42
42struct cs42l51_private { 43struct cs42l51_private {
43 enum snd_soc_control_type control_type;
44 unsigned int mclk; 44 unsigned int mclk;
45 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 45 unsigned int audio_mode; /* The mode (I2S or left-justified) */
46 enum master_slave_mode func; 46 enum master_slave_mode func;
@@ -52,24 +52,6 @@ struct cs42l51_private {
52 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ 52 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \
53 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE) 53 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
54 54
55static int cs42l51_fill_cache(struct snd_soc_codec *codec)
56{
57 u8 *cache = codec->reg_cache + 1;
58 struct i2c_client *i2c_client = to_i2c_client(codec->dev);
59 s32 length;
60
61 length = i2c_smbus_read_i2c_block_data(i2c_client,
62 CS42L51_FIRSTREG | 0x80, CS42L51_NUMREGS, cache);
63 if (length != CS42L51_NUMREGS) {
64 dev_err(&i2c_client->dev,
65 "I2C read failure, addr=0x%x (ret=%d vs %d)\n",
66 i2c_client->addr, length, CS42L51_NUMREGS);
67 return -EIO;
68 }
69
70 return 0;
71}
72
73static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, 55static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
74 struct snd_ctl_elem_value *ucontrol) 56 struct snd_ctl_elem_value *ucontrol)
75{ 57{
@@ -505,16 +487,9 @@ static struct snd_soc_dai_driver cs42l51_dai = {
505 487
506static int cs42l51_probe(struct snd_soc_codec *codec) 488static int cs42l51_probe(struct snd_soc_codec *codec)
507{ 489{
508 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
509 int ret, reg; 490 int ret, reg;
510 491
511 ret = cs42l51_fill_cache(codec); 492 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
512 if (ret < 0) {
513 dev_err(codec->dev, "failed to fill register cache\n");
514 return ret;
515 }
516
517 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs42l51->control_type);
518 if (ret < 0) { 493 if (ret < 0) {
519 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 494 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
520 return ret; 495 return ret;
@@ -538,8 +513,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
538 513
539static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { 514static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
540 .probe = cs42l51_probe, 515 .probe = cs42l51_probe,
541 .reg_cache_size = CS42L51_NUMREGS + 1,
542 .reg_word_size = sizeof(u8),
543 516
544 .controls = cs42l51_snd_controls, 517 .controls = cs42l51_snd_controls,
545 .num_controls = ARRAY_SIZE(cs42l51_snd_controls), 518 .num_controls = ARRAY_SIZE(cs42l51_snd_controls),
@@ -549,38 +522,53 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = {
549 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), 522 .num_dapm_routes = ARRAY_SIZE(cs42l51_routes),
550}; 523};
551 524
525static const struct regmap_config cs42l51_regmap = {
526 .reg_bits = 8,
527 .val_bits = 8,
528
529 .max_register = CS42L51_CHARGE_FREQ,
530 .cache_type = REGCACHE_RBTREE,
531};
532
552static int cs42l51_i2c_probe(struct i2c_client *i2c_client, 533static int cs42l51_i2c_probe(struct i2c_client *i2c_client,
553 const struct i2c_device_id *id) 534 const struct i2c_device_id *id)
554{ 535{
555 struct cs42l51_private *cs42l51; 536 struct cs42l51_private *cs42l51;
537 struct regmap *regmap;
538 unsigned int val;
556 int ret; 539 int ret;
557 540
541 regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap);
542 if (IS_ERR(regmap)) {
543 ret = PTR_ERR(regmap);
544 dev_err(&i2c_client->dev, "Failed to create regmap: %d\n",
545 ret);
546 return ret;
547 }
548
558 /* Verify that we have a CS42L51 */ 549 /* Verify that we have a CS42L51 */
559 ret = i2c_smbus_read_byte_data(i2c_client, CS42L51_CHIP_REV_ID); 550 ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val);
560 if (ret < 0) { 551 if (ret < 0) {
561 dev_err(&i2c_client->dev, "failed to read I2C\n"); 552 dev_err(&i2c_client->dev, "failed to read I2C\n");
562 goto error; 553 goto error;
563 } 554 }
564 555
565 if ((ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && 556 if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
566 (ret != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { 557 (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
567 dev_err(&i2c_client->dev, "Invalid chip id\n"); 558 dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val);
568 ret = -ENODEV; 559 ret = -ENODEV;
569 goto error; 560 goto error;
570 } 561 }
571 562
572 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", 563 dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n",
573 ret & 7); 564 val & 7);
574 565
575 cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), 566 cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private),
576 GFP_KERNEL); 567 GFP_KERNEL);
577 if (!cs42l51) { 568 if (!cs42l51)
578 dev_err(&i2c_client->dev, "could not allocate codec\n");
579 return -ENOMEM; 569 return -ENOMEM;
580 }
581 570
582 i2c_set_clientdata(i2c_client, cs42l51); 571 i2c_set_clientdata(i2c_client, cs42l51);
583 cs42l51->control_type = SND_SOC_I2C;
584 572
585 ret = snd_soc_register_codec(&i2c_client->dev, 573 ret = snd_soc_register_codec(&i2c_client->dev,
586 &soc_codec_device_cs42l51, &cs42l51_dai, 1); 574 &soc_codec_device_cs42l51, &cs42l51_dai, 1);
@@ -600,10 +588,17 @@ static const struct i2c_device_id cs42l51_id[] = {
600}; 588};
601MODULE_DEVICE_TABLE(i2c, cs42l51_id); 589MODULE_DEVICE_TABLE(i2c, cs42l51_id);
602 590
591static const struct of_device_id cs42l51_of_match[] = {
592 { .compatible = "cirrus,cs42l51", },
593 { }
594};
595MODULE_DEVICE_TABLE(of, cs42l51_of_match);
596
603static struct i2c_driver cs42l51_i2c_driver = { 597static struct i2c_driver cs42l51_i2c_driver = {
604 .driver = { 598 .driver = {
605 .name = "cs42l51-codec", 599 .name = "cs42l51-codec",
606 .owner = THIS_MODULE, 600 .owner = THIS_MODULE,
601 .of_match_table = cs42l51_of_match,
607 }, 602 },
608 .id_table = cs42l51_id, 603 .id_table = cs42l51_id,
609 .probe = cs42l51_i2c_probe, 604 .probe = cs42l51_i2c_probe,