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