1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/delay.h>
23#include <linux/init.h>
24#include <linux/slab.h>
25#include <linux/mutex.h>
26#include <linux/module.h>
27
28#include <sound/core.h>
29#include <sound/ak4531_codec.h>
30#include <sound/tlv.h>
31
32
33
34
35
36
37
38static void snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531);
39
40
41
42
43
44#if 0
45
46static void snd_ak4531_dump(struct snd_ak4531 *ak4531)
47{
48 int idx;
49
50 for (idx = 0; idx < 0x19; idx++)
51 printk(KERN_DEBUG "ak4531 0x%x: 0x%x\n",
52 idx, ak4531->regs[idx]);
53}
54
55#endif
56
57
58
59
60
61#define AK4531_SINGLE(xname, xindex, reg, shift, mask, invert) \
62{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
63 .info = snd_ak4531_info_single, \
64 .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \
65 .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22) }
66#define AK4531_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
67{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
68 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
69 .name = xname, .index = xindex, \
70 .info = snd_ak4531_info_single, \
71 .get = snd_ak4531_get_single, .put = snd_ak4531_put_single, \
72 .private_value = reg | (shift << 16) | (mask << 24) | (invert << 22), \
73 .tlv = { .p = (xtlv) } }
74
75static int snd_ak4531_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
76{
77 int mask = (kcontrol->private_value >> 24) & 0xff;
78
79 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
80 uinfo->count = 1;
81 uinfo->value.integer.min = 0;
82 uinfo->value.integer.max = mask;
83 return 0;
84}
85
86static int snd_ak4531_get_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
87{
88 struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
89 int reg = kcontrol->private_value & 0xff;
90 int shift = (kcontrol->private_value >> 16) & 0x07;
91 int mask = (kcontrol->private_value >> 24) & 0xff;
92 int invert = (kcontrol->private_value >> 22) & 1;
93 int val;
94
95 mutex_lock(&ak4531->reg_mutex);
96 val = (ak4531->regs[reg] >> shift) & mask;
97 mutex_unlock(&ak4531->reg_mutex);
98 if (invert) {
99 val = mask - val;
100 }
101 ucontrol->value.integer.value[0] = val;
102 return 0;
103}
104
105static int snd_ak4531_put_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
106{
107 struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
108 int reg = kcontrol->private_value & 0xff;
109 int shift = (kcontrol->private_value >> 16) & 0x07;
110 int mask = (kcontrol->private_value >> 24) & 0xff;
111 int invert = (kcontrol->private_value >> 22) & 1;
112 int change;
113 int val;
114
115 val = ucontrol->value.integer.value[0] & mask;
116 if (invert) {
117 val = mask - val;
118 }
119 val <<= shift;
120 mutex_lock(&ak4531->reg_mutex);
121 val = (ak4531->regs[reg] & ~(mask << shift)) | val;
122 change = val != ak4531->regs[reg];
123 ak4531->write(ak4531, reg, ak4531->regs[reg] = val);
124 mutex_unlock(&ak4531->reg_mutex);
125 return change;
126}
127
128#define AK4531_DOUBLE(xname, xindex, left_reg, right_reg, left_shift, right_shift, mask, invert) \
129{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
130 .info = snd_ak4531_info_double, \
131 .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \
132 .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22) }
133#define AK4531_DOUBLE_TLV(xname, xindex, left_reg, right_reg, left_shift, right_shift, mask, invert, xtlv) \
134{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
135 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
136 .name = xname, .index = xindex, \
137 .info = snd_ak4531_info_double, \
138 .get = snd_ak4531_get_double, .put = snd_ak4531_put_double, \
139 .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) | (invert << 22), \
140 .tlv = { .p = (xtlv) } }
141
142static int snd_ak4531_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
143{
144 int mask = (kcontrol->private_value >> 24) & 0xff;
145
146 uinfo->type = mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
147 uinfo->count = 2;
148 uinfo->value.integer.min = 0;
149 uinfo->value.integer.max = mask;
150 return 0;
151}
152
153static int snd_ak4531_get_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
154{
155 struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
156 int left_reg = kcontrol->private_value & 0xff;
157 int right_reg = (kcontrol->private_value >> 8) & 0xff;
158 int left_shift = (kcontrol->private_value >> 16) & 0x07;
159 int right_shift = (kcontrol->private_value >> 19) & 0x07;
160 int mask = (kcontrol->private_value >> 24) & 0xff;
161 int invert = (kcontrol->private_value >> 22) & 1;
162 int left, right;
163
164 mutex_lock(&ak4531->reg_mutex);
165 left = (ak4531->regs[left_reg] >> left_shift) & mask;
166 right = (ak4531->regs[right_reg] >> right_shift) & mask;
167 mutex_unlock(&ak4531->reg_mutex);
168 if (invert) {
169 left = mask - left;
170 right = mask - right;
171 }
172 ucontrol->value.integer.value[0] = left;
173 ucontrol->value.integer.value[1] = right;
174 return 0;
175}
176
177static int snd_ak4531_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
178{
179 struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
180 int left_reg = kcontrol->private_value & 0xff;
181 int right_reg = (kcontrol->private_value >> 8) & 0xff;
182 int left_shift = (kcontrol->private_value >> 16) & 0x07;
183 int right_shift = (kcontrol->private_value >> 19) & 0x07;
184 int mask = (kcontrol->private_value >> 24) & 0xff;
185 int invert = (kcontrol->private_value >> 22) & 1;
186 int change;
187 int left, right;
188
189 left = ucontrol->value.integer.value[0] & mask;
190 right = ucontrol->value.integer.value[1] & mask;
191 if (invert) {
192 left = mask - left;
193 right = mask - right;
194 }
195 left <<= left_shift;
196 right <<= right_shift;
197 mutex_lock(&ak4531->reg_mutex);
198 if (left_reg == right_reg) {
199 left = (ak4531->regs[left_reg] & ~((mask << left_shift) | (mask << right_shift))) | left | right;
200 change = left != ak4531->regs[left_reg];
201 ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left);
202 } else {
203 left = (ak4531->regs[left_reg] & ~(mask << left_shift)) | left;
204 right = (ak4531->regs[right_reg] & ~(mask << right_shift)) | right;
205 change = left != ak4531->regs[left_reg] || right != ak4531->regs[right_reg];
206 ak4531->write(ak4531, left_reg, ak4531->regs[left_reg] = left);
207 ak4531->write(ak4531, right_reg, ak4531->regs[right_reg] = right);
208 }
209 mutex_unlock(&ak4531->reg_mutex);
210 return change;
211}
212
213#define AK4531_INPUT_SW(xname, xindex, reg1, reg2, left_shift, right_shift) \
214{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
215 .info = snd_ak4531_info_input_sw, \
216 .get = snd_ak4531_get_input_sw, .put = snd_ak4531_put_input_sw, \
217 .private_value = reg1 | (reg2 << 8) | (left_shift << 16) | (right_shift << 24) }
218
219static int snd_ak4531_info_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
220{
221 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
222 uinfo->count = 4;
223 uinfo->value.integer.min = 0;
224 uinfo->value.integer.max = 1;
225 return 0;
226}
227
228static int snd_ak4531_get_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
229{
230 struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
231 int reg1 = kcontrol->private_value & 0xff;
232 int reg2 = (kcontrol->private_value >> 8) & 0xff;
233 int left_shift = (kcontrol->private_value >> 16) & 0x0f;
234 int right_shift = (kcontrol->private_value >> 24) & 0x0f;
235
236 mutex_lock(&ak4531->reg_mutex);
237 ucontrol->value.integer.value[0] = (ak4531->regs[reg1] >> left_shift) & 1;
238 ucontrol->value.integer.value[1] = (ak4531->regs[reg2] >> left_shift) & 1;
239 ucontrol->value.integer.value[2] = (ak4531->regs[reg1] >> right_shift) & 1;
240 ucontrol->value.integer.value[3] = (ak4531->regs[reg2] >> right_shift) & 1;
241 mutex_unlock(&ak4531->reg_mutex);
242 return 0;
243}
244
245static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
246{
247 struct snd_ak4531 *ak4531 = snd_kcontrol_chip(kcontrol);
248 int reg1 = kcontrol->private_value & 0xff;
249 int reg2 = (kcontrol->private_value >> 8) & 0xff;
250 int left_shift = (kcontrol->private_value >> 16) & 0x0f;
251 int right_shift = (kcontrol->private_value >> 24) & 0x0f;
252 int change;
253 int val1, val2;
254
255 mutex_lock(&ak4531->reg_mutex);
256 val1 = ak4531->regs[reg1] & ~((1 << left_shift) | (1 << right_shift));
257 val2 = ak4531->regs[reg2] & ~((1 << left_shift) | (1 << right_shift));
258 val1 |= (ucontrol->value.integer.value[0] & 1) << left_shift;
259 val2 |= (ucontrol->value.integer.value[1] & 1) << left_shift;
260 val1 |= (ucontrol->value.integer.value[2] & 1) << right_shift;
261 val2 |= (ucontrol->value.integer.value[3] & 1) << right_shift;
262 change = val1 != ak4531->regs[reg1] || val2 != ak4531->regs[reg2];
263 ak4531->write(ak4531, reg1, ak4531->regs[reg1] = val1);
264 ak4531->write(ak4531, reg2, ak4531->regs[reg2] = val2);
265 mutex_unlock(&ak4531->reg_mutex);
266 return change;
267}
268
269static const DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0);
270static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0);
271static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0);
272
273static struct snd_kcontrol_new snd_ak4531_controls[] = {
274
275AK4531_DOUBLE_TLV("Master Playback Switch", 0,
276 AK4531_LMASTER, AK4531_RMASTER, 7, 7, 1, 1,
277 db_scale_master),
278AK4531_DOUBLE("Master Playback Volume", 0, AK4531_LMASTER, AK4531_RMASTER, 0, 0, 0x1f, 1),
279
280AK4531_SINGLE_TLV("Master Mono Playback Switch", 0, AK4531_MONO_OUT, 7, 1, 1,
281 db_scale_mono),
282AK4531_SINGLE("Master Mono Playback Volume", 0, AK4531_MONO_OUT, 0, 0x07, 1),
283
284AK4531_DOUBLE("PCM Switch", 0, AK4531_LVOICE, AK4531_RVOICE, 7, 7, 1, 1),
285AK4531_DOUBLE_TLV("PCM Volume", 0, AK4531_LVOICE, AK4531_RVOICE, 0, 0, 0x1f, 1,
286 db_scale_input),
287AK4531_DOUBLE("PCM Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 3, 2, 1, 0),
288AK4531_DOUBLE("PCM Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 2, 2, 1, 0),
289
290AK4531_DOUBLE("PCM Switch", 1, AK4531_LFM, AK4531_RFM, 7, 7, 1, 1),
291AK4531_DOUBLE_TLV("PCM Volume", 1, AK4531_LFM, AK4531_RFM, 0, 0, 0x1f, 1,
292 db_scale_input),
293AK4531_DOUBLE("PCM Playback Switch", 1, AK4531_OUT_SW1, AK4531_OUT_SW1, 6, 5, 1, 0),
294AK4531_INPUT_SW("PCM Capture Route", 1, AK4531_LIN_SW1, AK4531_RIN_SW1, 6, 5),
295
296AK4531_DOUBLE("CD Switch", 0, AK4531_LCD, AK4531_RCD, 7, 7, 1, 1),
297AK4531_DOUBLE_TLV("CD Volume", 0, AK4531_LCD, AK4531_RCD, 0, 0, 0x1f, 1,
298 db_scale_input),
299AK4531_DOUBLE("CD Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 2, 1, 1, 0),
300AK4531_INPUT_SW("CD Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 2, 1),
301
302AK4531_DOUBLE("Line Switch", 0, AK4531_LLINE, AK4531_RLINE, 7, 7, 1, 1),
303AK4531_DOUBLE_TLV("Line Volume", 0, AK4531_LLINE, AK4531_RLINE, 0, 0, 0x1f, 1,
304 db_scale_input),
305AK4531_DOUBLE("Line Playback Switch", 0, AK4531_OUT_SW1, AK4531_OUT_SW1, 4, 3, 1, 0),
306AK4531_INPUT_SW("Line Capture Route", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 4, 3),
307
308AK4531_DOUBLE("Aux Switch", 0, AK4531_LAUXA, AK4531_RAUXA, 7, 7, 1, 1),
309AK4531_DOUBLE_TLV("Aux Volume", 0, AK4531_LAUXA, AK4531_RAUXA, 0, 0, 0x1f, 1,
310 db_scale_input),
311AK4531_DOUBLE("Aux Playback Switch", 0, AK4531_OUT_SW2, AK4531_OUT_SW2, 5, 4, 1, 0),
312AK4531_INPUT_SW("Aux Capture Route", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 4, 3),
313
314AK4531_SINGLE("Mono Switch", 0, AK4531_MONO1, 7, 1, 1),
315AK4531_SINGLE_TLV("Mono Volume", 0, AK4531_MONO1, 0, 0x1f, 1, db_scale_input),
316AK4531_SINGLE("Mono Playback Switch", 0, AK4531_OUT_SW2, 0, 1, 0),
317AK4531_DOUBLE("Mono Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 0, 0, 1, 0),
318
319AK4531_SINGLE("Mono Switch", 1, AK4531_MONO2, 7, 1, 1),
320AK4531_SINGLE_TLV("Mono Volume", 1, AK4531_MONO2, 0, 0x1f, 1, db_scale_input),
321AK4531_SINGLE("Mono Playback Switch", 1, AK4531_OUT_SW2, 1, 1, 0),
322AK4531_DOUBLE("Mono Capture Switch", 1, AK4531_LIN_SW2, AK4531_RIN_SW2, 1, 1, 1, 0),
323
324AK4531_SINGLE_TLV("Mic Volume", 0, AK4531_MIC, 0, 0x1f, 1, db_scale_input),
325AK4531_SINGLE("Mic Switch", 0, AK4531_MIC, 7, 1, 1),
326AK4531_SINGLE("Mic Playback Switch", 0, AK4531_OUT_SW1, 0, 1, 0),
327AK4531_DOUBLE("Mic Capture Switch", 0, AK4531_LIN_SW1, AK4531_RIN_SW1, 0, 0, 1, 0),
328
329AK4531_DOUBLE("Mic Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 7, 7, 1, 0),
330AK4531_DOUBLE("Mono1 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 6, 6, 1, 0),
331AK4531_DOUBLE("Mono2 Bypass Capture Switch", 0, AK4531_LIN_SW2, AK4531_RIN_SW2, 5, 5, 1, 0),
332
333AK4531_SINGLE("AD Input Select", 0, AK4531_AD_IN, 0, 1, 0),
334AK4531_SINGLE("Mic Boost (+30dB)", 0, AK4531_MIC_GAIN, 0, 1, 0)
335};
336
337static int snd_ak4531_free(struct snd_ak4531 *ak4531)
338{
339 if (ak4531) {
340 if (ak4531->private_free)
341 ak4531->private_free(ak4531);
342 kfree(ak4531);
343 }
344 return 0;
345}
346
347static int snd_ak4531_dev_free(struct snd_device *device)
348{
349 struct snd_ak4531 *ak4531 = device->device_data;
350 return snd_ak4531_free(ak4531);
351}
352
353static u8 snd_ak4531_initial_map[0x19 + 1] = {
354 0x9f,
355 0x9f,
356 0x9f,
357 0x9f,
358 0x9f,
359 0x9f,
360 0x9f,
361 0x9f,
362 0x9f,
363 0x9f,
364 0x9f,
365 0x9f,
366 0x9f,
367 0x9f,
368 0x9f,
369 0x87,
370 0x00,
371 0x00,
372 0x00,
373 0x00,
374 0x00,
375 0x00,
376 0x00,
377 0x00,
378 0x00,
379 0x01
380};
381
382int snd_ak4531_mixer(struct snd_card *card,
383 struct snd_ak4531 *_ak4531,
384 struct snd_ak4531 **rak4531)
385{
386 unsigned int idx;
387 int err;
388 struct snd_ak4531 *ak4531;
389 static struct snd_device_ops ops = {
390 .dev_free = snd_ak4531_dev_free,
391 };
392
393 if (snd_BUG_ON(!card || !_ak4531))
394 return -EINVAL;
395 if (rak4531)
396 *rak4531 = NULL;
397 ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL);
398 if (ak4531 == NULL)
399 return -ENOMEM;
400 *ak4531 = *_ak4531;
401 mutex_init(&ak4531->reg_mutex);
402 if ((err = snd_component_add(card, "AK4531")) < 0) {
403 snd_ak4531_free(ak4531);
404 return err;
405 }
406 strcpy(card->mixername, "Asahi Kasei AK4531");
407 ak4531->write(ak4531, AK4531_RESET, 0x03);
408 udelay(100);
409 ak4531->write(ak4531, AK4531_CLOCK, 0x00);
410 for (idx = 0; idx <= 0x19; idx++) {
411 if (idx == AK4531_RESET || idx == AK4531_CLOCK)
412 continue;
413 ak4531->write(ak4531, idx, ak4531->regs[idx] = snd_ak4531_initial_map[idx]);
414 }
415 for (idx = 0; idx < ARRAY_SIZE(snd_ak4531_controls); idx++) {
416 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_ak4531_controls[idx], ak4531))) < 0) {
417 snd_ak4531_free(ak4531);
418 return err;
419 }
420 }
421 snd_ak4531_proc_init(card, ak4531);
422 if ((err = snd_device_new(card, SNDRV_DEV_CODEC, ak4531, &ops)) < 0) {
423 snd_ak4531_free(ak4531);
424 return err;
425 }
426
427#if 0
428 snd_ak4531_dump(ak4531);
429#endif
430 if (rak4531)
431 *rak4531 = ak4531;
432 return 0;
433}
434
435
436
437
438#ifdef CONFIG_PM
439void snd_ak4531_suspend(struct snd_ak4531 *ak4531)
440{
441
442 ak4531->write(ak4531, AK4531_LMASTER, 0x9f);
443 ak4531->write(ak4531, AK4531_RMASTER, 0x9f);
444
445 ak4531->write(ak4531, AK4531_RESET, 0x01);
446}
447
448void snd_ak4531_resume(struct snd_ak4531 *ak4531)
449{
450 int idx;
451
452
453 ak4531->write(ak4531, AK4531_RESET, 0x03);
454 udelay(100);
455 ak4531->write(ak4531, AK4531_CLOCK, 0x00);
456
457 for (idx = 0; idx <= 0x19; idx++) {
458 if (idx == AK4531_RESET || idx == AK4531_CLOCK)
459 continue;
460 ak4531->write(ak4531, idx, ak4531->regs[idx]);
461 }
462}
463#endif
464
465
466
467
468
469static void snd_ak4531_proc_read(struct snd_info_entry *entry,
470 struct snd_info_buffer *buffer)
471{
472 struct snd_ak4531 *ak4531 = entry->private_data;
473
474 snd_iprintf(buffer, "Asahi Kasei AK4531\n\n");
475 snd_iprintf(buffer, "Recording source : %s\n"
476 "MIC gain : %s\n",
477 ak4531->regs[AK4531_AD_IN] & 1 ? "external" : "mixer",
478 ak4531->regs[AK4531_MIC_GAIN] & 1 ? "+30dB" : "+0dB");
479}
480
481static void
482snd_ak4531_proc_init(struct snd_card *card, struct snd_ak4531 *ak4531)
483{
484 struct snd_info_entry *entry;
485
486 if (! snd_card_proc_new(card, "ak4531", &entry))
487 snd_info_set_text_ops(entry, ak4531, snd_ak4531_proc_read);
488}
489