-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ALSA: bebob: Add commands and connections/streams management
This commit adds management functionality for connections and streams. BeBoB uses CMP to manage connections and uses AMDTP for streams. This commit also adds some BridgeCo's AV/C extension commands. There are some BridgeCo's AV/C extension commands but this commit just uses below commands to get device's capability and status: 1.Extended Plug Info commands - Plug Channel Position Specific Data - Plug Type Specific Data - Cluster(Section) Info Specific Data - Plug Input Specific Data 2.Extended Stream Format Information commands - Extended Stream Format Information Command - List Request For Extended Plug Info commands for Cluster Info Specific Data, I pick up 'section' instead of 'cluster' from document to prevent from misunderstanding because 'cluster' is also used in IEC 61883-6. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de>
- Loading branch information
Takashi Sakamoto
authored and
Takashi Iwai
committed
May 26, 2014
1 parent
fd6f4b0
commit eb7b3a0
Showing
5 changed files
with
1,208 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
snd-bebob-objs := bebob.o | ||
snd-bebob-objs := bebob_command.o bebob_stream.o bebob.o | ||
obj-m += snd-bebob.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
/* | ||
* bebob_command.c - driver for BeBoB based devices | ||
* | ||
* Copyright (c) 2013-2014 Takashi Sakamoto | ||
* | ||
* Licensed under the terms of the GNU General Public License, version 2. | ||
*/ | ||
|
||
#include "./bebob.h" | ||
|
||
static inline void | ||
avc_bridgeco_fill_extension_addr(u8 *buf, u8 *addr) | ||
{ | ||
buf[1] = addr[0]; | ||
memcpy(buf + 4, addr + 1, 5); | ||
} | ||
|
||
static inline void | ||
avc_bridgeco_fill_plug_info_extension_command(u8 *buf, u8 *addr, | ||
unsigned int itype) | ||
{ | ||
buf[0] = 0x01; /* AV/C STATUS */ | ||
buf[2] = 0x02; /* AV/C GENERAL PLUG INFO */ | ||
buf[3] = 0xc0; /* BridgeCo extension */ | ||
avc_bridgeco_fill_extension_addr(buf, addr); | ||
buf[9] = itype; /* info type */ | ||
} | ||
|
||
int avc_bridgeco_get_plug_type(struct fw_unit *unit, | ||
u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
enum avc_bridgeco_plug_type *type) | ||
{ | ||
u8 *buf; | ||
int err; | ||
|
||
buf = kzalloc(12, GFP_KERNEL); | ||
if (buf == NULL) | ||
return -ENOMEM; | ||
|
||
/* Info type is 'plug type'. */ | ||
avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x00); | ||
|
||
err = fcp_avc_transaction(unit, buf, 12, buf, 12, | ||
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
BIT(6) | BIT(7) | BIT(9)); | ||
if ((err >= 0) && (err < 8)) | ||
err = -EIO; | ||
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
err = -ENOSYS; | ||
else if (buf[0] == 0x0a) /* REJECTED */ | ||
err = -EINVAL; | ||
else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
err = -EAGAIN; | ||
if (err < 0) | ||
goto end; | ||
|
||
*type = buf[10]; | ||
err = 0; | ||
end: | ||
kfree(buf); | ||
return err; | ||
} | ||
|
||
int avc_bridgeco_get_plug_ch_pos(struct fw_unit *unit, | ||
u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
u8 *buf, unsigned int len) | ||
{ | ||
int err; | ||
|
||
/* Info type is 'channel position'. */ | ||
avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x03); | ||
|
||
err = fcp_avc_transaction(unit, buf, 12, buf, 256, | ||
BIT(1) | BIT(2) | BIT(3) | BIT(4) | | ||
BIT(5) | BIT(6) | BIT(7) | BIT(9)); | ||
if ((err >= 0) && (err < 8)) | ||
err = -EIO; | ||
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
err = -ENOSYS; | ||
else if (buf[0] == 0x0a) /* REJECTED */ | ||
err = -EINVAL; | ||
else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
err = -EAGAIN; | ||
if (err < 0) | ||
goto end; | ||
|
||
/* Pick up specific data. */ | ||
memmove(buf, buf + 10, err - 10); | ||
err = 0; | ||
end: | ||
return err; | ||
} | ||
|
||
int avc_bridgeco_get_plug_section_type(struct fw_unit *unit, | ||
u8 addr[AVC_BRIDGECO_ADDR_BYTES], | ||
unsigned int id, u8 *type) | ||
{ | ||
u8 *buf; | ||
int err; | ||
|
||
/* section info includes charactors but this module don't need it */ | ||
buf = kzalloc(12, GFP_KERNEL); | ||
if (buf == NULL) | ||
return -ENOMEM; | ||
|
||
/* Info type is 'section info'. */ | ||
avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x07); | ||
buf[10] = 0xff & ++id; /* section id */ | ||
|
||
err = fcp_avc_transaction(unit, buf, 12, buf, 12, | ||
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
BIT(6) | BIT(7) | BIT(9) | BIT(10)); | ||
if ((err >= 0) && (err < 8)) | ||
err = -EIO; | ||
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
err = -ENOSYS; | ||
else if (buf[0] == 0x0a) /* REJECTED */ | ||
err = -EINVAL; | ||
else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
err = -EAGAIN; | ||
if (err < 0) | ||
goto end; | ||
|
||
*type = buf[11]; | ||
err = 0; | ||
end: | ||
kfree(buf); | ||
return err; | ||
} | ||
|
||
int avc_bridgeco_get_plug_input(struct fw_unit *unit, | ||
u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 input[7]) | ||
{ | ||
int err; | ||
u8 *buf; | ||
|
||
buf = kzalloc(18, GFP_KERNEL); | ||
if (buf == NULL) | ||
return -ENOMEM; | ||
|
||
/* Info type is 'plug input'. */ | ||
avc_bridgeco_fill_plug_info_extension_command(buf, addr, 0x05); | ||
|
||
err = fcp_avc_transaction(unit, buf, 16, buf, 16, | ||
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
BIT(6) | BIT(7)); | ||
if ((err >= 0) && (err < 8)) | ||
err = -EIO; | ||
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
err = -ENOSYS; | ||
else if (buf[0] == 0x0a) /* REJECTED */ | ||
err = -EINVAL; | ||
else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
err = -EAGAIN; | ||
if (err < 0) | ||
goto end; | ||
|
||
memcpy(input, buf + 10, 5); | ||
err = 0; | ||
end: | ||
kfree(buf); | ||
return err; | ||
} | ||
|
||
int avc_bridgeco_get_plug_strm_fmt(struct fw_unit *unit, | ||
u8 addr[AVC_BRIDGECO_ADDR_BYTES], u8 *buf, | ||
unsigned int *len, unsigned int eid) | ||
{ | ||
int err; | ||
|
||
/* check given buffer */ | ||
if ((buf == NULL) || (*len < 12)) { | ||
err = -EINVAL; | ||
goto end; | ||
} | ||
|
||
buf[0] = 0x01; /* AV/C STATUS */ | ||
buf[2] = 0x2f; /* AV/C STREAM FORMAT SUPPORT */ | ||
buf[3] = 0xc1; /* Bridgeco extension - List Request */ | ||
avc_bridgeco_fill_extension_addr(buf, addr); | ||
buf[10] = 0xff & eid; /* Entry ID */ | ||
|
||
err = fcp_avc_transaction(unit, buf, 12, buf, *len, | ||
BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | | ||
BIT(6) | BIT(7) | BIT(10)); | ||
if ((err >= 0) && (err < 12)) | ||
err = -EIO; | ||
else if (buf[0] == 0x08) /* NOT IMPLEMENTED */ | ||
err = -ENOSYS; | ||
else if (buf[0] == 0x0a) /* REJECTED */ | ||
err = -EINVAL; | ||
else if (buf[0] == 0x0b) /* IN TRANSITION */ | ||
err = -EAGAIN; | ||
else if (buf[10] != eid) | ||
err = -EIO; | ||
if (err < 0) | ||
goto end; | ||
|
||
/* Pick up 'stream format info'. */ | ||
memmove(buf, buf + 11, err - 11); | ||
*len = err - 11; | ||
err = 0; | ||
end: | ||
return err; | ||
} |
Oops, something went wrong.