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