4 #include <alsa/asoundlib.h>
10 #define MODE_RINGTONE 1
11 #define MODE_IN_CALL 2
12 #define MODE_IN_COMMUNICATION 3
14 #define DISCONNECT 0x00
15 #define DEVICE_OUT_EARPIECE 0x1
16 #define DEVICE_OUT_SPEAKER 0x2
17 #define DEVICE_OUT_WIRED_HEADSET 0x4
18 #define DEVICE_OUT_WIRED_HEADPHONE 0x8
20 #define A1026_IOCTL_MAGIC 'u'
22 #define A1026_BOOTUP_INIT _IO(A1026_IOCTL_MAGIC, 0x01)
23 #define A1026_SUSPEND _IO(A1026_IOCTL_MAGIC, 0x02)
24 #define A1026_ENABLE_CLOCK _IO(A1026_IOCTL_MAGIC, 0x03)
26 #define ES305B_DEVICE "/dev/audience_es305"
28 #define FIRMWARE_NAME_MAX_LENGTH 64
30 static const unsigned char es305b_no_acoustic[] = { 0x80, 0x31, 0x00, 0x06 };
32 static int a1026_enabled;
34 static snd_pcm_t *handle_playback = NULL;
35 static snd_pcm_t *handle_capture = NULL;
37 static const char *playback_name(int mode, uint32_t device)
40 case DEVICE_OUT_EARPIECE:
41 return "VoicePlayback_Earpiece_incall";
42 case DEVICE_OUT_SPEAKER:
43 return "VoicePlayback_Speaker_incall";
44 case DEVICE_OUT_WIRED_HEADSET:
45 return "VoicePlayback_Headset_incall";
46 case DEVICE_OUT_WIRED_HEADPHONE:
47 return "VoicePlayback_Headphone_incall";
52 static const char *capture_name(int mode, uint32_t device)
54 /* No distinction as ALSA mixer control are set during playback
56 return "VoiceCapture_incall";
59 static void pcm_init(void)
61 int card = snd_card_get_index("medfieldaudio");
63 dbg("Card index: %d\n", card);
66 static void pcm_enable(int mode, uint32_t device)
68 const char *pcm_playback;
69 const char *pcm_capture;
72 pcm_playback = playback_name(mode, device);
73 pcm_capture = capture_name(mode, device);
75 dbg("Playback: %s\n", pcm_playback);
76 dbg("Capture: %s\n", pcm_capture);
78 if (!pcm_playback || !pcm_capture)
82 snd_pcm_close(handle_capture);
83 handle_capture = NULL;
86 if (handle_playback) {
87 snd_pcm_close(handle_playback);
88 handle_playback = NULL;
91 err = snd_pcm_open(&handle_playback, pcm_playback,
92 SND_PCM_STREAM_PLAYBACK, 0);
94 err("Failed to open %s\n", pcm_playback);
98 err = snd_pcm_open(&handle_capture, pcm_capture,
99 SND_PCM_STREAM_CAPTURE, 0);
101 err("Failed to open %s\n", pcm_capture);
105 err = snd_pcm_set_params(handle_playback,
106 SND_PCM_FORMAT_S16_LE,
107 SND_PCM_ACCESS_RW_INTERLEAVED,
108 2, 48000, 0, 500000); /* 0.5sec */
110 err("Failed to set params for %s\n",
115 err = snd_pcm_set_params(handle_capture,
116 SND_PCM_FORMAT_S16_LE,
117 SND_PCM_ACCESS_RW_INTERLEAVED,
118 1, 48000, 1, 500000); /* 0.5sec */
120 err("Failed to set params for %s\n",
128 snd_pcm_close(handle_capture);
131 snd_pcm_close(handle_playback);
134 static void pcm_disable(void)
136 if (handle_capture) {
137 snd_pcm_close(handle_capture);
138 handle_capture = NULL;
141 if (handle_playback) {
142 snd_pcm_close(handle_playback);
143 handle_playback = NULL;
147 static void a1026_init(void)
149 const unsigned char cmd1[] = { 0x80, 0x20, 0x00, 0x00 };
150 const unsigned char cmd2[] = { 0x80, 0x21, 0x00, 0x00 };
151 const char firmware_name[FIRMWARE_NAME_MAX_LENGTH] = {
152 "vpimg_es305b-NH.bin"};
153 unsigned char buf[4];
155 ssize_t written, len;
161 fd = open(ES305B_DEVICE, O_RDWR, 0);
163 err("Failed to open audience device\n");
167 err = ioctl(fd, A1026_ENABLE_CLOCK);
169 err("Failed to enable audience clock\n");
173 err = ioctl(fd, A1026_BOOTUP_INIT, firmware_name);
175 err("Failed to boot up audience\n");
179 dbg("A1026 init done\n");
181 written = write(fd, cmd1, sizeof(cmd1));
183 err("First command failed\n");
187 for (i = 0; i < sizeof(label) - 1; i++) {
188 len = read(fd, buf, sizeof(buf));
190 err("Read command failed\n");
196 written = write(fd, cmd2, sizeof(cmd2));
198 err("Second command failed\n");
205 err("Firmware: %s\n", label);
210 err = ioctl(fd, A1026_SUSPEND);
212 err("Failed to suspend audience\n");
218 static void a1026_wakeup(void)
223 dbg("A1026 wakeup\n");
228 fd = open(ES305B_DEVICE, O_RDWR, 0);
230 err("Failed to open audience device\n");
234 err = ioctl(fd, A1026_ENABLE_CLOCK);
236 err("Failed to enable audience clock\n");
240 written = write(fd, es305b_no_acoustic, sizeof(es305b_no_acoustic));
242 err("Acoustic command failed\n");
250 static void a1026_suspend(void)
254 dbg("A1026 suspend\n");
259 fd = open(ES305B_DEVICE, O_RDWR, 0);
261 err("Failed to open audience device\n");
265 err = ioctl(fd, A1026_SUSPEND);
267 err("Failed to suspend audience\n");
274 static void medfield_init(void)
284 /* Enable and disable voice device since otherwise it seems the
285 * first call stays silent */
286 pcm_enable(MODE_IN_CALL, DEVICE_OUT_EARPIECE);
295 static void medfield_cleanup(void)
302 static void medfield_enable(int mode, uint32_t device)
306 pcm_enable(mode, device);
309 static void medfield_disable(void)
316 static inline int audio_device_converter(int device)
321 case CALL_SOUND_PATH_HANDSET:
322 return DEVICE_OUT_EARPIECE;
323 case CALL_SOUND_PATH_SPEAKER:
324 return DEVICE_OUT_SPEAKER;
326 return DEVICE_OUT_EARPIECE;
330 TReturn pr3_audio_set_sound_path(TcoreHal *hal, int device)
332 int devId = audio_device_converter(device);
334 dbg("device Id %d", devId);
336 if (devId == DISCONNECT)
339 medfield_enable(MODE_IN_CALL, devId);
341 return TCORE_RETURN_SUCCESS;
344 gboolean pr3_audio_init(void)
351 gboolean pr3_audio_unload(void)