1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#include <linux/module.h>
36#include <linux/moduleparam.h>
37#include <linux/init.h>
38#include <linux/delay.h>
39#include <linux/pm.h>
40#include <linux/i2c.h>
41#include <linux/gpio.h>
42#include <linux/regulator/consumer.h>
43#include <linux/of_gpio.h>
44#include <linux/slab.h>
45#include <sound/core.h>
46#include <sound/pcm.h>
47#include <sound/pcm_params.h>
48#include <sound/soc.h>
49#include <sound/initval.h>
50#include <sound/tlv.h>
51#include <sound/tlv320aic3x.h>
52
53#include "tlv320aic3x.h"
54
55#define AIC3X_NUM_SUPPLIES 4
56static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
57 "IOVDD",
58 "DVDD",
59 "AVDD",
60 "DRVDD",
61};
62
63static LIST_HEAD(reset_list);
64
65struct aic3x_priv;
66
67struct aic3x_disable_nb {
68 struct notifier_block nb;
69 struct aic3x_priv *aic3x;
70};
71
72
73struct aic3x_priv {
74 struct snd_soc_codec *codec;
75 struct regulator_bulk_data supplies[AIC3X_NUM_SUPPLIES];
76 struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES];
77 enum snd_soc_control_type control_type;
78 struct aic3x_setup_data *setup;
79 unsigned int sysclk;
80 struct list_head list;
81 int master;
82 int gpio_reset;
83 int power;
84#define AIC3X_MODEL_3X 0
85#define AIC3X_MODEL_33 1
86#define AIC3X_MODEL_3007 2
87 u16 model;
88};
89
90
91
92
93
94
95
96static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
97 0x00, 0x00, 0x00, 0x10,
98 0x04, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x01,
100 0x00, 0x00, 0x00, 0x80,
101 0x80, 0xff, 0xff, 0x78,
102 0x78, 0x78, 0x78, 0x78,
103 0x78, 0x00, 0x00, 0xfe,
104 0x00, 0x00, 0xfe, 0x00,
105 0x18, 0x18, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x80,
108 0x80, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x04,
110 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x04, 0x00,
112 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x04, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00,
115 0x04, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x02, 0x00,
123 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00,
125};
126
127#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
128{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
129 .info = snd_soc_info_volsw, \
130 .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw_aic3x, \
131 .private_value = SOC_SINGLE_VALUE(reg, shift, mask, invert) }
132
133
134
135
136
137static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
138 struct snd_ctl_elem_value *ucontrol)
139{
140 struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
141 struct snd_soc_dapm_widget *widget = wlist->widgets[0];
142 struct soc_mixer_control *mc =
143 (struct soc_mixer_control *)kcontrol->private_value;
144 unsigned int reg = mc->reg;
145 unsigned int shift = mc->shift;
146 int max = mc->max;
147 unsigned int mask = (1 << fls(max)) - 1;
148 unsigned int invert = mc->invert;
149 unsigned short val, val_mask;
150 int ret;
151 struct snd_soc_dapm_path *path;
152 int found = 0;
153
154 val = (ucontrol->value.integer.value[0] & mask);
155
156 mask = 0xf;
157 if (val)
158 val = mask;
159
160 if (invert)
161 val = mask - val;
162 val_mask = mask << shift;
163 val = val << shift;
164
165 mutex_lock(&widget->codec->mutex);
166
167 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
168
169 list_for_each_entry(path, &widget->dapm->card->paths, list) {
170 if (path->kcontrol != kcontrol)
171 continue;
172
173
174 found = 1;
175 if (val)
176
177 path->connect = invert ? 0 : 1;
178 else
179
180 path->connect = invert ? 1 : 0;
181
182 dapm_mark_dirty(path->source, "tlv320aic3x source");
183 dapm_mark_dirty(path->sink, "tlv320aic3x sink");
184
185 break;
186 }
187
188 if (found)
189 snd_soc_dapm_sync(widget->dapm);
190 }
191
192 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
193
194 mutex_unlock(&widget->codec->mutex);
195 return ret;
196}
197
198static const char *aic3x_left_dac_mux[] = { "DAC_L1", "DAC_L3", "DAC_L2" };
199static const char *aic3x_right_dac_mux[] = { "DAC_R1", "DAC_R3", "DAC_R2" };
200static const char *aic3x_left_hpcom_mux[] =
201 { "differential of HPLOUT", "constant VCM", "single-ended" };
202static const char *aic3x_right_hpcom_mux[] =
203 { "differential of HPROUT", "constant VCM", "single-ended",
204 "differential of HPLCOM", "external feedback" };
205static const char *aic3x_linein_mode_mux[] = { "single-ended", "differential" };
206static const char *aic3x_adc_hpf[] =
207 { "Disabled", "0.0045xFs", "0.0125xFs", "0.025xFs" };
208
209#define LDAC_ENUM 0
210#define RDAC_ENUM 1
211#define LHPCOM_ENUM 2
212#define RHPCOM_ENUM 3
213#define LINE1L_2_L_ENUM 4
214#define LINE1L_2_R_ENUM 5
215#define LINE1R_2_L_ENUM 6
216#define LINE1R_2_R_ENUM 7
217#define LINE2L_ENUM 8
218#define LINE2R_ENUM 9
219#define ADC_HPF_ENUM 10
220
221static const struct soc_enum aic3x_enum[] = {
222 SOC_ENUM_SINGLE(DAC_LINE_MUX, 6, 3, aic3x_left_dac_mux),
223 SOC_ENUM_SINGLE(DAC_LINE_MUX, 4, 3, aic3x_right_dac_mux),
224 SOC_ENUM_SINGLE(HPLCOM_CFG, 4, 3, aic3x_left_hpcom_mux),
225 SOC_ENUM_SINGLE(HPRCOM_CFG, 3, 5, aic3x_right_hpcom_mux),
226 SOC_ENUM_SINGLE(LINE1L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
227 SOC_ENUM_SINGLE(LINE1L_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
228 SOC_ENUM_SINGLE(LINE1R_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
229 SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
230 SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 7, 2, aic3x_linein_mode_mux),
231 SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 7, 2, aic3x_linein_mode_mux),
232 SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf),
233};
234
235static const char *aic3x_agc_level[] =
236 { "-5.5dB", "-8dB", "-10dB", "-12dB", "-14dB", "-17dB", "-20dB", "-24dB" };
237static const struct soc_enum aic3x_agc_level_enum[] = {
238 SOC_ENUM_SINGLE(LAGC_CTRL_A, 4, 8, aic3x_agc_level),
239 SOC_ENUM_SINGLE(RAGC_CTRL_A, 4, 8, aic3x_agc_level),
240};
241
242static const char *aic3x_agc_attack[] = { "8ms", "11ms", "16ms", "20ms" };
243static const struct soc_enum aic3x_agc_attack_enum[] = {
244 SOC_ENUM_SINGLE(LAGC_CTRL_A, 2, 4, aic3x_agc_attack),
245 SOC_ENUM_SINGLE(RAGC_CTRL_A, 2, 4, aic3x_agc_attack),
246};
247
248static const char *aic3x_agc_decay[] = { "100ms", "200ms", "400ms", "500ms" };
249static const struct soc_enum aic3x_agc_decay_enum[] = {
250 SOC_ENUM_SINGLE(LAGC_CTRL_A, 0, 4, aic3x_agc_decay),
251 SOC_ENUM_SINGLE(RAGC_CTRL_A, 0, 4, aic3x_agc_decay),
252};
253
254
255
256
257static DECLARE_TLV_DB_SCALE(dac_tlv, -6350, 50, 0);
258
259static DECLARE_TLV_DB_SCALE(adc_tlv, 0, 50, 0);
260
261
262
263
264
265
266
267
268
269static DECLARE_TLV_DB_SCALE(output_stage_tlv, -5900, 50, 1);
270
271static const struct snd_kcontrol_new aic3x_snd_controls[] = {
272
273 SOC_DOUBLE_R_TLV("PCM Playback Volume",
274 LDAC_VOL, RDAC_VOL, 0, 0x7f, 1, dac_tlv),
275
276
277
278
279
280
281 SOC_SINGLE_TLV("Left Line Mixer Line2R Bypass Volume",
282 LINE2R_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
283 SOC_SINGLE_TLV("Left Line Mixer PGAR Bypass Volume",
284 PGAR_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
285 SOC_SINGLE_TLV("Left Line Mixer DACR1 Playback Volume",
286 DACR1_2_LLOPM_VOL, 0, 118, 1, output_stage_tlv),
287
288 SOC_SINGLE_TLV("Right Line Mixer Line2L Bypass Volume",
289 LINE2L_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
290 SOC_SINGLE_TLV("Right Line Mixer PGAL Bypass Volume",
291 PGAL_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
292 SOC_SINGLE_TLV("Right Line Mixer DACL1 Playback Volume",
293 DACL1_2_RLOPM_VOL, 0, 118, 1, output_stage_tlv),
294
295 SOC_SINGLE_TLV("Left HP Mixer Line2R Bypass Volume",
296 LINE2R_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
297 SOC_SINGLE_TLV("Left HP Mixer PGAR Bypass Volume",
298 PGAR_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
299 SOC_SINGLE_TLV("Left HP Mixer DACR1 Playback Volume",
300 DACR1_2_HPLOUT_VOL, 0, 118, 1, output_stage_tlv),
301
302 SOC_SINGLE_TLV("Right HP Mixer Line2L Bypass Volume",
303 LINE2L_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
304 SOC_SINGLE_TLV("Right HP Mixer PGAL Bypass Volume",
305 PGAL_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
306 SOC_SINGLE_TLV("Right HP Mixer DACL1 Playback Volume",
307 DACL1_2_HPROUT_VOL, 0, 118, 1, output_stage_tlv),
308
309 SOC_SINGLE_TLV("Left HPCOM Mixer Line2R Bypass Volume",
310 LINE2R_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
311 SOC_SINGLE_TLV("Left HPCOM Mixer PGAR Bypass Volume",
312 PGAR_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
313 SOC_SINGLE_TLV("Left HPCOM Mixer DACR1 Playback Volume",
314 DACR1_2_HPLCOM_VOL, 0, 118, 1, output_stage_tlv),
315
316 SOC_SINGLE_TLV("Right HPCOM Mixer Line2L Bypass Volume",
317 LINE2L_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
318 SOC_SINGLE_TLV("Right HPCOM Mixer PGAL Bypass Volume",
319 PGAL_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
320 SOC_SINGLE_TLV("Right HPCOM Mixer DACL1 Playback Volume",
321 DACL1_2_HPRCOM_VOL, 0, 118, 1, output_stage_tlv),
322
323
324 SOC_DOUBLE_R_TLV("Line Line2 Bypass Volume",
325 LINE2L_2_LLOPM_VOL, LINE2R_2_RLOPM_VOL,
326 0, 118, 1, output_stage_tlv),
327 SOC_DOUBLE_R_TLV("Line PGA Bypass Volume",
328 PGAL_2_LLOPM_VOL, PGAR_2_RLOPM_VOL,
329 0, 118, 1, output_stage_tlv),
330 SOC_DOUBLE_R_TLV("Line DAC Playback Volume",
331 DACL1_2_LLOPM_VOL, DACR1_2_RLOPM_VOL,
332 0, 118, 1, output_stage_tlv),
333
334 SOC_DOUBLE_R_TLV("Mono Line2 Bypass Volume",
335 LINE2L_2_MONOLOPM_VOL, LINE2R_2_MONOLOPM_VOL,
336 0, 118, 1, output_stage_tlv),
337 SOC_DOUBLE_R_TLV("Mono PGA Bypass Volume",
338 PGAL_2_MONOLOPM_VOL, PGAR_2_MONOLOPM_VOL,
339 0, 118, 1, output_stage_tlv),
340 SOC_DOUBLE_R_TLV("Mono DAC Playback Volume",
341 DACL1_2_MONOLOPM_VOL, DACR1_2_MONOLOPM_VOL,
342 0, 118, 1, output_stage_tlv),
343
344 SOC_DOUBLE_R_TLV("HP Line2 Bypass Volume",
345 LINE2L_2_HPLOUT_VOL, LINE2R_2_HPROUT_VOL,
346 0, 118, 1, output_stage_tlv),
347 SOC_DOUBLE_R_TLV("HP PGA Bypass Volume",
348 PGAL_2_HPLOUT_VOL, PGAR_2_HPROUT_VOL,
349 0, 118, 1, output_stage_tlv),
350 SOC_DOUBLE_R_TLV("HP DAC Playback Volume",
351 DACL1_2_HPLOUT_VOL, DACR1_2_HPROUT_VOL,
352 0, 118, 1, output_stage_tlv),
353
354 SOC_DOUBLE_R_TLV("HPCOM Line2 Bypass Volume",
355 LINE2L_2_HPLCOM_VOL, LINE2R_2_HPRCOM_VOL,
356 0, 118, 1, output_stage_tlv),
357 SOC_DOUBLE_R_TLV("HPCOM PGA Bypass Volume",
358 PGAL_2_HPLCOM_VOL, PGAR_2_HPRCOM_VOL,
359 0, 118, 1, output_stage_tlv),
360 SOC_DOUBLE_R_TLV("HPCOM DAC Playback Volume",
361 DACL1_2_HPLCOM_VOL, DACR1_2_HPRCOM_VOL,
362 0, 118, 1, output_stage_tlv),
363
364
365 SOC_DOUBLE_R("Line Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3,
366 0x01, 0),
367 SOC_SINGLE("Mono Playback Switch", MONOLOPM_CTRL, 3, 0x01, 0),
368 SOC_DOUBLE_R("HP Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
369 0x01, 0),
370 SOC_DOUBLE_R("HPCOM Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
371 0x01, 0),
372
373
374
375
376
377 SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0),
378 SOC_ENUM("Left AGC Target level", aic3x_agc_level_enum[0]),
379 SOC_ENUM("Right AGC Target level", aic3x_agc_level_enum[1]),
380 SOC_ENUM("Left AGC Attack time", aic3x_agc_attack_enum[0]),
381 SOC_ENUM("Right AGC Attack time", aic3x_agc_attack_enum[1]),
382 SOC_ENUM("Left AGC Decay time", aic3x_agc_decay_enum[0]),
383 SOC_ENUM("Right AGC Decay time", aic3x_agc_decay_enum[1]),
384
385
386 SOC_DOUBLE("De-emphasis Switch", AIC3X_CODEC_DFILT_CTRL, 2, 0, 0x01, 0),
387
388
389 SOC_DOUBLE_R_TLV("PGA Capture Volume", LADC_VOL, RADC_VOL,
390 0, 119, 0, adc_tlv),
391 SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1),
392
393 SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]),
394};
395
396
397
398
399static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0);
400
401static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl =
402 SOC_DOUBLE_TLV("Class-D Playback Volume", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv);
403
404
405static const struct snd_kcontrol_new aic3x_left_dac_mux_controls =
406SOC_DAPM_ENUM("Route", aic3x_enum[LDAC_ENUM]);
407
408
409static const struct snd_kcontrol_new aic3x_right_dac_mux_controls =
410SOC_DAPM_ENUM("Route", aic3x_enum[RDAC_ENUM]);
411
412
413static const struct snd_kcontrol_new aic3x_left_hpcom_mux_controls =
414SOC_DAPM_ENUM("Route", aic3x_enum[LHPCOM_ENUM]);
415
416
417static const struct snd_kcontrol_new aic3x_right_hpcom_mux_controls =
418SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]);
419
420
421static const struct snd_kcontrol_new aic3x_left_line_mixer_controls[] = {
422 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
423 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
424 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_LLOPM_VOL, 7, 1, 0),
425 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
426 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_LLOPM_VOL, 7, 1, 0),
427 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_LLOPM_VOL, 7, 1, 0),
428};
429
430
431static const struct snd_kcontrol_new aic3x_right_line_mixer_controls[] = {
432 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
433 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_RLOPM_VOL, 7, 1, 0),
434 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_RLOPM_VOL, 7, 1, 0),
435 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
436 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
437 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_RLOPM_VOL, 7, 1, 0),
438};
439
440
441static const struct snd_kcontrol_new aic3x_mono_mixer_controls[] = {
442 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0),
443 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0),
444 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0),
445 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0),
446 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0),
447 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0),
448};
449
450
451static const struct snd_kcontrol_new aic3x_left_hp_mixer_controls[] = {
452 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
453 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
454 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0),
455 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLOUT_VOL, 7, 1, 0),
456 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0),
457 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLOUT_VOL, 7, 1, 0),
458};
459
460
461static const struct snd_kcontrol_new aic3x_right_hp_mixer_controls[] = {
462 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPROUT_VOL, 7, 1, 0),
463 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPROUT_VOL, 7, 1, 0),
464 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPROUT_VOL, 7, 1, 0),
465 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
466 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
467 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPROUT_VOL, 7, 1, 0),
468};
469
470
471static const struct snd_kcontrol_new aic3x_left_hpcom_mixer_controls[] = {
472 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
473 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
474 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0),
475 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPLCOM_VOL, 7, 1, 0),
476 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0),
477 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPLCOM_VOL, 7, 1, 0),
478};
479
480
481static const struct snd_kcontrol_new aic3x_right_hpcom_mixer_controls[] = {
482 SOC_DAPM_SINGLE("Line2L Bypass Switch", LINE2L_2_HPRCOM_VOL, 7, 1, 0),
483 SOC_DAPM_SINGLE("PGAL Bypass Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0),
484 SOC_DAPM_SINGLE("DACL1 Switch", DACL1_2_HPRCOM_VOL, 7, 1, 0),
485 SOC_DAPM_SINGLE("Line2R Bypass Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
486 SOC_DAPM_SINGLE("PGAR Bypass Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
487 SOC_DAPM_SINGLE("DACR1 Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0),
488};
489
490
491static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] = {
492 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1),
493 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_LADC_CTRL, 3, 1, 1),
494 SOC_DAPM_SINGLE_AIC3X("Line2L Switch", LINE2L_2_LADC_CTRL, 3, 1, 1),
495 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1),
496 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_LADC_CTRL, 0, 1, 1),
497};
498
499
500static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = {
501 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1),
502 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_RADC_CTRL, 3, 1, 1),
503 SOC_DAPM_SINGLE_AIC3X("Line2R Switch", LINE2R_2_RADC_CTRL, 3, 1, 1),
504 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_RADC_CTRL, 4, 1, 1),
505 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1),
506};
507
508
509static const struct snd_kcontrol_new aic3x_left_line1l_mux_controls =
510SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_L_ENUM]);
511static const struct snd_kcontrol_new aic3x_right_line1l_mux_controls =
512SOC_DAPM_ENUM("Route", aic3x_enum[LINE1L_2_R_ENUM]);
513
514
515static const struct snd_kcontrol_new aic3x_right_line1r_mux_controls =
516SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_R_ENUM]);
517static const struct snd_kcontrol_new aic3x_left_line1r_mux_controls =
518SOC_DAPM_ENUM("Route", aic3x_enum[LINE1R_2_L_ENUM]);
519
520
521static const struct snd_kcontrol_new aic3x_left_line2_mux_controls =
522SOC_DAPM_ENUM("Route", aic3x_enum[LINE2L_ENUM]);
523
524
525static const struct snd_kcontrol_new aic3x_right_line2_mux_controls =
526SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]);
527
528static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
529
530 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", DAC_PWR, 7, 0),
531 SND_SOC_DAPM_MUX("Left DAC Mux", SND_SOC_NOPM, 0, 0,
532 &aic3x_left_dac_mux_controls),
533 SND_SOC_DAPM_MUX("Left HPCOM Mux", SND_SOC_NOPM, 0, 0,
534 &aic3x_left_hpcom_mux_controls),
535 SND_SOC_DAPM_PGA("Left Line Out", LLOPM_CTRL, 0, 0, NULL, 0),
536 SND_SOC_DAPM_PGA("Left HP Out", HPLOUT_CTRL, 0, 0, NULL, 0),
537 SND_SOC_DAPM_PGA("Left HP Com", HPLCOM_CTRL, 0, 0, NULL, 0),
538
539
540 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", DAC_PWR, 6, 0),
541 SND_SOC_DAPM_MUX("Right DAC Mux", SND_SOC_NOPM, 0, 0,
542 &aic3x_right_dac_mux_controls),
543 SND_SOC_DAPM_MUX("Right HPCOM Mux", SND_SOC_NOPM, 0, 0,
544 &aic3x_right_hpcom_mux_controls),
545 SND_SOC_DAPM_PGA("Right Line Out", RLOPM_CTRL, 0, 0, NULL, 0),
546 SND_SOC_DAPM_PGA("Right HP Out", HPROUT_CTRL, 0, 0, NULL, 0),
547 SND_SOC_DAPM_PGA("Right HP Com", HPRCOM_CTRL, 0, 0, NULL, 0),
548
549
550 SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0),
551
552
553 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0),
554 SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0,
555 &aic3x_left_pga_mixer_controls[0],
556 ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
557 SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
558 &aic3x_left_line1l_mux_controls),
559 SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
560 &aic3x_left_line1r_mux_controls),
561 SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
562 &aic3x_left_line2_mux_controls),
563
564
565 SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
566 LINE1R_2_RADC_CTRL, 2, 0),
567 SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0,
568 &aic3x_right_pga_mixer_controls[0],
569 ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
570 SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
571 &aic3x_right_line1l_mux_controls),
572 SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0,
573 &aic3x_right_line1r_mux_controls),
574 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
575 &aic3x_right_line2_mux_controls),
576
577
578
579
580
581
582 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "GPIO1 dmic modclk",
583 AIC3X_GPIO1_REG, 4, 0xf,
584 AIC3X_GPIO1_FUNC_DIGITAL_MIC_MODCLK,
585 AIC3X_GPIO1_FUNC_DISABLED),
586
587
588
589
590
591 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 128",
592 AIC3X_ASD_INTF_CTRLA, 0, 3, 1, 0),
593 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 64",
594 AIC3X_ASD_INTF_CTRLA, 0, 3, 2, 0),
595 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 32",
596 AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0),
597
598
599 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2V",
600 MICBIAS_CTRL, 6, 3, 1, 0),
601 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias 2.5V",
602 MICBIAS_CTRL, 6, 3, 2, 0),
603 SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "Mic Bias AVDD",
604 MICBIAS_CTRL, 6, 3, 3, 0),
605
606
607 SND_SOC_DAPM_MIXER("Left Line Mixer", SND_SOC_NOPM, 0, 0,
608 &aic3x_left_line_mixer_controls[0],
609 ARRAY_SIZE(aic3x_left_line_mixer_controls)),
610 SND_SOC_DAPM_MIXER("Right Line Mixer", SND_SOC_NOPM, 0, 0,
611 &aic3x_right_line_mixer_controls[0],
612 ARRAY_SIZE(aic3x_right_line_mixer_controls)),
613 SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0,
614 &aic3x_mono_mixer_controls[0],
615 ARRAY_SIZE(aic3x_mono_mixer_controls)),
616 SND_SOC_DAPM_MIXER("Left HP Mixer", SND_SOC_NOPM, 0, 0,
617 &aic3x_left_hp_mixer_controls[0],
618 ARRAY_SIZE(aic3x_left_hp_mixer_controls)),
619 SND_SOC_DAPM_MIXER("Right HP Mixer", SND_SOC_NOPM, 0, 0,
620 &aic3x_right_hp_mixer_controls[0],
621 ARRAY_SIZE(aic3x_right_hp_mixer_controls)),
622 SND_SOC_DAPM_MIXER("Left HPCOM Mixer", SND_SOC_NOPM, 0, 0,
623 &aic3x_left_hpcom_mixer_controls[0],
624 ARRAY_SIZE(aic3x_left_hpcom_mixer_controls)),
625 SND_SOC_DAPM_MIXER("Right HPCOM Mixer", SND_SOC_NOPM, 0, 0,
626 &aic3x_right_hpcom_mixer_controls[0],
627 ARRAY_SIZE(aic3x_right_hpcom_mixer_controls)),
628
629 SND_SOC_DAPM_OUTPUT("LLOUT"),
630 SND_SOC_DAPM_OUTPUT("RLOUT"),
631 SND_SOC_DAPM_OUTPUT("MONO_LOUT"),
632 SND_SOC_DAPM_OUTPUT("HPLOUT"),
633 SND_SOC_DAPM_OUTPUT("HPROUT"),
634 SND_SOC_DAPM_OUTPUT("HPLCOM"),
635 SND_SOC_DAPM_OUTPUT("HPRCOM"),
636
637 SND_SOC_DAPM_INPUT("MIC3L"),
638 SND_SOC_DAPM_INPUT("MIC3R"),
639 SND_SOC_DAPM_INPUT("LINE1L"),
640 SND_SOC_DAPM_INPUT("LINE1R"),
641 SND_SOC_DAPM_INPUT("LINE2L"),
642 SND_SOC_DAPM_INPUT("LINE2R"),
643
644
645
646
647
648
649
650 SND_SOC_DAPM_OUTPUT("Detection"),
651};
652
653static const struct snd_soc_dapm_widget aic3007_dapm_widgets[] = {
654
655 SND_SOC_DAPM_PGA("Left Class-D Out", CLASSD_CTRL, 3, 0, NULL, 0),
656 SND_SOC_DAPM_PGA("Right Class-D Out", CLASSD_CTRL, 2, 0, NULL, 0),
657
658 SND_SOC_DAPM_OUTPUT("SPOP"),
659 SND_SOC_DAPM_OUTPUT("SPOM"),
660};
661
662static const struct snd_soc_dapm_route intercon[] = {
663
664 {"Left Line1L Mux", "single-ended", "LINE1L"},
665 {"Left Line1L Mux", "differential", "LINE1L"},
666
667 {"Left Line2L Mux", "single-ended", "LINE2L"},
668 {"Left Line2L Mux", "differential", "LINE2L"},
669
670 {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"},
671 {"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"},
672 {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"},
673 {"Left PGA Mixer", "Mic3L Switch", "MIC3L"},
674 {"Left PGA Mixer", "Mic3R Switch", "MIC3R"},
675
676 {"Left ADC", NULL, "Left PGA Mixer"},
677 {"Left ADC", NULL, "GPIO1 dmic modclk"},
678
679
680 {"Right Line1R Mux", "single-ended", "LINE1R"},
681 {"Right Line1R Mux", "differential", "LINE1R"},
682
683 {"Right Line2R Mux", "single-ended", "LINE2R"},
684 {"Right Line2R Mux", "differential", "LINE2R"},
685
686 {"Right PGA Mixer", "Line1L Switch", "Right Line1L Mux"},
687 {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"},
688 {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"},
689 {"Right PGA Mixer", "Mic3L Switch", "MIC3L"},
690 {"Right PGA Mixer", "Mic3R Switch", "MIC3R"},
691
692 {"Right ADC", NULL, "Right PGA Mixer"},
693 {"Right ADC", NULL, "GPIO1 dmic modclk"},
694
695
696
697
698
699 {"GPIO1 dmic modclk", NULL, "DMic Rate 128"},
700 {"GPIO1 dmic modclk", NULL, "DMic Rate 64"},
701 {"GPIO1 dmic modclk", NULL, "DMic Rate 32"},
702
703
704 {"Left DAC Mux", "DAC_L1", "Left DAC"},
705 {"Left DAC Mux", "DAC_L2", "Left DAC"},
706 {"Left DAC Mux", "DAC_L3", "Left DAC"},
707
708
709 {"Right DAC Mux", "DAC_R1", "Right DAC"},
710 {"Right DAC Mux", "DAC_R2", "Right DAC"},
711 {"Right DAC Mux", "DAC_R3", "Right DAC"},
712
713
714 {"Left Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
715 {"Left Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
716 {"Left Line Mixer", "DACL1 Switch", "Left DAC Mux"},
717 {"Left Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
718 {"Left Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
719 {"Left Line Mixer", "DACR1 Switch", "Right DAC Mux"},
720
721 {"Left Line Out", NULL, "Left Line Mixer"},
722 {"Left Line Out", NULL, "Left DAC Mux"},
723 {"LLOUT", NULL, "Left Line Out"},
724
725
726 {"Right Line Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
727 {"Right Line Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
728 {"Right Line Mixer", "DACL1 Switch", "Left DAC Mux"},
729 {"Right Line Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
730 {"Right Line Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
731 {"Right Line Mixer", "DACR1 Switch", "Right DAC Mux"},
732
733 {"Right Line Out", NULL, "Right Line Mixer"},
734 {"Right Line Out", NULL, "Right DAC Mux"},
735 {"RLOUT", NULL, "Right Line Out"},
736
737
738 {"Mono Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
739 {"Mono Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
740 {"Mono Mixer", "DACL1 Switch", "Left DAC Mux"},
741 {"Mono Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
742 {"Mono Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
743 {"Mono Mixer", "DACR1 Switch", "Right DAC Mux"},
744
745 {"Mono Out", NULL, "Mono Mixer"},
746 {"MONO_LOUT", NULL, "Mono Out"},
747
748
749 {"Left HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
750 {"Left HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
751 {"Left HP Mixer", "DACL1 Switch", "Left DAC Mux"},
752 {"Left HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
753 {"Left HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
754 {"Left HP Mixer", "DACR1 Switch", "Right DAC Mux"},
755
756 {"Left HP Out", NULL, "Left HP Mixer"},
757 {"Left HP Out", NULL, "Left DAC Mux"},
758 {"HPLOUT", NULL, "Left HP Out"},
759
760
761 {"Right HP Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
762 {"Right HP Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
763 {"Right HP Mixer", "DACL1 Switch", "Left DAC Mux"},
764 {"Right HP Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
765 {"Right HP Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
766 {"Right HP Mixer", "DACR1 Switch", "Right DAC Mux"},
767
768 {"Right HP Out", NULL, "Right HP Mixer"},
769 {"Right HP Out", NULL, "Right DAC Mux"},
770 {"HPROUT", NULL, "Right HP Out"},
771
772
773 {"Left HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
774 {"Left HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
775 {"Left HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"},
776 {"Left HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
777 {"Left HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
778 {"Left HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"},
779
780 {"Left HPCOM Mux", "differential of HPLOUT", "Left HP Mixer"},
781 {"Left HPCOM Mux", "constant VCM", "Left HPCOM Mixer"},
782 {"Left HPCOM Mux", "single-ended", "Left HPCOM Mixer"},
783 {"Left HP Com", NULL, "Left HPCOM Mux"},
784 {"HPLCOM", NULL, "Left HP Com"},
785
786
787 {"Right HPCOM Mixer", "Line2L Bypass Switch", "Left Line2L Mux"},
788 {"Right HPCOM Mixer", "PGAL Bypass Switch", "Left PGA Mixer"},
789 {"Right HPCOM Mixer", "DACL1 Switch", "Left DAC Mux"},
790 {"Right HPCOM Mixer", "Line2R Bypass Switch", "Right Line2R Mux"},
791 {"Right HPCOM Mixer", "PGAR Bypass Switch", "Right PGA Mixer"},
792 {"Right HPCOM Mixer", "DACR1 Switch", "Right DAC Mux"},
793
794 {"Right HPCOM Mux", "differential of HPROUT", "Right HP Mixer"},
795 {"Right HPCOM Mux", "constant VCM", "Right HPCOM Mixer"},
796 {"Right HPCOM Mux", "single-ended", "Right HPCOM Mixer"},
797 {"Right HPCOM Mux", "differential of HPLCOM", "Left HPCOM Mixer"},
798 {"Right HPCOM Mux", "external feedback", "Right HPCOM Mixer"},
799 {"Right HP Com", NULL, "Right HPCOM Mux"},
800 {"HPRCOM", NULL, "Right HP Com"},
801};
802
803static const struct snd_soc_dapm_route intercon_3007[] = {
804
805 {"Left Class-D Out", NULL, "Left Line Out"},
806 {"Right Class-D Out", NULL, "Left Line Out"},
807 {"SPOP", NULL, "Left Class-D Out"},
808 {"SPOM", NULL, "Right Class-D Out"},
809};
810
811static int aic3x_add_widgets(struct snd_soc_codec *codec)
812{
813 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
814 struct snd_soc_dapm_context *dapm = &codec->dapm;
815
816 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
817 ARRAY_SIZE(aic3x_dapm_widgets));
818
819
820 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
821
822 if (aic3x->model == AIC3X_MODEL_3007) {
823 snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets,
824 ARRAY_SIZE(aic3007_dapm_widgets));
825 snd_soc_dapm_add_routes(dapm, intercon_3007,
826 ARRAY_SIZE(intercon_3007));
827 }
828
829 return 0;
830}
831
832static int aic3x_hw_params(struct snd_pcm_substream *substream,
833 struct snd_pcm_hw_params *params,
834 struct snd_soc_dai *dai)
835{
836 struct snd_soc_codec *codec = dai->codec;
837 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
838 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
839 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
840 u16 d, pll_d = 1;
841 int clk;
842
843
844 data = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4));
845 switch (params_format(params)) {
846 case SNDRV_PCM_FORMAT_S16_LE:
847 break;
848 case SNDRV_PCM_FORMAT_S20_3LE:
849 data |= (0x01 << 4);
850 break;
851 case SNDRV_PCM_FORMAT_S24_LE:
852 data |= (0x02 << 4);
853 break;
854 case SNDRV_PCM_FORMAT_S32_LE:
855 data |= (0x03 << 4);
856 break;
857 }
858 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, data);
859
860
861 fsref = (params_rate(params) % 11025 == 0) ? 44100 : 48000;
862
863
864
865 for (pll_q = 2; pll_q < 18; pll_q++)
866 if (aic3x->sysclk / (128 * pll_q) == fsref) {
867 bypass_pll = 1;
868 break;
869 }
870
871 if (bypass_pll) {
872 pll_q &= 0xf;
873 snd_soc_write(codec, AIC3X_PLL_PROGA_REG, pll_q << PLLQ_SHIFT);
874 snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_CLKDIV);
875
876 snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLL_ENABLE, 0);
877
878 } else {
879 snd_soc_write(codec, AIC3X_GPIOB_REG, CODEC_CLKIN_PLLDIV);
880
881 snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
882 PLL_ENABLE, PLL_ENABLE);
883 }
884
885
886
887 data = (LDAC2LCH | RDAC2RCH);
888 data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000;
889 if (params_rate(params) >= 64000)
890 data |= DUAL_RATE_MODE;
891 snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, data);
892
893
894 data = (fsref * 20) / params_rate(params);
895 if (params_rate(params) < 64000)
896 data /= 2;
897 data /= 5;
898 data -= 2;
899 data |= (data << 4);
900 snd_soc_write(codec, AIC3X_SAMPLE_RATE_SEL_REG, data);
901
902 if (bypass_pll)
903 return 0;
904
905
906
907
908
909
910
911 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000);
912
913 for (r = 1; r <= 16; r++)
914 for (p = 1; p <= 8; p++) {
915 for (j = 4; j <= 55; j++) {
916
917
918
919
920 int tmp_clk = (1000 * j * r) / p;
921
922
923
924
925 if (abs(codec_clk - tmp_clk) <
926 abs(codec_clk - last_clk)) {
927 pll_j = j; pll_d = 0;
928 pll_r = r; pll_p = p;
929 last_clk = tmp_clk;
930 }
931
932
933 if (tmp_clk == codec_clk)
934 goto found;
935 }
936 }
937
938
939 for (p = 1; p <= 8; p++) {
940 j = codec_clk * p / 1000;
941
942 if (j < 4 || j > 11)
943 continue;
944
945
946 d = ((2048 * p * fsref) - j * aic3x->sysclk)
947 * 100 / (aic3x->sysclk/100);
948
949 clk = (10000 * j + d) / (10 * p);
950
951
952
953 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
954 pll_j = j; pll_d = d; pll_r = 1; pll_p = p;
955 last_clk = clk;
956 }
957
958
959 if (clk == codec_clk)
960 goto found;
961 }
962
963 if (last_clk == 0) {
964 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__);
965 return -EINVAL;
966 }
967
968found:
969 snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p);
970 snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG,
971 pll_r << PLLR_SHIFT);
972 snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT);
973 snd_soc_write(codec, AIC3X_PLL_PROGC_REG,
974 (pll_d >> 6) << PLLD_MSB_SHIFT);
975 snd_soc_write(codec, AIC3X_PLL_PROGD_REG,
976 (pll_d & 0x3F) << PLLD_LSB_SHIFT);
977
978 return 0;
979}
980
981static int aic3x_mute(struct snd_soc_dai *dai, int mute)
982{
983 struct snd_soc_codec *codec = dai->codec;
984 u8 ldac_reg = snd_soc_read(codec, LDAC_VOL) & ~MUTE_ON;
985 u8 rdac_reg = snd_soc_read(codec, RDAC_VOL) & ~MUTE_ON;
986
987 if (mute) {
988 snd_soc_write(codec, LDAC_VOL, ldac_reg | MUTE_ON);
989 snd_soc_write(codec, RDAC_VOL, rdac_reg | MUTE_ON);
990 } else {
991 snd_soc_write(codec, LDAC_VOL, ldac_reg);
992 snd_soc_write(codec, RDAC_VOL, rdac_reg);
993 }
994
995 return 0;
996}
997
998static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
999 int clk_id, unsigned int freq, int dir)
1000{
1001 struct snd_soc_codec *codec = codec_dai->codec;
1002 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1003
1004
1005 snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
1006 clk_id << PLLCLK_IN_SHIFT);
1007 snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
1008 clk_id << CLKDIV_IN_SHIFT);
1009
1010 aic3x->sysclk = freq;
1011 return 0;
1012}
1013
1014static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
1015 unsigned int fmt)
1016{
1017 struct snd_soc_codec *codec = codec_dai->codec;
1018 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1019 u8 iface_areg, iface_breg;
1020 int delay = 0;
1021
1022 iface_areg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
1023 iface_breg = snd_soc_read(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
1024
1025
1026 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1027 case SND_SOC_DAIFMT_CBM_CFM:
1028 aic3x->master = 1;
1029 iface_areg |= BIT_CLK_MASTER | WORD_CLK_MASTER;
1030 break;
1031 case SND_SOC_DAIFMT_CBS_CFS:
1032 aic3x->master = 0;
1033 iface_areg &= ~(BIT_CLK_MASTER | WORD_CLK_MASTER);
1034 break;
1035 default:
1036 return -EINVAL;
1037 }
1038
1039
1040
1041
1042
1043 switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
1044 SND_SOC_DAIFMT_INV_MASK)) {
1045 case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
1046 break;
1047 case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
1048 delay = 1;
1049 case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
1050 iface_breg |= (0x01 << 6);
1051 break;
1052 case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
1053 iface_breg |= (0x02 << 6);
1054 break;
1055 case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
1056 iface_breg |= (0x03 << 6);
1057 break;
1058 default:
1059 return -EINVAL;
1060 }
1061
1062
1063 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
1064 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
1065 snd_soc_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
1066
1067 return 0;
1068}
1069
1070static int aic3x_init_3007(struct snd_soc_codec *codec)
1071{
1072 u8 tmp1, tmp2, *cache = codec->reg_cache;
1073
1074
1075
1076
1077
1078 tmp1 = cache[0xD];
1079 tmp2 = cache[0x8];
1080
1081 snd_soc_write(codec, AIC3X_PAGE_SELECT, 0x0D);
1082 snd_soc_write(codec, 0xD, 0x0D);
1083 snd_soc_write(codec, 0x8, 0x5C);
1084 snd_soc_write(codec, 0x8, 0x5D);
1085 snd_soc_write(codec, 0x8, 0x5C);
1086 snd_soc_write(codec, AIC3X_PAGE_SELECT, 0x00);
1087 cache[0xD] = tmp1;
1088 cache[0x8] = tmp2;
1089
1090 return 0;
1091}
1092
1093static int aic3x_regulator_event(struct notifier_block *nb,
1094 unsigned long event, void *data)
1095{
1096 struct aic3x_disable_nb *disable_nb =
1097 container_of(nb, struct aic3x_disable_nb, nb);
1098 struct aic3x_priv *aic3x = disable_nb->aic3x;
1099
1100 if (event & REGULATOR_EVENT_DISABLE) {
1101
1102
1103
1104
1105 if (gpio_is_valid(aic3x->gpio_reset))
1106 gpio_set_value(aic3x->gpio_reset, 0);
1107 aic3x->codec->cache_sync = 1;
1108 }
1109
1110 return 0;
1111}
1112
1113static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1114{
1115 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1116 int i, ret;
1117 u8 *cache = codec->reg_cache;
1118
1119 if (power) {
1120 ret = regulator_bulk_enable(ARRAY_SIZE(aic3x->supplies),
1121 aic3x->supplies);
1122 if (ret)
1123 goto out;
1124 aic3x->power = 1;
1125
1126
1127
1128
1129 if (!codec->cache_sync)
1130 goto out;
1131
1132 if (gpio_is_valid(aic3x->gpio_reset)) {
1133 udelay(1);
1134 gpio_set_value(aic3x->gpio_reset, 1);
1135 }
1136
1137
1138 codec->cache_only = 0;
1139 for (i = AIC3X_SAMPLE_RATE_SEL_REG; i < ARRAY_SIZE(aic3x_reg); i++)
1140 snd_soc_write(codec, i, cache[i]);
1141 if (aic3x->model == AIC3X_MODEL_3007)
1142 aic3x_init_3007(codec);
1143 codec->cache_sync = 0;
1144 } else {
1145
1146
1147
1148
1149
1150 snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
1151 codec->cache_sync = 1;
1152 aic3x->power = 0;
1153
1154 codec->cache_only = 1;
1155 ret = regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies),
1156 aic3x->supplies);
1157 }
1158out:
1159 return ret;
1160}
1161
1162static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1163 enum snd_soc_bias_level level)
1164{
1165 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1166
1167 switch (level) {
1168 case SND_SOC_BIAS_ON:
1169 break;
1170 case SND_SOC_BIAS_PREPARE:
1171 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY &&
1172 aic3x->master) {
1173
1174 snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
1175 PLL_ENABLE, PLL_ENABLE);
1176 }
1177 break;
1178 case SND_SOC_BIAS_STANDBY:
1179 if (!aic3x->power)
1180 aic3x_set_power(codec, 1);
1181 if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE &&
1182 aic3x->master) {
1183
1184 snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG,
1185 PLL_ENABLE, 0);
1186 }
1187 break;
1188 case SND_SOC_BIAS_OFF:
1189 if (aic3x->power)
1190 aic3x_set_power(codec, 0);
1191 break;
1192 }
1193 codec->dapm.bias_level = level;
1194
1195 return 0;
1196}
1197
1198#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
1199#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1200 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
1201
1202static const struct snd_soc_dai_ops aic3x_dai_ops = {
1203 .hw_params = aic3x_hw_params,
1204 .digital_mute = aic3x_mute,
1205 .set_sysclk = aic3x_set_dai_sysclk,
1206 .set_fmt = aic3x_set_dai_fmt,
1207};
1208
1209static struct snd_soc_dai_driver aic3x_dai = {
1210 .name = "tlv320aic3x-hifi",
1211 .playback = {
1212 .stream_name = "Playback",
1213 .channels_min = 1,
1214 .channels_max = 2,
1215 .rates = AIC3X_RATES,
1216 .formats = AIC3X_FORMATS,},
1217 .capture = {
1218 .stream_name = "Capture",
1219 .channels_min = 1,
1220 .channels_max = 2,
1221 .rates = AIC3X_RATES,
1222 .formats = AIC3X_FORMATS,},
1223 .ops = &aic3x_dai_ops,
1224 .symmetric_rates = 1,
1225};
1226
1227static int aic3x_suspend(struct snd_soc_codec *codec)
1228{
1229 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1230
1231 return 0;
1232}
1233
1234static int aic3x_resume(struct snd_soc_codec *codec)
1235{
1236 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1237
1238 return 0;
1239}
1240
1241
1242
1243
1244
1245static int aic3x_init(struct snd_soc_codec *codec)
1246{
1247 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1248
1249 snd_soc_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
1250 snd_soc_write(codec, AIC3X_RESET, SOFT_RESET);
1251
1252
1253 snd_soc_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
1254 snd_soc_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
1255
1256
1257 snd_soc_write(codec, DACL1_2_HPLOUT_VOL, DEFAULT_VOL | ROUTE_ON);
1258 snd_soc_write(codec, DACR1_2_HPROUT_VOL, DEFAULT_VOL | ROUTE_ON);
1259 snd_soc_write(codec, DACL1_2_HPLCOM_VOL, DEFAULT_VOL | ROUTE_ON);
1260 snd_soc_write(codec, DACR1_2_HPRCOM_VOL, DEFAULT_VOL | ROUTE_ON);
1261
1262 snd_soc_write(codec, DACL1_2_LLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
1263 snd_soc_write(codec, DACR1_2_RLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
1264
1265 snd_soc_write(codec, DACL1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
1266 snd_soc_write(codec, DACR1_2_MONOLOPM_VOL, DEFAULT_VOL | ROUTE_ON);
1267
1268
1269 snd_soc_update_bits(codec, LLOPM_CTRL, UNMUTE, UNMUTE);
1270 snd_soc_update_bits(codec, RLOPM_CTRL, UNMUTE, UNMUTE);
1271 snd_soc_update_bits(codec, MONOLOPM_CTRL, UNMUTE, UNMUTE);
1272 snd_soc_update_bits(codec, HPLOUT_CTRL, UNMUTE, UNMUTE);
1273 snd_soc_update_bits(codec, HPROUT_CTRL, UNMUTE, UNMUTE);
1274 snd_soc_update_bits(codec, HPLCOM_CTRL, UNMUTE, UNMUTE);
1275 snd_soc_update_bits(codec, HPRCOM_CTRL, UNMUTE, UNMUTE);
1276
1277
1278 snd_soc_write(codec, LADC_VOL, DEFAULT_GAIN);
1279 snd_soc_write(codec, RADC_VOL, DEFAULT_GAIN);
1280
1281 snd_soc_write(codec, LINE1L_2_LADC_CTRL, 0x0);
1282 snd_soc_write(codec, LINE1R_2_RADC_CTRL, 0x0);
1283
1284
1285 snd_soc_write(codec, PGAL_2_HPLOUT_VOL, DEFAULT_VOL);
1286 snd_soc_write(codec, PGAR_2_HPROUT_VOL, DEFAULT_VOL);
1287 snd_soc_write(codec, PGAL_2_HPLCOM_VOL, DEFAULT_VOL);
1288 snd_soc_write(codec, PGAR_2_HPRCOM_VOL, DEFAULT_VOL);
1289
1290 snd_soc_write(codec, PGAL_2_LLOPM_VOL, DEFAULT_VOL);
1291 snd_soc_write(codec, PGAR_2_RLOPM_VOL, DEFAULT_VOL);
1292
1293 snd_soc_write(codec, PGAL_2_MONOLOPM_VOL, DEFAULT_VOL);
1294 snd_soc_write(codec, PGAR_2_MONOLOPM_VOL, DEFAULT_VOL);
1295
1296
1297 snd_soc_write(codec, LINE2L_2_HPLOUT_VOL, DEFAULT_VOL);
1298 snd_soc_write(codec, LINE2R_2_HPROUT_VOL, DEFAULT_VOL);
1299 snd_soc_write(codec, LINE2L_2_HPLCOM_VOL, DEFAULT_VOL);
1300 snd_soc_write(codec, LINE2R_2_HPRCOM_VOL, DEFAULT_VOL);
1301
1302 snd_soc_write(codec, LINE2L_2_LLOPM_VOL, DEFAULT_VOL);
1303 snd_soc_write(codec, LINE2R_2_RLOPM_VOL, DEFAULT_VOL);
1304
1305 snd_soc_write(codec, LINE2L_2_MONOLOPM_VOL, DEFAULT_VOL);
1306 snd_soc_write(codec, LINE2R_2_MONOLOPM_VOL, DEFAULT_VOL);
1307
1308 if (aic3x->model == AIC3X_MODEL_3007) {
1309 aic3x_init_3007(codec);
1310 snd_soc_write(codec, CLASSD_CTRL, 0);
1311 }
1312
1313 return 0;
1314}
1315
1316static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
1317{
1318 struct aic3x_priv *a;
1319
1320 list_for_each_entry(a, &reset_list, list) {
1321 if (gpio_is_valid(aic3x->gpio_reset) &&
1322 aic3x->gpio_reset == a->gpio_reset)
1323 return true;
1324 }
1325
1326 return false;
1327}
1328
1329static int aic3x_probe(struct snd_soc_codec *codec)
1330{
1331 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1332 int ret, i;
1333
1334 INIT_LIST_HEAD(&aic3x->list);
1335 aic3x->codec = codec;
1336
1337 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
1338 if (ret != 0) {
1339 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1340 return ret;
1341 }
1342
1343 if (gpio_is_valid(aic3x->gpio_reset) &&
1344 !aic3x_is_shared_reset(aic3x)) {
1345 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
1346 if (ret != 0)
1347 goto err_gpio;
1348 gpio_direction_output(aic3x->gpio_reset, 0);
1349 }
1350
1351 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1352 aic3x->supplies[i].supply = aic3x_supply_names[i];
1353
1354 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(aic3x->supplies),
1355 aic3x->supplies);
1356 if (ret != 0) {
1357 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1358 goto err_get;
1359 }
1360 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++) {
1361 aic3x->disable_nb[i].nb.notifier_call = aic3x_regulator_event;
1362 aic3x->disable_nb[i].aic3x = aic3x;
1363 ret = regulator_register_notifier(aic3x->supplies[i].consumer,
1364 &aic3x->disable_nb[i].nb);
1365 if (ret) {
1366 dev_err(codec->dev,
1367 "Failed to request regulator notifier: %d\n",
1368 ret);
1369 goto err_notif;
1370 }
1371 }
1372
1373 codec->cache_only = 1;
1374 aic3x_init(codec);
1375
1376 if (aic3x->setup) {
1377
1378 snd_soc_write(codec, AIC3X_GPIO1_REG,
1379 (aic3x->setup->gpio_func[0] & 0xf) << 4);
1380 snd_soc_write(codec, AIC3X_GPIO2_REG,
1381 (aic3x->setup->gpio_func[1] & 0xf) << 4);
1382 }
1383
1384 snd_soc_add_codec_controls(codec, aic3x_snd_controls,
1385 ARRAY_SIZE(aic3x_snd_controls));
1386 if (aic3x->model == AIC3X_MODEL_3007)
1387 snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1388
1389 aic3x_add_widgets(codec);
1390 list_add(&aic3x->list, &reset_list);
1391
1392 return 0;
1393
1394err_notif:
1395 while (i--)
1396 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1397 &aic3x->disable_nb[i].nb);
1398 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1399err_get:
1400 if (gpio_is_valid(aic3x->gpio_reset) &&
1401 !aic3x_is_shared_reset(aic3x))
1402 gpio_free(aic3x->gpio_reset);
1403err_gpio:
1404 return ret;
1405}
1406
1407static int aic3x_remove(struct snd_soc_codec *codec)
1408{
1409 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1410 int i;
1411
1412 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1413 list_del(&aic3x->list);
1414 if (gpio_is_valid(aic3x->gpio_reset) &&
1415 !aic3x_is_shared_reset(aic3x)) {
1416 gpio_set_value(aic3x->gpio_reset, 0);
1417 gpio_free(aic3x->gpio_reset);
1418 }
1419 for (i = 0; i < ARRAY_SIZE(aic3x->supplies); i++)
1420 regulator_unregister_notifier(aic3x->supplies[i].consumer,
1421 &aic3x->disable_nb[i].nb);
1422 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1423
1424 return 0;
1425}
1426
1427static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1428 .set_bias_level = aic3x_set_bias_level,
1429 .idle_bias_off = true,
1430 .reg_cache_size = ARRAY_SIZE(aic3x_reg),
1431 .reg_word_size = sizeof(u8),
1432 .reg_cache_default = aic3x_reg,
1433 .probe = aic3x_probe,
1434 .remove = aic3x_remove,
1435 .suspend = aic3x_suspend,
1436 .resume = aic3x_resume,
1437};
1438
1439
1440
1441
1442
1443
1444static const struct i2c_device_id aic3x_i2c_id[] = {
1445 { "tlv320aic3x", AIC3X_MODEL_3X },
1446 { "tlv320aic33", AIC3X_MODEL_33 },
1447 { "tlv320aic3007", AIC3X_MODEL_3007 },
1448 { }
1449};
1450MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
1451
1452
1453
1454
1455
1456static int aic3x_i2c_probe(struct i2c_client *i2c,
1457 const struct i2c_device_id *id)
1458{
1459 struct aic3x_pdata *pdata = i2c->dev.platform_data;
1460 struct aic3x_priv *aic3x;
1461 struct aic3x_setup_data *ai3x_setup;
1462 struct device_node *np = i2c->dev.of_node;
1463 int ret;
1464
1465 aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
1466 if (aic3x == NULL) {
1467 dev_err(&i2c->dev, "failed to create private data\n");
1468 return -ENOMEM;
1469 }
1470
1471 aic3x->control_type = SND_SOC_I2C;
1472
1473 i2c_set_clientdata(i2c, aic3x);
1474 if (pdata) {
1475 aic3x->gpio_reset = pdata->gpio_reset;
1476 aic3x->setup = pdata->setup;
1477 } else if (np) {
1478 ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup),
1479 GFP_KERNEL);
1480 if (ai3x_setup == NULL) {
1481 dev_err(&i2c->dev, "failed to create private data\n");
1482 return -ENOMEM;
1483 }
1484
1485 ret = of_get_named_gpio(np, "gpio-reset", 0);
1486 if (ret >= 0)
1487 aic3x->gpio_reset = ret;
1488 else
1489 aic3x->gpio_reset = -1;
1490
1491 if (of_property_read_u32_array(np, "ai3x-gpio-func",
1492 ai3x_setup->gpio_func, 2) >= 0) {
1493 aic3x->setup = ai3x_setup;
1494 }
1495
1496 } else {
1497 aic3x->gpio_reset = -1;
1498 }
1499
1500 aic3x->model = id->driver_data;
1501
1502 ret = snd_soc_register_codec(&i2c->dev,
1503 &soc_codec_dev_aic3x, &aic3x_dai, 1);
1504 return ret;
1505}
1506
1507static int aic3x_i2c_remove(struct i2c_client *client)
1508{
1509 snd_soc_unregister_codec(&client->dev);
1510 return 0;
1511}
1512
1513#if defined(CONFIG_OF)
1514static const struct of_device_id tlv320aic3x_of_match[] = {
1515 { .compatible = "ti,tlv320aic3x", },
1516 {},
1517};
1518MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match);
1519#endif
1520
1521
1522static struct i2c_driver aic3x_i2c_driver = {
1523 .driver = {
1524 .name = "tlv320aic3x-codec",
1525 .owner = THIS_MODULE,
1526 .of_match_table = of_match_ptr(tlv320aic3x_of_match),
1527 },
1528 .probe = aic3x_i2c_probe,
1529 .remove = aic3x_i2c_remove,
1530 .id_table = aic3x_i2c_id,
1531};
1532
1533module_i2c_driver(aic3x_i2c_driver);
1534
1535MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
1536MODULE_AUTHOR("Vladimir Barinov");
1537MODULE_LICENSE("GPL");
1538