Example #1
0
static int put_buffer(struct cras_iodev *iodev, unsigned nwritten)
{
	struct hfp_io *hfpio = (struct hfp_io *)iodev;

	if (!hfp_info_running(hfpio->info))
		return -1;

	hfp_buf_release(hfpio->info, iodev, nwritten);
	return 0;
}
Example #2
0
static int frames_queued(const struct cras_iodev *iodev,
			 struct timespec *tstamp)
{
	struct hfp_io *hfpio = (struct hfp_io *)iodev;

	if (!hfp_info_running(hfpio->info))
		return -1;

	/* Do not enable timestamp mechanism on HFP device because last time
	 * stamp might be a long time ago and it is not really useful. */
	clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
	return hfp_buf_queued(hfpio->info, iodev);
}
Example #3
0
static int close_dev(struct cras_iodev *iodev)
{
	struct hfp_io *hfpio = (struct hfp_io *)iodev;

	hfp_info_rm_iodev(hfpio->info, iodev);
	if (hfp_info_running(hfpio->info) && !hfp_info_has_iodev(hfpio->info)) {
		hfp_info_stop(hfpio->info);
		hfp_set_call_status(hfpio->slc, 0);
	}

	cras_iodev_free_format(iodev);
	cras_iodev_free_audio_area(iodev);
	return 0;
}
Example #4
0
static int get_buffer(struct cras_iodev *iodev,
		      struct cras_audio_area **area,
		      unsigned *frames)
{
	struct hfp_io *hfpio = (struct hfp_io *)iodev;
	uint8_t *dst = NULL;

	if (!hfp_info_running(hfpio->info))
		return -1;

	hfp_buf_acquire(hfpio->info, iodev, &dst, frames);

	iodev->area->frames = *frames;
	/* HFP is mono only. */
	iodev->area->channels[0].step_bytes =
		cras_get_format_bytes(iodev->format);
	iodev->area->channels[0].buf = dst;

	*area = iodev->area;
	return 0;
}
Example #5
0
static void destroy_audio_gateway(struct audio_gateway *ag)
{
	DL_DELETE(connected_ags, ag);

	if (ag->idev)
		hfp_iodev_destroy(ag->idev);
	if (ag->odev)
		hfp_iodev_destroy(ag->odev);
	if (ag->info) {
		if (hfp_info_running(ag->info))
			hfp_info_stop(ag->info);
		hfp_info_destroy(ag->info);
	}
	if (ag->slc_handle)
		hfp_slc_destroy(ag->slc_handle);

	/* If the bt device is not using a2dp, do a deeper clean up
	 * to force disconnect it. */
	if (!cras_bt_device_has_a2dp(ag->device))
		cras_bt_device_disconnect(ag->conn, ag->device);

	free(ag);
}
Example #6
0
static int open_dev(struct cras_iodev *iodev)
{
	struct hfp_io *hfpio = (struct hfp_io *)iodev;
	int sk, err, mtu;

	/* Assert format is set before opening device. */
	if (iodev->format == NULL)
		return -EINVAL;
	iodev->format->format = SND_PCM_FORMAT_S16_LE;
	cras_iodev_init_audio_area(iodev, iodev->format->num_channels);

	if (hfp_info_running(hfpio->info))
		goto add_dev;

	sk = cras_bt_device_sco_connect(hfpio->device);
	if (sk < 0)
		goto error;

	mtu = cras_bt_device_sco_mtu(hfpio->device, sk);

	/* Start hfp_info */
	err = hfp_info_start(sk, mtu, hfpio->info);
	if (err)
		goto error;

add_dev:
	hfp_info_add_iodev(hfpio->info, iodev);
	hfp_set_call_status(hfpio->slc, 1);

	iodev->buffer_size = hfp_buf_size(hfpio->info, iodev);

	return 0;
error:
	syslog(LOG_ERR, "Failed to open HFP iodev");
	return -1;
}