/* * load the firmware binaries */ static int vx_boot(const char *devname) { snd_hwdep_t *hw; const char *id; int err, is_pcmcia; unsigned int idx, dsps, loaded; snd_hwdep_dsp_status_t *stat; if ((err = snd_hwdep_open(&hw, devname, O_RDWR)) < 0) { error("cannot open hwdep %s\n", devname); return err; } if (check_hwinfo(hw, "VX Loader") < 0) { error("invalid hwdep %s\n", devname); snd_hwdep_close(hw); return -ENODEV; } snd_hwdep_dsp_status_alloca(&stat); /* get the current status */ if ((err = snd_hwdep_dsp_status(hw, stat)) < 0) { error("cannot get version for %s\n", devname); snd_hwdep_close(hw); return err; } if (snd_hwdep_dsp_status_get_chip_ready(stat)) return 0; /* already loaded */ id = snd_hwdep_dsp_status_get_id(stat); if (strcmp(id, "vxpocket") == 0 || strcmp(id, "vxp440") == 0) is_pcmcia = 1; else is_pcmcia = 0; dsps = snd_hwdep_dsp_status_get_num_dsps(stat); loaded = snd_hwdep_dsp_status_get_dsp_loaded(stat); for (idx = 0; idx < dsps; idx++) { if (loaded & (1 << idx)) continue; if ((err = load_firmware(hw, id, idx, is_pcmcia)) < 0) { snd_hwdep_close(hw); return err; } } snd_hwdep_close(hw); return 0; }
static int init(void) { const char* device; snd_hwdep_info_t* info; struct pollfd pollfd; int err; device = drv.device; if (!device || !*device) { device = search_device(); if (!device) { logprintf(LIRC_ERROR, "device not found"); return 0; } } err = snd_hwdep_open(&hwdep, device, SND_HWDEP_OPEN_READ); if (err < 0) { logprintf(LIRC_ERROR, "cannot open %s: %s", device, snd_strerror(err)); return 0; } snd_hwdep_info_alloca(&info); err = snd_hwdep_info(hwdep, info); if (err < 0) { snd_hwdep_close(hwdep); logprintf(LIRC_ERROR, "cannot get hwdep info: %s", snd_strerror(err)); return 0; } if (snd_hwdep_info_get_iface(info) != SND_HWDEP_IFACE_SB_RC) { snd_hwdep_close(hwdep); logprintf(LIRC_ERROR, "%s is not a Sound Blaster remote control device", device); return 0; } err = snd_hwdep_poll_descriptors(hwdep, &pollfd, 1); if (err < 0) { snd_hwdep_close(hwdep); logprintf(LIRC_ERROR, "cannot get file descriptor: %s", snd_strerror(err)); return 0; } if (err != 1) { snd_hwdep_close(hwdep); logprintf(LIRC_ERROR, "invalid number of file descriptors (%d): %s", err, snd_strerror(err)); return 0; } drv.fd = pollfd.fd; return 1; }
int main(int argc, char *argv[]) { int dev; int card; struct sigaction sa; #ifdef TEST int rlen; #endif int bt_dev = 0; struct pollfd pfds[16]; int err; char hwdep_name[16]; struct s_headset *akt_headset; atexit(cleanup); /* detect the audio device */ if (find_hwdep_device(&card, &dev)) { perror("Can't find device. Bail"); return 1; } printf("Device is %d:%d\n", card, dev); sprintf(hwdep_name, "hw:%i,%i", card, dev); if (check_bt_voice(bt_dev) < 0) return -1; /* find bdaddr */ switch (argc) { case 2: akt_headset = headset_new(); hci_devba(bt_dev, &akt_headset->local); str2ba(argv[1], &akt_headset->bdaddr); akt_headset->channel = detect_channel(&akt_headset->bdaddr); /* open hwdep on audio device */ if ((err = snd_hwdep_open(&akt_headset->handle, hwdep_name, O_RDWR)) < 0) { fprintf(stderr, "btsco open (%i-%i): %s\n", card, dev, snd_strerror(err)); return -1; } break; case 3: akt_headset = headset_new(); hci_devba(bt_dev, &akt_headset->local); str2ba(argv[1], &akt_headset->bdaddr); akt_headset->channel = atoi(argv[2]); /* open hwdep on audio device */ if ((err = snd_hwdep_open(&akt_headset->handle, hwdep_name, O_RDWR)) < 0) { fprintf(stderr, "btsco open (%i-%i): %s\n", card, dev, snd_strerror(err)); return -1; } break; default: usage(); exit(-1); } /* setup sigterm handler. we must make sure to do a clean disconnect */ memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP; sa.sa_handler = sig_term; sigaction(SIGTERM, &sa, NULL); sigaction(SIGINT, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction(SIGCHLD, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); /* we are not yet connected */ while (!terminate) { unsigned short revents; int nfds; nfds = 0; /* set up data polling description */ for (akt_headset = first; akt_headset != NULL; akt_headset = akt_headset->next) { if (akt_headset->rfcomm_fd == -1) { /* connect rfcomm control channel */ if ((akt_headset->rfcomm_fd = rfcomm_connect( &akt_headset->local, &akt_headset->bdaddr, akt_headset->channel)) < 0) fprintf(stderr, "Can't connect RFCOMM channel"); else fprintf(stderr, "RFCOMM channel %i connected\n", akt_headset->channel); } if (akt_headset->rfcomm_fd != -1) { pfds[nfds].fd = akt_headset->rfcomm_fd; pfds[nfds++].events = POLLIN; } if (akt_headset->handle != NULL) { /* polling data from hwdep interface */ nfds += snd_hwdep_poll_descriptors(akt_headset->handle, &pfds[nfds], 1); } } /*printf("outer loop\n"); */ if (nfds == 0) { sleep(3); continue; } if (poll(pfds, nfds, 1000) <= 0) continue; for (akt_headset = first; akt_headset != NULL; akt_headset = akt_headset->next) { int j; for (j = 0; j < nfds; j++) { if (pfds[j].fd == akt_headset->rfcomm_fd) { if (pfds[j].revents & POLLIN) headset_from_bt(akt_headset); continue; } #ifdef TEST if (pfds[j].fd == akt_headset->sco_fd) { /* Just for testing; handled by kernel driver */ fd_set rfds; if (0 && FD_ISSET(akt_headset->sco_fd, &rfds)) { int i; unsigned char buf[2048]; memset(buf, 0, sizeof(buf)); rlen = read(akt_headset->sco_fd, buf, sizeof(buf)); write(akt_headset->sco_fd, buf, rlen); i++; if (i % 15 == 0) printf("rlen: %d\n", rlen); } continue; } #endif /* Volume polling (sound card) */ if (!snd_hwdep_poll_descriptors_revents (akt_headset->handle, &pfds[j], 1, &revents) && revents & POLLIN) headset_volume_fromcard (akt_headset); } } } return 0; }