diff options
-rw-r--r-- | include/sound/cs42l73.h | 22 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l73.c | 51 | ||||
-rw-r--r-- | sound/soc/codecs/cs42l73.h | 1 |
3 files changed, 56 insertions, 18 deletions
diff --git a/include/sound/cs42l73.h b/include/sound/cs42l73.h new file mode 100644 index 000000000000..f354be4cdc9e --- /dev/null +++ b/include/sound/cs42l73.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * linux/sound/cs42l73.h -- Platform data for CS42L73 | ||
3 | * | ||
4 | * Copyright (c) 2012 Cirrus Logic Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __CS42L73_H | ||
12 | #define __CS42L73_H | ||
13 | |||
14 | struct cs42l73_platform_data { | ||
15 | /* RST GPIO */ | ||
16 | unsigned int reset_gpio; | ||
17 | unsigned int chgfreq; | ||
18 | int jack_detection; | ||
19 | unsigned int mclk_freq; | ||
20 | }; | ||
21 | |||
22 | #endif /* __CS42L73_H */ | ||
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 3b20c86cdb01..db9d39604d68 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/gpio.h> | ||
20 | #include <linux/pm.h> | 21 | #include <linux/pm.h> |
21 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
22 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
@@ -28,6 +29,7 @@ | |||
28 | #include <sound/soc-dapm.h> | 29 | #include <sound/soc-dapm.h> |
29 | #include <sound/initval.h> | 30 | #include <sound/initval.h> |
30 | #include <sound/tlv.h> | 31 | #include <sound/tlv.h> |
32 | #include <sound/cs42l73.h> | ||
31 | #include "cs42l73.h" | 33 | #include "cs42l73.h" |
32 | 34 | ||
33 | struct sp_config { | 35 | struct sp_config { |
@@ -35,6 +37,7 @@ struct sp_config { | |||
35 | u32 srate; | 37 | u32 srate; |
36 | }; | 38 | }; |
37 | struct cs42l73_private { | 39 | struct cs42l73_private { |
40 | struct cs42l73_platform_data pdata; | ||
38 | struct sp_config config[3]; | 41 | struct sp_config config[3]; |
39 | struct regmap *regmap; | 42 | struct regmap *regmap; |
40 | u32 sysclk; | 43 | u32 sysclk; |
@@ -310,15 +313,6 @@ static const struct soc_enum ng_delay_enum = | |||
310 | SOC_ENUM_SINGLE(CS42L73_NGCAB, 0, | 313 | SOC_ENUM_SINGLE(CS42L73_NGCAB, 0, |
311 | ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text); | 314 | ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text); |
312 | 315 | ||
313 | static const char * const charge_pump_freq_text[] = { | ||
314 | "0", "1", "2", "3", "4", | ||
315 | "5", "6", "7", "8", "9", | ||
316 | "10", "11", "12", "13", "14", "15" }; | ||
317 | |||
318 | static const struct soc_enum charge_pump_enum = | ||
319 | SOC_ENUM_SINGLE(CS42L73_CPFCHC, 4, | ||
320 | ARRAY_SIZE(charge_pump_freq_text), charge_pump_freq_text); | ||
321 | |||
322 | static const char * const cs42l73_mono_mix_texts[] = { | 316 | static const char * const cs42l73_mono_mix_texts[] = { |
323 | "Left", "Right", "Mono Mix"}; | 317 | "Left", "Right", "Mono Mix"}; |
324 | 318 | ||
@@ -511,8 +505,6 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = { | |||
511 | SOC_SINGLE("NG Threshold", CS42L73_NGCAB, 2, 7, 0), | 505 | SOC_SINGLE("NG Threshold", CS42L73_NGCAB, 2, 7, 0), |
512 | SOC_ENUM("NG Delay", ng_delay_enum), | 506 | SOC_ENUM("NG Delay", ng_delay_enum), |
513 | 507 | ||
514 | SOC_ENUM("Charge Pump Frequency", charge_pump_enum), | ||
515 | |||
516 | SOC_DOUBLE_R_TLV("XSP-IP Volume", | 508 | SOC_DOUBLE_R_TLV("XSP-IP Volume", |
517 | CS42L73_XSPAIPAA, CS42L73_XSPBIPBA, 0, 0x3F, 1, | 509 | CS42L73_XSPAIPAA, CS42L73_XSPBIPBA, 0, 0x3F, 1, |
518 | attn_tlv), | 510 | attn_tlv), |
@@ -1367,11 +1359,16 @@ static int cs42l73_probe(struct snd_soc_codec *codec) | |||
1367 | return ret; | 1359 | return ret; |
1368 | } | 1360 | } |
1369 | 1361 | ||
1370 | regcache_cache_only(cs42l73->regmap, true); | ||
1371 | |||
1372 | cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1362 | cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1373 | 1363 | ||
1374 | cs42l73->mclksel = CS42L73_CLKID_MCLK1; /* MCLK1 as master clk */ | 1364 | /* Set Charge Pump Frequency */ |
1365 | if (cs42l73->pdata.chgfreq) | ||
1366 | snd_soc_update_bits(codec, CS42L73_CPFCHC, | ||
1367 | CS42L73_CHARGEPUMP_MASK, | ||
1368 | cs42l73->pdata.chgfreq << 4); | ||
1369 | |||
1370 | /* MCLK1 as master clk */ | ||
1371 | cs42l73->mclksel = CS42L73_CLKID_MCLK1; | ||
1375 | cs42l73->mclk = 0; | 1372 | cs42l73->mclk = 0; |
1376 | 1373 | ||
1377 | return ret; | 1374 | return ret; |
@@ -1415,6 +1412,7 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1415 | const struct i2c_device_id *id) | 1412 | const struct i2c_device_id *id) |
1416 | { | 1413 | { |
1417 | struct cs42l73_private *cs42l73; | 1414 | struct cs42l73_private *cs42l73; |
1415 | struct cs42l73_platform_data *pdata = dev_get_platdata(&i2c_client->dev); | ||
1418 | int ret; | 1416 | int ret; |
1419 | unsigned int devid = 0; | 1417 | unsigned int devid = 0; |
1420 | unsigned int reg; | 1418 | unsigned int reg; |
@@ -1426,14 +1424,32 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1426 | return -ENOMEM; | 1424 | return -ENOMEM; |
1427 | } | 1425 | } |
1428 | 1426 | ||
1429 | i2c_set_clientdata(i2c_client, cs42l73); | ||
1430 | |||
1431 | cs42l73->regmap = devm_regmap_init_i2c(i2c_client, &cs42l73_regmap); | 1427 | cs42l73->regmap = devm_regmap_init_i2c(i2c_client, &cs42l73_regmap); |
1432 | if (IS_ERR(cs42l73->regmap)) { | 1428 | if (IS_ERR(cs42l73->regmap)) { |
1433 | ret = PTR_ERR(cs42l73->regmap); | 1429 | ret = PTR_ERR(cs42l73->regmap); |
1434 | dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); | 1430 | dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); |
1435 | return ret; | 1431 | return ret; |
1436 | } | 1432 | } |
1433 | |||
1434 | if (pdata) | ||
1435 | cs42l73->pdata = *pdata; | ||
1436 | |||
1437 | i2c_set_clientdata(i2c_client, cs42l73); | ||
1438 | |||
1439 | if (cs42l73->pdata.reset_gpio) { | ||
1440 | ret = gpio_request_one(cs42l73->pdata.reset_gpio, | ||
1441 | GPIOF_OUT_INIT_HIGH, "CS42L73 /RST"); | ||
1442 | if (ret < 0) { | ||
1443 | dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", | ||
1444 | cs42l73->pdata.reset_gpio, ret); | ||
1445 | return ret; | ||
1446 | } | ||
1447 | gpio_set_value_cansleep(cs42l73->pdata.reset_gpio, 0); | ||
1448 | gpio_set_value_cansleep(cs42l73->pdata.reset_gpio, 1); | ||
1449 | } | ||
1450 | |||
1451 | regcache_cache_bypass(cs42l73->regmap, true); | ||
1452 | |||
1437 | /* initialize codec */ | 1453 | /* initialize codec */ |
1438 | ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); | 1454 | ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); |
1439 | devid = (reg & 0xFF) << 12; | 1455 | devid = (reg & 0xFF) << 12; |
@@ -1444,7 +1460,6 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1444 | ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, ®); | 1460 | ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, ®); |
1445 | devid |= (reg & 0xF0) >> 4; | 1461 | devid |= (reg & 0xF0) >> 4; |
1446 | 1462 | ||
1447 | |||
1448 | if (devid != CS42L73_DEVID) { | 1463 | if (devid != CS42L73_DEVID) { |
1449 | ret = -ENODEV; | 1464 | ret = -ENODEV; |
1450 | dev_err(&i2c_client->dev, | 1465 | dev_err(&i2c_client->dev, |
@@ -1462,7 +1477,7 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1462 | dev_info(&i2c_client->dev, | 1477 | dev_info(&i2c_client->dev, |
1463 | "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF); | 1478 | "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF); |
1464 | 1479 | ||
1465 | regcache_cache_only(cs42l73->regmap, true); | 1480 | regcache_cache_bypass(cs42l73->regmap, false); |
1466 | 1481 | ||
1467 | ret = snd_soc_register_codec(&i2c_client->dev, | 1482 | ret = snd_soc_register_codec(&i2c_client->dev, |
1468 | &soc_codec_dev_cs42l73, cs42l73_dai, | 1483 | &soc_codec_dev_cs42l73, cs42l73_dai, |
diff --git a/sound/soc/codecs/cs42l73.h b/sound/soc/codecs/cs42l73.h index f30a4c4d62e6..4f83d39496a8 100644 --- a/sound/soc/codecs/cs42l73.h +++ b/sound/soc/codecs/cs42l73.h | |||
@@ -159,6 +159,7 @@ | |||
159 | #define THMOVLD_115C 2 | 159 | #define THMOVLD_115C 2 |
160 | #define THMOVLD_098C 3 | 160 | #define THMOVLD_098C 3 |
161 | 161 | ||
162 | #define CS42L73_CHARGEPUMP_MASK (0xF0) | ||
162 | 163 | ||
163 | /* CS42L73_ASPC, CS42L73_XSPC, CS42L73_VSPC */ | 164 | /* CS42L73_ASPC, CS42L73_XSPC, CS42L73_VSPC */ |
164 | #define SP_3ST (1 << 7) | 165 | #define SP_3ST (1 << 7) |