summaryrefslogtreecommitdiffstats
path: root/Jabra-Solemate/JabraUsbHAL.c
blob: 2ad3fb0b3d8bb533b9a12cf5d77e296ac2ba6801 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*
 * Copyright (C) 2016 "IoT.bzh"
 * Author Fulup Ar Foll <fulup@iot.bzh>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *
 * To find out which control your sound card uses
 *  aplay -l  # Check sndcard name name in between []
 *  amixer -D hw:v1340 controls # get supported controls
 *  amixer -Dhw:v1340 cget name=Power-Switch
 *  amixer -Dhw:v1340 cset name=Power-Switch true
 *
 */
#define _GNU_SOURCE
#include "hal-interface.h"

// Define few private tag for not standard functions
#define PCM_Volume_Multimedia 1000
#define PCM_Volume_Navigation 1001
#define PCM_Volume_Emergency      1002

// Default Values for MasterVolume Ramping
STATIC halVolRampT volRampMaster= {
    .mode    = RAMP_VOL_NORMAL,
    .slave   = Master_Playback_Volume,
    .delay   = 100*1000, // ramping delay in us
    .stepDown=1,
    .stepUp  =1,
};

//Solvol Ramping Value can be customize by Audio Role and Hardwar card
STATIC halVolRampT volRampGuidance= {
    .slave   = Guidance_Playback_Volume,
    .delay   = 50*1000, // ramping delay in us
    .stepDown= 2,
    .stepUp  = 4,
};

STATIC halVolRampT volRampCommunication= {
    .slave   = Communication_Playback_Volume,
    .delay   = 50*1000, // ramping delay in us
    .stepDown= 6,
    .stepUp  = 4,
};

STATIC halVolRampT volRampEntertainment= {
    .slave   = Entertainment_Playback_Volume,
    .delay   = 100*1000, // ramping delay in us
    .stepDown= 4,
    .stepUp  = 2,
};

STATIC halVolRampT volRampNotification= {
    .slave   = Notification_Playback_Volume,
    .delay   = 50*1000, // ramping delay in us
    .stepDown= 6,
    .stepUp  = 4,
};

STATIC halVolRampT volRampWarning= {
    .slave   = Warning_Playback_Volume,
    .delay   = 10*1000, // ramping delay in us
    .stepDown= 6,
    .stepUp  = 10,
};

STATIC halVolRampT volRampSystem= {
    .slave   = System_Playback_Volume,
    .delay   = 20*100, // ramping delay in us
    .stepDown= 6,
    .stepUp  = 10,
};

STATIC halVolRampT volRampStartup= {
    .slave   = Startup_Playback_Volume,
    .delay   = 20*100, // ramping delay in us
    .stepDown= 6,
    .stepUp  = 10,
};

STATIC halVolRampT volRampShutdown= {
    .slave   = Shutdown_Playback_Volume,
    .delay   = 20*100, // ramping delay in us
    .stepDown= 6,
    .stepUp  = 10,
};


// Map HAL hight sndctl with Alsa numid and optionally with a custom callback for non Alsa supported functionalities.
STATIC alsaHalMapT  alsaHalMap[]= {
  { .tag=Master_Playback_Volume, .  ctl={.name="PCM Playback Volume", .value=12 }},
  { .tag=PCM_Playback_Volume     , .ctl={.name="PCM Playback Volume", .value=12 }},
  { .tag=PCM_Playback_Switch     , .ctl={.name="PCM Playback Switch", .value=01 }},
  { .tag=Capture_Volume          , .ctl={.name="Mic Capture Volume"  }},

  // Sound card does not have hardware volume ramping
  { .tag=Master_Playback_Ramp   , .cb={.callback=volumeRamp, .handle=&volRampMaster}, .info="ramp volume linearly according to current ramp setting",
    .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .count=1, .minval=0, .maxval=100, .step=1, .name="Rampup Master"}
  },

  // Implement Rampup Volume for Virtual Channels (0-100)
  { .tag=Guidance_Playback_Ramp, .cb={.callback=volumeRamp, .handle=&volRampGuidance}, .info="RampUp Guidance Volume",
    .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER,.name="Guidance_Ramp", .minval=0, .maxval=100, .step=1, .value=80 }
  },
  { .tag=Entertainment_Playback_Ramp, .cb={.callback=volumeRamp, .handle=&volRampEntertainment}, .info="Rampup Entertainment Volume",
    .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER,.name="Entertainment_Ramp", .minval=0, .maxval=100, .step=1, .value=80 }
  },
  { .tag=Notification_Playback_Ramp, .cb={.callback=volumeRamp, .handle=&volRampNotification}, .info="Ramp-up Notification Volume",
    .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .name="Notification_Ramp", .minval=0, .maxval=100, .step=1, .value=80 }
  },
  { .tag=Communication_Playback_Ramp, .cb={.callback=volumeRamp, .handle=&volRampCommunication}, .info="RampUp Communication Volume",
    .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER,.name="Communication_Ramp", .minval=0, .maxval=100, .step=1, .value=80 }
  },
  { .tag=Warning_Playback_Ramp, .cb={.callback=volumeRamp, .handle=&volRampWarning}, .info="Ramp-up Warning Volume",
    .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .name="Warning_Ramp", .minval=0, .maxval=100, .step=1, .value=80 }
  },

  { .tag=System_Playback_Ramp, .cb={.callback=volumeRamp, .handle=&volRampSystem}, .info="Ramp-up System Volume",
    .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .name="System_Ramp", .minval=0, .maxval=100, .step=1, .value=80 }
  },
  { .tag=Startup_Playback_Ramp, .cb={.callback=volumeRamp, .handle=&volRampStartup}, .info="Ramp-up Startup Volume",
    .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .name="Startup_Ramp", .minval=0, .maxval=100, .step=1, .value=80 }
  },
  { .tag=Shutdown_Playback_Ramp, .cb={.callback=volumeRamp, .handle=&volRampShutdown}, .info="Ramp-up Shutdown Volume",
    .ctl={.numid=CTL_AUTO, .type=SND_CTL_ELEM_TYPE_INTEGER, .name="Shutdown_Ramp", .minval=0, .maxval=100, .step=1, .value=80 }
  },

  // Bind with existing ones created by ALSA configuration (and linked to softvol) [0-255]
  { .tag=Guidance_Playback_Volume      , .ctl={.name="Guidance_Volume", .minval=0, .maxval=255, .step=1, .value=204 } },
  { .tag=Entertainment_Playback_Volume , .ctl={.name="Entertainment_Volume", .minval=0, .maxval=255, .step=1, .value=204 } },
  { .tag=Notification_Playback_Volume  , .ctl={.name="Notification_Volume", .minval=0, .maxval=255, .step=1, .value=204 } },
  { .tag=Communication_Playback_Volume , .ctl={.name="Communications_Volume", .minval=0, .maxval=255, .step=1, .value=204 } },
  { .tag=Warning_Playback_Volume       , .ctl={.name="Warning_Volume", .minval=0, .maxval=255, .step=1, .value=204 } },
  { .tag=System_Playback_Volume        , .ctl={.name="System_Volume", .minval=0, .maxval=255, .step=1, .value=204 } },
  { .tag=Startup_Playback_Volume       , .ctl={.name="Startup_Volume", .minval=0, .maxval=255, .step=1, .value=204 } },
  { .tag=Shutdown_Playback_Volume      , .ctl={.name="Shutdown_Volume", .minval=0, .maxval=255, .step=1, .value=204 } },
  // Could have similar controls for input  side

  { .tag=EndHalCrlTag}  /* marker for end of the array */
} ;


// HAL sound card mapping info
STATIC alsaHalSndCardT alsaHalSndCard  = {
    .name  = "Jabra SOLEMATE v1.34.0", //  WARNING: name MUST match with 'aplay -l'
    .info  = "Hardware Abstraction Layer for Jabra Solamte USB speakers",
    .ctls  = alsaHalMap,
    .volumeCB = NULL, // use default volume normalisation function
};


STATIC int sndServiceInit () {
    int err;
    err = halServiceInit (afbBindingV2.api, &alsaHalSndCard);
    return err;
}

// API prefix should be unique for each snd card
PUBLIC const struct afb_binding_v2 afbBindingV2 = {
    .api     = "jabra-usb",
    .init    = sndServiceInit,
    .verbs   = halServiceApi,
    .onevent = halServiceEvent,
};