diff options
| -rw-r--r-- | sound/soc/codecs/Kconfig | 6 | ||||
| -rw-r--r-- | sound/soc/codecs/Makefile | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/cs42l51-i2c.c | 59 | ||||
| -rw-r--r-- | sound/soc/codecs/cs42l51.c | 75 | ||||
| -rw-r--r-- | sound/soc/codecs/cs42l51.h | 5 |
5 files changed, 90 insertions, 57 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f0e840137887..5279ef41597d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
| @@ -39,7 +39,7 @@ config SND_SOC_ALL_CODECS | |||
| 39 | select SND_SOC_ALC5623 if I2C | 39 | select SND_SOC_ALC5623 if I2C |
| 40 | select SND_SOC_ALC5632 if I2C | 40 | select SND_SOC_ALC5632 if I2C |
| 41 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC | 41 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC |
| 42 | select SND_SOC_CS42L51 if I2C | 42 | select SND_SOC_CS42L51_I2C if I2C |
| 43 | select SND_SOC_CS42L52 if I2C | 43 | select SND_SOC_CS42L52 if I2C |
| 44 | select SND_SOC_CS42L73 if I2C | 44 | select SND_SOC_CS42L73 if I2C |
| 45 | select SND_SOC_CS4270 if I2C | 45 | select SND_SOC_CS4270 if I2C |
| @@ -280,6 +280,10 @@ config SND_SOC_CQ0093VC | |||
| 280 | config SND_SOC_CS42L51 | 280 | config SND_SOC_CS42L51 |
| 281 | tristate | 281 | tristate |
| 282 | 282 | ||
| 283 | config SND_SOC_CS42L51_I2C | ||
| 284 | tristate | ||
| 285 | select SND_SOC_CS42L51 | ||
| 286 | |||
| 283 | config SND_SOC_CS42L52 | 287 | config SND_SOC_CS42L52 |
| 284 | tristate "Cirrus Logic CS42L52 CODEC" | 288 | tristate "Cirrus Logic CS42L52 CODEC" |
| 285 | depends on I2C | 289 | depends on I2C |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3c4d275d064b..e06f10032344 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
| @@ -26,6 +26,7 @@ snd-soc-ak5386-objs := ak5386.o | |||
| 26 | snd-soc-arizona-objs := arizona.o | 26 | snd-soc-arizona-objs := arizona.o |
| 27 | snd-soc-cq93vc-objs := cq93vc.o | 27 | snd-soc-cq93vc-objs := cq93vc.o |
| 28 | snd-soc-cs42l51-objs := cs42l51.o | 28 | snd-soc-cs42l51-objs := cs42l51.o |
| 29 | snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o | ||
| 29 | snd-soc-cs42l52-objs := cs42l52.o | 30 | snd-soc-cs42l52-objs := cs42l52.o |
| 30 | snd-soc-cs42l73-objs := cs42l73.o | 31 | snd-soc-cs42l73-objs := cs42l73.o |
| 31 | snd-soc-cs4270-objs := cs4270.o | 32 | snd-soc-cs4270-objs := cs4270.o |
| @@ -177,6 +178,7 @@ obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o | |||
| 177 | obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o | 178 | obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o |
| 178 | obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o | 179 | obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o |
| 179 | obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o | 180 | obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o |
| 181 | obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o | ||
| 180 | obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o | 182 | obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o |
| 181 | obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o | 183 | obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o |
| 182 | obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o | 184 | obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o |
diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c new file mode 100644 index 000000000000..cee51ae177c1 --- /dev/null +++ b/sound/soc/codecs/cs42l51-i2c.c | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | /* | ||
| 2 | * cs42l56.c -- CS42L51 ALSA SoC I2C audio driver | ||
| 3 | * | ||
| 4 | * Copyright 2014 CirrusLogic, Inc. | ||
| 5 | * | ||
| 6 | * Author: Brian Austin <brian.austin@cirrus.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/i2c.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <sound/soc.h> | ||
| 17 | |||
| 18 | #include "cs42l51.h" | ||
| 19 | |||
| 20 | static struct i2c_device_id cs42l51_i2c_id[] = { | ||
| 21 | {"cs42l51", 0}, | ||
| 22 | {} | ||
| 23 | }; | ||
| 24 | MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id); | ||
| 25 | |||
| 26 | static int cs42l51_i2c_probe(struct i2c_client *i2c, | ||
| 27 | const struct i2c_device_id *id) | ||
| 28 | { | ||
| 29 | struct regmap_config config; | ||
| 30 | |||
| 31 | config = cs42l51_regmap; | ||
| 32 | config.val_bits = 8; | ||
| 33 | config.reg_bits = 8; | ||
| 34 | |||
| 35 | return cs42l51_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &config)); | ||
| 36 | } | ||
| 37 | |||
| 38 | static int cs42l51_i2c_remove(struct i2c_client *i2c) | ||
| 39 | { | ||
| 40 | snd_soc_unregister_codec(&i2c->dev); | ||
| 41 | |||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | |||
| 45 | static struct i2c_driver cs42l51_i2c_driver = { | ||
| 46 | .driver = { | ||
| 47 | .name = "cs42l51", | ||
| 48 | .owner = THIS_MODULE, | ||
| 49 | }, | ||
| 50 | .probe = cs42l51_i2c_probe, | ||
| 51 | .remove = cs42l51_i2c_remove, | ||
| 52 | .id_table = cs42l51_i2c_id, | ||
| 53 | }; | ||
| 54 | |||
| 55 | module_i2c_driver(cs42l51_i2c_driver); | ||
| 56 | |||
| 57 | MODULE_DESCRIPTION("ASoC CS42L51 I2C Driver"); | ||
| 58 | MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); | ||
| 59 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6c0da2baa154..46abd3e02f14 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <sound/initval.h> | 29 | #include <sound/initval.h> |
| 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> | ||
| 33 | #include <linux/regmap.h> | 32 | #include <linux/regmap.h> |
| 34 | 33 | ||
| 35 | #include "cs42l51.h" | 34 | #include "cs42l51.h" |
| @@ -483,7 +482,7 @@ static struct snd_soc_dai_driver cs42l51_dai = { | |||
| 483 | .ops = &cs42l51_dai_ops, | 482 | .ops = &cs42l51_dai_ops, |
| 484 | }; | 483 | }; |
| 485 | 484 | ||
| 486 | static int cs42l51_probe(struct snd_soc_codec *codec) | 485 | static int cs42l51_codec_probe(struct snd_soc_codec *codec) |
| 487 | { | 486 | { |
| 488 | int ret, reg; | 487 | int ret, reg; |
| 489 | 488 | ||
| @@ -504,7 +503,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec) | |||
| 504 | } | 503 | } |
| 505 | 504 | ||
| 506 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | 505 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { |
| 507 | .probe = cs42l51_probe, | 506 | .probe = cs42l51_codec_probe, |
| 508 | 507 | ||
| 509 | .controls = cs42l51_snd_controls, | 508 | .controls = cs42l51_snd_controls, |
| 510 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), | 509 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), |
| @@ -514,91 +513,55 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | |||
| 514 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), | 513 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), |
| 515 | }; | 514 | }; |
| 516 | 515 | ||
| 517 | static const struct regmap_config cs42l51_regmap = { | 516 | const struct regmap_config cs42l51_regmap = { |
| 518 | .reg_bits = 8, | ||
| 519 | .val_bits = 8, | ||
| 520 | |||
| 521 | .max_register = CS42L51_CHARGE_FREQ, | 517 | .max_register = CS42L51_CHARGE_FREQ, |
| 522 | .cache_type = REGCACHE_RBTREE, | 518 | .cache_type = REGCACHE_RBTREE, |
| 523 | }; | 519 | }; |
| 520 | EXPORT_SYMBOL_GPL(cs42l51_regmap); | ||
| 524 | 521 | ||
| 525 | static int cs42l51_i2c_probe(struct i2c_client *i2c_client, | 522 | int cs42l51_probe(struct device *dev, struct regmap *regmap) |
| 526 | const struct i2c_device_id *id) | ||
| 527 | { | 523 | { |
| 528 | struct cs42l51_private *cs42l51; | 524 | struct cs42l51_private *cs42l51; |
| 529 | struct regmap *regmap; | ||
| 530 | unsigned int val; | 525 | unsigned int val; |
| 531 | int ret; | 526 | int ret; |
| 532 | 527 | ||
| 533 | regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap); | 528 | if (IS_ERR(regmap)) |
| 534 | if (IS_ERR(regmap)) { | 529 | return PTR_ERR(regmap); |
| 535 | ret = PTR_ERR(regmap); | 530 | |
| 536 | dev_err(&i2c_client->dev, "Failed to create regmap: %d\n", | 531 | cs42l51 = devm_kzalloc(dev, sizeof(struct cs42l51_private), |
| 537 | ret); | 532 | GFP_KERNEL); |
| 538 | return ret; | 533 | if (!cs42l51) |
| 539 | } | 534 | return -ENOMEM; |
| 535 | |||
| 536 | dev_set_drvdata(dev, cs42l51); | ||
| 540 | 537 | ||
| 541 | /* Verify that we have a CS42L51 */ | 538 | /* Verify that we have a CS42L51 */ |
| 542 | ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val); | 539 | ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val); |
| 543 | if (ret < 0) { | 540 | if (ret < 0) { |
| 544 | dev_err(&i2c_client->dev, "failed to read I2C\n"); | 541 | dev_err(dev, "failed to read I2C\n"); |
| 545 | goto error; | 542 | goto error; |
| 546 | } | 543 | } |
| 547 | 544 | ||
| 548 | if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && | 545 | if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && |
| 549 | (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { | 546 | (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { |
| 550 | dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val); | 547 | dev_err(dev, "Invalid chip id: %x\n", val); |
| 551 | ret = -ENODEV; | 548 | ret = -ENODEV; |
| 552 | goto error; | 549 | goto error; |
| 553 | } | 550 | } |
| 551 | dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n", val & 0xFF); | ||
| 554 | 552 | ||
