162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0+ */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * u_audio.h -- interface to USB gadget "ALSA sound card" utilities 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2016 662306a36Sopenharmony_ci * Author: Ruslan Bilovol <ruslan.bilovol@gmail.com> 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef __U_AUDIO_H 1062306a36Sopenharmony_ci#define __U_AUDIO_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/usb/composite.h> 1362306a36Sopenharmony_ci#include "uac_common.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* 1662306a36Sopenharmony_ci * Same maximum frequency deviation on the slower side as in 1762306a36Sopenharmony_ci * sound/usb/endpoint.c. Value is expressed in per-mil deviation. 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_ci#define FBACK_SLOW_MAX 250 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* 2262306a36Sopenharmony_ci * Maximum frequency deviation on the faster side, default value for UAC1/2. 2362306a36Sopenharmony_ci * Value is expressed in per-mil deviation. 2462306a36Sopenharmony_ci * UAC2 provides the value as a parameter as it impacts the endpoint required 2562306a36Sopenharmony_ci * bandwidth. 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_ci#define FBACK_FAST_MAX 5 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* Feature Unit parameters */ 3062306a36Sopenharmony_cistruct uac_fu_params { 3162306a36Sopenharmony_ci int id; /* Feature Unit ID */ 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci bool mute_present; /* mute control enable */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci bool volume_present; /* volume control enable */ 3662306a36Sopenharmony_ci s16 volume_min; /* min volume in 1/256 dB */ 3762306a36Sopenharmony_ci s16 volume_max; /* max volume in 1/256 dB */ 3862306a36Sopenharmony_ci s16 volume_res; /* volume resolution in 1/256 dB */ 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistruct uac_params { 4262306a36Sopenharmony_ci /* playback */ 4362306a36Sopenharmony_ci int p_chmask; /* channel mask */ 4462306a36Sopenharmony_ci int p_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */ 4562306a36Sopenharmony_ci int p_ssize; /* sample size */ 4662306a36Sopenharmony_ci struct uac_fu_params p_fu; /* Feature Unit parameters */ 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci /* capture */ 4962306a36Sopenharmony_ci int c_chmask; /* channel mask */ 5062306a36Sopenharmony_ci int c_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */ 5162306a36Sopenharmony_ci int c_ssize; /* sample size */ 5262306a36Sopenharmony_ci struct uac_fu_params c_fu; /* Feature Unit parameters */ 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci /* rates are dynamic, in uac_rtd_params */ 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci int req_number; /* number of preallocated requests */ 5762306a36Sopenharmony_ci int fb_max; /* upper frequency drift feedback limit per-mil */ 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistruct g_audio { 6162306a36Sopenharmony_ci struct usb_function func; 6262306a36Sopenharmony_ci struct usb_gadget *gadget; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci struct usb_ep *in_ep; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci struct usb_ep *out_ep; 6762306a36Sopenharmony_ci /* feedback IN endpoint corresponding to out_ep */ 6862306a36Sopenharmony_ci struct usb_ep *in_ep_fback; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci /* Max packet size for all in_ep possible speeds */ 7162306a36Sopenharmony_ci unsigned int in_ep_maxpsize; 7262306a36Sopenharmony_ci /* Max packet size for all out_ep possible speeds */ 7362306a36Sopenharmony_ci unsigned int out_ep_maxpsize; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci /* Notify UAC driver about control change */ 7662306a36Sopenharmony_ci int (*notify)(struct g_audio *g_audio, int unit_id, int cs); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci /* The ALSA Sound Card it represents on the USB-Client side */ 7962306a36Sopenharmony_ci struct snd_uac_chip *uac; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci struct uac_params params; 8262306a36Sopenharmony_ci}; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic inline struct g_audio *func_to_g_audio(struct usb_function *f) 8562306a36Sopenharmony_ci{ 8662306a36Sopenharmony_ci return container_of(f, struct g_audio, func); 8762306a36Sopenharmony_ci} 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_cistatic inline uint num_channels(uint chanmask) 9062306a36Sopenharmony_ci{ 9162306a36Sopenharmony_ci uint num = 0; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci while (chanmask) { 9462306a36Sopenharmony_ci num += (chanmask & 1); 9562306a36Sopenharmony_ci chanmask >>= 1; 9662306a36Sopenharmony_ci } 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci return num; 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci/* 10262306a36Sopenharmony_ci * g_audio_setup - initialize one virtual ALSA sound card 10362306a36Sopenharmony_ci * @g_audio: struct with filled params, in_ep_maxpsize, out_ep_maxpsize 10462306a36Sopenharmony_ci * @pcm_name: the id string for a PCM instance of this sound card 10562306a36Sopenharmony_ci * @card_name: name of this soundcard 10662306a36Sopenharmony_ci * 10762306a36Sopenharmony_ci * This sets up the single virtual ALSA sound card that may be exported by a 10862306a36Sopenharmony_ci * gadget driver using this framework. 10962306a36Sopenharmony_ci * 11062306a36Sopenharmony_ci * Context: may sleep 11162306a36Sopenharmony_ci * 11262306a36Sopenharmony_ci * Returns zero on success, or a negative error on failure. 11362306a36Sopenharmony_ci */ 11462306a36Sopenharmony_ciint g_audio_setup(struct g_audio *g_audio, const char *pcm_name, 11562306a36Sopenharmony_ci const char *card_name); 11662306a36Sopenharmony_civoid g_audio_cleanup(struct g_audio *g_audio); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciint u_audio_start_capture(struct g_audio *g_audio); 11962306a36Sopenharmony_civoid u_audio_stop_capture(struct g_audio *g_audio); 12062306a36Sopenharmony_ciint u_audio_start_playback(struct g_audio *g_audio); 12162306a36Sopenharmony_civoid u_audio_stop_playback(struct g_audio *g_audio); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ciint u_audio_get_capture_srate(struct g_audio *audio_dev, u32 *val); 12462306a36Sopenharmony_ciint u_audio_set_capture_srate(struct g_audio *audio_dev, int srate); 12562306a36Sopenharmony_ciint u_audio_get_playback_srate(struct g_audio *audio_dev, u32 *val); 12662306a36Sopenharmony_ciint u_audio_set_playback_srate(struct g_audio *audio_dev, int srate); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ciint u_audio_get_volume(struct g_audio *g_audio, int playback, s16 *val); 12962306a36Sopenharmony_ciint u_audio_set_volume(struct g_audio *g_audio, int playback, s16 val); 13062306a36Sopenharmony_ciint u_audio_get_mute(struct g_audio *g_audio, int playback, int *val); 13162306a36Sopenharmony_ciint u_audio_set_mute(struct g_audio *g_audio, int playback, int val); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_civoid u_audio_suspend(struct g_audio *g_audio); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci#endif /* __U_AUDIO_H */ 136