@@ -41,79 +41,74 @@ enum tpa_model {
41
41
TPA6140A2 ,
42
42
};
43
43
44
- static struct i2c_client * tpa6130a2_client ;
45
-
46
44
/* This struct is used to save the context */
47
45
struct tpa6130a2_data {
48
- struct mutex mutex ;
46
+ struct device * dev ;
49
47
struct regmap * regmap ;
50
48
struct regulator * supply ;
51
49
int power_gpio ;
52
- u8 power_state :1 ;
53
50
enum tpa_model id ;
54
51
};
55
52
56
- static int tpa6130a2_power (u8 power )
53
+ static int tpa6130a2_power (struct tpa6130a2_data * data , bool enable )
57
54
{
58
- struct tpa6130a2_data * data ;
59
- int ret = 0 ;
60
-
61
- if (WARN_ON (!tpa6130a2_client ))
62
- return - EINVAL ;
63
- data = i2c_get_clientdata (tpa6130a2_client );
64
-
65
- mutex_lock (& data -> mutex );
66
- if (power == data -> power_state )
67
- goto exit ;
55
+ int ret ;
68
56
69
- if (power ) {
57
+ if (enable ) {
70
58
ret = regulator_enable (data -> supply );
71
59
if (ret != 0 ) {
72
- dev_err (& tpa6130a2_client -> dev ,
60
+ dev_err (data -> dev ,
73
61
"Failed to enable supply: %d\n" , ret );
74
- goto exit ;
62
+ return ret ;
75
63
}
76
64
/* Power on */
77
65
if (data -> power_gpio >= 0 )
78
66
gpio_set_value (data -> power_gpio , 1 );
79
-
80
- data -> power_state = 1 ;
81
- ret = regcache_sync (data -> regmap );
82
- if (ret < 0 ) {
83
- dev_err (& tpa6130a2_client -> dev ,
84
- "Failed to initialize chip\n" );
85
- if (data -> power_gpio >= 0 )
86
- gpio_set_value (data -> power_gpio , 0 );
87
- regulator_disable (data -> supply );
88
- data -> power_state = 0 ;
89
- goto exit ;
90
- }
91
67
} else {
92
- /* set SWS */
93
- regmap_update_bits (data -> regmap , TPA6130A2_REG_CONTROL ,
94
- TPA6130A2_SWS , TPA6130A2_SWS );
95
-
96
68
/* Power off */
97
69
if (data -> power_gpio >= 0 )
98
70
gpio_set_value (data -> power_gpio , 0 );
99
71
100
72
ret = regulator_disable (data -> supply );
101
73
if (ret != 0 ) {
102
- dev_err (& tpa6130a2_client -> dev ,
74
+ dev_err (data -> dev ,
103
75
"Failed to disable supply: %d\n" , ret );
104
- goto exit ;
76
+ return ret ;
105
77
}
106
78
107
- data -> power_state = 0 ;
108
79
/* device regs does not match the cache state anymore */
109
80
regcache_mark_dirty (data -> regmap );
110
81
}
111
82
112
- exit :
113
- mutex_unlock (& data -> mutex );
114
83
return ret ;
115
84
}
116
85
86
+ static int tpa6130a2_power_event (struct snd_soc_dapm_widget * w ,
87
+ struct snd_kcontrol * kctrl , int event )
88
+ {
89
+ struct snd_soc_component * c = snd_soc_dapm_to_component (w -> dapm );
90
+ struct tpa6130a2_data * data = snd_soc_component_get_drvdata (c );
91
+ int ret ;
92
+
93
+ /* before widget power up */
94
+ if (SND_SOC_DAPM_EVENT_ON (event )) {
95
+ /* Turn on the chip */
96
+ tpa6130a2_power (data , true);
97
+ /* Sync the registers */
98
+ ret = regcache_sync (data -> regmap );
99
+ if (ret < 0 ) {
100
+ dev_err (c -> dev , "Failed to initialize chip\n" );
101
+ tpa6130a2_power (data , false);
102
+ return ret ;
103
+ }
104
+ /* after widget power down */
105
+ } else {
106
+ tpa6130a2_power (data , false);
107
+ }
108
+
109
+ return 0 ;
110
+ }
111
+
117
112
/*
118
113
* TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
119
114
* down in gain.
@@ -149,57 +144,6 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
149
144
tpa6140_tlv ),
150
145
};
151
146
152
- /*
153
- * Enable or disable channel (left or right)
154
- * The bit number for mute and amplifier are the same per channel:
155
- * bit 6: Right channel
156
- * bit 7: Left channel
157
- * in both registers.
158
- */
159
- static void tpa6130a2_channel_enable (u8 channel , int enable )
160
- {
161
- struct tpa6130a2_data * data = i2c_get_clientdata (tpa6130a2_client );
162
-
163
- if (enable ) {
164
- /* Enable channel */
165
- /* Enable amplifier */
166
- regmap_update_bits (data -> regmap , TPA6130A2_REG_CONTROL ,
167
- channel | TPA6130A2_SWS , channel & ~TPA6130A2_SWS );
168
-
169
- /* Unmute channel */
170
- regmap_update_bits (data -> regmap , TPA6130A2_REG_VOL_MUTE ,
171
- channel , 0 );
172
- } else {
173
- /* Disable channel */
174
- /* Mute channel */
175
- regmap_update_bits (data -> regmap , TPA6130A2_REG_VOL_MUTE ,
176
- channel , channel );
177
-
178
- /* Disable amplifier */
179
- regmap_update_bits (data -> regmap , TPA6130A2_REG_CONTROL ,
180
- channel , 0 );
181
- }
182
- }
183
-
184
- int tpa6130a2_stereo_enable (struct snd_soc_codec * codec , int enable )
185
- {
186
- int ret = 0 ;
187
- if (enable ) {
188
- ret = tpa6130a2_power (1 );
189
- if (ret < 0 )
190
- return ret ;
191
- tpa6130a2_channel_enable (TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L ,
192
- 1 );
193
- } else {
194
- tpa6130a2_channel_enable (TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L ,
195
- 0 );
196
- ret = tpa6130a2_power (0 );
197
- }
198
-
199
- return ret ;
200
- }
201
- EXPORT_SYMBOL_GPL (tpa6130a2_stereo_enable );
202
-
203
147
static int tpa6130a2_component_probe (struct snd_soc_component * component )
204
148
{
205
149
struct tpa6130a2_data * data = snd_soc_component_get_drvdata (component );
@@ -212,9 +156,47 @@ static int tpa6130a2_component_probe(struct snd_soc_component *component)
212
156
tpa6130a2_controls , ARRAY_SIZE (tpa6130a2_controls ));
213
157
}
214
158
159
+ static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets [] = {
160
+ SND_SOC_DAPM_INPUT ("LEFTIN" ),
161
+ SND_SOC_DAPM_INPUT ("RIGHTIN" ),
162
+ SND_SOC_DAPM_OUTPUT ("HPLEFT" ),
163
+ SND_SOC_DAPM_OUTPUT ("HPRIGHT" ),
164
+
165
+ SND_SOC_DAPM_PGA ("Left Mute" , TPA6130A2_REG_VOL_MUTE ,
166
+ TPA6130A2_HP_EN_L_SHIFT , 1 , NULL , 0 ),
167
+ SND_SOC_DAPM_PGA ("Right Mute" , TPA6130A2_REG_VOL_MUTE ,
168
+ TPA6130A2_HP_EN_R_SHIFT , 1 , NULL , 0 ),
169
+ SND_SOC_DAPM_PGA ("Left PGA" , TPA6130A2_REG_CONTROL ,
170
+ TPA6130A2_HP_EN_L_SHIFT , 0 , NULL , 0 ),
171
+ SND_SOC_DAPM_PGA ("Right PGA" , TPA6130A2_REG_CONTROL ,
172
+ TPA6130A2_HP_EN_R_SHIFT , 0 , NULL , 0 ),
173
+
174
+ SND_SOC_DAPM_SUPPLY ("Power" , TPA6130A2_REG_CONTROL ,
175
+ TPA6130A2_SWS_SHIFT , 1 , tpa6130a2_power_event ,
176
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD ),
177
+ };
178
+
179
+ static const struct snd_soc_dapm_route tpa6130a2_dapm_routes [] = {
180
+ { "Left PGA" , NULL , "LEFTIN" },
181
+ { "Right PGA" , NULL , "RIGHTIN" },
182
+
183
+ { "Left Mute" , NULL , "Left PGA" },
184
+ { "Right Mute" , NULL , "Right PGA" },
185
+
186
+ { "HPLEFT" , NULL , "Left Mute" },
187
+ { "HPRIGHT" , NULL , "Right Mute" },
188
+
189
+ { "Left PGA" , NULL , "Power" },
190
+ { "Right PGA" , NULL , "Power" },
191
+ };
192
+
215
193
struct snd_soc_component_driver tpa6130a2_component_driver = {
216
194
.name = "tpa6130a2" ,
217
195
.probe = tpa6130a2_component_probe ,
196
+ .dapm_widgets = tpa6130a2_dapm_widgets ,
197
+ .num_dapm_widgets = ARRAY_SIZE (tpa6130a2_dapm_widgets ),
198
+ .dapm_routes = tpa6130a2_dapm_routes ,
199
+ .num_dapm_routes = ARRAY_SIZE (tpa6130a2_dapm_routes ),
218
200
};
219
201
220
202
static const struct reg_default tpa6130a2_reg_defaults [] = {
@@ -248,6 +230,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
248
230
if (!data )
249
231
return - ENOMEM ;
250
232
233
+ data -> dev = dev ;
234
+
251
235
data -> regmap = devm_regmap_init_i2c (client , & tpa6130a2_regmap_config );
252
236
if (IS_ERR (data -> regmap ))
253
237
return PTR_ERR (data -> regmap );
@@ -262,14 +246,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
262
246
return - ENODEV ;
263
247
}
264
248
265
- tpa6130a2_client = client ;
266
-
267
- i2c_set_clientdata (tpa6130a2_client , data );
249
+ i2c_set_clientdata (client , data );
268
250
269
251
data -> id = id -> driver_data ;
270
252
271
- mutex_init (& data -> mutex );
272
-
273
253
if (data -> power_gpio >= 0 ) {
274
254
ret = devm_gpio_request (dev , data -> power_gpio ,
275
255
"tpa6130a2 enable" );
@@ -300,7 +280,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
300
280
goto err_gpio ;
301
281
}
302
282
303
- ret = tpa6130a2_power (1 );
283
+ ret = tpa6130a2_power (data , true );
304
284
if (ret != 0 )
305
285
goto err_gpio ;
306
286
@@ -312,27 +292,17 @@ static int tpa6130a2_probe(struct i2c_client *client,
312
292
dev_warn (dev , "UNTESTED version detected (%d)\n" , version );
313
293
314
294
/* Disable the chip */
315
- ret = tpa6130a2_power (0 );
295
+ ret = tpa6130a2_power (data , false );
316
296
if (ret != 0 )
317
297
goto err_gpio ;
318
298
319
299
return devm_snd_soc_register_component (& client -> dev ,
320
300
& tpa6130a2_component_driver , NULL , 0 );
321
301
322
302
err_gpio :
323
- tpa6130a2_client = NULL ;
324
-
325
303
return ret ;
326
304
}
327
305
328
- static int tpa6130a2_remove (struct i2c_client * client )
329
- {
330
- tpa6130a2_power (0 );
331
- tpa6130a2_client = NULL ;
332
-
333
- return 0 ;
334
- }
335
-
336
306
static const struct i2c_device_id tpa6130a2_id [] = {
337
307
{ "tpa6130a2" , TPA6130A2 },
338
308
{ "tpa6140a2" , TPA6140A2 },
@@ -355,7 +325,6 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
355
325
.of_match_table = of_match_ptr (tpa6130a2_of_match ),
356
326
},
357
327
.probe = tpa6130a2_probe ,
358
- .remove = tpa6130a2_remove ,
359
328
.id_table = tpa6130a2_id ,
360
329
};
361
330
0 commit comments