• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 The Chromium OS Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file.
4  */
5 
6 #include <sys/socket.h>
7 #include <sys/time.h>
8 #include <syslog.h>
9 
10 #include "cras_audio_area.h"
11 #include "cras_hfp_slc.h"
12 #include "cras_iodev.h"
13 #include "cras_system_state.h"
14 #include "cras_util.h"
15 #include "utlist.h"
16 #include "cras_bt_device.h"
17 
18 #include "cras_hfp_alsa_iodev.h"
19 
20 /* Object to represent a special HFP iodev which would be managed by bt_io but
21  * playback/capture via an inner ALSA iodev.
22  * Members:
23  *    base - The base class cras_iodev.
24  *    device - The corresponding remote BT device.
25  *    slc - The service level connection.
26  *    aio - The effective iodev for playback/capture.
27  */
28 struct hfp_alsa_io {
29 	struct cras_iodev base;
30 	struct cras_bt_device *device;
31 	struct hfp_slc_handle *slc;
32 	struct cras_iodev *aio;
33 };
34 
hfp_alsa_get_valid_frames(struct cras_iodev * iodev,struct timespec * hw_tstamp)35 static int hfp_alsa_get_valid_frames(struct cras_iodev *iodev,
36 				     struct timespec *hw_tstamp)
37 {
38 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
39 	struct cras_iodev *aio = hfp_alsa_io->aio;
40 
41 	return aio->get_valid_frames(aio, hw_tstamp);
42 }
43 
hfp_alsa_open_dev(struct cras_iodev * iodev)44 static int hfp_alsa_open_dev(struct cras_iodev *iodev)
45 {
46 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
47 	struct cras_iodev *aio = hfp_alsa_io->aio;
48 
49 	return aio->open_dev(aio);
50 }
51 
hfp_alsa_update_supported_formats(struct cras_iodev * iodev)52 static int hfp_alsa_update_supported_formats(struct cras_iodev *iodev)
53 {
54 	/* 16 bit, mono, 8kHz (narrow band speech); */
55 	free(iodev->supported_rates);
56 	iodev->supported_rates = malloc(2 * sizeof(*iodev->supported_rates));
57 	if (!iodev->supported_rates)
58 		return -ENOMEM;
59 	iodev->supported_rates[0] = 8000;
60 	iodev->supported_rates[1] = 0;
61 
62 	free(iodev->supported_channel_counts);
63 	iodev->supported_channel_counts =
64 		malloc(2 * sizeof(*iodev->supported_channel_counts));
65 	if (!iodev->supported_channel_counts)
66 		return -ENOMEM;
67 	iodev->supported_channel_counts[0] = 1;
68 	iodev->supported_channel_counts[1] = 0;
69 
70 	free(iodev->supported_formats);
71 	iodev->supported_formats =
72 		malloc(2 * sizeof(*iodev->supported_formats));
73 	if (!iodev->supported_formats)
74 		return -ENOMEM;
75 	iodev->supported_formats[0] = SND_PCM_FORMAT_S16_LE;
76 	iodev->supported_formats[1] = 0;
77 
78 	return 0;
79 }
80 
hfp_alsa_configure_dev(struct cras_iodev * iodev)81 static int hfp_alsa_configure_dev(struct cras_iodev *iodev)
82 {
83 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
84 	struct cras_iodev *aio = hfp_alsa_io->aio;
85 	int rc;
86 
87 	/* Fill back the format iodev is using. */
88 	if (aio->format == NULL) {
89 		aio->format = (struct cras_audio_format *)malloc(
90 			sizeof(*aio->format));
91 		if (!aio->format)
92 			return -ENOMEM;
93 		*aio->format = *iodev->format;
94 	}
95 
96 	rc = aio->configure_dev(aio);
97 	if (rc) {
98 		syslog(LOG_ERR, "Failed to configure aio: %d\n", rc);
99 		return rc;
100 	}
101 
102 	rc = cras_bt_device_get_sco(
103 		hfp_alsa_io->device,
104 		hfp_slc_get_selected_codec(hfp_alsa_io->slc));
105 	if (rc < 0) {
106 		syslog(LOG_ERR, "Failed to get sco: %d\n", rc);
107 		return rc;
108 	}
109 
110 	hfp_set_call_status(hfp_alsa_io->slc, 1);
111 	iodev->buffer_size = aio->buffer_size;
112 
113 	return 0;
114 }
115 
hfp_alsa_close_dev(struct cras_iodev * iodev)116 static int hfp_alsa_close_dev(struct cras_iodev *iodev)
117 {
118 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
119 	struct cras_iodev *aio = hfp_alsa_io->aio;
120 
121 	hfp_set_call_status(hfp_alsa_io->slc, 0);
122 	cras_bt_device_put_sco(hfp_alsa_io->device);
123 	cras_iodev_free_format(iodev);
124 	return aio->close_dev(aio);
125 }
126 
hfp_alsa_frames_queued(const struct cras_iodev * iodev,struct timespec * tstamp)127 static int hfp_alsa_frames_queued(const struct cras_iodev *iodev,
128 				  struct timespec *tstamp)
129 {
130 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
131 	struct cras_iodev *aio = hfp_alsa_io->aio;
132 
133 	return aio->frames_queued(aio, tstamp);
134 }
135 
hfp_alsa_delay_frames(const struct cras_iodev * iodev)136 static int hfp_alsa_delay_frames(const struct cras_iodev *iodev)
137 {
138 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
139 	struct cras_iodev *aio = hfp_alsa_io->aio;
140 
141 	return aio->delay_frames(aio);
142 }
143 
hfp_alsa_get_buffer(struct cras_iodev * iodev,struct cras_audio_area ** area,unsigned * frames)144 static int hfp_alsa_get_buffer(struct cras_iodev *iodev,
145 			       struct cras_audio_area **area, unsigned *frames)
146 {
147 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
148 	struct cras_iodev *aio = hfp_alsa_io->aio;
149 
150 	return aio->get_buffer(aio, area, frames);
151 }
152 
hfp_alsa_put_buffer(struct cras_iodev * iodev,unsigned nwritten)153 static int hfp_alsa_put_buffer(struct cras_iodev *iodev, unsigned nwritten)
154 {
155 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
156 	struct cras_iodev *aio = hfp_alsa_io->aio;
157 
158 	return aio->put_buffer(aio, nwritten);
159 }
160 
hfp_alsa_flush_buffer(struct cras_iodev * iodev)161 static int hfp_alsa_flush_buffer(struct cras_iodev *iodev)
162 {
163 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
164 	struct cras_iodev *aio = hfp_alsa_io->aio;
165 
166 	return aio->flush_buffer(aio);
167 }
168 
hfp_alsa_update_active_node(struct cras_iodev * iodev,unsigned node_idx,unsigned dev_enabled)169 static void hfp_alsa_update_active_node(struct cras_iodev *iodev,
170 					unsigned node_idx, unsigned dev_enabled)
171 {
172 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
173 	struct cras_iodev *aio = hfp_alsa_io->aio;
174 
175 	aio->update_active_node(aio, node_idx, dev_enabled);
176 }
177 
hfp_alsa_start(const struct cras_iodev * iodev)178 static int hfp_alsa_start(const struct cras_iodev *iodev)
179 {
180 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
181 	struct cras_iodev *aio = hfp_alsa_io->aio;
182 
183 	return aio->start(aio);
184 }
185 
hfp_alsa_set_volume(struct cras_iodev * iodev)186 static void hfp_alsa_set_volume(struct cras_iodev *iodev)
187 {
188 	size_t volume;
189 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
190 
191 	volume = cras_system_get_volume();
192 	if (iodev->active_node)
193 		volume = cras_iodev_adjust_node_volume(iodev->active_node,
194 						       volume);
195 
196 	hfp_event_speaker_gain(hfp_alsa_io->slc, volume);
197 }
198 
hfp_alsa_no_stream(struct cras_iodev * iodev,int enable)199 static int hfp_alsa_no_stream(struct cras_iodev *iodev, int enable)
200 {
201 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
202 	struct cras_iodev *aio = hfp_alsa_io->aio;
203 
204 	/*
205 	 * Copy iodev->min_cb_level and iodev->max_cb_level from the parent
206 	 * (i.e. hfp_alsa_iodev).  no_stream() of alsa_io will use them.
207 	 */
208 	aio->min_cb_level = iodev->min_cb_level;
209 	aio->max_cb_level = iodev->max_cb_level;
210 	return aio->no_stream(aio, enable);
211 }
212 
hfp_alsa_is_free_running(const struct cras_iodev * iodev)213 static int hfp_alsa_is_free_running(const struct cras_iodev *iodev)
214 {
215 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
216 	struct cras_iodev *aio = hfp_alsa_io->aio;
217 
218 	return aio->is_free_running(aio);
219 }
220 
hfp_alsa_output_underrun(struct cras_iodev * iodev)221 static int hfp_alsa_output_underrun(struct cras_iodev *iodev)
222 {
223 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
224 	struct cras_iodev *aio = hfp_alsa_io->aio;
225 
226 	/*
227 	 * Copy iodev->min_cb_level and iodev->max_cb_level from the parent
228 	 * (i.e. hfp_alsa_iodev).  output_underrun() of alsa_io will use them.
229 	 */
230 	aio->min_cb_level = iodev->min_cb_level;
231 	aio->max_cb_level = iodev->max_cb_level;
232 
233 	return aio->output_underrun(aio);
234 }
235 
hfp_alsa_iodev_create(struct cras_iodev * aio,struct cras_bt_device * device,struct hfp_slc_handle * slc,enum cras_bt_device_profile profile)236 struct cras_iodev *hfp_alsa_iodev_create(struct cras_iodev *aio,
237 					 struct cras_bt_device *device,
238 					 struct hfp_slc_handle *slc,
239 					 enum cras_bt_device_profile profile)
240 {
241 	struct hfp_alsa_io *hfp_alsa_io;
242 	struct cras_iodev *iodev;
243 	struct cras_ionode *node;
244 	const char *name;
245 
246 	hfp_alsa_io = calloc(1, sizeof(*hfp_alsa_io));
247 	if (!hfp_alsa_io)
248 		return NULL;
249 
250 	iodev = &hfp_alsa_io->base;
251 	iodev->direction = aio->direction;
252 
253 	hfp_alsa_io->device = device;
254 	hfp_alsa_io->slc = slc;
255 	hfp_alsa_io->aio = aio;
256 
257 	/* Set iodev's name to device readable name or the address. */
258 	name = cras_bt_device_name(device);
259 	if (!name)
260 		name = cras_bt_device_object_path(device);
261 	snprintf(iodev->info.name, sizeof(iodev->info.name), "%s", name);
262 	iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = 0;
263 	iodev->info.stable_id = cras_bt_device_get_stable_id(device);
264 
265 	iodev->open_dev = hfp_alsa_open_dev;
266 	iodev->update_supported_formats = hfp_alsa_update_supported_formats;
267 	iodev->configure_dev = hfp_alsa_configure_dev;
268 	iodev->close_dev = hfp_alsa_close_dev;
269 
270 	iodev->frames_queued = hfp_alsa_frames_queued;
271 	iodev->delay_frames = hfp_alsa_delay_frames;
272 	iodev->get_buffer = hfp_alsa_get_buffer;
273 	iodev->put_buffer = hfp_alsa_put_buffer;
274 	iodev->flush_buffer = hfp_alsa_flush_buffer;
275 
276 	iodev->update_active_node = hfp_alsa_update_active_node;
277 	iodev->start = hfp_alsa_start;
278 	iodev->set_volume = hfp_alsa_set_volume;
279 	iodev->get_valid_frames = hfp_alsa_get_valid_frames;
280 	iodev->no_stream = hfp_alsa_no_stream;
281 	iodev->is_free_running = hfp_alsa_is_free_running;
282 	iodev->output_underrun = hfp_alsa_output_underrun;
283 
284 	iodev->min_buffer_level = aio->min_buffer_level;
285 
286 	node = calloc(1, sizeof(*node));
287 	node->dev = iodev;
288 	strcpy(node->name, iodev->info.name);
289 
290 	node->plugged = 1;
291 	/* If headset mic uses legacy narrow band, i.e CVSD codec, report a
292 	 * different node type so UI can set different plug priority. */
293 	node->type = CRAS_NODE_TYPE_BLUETOOTH;
294 	if ((hfp_slc_get_selected_codec(hfp_alsa_io->slc) ==
295 	     HFP_CODEC_ID_CVSD) &&
296 	    (iodev->direction == CRAS_STREAM_INPUT))
297 		node->type = CRAS_NODE_TYPE_BLUETOOTH_NB_MIC;
298 	node->volume = 100;
299 	gettimeofday(&node->plugged_time, NULL);
300 
301 	/* Prepare active node before append, so bt_io can extract correct
302 	 * info from hfp_alsa iodev and node. */
303 	cras_iodev_add_node(iodev, node);
304 	cras_iodev_set_active_node(iodev, node);
305 	cras_bt_device_append_iodev(device, iodev, profile);
306 
307 	/* Record max supported channels into cras_iodev_info. */
308 	iodev->info.max_supported_channels = 1;
309 
310 	/* Specifically disable EWMA calculation on this and the child iodev. */
311 	ewma_power_disable(&iodev->ewma);
312 	ewma_power_disable(&aio->ewma);
313 
314 	return iodev;
315 }
316 
hfp_alsa_iodev_destroy(struct cras_iodev * iodev)317 void hfp_alsa_iodev_destroy(struct cras_iodev *iodev)
318 {
319 	struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
320 	struct cras_ionode *node;
321 
322 	cras_bt_device_rm_iodev(hfp_alsa_io->device, iodev);
323 
324 	node = iodev->active_node;
325 	if (node) {
326 		cras_iodev_rm_node(iodev, node);
327 		free(node);
328 	}
329 
330 	free(iodev->supported_channel_counts);
331 	free(iodev->supported_rates);
332 	free(iodev->supported_formats);
333 	cras_iodev_free_resources(iodev);
334 
335 	free(hfp_alsa_io);
336 }
337