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