greybus: audio: Register CPorts for specific directions

Currently, it is assumed that all audio data CPorts registered on
APB1 are used for transmitting audio data.  That may not always be
true like when a microphone is connected but no speakers.  Also,
the current special protocol lacks a way to tell APB1 whether the CPort
being registered is for transmitting, receiving, or both.

Fix by adding a 'direction' field to the register and unregister CPort
requests and define bits indicating which direction (or both) audio
data will go on that CPort.

Signed-off-by: Mark Greer <mgreer@animalcreek.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Mark Greer 2016-02-26 17:04:36 -07:00 committed by Greg Kroah-Hartman
parent 611924dd72
commit 4a8e519902
4 changed files with 21 additions and 7 deletions

View file

@ -29,13 +29,15 @@ int gb_audio_apbridgea_set_config(struct gb_connection *connection,
EXPORT_SYMBOL_GPL(gb_audio_apbridgea_set_config);
int gb_audio_apbridgea_register_cport(struct gb_connection *connection,
__u16 i2s_port, __u16 cportid)
__u16 i2s_port, __u16 cportid,
__u8 direction)
{
struct audio_apbridgea_register_cport_request req;
req.hdr.type = AUDIO_APBRIDGEA_TYPE_REGISTER_CPORT;
req.hdr.i2s_port = cpu_to_le16(i2s_port);
req.cport = cpu_to_le16(cportid);
req.direction = direction;
return gb_hd_output(connection->hd, &req, sizeof(req),
GB_APB_REQUEST_AUDIO_CONTROL, true);
@ -43,13 +45,15 @@ int gb_audio_apbridgea_register_cport(struct gb_connection *connection,
EXPORT_SYMBOL_GPL(gb_audio_apbridgea_register_cport);
int gb_audio_apbridgea_unregister_cport(struct gb_connection *connection,
__u16 i2s_port, __u16 cportid)
__u16 i2s_port, __u16 cportid,
__u8 direction)
{
struct audio_apbridgea_unregister_cport_request req;
req.hdr.type = AUDIO_APBRIDGEA_TYPE_UNREGISTER_CPORT;
req.hdr.i2s_port = cpu_to_le16(i2s_port);
req.cport = cpu_to_le16(cportid);
req.direction = direction;
return gb_hd_output(connection->hd, &req, sizeof(req),
GB_APB_REQUEST_AUDIO_CONTROL, true);

View file

@ -75,6 +75,9 @@
#define AUDIO_APBRIDGEA_PCM_RATE_176400 BIT(11)
#define AUDIO_APBRIDGEA_PCM_RATE_192000 BIT(12)
#define AUDIO_APBRIDGEA_DIRECTION_TX BIT(0)
#define AUDIO_APBRIDGEA_DIRECTION_RX BIT(1)
/* The I2S port is passed in the 'index' parameter of the USB request */
/* The CPort is passed in the 'value' parameter of the USB request */
@ -94,11 +97,13 @@ struct audio_apbridgea_set_config_request {
struct audio_apbridgea_register_cport_request {
struct audio_apbridgea_hdr hdr;
__le16 cport;
__u8 direction;
} __packed;
struct audio_apbridgea_unregister_cport_request {
struct audio_apbridgea_hdr hdr;
__le16 cport;
__u8 direction;
} __packed;
struct audio_apbridgea_set_tx_data_size_request {

View file

@ -60,7 +60,8 @@ static int gbcodec_startup(struct snd_pcm_substream *substream,
i2s_port = 0; /* fixed for now */
cportid = gb_dai->connection->hd_cport_id;
ret = gb_audio_apbridgea_register_cport(gb_dai->connection, i2s_port,
cportid);
cportid,
AUDIO_APBRIDGEA_DIRECTION_TX);
dev_dbg(dai->dev, "Register %s:%d DAI, ret:%d\n", dai->name, cportid,
ret);
@ -117,7 +118,8 @@ static void gbcodec_shutdown(struct snd_pcm_substream *substream,
/* un register cport */
i2s_port = 0; /* fixed for now */
ret = gb_audio_apbridgea_unregister_cport(gb_dai->connection, i2s_port,
gb_dai->connection->hd_cport_id);
gb_dai->connection->hd_cport_id,
AUDIO_APBRIDGEA_DIRECTION_TX);
dev_dbg(dai->dev, "Unregister %s:%d DAI, ret:%d\n", dai->name,
gb_dai->connection->hd_cport_id, ret);
@ -495,7 +497,8 @@ static void gb_audio_cleanup(struct gbaudio_codec_info *gb)
ret);
cportid = connection->hd_cport_id;
ret = gb_audio_apbridgea_unregister_cport(connection, 0,
cportid);
cportid,
AUDIO_APBRIDGEA_DIRECTION_TX);
if (ret)
dev_info(dev, "%d:Failed during unregister cport\n",
ret);

View file

@ -198,9 +198,11 @@ extern int gb_audio_apbridgea_set_config(struct gb_connection *connection,
__u16 i2s_port, __u32 format,
__u32 rate, __u32 mclk_freq);
extern int gb_audio_apbridgea_register_cport(struct gb_connection *connection,
__u16 i2s_port, __u16 cportid);
__u16 i2s_port, __u16 cportid,
__u8 direction);
extern int gb_audio_apbridgea_unregister_cport(struct gb_connection *connection,
__u16 i2s_port, __u16 cportid);
__u16 i2s_port, __u16 cportid,
__u8 direction);
extern int gb_audio_apbridgea_set_tx_data_size(struct gb_connection *connection,
__u16 i2s_port, __u16 size);
extern int gb_audio_apbridgea_get_tx_delay(struct gb_connection *connection,