예제 #1
0
파일: mixer.c 프로젝트: bsdplus/fluxbsd
void scan_mixer_bar(struct text_object *obj, const char *arg)
{
	char buf1[64];
	int n;

	if (arg && sscanf(arg, "%63s %n", buf1, &n) >= 1) {
		obj->data.i = mixer_init(buf1);
		scan_bar(obj, arg + n);
	} else {
		obj->data.i = mixer_init(NULL);
		scan_bar(obj, arg);
	}
}
예제 #2
0
파일: i2s.c 프로젝트: edgar-pek/PerspicuOS
static void
i2s_postattach(void *xsc)
{
	struct i2s_softc 	*sc = xsc;
	device_t 		 self;
	int 			 i;

	self = sc->aoa.sc_dev;

	/* Reset the codec. */
	i2s_audio_hw_reset(sc);

	/* If we have a codec, initialize it. */
	if (i2s_mixer)
		mixer_init(self, i2s_mixer_class, i2s_mixer);

	/* Read initial port status. */
	i2s_cint(sc);

	/* Enable GPIO interrupt callback. */	
	for (i = 0; i < GPIO_CTRL_NUM; i++)
		if (gpio_ctrls[i])
			gpio_ctrls[i]->i2s = sc;

	config_intrhook_disestablish(i2s_delayed_attach);
	free(i2s_delayed_attach, M_TEMP);
}
예제 #3
0
static void sound_init()
{
   if (mixer_id>0) mixer_fini(mixer_id);
   if (audio_src_list) g_list_free(audio_src_list);
   mixer_id = mixer_init (mixer_dev);
   if (mixer_id<=0)
   {
      g_print("**ERROR: opening mixer device (%s): %s\n",
         mixer_dev, strerror(errno));
   }
   else
   {
      int i; 
      int num_devs = mixer_num_of_devs (mixer_id);
      for (i=0;i<num_devs;i++)
      {
         audio_src_list = g_list_append(audio_src_list,
            (gpointer) mixer_get_label(mixer_id, i));
         if (i==audio_src)
         {
            volume = mixer_get_vol_left(mixer_id, i);
            gtk_timeout_add(100, (GtkFunction) get_volume, NULL);
         }
      }
   }
}
예제 #4
0
GtkWidget *create_audio_sliders()
{
	GtkWidget *vbox, *scrollbar, *label, *pixmap_w;
	GtkObject *adj;
	GtkTooltips *tooltip;
	int no_of_devs, i = -1, value;

	tooltip = gtk_tooltips_new();
	vbox = gtk_vbox_new (FALSE, 0);

	mixer_id = mixer_init (getenv("LAV_MIXER_DEV"));
	if (mixer_id > 0)
	{
		no_of_devs = mixer_num_of_devs (mixer_id);
		for (i = 0; i < no_of_devs; i++)
		{
			if (strcmp(mixer_get_label(mixer_id, i), "Line ") == 0 && audio_recsrc == 'l')
			{
				break;
			}
			else if (strcmp(mixer_get_label(mixer_id, i), "Mic  ") == 0 && audio_recsrc == 'm')
			{
				break;
			}
			else if (strcmp(mixer_get_label(mixer_id, i), "CD   ") == 0 && audio_recsrc == 'c')
			{
				break;
			}
		}
	}

	value = 100 - mixer_get_vol_left(mixer_id, i);

	label = gtk_label_new("\n");
	gtk_box_pack_start(GTK_BOX (vbox), label, FALSE, FALSE, 0);
	gtk_widget_show (label);

	adj = gtk_adjustment_new(value, 0, 100, 1, 10, 0);
	gtk_signal_connect(adj, "value_changed", GTK_SIGNAL_FUNC(audio_slider_changed), NULL);
	scrollbar = gtk_vscale_new(GTK_ADJUSTMENT (adj));
	gtk_scale_set_draw_value(GTK_SCALE(scrollbar), 0);
	gtk_box_pack_start(GTK_BOX (vbox), scrollbar, TRUE, TRUE, 0);
	gtk_widget_show(scrollbar);

	gtk_tooltips_set_tip(tooltip, scrollbar, "Volume", NULL);
	pixmap_w = gtk_widget_from_xpm_data(slider_volume_xpm);
	gtk_widget_show(pixmap_w);
	gtk_box_pack_start(GTK_BOX(vbox), pixmap_w, FALSE, FALSE, 0);

	label = gtk_label_new("\n");
	gtk_box_pack_start(GTK_BOX (vbox), label, FALSE, FALSE, 0);
	gtk_widget_show (label);

	return vbox;
}
예제 #5
0
int main(int argc, char *argv[])
{
    enum { SC = 3 };
    int opt, n;
    int sigs[] = { SIGINT, SIGHUP, SIGTERM };
    void (*sighandlers[])() = { sigint_handler,
                                sighup_handler,
                                sigterm_handler };
    struct sigaction s[SC];

    for (n = 0; n < SC; ++n)
    {
        s[n].sa_handler = SIG_IGN;
        sigfillset(&s[n].sa_mask);
        s[n].sa_flags = 0;
        sigaction(sigs[n], &s[n], NULL);
    }

    for (opt = 1; opt < argc; ++opt)
    {
        if (strcmp(argv[opt], "-h") == 0
         || strcmp(argv[opt], "--help") == 0)
        {
            show_usage();
            return 0;
        }
    }

    mod_src_create();
    gtk_init(&argc, &argv);
    settings_init();
    driver_init();
    lfo_tables_init();
    mixer_init();
    patch_control_init();
    dish_file_state_init();
    session_init(argc, argv);
    gui_init();

    for (n = 0; n < SC; ++n)
    {
        s[n].sa_handler = sighandlers[n];
        sigfillset(&s[n].sa_mask);
        s[n].sa_flags = 0;
        sigaction(sigs[n], &s[n], NULL);
    }

    gtk_main();

    cleanup();

    return 0;
}
예제 #6
0
파일: uaudio_pcm.c 프로젝트: MarginC/kame
static int
ua_attach(device_t dev)
{
	struct ua_info *ua;
	char status[SND_STATUSLEN];
	unsigned int bufsz;

	ua = (struct ua_info *)malloc(sizeof *ua, M_DEVBUF, M_NOWAIT);
	if (!ua)
		return ENXIO;
	bzero(ua, sizeof *ua);

	ua->sc_dev = dev;

	bufsz = pcm_getbuffersize(dev, 4096, UAUDIO_PCM_BUFF_SIZE, 65536);

	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
				/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
				/*highaddr*/BUS_SPACE_MAXADDR,
				/*filter*/NULL, /*filterarg*/NULL,
				/*maxsize*/bufsz, /*nsegments*/1,
				/*maxsegz*/0x3fff, /*flags*/0,
				&ua->parent_dmat) != 0) {
		device_printf(dev, "unable to create dma tag\n");
		goto bad;
	}

	if (mixer_init(dev, &ua_mixer_class, ua)) {
		return(ENXIO);
	}

	snprintf(status, SND_STATUSLEN, "at addr ?");

	if (pcm_register(dev, ua, 1, 0)) {
		return(ENXIO);
	}

	pcm_addchan(dev, PCMDIR_PLAY, &ua_chan_class, ua);
#ifndef NO_RECORDING
	pcm_addchan(dev, PCMDIR_REC, &ua_chan_class, ua);
#endif
	pcm_setstatus(dev, status);

	return 0;
bad:
	if (ua->parent_dmat)
		bus_dma_tag_destroy(ua->parent_dmat);
	free(ua, M_DEVBUF);

	return ENXIO;
}
예제 #7
0
static struct mixer *
alsa_mixer_init(G_GNUC_UNUSED void *ao, const struct config_param *param,
		G_GNUC_UNUSED GError **error_r)
{
	struct alsa_mixer *am = g_new(struct alsa_mixer, 1);

	mixer_init(&am->base, &alsa_mixer_plugin);

	am->device = config_get_block_string(param, "mixer_device",
					     VOLUME_MIXER_ALSA_DEFAULT);
	am->control = config_get_block_string(param, "mixer_control",
					      VOLUME_MIXER_ALSA_CONTROL_DEFAULT);
	am->index = config_get_block_unsigned(param, "mixer_index",
					      VOLUME_MIXER_ALSA_INDEX_DEFAULT);

	return &am->base;
}
예제 #8
0
int alsa_init(audiodevice_t *dev, char *devname, boolean automix) {
	audio_alsa09_t *alsa;
	
	alsa = g_new0(audio_alsa09_t, 1);
	alsa->dev = devname;
	dev->data_pcm = alsa;
	
	mixer_init(dev);
	
	dev->id      = AUDIO_PCM_ALSA09;
	dev->fd      = -1;
	dev->open    = audio_open;
	dev->close   = audio_close;
	dev->write   = audio_write;
	dev->mix_set = mixer_set_level;
	dev->mix_get = mixer_get_level;
	dev->exit    = alsa_exit;
	
	NOTICE("ALSA Initilize OK\n");
	return OK;
}
예제 #9
0
int sunaudio_init(audiodevice_t *dev, char *devaudio, char *devaudioctl) {
	audio_sun_t *asun;

	asun = g_new0(audio_sun_t, 1);
	
	asun->fd = -1;
	asun->dev = (devaudio == NULL ? "/dev/audio" : devaudio);
	mixer_init(dev, devaudioctl);
	
	dev->data_pcm = asun;
	dev->id = AUDIO_PCM_SUN;
	dev->fd = -1;
	dev->open = audio_open;
	dev->close = audio_close;
	dev->write = audio_write;
	dev->mix_set = mixer_set_level;
	dev->mix_get = mixer_get_level;
	dev->exit = sunaudio_exit;
	
	NOTICE("SUN audio Initilize OK\n");
	
	return OK;
}
예제 #10
0
static void
bcm2835_audio_delayed_init(void *xsc)
{
    	struct bcm2835_audio_info *sc;
    	char status[SND_STATUSLEN];

	sc = xsc;

	config_intrhook_disestablish(&sc->intr_hook);

	bcm2835_audio_init(sc);
	bcm2835_audio_open(sc);
	sc->volume = 75;
	sc->dest = DEST_AUTO;

    	if (mixer_init(sc->dev, &bcmmixer_class, sc)) {
		device_printf(sc->dev, "mixer_init failed\n");
		goto no;
	}

    	if (pcm_register(sc->dev, sc, 1, 1)) {
		device_printf(sc->dev, "pcm_register failed\n");
		goto no;
	}

	pcm_addchan(sc->dev, PCMDIR_PLAY, &bcmchan_class, sc);
    	snprintf(status, SND_STATUSLEN, "at VCHIQ");
	pcm_setstatus(sc->dev, status);

	bcm2835_audio_reset_channel(&sc->pch);
	bcm2835_audio_create_worker(sc);

	vchi_audio_sysctl_init(sc);

no:
	;
}
예제 #11
0
static int
nm_pci_attach(device_t dev)
{
	snddev_info    *d;
	u_int32_t	data;
	struct sc_info *sc;
	struct ac97_info *codec;
	char 		status[SND_STATUSLEN];

	d = device_get_softc(dev);
	if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
		device_printf(dev, "cannot allocate softc\n");
		return ENXIO;
	}

	bzero(sc, sizeof(*sc));
	sc->dev = dev;
	sc->type = pci_get_devid(dev);

	data = pci_read_config(dev, PCIR_COMMAND, 2);
	data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
	pci_write_config(dev, PCIR_COMMAND, data, 2);
	data = pci_read_config(dev, PCIR_COMMAND, 2);

	sc->bufid = PCIR_MAPS;
	sc->buf = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bufid,
				     0, ~0, 1, RF_ACTIVE);
	sc->regid = PCIR_MAPS + 4;
	sc->reg = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->regid,
				     0, ~0, 1, RF_ACTIVE);

	if (!sc->buf || !sc->reg) {
		device_printf(dev, "unable to map register space\n");
		goto bad;
	}

	if (nm_init(sc) == -1) {
		device_printf(dev, "unable to initialize the card\n");
		goto bad;
	}

	codec = ac97_create(dev, sc, nm_rdcd, nm_wrcd);
	if (codec == NULL) goto bad;
	mixer_init(d, &ac97_mixer, codec);

	sc->irqid = 0;
	sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid,
				 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
	if (!sc->irq ||
	    bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, nm_intr, sc, &sc->ih)) {
		device_printf(dev, "unable to map interrupt\n");
		goto bad;
	}

	snprintf(status, SND_STATUSLEN, "at memory 0x%lx, 0x%lx irq %ld",
		 rman_get_start(sc->buf), rman_get_start(sc->reg),
		 rman_get_start(sc->irq));

	if (pcm_register(dev, sc, 1, 1)) goto bad;
	pcm_addchan(dev, PCMDIR_REC, &nm_chantemplate, sc);
	pcm_addchan(dev, PCMDIR_PLAY, &nm_chantemplate, sc);
	pcm_setstatus(dev, status);

	return 0;

bad:
	if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf);
	if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
	if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih);
	if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
	free(sc, M_DEVBUF);
	return ENXIO;
}
예제 #12
0
파일: wmix.c 프로젝트: bbidulock/dockapps
int main(int argc, char **argv)
{
    XEvent event;

    config_init();
    parse_cli_options(argc, argv);
    config_read();

    mixer_init(config.mixer_device, config.verbose, (const char **)config.exclude_channel);
    mixer_set_channel(0);

    display = XOpenDisplay(config.display_name);
    if (display == NULL) {
	const char *name;

	if (config.display_name) {
	    name = config.display_name;
	} else {
	    name = getenv("DISPLAY");
	    if (name == NULL) {
		fprintf(stderr, "wmix:error: Unable to open display, variable $DISPLAY not set\n");
		return EXIT_FAILURE;
	    }
	}
	fprintf(stderr, "wmix:error: Unable to open display \"%s\"\n", name);
	return EXIT_FAILURE;
    }
    display_width = (float)DisplayWidth(display, DefaultScreen(display)) / 4.0;
    display_height = (float)DisplayHeight(display, DefaultScreen(display)) / 2.0;

    dockapp_init(display);
    new_window("wmix", 64, 64);
    new_osd(DisplayWidth(display, DefaultScreen(display)) - 200, 60);

    if (config.mmkeys)
	    mmkey_install(display);

    config_release();

    blit_string("wmix " VERSION);
    scroll_text(3, 4, 57, true);
    ui_update();

    /* add click regions */
    add_region(1, 37, 36, 25, 25);	/* knob */
    add_region(2, 4, 42, 27, 15);	/* balancer */
    add_region(3, 2, 26, 7, 10);	/* previous channel */
    add_region(4, 10, 26, 7, 10);	/* next channel */
    add_region(5, 39, 14, 20, 7);	/* mute toggle */
    add_region(6, 4, 14, 13, 7);	/* rec toggle */
    add_region(10, 3, 4, 56, 7);	/* re-scroll current channel name */

    /* setup up/down signal handler */
    create_pid_file();
    signal(SIGUSR1, (void *) signal_catch);
    signal(SIGUSR2, (void *) signal_catch);

    while (true) {
	if (button_pressed || slider_pressed || (XPending(display) > 0)) {
	    XNextEvent(display, &event);
	    switch (event.type) {
		case KeyPress:
		    if (key_press_event(&event.xkey))
			idle_loop = 0;
		    break;
		case Expose:
		    redraw_window();
		    break;
		case ButtonPress:
		    button_press_event(&event.xbutton);
		    idle_loop = 0;
		    break;
		case ButtonRelease:
		    button_release_event(&event.xbutton);
		    idle_loop = 0;
		    break;
		case MotionNotify:
		    /* process cursor change, or drag events */
		    motion_event(&event.xmotion);
		    idle_loop = 0;
		    break;
		case LeaveNotify:
		    /* go back to standard cursor */
		    if ((!button_pressed) && (!slider_pressed))
			set_cursor(NORMAL_CURSOR);
		    break;
		case DestroyNotify:
		    XCloseDisplay(display);
		    return EXIT_SUCCESS;
		default:
		    break;
	    }
	} else {
	    usleep(100000);
	    scroll_text(3, 4, 57, false);
	    /* rescroll message after some delay */
	    if (idle_loop++ > 256) {
		scroll_text(3, 4, 57, true);
		idle_loop = 0;
	    }
	    /* get rid of OSD after a few seconds of idle */
	    if ((idle_loop > 15) && osd_mapped() && !button_pressed) {
		unmap_osd();
		idle_loop = 0;
	    }
	    if (mixer_is_changed())
		ui_update();
	}
    }
    return EXIT_SUCCESS;
}
예제 #13
0
static int
cs4281_pci_attach(device_t dev)
{
    struct sc_info *sc;
    struct ac97_info *codec = NULL;
    u_int32_t data;
    char status[SND_STATUSLEN];

    if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
	device_printf(dev, "cannot allocate softc\n");
	return ENXIO;
    }

    bzero(sc, sizeof(*sc));
    sc->dev = dev;
    sc->type = pci_get_devid(dev);

    data = pci_read_config(dev, PCIR_COMMAND, 2);
    data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN);
    pci_write_config(dev, PCIR_COMMAND, data, 2);

    data = pci_read_config(dev, PCIR_COMMAND, 2);

#if __FreeBSD_version > 500000
    if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
	/* Reset the power state. */
	device_printf(dev, "chip is in D%d power mode "
		      "-- setting to D0\n", pci_get_powerstate(dev));

	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
    }
#endif
    sc->regid   = PCIR_MAPS;
    sc->regtype = SYS_RES_MEMORY;
    sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid,
				 0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE);
    if (!sc->reg) {
	sc->regtype = SYS_RES_IOPORT;
	sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid,
				     0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE);
	if (!sc->reg) {
	    device_printf(dev, "unable to allocate register space\n");
	    goto bad;
	}
    }
    sc->st = rman_get_bustag(sc->reg);
    sc->sh = rman_get_bushandle(sc->reg);

    sc->memid = PCIR_MAPS + 4;
    sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->memid, 0,
				 ~0, CS4281PCI_BA1_SIZE, RF_ACTIVE);
    if (sc->mem == NULL) {
	device_printf(dev, "unable to allocate fifo space\n");
	goto bad;
    }

    sc->irqid = 0;
    sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid,
				 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
    if (!sc->irq) {
	device_printf(dev, "unable to allocate interrupt\n");
	goto bad;
    }

    if (bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, cs4281_intr, sc, &sc->ih)) {
	device_printf(dev, "unable to setup interrupt\n");
	goto bad;
    }

    if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
			   /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
			   /*highaddr*/BUS_SPACE_MAXADDR,
			   /*filter*/NULL, /*filterarg*/NULL,
			   /*maxsize*/CS4281_BUFFER_SIZE, /*nsegments*/1,
			   /*maxsegz*/0x3ffff,
			   /*flags*/0, &sc->parent_dmat) != 0) {
	device_printf(dev, "unable to create dma tag\n");
	goto bad;
    }

    /* power up */
    cs4281_power(sc, 0);

    /* init chip */
    if (cs4281_init(sc) == -1) {
	device_printf(dev, "unable to initialize the card\n");
	goto bad;
    }

    /* create/init mixer */
    codec = AC97_CREATE(dev, sc, cs4281_ac97);
    if (codec == NULL)
        goto bad;

    mixer_init(dev, ac97_getmixerclass(), codec);

    if (pcm_register(dev, sc, 1, 1))
	goto bad;

    pcm_addchan(dev, PCMDIR_PLAY, &cs4281chan_class, sc);
    pcm_addchan(dev, PCMDIR_REC, &cs4281chan_class, sc);

    snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld",
	     (sc->regtype == SYS_RES_IOPORT)? "io" : "memory",
	     rman_get_start(sc->reg), rman_get_start(sc->irq));
    pcm_setstatus(dev, status);

    return 0;

 bad:
    if (codec)
	ac97_destroy(codec);
    if (sc->reg)
	bus_release_resource(dev, sc->regtype, sc->regid, sc->reg);
    if (sc->mem)
	bus_release_resource(dev, SYS_RES_MEMORY, sc->memid, sc->mem);
    if (sc->ih)
	bus_teardown_intr(dev, sc->irq, sc->ih);
    if (sc->irq)
	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
    if (sc->parent_dmat)
	bus_dma_tag_destroy(sc->parent_dmat);
    free(sc, M_DEVBUF);

    return ENXIO;
}
예제 #14
0
int os_main(int argc, char* argv[])
{
	int keyboard_id;
	adv_conf* context;
	const char* s;
        char* section_map[1];
	const char** file_map;
	unsigned file_mac;
	int i;
	double latency_time;
	double buffer_time;
	double volume;
	unsigned rate;
	int attenuation;
	adv_bool opt_log;
	adv_bool opt_logsync;

	opt_log = 0;
	opt_logsync = 0;
	file_map = 0;
	file_mac = 0;

	context = conf_init();

	if (os_init(context) != 0)
		goto err_conf;

	mixer_reg(context);

	conf_int_register_limit_default(context, "sound_volume", -32, 0, 0);
	conf_int_register_limit_default(context, "sound_samplerate", 5000, 96000, 44100);
	conf_float_register_limit_default(context, "sound_latency", 0.01, 2.0, 0.1);
	conf_float_register_limit_default(context, "sound_buffer", 0.05, 2.0, 0.1);

	if (conf_input_args_load(context, 0, "", &argc, argv, error_callback, 0) != 0)
		goto err_os;

	file_map = malloc(argc * sizeof(const char*));

	for(i=1;i<argc;++i) {
		if (target_option_compare(argv[i], "log")) {
			opt_log = 1;
		} else if (target_option_compare(argv[i], "logsync")) {
			opt_logsync = 1;
		} else if (target_option_extract(argv[i]) == 0) {
			file_map[file_mac++] = argv[i];
		} else {
			target_err("Unknown command line option '%s'.\n", argv[i]);
			goto err_os;
		}
	}

	if (argc <= 1 || file_mac == 0) {
		target_err("Syntax: advs FILES...\n");
		goto err_os;
	}

	if (opt_log || opt_logsync) {
		const char* log = "advs.log";
		remove(log);
		log_init(log, opt_logsync);
        }

	section_map[0] = "";
	conf_section_set(context, section_map, 1);

	if (mixer_load(context) != 0) {
		goto err_os;
	}

	attenuation = conf_int_get_default(context, "sound_volume");
	latency_time = conf_float_get_default(context, "sound_latency");
	buffer_time = conf_float_get_default(context, "sound_buffer");
	rate = conf_int_get_default(context, "sound_samplerate");
	volume = 1.0;
	while (attenuation++ < 0)
		volume /= 1.122018454; /* = (10 ^ (1/20)) = 1dB */

	if (os_inner_init("AdvanceSOUND") != 0)
		goto err_os;

	if (file_mac > MIXER_CHANNEL_MAX) {
		target_err("Too many files\n");
		goto err_os_inner;
	}

	if (mixer_init(rate, file_mac, 1, buffer_time + latency_time, latency_time) != 0) {
		target_err("%s\n", error_get());
		goto err_os_inner;
	}

	mixer_volume(volume);

	for(i=0;i<file_mac;++i)
		run(i, file_map[i]);

	free(file_map);

	signal(SIGINT, sigint);

	while (!done) {
		for(i=0;i<file_mac;++i)
			if (mixer_is_playing(i))
				break;
		if (i==file_mac)
			break;

		mixer_poll();
		target_idle();
	}

	log_std(("s: shutdown\n"));

	mixer_done();

	os_inner_done();

	log_std(("s: the end\n"));

	if (opt_log || opt_logsync) {
		log_done();
	}

	os_done();
	conf_done(context);

	return EXIT_SUCCESS;

err_os_inner:
	os_inner_done();
	log_done();
err_os:
	os_done();
err_conf:
	conf_done(context);
err:
	return EXIT_FAILURE;

}
예제 #15
0
파일: mixer.c 프로젝트: pzanoni/tray
int main(int argc, char **argv)
{
	int o;
	char *name = "Master";
	char *iname = "Capture";
	int showinput = 0;

	bindtextdomain("tray_mixer", LOCALE_DIR);
	textdomain("tray_mixer");

	while ((o = getopt(argc, argv, "e:Ii:")) >= 0) {
		switch (o) {
		case 'e':
			name = optarg;
			break;
		case 'i':
			iname = optarg;
			/* fall through */
		case 'I':
			showinput = 1;
			break;
		}
	}

	gtk_init(&argc, &argv);

	mixer_init(name, iname);

	icon = gtk_status_icon_new_from_file(ICON_PATH "speaker.png");
	g_signal_connect(G_OBJECT(icon), "activate", G_CALLBACK(click), NULL);

	item = gtk_menu_item_new_with_label(_("Quit"));
	menu = gtk_menu_new();
	gtk_widget_show(item);
	gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);

	g_signal_connect(G_OBJECT(icon), "popup-menu", G_CALLBACK(popup), NULL);
	g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(quit), NULL);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
	gtk_container_set_border_width(GTK_CONTAINER(window), 10);
	gtk_window_set_skip_taskbar_hint(GTK_WINDOW(window), TRUE);
	gtk_window_set_skip_pager_hint(GTK_WINDOW(window), TRUE);
	gtk_window_set_type_hint(GTK_WINDOW(window),
					GDK_WINDOW_TYPE_HINT_DIALOG);
	gtk_window_set_default_size(GTK_WINDOW(window), 60, 140);

	hbox = gtk_hbox_new(TRUE, 5);
	gtk_container_add(GTK_CONTAINER(window), hbox);

	add_channel(&ch[0]);

	if (showinput)
		add_channel(&ch[1]);

	gtk_status_icon_set_visible(GTK_STATUS_ICON(icon), TRUE);

	gtk_main();

	return 0;
}
예제 #16
0
/* Driver initialization routine */
static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
{
	struct emu10k1_card *card;

	if ((card = kmalloc(sizeof(struct emu10k1_card), GFP_KERNEL)) == NULL) {
		printk(KERN_ERR "emu10k1: out of memory\n");
		return -ENOMEM;
	}
	memset(card, 0, sizeof(struct emu10k1_card));

#if LINUX_VERSION_CODE > 0x020320
	if (!pci_dma_supported(pci_dev, EMU10K1_DMA_MASK)) {
		printk(KERN_ERR "emu10k1: architecture does not support 32bit PCI busmaster DMA\n");
		kfree(card);
		return -ENODEV;
	}

	if (pci_enable_device(pci_dev)) {
		printk(KERN_ERR "emu10k1: couldn't enable device\n");
		kfree(card);
		return -ENODEV;
	}

	pci_set_master(pci_dev);

	card->iobase = pci_dev->resource[0].start;

	if (request_region(card->iobase, EMU10K1_EXTENT, card_names[pci_id->driver_data]) == NULL) {
		printk(KERN_ERR "emu10k1: IO space in use\n");
		kfree(card);
		return -ENODEV;
	}
	pci_dev->driver_data = card;
	pci_dev->dma_mask = EMU10K1_DMA_MASK;
#else
	pci_set_master(pci_dev);

	card->iobase = pci_dev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;

	if (check_region(card->iobase, EMU10K1_EXTENT)) {
		printk(KERN_ERR "emu10k1: IO space in use\n");
		kfree(card);
		return -ENODEV;
	}

	request_region(card->iobase, EMU10K1_EXTENT, card_names[pci_id->driver_data]);
#endif
	card->irq = pci_dev->irq;
	card->pci_dev = pci_dev;

	/* Reserve IRQ Line */
	if (request_irq(card->irq, emu10k1_interrupt, SA_SHIRQ, card_names[pci_id->driver_data], card)) {
		printk(KERN_ERR "emu10k1: IRQ in use\n");
		goto err_irq;
	}

	pci_read_config_byte(pci_dev, PCI_REVISION_ID, &card->chiprev);

	printk(KERN_INFO "emu10k1: %s rev %d found at IO 0x%04lx, IRQ %d\n", card_names[pci_id->driver_data], card->chiprev, card->iobase, card->irq);

	spin_lock_init(&card->lock);
	card->mixeraddx = card->iobase + AC97DATA;
	init_MUTEX(&card->open_sem);
	card->open_mode = 0;
	init_waitqueue_head(&card->open_wait);

	/* Register devices */
	if ((card->audio1_num = register_sound_dsp(&emu10k1_audio_fops, -1)) < 0) {
		printk(KERN_ERR "emu10k1: cannot register first audio device!\n");
		goto err_dev0;
	}

	if ((card->audio2_num = register_sound_dsp(&emu10k1_audio_fops, -1)) < 0) {
		printk(KERN_ERR "emu10k1: cannot register second audio device!\n");
		goto err_dev1;
	}

	if ((card->mixer_num = register_sound_mixer(&emu10k1_mixer_fops, -1)) < 0) {
		printk(KERN_ERR "emu10k1: cannot register mixer device!\n");
		goto err_dev2;
	}

	if ((card->midi_num = register_sound_midi(&emu10k1_midi_fops, -1)) < 0) {
		printk(KERN_ERR "emu10k1: cannot register midi device!\n");
		goto err_dev3;
	}

	if (emu10k1_init(card) != CTSTATUS_SUCCESS) {
		printk(KERN_ERR "emu10k1: cannot initialize device!\n");
		goto err_emu10k1_init;
	}

	if (audio_init(card) != CTSTATUS_SUCCESS) {
		printk(KERN_ERR "emu10k1: cannot initialize audio!\n");
		goto err_audio_init;
	}

	if (midi_init(card) != CTSTATUS_SUCCESS) {
		printk(KERN_ERR "emu10k1: cannot initialize midi!\n");
		goto err_midi_init;
	}

	mixer_init(card);

	DPD(2, "Hardware initialized. TRAM allocated: %u bytes\n", (unsigned int) card->tmemsize);

	list_add(&card->list, &emu10k1_devs);

	return 0;

      err_midi_init:
	audio_exit(card);

      err_audio_init:
	emu10k1_exit(card);

      err_emu10k1_init:
	unregister_sound_midi(card->midi_num);

      err_dev3:
	unregister_sound_mixer(card->mixer_num);

      err_dev2:
	unregister_sound_dsp(card->audio2_num);

      err_dev1:
	unregister_sound_dsp(card->audio1_num);

      err_dev0:
	free_irq(card->irq, card);

      err_irq:
	release_region(card->iobase, EMU10K1_EXTENT);
	kfree(card);

	return -ENODEV;
}
예제 #17
0
파일: neomagic.c 프로젝트: JabirTech/Source
static int
nm_pci_attach(device_t dev)
{
	struct sc_info *sc;
	struct ac97_info *codec = 0;
	char 		status[SND_STATUSLEN];

	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
	sc->dev = dev;
	sc->type = pci_get_devid(dev);

	pci_enable_busmaster(dev);

	sc->bufid = PCIR_BAR(0);
	sc->buf = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->bufid,
					 RF_ACTIVE);
	sc->regid = PCIR_BAR(1);
	sc->reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->regid,
					 RF_ACTIVE);

	if (!sc->buf || !sc->reg) {
		device_printf(dev, "unable to map register space\n");
		goto bad;
	}

	if (nm_init(sc) == -1) {
		device_printf(dev, "unable to initialize the card\n");
		goto bad;
	}

	codec = AC97_CREATE(dev, sc, nm_ac97);
	if (codec == NULL) goto bad;
	if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;

	sc->irqid = 0;
	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
					 RF_ACTIVE | RF_SHAREABLE);
	if (!sc->irq || snd_setup_intr(dev, sc->irq, 0, nm_intr, sc, &sc->ih)) {
		device_printf(dev, "unable to map interrupt\n");
		goto bad;
	}

	snprintf(status, SND_STATUSLEN, "at memory 0x%lx, 0x%lx irq %ld %s",
		 rman_get_start(sc->buf), rman_get_start(sc->reg),
		 rman_get_start(sc->irq),PCM_KLDSTRING(snd_neomagic));

	if (pcm_register(dev, sc, 1, 1)) goto bad;
	pcm_addchan(dev, PCMDIR_REC, &nmchan_class, sc);
	pcm_addchan(dev, PCMDIR_PLAY, &nmchan_class, sc);
	pcm_setstatus(dev, status);

	return 0;

bad:
	if (codec) ac97_destroy(codec);
	if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf);
	if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
	if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih);
	if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
	free(sc, M_DEVBUF);
	return ENXIO;
}
예제 #18
0
파일: mixer.c 프로젝트: bsdplus/fluxbsd
void parse_mixer_arg(struct text_object *obj, const char *arg)
{
	obj->data.l = mixer_init(arg);
}
예제 #19
0
static int
via_attach(device_t dev)
{
	struct via_info *via = 0;
	char status[SND_STATUSLEN];
	u_int32_t data, cnt;

	via = kmalloc(sizeof *via, M_DEVBUF, M_WAITOK | M_ZERO);
	via->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");

	/* Get resources */
	data = pci_read_config(dev, PCIR_COMMAND, 2);
	data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN);
	pci_write_config(dev, PCIR_COMMAND, data, 2);
	data = pci_read_config(dev, PCIR_COMMAND, 2);

	/* Wake up and reset AC97 if necessary */
	data = pci_read_config(dev, VIA_AC97STATUS, 1);

	if ((data & VIA_AC97STATUS_RDY) == 0) {
		/* Cold reset per ac97r2.3 spec (page 95) */
		pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN, 1);			/* Assert low */
		DELAY(100);									/* Wait T_rst_low */
		pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN | VIA_ACLINK_NRST, 1);	/* Assert high */
		DELAY(5);									/* Wait T_rst2clk */
		pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN, 1);			/* Assert low */
	} else {
		/* Warm reset */
		pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN, 1);			/* Force no sync */
		DELAY(100);
		pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN | VIA_ACLINK_SYNC, 1);	/* Sync */
		DELAY(5);									/* Wait T_sync_high */
		pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN, 1);			/* Force no sync */
		DELAY(5);									/* Wait T_sync2clk */
	}

	/* Power everything up */
	pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_DESIRED, 1);	

	/* Wait for codec to become ready (largest reported delay here 310ms) */
	for (cnt = 0; cnt < 2000; cnt++) {
		data = pci_read_config(dev, VIA_AC97STATUS, 1);
		if (data & VIA_AC97STATUS_RDY) 
			break;
		DELAY(5000);
	}

	via->regid = PCIR_BAR(0);
	via->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
		&via->regid, RF_ACTIVE);
	if (!via->reg) {
		device_printf(dev, "cannot allocate bus resource.");
		goto bad;
	}
	via->st = rman_get_bustag(via->reg);
	via->sh = rman_get_bushandle(via->reg);

	via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536);

	via->irqid = 0;
	via->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &via->irqid,
		RF_ACTIVE | RF_SHAREABLE);
	if (!via->irq || snd_setup_intr(dev, via->irq, INTR_MPSAFE, via_intr, via, &via->ih)) {
		device_printf(dev, "unable to map interrupt\n");
		goto bad;
	}

	via_wr(via, VIA_PLAY_MODE, VIA_RPMODE_AUTOSTART | VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1);
	via_wr(via, VIA_RECORD_MODE, VIA_RPMODE_AUTOSTART | VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1);

	via->codec = AC97_CREATE(dev, via, via_ac97);
	if (!via->codec)
		goto bad;

	if (mixer_init(dev, ac97_getmixerclass(), via->codec))
		goto bad;

	via->codec_caps = ac97_getextcaps(via->codec);
	ac97_setextmode(via->codec, 
			via->codec_caps & (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM));

	/* DMA tag for buffers */
	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
		/*highaddr*/BUS_SPACE_MAXADDR,
		/*filter*/NULL, /*filterarg*/NULL,
		/*maxsize*/via->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
		/*flags*/0,
		&via->parent_dmat) != 0) {
		device_printf(dev, "unable to create dma tag\n");
		goto bad;
	}

	/*
	 *  DMA tag for SGD table.  The 686 uses scatter/gather DMA and
	 *  requires a list in memory of work to do.  We need only 16 bytes
	 *  for this list, and it is wasteful to allocate 16K.
	 */
	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
		/*highaddr*/BUS_SPACE_MAXADDR,
		/*filter*/NULL, /*filterarg*/NULL,
		/*maxsize*/NSEGS * sizeof(struct via_dma_op),
		/*nsegments*/1, /*maxsegz*/0x3ffff,
		/*flags*/0,
		&via->sgd_dmat) != 0) {
		device_printf(dev, "unable to create dma tag\n");
		goto bad;
	}

	if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table,
	    BUS_DMA_NOWAIT, &via->sgd_dmamap) != 0)
		goto bad;
	if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table,
	    NSEGS * sizeof(struct via_dma_op), dma_cb, via, 0) != 0)
		goto bad;

	ksnprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s",
		 rman_get_start(via->reg), rman_get_start(via->irq),
		 PCM_KLDSTRING(snd_via82c686));

	/* Register */
	if (pcm_register(dev, via, 1, 1)) goto bad;
	pcm_addchan(dev, PCMDIR_PLAY, &viachan_class, via);
	pcm_addchan(dev, PCMDIR_REC, &viachan_class, via);
	pcm_setstatus(dev, status);
	return 0;
bad:
	if (via->codec) ac97_destroy(via->codec);
	if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg);
	if (via->ih) bus_teardown_intr(dev, via->irq, via->ih);
	if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
	if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat);
	if (via->sgd_dmamap) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
	if (via->sgd_table) bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
	if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat);
	if (via->lock) snd_mtxfree(via->lock);
	if (via) kfree(via, M_DEVBUF);
	return ENXIO;
}
예제 #20
0
int alsa_init(audiodevice_t *dev, int cardno, int pcmdev, int mixdev, boolean automix) {
	snd_ctl_t *ctl_handle;
	snd_ctl_hw_info_t *hwinfo;
	audio_alsa05_t *alsa;
	int i, j, ncards;
	snd_pcm_t *pcm_handle;
	
	/* サウンドカードが存在するかチェック */
	ncards = snd_cards();
	if (ncards < 1) {
		WARNING("No ALSA device found\n");
		return NG;
	}
	
	if (cardno == -1 && pcmdev == -1) {
		/* 最初に見つかった使用可能なカード */
		if (NULL == (hwinfo = (snd_ctl_hw_info_t *)malloc(sizeof(*hwinfo) * ncards))) {
			NOMEMERR();
			return NG;
		}
		for (i = 0; i < ncards; i++) {
			if (0 > snd_ctl_open(&ctl_handle, i)) {
				WARNING("Can't Open Card %d\n", i);
				free(hwinfo);
				return NG;
			}
			if (0 > snd_ctl_hw_info(ctl_handle, hwinfo + i)) {
				WARNING("Can't Get Card(%d) info\n", i);
				free(hwinfo);
				return NG;
			}
			snd_ctl_close(ctl_handle);
			for (j = 0; j < hwinfo[i].pcmdevs; j++) {
				//open してチェック OK なら outへ
				if (0 > snd_pcm_open(&pcm_handle, i, j, SND_PCM_OPEN_PLAYBACK)) continue;
				cardno = i; pcmdev  = j;
				snd_pcm_close(pcm_handle);
				NOTICE("ALSA Use(%d:%d) device\n", i, j);
				goto out;
			}
		}
		// 使用可能なデバイスが1つもない場合
		WARNING("Can't Get Card(%d) info\n", i);
		return NG;
	out:
		free(hwinfo);
	} else {
		/* 指定のカード */
		if (0 > snd_ctl_open(&ctl_handle, cardno)) {
			WARNING("Can't Open Card %d\n", cardno);
			return NG;
		}
		snd_ctl_close(ctl_handle);
		
		/* 指定の pcmdevice がカードの中にあるかどうか */
		if (pcmdev >= 0 && pcmdev < hwinfo[cardno].pcmdevs) {
			//opne してチェック
			if (0 > snd_pcm_open(&pcm_handle, cardno, pcmdev, SND_PCM_OPEN_PLAYBACK)) {
				WARNING("Can't Open (%d:%d)\n", cardno, pcmdev);
				return NG;
			}
			snd_pcm_close(pcm_handle);
			NOTICE("ALSA Use(%d:%d) device\n", cardno, pcmdev);
		} else {
			WARNING("Can't Open (%d:%d)\n", cardno, pcmdev);
			return NG;
		}
	}
	
	if (mixer_init(dev, cardno, mixdev, &hwinfo) < 0) {
		return NG;
	}
	
	alsa = g_new0(audio_alsa05_t, 1);
	
	alsa->card = cardno;
	alsa->pcm_dev = pcmdev;
	alsa->automixer = automix;
	
	dev->data_pcm = alsa;
	
	dev->id      = AUDIO_PCM_ALSA;
	dev->fd      = -1;
	dev->open    = audio_open;
	dev->close   = audio_close;
	dev->write   = audio_write;
	dev->mix_set = mixer_set_level;
	dev->mix_get = mixer_get_level;
	dev->exit    = alsa_exit;
	
	NOTICE("ALSA Initilize OK\n");
	return 0;
}
예제 #21
0
static void
atiixp_chip_post_init(void *arg)
{
	struct atiixp_info *sc = (struct atiixp_info *)arg;
	uint32_t subdev;
	int i, timeout, found;
	char status[SND_STATUSLEN];

	atiixp_lock(sc);

	if (sc->delayed_attach.ich_func) {
		config_intrhook_disestablish(&sc->delayed_attach);
		sc->delayed_attach.ich_func = NULL;
	}

	/* wait for the interrupts to happen */
	timeout = 100;
	while (--timeout) {
		snd_mtxsleep(sc, sc->lock, 0, "ixpslp", 1);
		if (sc->codec_not_ready_bits)
			break;
	}

	atiixp_disable_interrupts(sc);

	if (timeout == 0) {
		device_printf(sc->dev,
			"WARNING: timeout during codec detection; "
			"codecs might be present but haven't interrupted\n");
		atiixp_unlock(sc);
		goto postinitbad;
	}

	found = 0;

	/*
	 * ATI IXP can have upto 3 codecs, but single codec should be
	 * suffice for now.
	 */
	if (!(sc->codec_not_ready_bits &
				ATI_REG_ISR_CODEC0_NOT_READY)) {
		/* codec 0 present */
		sc->codec_found++;
		sc->codec_idx = 0;
		found++;
	}

	if (!(sc->codec_not_ready_bits &
				ATI_REG_ISR_CODEC1_NOT_READY)) {
		/* codec 1 present */
		sc->codec_found++;
	}

	if (!(sc->codec_not_ready_bits &
				ATI_REG_ISR_CODEC2_NOT_READY)) {
		/* codec 2 present */
		sc->codec_found++;
	}

	atiixp_unlock(sc);

	if (found == 0)
		goto postinitbad;

	/* create/init mixer */
	sc->codec = AC97_CREATE(sc->dev, sc, atiixp_ac97);
	if (sc->codec == NULL)
		goto postinitbad;

	subdev = (pci_get_subdevice(sc->dev) << 16) | pci_get_subvendor(sc->dev);
	switch (subdev) {
	case 0x11831043:	/* ASUS A6R */
	case 0x2043161f:	/* Maxselect x710s - http://maxselect.ru/ */
		ac97_setflags(sc->codec, ac97_getflags(sc->codec) | AC97_F_EAPD_INV);
		break;
	default:
		break;
	}

	mixer_init(sc->dev, ac97_getmixerclass(), sc->codec);

	if (pcm_register(sc->dev, sc, ATI_IXP_NPCHAN, ATI_IXP_NRCHAN))
		goto postinitbad;

	for (i = 0; i < ATI_IXP_NPCHAN; i++)
		pcm_addchan(sc->dev, PCMDIR_PLAY, &atiixp_chan_class, sc);
	for (i = 0; i < ATI_IXP_NRCHAN; i++)
		pcm_addchan(sc->dev, PCMDIR_REC, &atiixp_chan_class, sc);

	ksnprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s", 
			rman_get_start(sc->reg), rman_get_start(sc->irq),
			PCM_KLDSTRING(snd_atiixp));

	pcm_setstatus(sc->dev, status);

	atiixp_lock(sc);
	atiixp_enable_interrupts(sc);
	atiixp_unlock(sc);

	return;

postinitbad:
	atiixp_release_resource(sc);
}
예제 #22
0
파일: fm801.c 프로젝트: kusumi/DragonFlyBSD
static int
fm801_pci_attach(device_t dev)
{
	struct ac97_info 	*codec = 0;
	struct fm801_info 	*fm801;
	int 			i;
	int 			mapped = 0;
	char 			status[SND_STATUSLEN];

	fm801 = kmalloc(sizeof(*fm801), M_DEVBUF, M_WAITOK | M_ZERO);
	fm801->type = pci_get_devid(dev);

	pci_enable_busmaster(dev);

	for (i = 0; (mapped == 0) && (i < PCI_MAXMAPS_0); i++) {
		fm801->regid = PCIR_BAR(i);
		fm801->regtype = SYS_RES_MEMORY;
		fm801->reg = bus_alloc_resource_any(dev, fm801->regtype,
						    &fm801->regid, RF_ACTIVE);
		if(!fm801->reg)
		{
			fm801->regtype = SYS_RES_IOPORT;
			fm801->reg = bus_alloc_resource_any(dev, 
							    fm801->regtype,
							    &fm801->regid,
							    RF_ACTIVE);
		}

		if(fm801->reg) {
			fm801->st = rman_get_bustag(fm801->reg);
			fm801->sh = rman_get_bushandle(fm801->reg);
			mapped++;
		}
	}

	if (mapped == 0) {
		device_printf(dev, "unable to map register space\n");
		goto oops;
	}

	fm801->bufsz = pcm_getbuffersize(dev, 4096, FM801_DEFAULT_BUFSZ, 65536);

	fm801_init(fm801);

	codec = AC97_CREATE(dev, fm801, fm801_ac97);
	if (codec == NULL) goto oops;

	if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto oops;

	fm801->irqid = 0;
	fm801->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fm801->irqid,
					    RF_ACTIVE | RF_SHAREABLE);
	if (!fm801->irq || snd_setup_intr(dev, fm801->irq, 0, fm801_intr, fm801, &fm801->ih)) {
		device_printf(dev, "unable to map interrupt\n");
		goto oops;
	}

	if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
		/*boundary*/0,
		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
		/*highaddr*/BUS_SPACE_MAXADDR,
		/*filter*/NULL, /*filterarg*/NULL,
		/*maxsize*/fm801->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
		/*flags*/0,
		&fm801->parent_dmat) != 0) {
		device_printf(dev, "unable to create dma tag\n");
		goto oops;
	}

	ksnprintf(status, 64, "at %s 0x%lx irq %ld %s",
		(fm801->regtype == SYS_RES_IOPORT)? "io" : "memory",
		rman_get_start(fm801->reg), rman_get_start(fm801->irq),PCM_KLDSTRING(snd_fm801));

#define FM801_MAXPLAYCH	1
	if (pcm_register(dev, fm801, FM801_MAXPLAYCH, 1)) goto oops;
	pcm_addchan(dev, PCMDIR_PLAY, &fm801ch_class, fm801);
	pcm_addchan(dev, PCMDIR_REC, &fm801ch_class, fm801);
	pcm_setstatus(dev, status);

	fm801->radio = device_add_child(dev, "radio", -1);
	bus_generic_attach(dev);

	return 0;

oops:
	if (codec) ac97_destroy(codec);
	if (fm801->reg) bus_release_resource(dev, fm801->regtype, fm801->regid, fm801->reg);
	if (fm801->ih) bus_teardown_intr(dev, fm801->irq, fm801->ih);
	if (fm801->irq) bus_release_resource(dev, SYS_RES_IRQ, fm801->irqid, fm801->irq);
	if (fm801->parent_dmat) bus_dma_tag_destroy(fm801->parent_dmat);
	kfree(fm801, M_DEVBUF);
	return ENXIO;
}
예제 #23
0
static int
via_attach(device_t dev)
{
	struct via_info *via = NULL;
	char status[SND_STATUSLEN];
	int i, via_dxs_disabled, via_dxs_src, via_dxs_chnum, via_sgd_chnum;
	uint32_t revid;

	via = kmalloc(sizeof *via, M_DEVBUF, M_WAITOK | M_ZERO);
	via->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");

	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
	pci_enable_busmaster(dev);

	via->regid = PCIR_BAR(0);
	via->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &via->regid,
					  RF_ACTIVE);
	if (!via->reg) {
		device_printf(dev, "cannot allocate bus resource.");
		goto bad;
	}
	via->st = rman_get_bustag(via->reg);
	via->sh = rman_get_bushandle(via->reg);

	via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536);

	via->irqid = 0;
	via->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &via->irqid,
					  RF_ACTIVE | RF_SHAREABLE);
	if (!via->irq || 
	    snd_setup_intr(dev, via->irq, INTR_MPSAFE, via_intr, via, &via->ih)) {
		device_printf(dev, "unable to map interrupt\n");
		goto bad;
	}

	/* DMA tag for buffers */
	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
		/*highaddr*/BUS_SPACE_MAXADDR,
		/*filter*/NULL, /*filterarg*/NULL,
		/*maxsize*/via->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
		/*flags*/0,
		&via->parent_dmat) != 0) {
		device_printf(dev, "unable to create dma tag\n");
		goto bad;
	}

	/*
	 *  DMA tag for SGD table.  The 686 uses scatter/gather DMA and
	 *  requires a list in memory of work to do.  We need only 16 bytes
	 *  for this list, and it is wasteful to allocate 16K.
	 */
	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
		/*highaddr*/BUS_SPACE_MAXADDR,
		/*filter*/NULL, /*filterarg*/NULL,
		/*maxsize*/NSEGS * sizeof(struct via_dma_op),
		/*nsegments*/1, /*maxsegz*/0x3ffff,
		/*flags*/0,
		&via->sgd_dmat) != 0) {
		device_printf(dev, "unable to create dma tag\n");
		goto bad;
	}

	if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, 
			     BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1)
		goto bad;
	if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, 
			    NSEGS * sizeof(struct via_dma_op), dma_cb, via, 0))
		goto bad;

	if (via_chip_init(dev))
		goto bad;

	via->codec = AC97_CREATE(dev, via, via_ac97);
	if (!via->codec)
		goto bad;

	mixer_init(dev, ac97_getmixerclass(), via->codec);

	via->codec_caps = ac97_getextcaps(via->codec);

	/* Try to set VRA without generating an error, VRM not reqrd yet */
	if (via->codec_caps & 
	    (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM | AC97_EXTCAP_DRA)) {
		u_int16_t ext = ac97_getextmode(via->codec);
		ext |= (via->codec_caps & 
			(AC97_EXTCAP_VRA | AC97_EXTCAP_VRM));
		ext &= ~AC97_EXTCAP_DRA;
		ac97_setextmode(via->codec, ext);
	}

	ksnprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s", 
		 rman_get_start(via->reg), rman_get_start(via->irq),PCM_KLDSTRING(snd_via8233));

	revid = pci_get_revid(dev);

	/*
	 * VIA8251 lost its interrupt after DMA EOL, and need
	 * a gentle spank on its face within interrupt handler.
	 */
	if (revid == VIA8233_REV_ID_8251)
		via->dma_eol_wake = 1;
	else
		via->dma_eol_wake = 0;

	/*
	 * Decide whether DXS had to be disabled or not
	 */
	if (revid == VIA8233_REV_ID_8233A) {
		/*
		 * DXS channel is disabled.  Reports from multiple users
		 * that it plays at half-speed.  Do not see this behaviour
		 * on available 8233C or when emulating 8233A register set
		 * on 8233C (either with or without ac97 VRA).
		 */
		via_dxs_disabled = 1;
	} else if (resource_int_value(device_get_name(dev),
			device_get_unit(dev), "via_dxs_disabled",
			&via_dxs_disabled) == 0)
		via_dxs_disabled = (via_dxs_disabled > 0) ? 1 : 0;
	else
		via_dxs_disabled = 0;

	if (via_dxs_disabled) {
		via_dxs_chnum = 0;
		via_sgd_chnum = 1;
	} else {
		if (resource_int_value(device_get_name(dev),
				device_get_unit(dev), "via_dxs_channels",
				&via_dxs_chnum) != 0)
			via_dxs_chnum = NDXSCHANS;
		if (resource_int_value(device_get_name(dev),
				device_get_unit(dev), "via_sgd_channels",
				&via_sgd_chnum) != 0)
			via_sgd_chnum = NMSGDCHANS;
	}
	if (via_dxs_chnum > NDXSCHANS)
		via_dxs_chnum = NDXSCHANS;
	else if (via_dxs_chnum < 0)
		via_dxs_chnum = 0;
	if (via_sgd_chnum > NMSGDCHANS)
		via_sgd_chnum = NMSGDCHANS;
	else if (via_sgd_chnum < 0)
		via_sgd_chnum = 0;
	if (via_dxs_chnum + via_sgd_chnum < 1) {
		/* Minimalist ? */
		via_dxs_chnum = 1;
		via_sgd_chnum = 0;
	}
	if (via_dxs_chnum > 0 && resource_int_value(device_get_name(dev),
			device_get_unit(dev), "via_dxs_src",
			&via_dxs_src) == 0)
		via->dxs_src = (via_dxs_src > 0) ? 1 : 0;
	else
		via->dxs_src = 0;
	/* Register */
	if (pcm_register(dev, via, via_dxs_chnum + via_sgd_chnum, NWRCHANS))
	      goto bad;
	for (i = 0; i < via_dxs_chnum; i++)
	      pcm_addchan(dev, PCMDIR_PLAY, &via8233dxs_class, via);
	for (i = 0; i < via_sgd_chnum; i++)
	      pcm_addchan(dev, PCMDIR_PLAY, &via8233msgd_class, via);
	for (i = 0; i < NWRCHANS; i++)
	      pcm_addchan(dev, PCMDIR_REC, &via8233wr_class, via);
	if (via_dxs_chnum > 0)
		via_init_sysctls(dev);
	device_printf(dev, "<VIA DXS %sabled: DXS%s %d / SGD %d / REC %d>\n",
		(via_dxs_chnum > 0) ? "En" : "Dis",
		(via->dxs_src) ? "(SRC)" : "",
		via_dxs_chnum, via_sgd_chnum, NWRCHANS);

	pcm_setstatus(dev, status);

	return 0;
bad:
	if (via->codec) ac97_destroy(via->codec);
	if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg);
	if (via->ih) bus_teardown_intr(dev, via->irq, via->ih);
	if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
	if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat);
	if (via->sgd_dmamap) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
	if (via->sgd_table) bus_dmamem_free(via->sgd_dmat, via->sgd_table, via->sgd_dmamap);
	if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat);
	if (via->lock) snd_mtxfree(via->lock);
	if (via) kfree(via, M_DEVBUF);
	return ENXIO;
}
예제 #24
0
파일: ds1.c 프로젝트: Alkzndr/freebsd
static int
ds_pci_attach(device_t dev)
{
	u_int32_t subdev, i;
	struct sc_info *sc;
	struct ac97_info *codec = NULL;
	char 		status[SND_STATUSLEN];

	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_ds1 softc");
	sc->dev = dev;
	subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
	sc->type = ds_finddev(pci_get_devid(dev), subdev);
	sc->rev = pci_get_revid(dev);

	pci_enable_busmaster(dev);

	sc->regid = PCIR_BAR(0);
	sc->reg = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->regid,
					 RF_ACTIVE);
	if (!sc->reg) {
		device_printf(dev, "unable to map register space\n");
		goto bad;
	}

	sc->st = rman_get_bustag(sc->reg);
	sc->sh = rman_get_bushandle(sc->reg);

	sc->bufsz = pcm_getbuffersize(dev, 4096, DS1_BUFFSIZE, 65536);

	if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
		/*boundary*/0,
		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
		/*highaddr*/BUS_SPACE_MAXADDR,
		/*filter*/NULL, /*filterarg*/NULL,
		/*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
		/*flags*/0, /*lockfunc*/NULL,
		/*lockarg*/NULL, &sc->buffer_dmat) != 0) {
		device_printf(dev, "unable to create dma tag\n");
		goto bad;
	}

	sc->regbase = NULL;
	if (ds_init(sc) == -1) {
		device_printf(dev, "unable to initialize the card\n");
		goto bad;
	}

	codec = AC97_CREATE(dev, sc, ds_ac97);
	if (codec == NULL)
		goto bad;
	/*
	 * Turn on inverted external amplifier sense flags for few
	 * 'special' boards.
	 */
	switch (subdev) {
	case 0x81171033:	/* NEC ValueStar (VT550/0) */
		ac97_setflags(codec, ac97_getflags(codec) | AC97_F_EAPD_INV);
		break;
	default:
		break;
	}
	mixer_init(dev, ac97_getmixerclass(), codec);

	sc->irqid = 0;
	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
					 RF_ACTIVE | RF_SHAREABLE);
	if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ds_intr, sc, &sc->ih)) {
		device_printf(dev, "unable to map interrupt\n");
		goto bad;
	}

	snprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s",
		 rman_get_start(sc->reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_ds1));

	if (pcm_register(dev, sc, DS1_CHANS, 2))
		goto bad;
	for (i = 0; i < DS1_CHANS; i++)
		pcm_addchan(dev, PCMDIR_PLAY, &ds1pchan_class, sc);
	for (i = 0; i < 2; i++)
		pcm_addchan(dev, PCMDIR_REC, &ds1rchan_class, sc);
	pcm_setstatus(dev, status);

	return 0;

bad:
	if (codec)
		ac97_destroy(codec);
	if (sc->reg)
		bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg);
	if (sc->ih)
		bus_teardown_intr(dev, sc->irq, sc->ih);
	if (sc->irq)
		bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
	if (sc->buffer_dmat)
		bus_dma_tag_destroy(sc->buffer_dmat);
	if (sc->control_dmat)
		bus_dma_tag_destroy(sc->control_dmat);
	if (sc->lock)
		snd_mtxfree(sc->lock);
	free(sc, M_DEVBUF);
	return ENXIO;
}
예제 #25
0
파일: davbus.c 프로젝트: JabirTech/Source
static int
davbus_attach(device_t self)
{
	struct davbus_softc 	*sc;
	struct resource 	*dbdma_irq, *cintr;
	void 			*cookie;
	char			 compat[64];
	int 			 rid, oirq, err;

	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);

	sc->aoa.sc_dev = self;
	sc->node = ofw_bus_get_node(self);
	sc->soundnode = OF_child(sc->node);

	/* Map the controller register space. */
	rid = 0;
	sc->reg = bus_alloc_resource_any(self, SYS_RES_MEMORY, &rid, RF_ACTIVE);
	if (sc->reg == NULL) 
		return (ENXIO);

	/* Map the DBDMA channel register space. */
	rid = 1;
	sc->aoa.sc_odma = bus_alloc_resource_any(self, SYS_RES_MEMORY, 
	    &rid, RF_ACTIVE);
	if (sc->aoa.sc_odma == NULL)
		return (ENXIO);

	/* Establish the DBDMA channel edge-triggered interrupt. */
	rid = 1;
	dbdma_irq = bus_alloc_resource_any(self, SYS_RES_IRQ, 
	    &rid, RF_SHAREABLE | RF_ACTIVE);
	if (dbdma_irq == NULL)
		return (ENXIO);

	oirq = rman_get_start(dbdma_irq);
	
	DPRINTF(("interrupting at irq %d\n", oirq));

	err = powerpc_config_intr(oirq, INTR_TRIGGER_EDGE, INTR_POLARITY_LOW);
	if (err != 0)
		return (err);
		
	snd_setup_intr(self, dbdma_irq, INTR_MPSAFE, aoa_interrupt,
	    sc, &cookie);

	/* Now initialize the controller. */

	bzero(compat, sizeof(compat));
	OF_getprop(sc->soundnode, "compatible", compat, sizeof(compat));
	OF_getprop(sc->soundnode, "device-id", &sc->device_id, sizeof(u_int));

	mtx_init(&sc->mutex, "DAVbus", NULL, MTX_DEF);

	device_printf(self, "codec: <%s>\n", compat);

	/* Setup the control interrupt. */
	rid = 0;
	cintr = bus_alloc_resource_any(self, SYS_RES_IRQ, 
	     &rid, RF_SHAREABLE | RF_ACTIVE);
	if (cintr != NULL) 
		bus_setup_intr(self, cintr, INTR_TYPE_MISC | INTR_MPSAFE,
		    NULL, davbus_cint, sc, &cookie);
	
	/* Initialize controller registers. */
        bus_write_4(sc->reg, DAVBUS_SOUND_CTRL, DAVBUS_INPUT_SUBFRAME0 | 
	    DAVBUS_OUTPUT_SUBFRAME0 | DAVBUS_RATE_44100 | DAVBUS_INTR_PORTCHG);

	/* Attach DBDMA engine and PCM layer */
	err = aoa_attach(sc);
	if (err)
		return (err);

	/* Install codec module */
	if (strcmp(compat, "screamer") == 0)
		mixer_init(self, &screamer_mixer_class, sc);
	else if (strcmp(compat, "burgundy") == 0)
		mixer_init(self, &burgundy_mixer_class, sc);

	return (0);
}
예제 #26
0
static int
cs4281_pci_attach(device_t dev)
{
    struct sc_info *sc;
    struct ac97_info *codec = NULL;
    char status[SND_STATUSLEN];

    sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
    sc->dev = dev;
    sc->type = pci_get_devid(dev);

    pci_enable_busmaster(dev);

#if __FreeBSD_version > 500000
    if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
	/* Reset the power state. */
	device_printf(dev, "chip is in D%d power mode "
		      "-- setting to D0\n", pci_get_powerstate(dev));

	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
    }
#else
    data = pci_read_config(dev, CS4281PCI_PMCS_OFFSET, 4);
    if (data & CS4281PCI_PMCS_PS_MASK) {
	    /* Reset the power state. */
	    device_printf(dev, "chip is in D%d power mode "
			  "-- setting to D0\n",
			  data & CS4281PCI_PMCS_PS_MASK);
	    pci_write_config(dev, CS4281PCI_PMCS_OFFSET,
			     data & ~CS4281PCI_PMCS_PS_MASK, 4);
    }
#endif

    sc->regid   = PCIR_BAR(0);
    sc->regtype = SYS_RES_MEMORY;
    sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid,
				 0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE);
    if (!sc->reg) {
	sc->regtype = SYS_RES_IOPORT;
	sc->reg = bus_alloc_resource(dev, sc->regtype, &sc->regid,
				     0, ~0, CS4281PCI_BA0_SIZE, RF_ACTIVE);
	if (!sc->reg) {
	    device_printf(dev, "unable to allocate register space\n");
	    goto bad;
	}
    }
    sc->st = rman_get_bustag(sc->reg);
    sc->sh = rman_get_bushandle(sc->reg);

    sc->memid = PCIR_BAR(1);
    sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->memid, 0,
				 ~0, CS4281PCI_BA1_SIZE, RF_ACTIVE);
    if (sc->mem == NULL) {
	device_printf(dev, "unable to allocate fifo space\n");
	goto bad;
    }

    sc->irqid = 0;
    sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
				     RF_ACTIVE | RF_SHAREABLE);
    if (!sc->irq) {
	device_printf(dev, "unable to allocate interrupt\n");
	goto bad;
    }

    if (snd_setup_intr(dev, sc->irq, 0, cs4281_intr, sc, &sc->ih)) {
	device_printf(dev, "unable to setup interrupt\n");
	goto bad;
    }

    sc->bufsz = pcm_getbuffersize(dev, 4096, CS4281_DEFAULT_BUFSZ, 65536);

    if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
			   /*boundary*/0,
			   /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
			   /*highaddr*/BUS_SPACE_MAXADDR,
			   /*filter*/NULL, /*filterarg*/NULL,
			   /*maxsize*/sc->bufsz, /*nsegments*/1,
			   /*maxsegz*/0x3ffff,
			   /*flags*/0, /*lockfunc*/busdma_lock_mutex,
			   /*lockarg*/&Giant, &sc->parent_dmat) != 0) {
	device_printf(dev, "unable to create dma tag\n");
	goto bad;
    }

    /* power up */
    cs4281_power(sc, 0);

    /* init chip */
    if (cs4281_init(sc) == -1) {
	device_printf(dev, "unable to initialize the card\n");
	goto bad;
    }

    /* create/init mixer */
    codec = AC97_CREATE(dev, sc, cs4281_ac97);
    if (codec == NULL)
        goto bad;

    mixer_init(dev, ac97_getmixerclass(), codec);

    if (pcm_register(dev, sc, 1, 1))
	goto bad;

    pcm_addchan(dev, PCMDIR_PLAY, &cs4281chan_class, sc);
    pcm_addchan(dev, PCMDIR_REC, &cs4281chan_class, sc);

    snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld %s",
	     (sc->regtype == SYS_RES_IOPORT)? "io" : "memory",
	     rman_get_start(sc->reg), rman_get_start(sc->irq),PCM_KLDSTRING(snd_cs4281));
    pcm_setstatus(dev, status);

    return 0;

 bad:
    if (codec)
	ac97_destroy(codec);
    if (sc->reg)
	bus_release_resource(dev, sc->regtype, sc->regid, sc->reg);
    if (sc->mem)
	bus_release_resource(dev, SYS_RES_MEMORY, sc->memid, sc->mem);
    if (sc->ih)
	bus_teardown_intr(dev, sc->irq, sc->ih);
    if (sc->irq)
	bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
    if (sc->parent_dmat)
	bus_dma_tag_destroy(sc->parent_dmat);
    free(sc, M_DEVBUF);

    return ENXIO;
}
예제 #27
0
/*
 * Attach
 */
static int
au88x0_pci_attach(device_t dev)
{
	struct au88x0_chipset *auc;
	struct au88x0_info *aui = NULL;
	uint32_t config;
	int error;

	aui = kmalloc(sizeof *aui, M_DEVBUF, M_WAITOK | M_ZERO);
	aui->aui_dev = dev;

	/* Model-specific parameters */
	aui->aui_model = pci_get_devid(dev);
	for (auc = au88x0_chipsets; auc->auc_pci_id; ++auc)
		if (auc->auc_pci_id == aui->aui_model)
			aui->aui_chipset = auc;
	if (aui->aui_chipset == NULL)
		panic("%s() called for non-au88x0 device", __func__);

	/* enable pio, mmio, bus-mastering dma */
	config = pci_read_config(dev, PCIR_COMMAND, 2);
	config |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
	pci_write_config(dev, PCIR_COMMAND, config, 2);

	/* register mapping */
	config = pci_read_config(dev, PCIR_COMMAND, 2);
	if (config & PCIM_CMD_MEMEN) {
		/* try memory-mapped I/O */
		aui->aui_regid = PCIR_BAR(0);
		aui->aui_regtype = SYS_RES_MEMORY;
		aui->aui_reg = bus_alloc_resource_any(dev, aui->aui_regtype,
		    &aui->aui_regid, RF_ACTIVE);
	}
	if (aui->aui_reg == NULL && (config & PCIM_CMD_PORTEN)) {
		/* fall back on port I/O */
		aui->aui_regid = PCIR_BAR(0);
		aui->aui_regtype = SYS_RES_IOPORT;
		aui->aui_reg = bus_alloc_resource_any(dev, aui->aui_regtype,
		    &aui->aui_regid, RF_ACTIVE);
	}
	if (aui->aui_reg == NULL) {
		/* both mmio and pio failed... */
		device_printf(dev, "failed to map registers\n");
		goto failed;
	}
	aui->aui_spct = rman_get_bustag(aui->aui_reg);
	aui->aui_spch = rman_get_bushandle(aui->aui_reg);

	/* IRQ mapping */
	aui->aui_irqid = 0;
	aui->aui_irqtype = SYS_RES_IRQ;
	aui->aui_irq = bus_alloc_resource_any(dev, aui->aui_irqtype,
	    &aui->aui_irqid, RF_ACTIVE | RF_SHAREABLE);
	if (aui->aui_irq == 0) {
		device_printf(dev, "failed to map IRQ\n");
		goto failed;
	}

	/* install interrupt handler */
	error = snd_setup_intr(dev, aui->aui_irq, 0, au88x0_intr,
	    aui, &aui->aui_irqh);
	if (error != 0) {
		device_printf(dev, "failed to install interrupt handler\n");
		goto failed;
	}

	/* DMA mapping */
	aui->aui_bufsize = pcm_getbuffersize(dev, AU88X0_BUFSIZE_MIN,
	    AU88X0_BUFSIZE_DFLT, AU88X0_BUFSIZE_MAX);
	error = bus_dma_tag_create(NULL,
	    2, 0, /* 16-bit alignment, no boundary */
	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, /* restrict to 4GB */
	    NULL, NULL, /* no filter */
	    aui->aui_bufsize, 1, aui->aui_bufsize,
	    0, busdma_lock_mutex, &Giant, &aui->aui_dmat);
	if (error != 0) {
		device_printf(dev, "failed to create DMA tag\n");
		goto failed;
	}

	/* initialize the hardware */
	au88x0_init(aui);

	/* initialize the ac97 codec and mixer */
	if ((aui->aui_ac97i = AC97_CREATE(dev, aui, au88x0_ac97)) == NULL) {
		device_printf(dev, "failed to initialize ac97 codec\n");
		goto failed;
	}
	if (mixer_init(dev, ac97_getmixerclass(), aui->aui_ac97i) != 0) {
		device_printf(dev, "failed to initialize ac97 mixer\n");
		goto failed;
	}

	/* register with the pcm driver */
	if (pcm_register(dev, aui, 0, 0))
		goto failed;
	pcm_addchan(dev, PCMDIR_PLAY, &au88x0_chan_class, aui);
#if 0
	pcm_addchan(dev, PCMDIR_REC, &au88x0_chan_class, aui);
#endif
	au88x0_set_status(dev);

	return (0);
failed:
	if (aui->aui_ac97i != NULL)
		ac97_destroy(aui->aui_ac97i);
	if (aui->aui_dmat)
		bus_dma_tag_destroy(aui->aui_dmat);
	if (aui->aui_irqh != NULL)
		bus_teardown_intr(dev, aui->aui_irq, aui->aui_irqh);
	if (aui->aui_irq)
		bus_release_resource(dev, aui->aui_irqtype,
		    aui->aui_irqid, aui->aui_irq);
	if (aui->aui_reg)
		bus_release_resource(dev, aui->aui_regtype,
		    aui->aui_regid, aui->aui_reg);
	kfree(aui, M_DEVBUF);
	return (ENXIO);
}