motu: the 4pre channel layout within packets is now believed to be correct. Thanks...
[ffado.git] / libffado / src / fireworks / efc / efc_cmd.cpp
blob0f8447260a7f7df034cfda17a0f3d517df9e2eb0
1 /*
2 * Copyright (C) 2005-2008 by Pieter Palmers
4 * This file is part of FFADO
5 * FFADO = Free Firewire (pro-)audio drivers for linux
7 * FFADO is based upon FreeBoB
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) version 3 of the License.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "efc_cmd.h"
25 #include "efc_cmds_hardware.h"
27 #include "libutil/ByteSwap.h"
28 #include <iostream>
29 #include <cstring>
31 using namespace std;
33 namespace FireWorks {
35 IMPL_DEBUG_MODULE( EfcCmd, EfcCmd, DEBUG_LEVEL_NORMAL );
37 // static int to keep track of the sequence index
38 uint32_t EfcCmd::m_seqnum = 1;
40 // some generic string generation functions
41 const char *eMixerTargetToString(const enum eMixerTarget target) {
42 switch (target) {
43 case eMT_PhysicalOutputMix:
44 return "PhysicalOutputMix";
45 case eMT_PhysicalInputMix:
46 return "PhysicalInputMix";
47 case eMT_PlaybackMix:
48 return "PlaybackMix";
49 case eMT_RecordMix:
50 return "RecordMix";
51 default:
52 return "invalid";
56 const char *eMixerCommandToString(const enum eMixerCommand command) {
57 switch (command) {
58 case eMC_Gain:
59 return "Gain";
60 case eMC_Solo:
61 return "Solo";
62 case eMC_Mute:
63 return "Mute";
64 case eMC_Pan:
65 return "Pan";
66 case eMC_Nominal:
67 return "Nominal";
68 default:
69 return "invalid";
73 const char *eIOConfigRegisterToString(const enum eIOConfigRegister reg) {
74 switch (reg) {
75 case eCR_Mirror:
76 return "Mirror";
77 case eCR_DigitalInterface:
78 return "DigitalInterface";
79 case eCR_Phantom:
80 return "Phantom";
81 case eCR_IsocMap:
82 return "IsocMap";
83 default:
84 return "invalid";
88 // the real deal
90 EfcCmd::EfcCmd(uint32_t cat, uint32_t cmd)
91 : m_length ( 0 )
92 , m_category_id ( cat )
93 , m_command_id ( cmd )
95 memset(&m_header,0,sizeof(m_header));
98 EfcCmd::EfcCmd()
99 : m_length ( 0 )
100 , m_category_id ( EFC_CAT_INVALID )
101 , m_command_id ( EFC_CMD_INVALID )
103 memset(&m_header,0,sizeof(m_header));
106 EfcCmd::~EfcCmd()
110 bool
111 EfcCmd::serialize( Util::Cmd::IOSSerialize& se )
113 bool result=true;
115 result &= se.write(CondSwapToBus32(m_length), "EFC length");
117 unsigned int i=0;
119 // assign the category and the command
120 m_header.category=m_category_id;
121 m_header.command=m_command_id;
123 // set the sequence number
124 m_header.seqnum=m_seqnum++;
126 // serialize the header
127 quadlet_t *header_as_quadlets=(quadlet_t *)&m_header;
128 result &= se.write(CondSwapToBus32(*(header_as_quadlets+i)), "EFC header version"); i++;
129 result &= se.write(CondSwapToBus32(*(header_as_quadlets+i)), "EFC header seqnum"); i++;
130 result &= se.write(CondSwapToBus32(*(header_as_quadlets+i)), "EFC header category"); i++;
131 result &= se.write(CondSwapToBus32(*(header_as_quadlets+i)), "EFC header command"); i++;
132 result &= se.write(CondSwapToBus32(*(header_as_quadlets+i)), "EFC header return value"); i++;
134 return result;
137 bool
138 EfcCmd::deserialize( Util::Cmd::IISDeserialize& de )
140 bool result=true;
142 result &= de.read(&m_length);
143 m_length=CondSwapFromBus32(m_length);
145 // read the EFC header
146 quadlet_t *header_as_quadlets=(quadlet_t *)&m_header;
147 for (unsigned int i=0; i<sizeof(m_header)/4; i++) {
148 result &= de.read((header_as_quadlets+i));
149 *(header_as_quadlets+i)=CondSwapFromBus32(*(header_as_quadlets+i));
152 // check the EFC version
153 if(m_header.version > 1) {
154 debugError("Unsupported EFC version: %d\n", m_header.version);
155 return false;
158 // check whether the category and command of the response are valid
159 if (m_header.category != m_category_id) {
160 debugError("Invalid category response: %d != %d\n", m_header.category, m_category_id);
161 return false;
163 if (m_header.command != m_command_id) {
164 debugError("Invalid command response: %d != %d\n", m_header.command, m_command_id);
165 return false;
167 return result;
170 void
171 EfcCmd::showEfcCmd()
173 debugOutput(DEBUG_LEVEL_NORMAL, "EFC Length: %d\n", m_length);
174 debugOutput(DEBUG_LEVEL_NORMAL, "EFC Header:\n");
175 debugOutput(DEBUG_LEVEL_NORMAL, " Version : 0x%08X\n", m_header.version);
176 debugOutput(DEBUG_LEVEL_NORMAL, " Sequence number : 0x%08X\n", m_header.seqnum);
177 debugOutput(DEBUG_LEVEL_NORMAL, " Category : 0x%08X\n", m_header.category);
178 debugOutput(DEBUG_LEVEL_NORMAL, " Command : 0x%08X\n", m_header.command);
179 debugOutput(DEBUG_LEVEL_NORMAL, " Return Value : 0x%08X\n", m_header.retval);
182 void
183 EfcCmd::setVerboseLevel(int l)
185 setDebugLevel(l);
188 } // namespace FireWorks