aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Dannenberg <dannenberg@ti.com>2017-12-11 14:01:54 -0500
committerMark Brown <broonie@kernel.org>2017-12-12 07:03:03 -0500
commit872bcad246e30f0ae8009a0f8c13874009601445 (patch)
treeb9816a41bde2f2221af74a8df641d12c06a509e0
parent4fbd8d194f06c8a3fd2af1ce560ddb31f7ec8323 (diff)
ASoC: tas5720: add basic support for TAS5722 devices
The TI TAS5722 digital amplifier is very similar to the TAS5720 from an overall and register map perspective. Therefore the existing driver can be extended easily to support this additional device. This commit allows TAS5722 devices to be used in a "subset" type of fashion, without exposing any of the additional features they offer. Signed-off-by: Andreas Dannenberg <dannenberg@ti.com> Signed-off-by: Andrew F. Davis <afd@ti.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--Documentation/devicetree/bindings/sound/tas5720.txt4
-rw-r--r--sound/soc/codecs/tas5720.c38
-rw-r--r--sound/soc/codecs/tas5720.h1
3 files changed, 35 insertions, 8 deletions
diff --git a/Documentation/devicetree/bindings/sound/tas5720.txt b/Documentation/devicetree/bindings/sound/tas5720.txt
index 40d94f82beb3..7481653fe8e3 100644
--- a/Documentation/devicetree/bindings/sound/tas5720.txt
+++ b/Documentation/devicetree/bindings/sound/tas5720.txt
@@ -6,10 +6,12 @@ audio playback. For more product information please see the links below:
6 6
7http://www.ti.com/product/TAS5720L 7http://www.ti.com/product/TAS5720L
8http://www.ti.com/product/TAS5720M 8http://www.ti.com/product/TAS5720M
9http://www.ti.com/product/TAS5722L
9 10
10Required properties: 11Required properties:
11 12
12- compatible : "ti,tas5720" 13- compatible : "ti,tas5720",
14 "ti,tas5722"
13- reg : I2C slave address 15- reg : I2C slave address
14- dvdd-supply : phandle to a 3.3-V supply for the digital circuitry 16- dvdd-supply : phandle to a 3.3-V supply for the digital circuitry
15- pvdd-supply : phandle to a supply used for the Class-D amp and the analog 17- pvdd-supply : phandle to a supply used for the Class-D amp and the analog
diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c
index a736a2a6976c..5def54d1336d 100644
--- a/sound/soc/codecs/tas5720.c
+++ b/sound/soc/codecs/tas5720.c
@@ -36,6 +36,11 @@
36/* Define how often to check (and clear) the fault status register (in ms) */ 36/* Define how often to check (and clear) the fault status register (in ms) */
37#define TAS5720_FAULT_CHECK_INTERVAL 200 37#define TAS5720_FAULT_CHECK_INTERVAL 200
38 38
39enum tas572x_type {
40 TAS5720,
41 TAS5722,
42};
43
39static const char * const tas5720_supply_names[] = { 44static const char * const tas5720_supply_names[] = {
40 "dvdd", /* Digital power supply. Connect to 3.3-V supply. */ 45 "dvdd", /* Digital power supply. Connect to 3.3-V supply. */
41 "pvdd", /* Class-D amp and analog power supply (connected). */ 46 "pvdd", /* Class-D amp and analog power supply (connected). */
@@ -47,6 +52,7 @@ struct tas5720_data {
47 struct snd_soc_codec *codec; 52 struct snd_soc_codec *codec;
48 struct regmap *regmap; 53 struct regmap *regmap;
49 struct i2c_client *tas5720_client; 54 struct i2c_client *tas5720_client;
55 enum tas572x_type devtype;
50 struct regulator_bulk_data supplies[TAS5720_NUM_SUPPLIES]; 56 struct regulator_bulk_data supplies[TAS5720_NUM_SUPPLIES];
51 struct delayed_work fault_check_work; 57 struct delayed_work fault_check_work;
52 unsigned int last_fault; 58 unsigned int last_fault;
@@ -264,7 +270,7 @@ out:
264static int tas5720_codec_probe(struct snd_soc_codec *codec) 270static int tas5720_codec_probe(struct snd_soc_codec *codec)
265{ 271{
266 struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec); 272 struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec);
267 unsigned int device_id; 273 unsigned int device_id, expected_device_id;
268 int ret; 274 int ret;
269 275
270 tas5720->codec = codec; 276 tas5720->codec = codec;
@@ -276,6 +282,11 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec)
276 return ret; 282 return ret;
277 } 283 }
278 284
285 /*
286 * Take a liberal approach to checking the device ID to allow the
287 * driver to be used even if the device ID does not match, however
288 * issue a warning if there is a mismatch.
289 */
279 ret = regmap_read(tas5720->regmap, TAS5720_DEVICE_ID_REG, &device_id); 290 ret = regmap_read(tas5720->regmap, TAS5720_DEVICE_ID_REG, &device_id);
280 if (ret < 0) { 291 if (ret < 0) {
281 dev_err(codec->dev, "failed to read device ID register: %d\n", 292 dev_err(codec->dev, "failed to read device ID register: %d\n",
@@ -283,13 +294,22 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec)
283 goto probe_fail; 294 goto probe_fail;
284 } 295 }
285 296
286 if (device_id != TAS5720_DEVICE_ID) { 297 switch (tas5720->devtype) {
287 dev_err(codec->dev, "wrong device ID. expected: %u read: %u\n", 298 case TAS5720:
288 TAS5720_DEVICE_ID, device_id); 299 expected_device_id = TAS5720_DEVICE_ID;
289 ret = -ENODEV; 300 break;
290 goto probe_fail; 301 case TAS5722:
302 expected_device_id = TAS5722_DEVICE_ID;
303 break;
304 default:
305 dev_err(codec->dev, "unexpected private driver data\n");
306 return -EINVAL;
291 } 307 }
292 308
309 if (device_id != expected_device_id)
310 dev_warn(codec->dev, "wrong device ID. expected: %u read: %u\n",
311 expected_device_id, device_id);
312
293 /* Set device to mute */ 313 /* Set device to mute */
294 ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG, 314 ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG,
295 TAS5720_MUTE, TAS5720_MUTE); 315 TAS5720_MUTE, TAS5720_MUTE);
@@ -552,6 +572,8 @@ static int tas5720_probe(struct i2c_client *client,
552 return -ENOMEM; 572 return -ENOMEM;
553 573
554 data->tas5720_client = client; 574 data->tas5720_client = client;
575 data->devtype = id->driver_data;
576
555 data->regmap = devm_regmap_init_i2c(client, &tas5720_regmap_config); 577 data->regmap = devm_regmap_init_i2c(client, &tas5720_regmap_config);
556 if (IS_ERR(data->regmap)) { 578 if (IS_ERR(data->regmap)) {
557 ret = PTR_ERR(data->regmap); 579 ret = PTR_ERR(data->regmap);
@@ -592,7 +614,8 @@ static int tas5720_remove(struct i2c_client *client)
592} 614}
593 615
594static const struct i2c_device_id tas5720_id[] = { 616static const struct i2c_device_id tas5720_id[] = {
595 { "tas5720", 0 }, 617 { "tas5720", TAS5720 },
618 { "tas5722", TAS5722 },
596 { } 619 { }
597}; 620};
598MODULE_DEVICE_TABLE(i2c, tas5720_id); 621MODULE_DEVICE_TABLE(i2c, tas5720_id);
@@ -600,6 +623,7 @@ MODULE_DEVICE_TABLE(i2c, tas5720_id);
600#if IS_ENABLED(CONFIG_OF) 623#if IS_ENABLED(CONFIG_OF)
601static const struct of_device_id tas5720_of_match[] = { 624static const struct of_device_id tas5720_of_match[] = {
602 { .compatible = "ti,tas5720", }, 625 { .compatible = "ti,tas5720", },
626 { .compatible = "ti,tas5722", },
603 { }, 627 { },
604}; 628};
605MODULE_DEVICE_TABLE(of, tas5720_of_match); 629MODULE_DEVICE_TABLE(of, tas5720_of_match);
diff --git a/sound/soc/codecs/tas5720.h b/sound/soc/codecs/tas5720.h
index 3d077c779b12..bef802afcc69 100644
--- a/sound/soc/codecs/tas5720.h
+++ b/sound/soc/codecs/tas5720.h
@@ -32,6 +32,7 @@
32 32
33/* TAS5720_DEVICE_ID_REG */ 33/* TAS5720_DEVICE_ID_REG */
34#define TAS5720_DEVICE_ID 0x01 34#define TAS5720_DEVICE_ID 0x01
35#define TAS5722_DEVICE_ID 0x12
35 36
36/* TAS5720_POWER_CTRL_REG */ 37/* TAS5720_POWER_CTRL_REG */
37#define TAS5720_DIG_CLIP_MASK GENMASK(7, 2) 38#define TAS5720_DIG_CLIP_MASK GENMASK(7, 2)