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