2 Copyright (C) 2001 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 $Id: hammerfall.c,v 1.3 2005/09/29 14:51:59 letz Exp $
22 #include "alsa_driver.h"
23 #include "hammerfall.h"
24 #include "JackError.h"
29 /* Set this to 1 if you want this compile error:
30 * warning: `hammerfall_monitor_controls' defined but not used */
31 #define HAMMERFALL_MONITOR_CONTROLS 0
34 set_control_id (snd_ctl_elem_id_t
*ctl
, const char *name
)
36 snd_ctl_elem_id_set_name (ctl
, name
);
37 snd_ctl_elem_id_set_numid (ctl
, 0);
38 snd_ctl_elem_id_set_interface (ctl
, SND_CTL_ELEM_IFACE_MIXER
);
39 snd_ctl_elem_id_set_device (ctl
, 0);
40 snd_ctl_elem_id_set_subdevice (ctl
, 0);
41 snd_ctl_elem_id_set_index (ctl
, 0);
44 #if HAMMERFALL_MONITOR_CONTROLS
46 hammerfall_broadcast_channel_status_change (hammerfall_t
*h
, int lock
, int sync
, channel_t lowchn
, channel_t highchn
)
50 ClockSyncStatus status
= 0;
64 for (chn
= lowchn
; chn
< highchn
; chn
++) {
65 alsa_driver_set_clock_sync_status (h
->driver
, chn
, status
);
70 hammerfall_check_sync_state (hammerfall_t
*h
, int val
, int adat_id
)
76 /* S/PDIF channel is always locked and synced, but we only
77 need tell people once that this is TRUE.
79 XXX - maybe need to make sure that the rate matches our
80 idea of the current rate ?
83 if (!h
->said_that_spdif_is_fine
) {
84 ClockSyncStatus status
;
88 /* XXX broken! fix for hammerfall light ! */
90 alsa_driver_set_clock_sync_status (h
->driver
, 24, status
);
91 alsa_driver_set_clock_sync_status (h
->driver
, 25, status
);
93 h
->said_that_spdif_is_fine
= TRUE
;
96 lock
= (val
& 0x1) ? TRUE
: FALSE
;
97 sync
= (val
& 0x2) ? TRUE
: FALSE
;
99 if (h
->lock_status
[adat_id
] != lock
||
100 h
->sync_status
[adat_id
] != sync
) {
101 hammerfall_broadcast_channel_status_change (h
, lock
, sync
, adat_id
*8, (adat_id
*8)+8);
104 h
->lock_status
[adat_id
] = lock
;
105 h
->sync_status
[adat_id
] = sync
;
109 hammerfall_check_sync (hammerfall_t
*h
, snd_ctl_elem_value_t
*ctl
)
114 snd_ctl_elem_id_t
*ctl_id
;
116 jack_info ("check sync");
118 snd_ctl_elem_id_alloca (&ctl_id
);
119 snd_ctl_elem_value_get_id (ctl
, ctl_id
);
121 name
= snd_ctl_elem_id_get_name (ctl_id
);
123 if (strcmp (name
, "ADAT1 Sync Check") == 0) {
124 val
= snd_ctl_elem_value_get_enumerated (ctl
, 0);
125 hammerfall_check_sync_state (h
, val
, 0);
126 } else if (strcmp (name
, "ADAT2 Sync Check") == 0) {
127 val
= snd_ctl_elem_value_get_enumerated (ctl
, 0);
128 hammerfall_check_sync_state (h
, val
, 1);
129 } else if (strcmp (name
, "ADAT3 Sync Check") == 0) {
130 val
= snd_ctl_elem_value_get_enumerated (ctl
, 0);
131 hammerfall_check_sync_state (h
, val
, 2);
133 jack_error ("Hammerfall: unknown control \"%s\"", name
);
136 #endif /* HAMMERFALL_MONITOR_CONTROLS */
139 hammerfall_set_input_monitor_mask (jack_hardware_t
*hw
, unsigned long mask
)
141 hammerfall_t
*h
= (hammerfall_t
*) hw
->private_hw
;
142 snd_ctl_elem_value_t
*ctl
;
143 snd_ctl_elem_id_t
*ctl_id
;
147 snd_ctl_elem_value_alloca (&ctl
);
148 snd_ctl_elem_id_alloca (&ctl_id
);
149 set_control_id (ctl_id
, "Channels Thru");
150 snd_ctl_elem_value_set_id (ctl
, ctl_id
);
152 for (i
= 0; i
< 26; i
++) {
153 snd_ctl_elem_value_set_integer (ctl
, i
, (mask
& (1<<i
)) ? 1 : 0);
156 if ((err
= snd_ctl_elem_write (h
->driver
->ctl_handle
, ctl
)) != 0) {
157 jack_error ("ALSA/Hammerfall: cannot set input monitoring (%s)", snd_strerror (err
));
161 hw
->input_monitor_mask
= mask
;
167 hammerfall_change_sample_clock (jack_hardware_t
*hw
, SampleClockMode mode
)
169 hammerfall_t
*h
= (hammerfall_t
*) hw
->private_hw
;
170 snd_ctl_elem_value_t
*ctl
;
171 snd_ctl_elem_id_t
*ctl_id
;
174 snd_ctl_elem_value_alloca (&ctl
);
175 snd_ctl_elem_id_alloca (&ctl_id
);
176 set_control_id (ctl_id
, "Sync Mode");
177 snd_ctl_elem_value_set_id (ctl
, ctl_id
);
181 snd_ctl_elem_value_set_enumerated (ctl
, 0, 0);
184 snd_ctl_elem_value_set_enumerated (ctl
, 0, 1);
187 snd_ctl_elem_value_set_enumerated (ctl
, 0, 2);
191 if ((err
= snd_ctl_elem_write (h
->driver
->ctl_handle
, ctl
)) < 0) {
192 jack_error ("ALSA-Hammerfall: cannot set clock mode");
199 hammerfall_release (jack_hardware_t
*hw
)
202 hammerfall_t
*h
= (hammerfall_t
*) hw
->private_hw
;
209 if (h
->monitor_thread
) {
210 pthread_cancel (h
->monitor_thread
);
211 pthread_join (h
->monitor_thread
, &status
);
217 #if HAMMERFALL_MONITOR_CONTROLS
219 hammerfall_monitor_controls (void *arg
)
221 jack_hardware_t
*hw
= (jack_hardware_t
*) arg
;
222 hammerfall_t
*h
= (hammerfall_t
*) hw
->private_hw
;
223 snd_ctl_elem_id_t
*switch_id
[3];
224 snd_ctl_elem_value_t
*sw
[3];
226 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS
, NULL
);
228 snd_ctl_elem_id_malloc (&switch_id
[0]);
229 snd_ctl_elem_id_malloc (&switch_id
[1]);
230 snd_ctl_elem_id_malloc (&switch_id
[2]);
232 snd_ctl_elem_value_malloc (&sw
[0]);
233 snd_ctl_elem_value_malloc (&sw
[1]);
234 snd_ctl_elem_value_malloc (&sw
[2]);
236 set_control_id (switch_id
[0], "ADAT1 Sync Check");
237 set_control_id (switch_id
[1], "ADAT2 Sync Check");
238 set_control_id (switch_id
[2], "ADAT3 Sync Check");
240 snd_ctl_elem_value_set_id (sw
[0], switch_id
[0]);
241 snd_ctl_elem_value_set_id (sw
[1], switch_id
[1]);
242 snd_ctl_elem_value_set_id (sw
[2], switch_id
[2]);
245 if (snd_ctl_elem_read (h
->driver
->ctl_handle
, sw
[0])) {
246 jack_error ("cannot read control switch 0 ...");
248 hammerfall_check_sync (h
, sw
[0]);
250 if (snd_ctl_elem_read (h
->driver
->ctl_handle
, sw
[1])) {
251 jack_error ("cannot read control switch 0 ...");
253 hammerfall_check_sync (h
, sw
[1]);
255 if (snd_ctl_elem_read (h
->driver
->ctl_handle
, sw
[2])) {
256 jack_error ("cannot read control switch 0 ...");
258 hammerfall_check_sync (h
, sw
[2]);
260 if (nanosleep (&h
->monitor_interval
, 0)) {
267 #endif /* HAMMERFALL_MONITOR_CONTROLS */
270 jack_alsa_hammerfall_hw_new (alsa_driver_t
*driver
)
275 hw
= (jack_hardware_t
*) malloc (sizeof (jack_hardware_t
));
277 hw
->capabilities
= Cap_HardwareMonitoring
|Cap_AutoSync
|Cap_WordClock
|Cap_ClockMaster
|Cap_ClockLockReporting
;
278 hw
->input_monitor_mask
= 0;
281 hw
->set_input_monitor_mask
= hammerfall_set_input_monitor_mask
;
282 hw
->change_sample_clock
= hammerfall_change_sample_clock
;
283 hw
->release
= hammerfall_release
;
285 h
= (hammerfall_t
*) malloc (sizeof (hammerfall_t
));
287 h
->lock_status
[0] = FALSE
;
288 h
->sync_status
[0] = FALSE
;
289 h
->lock_status
[1] = FALSE
;
290 h
->sync_status
[1] = FALSE
;
291 h
->lock_status
[2] = FALSE
;
292 h
->sync_status
[2] = FALSE
;
293 h
->said_that_spdif_is_fine
= FALSE
;
296 h
->monitor_interval
.tv_sec
= 1;
297 h
->monitor_interval
.tv_nsec
= 0;
302 if (pthread_create (&h
->monitor_thread
, 0, hammerfall_monitor_controls
, hw
)) {
303 jack_error ("ALSA/Hammerfall: cannot create sync monitor thread");