27 #include <linux/tty.h>
28 #include <linux/module.h>
40 #include "../codecs/cx20442.h"
55 {
"TELIN",
NULL,
"Mouthpiece"},
56 {
"Earpiece",
NULL,
"TELOUT"},
58 {
"MIC",
NULL,
"Microphone"},
59 {
"Speaker",
NULL,
"SPKOUT"},
67 static const char *ams_delta_audio_mode[] =
68 {
"Mixed",
"Handset",
"Handsfree",
"Speakerphone"};
71 #define AMS_DELTA_MOUTHPIECE 0
72 #define AMS_DELTA_EARPIECE 1
73 #define AMS_DELTA_MICROPHONE 2
74 #define AMS_DELTA_SPEAKER 3
75 #define AMS_DELTA_AGC 4
77 #define AMS_DELTA_MIXED ((1 << AMS_DELTA_EARPIECE) | \
78 (1 << AMS_DELTA_MICROPHONE))
79 #define AMS_DELTA_HANDSET ((1 << AMS_DELTA_MOUTHPIECE) | \
80 (1 << AMS_DELTA_EARPIECE))
81 #define AMS_DELTA_HANDSFREE ((1 << AMS_DELTA_MICROPHONE) | \
82 (1 << AMS_DELTA_SPEAKER))
83 #define AMS_DELTA_SPEAKERPHONE (AMS_DELTA_HANDSFREE | (1 << AMS_DELTA_AGC))
85 static const unsigned short ams_delta_audio_mode_pins[] = {
92 static unsigned short ams_delta_audio_agc;
94 static int ams_delta_set_audio_mode(
struct snd_kcontrol *kcontrol,
107 if (ucontrol->
value.enumerated.item[0] >= control->
max)
113 pins = ams_delta_audio_mode_pins[ucontrol->
value.enumerated.item[0]];
149 if (pin != ams_delta_audio_agc) {
150 ams_delta_audio_agc =
pin;
165 static int ams_delta_get_audio_mode(
struct snd_kcontrol *kcontrol,
186 for (mode = 0; mode <
ARRAY_SIZE(ams_delta_audio_mode); mode++)
187 if (pins == ams_delta_audio_mode_pins[mode])
193 ucontrol->
value.enumerated.item[0] =
mode;
198 static const struct soc_enum ams_delta_audio_enum[] = {
200 ams_delta_audio_mode),
205 ams_delta_get_audio_mode, ams_delta_set_audio_mode),
210 static struct snd_soc_jack_gpio ams_delta_hook_switch_gpios[] = {
213 .name =
"hook_switch",
216 .debounce_time = 150,
255 static bool cx81801_cmd_pending;
256 static bool ams_delta_muted;
259 static void cx81801_timeout(
unsigned long data)
263 spin_lock(&ams_delta_lock);
264 cx81801_cmd_pending = 0;
265 muted = ams_delta_muted;
266 spin_unlock(&ams_delta_lock);
271 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0);
281 static int cx81801_open(
struct tty_struct *tty)
303 static void cx81801_close(
struct tty_struct *tty)
311 INIT_LIST_HEAD(&ams_delta_hook_switch.pins);
328 static int cx81801_hangup(
struct tty_struct *tty)
335 static void cx81801_receive(
struct tty_struct *tty,
336 const unsigned char *
cp,
char *
fp,
int count)
339 const unsigned char *
c;
351 v253_ops.receive_buf(tty, cp, fp, count);
356 ams_delta_hook_switch_pins);
359 "Failed to link hook switch to DAPM pins, "
360 "will continue with hook switch unlinked.\n");
365 v253_ops.receive_buf(tty, cp, fp, count);
367 for (c = &cp[count - 1]; c >=
cp; c--) {
372 spin_lock_bh(&ams_delta_lock);
374 apply = !ams_delta_muted && !cx81801_cmd_pending;
375 cx81801_cmd_pending = 1;
376 spin_unlock_bh(&ams_delta_lock);
381 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
382 AMS_DELTA_LATCH2_MODEM_CODEC);
388 static void cx81801_wakeup(
struct tty_struct *tty)
397 .open = cx81801_open,
398 .close = cx81801_close,
399 .hangup = cx81801_hangup,
400 .receive_buf = cx81801_receive,
401 .write_wakeup = cx81801_wakeup,
425 .hw_params = ams_delta_hw_params,
431 static bool ams_delta_muted = 1;
437 if (ams_delta_muted == mute)
440 spin_lock_bh(&ams_delta_lock);
441 ams_delta_muted =
mute;
442 apply = !cx81801_cmd_pending;
443 spin_unlock_bh(&ams_delta_lock);
446 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
447 mute ? AMS_DELTA_LATCH2_MODEM_CODEC : 0);
453 .digital_mute = ams_delta_digital_mute,
459 return ams_delta_digital_mute(
NULL, 0);
464 ams_delta_digital_mute(
NULL, 1);
482 cx20442_codec =
codec;
485 if (!codec_dai->
driver->ops) {
486 codec_dai->
driver->ops = &ams_delta_dai_ops;
488 ams_delta_ops.
startup = ams_delta_startup;
489 ams_delta_ops.
shutdown = ams_delta_shutdown;
498 "Failed to allocate resources for hook switch, "
499 "will continue without one.\n");
501 ret = snd_soc_jack_add_gpios(&ams_delta_hook_switch,
503 ams_delta_hook_switch_gpios);
506 "Failed to set up hook switch GPIO line, "
507 "will continue with hook switch inactive.\n");
514 "Failed to register line discipline, "
515 "will continue without any controls.\n");
524 "Failed to register DAPM controls, "
525 "will continue without any.\n");
533 "Failed to set up DAPM routes, "
534 "will continue with codec default map.\n");
551 "Failed to register audio mode control, "
552 "will continue without it.\n");
560 .stream_name =
"CX20442",
561 .cpu_dai_name =
"omap-mcbsp.1",
562 .codec_dai_name =
"cx20442-voice",
563 .init = ams_delta_cx20442_init,
564 .platform_name =
"omap-pcm-audio",
565 .codec_name =
"cx20442-codec",
566 .ops = &ams_delta_ops,
573 .dai_link = &ams_delta_dai_link,
587 dev_err(&pdev->
dev,
"snd_soc_register_card failed (%d)\n", ret);
600 "failed to unregister V253 line discipline\n");
602 snd_soc_jack_free_gpios(&ams_delta_hook_switch,
604 ams_delta_hook_switch_gpios);
611 #define DRV_NAME "ams-delta-audio"
618 .probe = ams_delta_probe,