~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
JACK/drivers/alsa/hammerfall.c


** Warning: Cannot open xref database.

1 /* 2 Copyright (C) 2001 Paul Davis 3 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. 8 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. 13 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. 17 18 $Id: hammerfall.c,v 1.5 2003/08/29 00:06:30 trutkin Exp $ 19 */ 20 21 #include <jack/hardware.h> 22 #include "alsa_driver.h" 23 #include "hammerfall.h" 24 #include <jack/internal.h> 25 26 /* Set this to 1 if you want this compile error: 27 * warning: `hammerfall_monitor_controls' defined but not used */ 28 #define HAMMERFALL_MONITOR_CONTROLS 0 29 30 static void 31 set_control_id (snd_ctl_elem_id_t *ctl, const char *name) 32 { 33 snd_ctl_elem_id_set_name (ctl, name); 34 snd_ctl_elem_id_set_numid (ctl, 0); 35 snd_ctl_elem_id_set_interface (ctl, SND_CTL_ELEM_IFACE_PCM); 36 snd_ctl_elem_id_set_device (ctl, 0); 37 snd_ctl_elem_id_set_subdevice (ctl, 0); 38 snd_ctl_elem_id_set_index (ctl, 0); 39 } 40 41 #if HAMMERFALL_MONITOR_CONTROLS 42 static void 43 hammerfall_broadcast_channel_status_change (hammerfall_t *h, int lock, int sync, channel_t lowchn, channel_t highchn) 44 45 { 46 channel_t chn; 47 ClockSyncStatus status = 0; 48 49 if (lock) { 50 status |= Lock; 51 } else { 52 status |= NoLock; 53 } 54 55 if (sync) { 56 status |= Sync; 57 } else { 58 status |= NoSync; 59 } 60 61 for (chn = lowchn; chn < highchn; chn++) { 62 alsa_driver_set_clock_sync_status (h->driver, chn, status); 63 } 64 } 65 66 static void 67 hammerfall_check_sync_state (hammerfall_t *h, int val, int adat_id) 68 69 { 70 int lock; 71 int sync; 72 73 /* S/PDIF channel is always locked and synced, but we only 74 need tell people once that this is TRUE. 75 76 XXX - maybe need to make sure that the rate matches our 77 idea of the current rate ? 78 */ 79 80 if (!h->said_that_spdif_is_fine) { 81 ClockSyncStatus status; 82 83 status = Lock|Sync; 84 85 /* XXX broken! fix for hammerfall light ! */ 86 87 alsa_driver_set_clock_sync_status (h->driver, 24, status); 88 alsa_driver_set_clock_sync_status (h->driver, 25, status); 89 90 h->said_that_spdif_is_fine = TRUE; 91 } 92 93 lock = (val & 0x1) ? TRUE : FALSE; 94 sync = (val & 0x2) ? TRUE : FALSE; 95 96 if (h->lock_status[adat_id] != lock || 97 h->sync_status[adat_id] != sync) { 98 hammerfall_broadcast_channel_status_change (h, lock, sync, adat_id*8, (adat_id*8)+8); 99 } 100 101 h->lock_status[adat_id] = lock; 102 h->sync_status[adat_id] = sync; 103 } 104 105 static void 106 hammerfall_check_sync (hammerfall_t *h, snd_ctl_elem_value_t *ctl) 107 108 { 109 const char *name; 110 int val; 111 snd_ctl_elem_id_t *ctl_id; 112 113 printf ("check sync\n"); 114 115 snd_ctl_elem_id_alloca (&ctl_id); 116 snd_ctl_elem_value_get_id (ctl, ctl_id); 117 118 name = snd_ctl_elem_id_get_name (ctl_id); 119 120 if (strcmp (name, "ADAT1 Sync Check") == 0) { 121 val = snd_ctl_elem_value_get_enumerated (ctl, 0); 122 hammerfall_check_sync_state (h, val, 0); 123 } else if (strcmp (name, "ADAT2 Sync Check") == 0) { 124 val = snd_ctl_elem_value_get_enumerated (ctl, 0); 125 hammerfall_check_sync_state (h, val, 1); 126 } else if (strcmp (name, "ADAT3 Sync Check") == 0) { 127 val = snd_ctl_elem_value_get_enumerated (ctl, 0); 128 hammerfall_check_sync_state (h, val, 2); 129 } else { 130 jack_error ("Hammerfall: unknown control \"%s\"", name); 131 } 132 } 133 #endif /* HAMMERFALL_MONITOR_CONTROLS */ 134 135 static int 136 hammerfall_set_input_monitor_mask (jack_hardware_t *hw, unsigned long mask) 137 { 138 hammerfall_t *h = (hammerfall_t *) hw->private; 139 snd_ctl_elem_value_t *ctl; 140 snd_ctl_elem_id_t *ctl_id; 141 int err; 142 int i; 143 144 snd_ctl_elem_value_alloca (&ctl); 145 snd_ctl_elem_id_alloca (&ctl_id); 146 set_control_id (ctl_id, "Channels Thru"); 147 snd_ctl_elem_value_set_id (ctl, ctl_id); 148 149 for (i = 0; i < 26; i++) { 150 snd_ctl_elem_value_set_integer (ctl, i, (mask & (1<<i)) ? 1 : 0); 151 } 152 153 if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) != 0) { 154 jack_error ("ALSA/Hammerfall: cannot set input monitoring (%s)", snd_strerror (err)); 155 return -1; 156 } 157 158 hw->input_monitor_mask = mask; 159 160 return 0; 161 } 162 163 static int 164 hammerfall_change_sample_clock (jack_hardware_t *hw, SampleClockMode mode) 165 { 166 hammerfall_t *h = (hammerfall_t *) hw->private; 167 snd_ctl_elem_value_t *ctl; 168 snd_ctl_elem_id_t *ctl_id; 169 int err; 170 171 snd_ctl_elem_value_alloca (&ctl); 172 snd_ctl_elem_id_alloca (&ctl_id); 173 set_control_id (ctl_id, "Sync Mode"); 174 snd_ctl_elem_value_set_id (ctl, ctl_id); 175 176 switch (mode) { 177 case AutoSync: 178 snd_ctl_elem_value_set_enumerated (ctl, 0, 0); 179 break; 180 case ClockMaster: 181 snd_ctl_elem_value_set_enumerated (ctl, 0, 1); 182 break; 183 case WordClock: 184 snd_ctl_elem_value_set_enumerated (ctl, 0, 2); 185 break; 186 } 187 188 if ((err = snd_ctl_elem_write (h->driver->ctl_handle, ctl)) < 0) { 189 jack_error ("ALSA-Hammerfall: cannot set clock mode"); 190 } 191 192 return 0; 193 } 194 195 static void 196 hammerfall_release (jack_hardware_t *hw) 197 198 { 199 hammerfall_t *h = (hammerfall_t *) hw->private; 200 void *status; 201 202 if (h == 0) { 203 return; 204 } 205 206 pthread_cancel (h->monitor_thread); 207 pthread_join (h->monitor_thread, &status); 208 209 free (h); 210 } 211 212 #if HAMMERFALL_MONITOR_CONTROLS 213 static void * 214 hammerfall_monitor_controls (void *arg) 215 { 216 jack_hardware_t *hw = (jack_hardware_t *) arg; 217 hammerfall_t *h = (hammerfall_t *) hw->private; 218 snd_ctl_elem_id_t *switch_id[3]; 219 snd_ctl_elem_value_t *sw[3]; 220 221 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 222 223 snd_ctl_elem_id_malloc (&switch_id[0]); 224 snd_ctl_elem_id_malloc (&switch_id[1]); 225 snd_ctl_elem_id_malloc (&switch_id[2]); 226 227 snd_ctl_elem_value_malloc (&sw[0]); 228 snd_ctl_elem_value_malloc (&sw[1]); 229 snd_ctl_elem_value_malloc (&sw[2]); 230 231 set_control_id (switch_id[0], "ADAT1 Sync Check"); 232 set_control_id (switch_id[1], "ADAT2 Sync Check"); 233 set_control_id (switch_id[2], "ADAT3 Sync Check"); 234 235 snd_ctl_elem_value_set_id (sw[0], switch_id[0]); 236 snd_ctl_elem_value_set_id (sw[1], switch_id[1]); 237 snd_ctl_elem_value_set_id (sw[2], switch_id[2]); 238 239 while (1) { 240 if (snd_ctl_elem_read (h->driver->ctl_handle, sw[0])) { 241 jack_error ("cannot read control switch 0 ..."); 242 } 243 hammerfall_check_sync (h, sw[0]); 244 245 if (snd_ctl_elem_read (h->driver->ctl_handle, sw[1])) { 246 jack_error ("cannot read control switch 0 ..."); 247 } 248 hammerfall_check_sync (h, sw[1]); 249 250 if (snd_ctl_elem_read (h->driver->ctl_handle, sw[2])) { 251 jack_error ("cannot read control switch 0 ..."); 252 } 253 hammerfall_check_sync (h, sw[2]); 254 255 if (nanosleep (&h->monitor_interval, 0)) { 256 break; 257 } 258 } 259 260 pthread_exit (0); 261 } 262 #endif /* HAMMERFALL_MONITOR_CONTROLS */ 263 264 jack_hardware_t * 265 jack_alsa_hammerfall_hw_new (alsa_driver_t *driver) 266 267 { 268 jack_hardware_t *hw; 269 hammerfall_t *h; 270 271 hw = (jack_hardware_t *) malloc (sizeof (jack_hardware_t)); 272 273 hw->capabilities = Cap_HardwareMonitoring|Cap_AutoSync|Cap_WordClock|Cap_ClockMaster|Cap_ClockLockReporting; 274 hw->input_monitor_mask = 0; 275 hw->private = 0; 276 277 hw->set_input_monitor_mask = hammerfall_set_input_monitor_mask; 278 hw->change_sample_clock = hammerfall_change_sample_clock; 279 hw->release = hammerfall_release; 280 281 h = (hammerfall_t *) malloc (sizeof (hammerfall_t)); 282 283 h->lock_status[0] = FALSE; 284 h->sync_status[0] = FALSE; 285 h->lock_status[1] = FALSE; 286 h->sync_status[1] = FALSE; 287 h->lock_status[2] = FALSE; 288 h->sync_status[2] = FALSE; 289 h->said_that_spdif_is_fine = FALSE; 290 h->driver = driver; 291 292 h->monitor_interval.tv_sec = 1; 293 h->monitor_interval.tv_nsec = 0; 294 295 hw->private = h; 296 297 #if 0 298 if (pthread_create (&h->monitor_thread, 0, hammerfall_monitor_controls, hw)) { 299 jack_error ("ALSA/Hammerfall: cannot create sync monitor thread"); 300 } 301 #endif 302 303 return hw; 304 } 305

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.