From 326767870bf8c3b2440133b17a84e14cfbc91e0b Mon Sep 17 00:00:00 2001 From: Fredrik Modeen Date: Sat, 12 Jul 2008 10:55:44 +0000 Subject: [PATCH] unsuccessfully effort to move emuxkigamport to the emuxki audio driver where it belongs. The sound got distorted when the joystick was used. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26391 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/drivers/audio/emuxki/Jamfile | 1 + .../kernel/drivers/audio/emuxki/emuxki.c | 55 ++++++++- .../kernel/drivers/audio/emuxki/emuxki.h | 25 +++- src/add-ons/kernel/drivers/audio/emuxki/joy.c | 95 +++++++++++++++ .../drivers/audio/emuxki/joystick_driver.h | 113 ++++++++++++++++++ 5 files changed, 283 insertions(+), 6 deletions(-) create mode 100644 src/add-ons/kernel/drivers/audio/emuxki/joy.c create mode 100644 src/add-ons/kernel/drivers/audio/emuxki/joystick_driver.h diff --git a/src/add-ons/kernel/drivers/audio/emuxki/Jamfile b/src/add-ons/kernel/drivers/audio/emuxki/Jamfile index 558b870fa0..d7ac8abbc4 100644 --- a/src/add-ons/kernel/drivers/audio/emuxki/Jamfile +++ b/src/add-ons/kernel/drivers/audio/emuxki/Jamfile @@ -12,6 +12,7 @@ KernelAddon emuxki : midi.c multi.c util.c +# joy.c ; SEARCH on emuxki.settings = $(SUBDIR) ; diff --git a/src/add-ons/kernel/drivers/audio/emuxki/emuxki.c b/src/add-ons/kernel/drivers/audio/emuxki/emuxki.c index ef444e5de0..ec7e117600 100644 --- a/src/add-ons/kernel/drivers/audio/emuxki/emuxki.c +++ b/src/add-ons/kernel/drivers/audio/emuxki/emuxki.c @@ -3,6 +3,10 @@ * * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) * + * Authors: + * Alexander Coers Alexander.Coers@gmx.de + * Fredrik Modéen fredrik@modeen.se + * */ /* This code is derived from the NetBSD driver for Creative Labs SBLive! series * @@ -69,7 +73,8 @@ device_hooks * find_device(const char *); pci_module_info *pci; generic_mpu401_module * mpu401; - +//static char gameport_name[] = "generic/gameport/v2"; +//generic_gameport_module * gameport; int32 num_cards; emuxki_dev cards[NUM_CARDS]; @@ -88,6 +93,7 @@ status_t emuxki_init(emuxki_dev * card); extern device_hooks multi_hooks; extern device_hooks midi_hooks; +//extern device_hooks joy_hooks; /* Hardware Dump */ @@ -2007,8 +2013,9 @@ emuxki_int(void *arg) status_t init_hardware(void) { - int ix=0; + int ix = 0; pci_info info; +// uint32 buffer; status_t err = ENODEV; LOG_CREATE(); @@ -2027,6 +2034,16 @@ init_hardware(void) #endif )) { err = B_OK; + +/* + Joystick suport + if (!(info.u.h0.subsystem_id == 0x20 || + info.u.h0.subsystem_id == 0xc400 || + (info.u.h0.subsystem_id == 0x21 && info.revision < 6))) { + buffer = (*pci->read_io_32)(info.u.h0.base_registers[0] + HCFG); + buffer |= HCFG_JOYENABLE; + (*pci->write_io_32)(info.u.h0.base_registers[0] + HCFG, buffer); + }*/ } ix++; } @@ -2040,11 +2057,13 @@ static void make_device_names( emuxki_dev * card) { - #if MIDI sprintf(card->midi.name, "midi/emuxki/%ld", card-cards+1); names[num_names++] = card->midi.name; #endif + +// sprintf(card->joy.name1, "joystick/"DRIVER_NAME "/%x", card-cards+1); +// names[num_names++] = card->joy.name1; sprintf(card->name, "audio/hmulti/emuxki/%ld", card-cards+1); names[num_names++] = card->name; @@ -2058,6 +2077,7 @@ emuxki_setup(emuxki_dev * card) { status_t err = B_OK; unsigned char cmd; + int32 base; PRINT(("setup_emuxki(%p)\n", card)); @@ -2092,11 +2112,22 @@ emuxki_setup(emuxki_dev * card) //SBLIVE : EMU_MUDATA, workaround 0, AUDIGY, AUDIGY2: 0, workaround 0x11020004 if ((err = (*mpu401->create_device)((card->config.nabmbar + !IS_AUDIGY(&card->config) ? EMU_MUDATA : 0), &card->midi.driver, !IS_AUDIGY(&card->config) ? 0 : 0x11020004, midi_interrupt_op, &card->midi)) < B_OK) - return (err); + return (err); card->midi.card = card; #endif - + + // begin Joystick part +/* base = card->info.u.h0.base_registers[0]; + (*pci->write_pci_config) (card->info.bus,card->info.device, + card->info.function, 0x10, 2, base); + + if ((*gameport->create_device)(base, &card->joy.driver) < B_OK) { + dprintf("Audigy joystick - Error creating device\n"); + (*gameport->delete_device)(card->joy.driver); + }*/ + // end Joystick part + /* reset the codec */ PRINT(("codec reset\n")); emuxki_codec_write(&card->config, 0x00, 0x0000); @@ -2816,7 +2847,13 @@ init_driver(void) if (get_module(B_PCI_MODULE_NAME, (module_info **) &pci)) return ENOSYS; +// if (get_module (gameport_name, (module_info **)&gameport)) { +// put_module (B_PCI_MODULE_NAME); +// return ENOSYS; +// } + if (get_module(B_MPU_401_MODULE_NAME, (module_info **) &mpu401)) { + //put_module(gameport_name); put_module(B_PCI_MODULE_NAME); return ENOSYS; } @@ -2846,6 +2883,7 @@ init_driver(void) } if (!num_cards) { put_module(B_MPU_401_MODULE_NAME); +// put_module(gameport_name); put_module(B_PCI_MODULE_NAME); PRINT(("emuxki: no suitable cards found\n")); return ENODEV; @@ -2919,6 +2957,8 @@ emuxki_shutdown(emuxki_dev *card) PRINT(("freeing silentpage_area\n")); if (card->silentpage_area > B_OK) delete_area(card->silentpage_area); + +// (*gameport->delete_device)(card->joy.driver); } @@ -2934,6 +2974,7 @@ uninit_driver(void) } memset(&cards, 0, sizeof(cards)); put_module(B_MPU_401_MODULE_NAME); +// put_module(gameport_name); put_module(B_PCI_MODULE_NAME); num_cards = 0; } @@ -2965,6 +3006,10 @@ find_device(const char * name) return &midi_hooks; } #endif +// if (!strcmp(cards[ix].joy.name1, name)) { +// return &joy_hooks; +// } + if (!strcmp(cards[ix].name, name)) { return &multi_hooks; } diff --git a/src/add-ons/kernel/drivers/audio/emuxki/emuxki.h b/src/add-ons/kernel/drivers/audio/emuxki/emuxki.h index c7d7de20e8..ec2865c0f5 100644 --- a/src/add-ons/kernel/drivers/audio/emuxki/emuxki.h +++ b/src/add-ons/kernel/drivers/audio/emuxki/emuxki.h @@ -3,6 +3,10 @@ * * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) * + * Authors: + * Alexander Coers Alexander.Coers@gmx.de + * Fredrik Modéen fredrik@modeen.se + * * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. * @@ -48,6 +52,7 @@ #include "queue.h" #include "hmulti_audio.h" #include "multi.h" +#include "joystick_driver.h" #define CREATIVELABS_VENDOR_ID 0x1102 /* Creative Labs */ @@ -86,6 +91,22 @@ typedef struct { extern emuxki_settings current_settings; +/* + * Gameport stuff + */ + +#define HCFG 0x14 /* Hardware Configuration Register of SB-Live */ +#define HCFG_JOYENABLE 0x00000200 /* Mask for enabling Joystick */ + +extern generic_gameport_module * gameport; + +typedef struct _joy_dev +{ + void * driver; + char name1[64]; +} joy_dev; +/* End Gameport stuff*/ + /* * Emu10k1 midi */ @@ -321,6 +342,7 @@ typedef enum { EMU_AUDIO_MODE = 1 << 1 } emuxki_parameter_type; + /* * Devices */ @@ -357,6 +379,7 @@ typedef struct _emuxki_dev { sem_id buffer_ready_sem; + joy_dev joy; midi_dev midi; /* mixer controls */ @@ -364,7 +387,7 @@ typedef struct _emuxki_dev { uint32 gpr_count; /* multi_audio */ - multi_dev multi; + multi_dev multi; } emuxki_dev; extern int32 num_cards; diff --git a/src/add-ons/kernel/drivers/audio/emuxki/joy.c b/src/add-ons/kernel/drivers/audio/emuxki/joy.c new file mode 100644 index 0000000000..cff080aca4 --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/emuxki/joy.c @@ -0,0 +1,95 @@ +/* + * Copyright 2008 Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Alexander Coers Alexander.Coers@gmx.de + * Fredrik Modéen fredrik@modeen.se + */ + +#include "emuxki.h" +#include "debug.h" + +#if !defined(_KERNEL_EXPORT_H) +#include +#endif /* _KERNEL_EXPORT_H */ + +static status_t joy_open(const char *name, uint32 flags, void **cookie); +static status_t joy_close(void *cookie); +static status_t joy_free(void *cookie); +static status_t joy_control(void *cookie, uint32 op, void *data, size_t len); +static status_t joy_read(void *cookie, off_t pos, void *data, size_t *len); +static status_t joy_write(void *cookie, off_t pos, const void *data, size_t *len); + +#define MIN_COMP -7 +#define MAX_COMP 8 + +device_hooks joy_hooks = { + &joy_open, + &joy_close, + &joy_free, + &joy_control, + &joy_read, + &joy_write, + NULL, /* select */ + NULL, /* deselect */ + NULL, /* readv */ + NULL /* writev */ +}; + + +static status_t +joy_open(const char * name, uint32 flags, void ** cookie) +{ + int ix; + int offset = -1; + + LOG(("GamePort: joy_open()\n")); + + *cookie = NULL; + for (ix = 0; ix < num_cards; ix++) { + if (!strcmp(name, cards[ix].joy.name1)) { + offset = 0; + break; + } + } + if (offset < 0) { + return ENODEV; + } + return (*gameport->open_hook)(cards[ix].joy.driver, flags, cookie); +} + + +static status_t +joy_close(void * cookie) +{ + return (*gameport->close_hook)(cookie); +} + + +static status_t +joy_free(void * cookie) +{ + return (*gameport->free_hook)(cookie); +} + + +static status_t +joy_control(void * cookie, uint32 iop, void * data, size_t len) +{ + return (*gameport->control_hook)(cookie, iop, data, len); +} + + +static status_t +joy_read(void * cookie, off_t pos, void * data, size_t * nread) +{ + return (*gameport->read_hook)(cookie, pos, data, nread); +} + + +static status_t +joy_write(void * cookie, off_t pos, const void * data, size_t * nwritten) +{ + return (*gameport->write_hook)(cookie, pos, data, nwritten); +} diff --git a/src/add-ons/kernel/drivers/audio/emuxki/joystick_driver.h b/src/add-ons/kernel/drivers/audio/emuxki/joystick_driver.h new file mode 100644 index 0000000000..5c88981f6f --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/emuxki/joystick_driver.h @@ -0,0 +1,113 @@ +/* + Copyright 1999, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ + +#ifndef _JOYSTICK_DRIVER_H +#define _JOYSTICK_DRIVER_H + +#include +#include +#include + +typedef struct _joystick { + bigtime_t timestamp; + uint32 horizontal; + uint32 vertical; + bool button1; + bool button2; +} joystick; + +/* maximum number of axes on one controller (pads count as 2 axes each) */ +#define MAX_AXES 12 +/* maximum number of hats on one controller -- PADS SHOULD BE RETURNED AS AXES! */ +#define MAX_HATS 8 +/* maximum number of buttons on one controller */ +#define MAX_BUTTONS 32 +/* maximum number of controllers on one port */ +#define MAX_STICKS 4 + +typedef struct _extended_joystick { + bigtime_t timestamp; /* system_time when it was read */ + uint32 buttons; /* lsb to msb, 1 == on */ + int16 axes[MAX_AXES]; /* -32768 to 32767, X, Y, Z, U, V, W */ + uint8 hats[MAX_HATS]; /* 0 through 8 (1 == N, 3 == E, 5 == S, 7 == W) */ +} extended_joystick; + +#define MAX_CONFIG_SIZE 100 + +enum { /* flags for joystick module info */ + js_flag_force_feedback = 0x1, + js_flag_force_feedback_directional = 0x2 +}; + +typedef struct _joystick_module_info { + char module_name[64]; + char device_name[64]; + int16 num_axes; + int16 num_buttons; + int16 num_hats; + uint16 _reserved[7]; + uint32 flags; + uint16 num_sticks; + int16 config_size; + char device_config[MAX_CONFIG_SIZE]; /* device specific */ +} joystick_module_info; + +/* Note that joystick_module is something used by the game port driver */ +/* to talk to digital joysticks; if you're writing a sound card driver */ +/* and want to add support for a /dev/joystick device, use the generic_gameport */ +/* module. */ + +typedef struct _joystick_module { + module_info minfo; + /** "configure" might change the "info" if it auto-detects a device */ + int (*configure)(int port, joystick_module_info * info, size_t size, void ** out_cookie); + /** "read" actual data from device into "data" */ + int (*read)(void * cookie, int port, extended_joystick * data, size_t size); + /** "crumble" the cookie (deallocate) when done */ + int (*crumble)(void * cookie, int port); + /** "force" tells the joystick to exert force on the same axes as input for the specified duration */ + int (*force)(void * cookie, int port, bigtime_t duration, extended_joystick * force, size_t size); + int _reserved_; +} joystick_module; + +/** Doing force feedback means writing an extended_joystick to the device with force values. + The "timestamp" should be the duration of the feedback. Successive writes will be queued + by the device module. */ +enum { /* Joystick driver ioctl() opcodes */ + B_JOYSTICK_GET_SPEED_COMPENSATION = B_JOYSTICK_DRIVER_BASE, + /* arg -> ptr to int32 */ + B_JOYSTICK_SET_SPEED_COMPENSATION, /* arg -> ptr to int32 */ + B_JOYSTICK_GET_MAX_LATENCY, /* arg -> ptr to long long */ + B_JOYSTICK_SET_MAX_LATENCY, /* arg -> ptr to long long */ + B_JOYSTICK_SET_DEVICE_MODULE, /* arg -> ptr to joystick_module; also enters enhanced mode */ + B_JOYSTICK_GET_DEVICE_MODULE, /* arg -> ptr to joystick_module */ + B_JOYSTICK_SET_RAW_MODE /* arg -> ptr to bool (true or false) */ +}; + +/* Speed compensation is not generally necessary, because the joystick */ +/* driver is measuring using real time, not just # cycles. "0" means the */ +/* default, center value. + typically returns higher values; - returns lower */ +/* A typical range might be from -10 to +10, but it varies by driver */ + +/* Lower latency will make for more overhead in reading the joystick */ +/* ideally, you set this value to just short of how long it takes you */ +/* to calculate and render a frame. 30 fps -> latency 33000 */ + + +typedef struct _generic_gameport_module { + module_info minfo; + status_t (*create_device)(int port, void ** out_storage); + status_t (*delete_device)(void * storage); + status_t (*open_hook)(void * storage, uint32 flags, void ** out_cookie); + status_t (*close_hook)(void * cookie); + status_t (*free_hook)(void * cookie); + status_t (*control_hook)(void * cookie, uint32 op, void * data, size_t len); + status_t (*read_hook)(void * cookie, off_t pos, void * data, size_t * len); + status_t (*write_hook)(void * cookie, off_t pos, const void * data, size_t * len); + int _reserved_; +} generic_gameport_module; + + +#endif