1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Apple Onboard Audio driver for tas codec |
4 | * |
5 | * Copyright 2006 Johannes Berg <johannes@sipsolutions.net> |
6 | * |
7 | * Open questions: |
8 | * - How to distinguish between 3004 and versions? |
9 | * |
10 | * FIXMEs: |
11 | * - This codec driver doesn't honour the 'connected' |
12 | * property of the aoa_codec struct, hence if |
13 | * it is used in machines where not everything is |
14 | * connected it will display wrong mixer elements. |
15 | * - Driver assumes that the microphone is always |
16 | * monaureal and connected to the right channel of |
17 | * the input. This should also be a codec-dependent |
18 | * flag, maybe the codec should have 3 different |
19 | * bits for the three different possibilities how |
20 | * it can be hooked up... |
21 | * But as long as I don't see any hardware hooked |
22 | * up that way... |
23 | * - As Apple notes in their code, the tas3004 seems |
24 | * to delay the right channel by one sample. You can |
25 | * see this when for example recording stereo in |
26 | * audacity, or recording the tas output via cable |
27 | * on another machine (use a sinus generator or so). |
28 | * I tried programming the BiQuads but couldn't |
29 | * make the delay work, maybe someone can read the |
30 | * datasheet and fix it. The relevant Apple comment |
31 | * is in AppleTAS3004Audio.cpp lines 1637 ff. Note |
32 | * that their comment describing how they program |
33 | * the filters sucks... |
34 | * |
35 | * Other things: |
36 | * - this should actually register *two* aoa_codec |
37 | * structs since it has two inputs. Then it must |
38 | * use the prepare callback to forbid running the |
39 | * secondary output on a different clock. |
40 | * Also, whatever bus knows how to do this must |
41 | * provide two soundbus_dev devices and the fabric |
42 | * must be able to link them correctly. |
43 | * |
44 | * I don't even know if Apple ever uses the second |
45 | * port on the tas3004 though, I don't think their |
46 | * i2s controllers can even do it. OTOH, they all |
47 | * derive the clocks from common clocks, so it |
48 | * might just be possible. The framework allows the |
49 | * codec to refine the transfer_info items in the |
50 | * usable callback, so we can simply remove the |
51 | * rates the second instance is not using when it |
52 | * actually is in use. |
53 | * Maybe we'll need to make the sound busses have |
54 | * a 'clock group id' value so the codec can |
55 | * determine if the two outputs can be driven at |
56 | * the same time. But that is likely overkill, up |
57 | * to the fabric to not link them up incorrectly, |
58 | * and up to the hardware designer to not wire |
59 | * them up in some weird unusable way. |
60 | */ |
61 | #include <linux/i2c.h> |
62 | #include <asm/pmac_low_i2c.h> |
63 | #include <linux/delay.h> |
64 | #include <linux/module.h> |
65 | #include <linux/mutex.h> |
66 | #include <linux/of.h> |
67 | #include <linux/slab.h> |
68 | |
69 | MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>" ); |
70 | MODULE_LICENSE("GPL" ); |
71 | MODULE_DESCRIPTION("tas codec driver for snd-aoa" ); |
72 | |
73 | #include "tas.h" |
74 | #include "tas-gain-table.h" |
75 | #include "tas-basstreble.h" |
76 | #include "../aoa.h" |
77 | #include "../soundbus/soundbus.h" |
78 | |
79 | #define PFX "snd-aoa-codec-tas: " |
80 | |
81 | |
82 | struct tas { |
83 | struct aoa_codec codec; |
84 | struct i2c_client *i2c; |
85 | u32 mute_l:1, mute_r:1 , |
86 | controls_created:1 , |
87 | drc_enabled:1, |
88 | hw_enabled:1; |
89 | u8 cached_volume_l, cached_volume_r; |
90 | u8 mixer_l[3], mixer_r[3]; |
91 | u8 bass, treble; |
92 | u8 acr; |
93 | int drc_range; |
94 | /* protects hardware access against concurrency from |
95 | * userspace when hitting controls and during |
96 | * codec init/suspend/resume */ |
97 | struct mutex mtx; |
98 | }; |
99 | |
100 | static int tas_reset_init(struct tas *tas); |
101 | |
102 | static struct tas *codec_to_tas(struct aoa_codec *codec) |
103 | { |
104 | return container_of(codec, struct tas, codec); |
105 | } |
106 | |
107 | static inline int tas_write_reg(struct tas *tas, u8 reg, u8 len, u8 *data) |
108 | { |
109 | if (len == 1) |
110 | return i2c_smbus_write_byte_data(client: tas->i2c, command: reg, value: *data); |
111 | else |
112 | return i2c_smbus_write_i2c_block_data(client: tas->i2c, command: reg, length: len, values: data); |
113 | } |
114 | |
115 | static void tas3004_set_drc(struct tas *tas) |
116 | { |
117 | unsigned char val[6]; |
118 | |
119 | if (tas->drc_enabled) |
120 | val[0] = 0x50; /* 3:1 above threshold */ |
121 | else |
122 | val[0] = 0x51; /* disabled */ |
123 | val[1] = 0x02; /* 1:1 below threshold */ |
124 | if (tas->drc_range > 0xef) |
125 | val[2] = 0xef; |
126 | else if (tas->drc_range < 0) |
127 | val[2] = 0x00; |
128 | else |
129 | val[2] = tas->drc_range; |
130 | val[3] = 0xb0; |
131 | val[4] = 0x60; |
132 | val[5] = 0xa0; |
133 | |
134 | tas_write_reg(tas, TAS_REG_DRC, len: 6, data: val); |
135 | } |
136 | |
137 | static void tas_set_treble(struct tas *tas) |
138 | { |
139 | u8 tmp; |
140 | |
141 | tmp = tas3004_treble(idx: tas->treble); |
142 | tas_write_reg(tas, TAS_REG_TREBLE, len: 1, data: &tmp); |
143 | } |
144 | |
145 | static void tas_set_bass(struct tas *tas) |
146 | { |
147 | u8 tmp; |
148 | |
149 | tmp = tas3004_bass(idx: tas->bass); |
150 | tas_write_reg(tas, TAS_REG_BASS, len: 1, data: &tmp); |
151 | } |
152 | |
153 | static void tas_set_volume(struct tas *tas) |
154 | { |
155 | u8 block[6]; |
156 | int tmp; |
157 | u8 left, right; |
158 | |
159 | left = tas->cached_volume_l; |
160 | right = tas->cached_volume_r; |
161 | |
162 | if (left > 177) left = 177; |
163 | if (right > 177) right = 177; |
164 | |
165 | if (tas->mute_l) left = 0; |
166 | if (tas->mute_r) right = 0; |
167 | |
168 | /* analysing the volume and mixer tables shows |
169 | * that they are similar enough when we shift |
170 | * the mixer table down by 4 bits. The error |
171 | * is miniscule, in just one item the error |
172 | * is 1, at a value of 0x07f17b (mixer table |
173 | * value is 0x07f17a) */ |
174 | tmp = tas_gaintable[left]; |
175 | block[0] = tmp>>20; |
176 | block[1] = tmp>>12; |
177 | block[2] = tmp>>4; |
178 | tmp = tas_gaintable[right]; |
179 | block[3] = tmp>>20; |
180 | block[4] = tmp>>12; |
181 | block[5] = tmp>>4; |
182 | tas_write_reg(tas, TAS_REG_VOL, len: 6, data: block); |
183 | } |
184 | |
185 | static void tas_set_mixer(struct tas *tas) |
186 | { |
187 | u8 block[9]; |
188 | int tmp, i; |
189 | u8 val; |
190 | |
191 | for (i=0;i<3;i++) { |
192 | val = tas->mixer_l[i]; |
193 | if (val > 177) val = 177; |
194 | tmp = tas_gaintable[val]; |
195 | block[3*i+0] = tmp>>16; |
196 | block[3*i+1] = tmp>>8; |
197 | block[3*i+2] = tmp; |
198 | } |
199 | tas_write_reg(tas, TAS_REG_LMIX, len: 9, data: block); |
200 | |
201 | for (i=0;i<3;i++) { |
202 | val = tas->mixer_r[i]; |
203 | if (val > 177) val = 177; |
204 | tmp = tas_gaintable[val]; |
205 | block[3*i+0] = tmp>>16; |
206 | block[3*i+1] = tmp>>8; |
207 | block[3*i+2] = tmp; |
208 | } |
209 | tas_write_reg(tas, TAS_REG_RMIX, len: 9, data: block); |
210 | } |
211 | |
212 | /* alsa stuff */ |
213 | |
214 | static int tas_dev_register(struct snd_device *dev) |
215 | { |
216 | return 0; |
217 | } |
218 | |
219 | static const struct snd_device_ops ops = { |
220 | .dev_register = tas_dev_register, |
221 | }; |
222 | |
223 | static int tas_snd_vol_info(struct snd_kcontrol *kcontrol, |
224 | struct snd_ctl_elem_info *uinfo) |
225 | { |
226 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
227 | uinfo->count = 2; |
228 | uinfo->value.integer.min = 0; |
229 | uinfo->value.integer.max = 177; |
230 | return 0; |
231 | } |
232 | |
233 | static int tas_snd_vol_get(struct snd_kcontrol *kcontrol, |
234 | struct snd_ctl_elem_value *ucontrol) |
235 | { |
236 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
237 | |
238 | mutex_lock(&tas->mtx); |
239 | ucontrol->value.integer.value[0] = tas->cached_volume_l; |
240 | ucontrol->value.integer.value[1] = tas->cached_volume_r; |
241 | mutex_unlock(lock: &tas->mtx); |
242 | return 0; |
243 | } |
244 | |
245 | static int tas_snd_vol_put(struct snd_kcontrol *kcontrol, |
246 | struct snd_ctl_elem_value *ucontrol) |
247 | { |
248 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
249 | |
250 | if (ucontrol->value.integer.value[0] < 0 || |
251 | ucontrol->value.integer.value[0] > 177) |
252 | return -EINVAL; |
253 | if (ucontrol->value.integer.value[1] < 0 || |
254 | ucontrol->value.integer.value[1] > 177) |
255 | return -EINVAL; |
256 | |
257 | mutex_lock(&tas->mtx); |
258 | if (tas->cached_volume_l == ucontrol->value.integer.value[0] |
259 | && tas->cached_volume_r == ucontrol->value.integer.value[1]) { |
260 | mutex_unlock(lock: &tas->mtx); |
261 | return 0; |
262 | } |
263 | |
264 | tas->cached_volume_l = ucontrol->value.integer.value[0]; |
265 | tas->cached_volume_r = ucontrol->value.integer.value[1]; |
266 | if (tas->hw_enabled) |
267 | tas_set_volume(tas); |
268 | mutex_unlock(lock: &tas->mtx); |
269 | return 1; |
270 | } |
271 | |
272 | static const struct snd_kcontrol_new volume_control = { |
273 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
274 | .name = "Master Playback Volume" , |
275 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
276 | .info = tas_snd_vol_info, |
277 | .get = tas_snd_vol_get, |
278 | .put = tas_snd_vol_put, |
279 | }; |
280 | |
281 | #define tas_snd_mute_info snd_ctl_boolean_stereo_info |
282 | |
283 | static int tas_snd_mute_get(struct snd_kcontrol *kcontrol, |
284 | struct snd_ctl_elem_value *ucontrol) |
285 | { |
286 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
287 | |
288 | mutex_lock(&tas->mtx); |
289 | ucontrol->value.integer.value[0] = !tas->mute_l; |
290 | ucontrol->value.integer.value[1] = !tas->mute_r; |
291 | mutex_unlock(lock: &tas->mtx); |
292 | return 0; |
293 | } |
294 | |
295 | static int tas_snd_mute_put(struct snd_kcontrol *kcontrol, |
296 | struct snd_ctl_elem_value *ucontrol) |
297 | { |
298 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
299 | |
300 | mutex_lock(&tas->mtx); |
301 | if (tas->mute_l == !ucontrol->value.integer.value[0] |
302 | && tas->mute_r == !ucontrol->value.integer.value[1]) { |
303 | mutex_unlock(lock: &tas->mtx); |
304 | return 0; |
305 | } |
306 | |
307 | tas->mute_l = !ucontrol->value.integer.value[0]; |
308 | tas->mute_r = !ucontrol->value.integer.value[1]; |
309 | if (tas->hw_enabled) |
310 | tas_set_volume(tas); |
311 | mutex_unlock(lock: &tas->mtx); |
312 | return 1; |
313 | } |
314 | |
315 | static const struct snd_kcontrol_new mute_control = { |
316 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
317 | .name = "Master Playback Switch" , |
318 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
319 | .info = tas_snd_mute_info, |
320 | .get = tas_snd_mute_get, |
321 | .put = tas_snd_mute_put, |
322 | }; |
323 | |
324 | static int tas_snd_mixer_info(struct snd_kcontrol *kcontrol, |
325 | struct snd_ctl_elem_info *uinfo) |
326 | { |
327 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
328 | uinfo->count = 2; |
329 | uinfo->value.integer.min = 0; |
330 | uinfo->value.integer.max = 177; |
331 | return 0; |
332 | } |
333 | |
334 | static int tas_snd_mixer_get(struct snd_kcontrol *kcontrol, |
335 | struct snd_ctl_elem_value *ucontrol) |
336 | { |
337 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
338 | int idx = kcontrol->private_value; |
339 | |
340 | mutex_lock(&tas->mtx); |
341 | ucontrol->value.integer.value[0] = tas->mixer_l[idx]; |
342 | ucontrol->value.integer.value[1] = tas->mixer_r[idx]; |
343 | mutex_unlock(lock: &tas->mtx); |
344 | |
345 | return 0; |
346 | } |
347 | |
348 | static int tas_snd_mixer_put(struct snd_kcontrol *kcontrol, |
349 | struct snd_ctl_elem_value *ucontrol) |
350 | { |
351 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
352 | int idx = kcontrol->private_value; |
353 | |
354 | mutex_lock(&tas->mtx); |
355 | if (tas->mixer_l[idx] == ucontrol->value.integer.value[0] |
356 | && tas->mixer_r[idx] == ucontrol->value.integer.value[1]) { |
357 | mutex_unlock(lock: &tas->mtx); |
358 | return 0; |
359 | } |
360 | |
361 | tas->mixer_l[idx] = ucontrol->value.integer.value[0]; |
362 | tas->mixer_r[idx] = ucontrol->value.integer.value[1]; |
363 | |
364 | if (tas->hw_enabled) |
365 | tas_set_mixer(tas); |
366 | mutex_unlock(lock: &tas->mtx); |
367 | return 1; |
368 | } |
369 | |
370 | #define MIXER_CONTROL(n,descr,idx) \ |
371 | static const struct snd_kcontrol_new n##_control = { \ |
372 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
373 | .name = descr " Playback Volume", \ |
374 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \ |
375 | .info = tas_snd_mixer_info, \ |
376 | .get = tas_snd_mixer_get, \ |
377 | .put = tas_snd_mixer_put, \ |
378 | .private_value = idx, \ |
379 | } |
380 | |
381 | MIXER_CONTROL(pcm1, "PCM" , 0); |
382 | MIXER_CONTROL(monitor, "Monitor" , 2); |
383 | |
384 | static int tas_snd_drc_range_info(struct snd_kcontrol *kcontrol, |
385 | struct snd_ctl_elem_info *uinfo) |
386 | { |
387 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
388 | uinfo->count = 1; |
389 | uinfo->value.integer.min = 0; |
390 | uinfo->value.integer.max = TAS3004_DRC_MAX; |
391 | return 0; |
392 | } |
393 | |
394 | static int tas_snd_drc_range_get(struct snd_kcontrol *kcontrol, |
395 | struct snd_ctl_elem_value *ucontrol) |
396 | { |
397 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
398 | |
399 | mutex_lock(&tas->mtx); |
400 | ucontrol->value.integer.value[0] = tas->drc_range; |
401 | mutex_unlock(lock: &tas->mtx); |
402 | return 0; |
403 | } |
404 | |
405 | static int tas_snd_drc_range_put(struct snd_kcontrol *kcontrol, |
406 | struct snd_ctl_elem_value *ucontrol) |
407 | { |
408 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
409 | |
410 | if (ucontrol->value.integer.value[0] < 0 || |
411 | ucontrol->value.integer.value[0] > TAS3004_DRC_MAX) |
412 | return -EINVAL; |
413 | |
414 | mutex_lock(&tas->mtx); |
415 | if (tas->drc_range == ucontrol->value.integer.value[0]) { |
416 | mutex_unlock(lock: &tas->mtx); |
417 | return 0; |
418 | } |
419 | |
420 | tas->drc_range = ucontrol->value.integer.value[0]; |
421 | if (tas->hw_enabled) |
422 | tas3004_set_drc(tas); |
423 | mutex_unlock(lock: &tas->mtx); |
424 | return 1; |
425 | } |
426 | |
427 | static const struct snd_kcontrol_new drc_range_control = { |
428 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
429 | .name = "DRC Range" , |
430 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
431 | .info = tas_snd_drc_range_info, |
432 | .get = tas_snd_drc_range_get, |
433 | .put = tas_snd_drc_range_put, |
434 | }; |
435 | |
436 | #define tas_snd_drc_switch_info snd_ctl_boolean_mono_info |
437 | |
438 | static int tas_snd_drc_switch_get(struct snd_kcontrol *kcontrol, |
439 | struct snd_ctl_elem_value *ucontrol) |
440 | { |
441 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
442 | |
443 | mutex_lock(&tas->mtx); |
444 | ucontrol->value.integer.value[0] = tas->drc_enabled; |
445 | mutex_unlock(lock: &tas->mtx); |
446 | return 0; |
447 | } |
448 | |
449 | static int tas_snd_drc_switch_put(struct snd_kcontrol *kcontrol, |
450 | struct snd_ctl_elem_value *ucontrol) |
451 | { |
452 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
453 | |
454 | mutex_lock(&tas->mtx); |
455 | if (tas->drc_enabled == ucontrol->value.integer.value[0]) { |
456 | mutex_unlock(lock: &tas->mtx); |
457 | return 0; |
458 | } |
459 | |
460 | tas->drc_enabled = !!ucontrol->value.integer.value[0]; |
461 | if (tas->hw_enabled) |
462 | tas3004_set_drc(tas); |
463 | mutex_unlock(lock: &tas->mtx); |
464 | return 1; |
465 | } |
466 | |
467 | static const struct snd_kcontrol_new drc_switch_control = { |
468 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
469 | .name = "DRC Range Switch" , |
470 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
471 | .info = tas_snd_drc_switch_info, |
472 | .get = tas_snd_drc_switch_get, |
473 | .put = tas_snd_drc_switch_put, |
474 | }; |
475 | |
476 | static int tas_snd_capture_source_info(struct snd_kcontrol *kcontrol, |
477 | struct snd_ctl_elem_info *uinfo) |
478 | { |
479 | static const char * const texts[] = { "Line-In" , "Microphone" }; |
480 | |
481 | return snd_ctl_enum_info(info: uinfo, channels: 1, items: 2, names: texts); |
482 | } |
483 | |
484 | static int tas_snd_capture_source_get(struct snd_kcontrol *kcontrol, |
485 | struct snd_ctl_elem_value *ucontrol) |
486 | { |
487 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
488 | |
489 | mutex_lock(&tas->mtx); |
490 | ucontrol->value.enumerated.item[0] = !!(tas->acr & TAS_ACR_INPUT_B); |
491 | mutex_unlock(lock: &tas->mtx); |
492 | return 0; |
493 | } |
494 | |
495 | static int tas_snd_capture_source_put(struct snd_kcontrol *kcontrol, |
496 | struct snd_ctl_elem_value *ucontrol) |
497 | { |
498 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
499 | int oldacr; |
500 | |
501 | if (ucontrol->value.enumerated.item[0] > 1) |
502 | return -EINVAL; |
503 | mutex_lock(&tas->mtx); |
504 | oldacr = tas->acr; |
505 | |
506 | /* |
507 | * Despite what the data sheet says in one place, the |
508 | * TAS_ACR_B_MONAUREAL bit forces mono output even when |
509 | * input A (line in) is selected. |
510 | */ |
511 | tas->acr &= ~(TAS_ACR_INPUT_B | TAS_ACR_B_MONAUREAL); |
512 | if (ucontrol->value.enumerated.item[0]) |
513 | tas->acr |= TAS_ACR_INPUT_B | TAS_ACR_B_MONAUREAL | |
514 | TAS_ACR_B_MON_SEL_RIGHT; |
515 | if (oldacr == tas->acr) { |
516 | mutex_unlock(lock: &tas->mtx); |
517 | return 0; |
518 | } |
519 | if (tas->hw_enabled) |
520 | tas_write_reg(tas, TAS_REG_ACR, len: 1, data: &tas->acr); |
521 | mutex_unlock(lock: &tas->mtx); |
522 | return 1; |
523 | } |
524 | |
525 | static const struct snd_kcontrol_new capture_source_control = { |
526 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
527 | /* If we name this 'Input Source', it properly shows up in |
528 | * alsamixer as a selection, * but it's shown under the |
529 | * 'Playback' category. |
530 | * If I name it 'Capture Source', it shows up in strange |
531 | * ways (two bools of which one can be selected at a |
532 | * time) but at least it's shown in the 'Capture' |
533 | * category. |
534 | * I was told that this was due to backward compatibility, |
535 | * but I don't understand then why the mangling is *not* |
536 | * done when I name it "Input Source"..... |
537 | */ |
538 | .name = "Capture Source" , |
539 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
540 | .info = tas_snd_capture_source_info, |
541 | .get = tas_snd_capture_source_get, |
542 | .put = tas_snd_capture_source_put, |
543 | }; |
544 | |
545 | static int tas_snd_treble_info(struct snd_kcontrol *kcontrol, |
546 | struct snd_ctl_elem_info *uinfo) |
547 | { |
548 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
549 | uinfo->count = 1; |
550 | uinfo->value.integer.min = TAS3004_TREBLE_MIN; |
551 | uinfo->value.integer.max = TAS3004_TREBLE_MAX; |
552 | return 0; |
553 | } |
554 | |
555 | static int tas_snd_treble_get(struct snd_kcontrol *kcontrol, |
556 | struct snd_ctl_elem_value *ucontrol) |
557 | { |
558 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
559 | |
560 | mutex_lock(&tas->mtx); |
561 | ucontrol->value.integer.value[0] = tas->treble; |
562 | mutex_unlock(lock: &tas->mtx); |
563 | return 0; |
564 | } |
565 | |
566 | static int tas_snd_treble_put(struct snd_kcontrol *kcontrol, |
567 | struct snd_ctl_elem_value *ucontrol) |
568 | { |
569 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
570 | |
571 | if (ucontrol->value.integer.value[0] < TAS3004_TREBLE_MIN || |
572 | ucontrol->value.integer.value[0] > TAS3004_TREBLE_MAX) |
573 | return -EINVAL; |
574 | mutex_lock(&tas->mtx); |
575 | if (tas->treble == ucontrol->value.integer.value[0]) { |
576 | mutex_unlock(lock: &tas->mtx); |
577 | return 0; |
578 | } |
579 | |
580 | tas->treble = ucontrol->value.integer.value[0]; |
581 | if (tas->hw_enabled) |
582 | tas_set_treble(tas); |
583 | mutex_unlock(lock: &tas->mtx); |
584 | return 1; |
585 | } |
586 | |
587 | static const struct snd_kcontrol_new treble_control = { |
588 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
589 | .name = "Treble" , |
590 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
591 | .info = tas_snd_treble_info, |
592 | .get = tas_snd_treble_get, |
593 | .put = tas_snd_treble_put, |
594 | }; |
595 | |
596 | static int tas_snd_bass_info(struct snd_kcontrol *kcontrol, |
597 | struct snd_ctl_elem_info *uinfo) |
598 | { |
599 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
600 | uinfo->count = 1; |
601 | uinfo->value.integer.min = TAS3004_BASS_MIN; |
602 | uinfo->value.integer.max = TAS3004_BASS_MAX; |
603 | return 0; |
604 | } |
605 | |
606 | static int tas_snd_bass_get(struct snd_kcontrol *kcontrol, |
607 | struct snd_ctl_elem_value *ucontrol) |
608 | { |
609 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
610 | |
611 | mutex_lock(&tas->mtx); |
612 | ucontrol->value.integer.value[0] = tas->bass; |
613 | mutex_unlock(lock: &tas->mtx); |
614 | return 0; |
615 | } |
616 | |
617 | static int tas_snd_bass_put(struct snd_kcontrol *kcontrol, |
618 | struct snd_ctl_elem_value *ucontrol) |
619 | { |
620 | struct tas *tas = snd_kcontrol_chip(kcontrol); |
621 | |
622 | if (ucontrol->value.integer.value[0] < TAS3004_BASS_MIN || |
623 | ucontrol->value.integer.value[0] > TAS3004_BASS_MAX) |
624 | return -EINVAL; |
625 | mutex_lock(&tas->mtx); |
626 | if (tas->bass == ucontrol->value.integer.value[0]) { |
627 | mutex_unlock(lock: &tas->mtx); |
628 | return 0; |
629 | } |
630 | |
631 | tas->bass = ucontrol->value.integer.value[0]; |
632 | if (tas->hw_enabled) |
633 | tas_set_bass(tas); |
634 | mutex_unlock(lock: &tas->mtx); |
635 | return 1; |
636 | } |
637 | |
638 | static const struct snd_kcontrol_new bass_control = { |
639 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
640 | .name = "Bass" , |
641 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
642 | .info = tas_snd_bass_info, |
643 | .get = tas_snd_bass_get, |
644 | .put = tas_snd_bass_put, |
645 | }; |
646 | |
647 | static struct transfer_info tas_transfers[] = { |
648 | { |
649 | /* input */ |
650 | .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S24_BE, |
651 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, |
652 | .transfer_in = 1, |
653 | }, |
654 | { |
655 | /* output */ |
656 | .formats = SNDRV_PCM_FMTBIT_S16_BE | SNDRV_PCM_FMTBIT_S24_BE, |
657 | .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, |
658 | .transfer_in = 0, |
659 | }, |
660 | {} |
661 | }; |
662 | |
663 | static int tas_usable(struct codec_info_item *cii, |
664 | struct transfer_info *ti, |
665 | struct transfer_info *out) |
666 | { |
667 | return 1; |
668 | } |
669 | |
670 | static int tas_reset_init(struct tas *tas) |
671 | { |
672 | u8 tmp; |
673 | |
674 | tas->codec.gpio->methods->all_amps_off(tas->codec.gpio); |
675 | msleep(msecs: 5); |
676 | tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0); |
677 | msleep(msecs: 5); |
678 | tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 1); |
679 | msleep(msecs: 20); |
680 | tas->codec.gpio->methods->set_hw_reset(tas->codec.gpio, 0); |
681 | msleep(msecs: 10); |
682 | tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio); |
683 | |
684 | tmp = TAS_MCS_SCLK64 | TAS_MCS_SPORT_MODE_I2S | TAS_MCS_SPORT_WL_24BIT; |
685 | if (tas_write_reg(tas, TAS_REG_MCS, len: 1, data: &tmp)) |
686 | goto outerr; |
687 | |
688 | tas->acr |= TAS_ACR_ANALOG_PDOWN; |
689 | if (tas_write_reg(tas, TAS_REG_ACR, len: 1, data: &tas->acr)) |
690 | goto outerr; |
691 | |
692 | tmp = 0; |
693 | if (tas_write_reg(tas, TAS_REG_MCS2, len: 1, data: &tmp)) |
694 | goto outerr; |
695 | |
696 | tas3004_set_drc(tas); |
697 | |
698 | /* Set treble & bass to 0dB */ |
699 | tas->treble = TAS3004_TREBLE_ZERO; |
700 | tas->bass = TAS3004_BASS_ZERO; |
701 | tas_set_treble(tas); |
702 | tas_set_bass(tas); |
703 | |
704 | tas->acr &= ~TAS_ACR_ANALOG_PDOWN; |
705 | if (tas_write_reg(tas, TAS_REG_ACR, len: 1, data: &tas->acr)) |
706 | goto outerr; |
707 | |
708 | return 0; |
709 | outerr: |
710 | return -ENODEV; |
711 | } |
712 | |
713 | static int tas_switch_clock(struct codec_info_item *cii, enum clock_switch clock) |
714 | { |
715 | struct tas *tas = cii->codec_data; |
716 | |
717 | switch(clock) { |
718 | case CLOCK_SWITCH_PREPARE_SLAVE: |
719 | /* Clocks are going away, mute mute mute */ |
720 | tas->codec.gpio->methods->all_amps_off(tas->codec.gpio); |
721 | tas->hw_enabled = 0; |
722 | break; |
723 | case CLOCK_SWITCH_SLAVE: |
724 | /* Clocks are back, re-init the codec */ |
725 | mutex_lock(&tas->mtx); |
726 | tas_reset_init(tas); |
727 | tas_set_volume(tas); |
728 | tas_set_mixer(tas); |
729 | tas->hw_enabled = 1; |
730 | tas->codec.gpio->methods->all_amps_restore(tas->codec.gpio); |
731 | mutex_unlock(lock: &tas->mtx); |
732 | break; |
733 | default: |
734 | /* doesn't happen as of now */ |
735 | return -EINVAL; |
736 | } |
737 | return 0; |
738 | } |
739 | |
740 | #ifdef CONFIG_PM |
741 | /* we are controlled via i2c and assume that is always up |
742 | * If that wasn't the case, we'd have to suspend once |
743 | * our i2c device is suspended, and then take note of that! */ |
744 | static int tas_suspend(struct tas *tas) |
745 | { |
746 | mutex_lock(&tas->mtx); |
747 | tas->hw_enabled = 0; |
748 | tas->acr |= TAS_ACR_ANALOG_PDOWN; |
749 | tas_write_reg(tas, TAS_REG_ACR, len: 1, data: &tas->acr); |
750 | mutex_unlock(lock: &tas->mtx); |
751 | return 0; |
752 | } |
753 | |
754 | static int tas_resume(struct tas *tas) |
755 | { |
756 | /* reset codec */ |
757 | mutex_lock(&tas->mtx); |
758 | tas_reset_init(tas); |
759 | tas_set_volume(tas); |
760 | tas_set_mixer(tas); |
761 | tas->hw_enabled = 1; |
762 | mutex_unlock(lock: &tas->mtx); |
763 | return 0; |
764 | } |
765 | |
766 | static int _tas_suspend(struct codec_info_item *cii, pm_message_t state) |
767 | { |
768 | return tas_suspend(tas: cii->codec_data); |
769 | } |
770 | |
771 | static int _tas_resume(struct codec_info_item *cii) |
772 | { |
773 | return tas_resume(tas: cii->codec_data); |
774 | } |
775 | #else /* CONFIG_PM */ |
776 | #define _tas_suspend NULL |
777 | #define _tas_resume NULL |
778 | #endif /* CONFIG_PM */ |
779 | |
780 | static struct codec_info tas_codec_info = { |
781 | .transfers = tas_transfers, |
782 | /* in theory, we can drive it at 512 too... |
783 | * but so far the framework doesn't allow |
784 | * for that and I don't see much point in it. */ |
785 | .sysclock_factor = 256, |
786 | /* same here, could be 32 for just one 16 bit format */ |
787 | .bus_factor = 64, |
788 | .owner = THIS_MODULE, |
789 | .usable = tas_usable, |
790 | .switch_clock = tas_switch_clock, |
791 | .suspend = _tas_suspend, |
792 | .resume = _tas_resume, |
793 | }; |
794 | |
795 | static int tas_init_codec(struct aoa_codec *codec) |
796 | { |
797 | struct tas *tas = codec_to_tas(codec); |
798 | int err; |
799 | |
800 | if (!tas->codec.gpio || !tas->codec.gpio->methods) { |
801 | printk(KERN_ERR PFX "gpios not assigned!!\n" ); |
802 | return -EINVAL; |
803 | } |
804 | |
805 | mutex_lock(&tas->mtx); |
806 | if (tas_reset_init(tas)) { |
807 | printk(KERN_ERR PFX "tas failed to initialise\n" ); |
808 | mutex_unlock(lock: &tas->mtx); |
809 | return -ENXIO; |
810 | } |
811 | tas->hw_enabled = 1; |
812 | mutex_unlock(lock: &tas->mtx); |
813 | |
814 | if (tas->codec.soundbus_dev->attach_codec(tas->codec.soundbus_dev, |
815 | aoa_get_card(), |
816 | &tas_codec_info, tas)) { |
817 | printk(KERN_ERR PFX "error attaching tas to soundbus\n" ); |
818 | return -ENODEV; |
819 | } |
820 | |
821 | if (aoa_snd_device_new(type: SNDRV_DEV_CODEC, device_data: tas, ops: &ops)) { |
822 | printk(KERN_ERR PFX "failed to create tas snd device!\n" ); |
823 | return -ENODEV; |
824 | } |
825 | err = aoa_snd_ctl_add(control: snd_ctl_new1(kcontrolnew: &volume_control, private_data: tas)); |
826 | if (err) |
827 | goto error; |
828 | |
829 | err = aoa_snd_ctl_add(control: snd_ctl_new1(kcontrolnew: &mute_control, private_data: tas)); |
830 | if (err) |
831 | goto error; |
832 | |
833 | err = aoa_snd_ctl_add(control: snd_ctl_new1(kcontrolnew: &pcm1_control, private_data: tas)); |
834 | if (err) |
835 | goto error; |
836 | |
837 | err = aoa_snd_ctl_add(control: snd_ctl_new1(kcontrolnew: &monitor_control, private_data: tas)); |
838 | if (err) |
839 | goto error; |
840 | |
841 | err = aoa_snd_ctl_add(control: snd_ctl_new1(kcontrolnew: &capture_source_control, private_data: tas)); |
842 | if (err) |
843 | goto error; |
844 | |
845 | err = aoa_snd_ctl_add(control: snd_ctl_new1(kcontrolnew: &drc_range_control, private_data: tas)); |
846 | if (err) |
847 | goto error; |
848 | |
849 | err = aoa_snd_ctl_add(control: snd_ctl_new1(kcontrolnew: &drc_switch_control, private_data: tas)); |
850 | if (err) |
851 | goto error; |
852 | |
853 | err = aoa_snd_ctl_add(control: snd_ctl_new1(kcontrolnew: &treble_control, private_data: tas)); |
854 | if (err) |
855 | goto error; |
856 | |
857 | err = aoa_snd_ctl_add(control: snd_ctl_new1(kcontrolnew: &bass_control, private_data: tas)); |
858 | if (err) |
859 | goto error; |
860 | |
861 | return 0; |
862 | error: |
863 | tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); |
864 | snd_device_free(card: aoa_get_card(), device_data: tas); |
865 | return err; |
866 | } |
867 | |
868 | static void tas_exit_codec(struct aoa_codec *codec) |
869 | { |
870 | struct tas *tas = codec_to_tas(codec); |
871 | |
872 | if (!tas->codec.soundbus_dev) |
873 | return; |
874 | tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); |
875 | } |
876 | |
877 | |
878 | static int tas_i2c_probe(struct i2c_client *client) |
879 | { |
880 | struct device_node *node = client->dev.of_node; |
881 | struct tas *tas; |
882 | |
883 | tas = kzalloc(size: sizeof(struct tas), GFP_KERNEL); |
884 | |
885 | if (!tas) |
886 | return -ENOMEM; |
887 | |
888 | mutex_init(&tas->mtx); |
889 | tas->i2c = client; |
890 | i2c_set_clientdata(client, data: tas); |
891 | |
892 | /* seems that half is a saner default */ |
893 | tas->drc_range = TAS3004_DRC_MAX / 2; |
894 | |
895 | strscpy(tas->codec.name, "tas" , MAX_CODEC_NAME_LEN); |
896 | tas->codec.owner = THIS_MODULE; |
897 | tas->codec.init = tas_init_codec; |
898 | tas->codec.exit = tas_exit_codec; |
899 | tas->codec.node = of_node_get(node); |
900 | |
901 | if (aoa_codec_register(codec: &tas->codec)) { |
902 | goto fail; |
903 | } |
904 | printk(KERN_DEBUG |
905 | "snd-aoa-codec-tas: tas found, addr 0x%02x on %pOF\n" , |
906 | (unsigned int)client->addr, node); |
907 | return 0; |
908 | fail: |
909 | mutex_destroy(lock: &tas->mtx); |
910 | kfree(objp: tas); |
911 | return -EINVAL; |
912 | } |
913 | |
914 | static void tas_i2c_remove(struct i2c_client *client) |
915 | { |
916 | struct tas *tas = i2c_get_clientdata(client); |
917 | u8 tmp = TAS_ACR_ANALOG_PDOWN; |
918 | |
919 | aoa_codec_unregister(codec: &tas->codec); |
920 | of_node_put(node: tas->codec.node); |
921 | |
922 | /* power down codec chip */ |
923 | tas_write_reg(tas, TAS_REG_ACR, len: 1, data: &tmp); |
924 | |
925 | mutex_destroy(lock: &tas->mtx); |
926 | kfree(objp: tas); |
927 | } |
928 | |
929 | static const struct i2c_device_id tas_i2c_id[] = { |
930 | { "MAC,tas3004" , 0 }, |
931 | { } |
932 | }; |
933 | MODULE_DEVICE_TABLE(i2c,tas_i2c_id); |
934 | |
935 | static struct i2c_driver tas_driver = { |
936 | .driver = { |
937 | .name = "aoa_codec_tas" , |
938 | }, |
939 | .probe = tas_i2c_probe, |
940 | .remove = tas_i2c_remove, |
941 | .id_table = tas_i2c_id, |
942 | }; |
943 | |
944 | module_i2c_driver(tas_driver); |
945 | |