1919#include <linux/pm.h>
2020#include <linux/i2c.h>
2121#include <linux/regmap.h>
22+ #include <linux/regulator/consumer.h>
2223#include <linux/slab.h>
2324#include <sound/core.h>
2425#include <sound/pcm.h>
@@ -108,6 +109,10 @@ static const struct reg_default nau8822_reg_defaults[] = {
108109 { NAU8822_REG_OUTPUT_TIEOFF , 0x0000 },
109110};
110111
112+ static const char * const nau8822_supply_names [NAU8822_NUM_SUPPLIES ] = {
113+ "vdda" , "vddb" , "vddc" , "vddspk" ,
114+ };
115+
111116static bool nau8822_readable_reg (struct device * dev , unsigned int reg )
112117{
113118 switch (reg ) {
@@ -1056,6 +1061,7 @@ static int nau8822_suspend(struct snd_soc_component *component)
10561061 struct snd_soc_dapm_context * dapm = snd_soc_component_to_dapm (component );
10571062
10581063 snd_soc_dapm_force_bias_level (dapm , SND_SOC_BIAS_OFF );
1064+ regulator_bulk_disable (NAU8822_NUM_SUPPLIES , nau8822 -> supplies );
10591065
10601066 regcache_mark_dirty (nau8822 -> regmap );
10611067
@@ -1066,6 +1072,15 @@ static int nau8822_resume(struct snd_soc_component *component)
10661072{
10671073 struct nau8822 * nau8822 = snd_soc_component_get_drvdata (component );
10681074 struct snd_soc_dapm_context * dapm = snd_soc_component_to_dapm (component );
1075+ int ret = regulator_bulk_enable (NAU8822_NUM_SUPPLIES , nau8822 -> supplies );
1076+
1077+ if (ret ) {
1078+ dev_err (component -> dev ,
1079+ "Failed to enable regulators: %d\n" , ret );
1080+ return ret ;
1081+ }
1082+
1083+ fsleep (100 );
10691084
10701085 regcache_sync (nau8822 -> regmap );
10711086
@@ -1153,7 +1168,7 @@ static int nau8822_i2c_probe(struct i2c_client *i2c)
11531168{
11541169 struct device * dev = & i2c -> dev ;
11551170 struct nau8822 * nau8822 = dev_get_platdata (dev );
1156- int ret ;
1171+ int ret , i ;
11571172
11581173 if (!nau8822 ) {
11591174 nau8822 = devm_kzalloc (dev , sizeof (* nau8822 ), GFP_KERNEL );
@@ -1167,6 +1182,13 @@ static int nau8822_i2c_probe(struct i2c_client *i2c)
11671182 return dev_err_probe (& i2c -> dev , PTR_ERR (nau8822 -> mclk ),
11681183 "Error getting mclk\n" );
11691184
1185+ for (i = 0 ; i < NAU8822_NUM_SUPPLIES ; i ++ )
1186+ nau8822 -> supplies [i ].supply = nau8822_supply_names [i ];
1187+
1188+ ret = devm_regulator_bulk_get (dev , NAU8822_NUM_SUPPLIES , nau8822 -> supplies );
1189+ if (ret )
1190+ return dev_err_probe (dev , ret , "Failed to get regulators\n" );
1191+
11701192 nau8822 -> regmap = devm_regmap_init_i2c (i2c , & nau8822_regmap_config );
11711193 if (IS_ERR (nau8822 -> regmap )) {
11721194 ret = PTR_ERR (nau8822 -> regmap );
@@ -1175,21 +1197,38 @@ static int nau8822_i2c_probe(struct i2c_client *i2c)
11751197 }
11761198 nau8822 -> dev = dev ;
11771199
1200+ ret = regulator_bulk_enable (NAU8822_NUM_SUPPLIES , nau8822 -> supplies );
1201+ if (ret )
1202+ return dev_err_probe (dev , ret , "Failed to enable regulators\n" );
1203+
1204+ fsleep (100 );
1205+
11781206 /* Reset the codec */
11791207 ret = regmap_write (nau8822 -> regmap , NAU8822_REG_RESET , 0x00 );
11801208 if (ret != 0 ) {
11811209 dev_err (& i2c -> dev , "Failed to issue reset: %d\n" , ret );
1182- return ret ;
1210+ goto err_reg ;
11831211 }
11841212
11851213 ret = devm_snd_soc_register_component (dev , & soc_component_dev_nau8822 ,
11861214 & nau8822_dai , 1 );
11871215 if (ret != 0 ) {
11881216 dev_err (& i2c -> dev , "Failed to register CODEC: %d\n" , ret );
1189- return ret ;
1217+ goto err_reg ;
11901218 }
11911219
11921220 return 0 ;
1221+
1222+ err_reg :
1223+ regulator_bulk_disable (NAU8822_NUM_SUPPLIES , nau8822 -> supplies );
1224+ return ret ;
1225+ }
1226+
1227+ static void nau8822_i2c_remove (struct i2c_client * i2c )
1228+ {
1229+ struct nau8822 * nau8822 = i2c_get_clientdata (i2c );
1230+
1231+ regulator_bulk_disable (NAU8822_NUM_SUPPLIES , nau8822 -> supplies );
11931232}
11941233
11951234static const struct i2c_device_id nau8822_i2c_id [] = {
@@ -1212,6 +1251,7 @@ static struct i2c_driver nau8822_i2c_driver = {
12121251 .of_match_table = of_match_ptr (nau8822_of_match ),
12131252 },
12141253 .probe = nau8822_i2c_probe ,
1254+ .remove = nau8822_i2c_remove ,
12151255 .id_table = nau8822_i2c_id ,
12161256};
12171257module_i2c_driver (nau8822_i2c_driver );
0 commit comments