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; }
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); }
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; }
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; }
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); }
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; }