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