From 9dd0ef681d495f46cab478cf42a6895efdd72936 Mon Sep 17 00:00:00 2001 From: Gauvain 'GovanifY' Roussel-Tarbouriech Date: Sun, 1 Nov 2020 00:51:21 +0100 Subject: [PATCH] USB: remove initial references for merge --- PCSX2_suite.sln | 23 - cmake/SelectPcsx2Plugins.cmake | 7 - common/include/PS2Edefs.h | 79 +- common/include/PluginCallbacks.h | 2 - pcsx2/Config.h | 1 - pcsx2/PluginManager.cpp | 71 - pcsx2/Plugins.h | 2 - pcsx2/gui/MainFrame.cpp | 1 - pcsx2/gui/SysState.cpp | 1 - plugins/CMakeLists.txt | 4 - plugins/USBnull/CMakeLists.txt | 61 - plugins/USBnull/License.txt | 342 - plugins/USBnull/ReadMe.txt | 34 - plugins/USBnull/USB.cpp | 296 - plugins/USBnull/USB.h | 39 - plugins/USBnull/Windows/ProjectRootDir.props | 15 - plugins/USBnull/Windows/USBnull.def | 29 - plugins/USBnull/Windows/USBnull.vcxproj | 69 - .../USBnull/Windows/USBnull.vcxproj.filters | 37 - plugins/USBqemu/License-qemu.txt | 23 - plugins/USBqemu/License.txt | 342 - plugins/USBqemu/ReadMe.txt | 26 - plugins/USBqemu/USB.cpp | 369 - plugins/USBqemu/USB.h | 65 - plugins/USBqemu/Win32/CfgHelpers.cpp | 159 - plugins/USBqemu/Win32/CfgHelpers.h | 15 - plugins/USBqemu/Win32/Config.cpp | 21 - plugins/USBqemu/Win32/ProjectRootDir.props | 16 - plugins/USBqemu/Win32/USBqemu.def | 24 - plugins/USBqemu/Win32/USBqemu.rc | 159 - plugins/USBqemu/Win32/USBqemu.vcxproj | 107 - plugins/USBqemu/Win32/USBqemu.vcxproj.filters | 97 - plugins/USBqemu/Win32/Win32.cpp | 80 - plugins/USBqemu/Win32/resource.h | 28 - plugins/USBqemu/qemu-usb/USBinternal.h | 289 - plugins/USBqemu/qemu-usb/qemu-queue.h | 449 - plugins/USBqemu/qemu-usb/usb-base.cpp | 351 - plugins/USBqemu/qemu-usb/usb-hid.cpp | 1007 --- plugins/USBqemu/qemu-usb/usb-hub.cpp | 547 -- plugins/USBqemu/qemu-usb/usb-kbd.cpp | 2114 ----- plugins/USBqemu/qemu-usb/usb-msd.cpp | 646 -- plugins/USBqemu/qemu-usb/usb-ohci.cpp | 1512 ---- plugins/USBqemu/qemu-usb/usb.h | 382 - plugins/USBqemu/qemu-usb/vl.cpp | 31 - plugins/USBqemu/qemu-usb/vl.h | 110 - plugins/USBqemu/usb-eyetoy/usb-eyetoy.cpp | 7873 ----------------- plugins/USBqemu/usb-mic/adcuser.h | 30 - plugins/USBqemu/usb-mic/audio.h | 372 - plugins/USBqemu/usb-mic/demo.h | 45 - plugins/USBqemu/usb-mic/type.h | 22 - plugins/USBqemu/usb-mic/usb-mic-dummy.cpp | 431 - plugins/USBqemu/usb-mic/usb-mic.c | 626 -- plugins/USBqemu/usb-mic/usb.h | 230 - plugins/USBqemu/usb-mic/usbcfg.h | 161 - plugins/USBqemu/usb-mic/usbcore.h | 50 - plugins/USBqemu/usb-mic/usbdesc.h | 36 - plugins/USBqemu/usb-mic/usbhw.h | 107 - plugins/USBqemu/usb-mic/usbreg.h | 195 - plugins/USBqemu/usb-mic/usbuser.h | 74 - 59 files changed, 1 insertion(+), 20333 deletions(-) delete mode 100644 plugins/USBnull/CMakeLists.txt delete mode 100644 plugins/USBnull/License.txt delete mode 100644 plugins/USBnull/ReadMe.txt delete mode 100644 plugins/USBnull/USB.cpp delete mode 100644 plugins/USBnull/USB.h delete mode 100644 plugins/USBnull/Windows/ProjectRootDir.props delete mode 100644 plugins/USBnull/Windows/USBnull.def delete mode 100644 plugins/USBnull/Windows/USBnull.vcxproj delete mode 100644 plugins/USBnull/Windows/USBnull.vcxproj.filters delete mode 100644 plugins/USBqemu/License-qemu.txt delete mode 100644 plugins/USBqemu/License.txt delete mode 100644 plugins/USBqemu/ReadMe.txt delete mode 100644 plugins/USBqemu/USB.cpp delete mode 100644 plugins/USBqemu/USB.h delete mode 100644 plugins/USBqemu/Win32/CfgHelpers.cpp delete mode 100644 plugins/USBqemu/Win32/CfgHelpers.h delete mode 100644 plugins/USBqemu/Win32/Config.cpp delete mode 100644 plugins/USBqemu/Win32/ProjectRootDir.props delete mode 100644 plugins/USBqemu/Win32/USBqemu.def delete mode 100644 plugins/USBqemu/Win32/USBqemu.rc delete mode 100644 plugins/USBqemu/Win32/USBqemu.vcxproj delete mode 100644 plugins/USBqemu/Win32/USBqemu.vcxproj.filters delete mode 100644 plugins/USBqemu/Win32/Win32.cpp delete mode 100644 plugins/USBqemu/Win32/resource.h delete mode 100644 plugins/USBqemu/qemu-usb/USBinternal.h delete mode 100644 plugins/USBqemu/qemu-usb/qemu-queue.h delete mode 100644 plugins/USBqemu/qemu-usb/usb-base.cpp delete mode 100644 plugins/USBqemu/qemu-usb/usb-hid.cpp delete mode 100644 plugins/USBqemu/qemu-usb/usb-hub.cpp delete mode 100644 plugins/USBqemu/qemu-usb/usb-kbd.cpp delete mode 100644 plugins/USBqemu/qemu-usb/usb-msd.cpp delete mode 100644 plugins/USBqemu/qemu-usb/usb-ohci.cpp delete mode 100644 plugins/USBqemu/qemu-usb/usb.h delete mode 100644 plugins/USBqemu/qemu-usb/vl.cpp delete mode 100644 plugins/USBqemu/qemu-usb/vl.h delete mode 100644 plugins/USBqemu/usb-eyetoy/usb-eyetoy.cpp delete mode 100644 plugins/USBqemu/usb-mic/adcuser.h delete mode 100644 plugins/USBqemu/usb-mic/audio.h delete mode 100644 plugins/USBqemu/usb-mic/demo.h delete mode 100644 plugins/USBqemu/usb-mic/type.h delete mode 100644 plugins/USBqemu/usb-mic/usb-mic-dummy.cpp delete mode 100644 plugins/USBqemu/usb-mic/usb-mic.c delete mode 100644 plugins/USBqemu/usb-mic/usb.h delete mode 100644 plugins/USBqemu/usb-mic/usbcfg.h delete mode 100644 plugins/USBqemu/usb-mic/usbcore.h delete mode 100644 plugins/USBqemu/usb-mic/usbdesc.h delete mode 100644 plugins/USBqemu/usb-mic/usbhw.h delete mode 100644 plugins/USBqemu/usb-mic/usbreg.h delete mode 100644 plugins/USBqemu/usb-mic/usbuser.h diff --git a/PCSX2_suite.sln b/PCSX2_suite.sln index 6b811d7329..ce70ca52d1 100644 --- a/PCSX2_suite.sln +++ b/PCSX2_suite.sln @@ -44,8 +44,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "3rdparty\zlib\zlib. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LilyPad", "plugins\LilyPad\LilyPad.vcxproj", "{E4081455-398C-4610-A87C-90A8A7D72DC3}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "USBnull", "plugins\USBnull\Windows\USBnull.vcxproj", "{BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "x86emitter", "common\build\x86emitter\x86emitter.vcxproj", "{A51123F5-9505-4EAE-85E7-D320290A272C}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "utilities", "common\build\Utilities\utilities.vcxproj", "{4639972E-424E-4E13-8B07-CA403C481346}" @@ -192,26 +190,6 @@ Global {E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|Win32.Build.0 = Release|Win32 {E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|x64.ActiveCfg = Release|x64 {E4081455-398C-4610-A87C-90A8A7D72DC3}.Release|x64.Build.0 = Release|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Debug|Win32.ActiveCfg = Debug|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Debug|Win32.Build.0 = Debug|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Debug|x64.ActiveCfg = Debug|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Debug|x64.Build.0 = Debug|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Devel|Win32.ActiveCfg = Release|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Devel|Win32.Build.0 = Release|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Devel|x64.ActiveCfg = Release|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Devel|x64.Build.0 = Release|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release AVX2|Win32.ActiveCfg = Release|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release AVX2|Win32.Build.0 = Release|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release AVX2|x64.ActiveCfg = Release|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release AVX2|x64.Build.0 = Release|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release SSE4|Win32.ActiveCfg = Release|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release SSE4|Win32.Build.0 = Release|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release SSE4|x64.ActiveCfg = Release|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release SSE4|x64.Build.0 = Release|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release|Win32.ActiveCfg = Release|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release|Win32.Build.0 = Release|Win32 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release|x64.ActiveCfg = Release|x64 - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70}.Release|x64.Build.0 = Release|x64 {A51123F5-9505-4EAE-85E7-D320290A272C}.Debug|Win32.ActiveCfg = Debug|Win32 {A51123F5-9505-4EAE-85E7-D320290A272C}.Debug|Win32.Build.0 = Debug|Win32 {A51123F5-9505-4EAE-85E7-D320290A272C}.Debug|x64.ActiveCfg = Debug|x64 @@ -524,7 +502,6 @@ Global {E9B51944-7E6D-4BCD-83F2-7BBD5A46182D} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38} {2F6C0388-20CB-4242-9F6C-A6EBB6A83F47} = {78EBE642-7A4D-4EA7-86BE-5639C6646C38} {E4081455-398C-4610-A87C-90A8A7D72DC3} = {703FD00B-D7A0-41E3-BD03-CEC86B385DAF} - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70} = {E1828E40-2FBB-48FE-AE7F-5587755DCE0E} {A51123F5-9505-4EAE-85E7-D320290A272C} = {88F517F9-CE1C-4005-9BDF-4481FEB55053} {4639972E-424E-4E13-8B07-CA403C481346} = {88F517F9-CE1C-4005-9BDF-4481FEB55053} {677B7D11-D5E1-40B3-88B1-9A4DF83D2213} = {2D6F0A62-A247-4CCF-947F-FCD54BE16103} diff --git a/cmake/SelectPcsx2Plugins.cmake b/cmake/SelectPcsx2Plugins.cmake index c3aa573828..7f6dfd2058 100644 --- a/cmake/SelectPcsx2Plugins.cmake +++ b/cmake/SelectPcsx2Plugins.cmake @@ -155,11 +155,4 @@ else() endif() #--------------------------------------- -#--------------------------------------- -# USBnull -#--------------------------------------- -if(GTKn_FOUND) - set(USBnull TRUE) -endif() -#--------------------------------------- #------------------------------------------------------------------------------- diff --git a/common/include/PS2Edefs.h b/common/include/PS2Edefs.h index 559ed6e62b..acd0ebca82 100644 --- a/common/include/PS2Edefs.h +++ b/common/include/PS2Edefs.h @@ -73,21 +73,18 @@ typedef struct _keyEvent /////////////////////////////////////////////////////////////////////// -#if defined(GSdefs) || defined(PADdefs) || defined(SIOdefs) || \ - defined(USBdefs) +#if defined(GSdefs) || defined(PADdefs) || defined(SIOdefs) #define COMMONdefs #endif // PS2EgetLibType returns (may be OR'd) #define PS2E_LT_GS 0x01 #define PS2E_LT_PAD 0x02 // -=[ OBSOLETE ]=- -#define PS2E_LT_USB 0x20 #define PS2E_LT_SIO 0x80 // PS2EgetLibVersion2 (high 16 bits) #define PS2E_GS_VERSION 0x0006 #define PS2E_PAD_VERSION 0x0002 // -=[ OBSOLETE ]=- -#define PS2E_USB_VERSION 0x0003 #define PS2E_SIO_VERSION 0x0001 #ifdef COMMONdefs @@ -122,9 +119,6 @@ typedef char __keyEvent_Size__[(sizeof(keyEvent) == 8) ? 1 : -1]; typedef int(CALLBACK *SIOchangeSlotCB)(int slot); -typedef void (*USBcallback)(int cycles); -typedef int (*USBhandler)(void); - typedef struct _GSdriverInfo { char name[8]; @@ -240,44 +234,6 @@ s32 CALLBACK PADtest(); #endif -/* USB plugin API */ - -// if this file is included with this define -// the next api will not be skipped by the compiler -#if defined(USBdefs) || defined(BUILTIN_USB_PLUGIN) - -// basic funcs - -s32 CALLBACK USBinit(); -s32 CALLBACK USBopen(void *pDsp); -void CALLBACK USBclose(); -void CALLBACK USBshutdown(); -void CALLBACK USBsetSettingsDir(const char *dir); -void CALLBACK USBsetLogDir(const char *dir); - -u8 CALLBACK USBread8(u32 addr); -u16 CALLBACK USBread16(u32 addr); -u32 CALLBACK USBread32(u32 addr); -void CALLBACK USBwrite8(u32 addr, u8 value); -void CALLBACK USBwrite16(u32 addr, u16 value); -void CALLBACK USBwrite32(u32 addr, u32 value); -void CALLBACK USBasync(u32 cycles); - -// cycles = IOP cycles before calling callback, -// if callback returns 1 the irq is triggered, else not -void CALLBACK USBirqCallback(USBcallback callback); -USBhandler CALLBACK USBirqHandler(void); -void CALLBACK USBsetRAM(void *mem); - -// extended funcs - -s32 CALLBACK USBfreeze(int mode, freezeData *data); -void CALLBACK USBconfigure(); -void CALLBACK USBabout(); -s32 CALLBACK USBtest(); - -#endif - // might be useful for emulators #ifdef PLUGINtypedefs @@ -330,23 +286,6 @@ typedef s32(CALLBACK *_PADsetSlot)(u8 port, u8 slot); typedef s32(CALLBACK *_PADqueryMtap)(u8 port); typedef void(CALLBACK *_PADWriteEvent)(keyEvent &evt); -// USB -// NOTE: The read/write functions CANNOT use XMM/MMX regs -// If you want to use them, need to save and restore current ones -typedef s32(CALLBACK *_USBopen)(void *pDsp); -typedef u8(CALLBACK *_USBread8)(u32 mem); -typedef u16(CALLBACK *_USBread16)(u32 mem); -typedef u32(CALLBACK *_USBread32)(u32 mem); -typedef void(CALLBACK *_USBwrite8)(u32 mem, u8 value); -typedef void(CALLBACK *_USBwrite16)(u32 mem, u16 value); -typedef void(CALLBACK *_USBwrite32)(u32 mem, u32 value); -typedef void(CALLBACK *_USBasync)(u32 cycles); - -typedef void(CALLBACK *_USBirqCallback)(USBcallback callback); -typedef USBhandler(CALLBACK *_USBirqHandler)(void); -typedef void(CALLBACK *_USBsetRAM)(void *mem); -#endif - #ifdef PLUGINfuncs // GS @@ -394,22 +333,6 @@ extern _PADqueryMtap PADqueryMtap; extern _PADWriteEvent PADWriteEvent; #endif -// USB -#ifndef BUILTIN_USB_PLUGIN -extern _USBopen USBopen; -extern _USBread8 USBread8; -extern _USBread16 USBread16; -extern _USBread32 USBread32; -extern _USBwrite8 USBwrite8; -extern _USBwrite16 USBwrite16; -extern _USBwrite32 USBwrite32; -extern _USBasync USBasync; - -extern _USBirqCallback USBirqCallback; -extern _USBirqHandler USBirqHandler; -extern _USBsetRAM USBsetRAM; -#endif - #endif #ifdef __cplusplus diff --git a/common/include/PluginCallbacks.h b/common/include/PluginCallbacks.h index b1384dfc42..8bbd192ca3 100644 --- a/common/include/PluginCallbacks.h +++ b/common/include/PluginCallbacks.h @@ -177,7 +177,6 @@ extern "C" { enum PS2E_ComponentTypes { PS2E_TYPE_GS = 0, PS2E_TYPE_PAD, - PS2E_TYPE_USB, PS2E_TYPE_SIO, PS2E_TYPE_Mcd, }; @@ -185,7 +184,6 @@ enum PS2E_ComponentTypes { enum PluginLibVersion { PS2E_VER_GS = 0x1000, PS2E_VER_PAD = 0x1000, - PS2E_VER_USB = 0x1000, PS2E_VER_SIO = 0x1000 }; diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 071196bf2e..efda99347c 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -23,7 +23,6 @@ enum PluginsEnum_t { PluginId_GS = 0, PluginId_PAD, - PluginId_USB, PluginId_Count, // Memorycard plugin support is preliminary, and is only hacked/hardcoded in at this diff --git a/pcsx2/PluginManager.cpp b/pcsx2/PluginManager.cpp index e42d4f0e0f..0675d8fc81 100644 --- a/pcsx2/PluginManager.cpp +++ b/pcsx2/PluginManager.cpp @@ -81,7 +81,6 @@ const PluginInfo tbl_PluginInfo[] = { { "GS", PluginId_GS, PS2E_LT_GS, PS2E_GS_VERSION }, { "PAD", PluginId_PAD, PS2E_LT_PAD, PS2E_PAD_VERSION }, - { "USB", PluginId_USB, PS2E_LT_USB, PS2E_USB_VERSION }, { NULL }, @@ -272,23 +271,6 @@ _PADWriteEvent PADWriteEvent; static void PAD_update( u32 padslot ) { } -// USB -#ifndef BUILTIN_USB_PLUGIN -_USBopen USBopen; -_USBread8 USBread8; -_USBread16 USBread16; -_USBread32 USBread32; -_USBwrite8 USBwrite8; -_USBwrite16 USBwrite16; -_USBwrite32 USBwrite32; -_USBasync USBasync; - -_USBirqCallback USBirqCallback; -_USBirqHandler USBirqHandler; -_USBsetRAM USBsetRAM; -#endif - -USBhandler usbHandler; uptr pDsp[2]; static s32 CALLBACK _hack_PADinit() @@ -390,42 +372,16 @@ static const LegacyApi_OptMethod s_MethMessOpt_PAD[] = { NULL }, }; -// ---------------------------------------------------------------------------- -// USB Mess! -// ---------------------------------------------------------------------------- -static const LegacyApi_ReqMethod s_MethMessReq_USB[] = -{ - { "USBopen", (vMeth**)&USBopen, NULL }, - { "USBread8", (vMeth**)&USBread8, NULL }, - { "USBread16", (vMeth**)&USBread16, NULL }, - { "USBread32", (vMeth**)&USBread32, NULL }, - { "USBwrite8", (vMeth**)&USBwrite8, NULL }, - { "USBwrite16", (vMeth**)&USBwrite16, NULL }, - { "USBwrite32", (vMeth**)&USBwrite32, NULL }, - { "USBirqCallback", (vMeth**)&USBirqCallback, NULL }, - { "USBirqHandler", (vMeth**)&USBirqHandler, NULL }, - { NULL } -}; - -static const LegacyApi_OptMethod s_MethMessOpt_USB[] = -{ - { "USBasync", (vMeth**)&USBasync }, - { "USBsetRAM", (vMeth**)&USBsetRAM }, - { NULL } -}; - static const LegacyApi_ReqMethod* const s_MethMessReq[] = { s_MethMessReq_GS, s_MethMessReq_PAD, - s_MethMessReq_USB, }; static const LegacyApi_OptMethod* const s_MethMessOpt[] = { s_MethMessOpt_GS, s_MethMessOpt_PAD, - s_MethMessOpt_USB, }; SysCorePlugins *g_plugins = NULL; @@ -588,10 +544,6 @@ void* StaticLibrary::GetSymbol(const wxString &name) #ifdef BUILTIN_PAD_PLUGIN RETURN_COMMON_SYMBOL(PAD); #endif -#ifdef BUILTIN_USB_PLUGIN - RETURN_COMMON_SYMBOL(USB); -#endif - #undef RETURN_COMMON_SYMBOL #undef RETURN_SYMBOL @@ -645,9 +597,6 @@ SysCorePlugins::PluginStatus_t::PluginStatus_t( PluginsEnum_t _pid, const wxStri #endif #ifdef BUILTIN_PAD_PLUGIN case PluginId_PAD: -#endif -#ifdef BUILTIN_USB_PLUGIN - case PluginId_USB: #endif case PluginId_Count: IsStatic = true; @@ -915,19 +864,6 @@ bool SysCorePlugins::OpenPlugin_PAD() return !PADopen( (void*)pDsp ); } -bool SysCorePlugins::OpenPlugin_USB() -{ - usbHandler = NULL; - - if( USBopen((void*)pDsp) ) return false; - USBirqCallback( usbIrq ); - usbHandler = USBirqHandler(); - // iopMem is not initialized yet. Moved elsewhere - //if( USBsetRAM != NULL ) - // USBsetRAM(iopMem->Main); - return true; -} - bool SysCorePlugins::OpenPlugin_Mcd() { ScopedLock lock( m_mtx_PluginStatus ); @@ -953,7 +889,6 @@ void SysCorePlugins::Open( PluginsEnum_t pid ) { case PluginId_GS: result = OpenPlugin_GS(); break; case PluginId_PAD: result = OpenPlugin_PAD(); break; - case PluginId_USB: result = OpenPlugin_USB(); break; jNO_DEFAULT; } @@ -1025,11 +960,6 @@ void SysCorePlugins::ClosePlugin_PAD() _generalclose( PluginId_PAD ); } -void SysCorePlugins::ClosePlugin_USB() -{ - _generalclose( PluginId_USB ); -} - void SysCorePlugins::ClosePlugin_Mcd() { ScopedLock lock( m_mtx_PluginStatus ); @@ -1049,7 +979,6 @@ void SysCorePlugins::Close( PluginsEnum_t pid ) { case PluginId_GS: ClosePlugin_GS(); break; case PluginId_PAD: ClosePlugin_PAD(); break; - case PluginId_USB: ClosePlugin_USB(); break; case PluginId_Mcd: ClosePlugin_Mcd(); break; jNO_DEFAULT; diff --git a/pcsx2/Plugins.h b/pcsx2/Plugins.h index d7b99f032e..f959a0caad 100644 --- a/pcsx2/Plugins.h +++ b/pcsx2/Plugins.h @@ -402,14 +402,12 @@ protected: virtual bool OpenPlugin_GS(); virtual bool OpenPlugin_PAD(); - virtual bool OpenPlugin_USB(); virtual bool OpenPlugin_Mcd(); void _generalclose( PluginsEnum_t pid ); virtual void ClosePlugin_GS(); virtual void ClosePlugin_PAD(); - virtual void ClosePlugin_USB(); virtual void ClosePlugin_Mcd(); friend class SysMtgsThread; diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index bd2045e1ec..ea02e61aaf 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -446,7 +446,6 @@ void MainEmuFrame::CreateConfigMenu() m_menuConfig.Append(MenuId_Config_GS, _("&Video (GS)"), m_PluginMenuPacks[PluginId_GS]); m_menuConfig.Append(MenuId_Config_PAD, _("&Controllers (PAD)"), m_PluginMenuPacks[PluginId_PAD]); - m_menuConfig.Append(MenuId_Config_USB, _("&USB"), m_PluginMenuPacks[PluginId_USB]); m_menuConfig.AppendSeparator(); m_menuConfig.Append(MenuId_Config_Multitap0Toggle, _("Multitap &1"), wxEmptyString, wxITEM_CHECK); diff --git a/pcsx2/gui/SysState.cpp b/pcsx2/gui/SysState.cpp index ea8ca848f6..22a1148711 100644 --- a/pcsx2/gui/SysState.cpp +++ b/pcsx2/gui/SysState.cpp @@ -289,7 +289,6 @@ static const std::unique_ptr SavestateEntries[] = { std::unique_ptr(new PluginSavestateEntry(PluginId_GS)), std::unique_ptr(new PluginSavestateEntry(PluginId_PAD)), - std::unique_ptr(new PluginSavestateEntry(PluginId_USB)), }; // It's bad mojo to have savestates trying to read and write from the same file at the diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 095f0bdc0e..6c69b4694a 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -29,7 +29,3 @@ endif() if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/PadNull" AND PadNull) add_subdirectory(PadNull) endif() - -if(EXISTS "${CMAKE_SOURCE_DIR}/plugins/USBnull" AND USBnull) - add_subdirectory(USBnull) -endif() diff --git a/plugins/USBnull/CMakeLists.txt b/plugins/USBnull/CMakeLists.txt deleted file mode 100644 index f37d2cfc03..0000000000 --- a/plugins/USBnull/CMakeLists.txt +++ /dev/null @@ -1,61 +0,0 @@ -# Check that people use the good file -if(NOT TOP_CMAKE_WAS_SOURCED) - message(FATAL_ERROR " - You did not 'cmake' the good CMakeLists.txt file. Use the one in the top dir. - It is advice to delete all wrongly generated cmake stuff => CMakeFiles & CMakeCache.txt") -endif() - - -# plugin name -set(Output USBnull-0.7.0) - -set(USBnullFinalFlags --fvisibility=hidden --Wall --Wno-parentheses - ) - -# USBnull sources -set(USBnullSources - USB.cpp) - -# USBnull headers -set(USBnullHeaders - USB.h) - -# USBnull Linux sources -set(USBnullLinuxSources -) - -# USBnull Linux headers -set(USBnullLinuxHeaders -) - -# USBnull Windows sources -set(USBnullWindowsSources - Windows/USBnull.def -) - -# USBnull Windows headers -set(USBnullWindowsHeaders -) - -set(USBnullFinalSources - ${USBnullSources} - ${USBnullHeaders} - ${USBnullLinuxSources} - ${USBnullLinuxHeaders} -) - -set(USBnullFinalLibs - ${GTK2_LIBRARIES} - ${wxWidgets_LIBRARIES} -) - -if(BUILTIN_USB) - add_pcsx2_lib(${Output} "${USBnullFinalSources}" "${USBnullFinalLibs}" "${USBnullFinalFlags}") -else() - add_pcsx2_plugin(${Output} "${USBnullFinalSources}" "${USBnullFinalLibs}" "${USBnullFinalFlags}") -endif() - -target_compile_features(${Output} PRIVATE cxx_std_17) \ No newline at end of file diff --git a/plugins/USBnull/License.txt b/plugins/USBnull/License.txt deleted file mode 100644 index bb0a0ce0eb..0000000000 --- a/plugins/USBnull/License.txt +++ /dev/null @@ -1,342 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - - diff --git a/plugins/USBnull/ReadMe.txt b/plugins/USBnull/ReadMe.txt deleted file mode 100644 index f8a9b564c6..0000000000 --- a/plugins/USBnull/ReadMe.txt +++ /dev/null @@ -1,34 +0,0 @@ -USBnull v0.4 -------------- - - This is an extension to use with play station2 emulators - as PCSX2 (only one right now). - The plugin is free open source code. - -Usage: ------ - Place the file "usbnull.dll" (win32) or usbnull.dll (win64) - at the Plugin directory of the Emulator to use it. - -Changes: -------- - v0.4: -*project files for vs2005 beta1 .64bit dll should work okay (not tested!) - - v0.3: - *up to pcsx2 specs 0.5.5 - *added ini and option for logging - *small adds around.. - - v0.2: - * First Release - * Tested with Pcsx2 - -Authors: -------- - -shadow - - - - diff --git a/plugins/USBnull/USB.cpp b/plugins/USBnull/USB.cpp deleted file mode 100644 index 69b4ba126f..0000000000 --- a/plugins/USBnull/USB.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/* USBnull - * Copyright (C) 2002-2010 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include -#include -#include "svnrev.h" -#include "USB.h" -#include "null/config.inl" - -std::string s_strIniPath = "inis"; -std::string s_strLogPath = "logs"; - -const unsigned char version = PS2E_USB_VERSION; -const unsigned char revision = 0; -const unsigned char build = 7; // increase that with each version - -static char libraryName[256]; - -USBcallback USBirq; - -s8 *usbregs, *ram; - -EXPORT_C_(void) -USBconfigure() -{ - const std::string ini_path = s_strIniPath + "/USBnull.ini"; - LoadConfig(ini_path); - ConfigureLogging(); - SaveConfig(ini_path); -} - -void LogInit() -{ - const std::string LogFile(s_strLogPath + "/USBnull.log"); - g_plugin_log.Open(LogFile); -} - -EXPORT_C_(void) -USBsetLogDir(const char *dir) -{ - // Get the path to the log directory. - s_strLogPath = (dir == NULL) ? "logs" : dir; - - // Reload the log file after updated the path - g_plugin_log.Close(); - LogInit(); -} - -EXPORT_C_(u32) -PS2EgetLibType() -{ - return PS2E_LT_USB; -} - -EXPORT_C_(const char *) -PS2EgetLibName() -{ - snprintf(libraryName, 255, "USBnull Driver %lld%s", SVN_REV, SVN_MODS ? "m" : ""); - return libraryName; -} - -EXPORT_C_(u32) -PS2EgetLibVersion2(u32 type) -{ - return (version << 16) | (revision << 8) | build; -} - -EXPORT_C_(s32) -USBinit() -{ - LoadConfig(s_strIniPath + "/USBnull.ini"); - LogInit(); - g_plugin_log.WriteLn("USBnull plugin version %d,%d", revision, build); - g_plugin_log.WriteLn("Initializing USBnull"); - - // Initialize memory structures here. - usbregs = (s8 *)calloc(0x10000, 1); - - if (usbregs == NULL) { - g_plugin_log.Message("Error allocating memory"); - return -1; - } - - return 0; -} - -EXPORT_C_(void) -USBshutdown() -{ - // Yes, we close things in the Shutdown routine, and - // don't do anything in the close routine. - g_plugin_log.Close(); - - free(usbregs); - usbregs = NULL; -} - -EXPORT_C_(s32) -USBopen(void *pDsp) -{ - g_plugin_log.WriteLn("Opening USBnull."); - - // Take care of anything else we need on opening, other then initialization. - return 0; -} - -EXPORT_C_(void) -USBclose() -{ - g_plugin_log.WriteLn("Closing USBnull."); -} - -// Note: actually uncommenting the read/write functions I provided here -// caused uLauncher.elf to hang on startup, so careful when experimenting. -EXPORT_C_(u8) -USBread8(u32 addr) -{ - u8 value = 0; - - switch (addr) { - // Handle any appropriate addresses here. - case 0x1f801600: - g_plugin_log.WriteLn("(USBnull) 8 bit read at address %lx", addr); - break; - - default: - //value = usbRu8(addr); - g_plugin_log.WriteLn("*(USBnull) 8 bit read at address %lx", addr); - break; - } - return value; -} - -EXPORT_C_(u16) -USBread16(u32 addr) -{ - u16 value = 0; - - switch (addr) { - // Handle any appropriate addresses here. - case 0x1f801600: - g_plugin_log.WriteLn("(USBnull) 16 bit read at address %lx", addr); - break; - - default: - //value = usbRu16(addr); - g_plugin_log.WriteLn("(USBnull) 16 bit read at address %lx", addr); - } - return value; -} - -EXPORT_C_(u32) -USBread32(u32 addr) -{ - u32 value = 0; - - switch (addr) { - // Handle any appropriate addresses here. - case 0x1f801600: - g_plugin_log.WriteLn("(USBnull) 32 bit read at address %lx", addr); - break; - - default: - //value = usbRu32(addr); - g_plugin_log.WriteLn("(USBnull) 32 bit read at address %lx", addr); - } - return value; -} - -EXPORT_C_(void) -USBwrite8(u32 addr, u8 value) -{ - switch (addr) { - // Handle any appropriate addresses here. - case 0x1f801600: - g_plugin_log.WriteLn("(USBnull) 8 bit write at address %lx value %x", addr, value); - break; - - default: - //usbRu8(addr) = value; - g_plugin_log.WriteLn("(USBnull) 8 bit write at address %lx value %x", addr, value); - } -} - -EXPORT_C_(void) -USBwrite16(u32 addr, u16 value) -{ - switch (addr) { - // Handle any appropriate addresses here. - case 0x1f801600: - g_plugin_log.WriteLn("(USBnull) 16 bit write at address %lx value %x", addr, value); - break; - - default: - //usbRu16(addr) = value; - g_plugin_log.WriteLn("(USBnull) 16 bit write at address %lx value %x", addr, value); - } -} - -EXPORT_C_(void) -USBwrite32(u32 addr, u32 value) -{ - switch (addr) { - // Handle any appropriate addresses here. - case 0x1f801600: - g_plugin_log.WriteLn("(USBnull) 16 bit write at address %lx value %x", addr, value); - break; - - default: - //usbRu32(addr) = value; - g_plugin_log.WriteLn("(USBnull) 32 bit write at address %lx value %x", addr, value); - } -} - -EXPORT_C_(void) -USBirqCallback(USBcallback callback) -{ - // Register USBirq, so we can trigger an interrupt with it later. - // It will be called as USBirq(cycles); where cycles is the number - // of cycles before the irq is triggered. - USBirq = callback; -} - -EXPORT_C_(int) -_USBirqHandler(void) -{ - // This is our USB irq handler, so if an interrupt gets triggered, - // deal with it here. - return 0; -} - -EXPORT_C_(USBhandler) -USBirqHandler(void) -{ - // Pass our handler to pcsx2. - return (USBhandler)_USBirqHandler; -} - -EXPORT_C_(void) -USBsetRAM(void *mem) -{ - ram = (s8 *)mem; - g_plugin_log.WriteLn("*Setting ram."); -} - -EXPORT_C_(void) -USBsetSettingsDir(const char *dir) -{ - // Get the path to the ini directory. - s_strIniPath = (dir == NULL) ? "inis" : dir; -} - -// extended funcs - -EXPORT_C_(s32) -USBfreeze(int mode, freezeData *data) -{ - // This should store or retrieve any information, for if emulation - // gets suspended, or for savestates. - switch (mode) { - case FREEZE_LOAD: - // Load previously saved data. - break; - case FREEZE_SAVE: - // Save data. - break; - case FREEZE_SIZE: - // return the size of the data. - break; - } - return 0; -} - -/*EXPORT_C_(void) USBasync(u32 cycles) -{ - // Optional function: Called in IopCounter.cpp. -}*/ - -EXPORT_C_(s32) -USBtest() -{ - // 0 if the plugin works, non-0 if it doesn't. - return 0; -} diff --git a/plugins/USBnull/USB.h b/plugins/USBnull/USB.h deleted file mode 100644 index a7be9fadcb..0000000000 --- a/plugins/USBnull/USB.h +++ /dev/null @@ -1,39 +0,0 @@ -/* USBnull - * Copyright (C) 2002-2010 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#ifndef __USB_H__ -#define __USB_H__ - -#include - -#define USBdefs -#include "PS2Edefs.h" -#include "PS2Eext.h" - -extern USBcallback USBirq; - -// Previous USB plugins have needed this in ohci. -static const s64 PSXCLK = 36864000; /* 36.864 Mhz */ - -extern s8 *usbregs, *ram; - -#define usbRs8(mem) usbregs[(mem)&0xffff] -#define usbRs16(mem) (*(s16 *)&usbregs[(mem)&0xffff]) -#define usbRs32(mem) (*(s32 *)&usbregs[(mem)&0xffff]) -#define usbRu8(mem) (*(u8 *)&usbregs[(mem)&0xffff]) -#define usbRu16(mem) (*(u16 *)&usbregs[(mem)&0xffff]) -#define usbRu32(mem) (*(u32 *)&usbregs[(mem)&0xffff]) - -#endif diff --git a/plugins/USBnull/Windows/ProjectRootDir.props b/plugins/USBnull/Windows/ProjectRootDir.props deleted file mode 100644 index 423e907385..0000000000 --- a/plugins/USBnull/Windows/ProjectRootDir.props +++ /dev/null @@ -1,15 +0,0 @@ - - - - $(ProjectRootDir)\..\.. - $(SvnRootDir)\common - - - <_ProjectFileVersion>10.0.30128.1 - - - - $(SvnRootDir) - - - \ No newline at end of file diff --git a/plugins/USBnull/Windows/USBnull.def b/plugins/USBnull/Windows/USBnull.def deleted file mode 100644 index 7a7e579f6d..0000000000 --- a/plugins/USBnull/Windows/USBnull.def +++ /dev/null @@ -1,29 +0,0 @@ -; USBlinuz.def : Declares the module parameters for the DLL. - -;LIBRARY "USBnull" -;DESCRIPTION 'USBnull Driver' - -EXPORTS - ; Explicit exports can go here - PS2EgetLibType @2 - PS2EgetLibName @3 - PS2EgetLibVersion2 @4 - USBinit @5 - USBshutdown @6 - USBopen @7 - USBclose @8 - USBread8 @9 - USBread16 @10 - USBread32 @11 - USBwrite8 @12 - USBwrite16 @13 - USBwrite32 @14 - USBirqCallback @15 - USBirqHandler @16 - USBsetRAM @17 - - USBconfigure @18 - USBtest @19 - - USBsetSettingsDir - USBsetLogDir diff --git a/plugins/USBnull/Windows/USBnull.vcxproj b/plugins/USBnull/Windows/USBnull.vcxproj deleted file mode 100644 index 489224c73a..0000000000 --- a/plugins/USBnull/Windows/USBnull.vcxproj +++ /dev/null @@ -1,69 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - {BF7B81A5-E348-4F7C-A69F-F74C8EEEAD70} - - - - DynamicLibrary - $(DefaultPlatformToolset) - MultiByte - true - true - false - - - - - - - - - - - - - - AllRules.ruleset - - - - USBnull.def - MachineX86 - MachineX64 - - - - - - - - - - - - - - - - - diff --git a/plugins/USBnull/Windows/USBnull.vcxproj.filters b/plugins/USBnull/Windows/USBnull.vcxproj.filters deleted file mode 100644 index 90257927f9..0000000000 --- a/plugins/USBnull/Windows/USBnull.vcxproj.filters +++ /dev/null @@ -1,37 +0,0 @@ - - - - - {94a66e11-75eb-4a79-a044-b78e97a6ccc3} - cpp;c;cxx;def;odl;idl;hpj;bat;asm - - - {2790b344-7a1a-45ef-9a16-0dd847d6de56} - h;hpp;hxx;hm;inl;inc - - - {bf432076-1764-488d-84b7-82e00f408011} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - - - Header Files - - - - - Resource Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/plugins/USBqemu/License-qemu.txt b/plugins/USBqemu/License-qemu.txt deleted file mode 100644 index 492bdd8732..0000000000 --- a/plugins/USBqemu/License-qemu.txt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * QEMU USB emulation - * - * Copyright (c) 2005 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ diff --git a/plugins/USBqemu/License.txt b/plugins/USBqemu/License.txt deleted file mode 100644 index bb0a0ce0eb..0000000000 --- a/plugins/USBqemu/License.txt +++ /dev/null @@ -1,342 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - - diff --git a/plugins/USBqemu/ReadMe.txt b/plugins/USBqemu/ReadMe.txt deleted file mode 100644 index 241c2199ab..0000000000 --- a/plugins/USBqemu/ReadMe.txt +++ /dev/null @@ -1,26 +0,0 @@ -USBlinuz v0.1 -------------- - - This is an extension to use with play station2 emulators - as PCSX2 (only one right now). - The plugin is free open source code. - -Usage: ------ - Place the file "usblinuz.dll" (win32) or usblinuz_64.dll (win64) - at the Plugin directory of the Emulator to use it. - -Changes: -------- -v0.1 (gigaherz) - * First Release - * Tested with Pcsx2 32 and 64bit - -Authors: -------- - - linuzappz - shadow - - - diff --git a/plugins/USBqemu/USB.cpp b/plugins/USBqemu/USB.cpp deleted file mode 100644 index d52cf4c6c6..0000000000 --- a/plugins/USBqemu/USB.cpp +++ /dev/null @@ -1,369 +0,0 @@ -/* USBqemu - * Copyright (C) 2002-2011 PCSX2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "qemu-usb/USBinternal.h" - -#ifdef _MSC_VER -# include "svnrev.h" -#endif - -const unsigned char version = PS2E_USB_VERSION; -const unsigned char revision = 0; -const unsigned char build = 1; // increase that with each version - -// PCSX2 expects ASNI, not unicode, so this MUST always be char... -static char libraryName[256]; - -OHCIState *qemu_ohci; - -Config conf; - -HWND gsWindowHandle=NULL; - -u8 *ram; -USBcallback _USBirq; -FILE *usbLog; -int64_t usb_frame_time=0; -int64_t usb_bit_time=0; - -s64 clocks=0; -s64 remaining=0; - -int64_t get_ticks_per_sec() -{ - return PSXCLK; -} - -void __Log(char *fmt, ...) { - va_list list; - - if (!conf.Log) return; - - va_start(list, fmt); - vfprintf(usbLog, fmt, list); - va_end(list); -} - -static void InitLibraryName() -{ -#ifdef USBQEMU_PUBLIC_RELEASE - - // Public Release! - // Output a simplified string that's just our name: - - strcpy( libraryName, "USBqemu" ); - -#else - #ifdef SVN_REV_UNKNOWN - - // Unknown revision. - // Output a name that includes devbuild status but not - // subversion revision tags: - - strcpy( libraryName, "USBqemu" - #ifdef DEBUG_FAST - "-Debug" - #elif defined( PCSX2_DEBUG ) - "-Debug/Strict" // strict debugging is slow! - #elif defined( PCSX2_DEVBUILD ) - "-Dev" - #else - "" - #endif - ); - - #else - - // Use TortoiseSVN's SubWCRev utility's output - // to label the specific revision: - - sprintf_s( libraryName, "USBqemu %lld%s" - #ifdef DEBUG_FAST - "-Debug" - #elif defined( PCSX2_DEBUG ) - "-Debug/Strict" // strict debugging is slow! - #elif defined( PCSX2_DEVBUILD ) - "-Dev" - #else - "" - #endif - ,SVN_REV,SVN_MODS ? "m" : "" - ); - #endif -#endif - -} - -u32 CALLBACK PS2EgetLibType() { - return PS2E_LT_USB; -} - -const char* CALLBACK PS2EgetLibName() -{ - InitLibraryName(); - return libraryName; -} - -u32 CALLBACK PS2EgetLibVersion2(u32 type) { - return (version<<16) | (revision<<8) | build; -} - -void USBirq(int cycles) -{ - USB_LOG("USBirq.\n"); - - _USBirq(cycles); -} - -s32 CALLBACK USBinit() { - LoadConfig(); - if (conf.Log) - { - usbLog = fopen("logs/usbLog.txt", "w"); - setvbuf(usbLog, NULL, _IONBF, 0); - USB_LOG("USBqemu plugin version %d,%d\n",revision,build); - USB_LOG("USBinit\n"); - } - - qemu_ohci = ohci_create(0x1f801600,2); - qemu_ohci->rhport[0].port.dev = usb_keyboard_init(); - qemu_ohci->rhport[0].port.ops->attach(&(qemu_ohci->rhport[0].port)); - - clocks = 0; - remaining = 0; - - return 0; -} - -void CALLBACK USBshutdown() { - - USBDevice* device = qemu_ohci->rhport[0].port.dev; - - qemu_ohci->rhport[0].port.ops->detach(&(qemu_ohci->rhport[0].port)); - device->info->handle_destroy(qemu_ohci->rhport[0].port.dev); - - free(qemu_ohci); - -#ifdef _DEBUG - if(usbLog) - fclose(usbLog); -#endif -} - -s32 CALLBACK USBopen(void *pDsp) { - USB_LOG("USBopen\n"); - - HWND hWnd=(HWND)pDsp; - - if (!IsWindow (hWnd) && !IsBadReadPtr ((u32*)hWnd, 4)) - hWnd = *(HWND*)hWnd; - if (!IsWindow (hWnd)) - hWnd = NULL; - else - { - while (GetWindowLong (hWnd, GWL_STYLE) & WS_CHILD) - hWnd = GetParent (hWnd); - } - gsWindowHandle = hWnd; - - return 0; -} - -void CALLBACK USBclose() { -} - -u8 CALLBACK USBread8(u32 addr) { - USB_LOG("* Invalid 8bit read at address %lx\n", addr); - return 0; -} - -u16 CALLBACK USBread16(u32 addr) { - USB_LOG("* Invalid 16bit read at address %lx\n", addr); - return 0; -} - -u32 CALLBACK USBread32(u32 addr) { - u32 hard; - - hard=ohci_mem_read(qemu_ohci,addr - qemu_ohci->mem); - - USB_LOG("* Known 32bit read at address %lx: %lx\n", addr, hard); - - return hard; -} - -void CALLBACK USBwrite8(u32 addr, u8 value) { - USB_LOG("* Invalid 8bit write at address %lx value %x\n", addr, value); -} - -void CALLBACK USBwrite16(u32 addr, u16 value) { - USB_LOG("* Invalid 16bit write at address %lx value %x\n", addr, value); -} - -void CALLBACK USBwrite32(u32 addr, u32 value) { - USB_LOG("* Known 32bit write at address %lx value %lx\n", addr, value); - ohci_mem_write(qemu_ohci,addr - qemu_ohci->mem, value); -} - -void CALLBACK USBirqCallback(USBcallback callback) { - _USBirq = callback; -} - -extern u32 bits; - -int CALLBACK _USBirqHandler(void) -{ - //fprintf(stderr," * USB: IRQ Acknowledged.\n"); - //qemu_ohci->intr_status&=~bits; - return 1; -} - -USBhandler CALLBACK USBirqHandler(void) { - return (USBhandler)_USBirqHandler; -} - -void CALLBACK USBsetRAM(void *mem) { - ram = (u8*)mem; -} - -// extended funcs - -char USBfreezeID[] = "USBqemu01"; - -typedef struct { - char freezeID[10]; - int cycles; - int remaining; - OHCIState t; - int extraData; // for future expansion with the device state -} USBfreezeData; - -s32 CALLBACK USBfreeze(int mode, freezeData *data) { - USBfreezeData usbd; - - if (mode == FREEZE_LOAD) - { - if(data->size < sizeof(USBfreezeData)) - { - SysMessage("ERROR: Unable to load freeze data! Got %d bytes, expected >= %d.", data->size, sizeof(USBfreezeData)); - return -1; - } - - usbd = *(USBfreezeData*)data->data; - usbd.freezeID[9] = 0; - usbd.cycles = static_cast(clocks); - usbd.remaining = static_cast(remaining); - - if( strcmp(usbd.freezeID, USBfreezeID) != 0) - { - SysMessage("ERROR: Unable to load freeze data! Found ID '%s', expected ID '%s'.", usbd.freezeID, USBfreezeID); - return -1; - } - - if (data->size != sizeof(USBfreezeData)) - return -1; - - for(int i=0; i< qemu_ohci->num_ports; i++) - { - usbd.t.rhport[i].port.opaque = qemu_ohci; - usbd.t.rhport[i].port.ops = qemu_ohci->rhport[i].port.ops; - usbd.t.rhport[i].port.dev = qemu_ohci->rhport[i].port.dev; // pointers - } - *qemu_ohci = usbd.t; - - // WARNING: TODO: Load the state of the attached devices! - - } - else if (mode == FREEZE_SAVE) - { - data->size = sizeof(USBfreezeData); - data->data = (s8*)malloc(data->size); - if (data->data == NULL) - return -1; - - - strcpy(usbd.freezeID, USBfreezeID); - usbd.t = *qemu_ohci; - for(int i=0; i< qemu_ohci->num_ports; i++) - { - usbd.t.rhport[i].port.ops = NULL; // pointers - usbd.t.rhport[i].port.opaque = NULL; // pointers - usbd.t.rhport[i].port.dev = NULL; // pointers - } - - clocks = usbd.cycles; - remaining = usbd.remaining; - - // WARNING: TODO: Save the state of the attached devices! - } - - return 0; -} - -void CALLBACK USBasync(u32 _cycles) -{ - remaining += _cycles; - clocks += remaining; - if(qemu_ohci->eof_timer>0) - { - while(remaining>=qemu_ohci->eof_timer) - { - remaining-=qemu_ohci->eof_timer; - qemu_ohci->eof_timer=0; - ohci_frame_boundary(qemu_ohci); - } - if((remaining>0)&&(qemu_ohci->eof_timer>0)) - { - s64 m = qemu_ohci->eof_timer; - if(remaining < m) - m = remaining; - qemu_ohci->eof_timer -= m; - remaining -= m; - } - } - //if(qemu_ohci->eof_timer <= 0) - //{ - // ohci_frame_boundary(qemu_ohci); - //} -} - -s32 CALLBACK USBtest() { - return 0; -} - -void cpu_physical_memory_rw(u32 addr, u8 *buf, - int len, int is_write) -{ - if(is_write) - memcpy(&(ram[addr]),buf,len); - else - memcpy(buf,&(ram[addr]),len); -} - -s64 get_clock() -{ - return clocks; -} - -void *qemu_mallocz(uint32_t size) -{ - void *m=malloc(size); - if(!m) return NULL; - memset(m,0,size); - return m; -} diff --git a/plugins/USBqemu/USB.h b/plugins/USBqemu/USB.h deleted file mode 100644 index 3404a8196c..0000000000 --- a/plugins/USBqemu/USB.h +++ /dev/null @@ -1,65 +0,0 @@ -/* USBqemu - * Copyright (C) 2002-2011 PCSX2 Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#pragma once - -#ifndef __USB_H__ -#define __USB_H__ - -#include - -#define USBdefs -#include "PS2Edefs.h" - -#ifdef _WIN32 -# include -# include -#else -# include -# define __inline inline -#endif - -#include -#include -#include -#include - -#define USB_LOG __Log - -typedef struct { - bool Log; -} Config; - -extern Config conf; - -#define PSXCLK 36864000 /* 36.864 Mhz */ - -void USBirq(int); - -void SaveConfig(); -void LoadConfig(); - -extern FILE *usbLog; -void __Log(char *fmt, ...); - -extern void SysMessage(const char *fmt, ...); -extern void SysMessage(const wchar_t *fmt, ...); - -extern HWND gsWindowHandle; - -#endif diff --git a/plugins/USBqemu/Win32/CfgHelpers.cpp b/plugins/USBqemu/Win32/CfgHelpers.cpp deleted file mode 100644 index 5fe6a75006..0000000000 --- a/plugins/USBqemu/Win32/CfgHelpers.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 - * Developed and maintained by the Pcsx2 Development Team. - * - * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] - * - * SPU2-X is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with SPU2-X. If not, see . - */ -#include "../USB.h" - -void SysMessage(const char *fmt, ...) -{ - va_list list; - char tmp[512]; - wchar_t wtmp[512]; - - va_start(list,fmt); - vsprintf_s(tmp,fmt,list); - va_end(list); - swprintf_s(wtmp, L"%S", tmp); - MessageBox( (!!gsWindowHandle) ? (HWND)gsWindowHandle : GetActiveWindow(), wtmp, - L"USBqemu System Message", MB_OK | MB_SETFOREGROUND); -} - -void SysMessage(const wchar_t *fmt, ...) -{ - va_list list; - wchar_t tmp[512]; - - va_start(list,fmt); - vswprintf_s(tmp,fmt,list); - va_end(list); - - MessageBox( (!!gsWindowHandle) ? (HWND)gsWindowHandle : GetActiveWindow(), tmp, - L"USBqemu System Message", MB_OK | MB_SETFOREGROUND); -} - -////// - -static TCHAR CfgFile[260] = L"inis/USBqemu.ini"; - -void CfgSetSettingsDir( const char* dir ) -{ - if(dir == NULL) - { - wcscpy(CfgFile, L"inis/USBqemu.ini"); - } - else - { - swprintf_s(CfgFile, L"%S", dir); - TCHAR term = CfgFile[wcslen(CfgFile)-1]; - if(term != L'\\' && term != L'/') - wcscat(CfgFile, L"\\"); - wcscat(CfgFile, L"USBQemu.ini" ); - } -} - - -/*¯| Config File Format: |¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯*\ -+--+---------------------+------------------------+ -| | -| Option=Value | -| | -| | -| Boolean Values: TRUE,YES,1,T,Y mean 'true', | -| everything else means 'false'. | -| | -| All Values are limited to 255 chars. | -| | -+-------------------------------------------------+ -\*______________________________________________*/ - - -void CfgWriteBool(const TCHAR* Section, const TCHAR* Name, bool Value) -{ - const TCHAR *Data = Value ? L"TRUE" : L"FALSE"; - WritePrivateProfileString( Section, Name, Data, CfgFile ); -} - -void CfgWriteInt(const TCHAR* Section, const TCHAR* Name, int Value) -{ - TCHAR Data[32]; - _itow( Value, Data, 10 ); - WritePrivateProfileString(Section,Name,Data,CfgFile); -} - -void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const TCHAR *Data) -{ - WritePrivateProfileString( Section, Name, Data, CfgFile ); -} - - -/*****************************************************************************/ - -bool CfgReadBool(const TCHAR *Section,const TCHAR* Name, bool Default) -{ - TCHAR Data[255] = {0}; - - GetPrivateProfileString( Section, Name, L"", Data, 255, CfgFile ); - Data[254]=0; - if(wcslen(Data)==0) { - CfgWriteBool(Section,Name,Default); - return Default; - } - - if(wcscmp(Data,L"1")==0) return true; - if(wcscmp(Data,L"Y")==0) return true; - if(wcscmp(Data,L"T")==0) return true; - if(wcscmp(Data,L"YES")==0) return true; - if(wcscmp(Data,L"TRUE")==0) return true; - return false; -} - - -int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default) -{ - TCHAR Data[255]={0}; - GetPrivateProfileString(Section,Name,L"",Data,255,CfgFile); - Data[254]=0; - - if(wcslen(Data)==0) { - CfgWriteInt(Section,Name,Default); - return Default; - } - - return _wtoi(Data); -} - -void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default) -{ - int chars = GetPrivateProfileString(Section,Name,L"",Data,DataSize,CfgFile); - - if(!chars) - { - wcscpy(Data, Default); - CfgWriteStr( Section, Name, Default ); - } -} - -// Tries to read the requested value. -// Returns FALSE if the value isn't found. -bool CfgFindName( const TCHAR *Section, const TCHAR* Name) -{ - // Only load 24 characters. No need to load more. - TCHAR Data[24]={0}; - GetPrivateProfileString(Section,Name,L"",Data,24,CfgFile); - Data[23]=0; - - if(wcslen(Data)==0) return false; - return true; -} diff --git a/plugins/USBqemu/Win32/CfgHelpers.h b/plugins/USBqemu/Win32/CfgHelpers.h deleted file mode 100644 index 4c87d4d86f..0000000000 --- a/plugins/USBqemu/Win32/CfgHelpers.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -extern void CfgSetSettingsDir( const char* dir ); - -extern bool CfgFindName( const TCHAR *Section, const TCHAR* Name); - -extern void CfgWriteBool(const TCHAR* Section, const TCHAR* Name, bool Value); -extern void CfgWriteInt(const TCHAR* Section, const TCHAR* Name, int Value); -extern void CfgWriteStr(const TCHAR* Section, const TCHAR* Name, const TCHAR *Data); - -extern bool CfgReadBool(const TCHAR *Section,const TCHAR* Name, bool Default); -extern void CfgReadStr(const TCHAR* Section, const TCHAR* Name, TCHAR* Data, int DataSize, const TCHAR* Default); -extern int CfgReadInt(const TCHAR* Section, const TCHAR* Name,int Default); diff --git a/plugins/USBqemu/Win32/Config.cpp b/plugins/USBqemu/Win32/Config.cpp deleted file mode 100644 index 05b1caaa08..0000000000 --- a/plugins/USBqemu/Win32/Config.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include - -#include "../USB.h" - -#include "CfgHelpers.h" - -void CALLBACK USBsetSettingsDir( const char* dir ) -{ - CfgSetSettingsDir(dir); -} - -void SaveConfig() -{ - CfgWriteBool(L"Interface", L"Logging", conf.Log); -} - -void LoadConfig() -{ - conf.Log = CfgReadBool(L"Interface", L"Logging", false); -} - diff --git a/plugins/USBqemu/Win32/ProjectRootDir.props b/plugins/USBqemu/Win32/ProjectRootDir.props deleted file mode 100644 index 45c14ddc1b..0000000000 --- a/plugins/USBqemu/Win32/ProjectRootDir.props +++ /dev/null @@ -1,16 +0,0 @@ - - - - $(ProjectDir).. - $(ProjectRootDir)\..\.. - $(SvnRootDir)\common - - - <_ProjectFileVersion>10.0.30128.1 - - - - $(SvnRootDir) - - - \ No newline at end of file diff --git a/plugins/USBqemu/Win32/USBqemu.def b/plugins/USBqemu/Win32/USBqemu.def deleted file mode 100644 index 115818e3a1..0000000000 --- a/plugins/USBqemu/Win32/USBqemu.def +++ /dev/null @@ -1,24 +0,0 @@ - -EXPORTS - ; Explicit exports can go here - PS2EgetLibType @2 - PS2EgetLibName @3 - PS2EgetLibVersion2 @4 - USBinit @5 - USBshutdown @6 - USBopen @7 - USBclose @8 - USBread8 @9 - USBread16 @10 - USBread32 @11 - USBwrite8 @12 - USBwrite16 @13 - USBwrite32 @14 - USBirqCallback @15 - USBirqHandler @16 - USBsetRAM @17 - USBasync @18 - - USBconfigure @19 - USBtest @20 - USBabout @21 diff --git a/plugins/USBqemu/Win32/USBqemu.rc b/plugins/USBqemu/Win32/USBqemu.rc deleted file mode 100644 index 0e88cb4388..0000000000 --- a/plugins/USBqemu/Win32/USBqemu.rc +++ /dev/null @@ -1,159 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Spanish (Argentina) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ESS) -#ifdef _WIN32 -LANGUAGE LANG_SPANISH, SUBLANG_SPANISH_ARGENTINA -#pragma code_page(1252) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_CONFIG DIALOGEX 0, 0, 212, 121 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "USBconfigure" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,48,100,50,14 - PUSHBUTTON "Cancel",IDCANCEL,113,100,50,14 - CONTROL "Enable Logging (for develop use only)",IDC_LOGGING, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,7,144,15 - COMBOBOX IDC_COMBO1,7,38,138,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Device in Port 1:",IDC_STATIC,8,30,54,8 - COMBOBOX IDC_COMBO2,7,63,138,51,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Device in Port 2:",IDC_STATIC,8,55,54,8 -END - -IDD_ABOUT DIALOGEX 0, 0, 177, 106 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "USBabout" -FONT 8, "MS Sans Serif", 0, 0, 0x0 -BEGIN - DEFPUSHBUTTON "OK",IDOK,65,85,50,14 - LTEXT "USBqemu Driver",IDC_NAME,70,10,54,8 - GROUPBOX "",IDC_STATIC,5,35,170,40 - LTEXT "Author: gigaherz ",IDC_STATIC,20,20,141,10 - LTEXT "Parts of this code were originally from the QEMU project.",IDC_STATIC,14,44,149,26 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_CONFIG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 205 - TOPMARGIN, 7 - BOTTOMMARGIN, 114 - END - - IDD_ABOUT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 170 - TOPMARGIN, 7 - BOTTOMMARGIN, 99 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog Info -// - -IDD_CONFIG DLGINIT -BEGIN - IDC_COMBO1, 0x403, 10, 0 -0x6f4e, 0x4420, 0x7665, 0x6369, 0x0065, - IDC_COMBO1, 0x403, 9, 0 -0x654b, 0x6279, 0x616f, 0x6472, "\000" - IDC_COMBO1, 0x403, 6, 0 -0x6f4d, 0x7375, 0x0065, - IDC_COMBO1, 0x403, 14, 0 -0x7945, 0x7465, 0x796f, 0x4320, 0x6d61, 0x7265, 0x0061, - IDC_COMBO1, 0x403, 20, 0 -0x6953, 0x676e, 0x7473, 0x7261, 0x4d20, 0x6369, 0x6f72, 0x6870, 0x6e6f, -0x0065, - IDC_COMBO2, 0x403, 10, 0 -0x6f4e, 0x4420, 0x7665, 0x6369, 0x0065, - IDC_COMBO2, 0x403, 9, 0 -0x654b, 0x6279, 0x616f, 0x6472, "\000" - IDC_COMBO2, 0x403, 6, 0 -0x6f4d, 0x7375, 0x0065, - IDC_COMBO2, 0x403, 14, 0 -0x7945, 0x7465, 0x796f, 0x4320, 0x6d61, 0x7265, 0x0061, - IDC_COMBO2, 0x403, 20, 0 -0x6953, 0x676e, 0x7473, 0x7261, 0x4d20, 0x6369, 0x6f72, 0x6870, 0x6e6f, -0x0065, - 0 -END - -#endif // Spanish (Argentina) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/plugins/USBqemu/Win32/USBqemu.vcxproj b/plugins/USBqemu/Win32/USBqemu.vcxproj deleted file mode 100644 index 0fe11f9af3..0000000000 --- a/plugins/USBqemu/Win32/USBqemu.vcxproj +++ /dev/null @@ -1,107 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Devel - Win32 - - - Devel - x64 - - - Release - Win32 - - - Release - x64 - - - - {E613DA9F-41B4-4613-9911-E418EF5533BC} - - - - DynamicLibrary - $(DefaultPlatformToolset) - Unicode - true - true - false - - - - - - - - - - - - - - - - AllRules.ruleset - - - - USBqemu.def - Windows - MachineX86 - MachineX64 - - - - - true - - - - - - - - true - - - true - - - true - - - - true - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/USBqemu/Win32/USBqemu.vcxproj.filters b/plugins/USBqemu/Win32/USBqemu.vcxproj.filters deleted file mode 100644 index b24198a398..0000000000 --- a/plugins/USBqemu/Win32/USBqemu.vcxproj.filters +++ /dev/null @@ -1,97 +0,0 @@ - - - - - {dfc571b5-5df6-405b-9920-d273ad48d332} - cpp;c;cxx;def;odl;idl;hpj;bat;asm - - - {fe40e0a3-a73a-44b8-a8ee-3d9591f91f0b} - - - {2f1d0e2b-ba2b-4bd2-8bbd-63b3e4909ff3} - h;hpp;hxx;hm;inl;inc - - - {d1b11b29-e230-4fb1-84e1-795a3aafe8dd} - - - {5468eb4e-6580-45d9-9432-a8ac8083abf9} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files\qemu-usb - - - Source Files\qemu-usb - - - Source Files\qemu-usb - - - Source Files\qemu-usb - - - Source Files\qemu-usb - - - Source Files\qemu-usb - - - Source Files\qemu-usb - - - Source Files\qemu-usb - - - Source Files - - - Source Files\qemu-usb - - - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files\qemu-usb - - - Header Files\qemu-usb - - - Header Files\qemu-usb - - - Header Files - - - Header Files\qemu-usb - - - - - Resource Files - - - \ No newline at end of file diff --git a/plugins/USBqemu/Win32/Win32.cpp b/plugins/USBqemu/Win32/Win32.cpp deleted file mode 100644 index f9a755ad7e..0000000000 --- a/plugins/USBqemu/Win32/Win32.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include -#include - -#include "../USB.h" -#include "resource.h" - -HINSTANCE hInst; - -void SysMessage(TCHAR *fmt, ...) { - va_list list; - TCHAR tmp[512]; - - va_start(list,fmt); - _vswprintf(tmp,fmt,list); - va_end(list); - MessageBox(0, tmp, L"USBqemu Msg", 0); -} - -BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { - - switch(uMsg) { - case WM_INITDIALOG: - LoadConfig(); - if (conf.Log) CheckDlgButton(hW, IDC_LOGGING, TRUE); - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDCANCEL: - EndDialog(hW, TRUE); - return TRUE; - case IDOK: - if (IsDlgButtonChecked(hW, IDC_LOGGING)) - conf.Log = 1; - else conf.Log = 0; - SaveConfig(); - EndDialog(hW, FALSE); - return TRUE; - } - } - return FALSE; -} - - -BOOL CALLBACK AboutDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) { - switch(uMsg) { - case WM_INITDIALOG: - return TRUE; - - case WM_COMMAND: - switch(LOWORD(wParam)) { - case IDOK: - EndDialog(hW, FALSE); - return TRUE; - } - } - return FALSE; -} - -void CALLBACK USBconfigure() { - DialogBox(hInst, - MAKEINTRESOURCE(IDD_CONFIG), - GetActiveWindow(), - (DLGPROC)ConfigureDlgProc); -} - -void CALLBACK USBabout() { - DialogBox(hInst, - MAKEINTRESOURCE(IDD_ABOUT), - GetActiveWindow(), - (DLGPROC)AboutDlgProc); -} - -BOOL APIENTRY DllMain(HANDLE hModule, // DLL INIT - DWORD dwReason, - LPVOID lpReserved) { - hInst = (HINSTANCE)hModule; - return TRUE; // very quick :) -} diff --git a/plugins/USBqemu/Win32/resource.h b/plugins/USBqemu/Win32/resource.h deleted file mode 100644 index f86e1500e8..0000000000 --- a/plugins/USBqemu/Win32/resource.h +++ /dev/null @@ -1,28 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by USBqemu.rc -// - -#ifndef IDC_STATIC -#define IDC_STATIC -1 -#endif - -#define IDD_CONFDLG 101 -#define IDD_CONFIG 101 -#define IDD_ABOUT 103 -#define IDC_NAME 1000 -#define IDC_CHECK1 1007 -#define IDC_LOGGING 1007 -#define IDC_COMBO1 1008 -#define IDC_COMBO2 1009 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 106 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1009 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/plugins/USBqemu/qemu-usb/USBinternal.h b/plugins/USBqemu/qemu-usb/USBinternal.h deleted file mode 100644 index b388c60bd2..0000000000 --- a/plugins/USBqemu/qemu-usb/USBinternal.h +++ /dev/null @@ -1,289 +0,0 @@ -#pragma once - -#include "../USB.h" -#include "vl.h" - -#ifdef PCSX2_DEVBUILD -# define DEBUG_OHCI -#endif -/* Dump packet contents. */ -//#define DEBUG_PACKET -/* This causes frames to occur 1000x slower */ -//#define OHCI_TIME_WARP 1 - -/* Number of Downstream Ports on the root hub. */ - -#define OHCI_MAX_PORTS 2 - -extern int64_t usb_frame_time; -extern int64_t usb_bit_time; - -typedef struct OHCIPort { - USBPort port; - uint32_t ctrl; -} OHCIPort; - -typedef uint32_t target_phys_addr_t; - -typedef struct { - //USBBus bus; - //qemu_irq irq; - int mem; - int num_ports; - const char *name; - - //QEMUTimer *eof_timer; - int64_t eof_timer; - int64_t sof_time; - - /* OHCI state */ - /* Control partition */ - uint32_t ctl, status; - uint32_t intr_status; - uint32_t intr; - - /* memory pointer partition */ - uint32_t hcca; - uint32_t ctrl_head, ctrl_cur; - uint32_t bulk_head, bulk_cur; - uint32_t per_cur; - uint32_t done; - int done_count; - - /* Frame counter partition */ - uint32_t fsmps:15; - uint32_t fit:1; - uint32_t fi:14; - uint32_t frt:1; - uint16_t frame_number; - uint16_t padding; - uint32_t pstart; - uint32_t lst; - - /* Root Hub partition */ - uint32_t rhdesc_a, rhdesc_b; - uint32_t rhstatus; - OHCIPort rhport[OHCI_MAX_PORTS]; - - /* PXA27x Non-OHCI events */ - uint32_t hstatus; - uint32_t hmask; - uint32_t hreset; - uint32_t htest; - - /* SM501 local memory offset */ - target_phys_addr_t localmem_base; - - /* Active packets. */ - uint32_t old_ctl; - USBPacket usb_packet; - uint8_t usb_buf[8192]; - uint32_t async_td; - int async_complete; - -} OHCIState; - -/* Host Controller Communications Area */ -struct ohci_hcca { - uint32_t intr[32]; - uint16_t frame, pad; - uint32_t done; -}; - -static void ohci_bus_stop(OHCIState *ohci); -static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev); - -/* Bitfields for the first word of an Endpoint Desciptor. */ -#define OHCI_ED_FA_SHIFT 0 -#define OHCI_ED_FA_MASK (0x7f<> OHCI_##field##_SHIFT) - -#define OHCI_SET_BM(val, field, newval) do { \ - val &= ~OHCI_##field##_MASK; \ - val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \ - } while(0) - -/* endpoint descriptor */ -struct ohci_ed { - uint32_t flags; - uint32_t tail; - uint32_t head; - uint32_t next; -}; - -/* General transfer descriptor */ -struct ohci_td { - uint32_t flags; - uint32_t cbp; - uint32_t next; - uint32_t be; -}; - -/* Isochronous transfer descriptor */ -struct ohci_iso_td { - uint32_t flags; - uint32_t bp; - uint32_t next; - uint32_t be; - uint16_t offset[8]; -}; - -#define USB_HZ 12000000 - -/* OHCI Local stuff */ -#define OHCI_CTL_CBSR ((1<<0)|(1<<1)) -#define OHCI_CTL_PLE (1<<2) -#define OHCI_CTL_IE (1<<3) -#define OHCI_CTL_CLE (1<<4) -#define OHCI_CTL_BLE (1<<5) -#define OHCI_CTL_HCFS ((1<<6)|(1<<7)) -#define OHCI_USB_RESET 0x00 -#define OHCI_USB_RESUME 0x40 -#define OHCI_USB_OPERATIONAL 0x80 -#define OHCI_USB_SUSPEND 0xc0 -#define OHCI_CTL_IR (1<<8) -#define OHCI_CTL_RWC (1<<9) -#define OHCI_CTL_RWE (1<<10) - -#define OHCI_STATUS_HCR (1<<0) -#define OHCI_STATUS_CLF (1<<1) -#define OHCI_STATUS_BLF (1<<2) -#define OHCI_STATUS_OCR (1<<3) -#define OHCI_STATUS_SOC ((1<<6)|(1<<7)) - -#define OHCI_INTR_SO (1<<0) /* Scheduling overrun */ -#define OHCI_INTR_WD (1<<1) /* HcDoneHead writeback */ -#define OHCI_INTR_SF (1<<2) /* Start of frame */ -#define OHCI_INTR_RD (1<<3) /* Resume detect */ -#define OHCI_INTR_UE (1<<4) /* Unrecoverable error */ -#define OHCI_INTR_FNO (1<<5) /* Frame number overflow */ -#define OHCI_INTR_RHSC (1<<6) /* Root hub status change */ -#define OHCI_INTR_OC (1<<30) /* Ownership change */ -#define OHCI_INTR_MIE (1<<31) /* Master Interrupt Enable */ - -#define OHCI_HCCA_SIZE 0x100 -#define OHCI_HCCA_MASK 0xffffff00 - -#define OHCI_EDPTR_MASK 0xfffffff0 - -#define OHCI_FMI_FI 0x00003fff -#define OHCI_FMI_FSMPS 0xffff0000 -#define OHCI_FMI_FIT 0x80000000 - -#define OHCI_FR_RT (1<<31) - -#define OHCI_LS_THRESH 0x628 - -#define OHCI_RHA_RW_MASK 0x00000000 /* Mask of supported features. */ -#define OHCI_RHA_PSM (1<<8) -#define OHCI_RHA_NPS (1<<9) -#define OHCI_RHA_DT (1<<10) -#define OHCI_RHA_OCPM (1<<11) -#define OHCI_RHA_NOCP (1<<12) -#define OHCI_RHA_POTPGT_MASK 0xff000000 - -#define OHCI_RHS_LPS (1<<0) -#define OHCI_RHS_OCI (1<<1) -#define OHCI_RHS_DRWE (1<<15) -#define OHCI_RHS_LPSC (1<<16) -#define OHCI_RHS_OCIC (1<<17) -#define OHCI_RHS_CRWE (1<<31) - -#define OHCI_PORT_CCS (1<<0) -#define OHCI_PORT_PES (1<<1) -#define OHCI_PORT_PSS (1<<2) -#define OHCI_PORT_POCI (1<<3) -#define OHCI_PORT_PRS (1<<4) -#define OHCI_PORT_PPS (1<<8) -#define OHCI_PORT_LSDA (1<<9) -#define OHCI_PORT_CSC (1<<16) -#define OHCI_PORT_PESC (1<<17) -#define OHCI_PORT_PSSC (1<<18) -#define OHCI_PORT_OCIC (1<<19) -#define OHCI_PORT_PRSC (1<<20) -#define OHCI_PORT_WTC (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \ - |OHCI_PORT_OCIC|OHCI_PORT_PRSC) - -#define OHCI_TD_DIR_SETUP 0x0 -#define OHCI_TD_DIR_OUT 0x1 -#define OHCI_TD_DIR_IN 0x2 -#define OHCI_TD_DIR_RESERVED 0x3 - -#define OHCI_CC_NOERROR 0x0 -#define OHCI_CC_CRC 0x1 -#define OHCI_CC_BITSTUFFING 0x2 -#define OHCI_CC_DATATOGGLEMISMATCH 0x3 -#define OHCI_CC_STALL 0x4 -#define OHCI_CC_DEVICENOTRESPONDING 0x5 -#define OHCI_CC_PIDCHECKFAILURE 0x6 -#define OHCI_CC_UNDEXPETEDPID 0x7 -#define OHCI_CC_DATAOVERRUN 0x8 -#define OHCI_CC_DATAUNDERRUN 0x9 -#define OHCI_CC_BUFFEROVERRUN 0xc -#define OHCI_CC_BUFFERUNDERRUN 0xd - -#define OHCI_HRESET_FSBIR (1 << 0) - -int64_t get_ticks_per_sec(); - -int64_t get_clock(); - -OHCIState *ohci_create(uint32_t base, int ports); - -uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr); -void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val); -void ohci_frame_boundary(void *opaque); - -int ohci_bus_start(OHCIState *ohci); -void ohci_bus_stop(OHCIState *ohci); - -USBDevice *usb_hub_init(int nb_ports); -USBDevice *usb_msd_init(const char *filename); -USBDevice *eyetoy_init(void); -USBDevice *usb_mouse_init(void); diff --git a/plugins/USBqemu/qemu-usb/qemu-queue.h b/plugins/USBqemu/qemu-usb/qemu-queue.h deleted file mode 100644 index 1d077458ce..0000000000 --- a/plugins/USBqemu/qemu-usb/qemu-queue.h +++ /dev/null @@ -1,449 +0,0 @@ -/* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */ - -/* - * Qemu version: Copy from netbsd, removed debug code, removed some of - * the implementations. Left in lists, simple queues, tail queues and - * circular queues. - */ - -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -#ifndef QEMU_SYS_QUEUE_H_ -#define QEMU_SYS_QUEUE_H_ - -/* - * This file defines four types of data structures: - * lists, simple queues, tail queues, and circular queues. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -/* - * List definitions. - */ -#define QLIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define QLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define QLIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ -#define QLIST_INIT(head) do { \ - (head)->lh_first = NULL; \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (/*CONSTCOND*/0) - -#define QLIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ -} while (/*CONSTCOND*/0) - -#define QLIST_FOREACH(var, head, field) \ - for ((var) = ((head)->lh_first); \ - (var); \ - (var) = ((var)->field.le_next)) - -#define QLIST_FOREACH_SAFE(var, head, field, next_var) \ - for ((var) = ((head)->lh_first); \ - (var) && ((next_var) = ((var)->field.le_next), 1); \ - (var) = (next_var)) - -/* - * List access methods. - */ -#define QLIST_EMPTY(head) ((head)->lh_first == NULL) -#define QLIST_FIRST(head) ((head)->lh_first) -#define QLIST_NEXT(elm, field) ((elm)->field.le_next) - - -/* - * Simple queue definitions. - */ -#define QSIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define QSIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define QSIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue functions. - */ -#define QSIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_REMOVE_HEAD(head, field) do { \ - if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\ - (head)->sqh_last = &(head)->sqh_first; \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \ - if ((head)->sqh_first == (elm)) { \ - QSIMPLEQ_REMOVE_HEAD((head), field); \ - } else { \ - struct type *curelm = (head)->sqh_first; \ - while (curelm->field.sqe_next != (elm)) \ - curelm = curelm->field.sqe_next; \ - if ((curelm->field.sqe_next = \ - curelm->field.sqe_next->field.sqe_next) == NULL) \ - (head)->sqh_last = &(curelm)->field.sqe_next; \ - } \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_FOREACH(var, head, field) \ - for ((var) = ((head)->sqh_first); \ - (var); \ - (var) = ((var)->field.sqe_next)) - -#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \ - for ((var) = ((head)->sqh_first); \ - (var) && ((next = ((var)->field.sqe_next)), 1); \ - (var) = (next)) - -#define QSIMPLEQ_CONCAT(head1, head2) do { \ - if (!QSIMPLEQ_EMPTY((head2))) { \ - *(head1)->sqh_last = (head2)->sqh_first; \ - (head1)->sqh_last = (head2)->sqh_last; \ - QSIMPLEQ_INIT((head2)); \ - } \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_LAST(head, type, field) \ - (QSIMPLEQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *)(void *) \ - ((char *)((head)->sqh_last) - offsetof(struct type, field)))) - -/* - * Simple queue access methods. - */ -#define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL) -#define QSIMPLEQ_FIRST(head) ((head)->sqh_first) -#define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - - -/* - * Tail queue definitions. - */ -#define Q_TAILQ_HEAD(name, type, qual) \ -struct name { \ - qual type *tqh_first; /* first element */ \ - qual type *qual *tqh_last; /* addr of last next element */ \ -} -#define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type,) - -#define QTAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define Q_TAILQ_ENTRY(type, qual) \ -struct { \ - qual type *tqe_next; /* next element */ \ - qual type *qual *tqe_prev; /* address of previous next element */\ -} -#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type,) - -/* - * Tail queue functions. - */ -#define QTAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_FOREACH(var, head, field) \ - for ((var) = ((head)->tqh_first); \ - (var); \ - (var) = ((var)->field.tqe_next)) - -#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \ - for ((var) = ((head)->tqh_first); \ - (var) && ((next_var) = ((var)->field.tqe_next), 1); \ - (var) = (next_var)) - -#define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \ - (var); \ - (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) - -/* - * Tail queue access methods. - */ -#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL) -#define QTAILQ_FIRST(head) ((head)->tqh_first) -#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define QTAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -#define QTAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - - -/* - * Circular queue definitions. - */ -#define QCIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define QCIRCLEQ_HEAD_INITIALIZER(head) \ - { (void *)&head, (void *)&head } - -#define QCIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue functions. - */ -#define QCIRCLEQ_INIT(head) do { \ - (head)->cqh_first = (void *)(head); \ - (head)->cqh_last = (void *)(head); \ -} while (/*CONSTCOND*/0) - -#define QCIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == (void *)(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} while (/*CONSTCOND*/0) - -#define QCIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == (void *)(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} while (/*CONSTCOND*/0) - -#define QCIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = (void *)(head); \ - if ((head)->cqh_last == (void *)(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} while (/*CONSTCOND*/0) - -#define QCIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.cqe_next = (void *)(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == (void *)(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} while (/*CONSTCOND*/0) - -#define QCIRCLEQ_REMOVE(head, elm, field) do { \ - if ((elm)->field.cqe_next == (void *)(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == (void *)(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ -} while (/*CONSTCOND*/0) - -#define QCIRCLEQ_FOREACH(var, head, field) \ - for ((var) = ((head)->cqh_first); \ - (var) != (const void *)(head); \ - (var) = ((var)->field.cqe_next)) - -#define QCIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for ((var) = ((head)->cqh_last); \ - (var) != (const void *)(head); \ - (var) = ((var)->field.cqe_prev)) - -/* - * Circular queue access methods. - */ -#define QCIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) -#define QCIRCLEQ_FIRST(head) ((head)->cqh_first) -#define QCIRCLEQ_LAST(head) ((head)->cqh_last) -#define QCIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) -#define QCIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) - -#define QCIRCLEQ_LOOP_NEXT(head, elm, field) \ - (((elm)->field.cqe_next == (void *)(head)) \ - ? ((head)->cqh_first) \ - : (elm->field.cqe_next)) -#define QCIRCLEQ_LOOP_PREV(head, elm, field) \ - (((elm)->field.cqe_prev == (void *)(head)) \ - ? ((head)->cqh_last) \ - : (elm->field.cqe_prev)) - -#endif /* !QEMU_SYS_QUEUE_H_ */ diff --git a/plugins/USBqemu/qemu-usb/usb-base.cpp b/plugins/USBqemu/qemu-usb/usb-base.cpp deleted file mode 100644 index 6ce2d90d32..0000000000 --- a/plugins/USBqemu/qemu-usb/usb-base.cpp +++ /dev/null @@ -1,351 +0,0 @@ -/* - * QEMU USB emulation - * - * Copyright (c) 2005 Fabrice Bellard - * - * 2008 Generic packet handler rewrite by Max Krasnyansky - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "USBinternal.h" -//#include "usb.h" - -#include - -void usb_attach(USBPort *port, USBDevice *dev) -{ - if (dev != NULL) { - /* attach */ - if (port->dev) { - usb_attach(port, NULL); - } - dev->port = port; - port->dev = dev; - port->ops->attach(port); - usb_send_msg(dev, USB_MSG_ATTACH); - } else { - /* detach */ - dev = port->dev; - assert(dev); - port->ops->detach(port); - usb_send_msg(dev, USB_MSG_DETACH); - dev->port = NULL; - port->dev = NULL; - } -} - -void usb_wakeup(USBDevice *dev) -{ - if (dev->remote_wakeup && dev->port && dev->port->ops->wakeup) { - dev->port->ops->wakeup(dev->port); - } -} - -/**********************/ - -/* generic USB device helpers (you are not forced to use them when - writing your USB device driver, but they help handling the - protocol) -*/ - -#define SETUP_STATE_IDLE 0 -#define SETUP_STATE_SETUP 1 -#define SETUP_STATE_DATA 2 -#define SETUP_STATE_ACK 3 - -static int do_token_setup(USBDevice *s, USBPacket *p) -{ - int request, value, index; - int ret = 0; - - if (p->len != 8) - return USB_RET_STALL; - - memcpy(s->setup_buf, p->data, 8); - s->setup_len = (s->setup_buf[7] << 8) | s->setup_buf[6]; - s->setup_index = 0; - - request = (s->setup_buf[0] << 8) | s->setup_buf[1]; - value = (s->setup_buf[3] << 8) | s->setup_buf[2]; - index = (s->setup_buf[5] << 8) | s->setup_buf[4]; - - if (s->setup_buf[0] & USB_DIR_IN) { - ret = s->info->handle_control(s, p, request, value, index, - s->setup_len, s->data_buf); - if (ret == USB_RET_ASYNC) { - s->setup_state = SETUP_STATE_SETUP; - return USB_RET_ASYNC; - } - if (ret < 0) - return ret; - - if (ret < s->setup_len) - s->setup_len = ret; - s->setup_state = SETUP_STATE_DATA; - } else { - if (s->setup_len > sizeof(s->data_buf)) { - fprintf(stderr, - "usb_generic_handle_packet: ctrl buffer too small (%d > %zu)\n", - s->setup_len, sizeof(s->data_buf)); - return USB_RET_STALL; - } - if (s->setup_len == 0) - s->setup_state = SETUP_STATE_ACK; - else - s->setup_state = SETUP_STATE_DATA; - } - - return ret; -} - -static int do_token_in(USBDevice *s, USBPacket *p) -{ - int request, value, index; - int ret = 0; - - if (p->devep != 0) - return s->info->handle_data(s, p); - - request = (s->setup_buf[0] << 8) | s->setup_buf[1]; - value = (s->setup_buf[3] << 8) | s->setup_buf[2]; - index = (s->setup_buf[5] << 8) | s->setup_buf[4]; - - switch(s->setup_state) { - case SETUP_STATE_ACK: - if (!(s->setup_buf[0] & USB_DIR_IN)) { - ret = s->info->handle_control(s, p, request, value, index, - s->setup_len, s->data_buf); - if (ret == USB_RET_ASYNC) { - return USB_RET_ASYNC; - } - s->setup_state = SETUP_STATE_IDLE; - if (ret > 0) - return 0; - return ret; - } - - /* return 0 byte */ - return 0; - - case SETUP_STATE_DATA: - if (s->setup_buf[0] & USB_DIR_IN) { - int len = s->setup_len - s->setup_index; - if (len > p->len) - len = p->len; - memcpy(p->data, s->data_buf + s->setup_index, len); - s->setup_index += len; - if (s->setup_index >= s->setup_len) - s->setup_state = SETUP_STATE_ACK; - return len; - } - - s->setup_state = SETUP_STATE_IDLE; - return USB_RET_STALL; - - default: - return USB_RET_STALL; - } -} - -static int do_token_out(USBDevice *s, USBPacket *p) -{ - if (p->devep != 0) - return s->info->handle_data(s, p); - - switch(s->setup_state) { - case SETUP_STATE_ACK: - if (s->setup_buf[0] & USB_DIR_IN) { - s->setup_state = SETUP_STATE_IDLE; - /* transfer OK */ - } else { - /* ignore additional output */ - } - return 0; - - case SETUP_STATE_DATA: - if (!(s->setup_buf[0] & USB_DIR_IN)) { - int len = s->setup_len - s->setup_index; - if (len > p->len) - len = p->len; - memcpy(s->data_buf + s->setup_index, p->data, len); - s->setup_index += len; - if (s->setup_index >= s->setup_len) - s->setup_state = SETUP_STATE_ACK; - return len; - } - - s->setup_state = SETUP_STATE_IDLE; - return USB_RET_STALL; - - default: - return USB_RET_STALL; - } -} - -/* - * Generic packet handler. - * Called by the HC (host controller). - * - * Returns length of the transaction or one of the USB_RET_XXX codes. - */ -int usb_generic_handle_packet(USBDevice *s, USBPacket *p) -{ - switch(p->pid) { - case USB_MSG_ATTACH: - s->state = USB_STATE_ATTACHED; - if (s->info->handle_attach) { - s->info->handle_attach(s); - } - return 0; - - case USB_MSG_DETACH: - s->state = USB_STATE_NOTATTACHED; - return 0; - - case USB_MSG_RESET: - s->remote_wakeup = 0; - s->addr = 0; - s->state = USB_STATE_DEFAULT; - if (s->info->handle_reset) { - s->info->handle_reset(s); - } - return 0; - } - - /* Rest of the PIDs must match our address */ - if (s->state < USB_STATE_DEFAULT || p->devaddr != s->addr) - return USB_RET_NODEV; - - switch (p->pid) { - case USB_TOKEN_SETUP: - return do_token_setup(s, p); - - case USB_TOKEN_IN: - return do_token_in(s, p); - - case USB_TOKEN_OUT: - return do_token_out(s, p); - - default: - return USB_RET_STALL; - } -} - -/* ctrl complete function for devices which use usb_generic_handle_packet and - may return USB_RET_ASYNC from their handle_control callback. Device code - which does this *must* call this function instead of the normal - usb_packet_complete to complete their async control packets. */ -void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p) -{ - if (p->len < 0) { - s->setup_state = SETUP_STATE_IDLE; - } - - switch (s->setup_state) { - case SETUP_STATE_SETUP: - if (p->len < s->setup_len) { - s->setup_len = p->len; - } - s->setup_state = SETUP_STATE_DATA; - p->len = 8; - break; - - case SETUP_STATE_ACK: - s->setup_state = SETUP_STATE_IDLE; - p->len = 0; - break; - - default: - break; - } - usb_packet_complete(s, p); -} - -/* XXX: fix overflow */ -int set_usb_string(uint8_t *buf, const char *str) -{ - int len, i; - uint8_t *q; - - q = buf; - len = strlen(str); - *q++ = 2 * len + 2; - *q++ = 3; - for(i = 0; i < len; i++) { - *q++ = str[i]; - *q++ = 0; - } - return q - buf; -} - -/* Send an internal message to a USB device. */ -void usb_send_msg(USBDevice *dev, int msg) -{ - USBPacket p; - int ret; - - memset(&p, 0, sizeof(p)); - p.pid = msg; - ret = usb_handle_packet(dev, &p); - /* This _must_ be synchronous */ - assert(ret != USB_RET_ASYNC); -} - -/* Hand over a packet to a device for processing. Return value - USB_RET_ASYNC indicates the processing isn't finished yet, the - driver will call usb_packet_complete() when done processing it. */ -int usb_handle_packet(USBDevice *dev, USBPacket *p) -{ - int ret; - - assert(p->owner == NULL); - ret = dev->info->handle_packet(dev, p); - if (ret == USB_RET_ASYNC) { - if (p->owner == NULL) { - p->owner = dev; - } else { - /* We'll end up here when usb_handle_packet is called - * recursively due to a hub being in the chain. Nothing - * to do. Leave p->owner pointing to the device, not the - * hub. */; - } - } - return ret; -} - -/* Notify the controller that an async packet is complete. This should only - be called for packets previously deferred by returning USB_RET_ASYNC from - handle_packet. */ -void usb_packet_complete(USBDevice *dev, USBPacket *p) -{ - /* Note: p->owner != dev is possible in case dev is a hub */ - assert(p->owner != NULL); - dev->port->ops->complete(dev->port, p); - p->owner = NULL; -} - -/* Cancel an active packet. The packed must have been deferred by - returning USB_RET_ASYNC from handle_packet, and not yet - completed. */ -void usb_cancel_packet(USBPacket * p) -{ - assert(p->owner != NULL); - p->owner->info->cancel_packet(p->owner, p); - p->owner = NULL; -} diff --git a/plugins/USBqemu/qemu-usb/usb-hid.cpp b/plugins/USBqemu/qemu-usb/usb-hid.cpp deleted file mode 100644 index b812da2a6a..0000000000 --- a/plugins/USBqemu/qemu-usb/usb-hid.cpp +++ /dev/null @@ -1,1007 +0,0 @@ -/* - * QEMU USB HID devices - * - * Copyright (c) 2005 Fabrice Bellard - * Copyright (c) 2007 OpenMoko, Inc. (andrew@openedhand.com) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "hw.h" -#include "console.h" -#include "usb.h" -#include "usb-desc.h" -#include "qemu-timer.h" - -/* HID interface requests */ -#define GET_REPORT 0xa101 -#define GET_IDLE 0xa102 -#define GET_PROTOCOL 0xa103 -#define SET_REPORT 0x2109 -#define SET_IDLE 0x210a -#define SET_PROTOCOL 0x210b - -/* HID descriptor types */ -#define USB_DT_HID 0x21 -#define USB_DT_REPORT 0x22 -#define USB_DT_PHY 0x23 - -#define USB_MOUSE 1 -#define USB_TABLET 2 -#define USB_KEYBOARD 3 - -typedef struct USBPointerEvent { - int32_t xdx, ydy; /* relative iff it's a mouse, otherwise absolute */ - int32_t dz, buttons_state; -} USBPointerEvent; - -#define QUEUE_LENGTH 16 /* should be enough for a triple-click */ -#define QUEUE_MASK (QUEUE_LENGTH-1u) -#define QUEUE_INCR(v) ((v)++, (v) &= QUEUE_MASK) - -typedef struct USBMouseState { - USBPointerEvent queue[QUEUE_LENGTH]; - int mouse_grabbed; - QEMUPutMouseEntry *eh_entry; -} USBMouseState; - -typedef struct USBKeyboardState { - uint32_t keycodes[QUEUE_LENGTH]; - uint16_t modifiers; - uint8_t leds; - uint8_t key[16]; - int32_t keys; -} USBKeyboardState; - -typedef struct USBHIDState { - USBDevice dev; - union { - USBMouseState ptr; - USBKeyboardState kbd; - }; - uint32_t head; /* index into circular queue */ - uint32_t n; - int kind; - int32_t protocol; - uint8_t idle; - int64_t next_idle_clock; - int changed; - void *datain_opaque; - void (*datain)(void *); -} USBHIDState; - -enum { - STR_MANUFACTURER = 1, - STR_PRODUCT_MOUSE, - STR_PRODUCT_TABLET, - STR_PRODUCT_KEYBOARD, - STR_SERIALNUMBER, - STR_CONFIG_MOUSE, - STR_CONFIG_TABLET, - STR_CONFIG_KEYBOARD, -}; - -static const USBDescStrings desc_strings = { - [STR_MANUFACTURER] = "QEMU " QEMU_VERSION, - [STR_PRODUCT_MOUSE] = "QEMU USB Mouse", - [STR_PRODUCT_TABLET] = "QEMU USB Tablet", - [STR_PRODUCT_KEYBOARD] = "QEMU USB Keyboard", - [STR_SERIALNUMBER] = "42", /* == remote wakeup works */ - [STR_CONFIG_MOUSE] = "HID Mouse", - [STR_CONFIG_TABLET] = "HID Tablet", - [STR_CONFIG_KEYBOARD] = "HID Keyboard", -}; - -static const USBDescIface desc_iface_mouse = { - .bInterfaceNumber = 0, - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_HID, - .bInterfaceSubClass = 0x01, /* boot */ - .bInterfaceProtocol = 0x02, - .ndesc = 1, - .descs = (USBDescOther[]) { - { - /* HID descriptor */ - .data = (uint8_t[]) { - 0x09, /* u8 bLength */ - USB_DT_HID, /* u8 bDescriptorType */ - 0x01, 0x00, /* u16 HID_class */ - 0x00, /* u8 country_code */ - 0x01, /* u8 num_descriptors */ - USB_DT_REPORT, /* u8 type: Report */ - 52, 0, /* u16 len */ - }, - }, - }, - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_IN | 0x01, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = 4, - .bInterval = 0x0a, - }, - }, -}; - -static const USBDescIface desc_iface_tablet = { - .bInterfaceNumber = 0, - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_HID, - .bInterfaceProtocol = 0x02, - .ndesc = 1, - .descs = (USBDescOther[]) { - { - /* HID descriptor */ - .data = (uint8_t[]) { - 0x09, /* u8 bLength */ - USB_DT_HID, /* u8 bDescriptorType */ - 0x01, 0x00, /* u16 HID_class */ - 0x00, /* u8 country_code */ - 0x01, /* u8 num_descriptors */ - USB_DT_REPORT, /* u8 type: Report */ - 74, 0, /* u16 len */ - }, - }, - }, - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_IN | 0x01, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = 8, - .bInterval = 0x0a, - }, - }, -}; - -static const USBDescIface desc_iface_keyboard = { - .bInterfaceNumber = 0, - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_HID, - .bInterfaceSubClass = 0x01, /* boot */ - .bInterfaceProtocol = 0x01, /* keyboard */ - .ndesc = 1, - .descs = (USBDescOther[]) { - { - /* HID descriptor */ - .data = (uint8_t[]) { - 0x09, /* u8 bLength */ - USB_DT_HID, /* u8 bDescriptorType */ - 0x11, 0x01, /* u16 HID_class */ - 0x00, /* u8 country_code */ - 0x01, /* u8 num_descriptors */ - USB_DT_REPORT, /* u8 type: Report */ - 0x3f, 0, /* u16 len */ - }, - }, - }, - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_IN | 0x01, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = 8, - .bInterval = 0x0a, - }, - }, -}; - -static const USBDescDevice desc_device_mouse = { - .bcdUSB = 0x0100, - .bMaxPacketSize0 = 8, - .bNumConfigurations = 1, - .confs = (USBDescConfig[]) { - { - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = STR_CONFIG_MOUSE, - .bmAttributes = 0xa0, - .bMaxPower = 50, - .nif = 1, - .ifs = &desc_iface_mouse, - }, - }, -}; - -static const USBDescDevice desc_device_tablet = { - .bcdUSB = 0x0100, - .bMaxPacketSize0 = 8, - .bNumConfigurations = 1, - .confs = (USBDescConfig[]) { - { - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = STR_CONFIG_TABLET, - .bmAttributes = 0xa0, - .bMaxPower = 50, - .nif = 1, - .ifs = &desc_iface_tablet, - }, - }, -}; - -static const USBDescDevice desc_device_keyboard = { - .bcdUSB = 0x0100, - .bMaxPacketSize0 = 8, - .bNumConfigurations = 1, - .confs = (USBDescConfig[]) { - { - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = STR_CONFIG_KEYBOARD, - .bmAttributes = 0xa0, - .bMaxPower = 50, - .nif = 1, - .ifs = &desc_iface_keyboard, - }, - }, -}; - -static const USBDesc desc_mouse = { - .id = { - .idVendor = 0x0627, - .idProduct = 0x0001, - .bcdDevice = 0, - .iManufacturer = STR_MANUFACTURER, - .iProduct = STR_PRODUCT_MOUSE, - .iSerialNumber = STR_SERIALNUMBER, - }, - .full = &desc_device_mouse, - .str = desc_strings, -}; - -static const USBDesc desc_tablet = { - .id = { - .idVendor = 0x0627, - .idProduct = 0x0001, - .bcdDevice = 0, - .iManufacturer = STR_MANUFACTURER, - .iProduct = STR_PRODUCT_TABLET, - .iSerialNumber = STR_SERIALNUMBER, - }, - .full = &desc_device_tablet, - .str = desc_strings, -}; - -static const USBDesc desc_keyboard = { - .id = { - .idVendor = 0x0627, - .idProduct = 0x0001, - .bcdDevice = 0, - .iManufacturer = STR_MANUFACTURER, - .iProduct = STR_PRODUCT_KEYBOARD, - .iSerialNumber = STR_SERIALNUMBER, - }, - .full = &desc_device_keyboard, - .str = desc_strings, -}; - -static const uint8_t qemu_mouse_hid_report_descriptor[] = { - 0x05, 0x01, /* Usage Page (Generic Desktop) */ - 0x09, 0x02, /* Usage (Mouse) */ - 0xa1, 0x01, /* Collection (Application) */ - 0x09, 0x01, /* Usage (Pointer) */ - 0xa1, 0x00, /* Collection (Physical) */ - 0x05, 0x09, /* Usage Page (Button) */ - 0x19, 0x01, /* Usage Minimum (1) */ - 0x29, 0x03, /* Usage Maximum (3) */ - 0x15, 0x00, /* Logical Minimum (0) */ - 0x25, 0x01, /* Logical Maximum (1) */ - 0x95, 0x03, /* Report Count (3) */ - 0x75, 0x01, /* Report Size (1) */ - 0x81, 0x02, /* Input (Data, Variable, Absolute) */ - 0x95, 0x01, /* Report Count (1) */ - 0x75, 0x05, /* Report Size (5) */ - 0x81, 0x01, /* Input (Constant) */ - 0x05, 0x01, /* Usage Page (Generic Desktop) */ - 0x09, 0x30, /* Usage (X) */ - 0x09, 0x31, /* Usage (Y) */ - 0x09, 0x38, /* Usage (Wheel) */ - 0x15, 0x81, /* Logical Minimum (-0x7f) */ - 0x25, 0x7f, /* Logical Maximum (0x7f) */ - 0x75, 0x08, /* Report Size (8) */ - 0x95, 0x03, /* Report Count (3) */ - 0x81, 0x06, /* Input (Data, Variable, Relative) */ - 0xc0, /* End Collection */ - 0xc0, /* End Collection */ -}; - -static const uint8_t qemu_tablet_hid_report_descriptor[] = { - 0x05, 0x01, /* Usage Page (Generic Desktop) */ - 0x09, 0x01, /* Usage (Pointer) */ - 0xa1, 0x01, /* Collection (Application) */ - 0x09, 0x01, /* Usage (Pointer) */ - 0xa1, 0x00, /* Collection (Physical) */ - 0x05, 0x09, /* Usage Page (Button) */ - 0x19, 0x01, /* Usage Minimum (1) */ - 0x29, 0x03, /* Usage Maximum (3) */ - 0x15, 0x00, /* Logical Minimum (0) */ - 0x25, 0x01, /* Logical Maximum (1) */ - 0x95, 0x03, /* Report Count (3) */ - 0x75, 0x01, /* Report Size (1) */ - 0x81, 0x02, /* Input (Data, Variable, Absolute) */ - 0x95, 0x01, /* Report Count (1) */ - 0x75, 0x05, /* Report Size (5) */ - 0x81, 0x01, /* Input (Constant) */ - 0x05, 0x01, /* Usage Page (Generic Desktop) */ - 0x09, 0x30, /* Usage (X) */ - 0x09, 0x31, /* Usage (Y) */ - 0x15, 0x00, /* Logical Minimum (0) */ - 0x26, 0xff, 0x7f, /* Logical Maximum (0x7fff) */ - 0x35, 0x00, /* Physical Minimum (0) */ - 0x46, 0xff, 0x7f, /* Physical Maximum (0x7fff) */ - 0x75, 0x10, /* Report Size (16) */ - 0x95, 0x02, /* Report Count (2) */ - 0x81, 0x02, /* Input (Data, Variable, Absolute) */ - 0x05, 0x01, /* Usage Page (Generic Desktop) */ - 0x09, 0x38, /* Usage (Wheel) */ - 0x15, 0x81, /* Logical Minimum (-0x7f) */ - 0x25, 0x7f, /* Logical Maximum (0x7f) */ - 0x35, 0x00, /* Physical Minimum (same as logical) */ - 0x45, 0x00, /* Physical Maximum (same as logical) */ - 0x75, 0x08, /* Report Size (8) */ - 0x95, 0x01, /* Report Count (1) */ - 0x81, 0x06, /* Input (Data, Variable, Relative) */ - 0xc0, /* End Collection */ - 0xc0, /* End Collection */ -}; - -static const uint8_t qemu_keyboard_hid_report_descriptor[] = { - 0x05, 0x01, /* Usage Page (Generic Desktop) */ - 0x09, 0x06, /* Usage (Keyboard) */ - 0xa1, 0x01, /* Collection (Application) */ - 0x75, 0x01, /* Report Size (1) */ - 0x95, 0x08, /* Report Count (8) */ - 0x05, 0x07, /* Usage Page (Key Codes) */ - 0x19, 0xe0, /* Usage Minimum (224) */ - 0x29, 0xe7, /* Usage Maximum (231) */ - 0x15, 0x00, /* Logical Minimum (0) */ - 0x25, 0x01, /* Logical Maximum (1) */ - 0x81, 0x02, /* Input (Data, Variable, Absolute) */ - 0x95, 0x01, /* Report Count (1) */ - 0x75, 0x08, /* Report Size (8) */ - 0x81, 0x01, /* Input (Constant) */ - 0x95, 0x05, /* Report Count (5) */ - 0x75, 0x01, /* Report Size (1) */ - 0x05, 0x08, /* Usage Page (LEDs) */ - 0x19, 0x01, /* Usage Minimum (1) */ - 0x29, 0x05, /* Usage Maximum (5) */ - 0x91, 0x02, /* Output (Data, Variable, Absolute) */ - 0x95, 0x01, /* Report Count (1) */ - 0x75, 0x03, /* Report Size (3) */ - 0x91, 0x01, /* Output (Constant) */ - 0x95, 0x06, /* Report Count (6) */ - 0x75, 0x08, /* Report Size (8) */ - 0x15, 0x00, /* Logical Minimum (0) */ - 0x25, 0xff, /* Logical Maximum (255) */ - 0x05, 0x07, /* Usage Page (Key Codes) */ - 0x19, 0x00, /* Usage Minimum (0) */ - 0x29, 0xff, /* Usage Maximum (255) */ - 0x81, 0x00, /* Input (Data, Array) */ - 0xc0, /* End Collection */ -}; - -#define USB_HID_USAGE_ERROR_ROLLOVER 0x01 -#define USB_HID_USAGE_POSTFAIL 0x02 -#define USB_HID_USAGE_ERROR_UNDEFINED 0x03 - -/* Indices are QEMU keycodes, values are from HID Usage Table. Indices - * above 0x80 are for keys that come after 0xe0 or 0xe1+0x1d or 0xe1+0x9d. */ -static const uint8_t usb_hid_usage_keys[0x100] = { - 0x00, 0x29, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x2d, 0x2e, 0x2a, 0x2b, - 0x14, 0x1a, 0x08, 0x15, 0x17, 0x1c, 0x18, 0x0c, - 0x12, 0x13, 0x2f, 0x30, 0x28, 0xe0, 0x04, 0x16, - 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x33, - 0x34, 0x35, 0xe1, 0x31, 0x1d, 0x1b, 0x06, 0x19, - 0x05, 0x11, 0x10, 0x36, 0x37, 0x38, 0xe5, 0x55, - 0xe2, 0x2c, 0x32, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, - 0x3f, 0x40, 0x41, 0x42, 0x43, 0x53, 0x47, 0x5f, - 0x60, 0x61, 0x56, 0x5c, 0x5d, 0x5e, 0x57, 0x59, - 0x5a, 0x5b, 0x62, 0x63, 0x00, 0x00, 0x00, 0x44, - 0x45, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, - 0xe8, 0xe9, 0x71, 0x72, 0x73, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, - - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0xe4, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x46, - 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4a, - 0x52, 0x4b, 0x00, 0x50, 0x00, 0x4f, 0x00, 0x4d, - 0x51, 0x4e, 0x49, 0x4c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe3, 0xe7, 0x65, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -static void usb_hid_changed(USBHIDState *hs) -{ - hs->changed = 1; - - if (hs->datain) - hs->datain(hs->datain_opaque); - - usb_wakeup(&hs->dev); -} - -static void usb_pointer_event_clear(USBPointerEvent *e, int buttons) { - e->xdx = e->ydy = e->dz = 0; - e->buttons_state = buttons; -} - -static void usb_pointer_event_combine(USBPointerEvent *e, int xyrel, - int x1, int y1, int z1) { - if (xyrel) { - e->xdx += x1; - e->ydy += y1; - } else { - e->xdx = x1; - e->ydy = y1; - } - e->dz += z1; -} - -static void usb_pointer_event(void *opaque, - int x1, int y1, int z1, int buttons_state) -{ - USBHIDState *hs = opaque; - USBMouseState *s = &hs->ptr; - unsigned use_slot = (hs->head + hs->n - 1) & QUEUE_MASK; - unsigned previous_slot = (use_slot - 1) & QUEUE_MASK; - - /* We combine events where feasible to keep the queue small. We shouldn't - * combine anything with the first event of a particular button state, as - * that would change the location of the button state change. When the - * queue is empty, a second event is needed because we don't know if - * the first event changed the button state. */ - if (hs->n == QUEUE_LENGTH) { - /* Queue full. Discard old button state, combine motion normally. */ - s->queue[use_slot].buttons_state = buttons_state; - } else if (hs->n < 2 || - s->queue[use_slot].buttons_state != buttons_state || - s->queue[previous_slot].buttons_state != s->queue[use_slot].buttons_state) { - /* Cannot or should not combine, so add an empty item to the queue. */ - QUEUE_INCR(use_slot); - hs->n++; - usb_pointer_event_clear(&s->queue[use_slot], buttons_state); - } - usb_pointer_event_combine(&s->queue[use_slot], - hs->kind == USB_MOUSE, - x1, y1, z1); - usb_hid_changed(hs); -} - -static void usb_keyboard_event(void *opaque, int keycode) -{ - USBHIDState *hs = opaque; - USBKeyboardState *s = &hs->kbd; - int slot; - - if (hs->n == QUEUE_LENGTH) { - fprintf(stderr, "usb-kbd: warning: key event queue full\n"); - return; - } - slot = (hs->head + hs->n) & QUEUE_MASK; hs->n++; - s->keycodes[slot] = keycode; - usb_hid_changed(hs); -} - -static void usb_keyboard_process_keycode(USBHIDState *hs) -{ - USBKeyboardState *s = &hs->kbd; - uint8_t hid_code, key; - int i, keycode, slot; - - if (hs->n == 0) { - return; - } - slot = hs->head & QUEUE_MASK; QUEUE_INCR(hs->head); hs->n--; - keycode = s->keycodes[slot]; - - key = keycode & 0x7f; - hid_code = usb_hid_usage_keys[key | ((s->modifiers >> 1) & (1 << 7))]; - s->modifiers &= ~(1 << 8); - - switch (hid_code) { - case 0x00: - return; - - case 0xe0: - if (s->modifiers & (1 << 9)) { - s->modifiers ^= 3 << 8; - return; - } - case 0xe1 ... 0xe7: - if (keycode & (1 << 7)) { - s->modifiers &= ~(1 << (hid_code & 0x0f)); - return; - } - case 0xe8 ... 0xef: - s->modifiers |= 1 << (hid_code & 0x0f); - return; - } - - if (keycode & (1 << 7)) { - for (i = s->keys - 1; i >= 0; i --) - if (s->key[i] == hid_code) { - s->key[i] = s->key[-- s->keys]; - s->key[s->keys] = 0x00; - break; - } - if (i < 0) - return; - } else { - for (i = s->keys - 1; i >= 0; i --) - if (s->key[i] == hid_code) - break; - if (i < 0) { - if (s->keys < sizeof(s->key)) - s->key[s->keys ++] = hid_code; - } else - return; - } -} - -static inline int int_clamp(int val, int vmin, int vmax) -{ - if (val < vmin) - return vmin; - else if (val > vmax) - return vmax; - else - return val; -} - -static int usb_pointer_poll(USBHIDState *hs, uint8_t *buf, int len) -{ - int dx, dy, dz, b, l; - int index; - USBMouseState *s = &hs->ptr; - USBPointerEvent *e; - - if (!s->mouse_grabbed) { - qemu_activate_mouse_event_handler(s->eh_entry); - s->mouse_grabbed = 1; - } - - /* When the buffer is empty, return the last event. Relative - movements will all be zero. */ - index = (hs->n ? hs->head : hs->head - 1); - e = &s->queue[index & QUEUE_MASK]; - - if (hs->kind == USB_MOUSE) { - dx = int_clamp(e->xdx, -127, 127); - dy = int_clamp(e->ydy, -127, 127); - e->xdx -= dx; - e->ydy -= dy; - } else { - dx = e->xdx; - dy = e->ydy; - } - dz = int_clamp(e->dz, -127, 127); - e->dz -= dz; - - b = 0; - if (e->buttons_state & MOUSE_EVENT_LBUTTON) - b |= 0x01; - if (e->buttons_state & MOUSE_EVENT_RBUTTON) - b |= 0x02; - if (e->buttons_state & MOUSE_EVENT_MBUTTON) - b |= 0x04; - - if (hs->n && - !e->dz && - (hs->kind == USB_TABLET || (!e->xdx && !e->ydy))) { - /* that deals with this event */ - QUEUE_INCR(hs->head); - hs->n--; - } - - /* Appears we have to invert the wheel direction */ - dz = 0 - dz; - l = 0; - switch (hs->kind) { - case USB_MOUSE: - if (len > l) - buf[l++] = b; - if (len > l) - buf[l++] = dx; - if (len > l) - buf[l++] = dy; - if (len > l) - buf[l++] = dz; - break; - - case USB_TABLET: - if (len > l) - buf[l++] = b; - if (len > l) - buf[l++] = dx & 0xff; - if (len > l) - buf[l++] = dx >> 8; - if (len > l) - buf[l++] = dy & 0xff; - if (len > l) - buf[l++] = dy >> 8; - if (len > l) - buf[l++] = dz; - break; - - default: - abort(); - } - - return l; -} - -static int usb_keyboard_poll(USBHIDState *hs, uint8_t *buf, int len) -{ - USBKeyboardState *s = &hs->kbd; - if (len < 2) - return 0; - - usb_keyboard_process_keycode(hs); - - buf[0] = s->modifiers & 0xff; - buf[1] = 0; - if (s->keys > 6) - memset(buf + 2, USB_HID_USAGE_ERROR_ROLLOVER, MIN(8, len) - 2); - else - memcpy(buf + 2, s->key, MIN(8, len) - 2); - - return MIN(8, len); -} - -static int usb_keyboard_write(USBKeyboardState *s, uint8_t *buf, int len) -{ - if (len > 0) { - int ledstate = 0; - /* 0x01: Num Lock LED - * 0x02: Caps Lock LED - * 0x04: Scroll Lock LED - * 0x08: Compose LED - * 0x10: Kana LED */ - s->leds = buf[0]; - if (s->leds & 0x04) - ledstate |= QEMU_SCROLL_LOCK_LED; - if (s->leds & 0x01) - ledstate |= QEMU_NUM_LOCK_LED; - if (s->leds & 0x02) - ledstate |= QEMU_CAPS_LOCK_LED; - kbd_put_ledstate(ledstate); - } - return 0; -} - -static void usb_mouse_handle_reset(USBDevice *dev) -{ - USBHIDState *s = (USBHIDState *)dev; - - memset(s->ptr.queue, 0, sizeof (s->ptr.queue)); - s->head = 0; - s->n = 0; - s->protocol = 1; -} - -static void usb_keyboard_handle_reset(USBDevice *dev) -{ - USBHIDState *s = (USBHIDState *)dev; - - qemu_add_kbd_event_handler(usb_keyboard_event, s); - memset(s->kbd.keycodes, 0, sizeof (s->kbd.keycodes)); - s->head = 0; - s->n = 0; - memset(s->kbd.key, 0, sizeof (s->kbd.key)); - s->kbd.keys = 0; - s->protocol = 1; -} - -static void usb_hid_set_next_idle(USBHIDState *s, int64_t curtime) -{ - s->next_idle_clock = curtime + (get_ticks_per_sec() * s->idle * 4) / 1000; -} - -static int usb_hid_handle_control(USBDevice *dev, USBPacket *p, - int request, int value, int index, int length, uint8_t *data) -{ - USBHIDState *s = (USBHIDState *)dev; - int ret; - - ret = usb_desc_handle_control(dev, p, request, value, index, length, data); - if (ret >= 0) { - return ret; - } - - ret = 0; - switch(request) { - case DeviceRequest | USB_REQ_GET_INTERFACE: - data[0] = 0; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_INTERFACE: - ret = 0; - break; - /* hid specific requests */ - case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: - switch(value >> 8) { - case 0x22: - if (s->kind == USB_MOUSE) { - memcpy(data, qemu_mouse_hid_report_descriptor, - sizeof(qemu_mouse_hid_report_descriptor)); - ret = sizeof(qemu_mouse_hid_report_descriptor); - } else if (s->kind == USB_TABLET) { - memcpy(data, qemu_tablet_hid_report_descriptor, - sizeof(qemu_tablet_hid_report_descriptor)); - ret = sizeof(qemu_tablet_hid_report_descriptor); - } else if (s->kind == USB_KEYBOARD) { - memcpy(data, qemu_keyboard_hid_report_descriptor, - sizeof(qemu_keyboard_hid_report_descriptor)); - ret = sizeof(qemu_keyboard_hid_report_descriptor); - } - break; - default: - goto fail; - } - break; - case GET_REPORT: - if (s->kind == USB_MOUSE || s->kind == USB_TABLET) { - ret = usb_pointer_poll(s, data, length); - } else if (s->kind == USB_KEYBOARD) { - ret = usb_keyboard_poll(s, data, length); - } - s->changed = s->n > 0; - break; - case SET_REPORT: - if (s->kind == USB_KEYBOARD) - ret = usb_keyboard_write(&s->kbd, data, length); - else - goto fail; - break; - case GET_PROTOCOL: - if (s->kind != USB_KEYBOARD && s->kind != USB_MOUSE) - goto fail; - ret = 1; - data[0] = s->protocol; - break; - case SET_PROTOCOL: - if (s->kind != USB_KEYBOARD && s->kind != USB_MOUSE) - goto fail; - ret = 0; - s->protocol = value; - break; - case GET_IDLE: - ret = 1; - data[0] = s->idle; - break; - case SET_IDLE: - s->idle = (uint8_t) (value >> 8); - usb_hid_set_next_idle(s, qemu_get_clock_ns(vm_clock)); - ret = 0; - break; - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static int usb_hid_handle_data(USBDevice *dev, USBPacket *p) -{ - USBHIDState *s = (USBHIDState *)dev; - int ret = 0; - - switch(p->pid) { - case USB_TOKEN_IN: - if (p->devep == 1) { - int64_t curtime = qemu_get_clock_ns(vm_clock); - if (!s->changed && (!s->idle || s->next_idle_clock - curtime > 0)) - return USB_RET_NAK; - usb_hid_set_next_idle(s, curtime); - if (s->kind == USB_MOUSE || s->kind == USB_TABLET) { - ret = usb_pointer_poll(s, p->data, p->len); - } - else if (s->kind == USB_KEYBOARD) { - ret = usb_keyboard_poll(s, p->data, p->len); - } - s->changed = s->n > 0; - } else { - goto fail; - } - break; - case USB_TOKEN_OUT: - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static void usb_hid_handle_destroy(USBDevice *dev) -{ - USBHIDState *s = (USBHIDState *)dev; - - switch(s->kind) { - case USB_KEYBOARD: - qemu_remove_kbd_event_handler(); - break; - default: - qemu_remove_mouse_event_handler(s->ptr.eh_entry); - } -} - -static int usb_hid_initfn(USBDevice *dev, int kind) -{ - USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev); - - usb_desc_init(dev); - s->kind = kind; - - if (s->kind == USB_MOUSE) { - s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s, - 0, "QEMU USB Mouse"); - } else if (s->kind == USB_TABLET) { - s->ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s, - 1, "QEMU USB Tablet"); - } - - /* Force poll routine to be run and grab input the first time. */ - s->changed = 1; - return 0; -} - -static int usb_tablet_initfn(USBDevice *dev) -{ - return usb_hid_initfn(dev, USB_TABLET); -} - -static int usb_mouse_initfn(USBDevice *dev) -{ - return usb_hid_initfn(dev, USB_MOUSE); -} - -static int usb_keyboard_initfn(USBDevice *dev) -{ - return usb_hid_initfn(dev, USB_KEYBOARD); -} - -void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)) -{ - USBHIDState *s = (USBHIDState *)dev; - - s->datain_opaque = opaque; - s->datain = datain; -} - -static int usb_hid_post_load(void *opaque, int version_id) -{ - USBHIDState *s = opaque; - - if (s->idle) { - usb_hid_set_next_idle(s, qemu_get_clock_ns(vm_clock)); - } - return 0; -} - -static const VMStateDescription vmstate_usb_ptr_queue = { - .name = "usb-ptr-queue", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField []) { - VMSTATE_INT32(xdx, USBPointerEvent), - VMSTATE_INT32(ydy, USBPointerEvent), - VMSTATE_INT32(dz, USBPointerEvent), - VMSTATE_INT32(buttons_state, USBPointerEvent), - VMSTATE_END_OF_LIST() - } -}; -static const VMStateDescription vmstate_usb_ptr = { - .name = "usb-ptr", - .version_id = 1, - .minimum_version_id = 1, - .post_load = usb_hid_post_load, - .fields = (VMStateField []) { - VMSTATE_USB_DEVICE(dev, USBHIDState), - VMSTATE_STRUCT_ARRAY(ptr.queue, USBHIDState, QUEUE_LENGTH, 0, - vmstate_usb_ptr_queue, USBPointerEvent), - VMSTATE_UINT32(head, USBHIDState), - VMSTATE_UINT32(n, USBHIDState), - VMSTATE_INT32(protocol, USBHIDState), - VMSTATE_UINT8(idle, USBHIDState), - VMSTATE_END_OF_LIST() - } -}; - -static const VMStateDescription vmstate_usb_kbd = { - .name = "usb-kbd", - .version_id = 1, - .minimum_version_id = 1, - .post_load = usb_hid_post_load, - .fields = (VMStateField []) { - VMSTATE_USB_DEVICE(dev, USBHIDState), - VMSTATE_UINT32_ARRAY(kbd.keycodes, USBHIDState, QUEUE_LENGTH), - VMSTATE_UINT32(head, USBHIDState), - VMSTATE_UINT32(n, USBHIDState), - VMSTATE_UINT16(kbd.modifiers, USBHIDState), - VMSTATE_UINT8(kbd.leds, USBHIDState), - VMSTATE_UINT8_ARRAY(kbd.key, USBHIDState, 16), - VMSTATE_INT32(kbd.keys, USBHIDState), - VMSTATE_INT32(protocol, USBHIDState), - VMSTATE_UINT8(idle, USBHIDState), - VMSTATE_END_OF_LIST() - } -}; - -static struct USBDeviceInfo hid_info[] = { - { - .product_desc = "QEMU USB Tablet", - .qdev.name = "usb-tablet", - .usbdevice_name = "tablet", - .qdev.size = sizeof(USBHIDState), - .qdev.vmsd = &vmstate_usb_ptr, - .usb_desc = &desc_tablet, - .init = usb_tablet_initfn, - .handle_packet = usb_generic_handle_packet, - .handle_reset = usb_mouse_handle_reset, - .handle_control = usb_hid_handle_control, - .handle_data = usb_hid_handle_data, - .handle_destroy = usb_hid_handle_destroy, - },{ - .product_desc = "QEMU USB Mouse", - .qdev.name = "usb-mouse", - .usbdevice_name = "mouse", - .qdev.size = sizeof(USBHIDState), - .qdev.vmsd = &vmstate_usb_ptr, - .usb_desc = &desc_mouse, - .init = usb_mouse_initfn, - .handle_packet = usb_generic_handle_packet, - .handle_reset = usb_mouse_handle_reset, - .handle_control = usb_hid_handle_control, - .handle_data = usb_hid_handle_data, - .handle_destroy = usb_hid_handle_destroy, - },{ - .product_desc = "QEMU USB Keyboard", - .qdev.name = "usb-kbd", - .usbdevice_name = "keyboard", - .qdev.size = sizeof(USBHIDState), - .qdev.vmsd = &vmstate_usb_kbd, - .usb_desc = &desc_keyboard, - .init = usb_keyboard_initfn, - .handle_packet = usb_generic_handle_packet, - .handle_reset = usb_keyboard_handle_reset, - .handle_control = usb_hid_handle_control, - .handle_data = usb_hid_handle_data, - .handle_destroy = usb_hid_handle_destroy, - },{ - /* end of list */ - } -}; - -static void usb_hid_register_devices(void) -{ - usb_qdev_register_many(hid_info); -} -device_init(usb_hid_register_devices) diff --git a/plugins/USBqemu/qemu-usb/usb-hub.cpp b/plugins/USBqemu/qemu-usb/usb-hub.cpp deleted file mode 100644 index 95efd172ed..0000000000 --- a/plugins/USBqemu/qemu-usb/usb-hub.cpp +++ /dev/null @@ -1,547 +0,0 @@ -/* - * QEMU USB HUB emulation - * - * Copyright (c) 2005 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "USBinternal.h" - -//#define DEBUG - -#define NUM_PORTS 8 - -typedef struct USBHubPort { - USBPort port; - uint16_t wPortStatus; - uint16_t wPortChange; -} USBHubPort; - -typedef struct USBHubState { - USBDevice dev; - USBHubPort ports[NUM_PORTS]; -} USBHubState; - -#define ClearHubFeature (0x2000 | USB_REQ_CLEAR_FEATURE) -#define ClearPortFeature (0x2300 | USB_REQ_CLEAR_FEATURE) -#define GetHubDescriptor (0xa000 | USB_REQ_GET_DESCRIPTOR) -#define GetHubStatus (0xa000 | USB_REQ_GET_STATUS) -#define GetPortStatus (0xa300 | USB_REQ_GET_STATUS) -#define SetHubFeature (0x2000 | USB_REQ_SET_FEATURE) -#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE) - -#define PORT_STAT_CONNECTION 0x0001 -#define PORT_STAT_ENABLE 0x0002 -#define PORT_STAT_SUSPEND 0x0004 -#define PORT_STAT_OVERCURRENT 0x0008 -#define PORT_STAT_RESET 0x0010 -#define PORT_STAT_POWER 0x0100 -#define PORT_STAT_LOW_SPEED 0x0200 -#define PORT_STAT_HIGH_SPEED 0x0400 -#define PORT_STAT_TEST 0x0800 -#define PORT_STAT_INDICATOR 0x1000 - -#define PORT_STAT_C_CONNECTION 0x0001 -#define PORT_STAT_C_ENABLE 0x0002 -#define PORT_STAT_C_SUSPEND 0x0004 -#define PORT_STAT_C_OVERCURRENT 0x0008 -#define PORT_STAT_C_RESET 0x0010 - -#define PORT_CONNECTION 0 -#define PORT_ENABLE 1 -#define PORT_SUSPEND 2 -#define PORT_OVERCURRENT 3 -#define PORT_RESET 4 -#define PORT_POWER 8 -#define PORT_LOWSPEED 9 -#define PORT_HIGHSPEED 10 -#define PORT_C_CONNECTION 16 -#define PORT_C_ENABLE 17 -#define PORT_C_SUSPEND 18 -#define PORT_C_OVERCURRENT 19 -#define PORT_C_RESET 20 -#define PORT_TEST 21 -#define PORT_INDICATOR 22 - -/* same as Linux kernel root hubs */ - -enum { - STR_MANUFACTURER = 1, - STR_PRODUCT, - STR_SERIALNUMBER, -}; - -static const USBDescStrings desc_strings = { - [STR_MANUFACTURER] = "QEMU " QEMU_VERSION, - [STR_PRODUCT] = "QEMU USB Hub", - [STR_SERIALNUMBER] = "314159", -}; - -static const USBDescIface desc_iface_hub = { - .bInterfaceNumber = 0, - .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_HUB, - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_IN | 0x01, - .bmAttributes = USB_ENDPOINT_XFER_INT, - .wMaxPacketSize = 1 + (NUM_PORTS + 7) / 8, - .bInterval = 0xff, - }, - } -}; - -static const USBDescDevice desc_device_hub = { - .bcdUSB = 0x0110, - .bDeviceClass = USB_CLASS_HUB, - .bMaxPacketSize0 = 8, - .bNumConfigurations = 1, - .confs = (USBDescConfig[]) { - { - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .bmAttributes = 0xe0, - .nif = 1, - .ifs = &desc_iface_hub, - }, - }, -}; - -static const USBDesc desc_hub = { - .id = { - .idVendor = 0, - .idProduct = 0, - .bcdDevice = 0x0101, - .iManufacturer = STR_MANUFACTURER, - .iProduct = STR_PRODUCT, - .iSerialNumber = STR_SERIALNUMBER, - }, - .full = &desc_device_hub, - .str = desc_strings, -}; - -static const uint8_t qemu_hub_hub_descriptor[] = -{ - 0x00, /* u8 bLength; patched in later */ - 0x29, /* u8 bDescriptorType; Hub-descriptor */ - 0x00, /* u8 bNbrPorts; (patched later) */ - 0x0a, /* u16 wHubCharacteristics; */ - 0x00, /* (per-port OC, no power switching) */ - 0x01, /* u8 bPwrOn2pwrGood; 2ms */ - 0x00 /* u8 bHubContrCurrent; 0 mA */ - - /* DeviceRemovable and PortPwrCtrlMask patched in later */ -}; - -static void usb_hub_attach(USBPort *port1) -{ - USBHubState *s = port1->opaque; - USBHubPort *port = &s->ports[port1->index]; - - port->wPortStatus |= PORT_STAT_CONNECTION; - port->wPortChange |= PORT_STAT_C_CONNECTION; - if (port->port.dev->speed == USB_SPEED_LOW) { - port->wPortStatus |= PORT_STAT_LOW_SPEED; - } else { - port->wPortStatus &= ~PORT_STAT_LOW_SPEED; - } -} - -static void usb_hub_detach(USBPort *port1) -{ - USBHubState *s = port1->opaque; - USBHubPort *port = &s->ports[port1->index]; - - /* Let upstream know the device on this port is gone */ - s->dev.port->ops->child_detach(s->dev.port, port1->dev); - - port->wPortStatus &= ~PORT_STAT_CONNECTION; - port->wPortChange |= PORT_STAT_C_CONNECTION; - if (port->wPortStatus & PORT_STAT_ENABLE) { - port->wPortStatus &= ~PORT_STAT_ENABLE; - port->wPortChange |= PORT_STAT_C_ENABLE; - } -} - -static void usb_hub_child_detach(USBPort *port1, USBDevice *child) -{ - USBHubState *s = port1->opaque; - - /* Pass along upstream */ - s->dev.port->ops->child_detach(s->dev.port, child); -} - -static void usb_hub_wakeup(USBPort *port1) -{ - USBHubState *s = port1->opaque; - USBHubPort *port = &s->ports[port1->index]; - - if (port->wPortStatus & PORT_STAT_SUSPEND) { - port->wPortChange |= PORT_STAT_C_SUSPEND; - usb_wakeup(&s->dev); - } -} - -static void usb_hub_complete(USBPort *port, USBPacket *packet) -{ - USBHubState *s = port->opaque; - - /* - * Just pass it along upstream for now. - * - * If we ever inplement usb 2.0 split transactions this will - * become a little more complicated ... - */ - usb_packet_complete(&s->dev, packet); -} - -static void usb_hub_handle_attach(USBDevice *dev) -{ - USBHubState *s = DO_UPCAST(USBHubState, dev, dev); - int i; - - for (i = 0; i < NUM_PORTS; i++) { - usb_port_location(&s->ports[i].port, dev->port, i+1); - } -} - -static void usb_hub_handle_reset(USBDevice *dev) -{ - /* XXX: do it */ -} - -static int usb_hub_handle_control(USBDevice *dev, USBPacket *p, - int request, int value, int index, int length, uint8_t *data) -{ - USBHubState *s = (USBHubState *)dev; - int ret; - - ret = usb_desc_handle_control(dev, p, request, value, index, length, data); - if (ret >= 0) { - return ret; - } - - switch(request) { - case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: - if (value == 0 && index != 0x81) { /* clear ep halt */ - goto fail; - } - ret = 0; - break; - case DeviceRequest | USB_REQ_GET_INTERFACE: - data[0] = 0; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_INTERFACE: - ret = 0; - break; - /* usb specific requests */ - case GetHubStatus: - data[0] = 0; - data[1] = 0; - data[2] = 0; - data[3] = 0; - ret = 4; - break; - case GetPortStatus: - { - unsigned int n = index - 1; - USBHubPort *port; - if (n >= NUM_PORTS) { - goto fail; - } - port = &s->ports[n]; - data[0] = port->wPortStatus; - data[1] = port->wPortStatus >> 8; - data[2] = port->wPortChange; - data[3] = port->wPortChange >> 8; - ret = 4; - } - break; - case SetHubFeature: - case ClearHubFeature: - if (value == 0 || value == 1) { - } else { - goto fail; - } - ret = 0; - break; - case SetPortFeature: - { - unsigned int n = index - 1; - USBHubPort *port; - USBDevice *dev; - if (n >= NUM_PORTS) { - goto fail; - } - port = &s->ports[n]; - dev = port->port.dev; - switch(value) { - case PORT_SUSPEND: - port->wPortStatus |= PORT_STAT_SUSPEND; - break; - case PORT_RESET: - if (dev) { - usb_send_msg(dev, USB_MSG_RESET); - port->wPortChange |= PORT_STAT_C_RESET; - /* set enable bit */ - port->wPortStatus |= PORT_STAT_ENABLE; - } - break; - case PORT_POWER: - break; - default: - goto fail; - } - ret = 0; - } - break; - case ClearPortFeature: - { - unsigned int n = index - 1; - USBHubPort *port; - - if (n >= NUM_PORTS) { - goto fail; - } - port = &s->ports[n]; - switch(value) { - case PORT_ENABLE: - port->wPortStatus &= ~PORT_STAT_ENABLE; - break; - case PORT_C_ENABLE: - port->wPortChange &= ~PORT_STAT_C_ENABLE; - break; - case PORT_SUSPEND: - port->wPortStatus &= ~PORT_STAT_SUSPEND; - break; - case PORT_C_SUSPEND: - port->wPortChange &= ~PORT_STAT_C_SUSPEND; - break; - case PORT_C_CONNECTION: - port->wPortChange &= ~PORT_STAT_C_CONNECTION; - break; - case PORT_C_OVERCURRENT: - port->wPortChange &= ~PORT_STAT_C_OVERCURRENT; - break; - case PORT_C_RESET: - port->wPortChange &= ~PORT_STAT_C_RESET; - break; - default: - goto fail; - } - ret = 0; - } - break; - case GetHubDescriptor: - { - unsigned int n, limit, var_hub_size = 0; - memcpy(data, qemu_hub_hub_descriptor, - sizeof(qemu_hub_hub_descriptor)); - data[2] = NUM_PORTS; - - /* fill DeviceRemovable bits */ - limit = ((NUM_PORTS + 1 + 7) / 8) + 7; - for (n = 7; n < limit; n++) { - data[n] = 0x00; - var_hub_size++; - } - - /* fill PortPwrCtrlMask bits */ - limit = limit + ((NUM_PORTS + 7) / 8); - for (;n < limit; n++) { - data[n] = 0xff; - var_hub_size++; - } - - ret = sizeof(qemu_hub_hub_descriptor) + var_hub_size; - data[0] = ret; - break; - } - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static int usb_hub_handle_data(USBDevice *dev, USBPacket *p) -{ - USBHubState *s = (USBHubState *)dev; - int ret; - - switch(p->pid) { - case USB_TOKEN_IN: - if (p->devep == 1) { - USBHubPort *port; - unsigned int status; - int i, n; - n = (NUM_PORTS + 1 + 7) / 8; - if (p->len == 1) { /* FreeBSD workaround */ - n = 1; - } else if (n > p->len) { - return USB_RET_BABBLE; - } - status = 0; - for(i = 0; i < NUM_PORTS; i++) { - port = &s->ports[i]; - if (port->wPortChange) - status |= (1 << (i + 1)); - } - if (status != 0) { - for(i = 0; i < n; i++) { - p->data[i] = status >> (8 * i); - } - ret = n; - } else { - ret = USB_RET_NAK; /* usb11 11.13.1 */ - } - } else { - goto fail; - } - break; - case USB_TOKEN_OUT: - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static int usb_hub_broadcast_packet(USBHubState *s, USBPacket *p) -{ - USBHubPort *port; - USBDevice *dev; - int i, ret; - - for(i = 0; i < NUM_PORTS; i++) { - port = &s->ports[i]; - dev = port->port.dev; - if (dev && (port->wPortStatus & PORT_STAT_ENABLE)) { - ret = usb_handle_packet(dev, p); - if (ret != USB_RET_NODEV) { - return ret; - } - } - } - return USB_RET_NODEV; -} - -static int usb_hub_handle_packet(USBDevice *dev, USBPacket *p) -{ - USBHubState *s = (USBHubState *)dev; - -#if defined(DEBUG) && 0 - printf("usb_hub: pid=0x%x\n", pid); -#endif - if (dev->state == USB_STATE_DEFAULT && - dev->addr != 0 && - p->devaddr != dev->addr && - (p->pid == USB_TOKEN_SETUP || - p->pid == USB_TOKEN_OUT || - p->pid == USB_TOKEN_IN)) { - /* broadcast the packet to the devices */ - return usb_hub_broadcast_packet(s, p); - } - return usb_generic_handle_packet(dev, p); -} - -static void usb_hub_handle_destroy(USBDevice *dev) -{ - USBHubState *s = (USBHubState *)dev; - int i; - - for (i = 0; i < NUM_PORTS; i++) { - usb_unregister_port(usb_bus_from_device(dev), - &s->ports[i].port); - } -} - -static USBPortOps usb_hub_port_ops = { - .attach = usb_hub_attach, - .detach = usb_hub_detach, - .child_detach = usb_hub_child_detach, - .wakeup = usb_hub_wakeup, - .complete = usb_hub_complete, -}; - -static int usb_hub_initfn(USBDevice *dev) -{ - USBHubState *s = DO_UPCAST(USBHubState, dev, dev); - USBHubPort *port; - int i; - - usb_desc_init(dev); - for (i = 0; i < NUM_PORTS; i++) { - port = &s->ports[i]; - usb_register_port(usb_bus_from_device(dev), - &port->port, s, i, &usb_hub_port_ops, - USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL); - port->wPortStatus = PORT_STAT_POWER; - port->wPortChange = 0; - } - return 0; -} - -static const VMStateDescription vmstate_usb_hub_port = { - .name = "usb-hub-port", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField []) { - VMSTATE_UINT16(wPortStatus, USBHubPort), - VMSTATE_UINT16(wPortChange, USBHubPort), - VMSTATE_END_OF_LIST() - } -}; - -static const VMStateDescription vmstate_usb_hub = { - .name = "usb-hub", - .version_id = 1, - .minimum_version_id = 1, - .fields = (VMStateField []) { - VMSTATE_USB_DEVICE(dev, USBHubState), - VMSTATE_STRUCT_ARRAY(ports, USBHubState, NUM_PORTS, 0, - vmstate_usb_hub_port, USBHubPort), - VMSTATE_END_OF_LIST() - } -}; - -static struct USBDeviceInfo hub_info = { - .product_desc = "QEMU USB Hub", - .qdev.name = "usb-hub", - .qdev.fw_name = "hub", - .qdev.size = sizeof(USBHubState), - .qdev.vmsd = &vmstate_usb_hub, - .usb_desc = &desc_hub, - .init = usb_hub_initfn, - .handle_packet = usb_hub_handle_packet, - .handle_attach = usb_hub_handle_attach, - .handle_reset = usb_hub_handle_reset, - .handle_control = usb_hub_handle_control, - .handle_data = usb_hub_handle_data, - .handle_destroy = usb_hub_handle_destroy, -}; - -static void usb_hub_register_devices(void) -{ - usb_qdev_register(&hub_info); -} -device_init(usb_hub_register_devices) diff --git a/plugins/USBqemu/qemu-usb/usb-kbd.cpp b/plugins/USBqemu/qemu-usb/usb-kbd.cpp deleted file mode 100644 index 3f07ecf215..0000000000 --- a/plugins/USBqemu/qemu-usb/usb-kbd.cpp +++ /dev/null @@ -1,2114 +0,0 @@ -/* - * QEMU USB HID devices - * - * Copyright (c) 2005 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "USBinternal.h" - -/* HID interface requests */ -#define GET_REPORT 0xa101 -#define GET_IDLE 0xa102 -#define GET_PROTOCOL 0xa103 -#define SET_IDLE 0x210a -#define SET_PROTOCOL 0x210b - -#define USB_MOUSE 1 -#define USB_TABLET 2 - -typedef struct USBKeyboardState { - USBDevice dev; - int keyboard_grabbed; -} USBKeyboardState; - -USBDeviceInfo devinfo; - - -#define VK_BASED - -#ifdef VK_BASED -static const uint8_t vk_to_key_code[] = { -0x00, //FAIL: 0x00 -0x00, //FAIL: LMOUSE -0x00, //FAIL: RMOUSE -0x00, //FAIL: Break -0x00, //FAIL: MMOUSE -0x00, //FAIL: X1MOUSE -0x00, //FAIL: X2MOUSE -0x00, //FAIL: 0x00 -0x2A, //OK: Backspace -0x2B, //OK: Tab -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x9C, //OK: Clear -0x28, //FAIL: ENTER -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: SHIFT -0x00, //FAIL: CTRL -0x00, //FAIL: ALT -0x48, //OK: Pause -0x39, //OK: Caps Lock -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -//0x00, //FAIL: 0x00 -//0x00, //FAIL: 0x00 -//0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x29, //FAIL: ESC -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x2C, //OK: Spacebar -#ifdef ENABLE_KEYPAD_Fx -0x4B, //FAIL: PAGE UP -0x4E, //FAIL: PAGE DOWN -0x4D, //OK: End -0x4A, //OK: Home -0x50, //FAIL: LEFT ARROW -0x52, //FAIL: UP ARROW -0x4F, //FAIL: RIGHT ARROW -0x51, //FAIL: DOWN ARROW -0x77, //OK: Select -0x00, //FAIL: PRINT -0x74, //OK: Execute -0x46, //FAIL: PRINT SCREEN -0x49, //FAIL: INS -0x4C, //FAIL: DEL -0x75, //OK: Help VK_HOME -#else -0x00, //FAIL: PAGE UP -0x00, //FAIL: PAGE DOWN -0x00, //OK: End -0x00, //OK: Home -0x00, //FAIL: LEFT ARROW -0x00, //FAIL: UP ARROW -0x00, //FAIL: RIGHT ARROW -0x00, //FAIL: DOWN ARROW -0x00, //OK: Select -0x00, //FAIL: PRINT -0x00, //OK: Execute -0x00, //FAIL: PRINT SCREEN -0x00, //FAIL: INS -0x00, //FAIL: DEL -0x00, //OK: Help VK_HOME -#endif -0x27, //OK: 0 -0x1E, //OK: 1 -0x1F, //OK: 2 -0x20, //OK: 3 -0x21, //OK: 4 -0x22, //OK: 5 -0x23, //OK: 6 -0x24, //OK: 7 -0x25, //OK: 8 -0x26, //OK: 9 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: not found -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x04, //OK: A -0x05, //OK: B -0x06, //OK: C -0x07, //OK: D -0x08, //OK: E -0x09, //OK: F -0x0A, //OK: G -0x0B, //OK: H -0x0C, //OK: I -0x0D, //OK: J -0x0E, //OK: K -0x0F, //OK: L -0x10, //OK: M -0x11, //OK: N -0x12, //OK: O -0x13, //OK: P -0x14, //OK: Q -0x15, //OK: R -0x16, //OK: S -0x17, //OK: T -0x18, //OK: U -0x19, //OK: V -0x1A, //OK: W -0x1B, //OK: X -0x1C, //OK: Y -0x1D, //OK: Z -#ifdef ENABLE_KEYPAD_Fx -0xE3, //OK: LGUI -0xE7, //OK: RGUI -0x65, //OK: Application -0x00, //FAIL: 0x00 -0x00, //FAIL: SLEEP -0x62, //OK: Keypad 0 -0x59, //OK: Keypad 1 -0x5A, //OK: Keypad 2 -0x5B, //OK: Keypad 3 -0x5C, //OK: Keypad 4 -0x5D, //OK: Keypad 5 -0x5E, //OK: Keypad 6 -0x5F, //OK: Keypad 7 -0x60, //OK: Keypad 8 -0x61, //OK: Keypad 9 -0x55, //OK: Keypad * -0x57, //OK: Keypad + -0x9F, //OK: Separator -0x56, //OK: Keypad - -0x63, //OK: Keypad . -0x54, //OK: Keypad / -0x3A, //OK: F1 -0x3B, //OK: F2 -0x3C, //OK: F3 -0x3D, //OK: F4 -0x3E, //OK: F5 -0x3F, //OK: F6 -0x40, //OK: F7 -0x41, //OK: F8 -0x42, //OK: F9 -0x43, //OK: F10 -0x44, //OK: F11 -0x45, //OK: F12 -0x68, //OK: F13 -0x69, //OK: F14 -0x6A, //OK: F15 -0x6B, //OK: F16 -0x6C, //OK: F17 -0x6D, //OK: F18 -0x6E, //OK: F19 -0x6F, //OK: F20 -0x70, //OK: F21 -0x71, //OK: F22 -0x72, //OK: F23 -0x73, //OK: F24 -#else -0x00, //OK: LGUI -0x00, //OK: RGUI -0x00, //OK: Application -0x00, //FAIL: 0x00 -0x00, //FAIL: SLEEP -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00, -#endif -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x83, //OK: NUM LOCK -0x47, //OK: Scroll Lock -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0xE1, //OK: LSHIFT -0xE5, //OK: RSHIFT -0xE0, //OK: LCONTROL -0xE4, //OK: RCONTROL -0xE3, //OK: LGUI -0xE7, //OK: RGUI -0x00, //FAIL: Windows 2000/XP: Browser Back -0x00, //FAIL: Windows 2000/XP: Browser Forward -0x00, //FAIL: Windows 2000/XP: Browser Refresh -0x00, //FAIL: Windows 2000/XP: Browser Stop -0x00, //FAIL: Windows 2000/XP: Browser Search -0x00, //FAIL: Windows 2000/XP: Browser Favorites -0x00, //FAIL: Windows 2000/XP: Browser Start and Home -0x00, //FAIL: Windows 2000/XP: Volume Mute -0x00, //FAIL: Windows 2000/XP: Volume Down -0x00, //FAIL: Windows 2000/XP: Volume Up -0x00, //FAIL: Windows 2000/XP: Next Track -0x00, //FAIL: Windows 2000/XP: Previous Track -0x00, //FAIL: Windows 2000/XP: Stop Media -0x00, //FAIL: Windows 2000/XP: Play/Pause Media -0x00, //FAIL: Windows 2000/XP: Start Mail -0x00, //FAIL: Windows 2000/XP: Select Media -0x00, //FAIL: Windows 2000/XP: Start Application 1 -0x00, //FAIL: Windows 2000/XP: Start Application 2 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x33, //FAIL: Windows 2000/XP: For the US standard keyboard, the ';:' key -0x2E, //FAIL: Windows 2000/XP: For any country/region, the '+' -0x36, //FAIL: Windows 2000/XP: For any country/region, the ',' -0x2D, //FAIL: Windows 2000/XP: For any country/region, the '-' -0x37, //FAIL: Windows 2000/XP: For any country/region, the '.' -0x38, //FAIL: Windows 2000/XP: For the US standard keyboard, the '/?' key -0x35, //FAIL: Windows 2000/XP: For the US standard keyboard, the '`~' key -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: not found -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x2F, //FAIL: Windows 2000/XP: For the US standard keyboard, the '[{' key -0x31, //FAIL: Windows 2000/XP: For the US standard keyboard, the '\|' key -0x30, //FAIL: Windows 2000/XP: For the US standard keyboard, the ']}' key -0x34, //FAIL: Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key -0x00, //FAIL: Used for miscellaneous characters; it can vary byboard. -0x00, //FAIL: Reserved -0x00, //FAIL: OEM specific -0x32, //FAIL: Windows 2000/XP: Either the angle bracket or the backslash key on the RT 102-key keyboard -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCEE6 -0x00, //FAIL: OEM specific -0x00, //FAIL: Windows 2000/XP: Used to pass Unicode characters as if they E8 -0x00, //FAIL: Unassigned -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: 0x00 -0x00, //FAIL: Attn -0xA3, //OK: CrSel -0xA4, //OK: ExSel -0x00, //FAIL: Erase EOF -0x00, //FAIL: Play -0x00, //FAIL: Zoom -0x00, //FAIL: Reserved -0x00, //FAIL: PA1 -0x9C, //OK: Clear -0x00, //FAIL: 0x00 -}; -#else -# ifdef ENABLE_KEYPAD_Fx -static const unsigned char scan_to_usb[] = { -0x00,0x29,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x2f,0x30,0x2a,0x2b, -0x14,0x1a,0x08,0x15,0x17,0x1c,0x18,0x0c,0x12,0x13,0x33,0x2e,0x28,0xe0,0x04,0x16, -0x07,0x09,0x0a,0x0b,0x0d,0x0e,0x0f,0x35,0x34,0x31,0xe1,0x38,0x1d,0x1b,0x06,0x19, -0x05,0x11,0x10,0x36,0x37,0x2d,0xe5,0x55,0xe3,0x2c,0x39,0x3a,0x3b,0x3c,0x3d,0x3e, -0x3f,0x40,0x41,0x42,0x43,0x83,0x47,0x5f,0x60,0x61,0x56,0x5c,0x5d,0x5e,0x57,0x59, -0x5a,0x5b,0x62,0x63,0x46,0x00,0x32,0x44,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x75,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x54,0x00,0x00,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe3,0xe7,0x65,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -}; -# else -static const unsigned char scan_to_usb[] = { -0x00,0x29,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x2f,0x30,0x2a,0x2b, -0x14,0x1a,0x08,0x15,0x17,0x1c,0x18,0x0c,0x12,0x13,0x33,0x2e,0x28,0xe0,0x04,0x16, -0x07,0x09,0x0a,0x0b,0x0d,0x0e,0x0f,0x35,0x34,0x31,0xe1,0x38,0x1d,0x1b,0x06,0x19, -0x05,0x11,0x10,0x36,0x37,0x2d,0xe5,0x00,0xe3,0x2c,0x39,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x83,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x46,0x00,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x75,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe4,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe7,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe3,0xe7,0x65,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -}; -# endif -#endif - -/* mostly the same values as the Bochs USB Keyboard device */ -static const uint8_t qemu_keyboard_dev_descriptor[] = { - 0x12, /* u8 bLength; */ - 0x01, /* u8 bDescriptorType; Device */ - 0x10, 0x00, /* u16 bcdUSB; v1.0 */ - - 0x00, /* u8 bDeviceClass; */ - 0x00, /* u8 bDeviceSubClass; */ - 0x00, /* u8 bDeviceProtocol; [ low/full speeds only ] */ - 0x08, /* u8 bMaxPacketSize0; 8 Bytes */ - - 0x27, 0x06, /* u16 idVendor; */ - 0x01, 0x00, /* u16 idProduct; */ - 0x00, 0x00, /* u16 bcdDevice */ - - 0x03, /* u8 iManufacturer; */ - 0x02, /* u8 iProduct; */ - 0x01, /* u8 iSerialNumber; */ - 0x01 /* u8 bNumConfigurations; */ -}; - -static const uint8_t qemu_keyboard_config_descriptor[] = { - /* one configuration */ - 0x09, /* u8 bLength; */ - 0x02, /* u8 bDescriptorType; Configuration */ - 0x22, 0x00, /* u16 wTotalLength; */ - 0x01, /* u8 bNumInterfaces; (1) */ - 0x01, /* u8 bConfigurationValue; */ - 0x04, /* u8 iConfiguration; */ - 0xa0, /* u8 bmAttributes; - Bit 7: must be set, - 6: Self-powered, - 5: Remote wakeup, - 4..0: resvd */ - 50, /* u8 MaxPower; */ - - /* USB 1.1: - * USB 2.0, single TT organization (mandatory): - * one interface, protocol 0 - * - * USB 2.0, multiple TT organization (optional): - * two interfaces, protocols 1 (like single TT) - * and 2 (multiple TT mode) ... config is - * sometimes settable - * NOT IMPLEMENTED - */ - - /* one interface */ - 0x09, /* u8 if_bLength; */ - 0x04, /* u8 if_bDescriptorType; Interface */ - 0x00, /* u8 if_bInterfaceNumber; */ - 0x00, /* u8 if_bAlternateSetting; */ - 0x01, /* u8 if_bNumEndpoints; */ - 0x03, /* u8 if_bInterfaceClass; */ - 0x01, /* u8 if_bInterfaceSubClass; */ - 0x01, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ - 0x05, /* u8 if_iInterface; */ - - /* HID descriptor */ - 0x09, /* u8 bLength; */ - 0x21, /* u8 bDescriptorType; */ - 0x01, 0x00, /* u16 HID_class */ - 0x00, /* u8 country_code */ - 0x01, /* u8 num_descriptors */ - 0x22, /* u8 type; Report */ - 50, 0, /* u16 len */ - - /* one endpoint (status change endpoint) */ - 0x07, /* u8 ep_bLength; */ - 0x05, /* u8 ep_bDescriptorType; Endpoint */ - 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* u8 ep_bmAttributes; Interrupt */ - 0x03, 0x00, /* u16 ep_wMaxPacketSize; */ - 0x0a, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ -}; - -static const uint8_t qemu_tablet_config_descriptor[] = { - /* one configuration */ - 0x09, /* u8 bLength; */ - 0x02, /* u8 bDescriptorType; Configuration */ - 0x22, 0x00, /* u16 wTotalLength; */ - 0x01, /* u8 bNumInterfaces; (1) */ - 0x01, /* u8 bConfigurationValue; */ - 0x04, /* u8 iConfiguration; */ - 0xa0, /* u8 bmAttributes; - Bit 7: must be set, - 6: Self-powered, - 5: Remote wakeup, - 4..0: resvd */ - 50, /* u8 MaxPower; */ - - /* USB 1.1: - * USB 2.0, single TT organization (mandatory): - * one interface, protocol 0 - * - * USB 2.0, multiple TT organization (optional): - * two interfaces, protocols 1 (like single TT) - * and 2 (multiple TT mode) ... config is - * sometimes settable - * NOT IMPLEMENTED - */ - - /* one interface */ - 0x09, /* u8 if_bLength; */ - 0x04, /* u8 if_bDescriptorType; Interface */ - 0x00, /* u8 if_bInterfaceNumber; */ - 0x00, /* u8 if_bAlternateSetting; */ - 0x01, /* u8 if_bNumEndpoints; */ - 0x03, /* u8 if_bInterfaceClass; */ - 0x01, /* u8 if_bInterfaceSubClass; */ - 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ - 0x05, /* u8 if_iInterface; */ - - /* HID descriptor */ - 0x09, /* u8 bLength; */ - 0x21, /* u8 bDescriptorType; */ - 0x03, 0x00, /* u16 HID_class */ - 0x00, /* u8 country_code */ - 0x01, /* u8 num_descriptors */ - 0x22, /* u8 type; Report */ - 74, 0, /* u16 len */ - - /* one endpoint (status change endpoint) */ - 0x07, /* u8 ep_bLength; */ - 0x05, /* u8 ep_bDescriptorType; Endpoint */ - 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* u8 ep_bmAttributes; Interrupt */ - 0x08, 0x00, /* u16 ep_wMaxPacketSize; */ - 0x03, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ -}; - -static const uint8_t qemu_keyboard_hid_report_descriptor[] = { - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x06, // USAGE (Keyboard) - 0xa1, 0x01, // COLLECTION (Application) - 0x05, 0x07, // USAGE_PAGE (Keyboard) - 0x19, 0xe0, // USAGE_MINIMUM (Keyboard Left Control) - 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x75, 0x01, // REPORT_SIZE (1) - 0x95, 0x08, // REPORT_COUNT (8) - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x08, // REPORT_SIZE (8) - 0x81, 0x03, // INPUT (Cnst,Var,Abs) - 0x95, 0x05, // REPORT_COUNT (5) - 0x75, 0x01, // REPORT_SIZE (1) - 0x05, 0x08, // USAGE_PAGE (LEDs) - 0x19, 0x01, // USAGE_MINIMUM (Num Lock) - 0x29, 0x05, // USAGE_MAXIMUM (Kana) - 0x91, 0x02, // OUTPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x03, // REPORT_SIZE (3) - 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) - 0x95, 0x06, // REPORT_COUNT (6) - 0x75, 0x08, // REPORT_SIZE (8) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x65, // LOGICAL_MAXIMUM (101) - 0x05, 0x07, // USAGE_PAGE (Keyboard) - 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) - 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) - 0x81, 0x00, // INPUT (Data,Ary,Abs) - 0xc0 // END_COLLECTION -}; - -static int usb_keyboard_poll(USBKeyboardState *s, uint8_t *buf, int len) -{ - static unsigned char keys[256]; - int l; - - if (!s->keyboard_grabbed) { - //qemu_add_keyboard_event_handler(usb_keyboard_event, s, 0); - s->keyboard_grabbed = 1; - } - - if(gsWindowHandle != GetForegroundWindow()) - { - for(int i=0;i<256;i++) - { - keys[i] = 0; - } - } - else - { - for(int i=0;i<256;i++) - { - keys[i] = GetAsyncKeyState(i)>>8; - } - } - - l=1; - l=2; - buf[0] = 0; - if(keys[VK_LCONTROL]>>7) buf[0]|=(1<<0); - if(keys[VK_LSHIFT]>>7) buf[0]|=(1<<1); - if(keys[VK_LMENU]>>7) buf[0]|=(1<<2); //ALT key - if(keys[VK_LWIN]>>7) buf[0]|=(1<<3); - if(keys[VK_RCONTROL]>>7) buf[0]|=(1<<4); - if(keys[VK_RSHIFT]>>7) buf[0]|=(1<<5); - if(keys[VK_RMENU]>>7) buf[0]|=(1<<6); - if(keys[VK_RWIN]>>7) buf[0]|=(1<<7); - - buf[1] = 0; //reserved byte - - int k=0; - for(int i=0;i<256;i++) - { - if(keys[i]>>7) //if pressed - { - if(l==8) - { - buf[1]=buf[1]=buf[1]=buf[1]=buf[1]=buf[1]=buf[1]=buf[1]=1; - } -#ifdef VK_BASED - int uc = vk_to_key_code[i]; -#else - int sc = MapVirtualKey(i,MAPVK_VK_TO_VSC_EX); - if((sc>>8)!=0) - sc=(sc&0x1FF)+256; - int uc = scan_to_usb[sc]; - printf("// %08x->%02x ",i,sc); - k++; -#endif - if((uc>0)&&(uc<=0x65)) // - buf[l++]=uc; - } - - } - if(k) printf("\n"); - - /*if(l>=1) - { - while(l<8) - buf[l++]=0; - printf("KEYS: %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); - l=l; - }*/ - - while(l<7) - buf[l++]=0; - - return l; -} - -static void usb_keyboard_handle_reset(USBDevice *dev) -{ - USBKeyboardState *s = (USBKeyboardState *)dev; -} - -static int usb_keyboard_handle_control(USBDevice *dev, USBPacket *p, int request, int value, - int index, int length, uint8_t *data) -{ - USBKeyboardState *s = (USBKeyboardState *)dev; - int ret = 0; - - switch(request) { - case DeviceRequest | USB_REQ_GET_STATUS: - data[0] = (1 << USB_DEVICE_SELF_POWERED) | - (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP); - data[1] = 0x00; - ret = 2; - break; - case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: - if (value == USB_DEVICE_REMOTE_WAKEUP) { - dev->remote_wakeup = 0; - } else { - goto fail; - } - ret = 0; - break; - case DeviceOutRequest | USB_REQ_SET_FEATURE: - if (value == USB_DEVICE_REMOTE_WAKEUP) { - dev->remote_wakeup = 1; - } else { - goto fail; - } - ret = 0; - break; - case DeviceOutRequest | USB_REQ_SET_ADDRESS: - dev->addr = value; - ret = 0; - break; - case DeviceRequest | USB_REQ_GET_DESCRIPTOR: - switch(value >> 8) { - case USB_DT_DEVICE: - memcpy(data, qemu_keyboard_dev_descriptor, - sizeof(qemu_keyboard_dev_descriptor)); - ret = sizeof(qemu_keyboard_dev_descriptor); - break; - case USB_DT_CONFIG: - memcpy(data, qemu_keyboard_config_descriptor, - sizeof(qemu_keyboard_config_descriptor)); - ret = sizeof(qemu_keyboard_config_descriptor); - break; - case USB_DT_STRING: - switch(value & 0xff) { - case 0: - /* language ids */ - data[0] = 4; - data[1] = 3; - data[2] = 0x09; - data[3] = 0x04; - ret = 4; - break; - case 1: - /* serial number */ - ret = set_usb_string(data, "1"); - break; - case 2: - /* product description */ - ret = set_usb_string(data, "Generic USB Keyboard"); - break; - case 3: - /* vendor description */ - ret = set_usb_string(data, "PCSX2/QEMU"); - break; - case 4: - ret = set_usb_string(data, "HID Keyboard"); - break; - case 5: - ret = set_usb_string(data, "Endpoint1 Interrupt Pipe"); - break; - default: - goto fail; - } - break; - default: - goto fail; - } - break; - case DeviceRequest | USB_REQ_GET_CONFIGURATION: - data[0] = 1; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: - ret = 0; - break; - case DeviceRequest | USB_REQ_GET_INTERFACE: - data[0] = 0; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_INTERFACE: - ret = 0; - break; - /* hid specific requests */ - case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: - switch(value >> 8) { - case 0x22: - memcpy(data, qemu_keyboard_hid_report_descriptor, - sizeof(qemu_keyboard_hid_report_descriptor)); - ret = sizeof(qemu_keyboard_hid_report_descriptor); - break; - default: - goto fail; - } - break; - case GET_REPORT: - ret = usb_keyboard_poll(s, data, length); - break; - case SET_IDLE: - ret = 0; - break; - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static int usb_keyboard_handle_data(USBDevice *dev, USBPacket* packet) -{ - USBKeyboardState *s = (USBKeyboardState *)dev; - int ret = 0; - - switch(packet->pid) { - case USB_TOKEN_IN: - if (packet->devep == 1) { - ret = usb_keyboard_poll(s, packet->data, packet->len); - } else { - goto fail; - } - break; - case USB_TOKEN_OUT: - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static void usb_keyboard_handle_destroy(USBDevice *dev) -{ - USBKeyboardState *s = (USBKeyboardState *)dev; - - //qemu_add_keyboard_event_handler(NULL, NULL, 0); - free(s); -} - -USBDevice *usb_keyboard_init(void) -{ - USBKeyboardState *s; - - s = (USBKeyboardState *)malloc(sizeof(USBKeyboardState)); - if (!s) - return NULL; - memset(s,0,sizeof(USBKeyboardState)); - s->dev.speed = USB_SPEED_FULL; - s->dev.info = &devinfo; - s->dev.info->handle_packet = usb_generic_handle_packet; - s->dev.info->handle_reset = usb_keyboard_handle_reset; - s->dev.info->handle_control = usb_keyboard_handle_control; - s->dev.info->handle_data = usb_keyboard_handle_data; - s->dev.info->handle_destroy = usb_keyboard_handle_destroy; - s->dev.info->product_desc = "Generic USB Keyboard"; - - return (USBDevice *)s; -} - -#if 0 -#define PS2KBD_VERSION 0x100 - -#define USB_SUBCLASS_BOOT 1 -#define USB_HIDPROTO_KEYBOARD 1 - -#define PS2KBD_MAXDEV 2 -#define PS2KBD_MAXKEYS 6 - -#define PS2KBD_DEFLINELEN 4096 -#define PS2KBD_DEFREPEATRATE 100 -/* Default repeat rate in milliseconds */ -#define PS2KBD_REPEATWAIT 1000 -/* Number of milliseconds to wait before starting key repeat */ -#define USB_KEYB_NUMLOCK 0x53 -#define USB_KEYB_CAPSLOCK 0x39 -#define USB_KEYB_SCRLOCK 0x47 - -#define USB_KEYB_NUMPAD_START 0x54 -#define USB_KEYB_NUMPAD_END 0x63 - -#define SEMA_ZERO -419 -#define SEMA_DELETED -425 - -int ps2kbd_init(); -void ps2kbd_config_set(int resultCode, int bytes, void *arg); -void ps2kbd_idlemode_set(int resultCode, int bytes, void *arg); -void ps2kbd_data_recv(int resultCode, int bytes, void *arg); -int ps2kbd_probe(int devId); -int ps2kbd_connect(int devId); -int ps2kbd_disconnect(int devId); -void usb_getstring(int endp, int index, char *desc); - -typedef struct _kbd_data_recv - -{ - u8 mod_keys; - u8 reserved; - u8 keycodes[PS2KBD_MAXKEYS]; -} kbd_data_recv; - -typedef struct _keyb_dev - -{ - int configEndp; - int dataEndp; - int packetSize; - int devId; - int interfaceNo; /* Holds the interface number selected on this device */ - char repeatkeys[2]; - u32 eventmask; - u8 ledStatus; /* Maintains state on the led status */ - kbd_data_recv oldData; - kbd_data_recv data; /* Holds the data for the transfers */ -} kbd_dev; - -/* Global Variables */ - -int kbd_readmode; -int kbd_blocking; -u32 kbd_repeatrate; -kbd_dev *devices[PS2KBD_MAXDEV]; /* Holds a list of current devices */ -int dev_count; -UsbDriver kbd_driver = { NULL, NULL, "PS2Kbd", ps2kbd_probe, ps2kbd_connect, ps2kbd_disconnect }; -u8 *lineBuffer; -u32 lineStartP, lineEndP; -int lineSema; -int bufferSema; -u32 lineSize; -u8 keymap[PS2KBD_KEYMAP_SIZE]; /* Normal key map */ -u8 shiftkeymap[PS2KBD_KEYMAP_SIZE]; /* Shifted key map */ -u8 keycap[PS2KBD_KEYMAP_SIZE]; /* Does this key get shifted by capslock ? */ -u8 special_keys[PS2KBD_KEYMAP_SIZE]; -u8 control_map[PS2KBD_KEYMAP_SIZE]; -u8 alt_map[PS2KBD_KEYMAP_SIZE]; -//static struct fileio_driver kbd_fdriver; -iop_device_t kbd_filedrv; -u8 keyModValue[8] = { 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7 }; -int repeat_tid; -int eventid; /* Id of the repeat event */ - -int _start () -{ - FlushDcache(); - - ps2kbd_init(); - - printf("PS2KBD - USB Keyboard Library\n"); - - return 0; - -} - -int ps2kbd_probe(int devId) - -{ - UsbDeviceDescriptor *dev; - UsbConfigDescriptor *conf; - UsbInterfaceDescriptor *intf; - UsbEndpointDescriptor *endp; - //UsbStringDescriptor *str; - - if(dev_count >= PS2KBD_MAXDEV) - { - printf("ERROR: Maximum keyboard devices reached\n"); - return 0; - } - - //printf("PS2Kbd_probe devId %d\n", devId); - - dev = UsbGetDeviceStaticDescriptor(devId, NULL, USB_DT_DEVICE); /* Get device descriptor */ - if(!dev) - { - printf("ERROR: Couldn't get device descriptor\n"); - return 0; - } - - //printf("Device class %d, Size %d, Man %d, Product %d Cpnfigurations %d\n", dev->bDeviceClass, dev->bMaxPacketSize0, dev->iManufacturer, dev->iProduct, dev->bNumConfigurations); - /* Check that the device class is specified in the interfaces and it has at least one configuration */ - if((dev->bDeviceClass != USB_CLASS_PER_INTERFACE) || (dev->bNumConfigurations < 1)) - { - //printf("This is not the droid you're looking for\n"); - return 0; - } - - conf = UsbGetDeviceStaticDescriptor(devId, dev, USB_DT_CONFIG); - if(!conf) - { - printf("ERROR: Couldn't get configuration descriptor\n"); - return 0; - } - //printf("Config Length %d Total %d Interfaces %d\n", conf->bLength, conf->wTotalLength, conf->bNumInterfaces); - - if((conf->bNumInterfaces < 1) || (conf->wTotalLength < (sizeof(UsbConfigDescriptor) + sizeof(UsbInterfaceDescriptor)))) - { - printf("ERROR: No interfaces available\n"); - return 0; - } - - intf = (UsbInterfaceDescriptor *) ((char *) conf + conf->bLength); /* Get first interface */ -/* printf("Interface Length %d Endpoints %d Class %d Sub %d Proto %d\n", intf->bLength, */ -/* intf->bNumEndpoints, intf->bInterfaceClass, intf->bInterfaceSubClass, */ -/* intf->bInterfaceProtocol); */ - - if((intf->bInterfaceClass != USB_CLASS_HID) || (intf->bInterfaceSubClass != USB_SUBCLASS_BOOT) || - (intf->bInterfaceProtocol != USB_HIDPROTO_KEYBOARD) || (intf->bNumEndpoints < 1)) - - { - //printf("We came, we saw, we told it to fuck off\n"); - return 0; - } - - endp = (UsbEndpointDescriptor *) ((char *) intf + intf->bLength); - endp = (UsbEndpointDescriptor *) ((char *) endp + endp->bLength); /* Go to the data endpoint */ - - //printf("Endpoint 1 Addr %d, Attr %d, MaxPacket %d\n", endp->bEndpointAddress, endp->bmAttributes, endp->wMaxPacketSizeLB); - - if(((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) || - ((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)) - { - printf("ERROR: Endpoint not interrupt type and/or an input\n"); - return 0; - } - - printf("PS2KBD: Found a keyboard device\n"); - - return 1; -} - -int ps2kbd_connect(int devId) - -{ - /* Assume we can only get here if we have already checked the device is kosher */ - - UsbDeviceDescriptor *dev; - UsbConfigDescriptor *conf; - UsbInterfaceDescriptor *intf; - UsbEndpointDescriptor *endp; - kbd_dev *currDev; - int devLoop; - - //printf("PS2Kbd_connect devId %d\n", devId); - - dev = UsbGetDeviceStaticDescriptor(devId, NULL, USB_DT_DEVICE); /* Get device descriptor */ - if(!dev) - { - printf("ERROR: Couldn't get device descriptor\n"); - return 1; - } - - conf = UsbGetDeviceStaticDescriptor(devId, dev, USB_DT_CONFIG); - if(!conf) - { - printf("ERROR: Couldn't get configuration descriptor\n"); - return 1; - } - - intf = (UsbInterfaceDescriptor *) ((char *) conf + conf->bLength); /* Get first interface */ - endp = (UsbEndpointDescriptor *) ((char *) intf + intf->bLength); - endp = (UsbEndpointDescriptor *) ((char *) endp + endp->bLength); /* Go to the data endpoint */ - - for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) - { - if(devices[devLoop] == NULL) - { - break; - } - } - - if(devLoop == PS2KBD_MAXDEV) - { - /* How the f*** did we end up here ??? */ - printf("ERROR: Device Weirdness!!\n"); - return 1; - } - - currDev = (kbd_dev *) AllocSysMemory(0, sizeof(kbd_dev), NULL); - if(!currDev) - { - printf("ERROR: Couldn't allocate a device point for the kbd\n"); - return 1; - } - - devices[devLoop] = currDev; - memset(currDev, 0, sizeof(kbd_dev)); - currDev->configEndp = UsbOpenEndpoint(devId, NULL); - currDev->dataEndp = UsbOpenEndpoint(devId, endp); - currDev->packetSize = endp->wMaxPacketSizeLB | ((int) endp->wMaxPacketSizeHB << 8); - currDev->eventmask = (1 << devLoop); - if(currDev->packetSize > sizeof(kbd_data_recv)) - { - currDev->packetSize = sizeof(kbd_data_recv); - } - - if(dev->iManufacturer != 0) - { - usb_getstring(currDev->configEndp, dev->iManufacturer, "Keyboard Manufacturer"); - } - - if(dev->iProduct != 0) - { - usb_getstring(currDev->configEndp, dev->iProduct, "Keyboard Product"); - } - - currDev->devId = devId; - currDev->interfaceNo = intf->bInterfaceNumber; - currDev->ledStatus = 0; - - UsbSetDevicePrivateData(devId, currDev); /* Set the index for the device data */ - - //printf("Configuration value %d\n", conf->bConfigurationValue); - UsbSetDeviceConfiguration(currDev->configEndp, conf->bConfigurationValue, ps2kbd_config_set, currDev); - - dev_count++; /* Increment device count */ - printf("PS2KBD: Connected device\n"); - - return 0; -} - -int ps2kbd_disconnect(int devId) - -{ - int devLoop; - //printf("PS2Kbd_disconnect devId %d\n", devId); - - for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) - { - if((devices[devLoop]) && (devices[devLoop]->devId == devId)) - { - dev_count--; - FreeSysMemory(devices[devLoop]); - devices[devLoop] = NULL; - printf("PS2KBD: Disconnected device\n"); - break; - } - } - - return 0; -} - -typedef struct _string_descriptor - -{ - u8 buf[200]; - char *desc; -} string_descriptor; - -void ps2kbd_getstring_set(int resultCode, int bytes, void *arg) - -{ - UsbStringDescriptor *str = (UsbStringDescriptor *) arg; - string_descriptor *strBuf = (string_descriptor *) arg; - char string[50]; - int strLoop; - -/* printf("=========getstring=========\n"); */ - -/* printf("PS2KEYBOARD: GET_DESCRIPTOR res %d, bytes %d, arg %p\n", resultCode, bytes, arg); */ - - if(resultCode == USB_RC_OK) - { - memset(string, 0, 50); - for(strLoop = 0; strLoop < ((bytes - 2) / 2); strLoop++) - { - string[strLoop] = str->wData[strLoop] & 0xFF; - } - printf("PS2KBD %s: %s\n", strBuf->desc, string); - } - - FreeSysMemory(arg); -} - -void usb_getstring(int endp, int index, char *desc) - -{ - u8 *data; - string_descriptor *str; - int ret; - - data = (u8 *) AllocSysMemory(0, sizeof(string_descriptor), NULL); - str = (string_descriptor *) data; - - if(data != NULL) - { - str->desc = desc; - ret = UsbControlTransfer(endp, 0x80, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | index, - 0, sizeof(string_descriptor) - 4, data, ps2kbd_getstring_set, data); - if(ret != USB_RC_OK) - { - printf("PS2KBD: Error sending string descriptor request\n"); - FreeSysMemory(data); - } - } -} - -void ps2kbd_config_set(int resultCode, int bytes, void *arg) - /* Called when we have finished choosing our configuration */ - -{ - kbd_dev *dev; - - if(resultCode != USB_RC_OK) - { - printf("PS2KEYBOARD: Configuration set error res %d, bytes %d, arg %p\n", resultCode, bytes, arg); - return; - } - - //printf("PS2KEYBOARD: Configuration set res %d, bytes %d, arg %p\n", resultCode, bytes, arg); - /* Do a interrupt data transfer */ - - dev = (kbd_dev *) arg; - if(dev != NULL) - { - int ret; - - ret = UsbControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_IDLE, 0, dev->interfaceNo, 0, NULL, ps2kbd_idlemode_set, arg); - } -} - -void ps2kbd_idlemode_set(int resultCode, int bytes, void *arg) - -{ - kbd_dev *dev; - - - - if(resultCode != USB_RC_OK) - { - printf("PS2KBD: Idlemode set error res %d, bytes %d, arg %p\n", resultCode, bytes, arg); - return; - } - - dev = (kbd_dev *) arg; - if(dev != NULL) - { - int ret; - - ret = UsbInterruptTransfer(dev->dataEndp, &dev->data, dev->packetSize, ps2kbd_data_recv, arg); - } -} - -void ps2kbd_led_set(int resultCode, int bytes, void *arg) - -{ - //printf("LED Set\n"); -} - -void ps2kbd_build_uniquekeys(u8 *res, const u8 *new, const u8 *old) - - /* Builds a list of unique keys */ - -{ - int loopNew, loopOld; - int loopRes = 0; - int foundKey; - - for(loopNew = 0; loopNew < PS2KBD_MAXKEYS; loopNew++) - { - if(new[loopNew] != 0) - { - foundKey = 0; - for(loopOld = 0; loopOld < PS2KBD_MAXKEYS; loopOld++) - { - if(new[loopNew] == old[loopOld]) - { - foundKey = 1; - break; - } - } - if(!foundKey) - { - res[loopRes++] = new[loopNew]; - } - } - } -} - -u32 ps2kbd_repeathandler(void *arg) - -{ - kbd_dev *dev = arg; - iop_sys_clock_t t; - //printf("Repeat handler\n"); - - iSetEventFlag(eventid, dev->eventmask); - - USec2SysClock(kbd_repeatrate * 1000, &t); - iSetAlarm(&t, (void *)ps2kbd_repeathandler, arg); - - return t.hi; -} - -void ps2kbd_getkeys(u8 keyMods, u8 ledStatus, const u8 *keys, kbd_dev *dev) - -{ - int loopKey; - int tempPos = 0; - int byteCount = 0; - u8 currChars[2]; - - if(lineStartP < lineEndP) - { - tempPos = lineStartP + lineSize; - } - else - { - tempPos = lineStartP; - } - - for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) - { - u8 currKey = keys[loopKey]; - - currChars[0] = 0; - currChars[1] = 0; - - if(lineEndP == (tempPos - 1)) - { - break; - } - - if(currKey) /* If this is a valid key */ - { - if((currKey >= USB_KEYB_NUMPAD_START) && (currKey <= USB_KEYB_NUMPAD_END)) - /* Handle numpad specially */ - { - if(ledStatus & PS2KBD_LED_NUMLOCK) - { - if(keymap[currKey]) - { - currChars[0] = keymap[currKey]; - } - } - else - { - if(special_keys[currKey]) - { - currChars[0] = PS2KBD_ESCAPE_KEY; - currChars[1] = special_keys[currKey]; - } - else if(keymap[currKey] != '5') /* Make sure this isnt a 5 key :) */ - { - currChars[0] = keymap[currKey]; - } - } - } - else if(special_keys[currKey]) /* This is a special key */ - { - currChars[0] = PS2KBD_ESCAPE_KEY; - currChars[1] = special_keys[currKey]; - } - else if(keyMods & PS2KBD_CTRL) /* CTRL */ - { - if(control_map[currKey]) - { - currChars[0] = control_map[currKey]; - } - } - else if(keyMods & PS2KBD_ALT) /* ALT */ - { - if(alt_map[currKey]) - { - currChars[0] = alt_map[currKey]; - } - } - else if(keyMods & PS2KBD_SHIFT) /* SHIFT */ - { - if((ledStatus & PS2KBD_LED_CAPSLOCK) && (keycap[currKey])) - { - currChars[0] = keymap[currKey]; - } - else - { - currChars[0] = shiftkeymap[currKey]; - } - } - else /* Normal key */ - { - if(keymap[keys[loopKey]]) - { - if((ledStatus & PS2KBD_LED_CAPSLOCK) && (keycap[currKey])) - { - currChars[0] = shiftkeymap[currKey]; - } - else - { - currChars[0] = keymap[currKey]; - } - } - } - } - - if((currChars[0] == PS2KBD_ESCAPE_KEY) && (currChars[1] != 0)) - { - if(lineEndP != (tempPos - 2)) - { - lineBuffer[lineEndP++] = currChars[0]; - lineEndP %= lineSize; - lineBuffer[lineEndP++] = currChars[1]; - lineEndP %= lineSize; - byteCount += 2; - } - dev->repeatkeys[0] = currChars[0]; - dev->repeatkeys[1] = currChars[1]; - } - else if(currChars[0] != 0) - { - lineBuffer[lineEndP++] = currChars[0]; - lineEndP %= lineSize; - byteCount++; - dev->repeatkeys[0] = currChars[0]; - dev->repeatkeys[1] = 0; - } - } - - if(byteCount > 0) - { - iop_sys_clock_t t; - /* Set alarm to do repeat rate */ - //printf("repeatkeys %d %d\n", kbd_repeatkeys[0], kbd_repeatkeys[1]); - USec2SysClock(PS2KBD_REPEATWAIT * 1000, &t); - SetAlarm(&t, (void *)ps2kbd_repeathandler, dev); - } - - for(loopKey = 0; loopKey < byteCount; loopKey++) /* Signal the sema to indicate data */ - { - SignalSema(bufferSema); - } - -/* lineBuffer[PS2KBD_DEFLINELEN - 1] = 0; */ -/* printf(lineBuffer); */ - //printf("lineStart %d, lineEnd %d\n", lineStartP, lineEndP); -} - - -void ps2kbd_getkeys_raw(u8 newKeyMods, u8 oldKeyMods, u8 *new, const u8 *old) - -{ - int loopKey; - u8 currKey; - u8 keyMods = newKeyMods ^ oldKeyMods; - u8 keyModsMap = newKeyMods & keyMods; - int tempPos = 0; - int byteCount = 0; - - if(lineStartP < lineEndP) - { - tempPos = lineStartP + lineSize; - } - else - { - tempPos = lineStartP; - } - - for(loopKey = 0; loopKey < 8; loopKey++) - { - int currMod = (1 << loopKey); - if(keyMods & currMod) - { - if(lineEndP == (tempPos - 2)) - { - return; - } - - currKey = keyModValue[loopKey]; - - if(keyModsMap & currMod) /* If key pressed */ - { - lineBuffer[lineEndP++] = PS2KBD_RAWKEY_DOWN; - //printf("Key down\n"); - } - else - { - lineBuffer[lineEndP++] = PS2KBD_RAWKEY_UP; - //printf("Key up\n"); - } - - lineEndP %= lineSize; - lineBuffer[lineEndP++] = currKey; - lineEndP %= lineSize; - byteCount += 2; - //printf("Key %d\n", currKey); - } - } - - for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) - { - if(lineEndP == (tempPos - 2)) - { - return; - } - - if(new[loopKey] != 0) - { - lineBuffer[lineEndP++] = PS2KBD_RAWKEY_DOWN; - lineEndP %= lineSize; - lineBuffer[lineEndP++] = new[loopKey]; - lineEndP %= lineSize; - byteCount += 2; - //printf("Key down\nKey %d\n", new[loopKey]); - } - - } - - for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) - { - if(lineEndP == (tempPos - 2)) - { - return; - } - - if(old[loopKey] != 0) - { - lineBuffer[lineEndP++] = PS2KBD_RAWKEY_UP; - lineEndP %= lineSize; - lineBuffer[lineEndP++] = old[loopKey]; - lineEndP %= lineSize; - byteCount += 2; - //printf("Key up\nKey %d\n", old[loopKey]); - } - - } - - for(loopKey = 0; loopKey < byteCount; loopKey++) /* Signal the sema for the number of bytes read */ - { - SignalSema(bufferSema); - } -} - -void ps2kbd_data_recv(int resultCode, int bytes, void *arg) - -{ - kbd_dev *dev; - int ret; - int phantom; - int loop; - - if(resultCode != USB_RC_OK) - { - printf("PS2KEYBOARD: Data Recv set res %d, bytes %d, arg %p\n", resultCode, bytes, arg); - return; - } - - //printf("PS2KBD: Data Recv set res %d, bytes %d, arg %p\n", resultCode, bytes, arg); - - dev = (kbd_dev *) arg; - if(dev == NULL) - { - printf("PS2KBD: dev == NULL\n"); - return; - } - -/* printf("PS2KBD Modifiers %02X, Keys ", dev->data.mod_keys); */ -/* for(loop = 0; loop < PS2KBD_MAXKEYS; loop++) */ -/* { */ -/* printf("%02X ", dev->data.keycodes[loop]); */ -/* } */ -/* printf("\n"); */ - - CancelAlarm((void *)ps2kbd_repeathandler, dev); /* Make sure repeat alarm is cancelled */ - - /* Check for phantom states */ - phantom = 1; - for(loop = 0; loop < PS2KBD_MAXKEYS; loop++) - { - if(dev->data.keycodes[loop] != 1) - { - phantom = 0; - break; - } - } - - if(!phantom) /* If not in a phantom state */ - { - u8 uniqueKeys[PS2KBD_MAXKEYS]; - u8 missingKeys[PS2KBD_MAXKEYS]; - int loopKey; - - memset(uniqueKeys, 0, PS2KBD_MAXKEYS); - memset(missingKeys, 0, PS2KBD_MAXKEYS); - ps2kbd_build_uniquekeys(uniqueKeys, dev->data.keycodes, dev->oldData.keycodes); - ps2kbd_build_uniquekeys(missingKeys, dev->oldData.keycodes, dev->data.keycodes); - /* Build new and missing key lists */ - -/* printf("Unique keys : "); */ -/* for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) */ -/* { */ -/* printf("%02X ", uniqueKeys[loopKey]); */ -/* } */ -/* printf("\n"); */ - -/* printf("Missing keys : "); */ -/* for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) */ -/* { */ -/* printf("%02X ", missingKeys[loopKey]); */ -/* } */ -/* printf("\n"); */ - - if(kbd_readmode == PS2KBD_READMODE_NORMAL) - { - u8 ledStatus; - - ledStatus = dev->ledStatus; - //printf("ledStatus %02X\n", ledStatus); - - for(loopKey = 0; loopKey < PS2KBD_MAXKEYS; loopKey++) /* Process key codes */ - { - switch(uniqueKeys[loopKey]) - { - case USB_KEYB_NUMLOCK : - ledStatus ^= PS2KBD_LED_NUMLOCK; - uniqueKeys[loopKey] = 0; - break; - case USB_KEYB_CAPSLOCK : - ledStatus ^= PS2KBD_LED_CAPSLOCK; - uniqueKeys[loopKey] = 0; - break; - case USB_KEYB_SCRLOCK : - ledStatus ^= PS2KBD_LED_SCRLOCK; - uniqueKeys[loopKey] = 0; - break; - } - } - - if(ledStatus != dev->ledStatus) - { - dev->ledStatus = ledStatus & PS2KBD_LED_MASK; - //printf("LEDS %02X\n", dev->ledStatus); - /* Call Set LEDS */ - UsbControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_REPORT, 0x200, - dev->interfaceNo, 1, &dev->ledStatus, ps2kbd_led_set, arg); - } - - WaitSema(lineSema); /* Make sure no other thread is going to manipulate the buffer */ - ps2kbd_getkeys(dev->data.mod_keys, dev->ledStatus, uniqueKeys, dev); /* read in remaining keys */ - SignalSema(lineSema); - } - else /* RAW Mode */ - { - WaitSema(lineSema); - ps2kbd_getkeys_raw(dev->data.mod_keys, dev->oldData.mod_keys, uniqueKeys, missingKeys); - SignalSema(lineSema); - } - - memcpy(&dev->oldData, &dev->data, sizeof(kbd_data_recv)); - } - - ret = UsbInterruptTransfer(dev->dataEndp, &dev->data, dev->packetSize, ps2kbd_data_recv, arg); -} - -void flushbuffer() - -{ - iop_sema_t s; - - lineStartP = 0; - lineEndP = 0; - memset(lineBuffer, 0, lineSize); - - DeleteSema(bufferSema); - s.initial = 0; - s.max = lineSize; - s.option = 0; - s.attr = 0; - bufferSema = CreateSema(&s); /* Create a sema to maintain status of readable data */ - - if(bufferSema <= 0) - { - printf("PS2KBD: Error creating buffer sema\n"); - } -} - -void ps2kbd_ioctl_setreadmode(u32 readmode) - -{ - int devLoop; - - if(readmode == kbd_readmode) return; - - if((readmode == PS2KBD_READMODE_NORMAL) || (readmode == PS2KBD_READMODE_RAW)) - { - /* Reset line buffer */ - //printf("ioctl_setreadmode %d\n", readmode); - for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) - { - CancelAlarm((void *)ps2kbd_repeathandler, devices[devLoop]); - } - - WaitSema(lineSema); - kbd_readmode = readmode; - flushbuffer(); - SignalSema(lineSema); - } -} - -void ps2kbd_ioctl_setkeymap(kbd_keymap *keymaps) - -{ - //printf("ioctl_setkeymap %p\n", keymaps); - WaitSema(lineSema); /* Lock the input so you dont end up with weird results */ - memcpy(keymap, keymaps->keymap, PS2KBD_KEYMAP_SIZE); - memcpy(shiftkeymap, keymaps->shiftkeymap, PS2KBD_KEYMAP_SIZE); - memcpy(keycap, keymaps->keycap, PS2KBD_KEYMAP_SIZE); - SignalSema(lineSema); -} - -void ps2kbd_ioctl_setctrlmap(u8 *ctrlmap) - -{ - //printf("ioctl_setctrlmap %p\n", ctrlmap); - WaitSema(lineSema); - memcpy(control_map, ctrlmap, PS2KBD_KEYMAP_SIZE); - SignalSema(lineSema); -} - -void ps2kbd_ioctl_setaltmap(u8 *altmap) - -{ - //printf("ioctl_setaltmap %p\n", altmap); - WaitSema(lineSema); - memcpy(alt_map, altmap, PS2KBD_KEYMAP_SIZE); - SignalSema(lineSema); -} - -void ps2kbd_ioctl_setspecialmap(u8 *special) - -{ - //printf("ioctl_setspecialmap %p\n", special); - WaitSema(lineSema); - memcpy(special_keys, special, PS2KBD_KEYMAP_SIZE); - SignalSema(lineSema); -} - -void ps2kbd_ioctl_resetkeymap() - /* Reset keymap to default US variety */ - -{ - //printf("ioctl_resetkeymap()\n"); - WaitSema(lineSema); - memcpy(keymap, us_keymap, PS2KBD_KEYMAP_SIZE); - memcpy(shiftkeymap, us_shiftkeymap, PS2KBD_KEYMAP_SIZE); - memcpy(keycap, us_keycap, PS2KBD_KEYMAP_SIZE); - memcpy(special_keys, us_special_keys, PS2KBD_KEYMAP_SIZE); - memcpy(control_map, us_control_map, PS2KBD_KEYMAP_SIZE); - memcpy(alt_map, us_alt_map, PS2KBD_KEYMAP_SIZE); - SignalSema(lineSema); -} - -void ps2kbd_ioctl_flushbuffer() - /* Flush the internal buffer */ - -{ - //printf("ioctl_flushbuffer()\n"); - WaitSema(lineSema); - flushbuffer(); - SignalSema(lineSema); -} - -void ps2kbd_ioctl_setleds(u8 ledStatus) - -{ - int devLoop; - kbd_dev *dev; - - //printf("ioctl_setleds %d\n", ledStatus); - ledStatus &= PS2KBD_LED_MASK; - for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) - { - dev = devices[devLoop]; - if(dev) - { - if(ledStatus != dev->ledStatus) - { - dev->ledStatus = ledStatus & PS2KBD_LED_MASK; - UsbControlTransfer(dev->configEndp, 0x21, USB_REQ_SET_REPORT, 0x200, - dev->interfaceNo, 1, &dev->ledStatus, ps2kbd_led_set, dev); - } - } - } -} - -void ps2kbd_ioctl_setblockmode(u32 blockmode) - -{ - if((blockmode == PS2KBD_BLOCKING) || (blockmode == PS2KBD_NONBLOCKING)) - { - kbd_blocking = blockmode; - //printf("ioctl_setblockmode %d\n", blockmode); - } -} - -void ps2kbd_ioctl_setrepeatrate(u32 rate) - -{ - kbd_repeatrate = rate; -} - -int fio_dummy() -{ - //printf("fio_dummy()\n"); - return -5; -} - -int fio_init(iop_device_t *driver) -{ - //printf("fio_init()\n"); - return 0; -} - -int fio_format(iop_file_t *f) -{ - //printf("fio_format()\n"); - return 0; -} - -int fio_open(iop_file_t *f, const char *name, int mode) -{ - //printf("fio_open() %s %d\n", name, mode); - if(strcmp(name, PS2KBD_KBDFILE)) /* If not the keyboard file */ - { - return -1; - } - - return 0; -} - -int fio_read(iop_file_t *f, void *buf, int size) - -{ - int count = 0; - char *data = (char *) buf; - int ret; - - //printf("fio_read() %p %d\n", buf, size); - - if(kbd_readmode == PS2KBD_READMODE_RAW) - { - size &= ~1; /* Ensure size of a multiple of 2 */ - } - - ret = PollSema(bufferSema); - if(ret < 0) - { - if((ret == SEMA_ZERO) && (kbd_blocking == PS2KBD_BLOCKING)) - { - //printf("Blocking\n"); - ret = WaitSema(bufferSema); - if(ret < 0) /* Means either an error or the sema was deleted from under us */ - { - return 0; - } - } - else - { - return 0; - } - } - - SignalSema(bufferSema); - ret = WaitSema(lineSema); - if(ret < 0) return 0; - - while((count < size) && (lineStartP != lineEndP)) - { - data[count] = lineBuffer[lineStartP++]; - lineStartP %= lineSize; - count++; - PollSema(bufferSema); /* Take off one count from the sema */ - } - - SignalSema(lineSema); -/* //printf("read %d bytes\n", count); */ -/* { */ -/* struct t_sema_status s; */ - -/* ReferSemaStatus(bufferSema, &s); */ -/* //printf("Sema count %d\n", s.curr_count); */ -/* } */ - - return count; -} - -int fio_ioctl(iop_file_t *f, unsigned long arg, void *param) - -{ - //printf("fio_ioctl() %ld %d\n", arg, *((u32 *) param)); - switch(arg) - { - case PS2KBD_IOCTL_SETREADMODE: ps2kbd_ioctl_setreadmode(*((u32 *) param)); - break; - case PS2KBD_IOCTL_SETKEYMAP: ps2kbd_ioctl_setkeymap((kbd_keymap *) param); - break; - case PS2KBD_IOCTL_SETALTMAP: ps2kbd_ioctl_setaltmap((u8 *) param); - break; - case PS2KBD_IOCTL_SETCTRLMAP: ps2kbd_ioctl_setctrlmap((u8 *) param); - break; - case PS2KBD_IOCTL_SETSPECIALMAP: ps2kbd_ioctl_setspecialmap((u8 *) param); - break; - case PS2KBD_IOCTL_FLUSHBUFFER: ps2kbd_ioctl_flushbuffer(); - break; - case PS2KBD_IOCTL_SETLEDS: ps2kbd_ioctl_setleds(*(u8*) param); - break; - case PS2KBD_IOCTL_SETBLOCKMODE: ps2kbd_ioctl_setblockmode(*(u32 *) param); - break; - case PS2KBD_IOCTL_RESETKEYMAP: ps2kbd_ioctl_resetkeymap(); - break; - case PS2KBD_IOCTL_SETREPEATRATE: ps2kbd_ioctl_setrepeatrate(*(u32 *) param); - break; - default : return -1; - } - - return 0; -} - -int fio_close(iop_file_t *f) - -{ - //printf("fio_close()\n"); - return 0; -} - -iop_device_ops_t fio_ops = - - { - fio_init, - fio_dummy, - fio_format, - fio_open, - fio_close, - fio_read, - fio_dummy, - fio_dummy, - fio_ioctl, - fio_dummy, - fio_dummy, - fio_dummy, - fio_dummy, - fio_dummy, - fio_dummy, - fio_dummy, - fio_dummy - }; - -int init_fio() - -{ - kbd_filedrv.name = PS2KBD_FSNAME; - kbd_filedrv.type = IOP_DT_CHAR; - kbd_filedrv.version = 0; - kbd_filedrv.desc = "USB Keyboard FIO driver"; - kbd_filedrv.ops = &fio_ops; - return AddDrv(&kbd_filedrv); -} - -void repeat_thread(void *arg) - -{ - u32 eventmask; - int devLoop; - - for(;;) - { - WaitEventFlag(eventid, 0xFFFFFFFF, 0x01 | 0x10, &eventmask); - //printf("Recieved event %08X\n", eventmask); - for(devLoop = 0; devLoop < PS2KBD_MAXDEV; devLoop++) - { - if((eventmask & (1 << devLoop)) && (devices[devLoop])) - { - int tempPos = 0; - - WaitSema(lineSema); - if(lineStartP < lineEndP) - { - tempPos = lineStartP + lineSize; - } - else - { - tempPos = lineStartP; - } - - if((devices[devLoop]->repeatkeys[0]) && (devices[devLoop]->repeatkeys[1])) - { - if(lineEndP != (tempPos - 2)) - { - lineBuffer[lineEndP++] = devices[devLoop]->repeatkeys[0]; - lineEndP %= lineSize; - lineBuffer[lineEndP++] = devices[devLoop]->repeatkeys[1]; - lineEndP %= lineSize; - SignalSema(bufferSema); - SignalSema(bufferSema); - } - } - else if(devices[devLoop]->repeatkeys[0]) - { - if(lineEndP != (tempPos - 1)) - { - lineBuffer[lineEndP++] = devices[devLoop]->repeatkeys[0]; - lineEndP %= lineSize; - SignalSema(bufferSema); - } - } - - SignalSema(lineSema); - } - } - } -} - -int init_repeatthread() - /* Creates a thread to handle key repeats */ - -{ - iop_thread_t param; - iop_event_t event; - - event.attr = 0; - event.option = 0; - event.bits = 0; - eventid = CreateEventFlag(&event); - - param.attr = TH_C; - param.thread = repeat_thread; - param.priority = 40; - param.stacksize = 0x800; - param.option = 0; - - repeat_tid = CreateThread(¶m); - if (repeat_tid > 0) { - StartThread(repeat_tid, 0); - return 0; - } - else - { - return 1; - } -} - -int ps2kbd_init() - -{ - int ret; - iop_sema_t s; - - s.initial = 1; - s.max = 1; - s.option = 0; - s.attr = 0; - lineSema = CreateSema(&s); - if(lineSema <= 0) - { - printf("PS2KBD: Error creating sema\n"); - return 1; - } - - s.initial = 0; - s.max = PS2KBD_DEFLINELEN; - s.option = 0; - s.attr = 0; - bufferSema = CreateSema(&s); /* Create a sema to maintain status of readable data */ - if(bufferSema <= 0) - { - printf("PS2KBD: Error creating buffer sema\n"); - return 1; - } - - lineBuffer = (u8 *) AllocSysMemory(0, PS2KBD_DEFLINELEN, NULL); - if(lineBuffer == NULL) - { - printf("PS2KBD: Error allocating line buffer\n"); - return 1; - } - lineStartP = 0; - lineEndP = 0; - lineSize = PS2KBD_DEFLINELEN; - memset(lineBuffer, 0, PS2KBD_DEFLINELEN); - - memset(devices, 0, sizeof(kbd_dev *) * PS2KBD_MAXDEV); - dev_count = 0; - kbd_blocking = PS2KBD_NONBLOCKING; - kbd_readmode = PS2KBD_READMODE_NORMAL; - kbd_repeatrate = PS2KBD_DEFREPEATRATE; - memcpy(keymap, us_keymap, PS2KBD_KEYMAP_SIZE); - memcpy(shiftkeymap, us_shiftkeymap, PS2KBD_KEYMAP_SIZE); - memcpy(keycap, us_keycap, PS2KBD_KEYMAP_SIZE); - memcpy(special_keys, us_special_keys, PS2KBD_KEYMAP_SIZE); - memcpy(control_map, us_control_map, PS2KBD_KEYMAP_SIZE); - memcpy(alt_map, us_alt_map, PS2KBD_KEYMAP_SIZE); - - ret = init_fio(); - //printf("ps2kbd AddDrv [%d]\n", ret); - init_repeatthread(); - - ret = UsbRegisterDriver(&kbd_driver); - if(ret != USB_RC_OK) - { - printf("PS2KBD: Error registering USB devices\n"); - return 1; - } - - //printf("UsbRegisterDriver %d\n", ret); - - return 0; -} -#endif \ No newline at end of file diff --git a/plugins/USBqemu/qemu-usb/usb-msd.cpp b/plugins/USBqemu/qemu-usb/usb-msd.cpp deleted file mode 100644 index 6391dad108..0000000000 --- a/plugins/USBqemu/qemu-usb/usb-msd.cpp +++ /dev/null @@ -1,646 +0,0 @@ -/* - * USB Mass Storage Device emulation - * - * Copyright (c) 2006 CodeSourcery. - * Written by Paul Brook - * - * This code is licensed under the LGPL. - */ - -#include "qemu-common.h" -#include "qemu-option.h" -#include "qemu-config.h" -#include "usb.h" -#include "usb-desc.h" -#include "scsi.h" -#include "console.h" -#include "monitor.h" -#include "sysemu.h" -#include "blockdev.h" - -//#define DEBUG_MSD - -#ifdef DEBUG_MSD -#define DPRINTF(fmt, ...) \ -do { printf("usb-msd: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) do {} while(0) -#endif - -/* USB requests. */ -#define MassStorageReset 0xff -#define GetMaxLun 0xfe - -enum USBMSDMode { - USB_MSDM_CBW, /* Command Block. */ - USB_MSDM_DATAOUT, /* Transfer data to device. */ - USB_MSDM_DATAIN, /* Transfer data from device. */ - USB_MSDM_CSW /* Command Status. */ -}; - -typedef struct { - USBDevice dev; - enum USBMSDMode mode; - uint32_t scsi_len; - uint8_t *scsi_buf; - uint32_t usb_len; - uint8_t *usb_buf; - uint32_t data_len; - uint32_t residue; - uint32_t tag; - SCSIRequest *req; - SCSIBus bus; - BlockConf conf; - char *serial; - SCSIDevice *scsi_dev; - uint32_t removable; - int result; - /* For async completion. */ - USBPacket *packet; -} MSDState; - -struct usb_msd_cbw { - uint32_t sig; - uint32_t tag; - uint32_t data_len; - uint8_t flags; - uint8_t lun; - uint8_t cmd_len; - uint8_t cmd[16]; -}; - -struct usb_msd_csw { - uint32_t sig; - uint32_t tag; - uint32_t residue; - uint8_t status; -}; - -enum { - STR_MANUFACTURER = 1, - STR_PRODUCT, - STR_SERIALNUMBER, - STR_CONFIG_FULL, - STR_CONFIG_HIGH, -}; - -static const USBDescStrings desc_strings = { - [STR_MANUFACTURER] = "QEMU " QEMU_VERSION, - [STR_PRODUCT] = "QEMU USB HARDDRIVE", - [STR_SERIALNUMBER] = "1", - [STR_CONFIG_FULL] = "Full speed config (usb 1.1)", - [STR_CONFIG_HIGH] = "High speed config (usb 2.0)", -}; - -static const USBDescIface desc_iface_full = { - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = 0x06, /* SCSI */ - .bInterfaceProtocol = 0x50, /* Bulk */ - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_IN | 0x01, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 64, - },{ - .bEndpointAddress = USB_DIR_OUT | 0x02, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 64, - }, - } -}; - -static const USBDescDevice desc_device_full = { - .bcdUSB = 0x0200, - .bMaxPacketSize0 = 8, - .bNumConfigurations = 1, - .confs = (USBDescConfig[]) { - { - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = STR_CONFIG_FULL, - .bmAttributes = 0xc0, - .nif = 1, - .ifs = &desc_iface_full, - }, - }, -}; - -static const USBDescIface desc_iface_high = { - .bInterfaceNumber = 0, - .bNumEndpoints = 2, - .bInterfaceClass = USB_CLASS_MASS_STORAGE, - .bInterfaceSubClass = 0x06, /* SCSI */ - .bInterfaceProtocol = 0x50, /* Bulk */ - .eps = (USBDescEndpoint[]) { - { - .bEndpointAddress = USB_DIR_IN | 0x01, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, - },{ - .bEndpointAddress = USB_DIR_OUT | 0x02, - .bmAttributes = USB_ENDPOINT_XFER_BULK, - .wMaxPacketSize = 512, - }, - } -}; - -static const USBDescDevice desc_device_high = { - .bcdUSB = 0x0200, - .bMaxPacketSize0 = 64, - .bNumConfigurations = 1, - .confs = (USBDescConfig[]) { - { - .bNumInterfaces = 1, - .bConfigurationValue = 1, - .iConfiguration = STR_CONFIG_HIGH, - .bmAttributes = 0xc0, - .nif = 1, - .ifs = &desc_iface_high, - }, - }, -}; - -static const USBDesc desc = { - .id = { - .idVendor = 0, - .idProduct = 0, - .bcdDevice = 0, - .iManufacturer = STR_MANUFACTURER, - .iProduct = STR_PRODUCT, - .iSerialNumber = STR_SERIALNUMBER, - }, - .full = &desc_device_full, - .high = &desc_device_high, - .str = desc_strings, -}; - -static void usb_msd_copy_data(MSDState *s) -{ - uint32_t len; - len = s->usb_len; - if (len > s->scsi_len) - len = s->scsi_len; - if (s->mode == USB_MSDM_DATAIN) { - memcpy(s->usb_buf, s->scsi_buf, len); - } else { - memcpy(s->scsi_buf, s->usb_buf, len); - } - s->usb_len -= len; - s->scsi_len -= len; - s->usb_buf += len; - s->scsi_buf += len; - s->data_len -= len; - if (s->scsi_len == 0 || s->data_len == 0) { - scsi_req_continue(s->req); - } -} - -static void usb_msd_send_status(MSDState *s, USBPacket *p) -{ - struct usb_msd_csw csw; - int len; - - csw.sig = cpu_to_le32(0x53425355); - csw.tag = cpu_to_le32(s->tag); - csw.residue = s->residue; - csw.status = s->result; - - len = MIN(sizeof(csw), p->len); - memcpy(p->data, &csw, len); -} - -static void usb_msd_transfer_data(SCSIRequest *req, uint32_t len) -{ - MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); - USBPacket *p = s->packet; - - assert((s->mode == USB_MSDM_DATAOUT) == (req->cmd.mode == SCSI_XFER_TO_DEV)); - s->scsi_len = len; - s->scsi_buf = scsi_req_get_buf(req); - if (p) { - usb_msd_copy_data(s); - if (s->packet && s->usb_len == 0) { - /* Set s->packet to NULL before calling usb_packet_complete - because another request may be issued before - usb_packet_complete returns. */ - DPRINTF("Packet complete %p\n", p); - s->packet = NULL; - usb_packet_complete(&s->dev, p); - } - } -} - -static void usb_msd_command_complete(SCSIRequest *req, uint32_t status) -{ - MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); - USBPacket *p = s->packet; - - DPRINTF("Command complete %d\n", status); - s->residue = s->data_len; - s->result = status != 0; - if (s->packet) { - if (s->data_len == 0 && s->mode == USB_MSDM_DATAOUT) { - /* A deferred packet with no write data remaining must be - the status read packet. */ - usb_msd_send_status(s, p); - s->mode = USB_MSDM_CBW; - } else { - if (s->data_len) { - s->data_len -= s->usb_len; - if (s->mode == USB_MSDM_DATAIN) { - memset(s->usb_buf, 0, s->usb_len); - } - s->usb_len = 0; - } - if (s->data_len == 0) { - s->mode = USB_MSDM_CSW; - } - } - s->packet = NULL; - usb_packet_complete(&s->dev, p); - } else if (s->data_len == 0) { - s->mode = USB_MSDM_CSW; - } - scsi_req_unref(req); - s->req = NULL; -} - -static void usb_msd_request_cancelled(SCSIRequest *req) -{ - MSDState *s = DO_UPCAST(MSDState, dev.qdev, req->bus->qbus.parent); - - if (req == s->req) { - scsi_req_unref(s->req); - s->req = NULL; - s->packet = NULL; - s->scsi_len = 0; - } -} - -static void usb_msd_handle_reset(USBDevice *dev) -{ - MSDState *s = (MSDState *)dev; - - DPRINTF("Reset\n"); - s->mode = USB_MSDM_CBW; -} - -static int usb_msd_handle_control(USBDevice *dev, USBPacket *p, - int request, int value, int index, int length, uint8_t *data) -{ - MSDState *s = (MSDState *)dev; - int ret; - - ret = usb_desc_handle_control(dev, p, request, value, index, length, data); - if (ret >= 0) { - return ret; - } - - ret = 0; - switch (request) { - case DeviceRequest | USB_REQ_GET_INTERFACE: - data[0] = 0; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_INTERFACE: - ret = 0; - break; - case EndpointOutRequest | USB_REQ_CLEAR_FEATURE: - ret = 0; - break; - case InterfaceOutRequest | USB_REQ_SET_INTERFACE: - ret = 0; - break; - /* Class specific requests. */ - case ClassInterfaceOutRequest | MassStorageReset: - /* Reset state ready for the next CBW. */ - s->mode = USB_MSDM_CBW; - ret = 0; - break; - case ClassInterfaceRequest | GetMaxLun: - data[0] = 0; - ret = 1; - break; - default: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static void usb_msd_cancel_io(USBDevice *dev, USBPacket *p) -{ - MSDState *s = DO_UPCAST(MSDState, dev, dev); - scsi_req_cancel(s->req); -} - -static int usb_msd_handle_data(USBDevice *dev, USBPacket *p) -{ - MSDState *s = (MSDState *)dev; - int ret = 0; - struct usb_msd_cbw cbw; - uint8_t devep = p->devep; - uint8_t *data = p->data; - int len = p->len; - - switch (p->pid) { - case USB_TOKEN_OUT: - if (devep != 2) - goto fail; - - switch (s->mode) { - case USB_MSDM_CBW: - if (len != 31) { - fprintf(stderr, "usb-msd: Bad CBW size"); - goto fail; - } - memcpy(&cbw, data, 31); - if (le32_to_cpu(cbw.sig) != 0x43425355) { - fprintf(stderr, "usb-msd: Bad signature %08x\n", - le32_to_cpu(cbw.sig)); - goto fail; - } - DPRINTF("Command on LUN %d\n", cbw.lun); - if (cbw.lun != 0) { - fprintf(stderr, "usb-msd: Bad LUN %d\n", cbw.lun); - goto fail; - } - s->tag = le32_to_cpu(cbw.tag); - s->data_len = le32_to_cpu(cbw.data_len); - if (s->data_len == 0) { - s->mode = USB_MSDM_CSW; - } else if (cbw.flags & 0x80) { - s->mode = USB_MSDM_DATAIN; - } else { - s->mode = USB_MSDM_DATAOUT; - } - DPRINTF("Command tag 0x%x flags %08x len %d data %d\n", - s->tag, cbw.flags, cbw.cmd_len, s->data_len); - s->residue = 0; - s->scsi_len = 0; - s->req = scsi_req_new(s->scsi_dev, s->tag, 0, NULL); - scsi_req_enqueue(s->req, cbw.cmd); - /* ??? Should check that USB and SCSI data transfer - directions match. */ - if (s->mode != USB_MSDM_CSW && s->residue == 0) { - scsi_req_continue(s->req); - } - ret = len; - break; - - case USB_MSDM_DATAOUT: - DPRINTF("Data out %d/%d\n", len, s->data_len); - if (len > s->data_len) - goto fail; - - s->usb_buf = data; - s->usb_len = len; - if (s->scsi_len) { - usb_msd_copy_data(s); - } - if (s->residue && s->usb_len) { - s->data_len -= s->usb_len; - if (s->data_len == 0) - s->mode = USB_MSDM_CSW; - s->usb_len = 0; - } - if (s->usb_len) { - DPRINTF("Deferring packet %p\n", p); - s->packet = p; - ret = USB_RET_ASYNC; - } else { - ret = len; - } - break; - - default: - DPRINTF("Unexpected write (len %d)\n", len); - goto fail; - } - break; - - case USB_TOKEN_IN: - if (devep != 1) - goto fail; - - switch (s->mode) { - case USB_MSDM_DATAOUT: - if (s->data_len != 0 || len < 13) - goto fail; - /* Waiting for SCSI write to complete. */ - s->packet = p; - ret = USB_RET_ASYNC; - break; - - case USB_MSDM_CSW: - DPRINTF("Command status %d tag 0x%x, len %d\n", - s->result, s->tag, len); - if (len < 13) - goto fail; - - usb_msd_send_status(s, p); - s->mode = USB_MSDM_CBW; - ret = 13; - break; - - case USB_MSDM_DATAIN: - DPRINTF("Data in %d/%d, scsi_len %d\n", len, s->data_len, s->scsi_len); - if (len > s->data_len) - len = s->data_len; - s->usb_buf = data; - s->usb_len = len; - if (s->scsi_len) { - usb_msd_copy_data(s); - } - if (s->residue && s->usb_len) { - s->data_len -= s->usb_len; - memset(s->usb_buf, 0, s->usb_len); - if (s->data_len == 0) - s->mode = USB_MSDM_CSW; - s->usb_len = 0; - } - if (s->usb_len) { - DPRINTF("Deferring packet %p\n", p); - s->packet = p; - ret = USB_RET_ASYNC; - } else { - ret = len; - } - break; - - default: - DPRINTF("Unexpected read (len %d)\n", len); - goto fail; - } - break; - - default: - DPRINTF("Bad token\n"); - fail: - ret = USB_RET_STALL; - break; - } - - return ret; -} - -static void usb_msd_password_cb(void *opaque, int err) -{ - MSDState *s = opaque; - - if (!err) - err = usb_device_attach(&s->dev); - - if (err) - qdev_unplug(&s->dev.qdev); -} - -static const struct SCSIBusOps usb_msd_scsi_ops = { - .transfer_data = usb_msd_transfer_data, - .complete = usb_msd_command_complete, - .cancel = usb_msd_request_cancelled -}; - -static int usb_msd_initfn(USBDevice *dev) -{ - MSDState *s = DO_UPCAST(MSDState, dev, dev); - BlockDriverState *bs = s->conf.bs; - DriveInfo *dinfo; - - if (!bs) { - error_report("usb-msd: drive property not set"); - return -1; - } - - /* - * Hack alert: this pretends to be a block device, but it's really - * a SCSI bus that can serve only a single device, which it - * creates automatically. But first it needs to detach from its - * blockdev, or else scsi_bus_legacy_add_drive() dies when it - * attaches again. - * - * The hack is probably a bad idea. - */ - bdrv_detach(bs, &s->dev.qdev); - s->conf.bs = NULL; - - if (!s->serial) { - /* try to fall back to value set with legacy -drive serial=... */ - dinfo = drive_get_by_blockdev(bs); - if (*dinfo->serial) { - s->serial = strdup(dinfo->serial); - } - } - if (s->serial) { - usb_desc_set_string(dev, STR_SERIALNUMBER, s->serial); - } - - usb_desc_init(dev); - scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, &usb_msd_scsi_ops); - s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable); - if (!s->scsi_dev) { - return -1; - } - s->bus.qbus.allow_hotplug = 0; - usb_msd_handle_reset(dev); - - if (bdrv_key_required(bs)) { - if (cur_mon) { - monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb, s); - s->dev.auto_attach = 0; - } else { - autostart = 0; - } - } - - add_boot_device_path(s->conf.bootindex, &dev->qdev, "/disk@0,0"); - return 0; -} - -static USBDevice *usb_msd_init(const char *filename) -{ - static int nr=0; - char id[8]; - QemuOpts *opts; - DriveInfo *dinfo; - USBDevice *dev; - const char *p1; - char fmt[32]; - - /* parse -usbdevice disk: syntax into drive opts */ - snprintf(id, sizeof(id), "usb%d", nr++); - opts = qemu_opts_create(qemu_find_opts("drive"), id, 0); - - p1 = strchr(filename, ':'); - if (p1++) { - const char *p2; - - if (strstart(filename, "format=", &p2)) { - int len = MIN(p1 - p2, sizeof(fmt)); - pstrcpy(fmt, len, p2); - qemu_opt_set(opts, "format", fmt); - } else if (*filename != ':') { - printf("unrecognized USB mass-storage option %s\n", filename); - return NULL; - } - filename = p1; - } - if (!*filename) { - printf("block device specification needed\n"); - return NULL; - } - qemu_opt_set(opts, "file", filename); - qemu_opt_set(opts, "if", "none"); - - /* create host drive */ - dinfo = drive_init(opts, 0); - if (!dinfo) { - qemu_opts_del(opts); - return NULL; - } - - /* create guest device */ - dev = usb_create(NULL /* FIXME */, "usb-storage"); - if (!dev) { - return NULL; - } - if (qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv) < 0) { - qdev_free(&dev->qdev); - return NULL; - } - if (qdev_init(&dev->qdev) < 0) - return NULL; - - return dev; -} - -static struct USBDeviceInfo msd_info = { - .product_desc = "QEMU USB MSD", - .qdev.name = "usb-storage", - .qdev.fw_name = "storage", - .qdev.size = sizeof(MSDState), - .usb_desc = &desc, - .init = usb_msd_initfn, - .handle_packet = usb_generic_handle_packet, - .cancel_packet = usb_msd_cancel_io, - .handle_attach = usb_desc_attach, - .handle_reset = usb_msd_handle_reset, - .handle_control = usb_msd_handle_control, - .handle_data = usb_msd_handle_data, - .usbdevice_name = "disk", - .usbdevice_init = usb_msd_init, - .qdev.props = (Property[]) { - DEFINE_BLOCK_PROPERTIES(MSDState, conf), - DEFINE_PROP_STRING("serial", MSDState, serial), - DEFINE_PROP_BIT("removable", MSDState, removable, 0, false), - DEFINE_PROP_END_OF_LIST(), - }, -}; - -static void usb_msd_register_devices(void) -{ - usb_qdev_register(&msd_info); -} -device_init(usb_msd_register_devices) diff --git a/plugins/USBqemu/qemu-usb/usb-ohci.cpp b/plugins/USBqemu/qemu-usb/usb-ohci.cpp deleted file mode 100644 index 083df5a777..0000000000 --- a/plugins/USBqemu/qemu-usb/usb-ohci.cpp +++ /dev/null @@ -1,1512 +0,0 @@ -/* - * QEMU USB OHCI Emulation - * Copyright (c) 2004 Gianni Tedesco - * Copyright (c) 2006 CodeSourcery - * Copyright (c) 2006 Openedhand Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - * - * TODO: - * o Isochronous transfers - * o Allocate bandwidth in frames properly - * o Disable timers when nothing needs to be done, or remove timer usage - * all together. - * o Handle unrecoverable errors properly - * o BIOS work to boot from USB storage -*/ - -//typedef CPUReadMemoryFunc - -#include "USBinternal.h" - -s64 last_cycle = 0; -#define MIN_IRQ_INTERVAL 64 /* hack */ - -extern FILE* usbLog; - -int dprintf(const char *fmt,...) -{ -#ifdef DEBUG_OHCI - int t; - va_list list; - - va_start(list, fmt); - t=vfprintf(stderr, fmt, list); - va_end(list); - - if(usbLog) - { - va_start(list, fmt); - vfprintf(usbLog, fmt, list); - va_end(list); - } - - return t; -#else - return 0; -#endif -} - -static int last_level = 0; - -/* Update IRQ levels */ -static inline void ohci_intr_update(OHCIState *ohci) -{ - int level = 0; - - if ((ohci->intr & OHCI_INTR_MIE) && - (ohci->intr_status & ohci->intr)) - level = 1; - - if(level && !last_level) - { - if( (get_clock() - last_cycle) > MIN_IRQ_INTERVAL) - { - USBirq(1); - last_cycle = get_clock(); - } - } -} - -/* Set an interrupt */ -static inline void ohci_set_interrupt(OHCIState *ohci, uint32_t intr) -{ - ohci->intr_status |= intr; - ohci_intr_update(ohci); -} - -/* Attach or detach a device on a root hub port. */ -static void ohci_attach(USBPort *port1) -{ - OHCIState *s = (OHCIState*)port1->opaque; - OHCIPort *port = &s->rhport[port1->index]; - uint32_t old_state = port->ctrl; - - /* set connect status */ - port->ctrl |= OHCI_PORT_CCS | OHCI_PORT_CSC; - - /* update speed */ - if (port->port.dev->speed == USB_SPEED_LOW) { - port->ctrl |= OHCI_PORT_LSDA; - } else { - port->ctrl &= ~OHCI_PORT_LSDA; - } - - /* notify of remote-wakeup */ - if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) { - ohci_set_interrupt(s, OHCI_INTR_RD); - } - - dprintf("usb-ohci: Attached port %d\n", port1->index); - - if (old_state != port->ctrl) { - ohci_set_interrupt(s, OHCI_INTR_RHSC); - } -} - -static void ohci_async_cancel_device(OHCIState *ohci, USBDevice *dev) -{ - if (ohci->async_td && ohci->usb_packet.owner == dev) { - usb_cancel_packet(&ohci->usb_packet); - ohci->async_td = 0; - } -} - -static void ohci_detach(USBPort *port1) -{ - OHCIState *s = (OHCIState*)port1->opaque; - OHCIPort *port = &s->rhport[port1->index]; - uint32_t old_state = port->ctrl; - - ohci_async_cancel_device(s, port1->dev); - - /* set connect status */ - if (port->ctrl & OHCI_PORT_CCS) { - port->ctrl &= ~OHCI_PORT_CCS; - port->ctrl |= OHCI_PORT_CSC; - } - /* disable port */ - if (port->ctrl & OHCI_PORT_PES) { - port->ctrl &= ~OHCI_PORT_PES; - port->ctrl |= OHCI_PORT_PESC; - } - dprintf("usb-ohci: Detached port %d\n", port1->index); - - if (old_state != port->ctrl) { - ohci_set_interrupt(s, OHCI_INTR_RHSC); - } -} - -static void ohci_wakeup(USBPort *port1) -{ - OHCIState *s = (OHCIState*)port1->opaque; - OHCIPort *port = &s->rhport[port1->index]; - uint32_t intr = 0; - if (port->ctrl & OHCI_PORT_PSS) { - dprintf("usb-ohci: port %d: wakeup\n", port1->index); - port->ctrl |= OHCI_PORT_PSSC; - port->ctrl &= ~OHCI_PORT_PSS; - intr = OHCI_INTR_RHSC; - } - /* Note that the controller can be suspended even if this port is not */ - if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) { - dprintf("usb-ohci: remote-wakeup: SUSPEND->RESUME\n"); - /* This is the one state transition the controller can do by itself */ - s->ctl &= ~OHCI_CTL_HCFS; - s->ctl |= OHCI_USB_RESUME; - /* In suspend mode only ResumeDetected is possible, not RHSC: - * see the OHCI spec 5.1.2.3. - */ - intr = OHCI_INTR_RD; - } - ohci_set_interrupt(s, intr); -} - -static void ohci_child_detach(USBPort *port1, USBDevice *child) -{ - OHCIState *s = (OHCIState*)port1->opaque; - - ohci_async_cancel_device(s, child); -} - -/* Reset the controller */ -static void ohci_reset(void *opaque) -{ - OHCIState *ohci = (OHCIState *)opaque; - OHCIPort *port; - int i; - - ohci_bus_stop(ohci); - ohci->ctl = 0; - ohci->old_ctl = 0; - ohci->status = 0; - ohci->intr_status = 0; - ohci->intr = OHCI_INTR_MIE; - - ohci->hcca = 0; - ohci->ctrl_head = ohci->ctrl_cur = 0; - ohci->bulk_head = ohci->bulk_cur = 0; - ohci->per_cur = 0; - ohci->done = 0; - ohci->done_count = 7; - - /* FSMPS is marked TBD in OCHI 1.0, what gives ffs? - * I took the value linux sets ... - */ - ohci->fsmps = 0x2778; - ohci->fi = 0x2edf; - ohci->fit = 0; - ohci->frt = 0; - ohci->frame_number = 0; - ohci->pstart = 0; - ohci->lst = OHCI_LS_THRESH; - - ohci->rhdesc_a = OHCI_RHA_NPS | ohci->num_ports; - ohci->rhdesc_b = 0x0; /* Impl. specific */ - ohci->rhstatus = 0; - - for (i = 0; i < ohci->num_ports; i++) - { - port = &ohci->rhport[i]; - port->ctrl = 0; - if (port->port.dev) { - usb_attach(&port->port, port->port.dev); - } - } - if (ohci->async_td) { - usb_cancel_packet(&ohci->usb_packet); - ohci->async_td = 0; - } - dprintf("usb-ohci: Reset %s\n", ohci->name); -} - -/* Get an array of dwords from main memory */ -static inline int get_dwords(OHCIState *ohci, - uint32_t addr, uint32_t *buf, int num) -{ - int i; - - addr += ohci->localmem_base; - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - cpu_physical_memory_read(addr, (uint8_t*)buf, sizeof(*buf)); - *buf = (*buf); - } - - return 1; -} - -/* Put an array of dwords in to main memory */ -static inline int put_dwords(OHCIState *ohci, - uint32_t addr, uint32_t *buf, int num) -{ - int i; - - addr += ohci->localmem_base; - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - uint32_t tmp = (*buf); - cpu_physical_memory_write(addr, (uint8_t*)&tmp, sizeof(tmp)); - } - - return 1; -} - -/* Get an array of words from main memory */ -static inline int get_words(OHCIState *ohci, - uint32_t addr, uint16_t *buf, int num) -{ - int i; - - addr += ohci->localmem_base; - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - cpu_physical_memory_read(addr, (uint8_t*)buf, sizeof(*buf)); - *buf = (*buf); - } - - return 1; -} - -/* Put an array of words in to main memory */ -static inline int put_words(OHCIState *ohci, - uint32_t addr, uint16_t *buf, int num) -{ - int i; - - addr += ohci->localmem_base; - - for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) { - uint16_t tmp = (*buf); - cpu_physical_memory_write(addr, (uint8_t*)&tmp, sizeof(tmp)); - } - - return 1; -} - -static inline int ohci_read_ed(OHCIState *ohci, - uint32_t addr, struct ohci_ed *ed) -{ - return get_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2); -} - -static inline int ohci_read_td(OHCIState *ohci, - uint32_t addr, struct ohci_td *td) -{ - return get_dwords(ohci, addr, (uint32_t *)td, sizeof(*td) >> 2); -} - -static inline int ohci_read_iso_td(OHCIState *ohci, - uint32_t addr, struct ohci_iso_td *td) -{ - return (get_dwords(ohci, addr, (uint32_t *)td, 4) && - get_words(ohci, addr + 16, td->offset, 8)); -} - -static inline int ohci_read_hcca(OHCIState *ohci, - uint32_t addr, struct ohci_hcca *hcca) -{ - cpu_physical_memory_read(addr + ohci->localmem_base, (uint8_t*)hcca, sizeof(*hcca)); - return 1; -} - -static inline int ohci_put_ed(OHCIState *ohci, - uint32_t addr, struct ohci_ed *ed) -{ - return put_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed) >> 2); -} - -static inline int ohci_put_td(OHCIState *ohci, - uint32_t addr, struct ohci_td *td) -{ - return put_dwords(ohci, addr, (uint32_t *)td, sizeof(*td) >> 2); -} - -static inline int ohci_put_iso_td(OHCIState *ohci, - uint32_t addr, struct ohci_iso_td *td) -{ - return (put_dwords(ohci, addr, (uint32_t *)td, 4) && - put_words(ohci, addr + 16, td->offset, 8)); -} - -static inline int ohci_put_hcca(OHCIState *ohci, - uint32_t addr, struct ohci_hcca *hcca) -{ - cpu_physical_memory_write(addr + ohci->localmem_base, (uint8_t*)hcca, sizeof(*hcca)); - return 1; -} - -/* Read/Write the contents of a TD from/to main memory. */ -static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td, - uint8_t *buf, size_t len, int write) -{ - uint32_t ptr; - uint32_t n; - - ptr = td->cbp; - n = 0x1000 - (ptr & 0xfff); - if (n > len) - n = len; - cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write); - if (n == len) - return; - ptr = td->be & ~0xfffu; - buf += n; - cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write); -} - -/* Read/Write the contents of an ISO TD from/to main memory. */ -static void ohci_copy_iso_td(OHCIState *ohci, - uint32_t start_addr, uint32_t end_addr, - uint8_t *buf, size_t len, int write) -{ - uint32_t ptr; - uint32_t n; - - ptr = start_addr; - n = 0x1000 - (ptr & 0xfff); - if (n > len) - n = len; - cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write); - if (n == len) - return; - ptr = end_addr & ~0xfffu; - buf += n; - cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write); -} - -static void ohci_process_lists(OHCIState *ohci, int completion); - -static void ohci_async_complete_packet(USBPort *port, USBPacket *packet) -{ - OHCIState *ohci = (OHCIState*)packet->owner->opaque; -#ifdef DEBUG_PACKET - dprintf("Async packet complete\n"); -#endif - ohci->async_complete = 1; - ohci_process_lists(ohci, 1); -} - -#define USUB(a, b) ((int16_t)((uint16_t)(a) - (uint16_t)(b))) - -static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed, - int completion) -{ - int dir; - size_t len = 0; -#ifdef DEBUG_ISOCH - const char *str = NULL; -#endif - int pid; - int ret; - int i; - USBDevice *dev; - struct ohci_iso_td iso_td; - uint32_t addr; - uint16_t starting_frame; - int16_t relative_frame_number; - int frame_count; - uint32_t start_offset, next_offset, end_offset = 0; - uint32_t start_addr, end_addr; - - addr = ed->head & OHCI_DPTR_MASK; - - if (!ohci_read_iso_td(ohci, addr, &iso_td)) { - printf("usb-ohci: ISO_TD read error at %x\n", addr); - return 0; - } - - starting_frame = OHCI_BM(iso_td.flags, TD_SF); - frame_count = OHCI_BM(iso_td.flags, TD_FC); - relative_frame_number = USUB(ohci->frame_number, starting_frame); - -#ifdef DEBUG_ISOCH - printf("--- ISO_TD ED head 0x%.8x tailp 0x%.8x\n" - "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n" - "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n" - "0x%.8x 0x%.8x 0x%.8x 0x%.8x\n" - "frame_number 0x%.8x starting_frame 0x%.8x\n" - "frame_count 0x%.8x relative %d\n" - "di 0x%.8x cc 0x%.8x\n", - ed->head & OHCI_DPTR_MASK, ed->tail & OHCI_DPTR_MASK, - iso_td.flags, iso_td.bp, iso_td.next, iso_td.be, - iso_td.offset[0], iso_td.offset[1], iso_td.offset[2], iso_td.offset[3], - iso_td.offset[4], iso_td.offset[5], iso_td.offset[6], iso_td.offset[7], - ohci->frame_number, starting_frame, - frame_count, relative_frame_number, - OHCI_BM(iso_td.flags, TD_DI), OHCI_BM(iso_td.flags, TD_CC)); -#endif - - if (relative_frame_number < 0) { - dprintf("usb-ohci: ISO_TD R=%d < 0\n", relative_frame_number); - return 1; - } else if (relative_frame_number > frame_count) { - /* ISO TD expired - retire the TD to the Done Queue and continue with - the next ISO TD of the same ED */ - dprintf("usb-ohci: ISO_TD R=%d > FC=%d\n", relative_frame_number, - frame_count); - OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_DATAOVERRUN); - ed->head &= ~OHCI_DPTR_MASK; - ed->head |= (iso_td.next & OHCI_DPTR_MASK); - iso_td.next = ohci->done; - ohci->done = addr; - i = OHCI_BM(iso_td.flags, TD_DI); - if (i < ohci->done_count) - ohci->done_count = i; - ohci_put_iso_td(ohci, addr, &iso_td); - return 0; - } - - dir = OHCI_BM(ed->flags, ED_D); - switch (dir) { - case OHCI_TD_DIR_IN: -#ifdef DEBUG_ISOCH - str = "in"; -#endif - pid = USB_TOKEN_IN; - break; - case OHCI_TD_DIR_OUT: -#ifdef DEBUG_ISOCH - str = "out"; -#endif - pid = USB_TOKEN_OUT; - break; - case OHCI_TD_DIR_SETUP: -#ifdef DEBUG_ISOCH - str = "setup"; -#endif - pid = USB_TOKEN_SETUP; - break; - default: - printf("usb-ohci: Bad direction %d\n", dir); - return 1; - } - - if (!iso_td.bp || !iso_td.be) { - printf("usb-ohci: ISO_TD bp 0x%.8x be 0x%.8x\n", iso_td.bp, iso_td.be); - return 1; - } - - start_offset = iso_td.offset[relative_frame_number]; - next_offset = iso_td.offset[relative_frame_number + 1]; - - if (!(OHCI_BM(start_offset, TD_PSW_CC) & 0xe) || - ((relative_frame_number < frame_count) && - !(OHCI_BM(next_offset, TD_PSW_CC) & 0xe))) { - printf("usb-ohci: ISO_TD cc != not accessed 0x%.8x 0x%.8x\n", - start_offset, next_offset); - return 1; - } - - if ((relative_frame_number < frame_count) && (start_offset > next_offset)) { - printf("usb-ohci: ISO_TD start_offset=0x%.8x > next_offset=0x%.8x\n", - start_offset, next_offset); - return 1; - } - - if ((start_offset & 0x1000) == 0) { - start_addr = (iso_td.bp & OHCI_PAGE_MASK) | - (start_offset & OHCI_OFFSET_MASK); - } else { - start_addr = (iso_td.be & OHCI_PAGE_MASK) | - (start_offset & OHCI_OFFSET_MASK); - } - - if (relative_frame_number < frame_count) { - end_offset = next_offset - 1; - if ((end_offset & 0x1000) == 0) { - end_addr = (iso_td.bp & OHCI_PAGE_MASK) | - (end_offset & OHCI_OFFSET_MASK); - } else { - end_addr = (iso_td.be & OHCI_PAGE_MASK) | - (end_offset & OHCI_OFFSET_MASK); - } - } else { - /* Last packet in the ISO TD */ - end_addr = iso_td.be; - } - - if ((start_addr & OHCI_PAGE_MASK) != (end_addr & OHCI_PAGE_MASK)) { - len = (end_addr & OHCI_OFFSET_MASK) + 0x1001 - - (start_addr & OHCI_OFFSET_MASK); - } else { - len = end_addr - start_addr + 1; - } - - if (len && dir != OHCI_TD_DIR_IN) { - ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len, 0); - } - - if (completion) { - ret = ohci->usb_packet.len; - } else { - ret = USB_RET_NODEV; - for (i = 0; i < ohci->num_ports; i++) { - dev = ohci->rhport[i].port.dev; - if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0) - continue; - ohci->usb_packet.pid = pid; - ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA); - ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN); - ohci->usb_packet.data = ohci->usb_buf; - ohci->usb_packet.len = len; - ret = usb_handle_packet(dev, &ohci->usb_packet); - if (ret != USB_RET_NODEV) - break; - } - - if (ret == USB_RET_ASYNC) { - return 1; - } - } - -#ifdef DEBUG_ISOCH - printf("so 0x%.8x eo 0x%.8x\nsa 0x%.8x ea 0x%.8x\ndir %s len %zu ret %d\n", - start_offset, end_offset, start_addr, end_addr, str, len, ret); -#endif - - /* Writeback */ - if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= static_cast(len)) { - /* IN transfer succeeded */ - ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret, 1); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, - OHCI_CC_NOERROR); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret); - } else if (dir == OHCI_TD_DIR_OUT && ret == len) { - /* OUT transfer succeeded */ - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, - OHCI_CC_NOERROR); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, 0); - } else { - if (ret > (signed) len) { - printf("usb-ohci: DataOverrun %d > %zu\n", ret, len); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, - OHCI_CC_DATAOVERRUN); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, - len); - } else if (ret >= 0) { - printf("usb-ohci: DataUnderrun %d\n", ret); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, - OHCI_CC_DATAUNDERRUN); - } else { - switch (ret) { - case USB_RET_NODEV: - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, - OHCI_CC_DEVICENOTRESPONDING); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, - 0); - break; - case USB_RET_NAK: - case USB_RET_STALL: - printf("usb-ohci: got NAK/STALL %d\n", ret); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, - OHCI_CC_STALL); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, - 0); - break; - default: - printf("usb-ohci: Bad device response %d\n", ret); - OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC, - OHCI_CC_UNDEXPETEDPID); - break; - } - } - } - - if (relative_frame_number == frame_count) { - /* Last data packet of ISO TD - retire the TD to the Done Queue */ - OHCI_SET_BM(iso_td.flags, TD_CC, OHCI_CC_NOERROR); - ed->head &= ~OHCI_DPTR_MASK; - ed->head |= (iso_td.next & OHCI_DPTR_MASK); - iso_td.next = ohci->done; - ohci->done = addr; - i = OHCI_BM(iso_td.flags, TD_DI); - if (i < ohci->done_count) - ohci->done_count = i; - } - ohci_put_iso_td(ohci, addr, &iso_td); - return 1; -} - -/* Service a transport descriptor. - Returns nonzero to terminate processing of this endpoint. */ - -static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed) -{ - int dir; - size_t len = 0; -#ifdef DEBUG_PACKET - const char *str = NULL; -#endif - int pid; - int ret; - int i; - USBDevice *dev; - struct ohci_td td; - uint32_t addr; - int flag_r; - int completion; - - addr = ed->head & OHCI_DPTR_MASK; - /* See if this TD has already been submitted to the device. */ - completion = (addr == ohci->async_td); - if (completion && !ohci->async_complete) { -#ifdef DEBUG_PACKET - dprintf("Skipping async TD\n"); -#endif - return 1; - } - if (!ohci_read_td(ohci, addr, &td)) { - fprintf(stderr, "usb-ohci: TD read error at %x\n", addr); - return 0; - } - - dir = OHCI_BM(ed->flags, ED_D); - switch (dir) { - case OHCI_TD_DIR_OUT: - case OHCI_TD_DIR_IN: - /* Same value. */ - break; - default: - dir = OHCI_BM(td.flags, TD_DP); - break; - } - - switch (dir) { - case OHCI_TD_DIR_IN: -#ifdef DEBUG_PACKET - str = "in"; -#endif - pid = USB_TOKEN_IN; - break; - case OHCI_TD_DIR_OUT: -#ifdef DEBUG_PACKET - str = "out"; -#endif - pid = USB_TOKEN_OUT; - break; - case OHCI_TD_DIR_SETUP: -#ifdef DEBUG_PACKET - str = "setup"; -#endif - pid = USB_TOKEN_SETUP; - break; - default: - fprintf(stderr, "usb-ohci: Bad direction\n"); - return 1; - } - if (td.cbp && td.be) { - if ((td.cbp & 0xfffff000) != (td.be & 0xfffff000)) { - len = (td.be & 0xfff) + 0x1001 - (td.cbp & 0xfff); - } else { - len = (td.be - td.cbp) + 1; - } - - if (len && dir != OHCI_TD_DIR_IN && !completion) { - ohci_copy_td(ohci, &td, ohci->usb_buf, len, 0); - } - } - - flag_r = (td.flags & OHCI_TD_R) != 0; -#ifdef DEBUG_PACKET - dprintf(" TD @ 0x%.8x %" PRId64 " bytes %s r=%d cbp=0x%.8x be=0x%.8x\n", - addr, (int64_t)len, str, flag_r, td.cbp, td.be); - - if (len > 0 && dir != OHCI_TD_DIR_IN) { - dprintf(" data:"); - for (i = 0; i < len; i++) - printf(" %.2x", ohci->usb_buf[i]); - dprintf("\n"); - } -#endif - if (completion) { - ret = ohci->usb_packet.len; - ohci->async_td = 0; - ohci->async_complete = 0; - } else { - ret = USB_RET_NODEV; - for (i = 0; i < ohci->num_ports; i++) { - dev = ohci->rhport[i].port.dev; - if ((ohci->rhport[i].ctrl & OHCI_PORT_PES) == 0) - continue; - - if (ohci->async_td) { - /* ??? The hardware should allow one active packet per - endpoint. We only allow one active packet per controller. - This should be sufficient as long as devices respond in a - timely manner. - */ -#ifdef DEBUG_PACKET - dprintf("Too many pending packets\n"); -#endif - return 1; - } - ohci->usb_packet.pid = pid; - ohci->usb_packet.devaddr = OHCI_BM(ed->flags, ED_FA); - ohci->usb_packet.devep = OHCI_BM(ed->flags, ED_EN); - ohci->usb_packet.data = ohci->usb_buf; - ohci->usb_packet.len = len; - ret = usb_handle_packet(dev, &ohci->usb_packet); - if (ret != USB_RET_NODEV) - break; - } -#ifdef DEBUG_PACKET - dprintf("ret=%d\n", ret); -#endif - if (ret == USB_RET_ASYNC) { - ohci->async_td = addr; - return 1; - } - } - if (ret >= 0) { - if (dir == OHCI_TD_DIR_IN) { - ohci_copy_td(ohci, &td, ohci->usb_buf, ret, 1); -#ifdef DEBUG_PACKET - dprintf(" data:"); - for (i = 0; i < ret; i++) - printf(" %.2x", ohci->usb_buf[i]); - dprintf("\n"); -#endif - } else { - ret = len; - } - } - - /* Writeback */ - if (ret == len || (dir == OHCI_TD_DIR_IN && ret >= 0 && flag_r)) { - /* Transmission succeeded. */ - if (ret == len) { - td.cbp = 0; - } else { - td.cbp += ret; - if ((td.cbp & 0xfff) + ret > 0xfff) { - td.cbp &= 0xfff; - td.cbp |= td.be & ~0xfff; - } - } - td.flags |= OHCI_TD_T1; - td.flags ^= OHCI_TD_T0; - OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_NOERROR); - OHCI_SET_BM(td.flags, TD_EC, 0); - - ed->head &= ~OHCI_ED_C; - if (td.flags & OHCI_TD_T0) - ed->head |= OHCI_ED_C; - } else { - if (ret >= 0) { - dprintf("usb-ohci: Underrun\n"); - OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAUNDERRUN); - } else { - switch (ret) { - case USB_RET_NODEV: - OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DEVICENOTRESPONDING); - case USB_RET_NAK: - dprintf("usb-ohci: got NAK\n"); - return 1; - case USB_RET_STALL: - dprintf("usb-ohci: got STALL\n"); - OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_STALL); - break; - case USB_RET_BABBLE: - dprintf("usb-ohci: got BABBLE\n"); - OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_DATAOVERRUN); - break; - default: - fprintf(stderr, "usb-ohci: Bad device response %d\n", ret); - OHCI_SET_BM(td.flags, TD_CC, OHCI_CC_UNDEXPETEDPID); - OHCI_SET_BM(td.flags, TD_EC, 3); - break; - } - } - ed->head |= OHCI_ED_H; - } - - /* Retire this TD */ - ed->head &= ~OHCI_DPTR_MASK; - ed->head |= td.next & OHCI_DPTR_MASK; - td.next = ohci->done; - ohci->done = addr; - i = OHCI_BM(td.flags, TD_DI); - if (i < ohci->done_count) - ohci->done_count = i; - ohci_put_td(ohci, addr, &td); - return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR; -} - -/* Service an endpoint list. Returns nonzero if active TD were found. */ -static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) -{ - struct ohci_ed ed; - uint32_t next_ed; - uint32_t cur; - int active; - - active = 0; - - if (head == 0) - return 0; - - for (cur = head; cur; cur = next_ed) { - if (!ohci_read_ed(ohci, cur, &ed)) { - fprintf(stderr, "usb-ohci: ED read error at %x\n", cur); - return 0; - } - - next_ed = ed.next & OHCI_DPTR_MASK; - - if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) { - uint32_t addr; - /* Cancel pending packets for ED that have been paused. */ - addr = ed.head & OHCI_DPTR_MASK; - if (ohci->async_td && addr == ohci->async_td) { - usb_cancel_packet(&ohci->usb_packet); - ohci->async_td = 0; - } - continue; - } - - while ((ed.head & OHCI_DPTR_MASK) != ed.tail) { -#ifdef DEBUG_PACKET - dprintf("ED @ 0x%.8x fa=%u en=%u d=%u s=%u k=%u f=%u mps=%u " - "h=%u c=%u\n head=0x%.8x tailp=0x%.8x next=0x%.8x\n", cur, - OHCI_BM(ed.flags, ED_FA), OHCI_BM(ed.flags, ED_EN), - OHCI_BM(ed.flags, ED_D), (ed.flags & OHCI_ED_S)!= 0, - (ed.flags & OHCI_ED_K) != 0, (ed.flags & OHCI_ED_F) != 0, - OHCI_BM(ed.flags, ED_MPS), (ed.head & OHCI_ED_H) != 0, - (ed.head & OHCI_ED_C) != 0, ed.head & OHCI_DPTR_MASK, - ed.tail & OHCI_DPTR_MASK, ed.next & OHCI_DPTR_MASK); -#endif - active = 1; - - if ((ed.flags & OHCI_ED_F) == 0) { - if (ohci_service_td(ohci, &ed)) - break; - } else { - /* Handle isochronous endpoints */ - if (ohci_service_iso_td(ohci, &ed, completion)) - break; - } - } - - ohci_put_ed(ohci, cur, &ed); - } - - return active; -} - -/* Generate a SOF event, and set a timer for EOF */ -static void ohci_sof(OHCIState *ohci) -{ - ohci->sof_time = get_clock(); - ohci->eof_timer += usb_frame_time; - //ohci->sof_time = qemu_get_clock_ns(vm_clock); - //qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time); - ohci_set_interrupt(ohci, OHCI_INTR_SF); -} - -/* Process Control and Bulk lists. */ -static void ohci_process_lists(OHCIState *ohci, int completion) -{ - if ((ohci->ctl & OHCI_CTL_CLE) && (ohci->status & OHCI_STATUS_CLF)) { - if (ohci->ctrl_cur && ohci->ctrl_cur != ohci->ctrl_head) { - dprintf("usb-ohci: head %x, cur %x\n", - ohci->ctrl_head, ohci->ctrl_cur); - } - if (!ohci_service_ed_list(ohci, ohci->ctrl_head, completion)) { - ohci->ctrl_cur = 0; - ohci->status &= ~OHCI_STATUS_CLF; - } - } - - if ((ohci->ctl & OHCI_CTL_BLE) && (ohci->status & OHCI_STATUS_BLF)) { - if (!ohci_service_ed_list(ohci, ohci->bulk_head, completion)) { - ohci->bulk_cur = 0; - ohci->status &= ~OHCI_STATUS_BLF; - } - } -} - -/* Do frame processing on frame boundary */ -void ohci_frame_boundary(void *opaque) -{ - OHCIState *ohci = (OHCIState*)opaque; - struct ohci_hcca hcca; - - ohci_read_hcca(ohci, ohci->hcca, &hcca); - - /* Process all the lists at the end of the frame */ - if (ohci->ctl & OHCI_CTL_PLE) { - int n; - - n = ohci->frame_number & 0x1f; - ohci_service_ed_list(ohci, (hcca.intr[n]), 0); - } - - /* Cancel all pending packets if either of the lists has been disabled. */ - if (ohci->async_td && - ohci->old_ctl & (~ohci->ctl) & (OHCI_CTL_BLE | OHCI_CTL_CLE)) { - usb_cancel_packet(&ohci->usb_packet); - ohci->async_td = 0; - } - ohci->old_ctl = ohci->ctl; - ohci_process_lists(ohci, 0); - - /* Frame boundary, so do EOF stuf here */ - ohci->frt = ohci->fit; - - /* Increment frame number and take care of endianness. */ - ohci->frame_number = (ohci->frame_number + 1) & 0xffff; - hcca.frame = (ohci->frame_number); - - if (ohci->done_count == 0 && !(ohci->intr_status & OHCI_INTR_WD)) { - if (!ohci->done) - abort(); - if (ohci->intr & ohci->intr_status) - ohci->done |= 1; - hcca.done = (ohci->done); - ohci->done = 0; - ohci->done_count = 7; - ohci_set_interrupt(ohci, OHCI_INTR_WD); - } - - if (ohci->done_count != 7 && ohci->done_count != 0) - ohci->done_count--; - - /* Do SOF stuff here */ - ohci_sof(ohci); - - /* Writeback HCCA */ - ohci_put_hcca(ohci, ohci->hcca, &hcca); -} - -/* Start sending SOF tokens across the USB bus, lists are processed in - * next frame - */ -static int ohci_bus_start(OHCIState *ohci) -{ - ohci->eof_timer = 0; - - dprintf("usb-ohci: %s: USB Operational\n", ohci->name); - - ohci_sof(ohci); - - return 1; -} - -/* Stop sending SOF tokens on the bus */ -static void ohci_bus_stop(OHCIState *ohci) -{ - if (ohci->eof_timer) - ohci->eof_timer=0; -} - -/* Sets a flag in a port status register but only set it if the port is - * connected, if not set ConnectStatusChange flag. If flag is enabled - * return 1. - */ -static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val) -{ - int ret = 1; - - /* writing a 0 has no effect */ - if (val == 0) - return 0; - - /* If CurrentConnectStatus is cleared we set - * ConnectStatusChange - */ - if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) { - ohci->rhport[i].ctrl |= OHCI_PORT_CSC; - if (ohci->rhstatus & OHCI_RHS_DRWE) { - /* TODO: CSC is a wakeup event */ - } - return 0; - } - - if (ohci->rhport[i].ctrl & val) - ret = 0; - - /* set the bit */ - ohci->rhport[i].ctrl |= val; - - return ret; -} - -/* Set the frame interval - frame interval toggle is manipulated by the hcd only */ -static void ohci_set_frame_interval(OHCIState *ohci, uint16_t val) -{ - val &= OHCI_FMI_FI; - - if (val != ohci->fi) { - dprintf("usb-ohci: %s: FrameInterval = 0x%x (%u)\n", - ohci->name, ohci->fi, ohci->fi); - } - - ohci->fi = val; -} - -static void ohci_port_power(OHCIState *ohci, int i, int p) -{ - if (p) { - ohci->rhport[i].ctrl |= OHCI_PORT_PPS; - } else { - ohci->rhport[i].ctrl &= ~(OHCI_PORT_PPS| - OHCI_PORT_CCS| - OHCI_PORT_PSS| - OHCI_PORT_PRS); - } -} - -/* Set HcControlRegister */ -static void ohci_set_ctl(OHCIState *ohci, uint32_t val) -{ - uint32_t old_state; - uint32_t new_state; - - old_state = ohci->ctl & OHCI_CTL_HCFS; - ohci->ctl = val; - new_state = ohci->ctl & OHCI_CTL_HCFS; - - /* no state change */ - if (old_state == new_state) - return; - - switch (new_state) { - case OHCI_USB_OPERATIONAL: - ohci_bus_start(ohci); - break; - case OHCI_USB_SUSPEND: - ohci_bus_stop(ohci); - dprintf("usb-ohci: %s: USB Suspended\n", ohci->name); - break; - case OHCI_USB_RESUME: - dprintf("usb-ohci: %s: USB Resume\n", ohci->name); - break; - case OHCI_USB_RESET: - ohci_reset(ohci); - dprintf("usb-ohci: %s: USB Reset\n", ohci->name); - break; - } -} - -static uint32_t ohci_get_frame_remaining(OHCIState *ohci) -{ - uint16_t fr; - int64_t tks; - - if ((ohci->ctl & OHCI_CTL_HCFS) != OHCI_USB_OPERATIONAL) - return (ohci->frt << 31); - - /* Being in USB operational state guarnatees sof_time was - * set already. - */ - tks = get_clock() - ohci->sof_time; - - /* avoid muldiv if possible */ - if (tks >= usb_frame_time) - return (ohci->frt << 31); - - tks = muldiv64(1, static_cast(tks), static_cast(usb_bit_time)); - fr = (uint16_t)(ohci->fi - tks); - - return (ohci->frt << 31) | fr; -} - - -/* Set root hub status */ -static void ohci_set_hub_status(OHCIState *ohci, uint32_t val) -{ - uint32_t old_state; - - old_state = ohci->rhstatus; - - /* write 1 to clear OCIC */ - if (val & OHCI_RHS_OCIC) - ohci->rhstatus &= ~OHCI_RHS_OCIC; - - if (val & OHCI_RHS_LPS) { - int i; - - for (i = 0; i < ohci->num_ports; i++) - ohci_port_power(ohci, i, 0); - dprintf("usb-ohci: powered down all ports\n"); - } - - if (val & OHCI_RHS_LPSC) { - int i; - - for (i = 0; i < ohci->num_ports; i++) - ohci_port_power(ohci, i, 1); - dprintf("usb-ohci: powered up all ports\n"); - } - - if (val & OHCI_RHS_DRWE) - ohci->rhstatus |= OHCI_RHS_DRWE; - - if (val & OHCI_RHS_CRWE) - ohci->rhstatus &= ~OHCI_RHS_DRWE; - - if (old_state != ohci->rhstatus) - ohci_set_interrupt(ohci, OHCI_INTR_RHSC); -} - -/* Set root hub port status */ -static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val) -{ - uint32_t old_state; - OHCIPort *port; - - port = &ohci->rhport[portnum]; - old_state = port->ctrl; - - /* Write to clear CSC, PESC, PSSC, OCIC, PRSC */ - if (val & OHCI_PORT_WTC) - port->ctrl &= ~(val & OHCI_PORT_WTC); - - if (val & OHCI_PORT_CCS) - port->ctrl &= ~OHCI_PORT_PES; - - ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PES); - - if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PSS)) { - dprintf("usb-ohci: port %d: SUSPEND\n", portnum); - } - - if (ohci_port_set_if_connected(ohci, portnum, val & OHCI_PORT_PRS)) { - dprintf("usb-ohci: port %d: RESET\n", portnum); - usb_send_msg(port->port.dev, USB_MSG_RESET); - port->ctrl &= ~OHCI_PORT_PRS; - /* ??? Should this also set OHCI_PORT_PESC. */ - port->ctrl |= OHCI_PORT_PES | OHCI_PORT_PRSC; - } - - /* Invert order here to ensure in ambiguous case, device is - * powered up... - */ - if (val & OHCI_PORT_LSDA) - ohci_port_power(ohci, portnum, 0); - if (val & OHCI_PORT_PPS) - ohci_port_power(ohci, portnum, 1); - - if (old_state != port->ctrl) - ohci_set_interrupt(ohci, OHCI_INTR_RHSC); - - return; -} - -uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) -{ - OHCIState *ohci = (OHCIState*)ptr; - uint32_t retval; - - addr &= 0xff; - - /* Only aligned reads are allowed on OHCI */ - if (addr & 3) { - fprintf(stderr, "usb-ohci: Mis-aligned read\n"); - return 0xffffffff; - } else if (addr >= 0x54 && addr < 0x54U + ohci->num_ports * 4) { - /* HcRhPortStatus */ - retval = ohci->rhport[(addr - 0x54) >> 2].ctrl | OHCI_PORT_PPS; - } else { - switch (addr >> 2) { - case 0: /* HcRevision */ - retval = 0x10; - break; - - case 1: /* HcControl */ - retval = ohci->ctl; - break; - - case 2: /* HcCommandStatus */ - retval = ohci->status; - break; - - case 3: /* HcInterruptStatus */ - retval = ohci->intr_status; - break; - - case 4: /* HcInterruptEnable */ - case 5: /* HcInterruptDisable */ - retval = ohci->intr; - break; - - case 6: /* HcHCCA */ - retval = ohci->hcca; - break; - - case 7: /* HcPeriodCurrentED */ - retval = ohci->per_cur; - break; - - case 8: /* HcControlHeadED */ - retval = ohci->ctrl_head; - break; - - case 9: /* HcControlCurrentED */ - retval = ohci->ctrl_cur; - break; - - case 10: /* HcBulkHeadED */ - retval = ohci->bulk_head; - break; - - case 11: /* HcBulkCurrentED */ - retval = ohci->bulk_cur; - break; - - case 12: /* HcDoneHead */ - retval = ohci->done; - break; - - case 13: /* HcFmInterretval */ - retval = (ohci->fit << 31) | (ohci->fsmps << 16) | (ohci->fi); - break; - - case 14: /* HcFmRemaining */ - retval = ohci_get_frame_remaining(ohci); - break; - - case 15: /* HcFmNumber */ - retval = ohci->frame_number; - break; - - case 16: /* HcPeriodicStart */ - retval = ohci->pstart; - break; - - case 17: /* HcLSThreshold */ - retval = ohci->lst; - break; - - case 18: /* HcRhDescriptorA */ - retval = ohci->rhdesc_a; - break; - - case 19: /* HcRhDescriptorB */ - retval = ohci->rhdesc_b; - break; - - case 20: /* HcRhStatus */ - retval = ohci->rhstatus; - break; - - /* PXA27x specific registers */ - case 24: /* HcStatus */ - retval = ohci->hstatus & ohci->hmask; - break; - - case 25: /* HcHReset */ - retval = ohci->hreset; - break; - - case 26: /* HcHInterruptEnable */ - retval = ohci->hmask; - break; - - case 27: /* HcHInterruptTest */ - retval = ohci->htest; - break; - - default: - fprintf(stderr, "ohci_read: Bad offset %x\n", (int)addr); - retval = 0xffffffff; - } - } - - return retval; -} - -void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) -{ - OHCIState *ohci = (OHCIState *)ptr; - - addr &= 0xff; - - /* Only aligned reads are allowed on OHCI */ - if (addr & 3) { - fprintf(stderr, "usb-ohci: Mis-aligned write\n"); - return; - } - - if (addr >= 0x54 && addr < 0x54U + ohci->num_ports * 4) { - /* HcRhPortStatus */ - ohci_port_set_status(ohci, (addr - 0x54) >> 2, val); - return; - } - - switch (addr >> 2) { - case 1: /* HcControl */ - ohci_set_ctl(ohci, val); - break; - - case 2: /* HcCommandStatus */ - /* SOC is read-only */ - val = (val & ~OHCI_STATUS_SOC); - - /* Bits written as '0' remain unchanged in the register */ - ohci->status |= val; - - if (ohci->status & OHCI_STATUS_HCR) - ohci_reset(ohci); - break; - - case 3: /* HcInterruptStatus */ - ohci->intr_status &= ~val; - ohci_intr_update(ohci); - break; - - case 4: /* HcInterruptEnable */ - ohci->intr |= val; - ohci_intr_update(ohci); - break; - - case 5: /* HcInterruptDisable */ - ohci->intr &= ~val; - ohci_intr_update(ohci); - break; - - case 6: /* HcHCCA */ - ohci->hcca = val & OHCI_HCCA_MASK; - break; - - case 7: /* HcPeriodCurrentED */ - /* Ignore writes to this read-only register, Linux does them */ - break; - - case 8: /* HcControlHeadED */ - ohci->ctrl_head = val & OHCI_EDPTR_MASK; - break; - - case 9: /* HcControlCurrentED */ - ohci->ctrl_cur = val & OHCI_EDPTR_MASK; - break; - - case 10: /* HcBulkHeadED */ - ohci->bulk_head = val & OHCI_EDPTR_MASK; - break; - - case 11: /* HcBulkCurrentED */ - ohci->bulk_cur = val & OHCI_EDPTR_MASK; - break; - - case 13: /* HcFmInterval */ - ohci->fsmps = (val & OHCI_FMI_FSMPS) >> 16; - ohci->fit = (val & OHCI_FMI_FIT) >> 31; - ohci_set_frame_interval(ohci, val); - break; - - case 15: /* HcFmNumber */ - break; - - case 16: /* HcPeriodicStart */ - ohci->pstart = val & 0xffff; - break; - - case 17: /* HcLSThreshold */ - ohci->lst = val & 0xffff; - break; - - case 18: /* HcRhDescriptorA */ - ohci->rhdesc_a &= ~OHCI_RHA_RW_MASK; - ohci->rhdesc_a |= val & OHCI_RHA_RW_MASK; - break; - - case 19: /* HcRhDescriptorB */ - break; - - case 20: /* HcRhStatus */ - ohci_set_hub_status(ohci, val); - break; - - /* PXA27x specific registers */ - case 24: /* HcStatus */ - ohci->hstatus &= ~(val & ohci->hmask); - - case 25: /* HcHReset */ - ohci->hreset = val & ~OHCI_HRESET_FSBIR; - if (val & OHCI_HRESET_FSBIR) - ohci_reset(ohci); - break; - - case 26: /* HcHInterruptEnable */ - ohci->hmask = val; - break; - - case 27: /* HcHInterruptTest */ - ohci->htest = val; - break; - - default: - fprintf(stderr, "ohci_write: Bad offset %x\n", (int)addr); - break; - } -} - -static USBPortOps ohci_port_ops = { - ohci_attach, - ohci_detach, - ohci_child_detach, - ohci_wakeup, - ohci_async_complete_packet, -}; - -static USBBusOps ohci_bus_ops = { -}; - -OHCIState *ohci_create(uint32_t base, int ports) -{ - OHCIState *ohci=(OHCIState*)malloc(sizeof(OHCIState)); - int i; - - memset(ohci,0,sizeof(OHCIState)); - - //ohci->localmem_base=base; - - ohci->mem = base; - //ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci); - //ohci->localmem_base = localmem_base; - ohci->name = "USBemu"; - - //ohci->irq = irq; - //ohci->type = type; - - - if (usb_frame_time == 0) { -#ifdef OHCI_TIME_WARP - usb_frame_time = get_ticks_per_sec(); - usb_bit_time = muldiv64(1, get_ticks_per_sec(), USB_HZ/1000); -#else - usb_frame_time = muldiv64(1, static_cast(get_ticks_per_sec()), 1000U); - if (get_ticks_per_sec() >= USB_HZ) { - usb_bit_time = muldiv64(1U, static_cast(get_ticks_per_sec()), USB_HZ); - } else { - usb_bit_time = 1; - } -#endif - dprintf("usb-ohci: usb_bit_time=%" PRId64 " usb_frame_time=%" PRId64 "\n", - usb_frame_time, usb_bit_time); - } - - ohci->num_ports = ports; - for (i = 0; i < ports; i++) { - ohci->rhport[i].port.opaque = ohci; - ohci->rhport[i].port.index = i; - ohci->rhport[i].port.ops = &ohci_port_ops; - } - - ohci->async_td = 0; - - return ohci; -} diff --git a/plugins/USBqemu/qemu-usb/usb.h b/plugins/USBqemu/qemu-usb/usb.h deleted file mode 100644 index 6da423e67c..0000000000 --- a/plugins/USBqemu/qemu-usb/usb.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * QEMU USB API - * - * Copyright (c) 2005 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "qemu-queue.h" - -/* Constants related to the USB / PCI interaction */ -#define USB_SBRN 0x60 /* Serial Bus Release Number Register */ -#define USB_RELEASE_1 0x10 /* USB 1.0 */ -#define USB_RELEASE_2 0x20 /* USB 2.0 */ -#define USB_RELEASE_3 0x30 /* USB 3.0 */ - -#define USB_TOKEN_SETUP 0x2d -#define USB_TOKEN_IN 0x69 /* device -> host */ -#define USB_TOKEN_OUT 0xe1 /* host -> device */ - -/* specific usb messages, also sent in the 'pid' parameter */ -#define USB_MSG_ATTACH 0x100 -#define USB_MSG_DETACH 0x101 -#define USB_MSG_RESET 0x102 - -#define USB_RET_NODEV (-1) -#define USB_RET_NAK (-2) -#define USB_RET_STALL (-3) -#define USB_RET_BABBLE (-4) -#define USB_RET_ASYNC (-5) - -#define USB_SPEED_LOW 0 -#define USB_SPEED_FULL 1 -#define USB_SPEED_HIGH 2 -#define USB_SPEED_SUPER 3 - -#define USB_SPEED_MASK_LOW (1 << USB_SPEED_LOW) -#define USB_SPEED_MASK_FULL (1 << USB_SPEED_FULL) -#define USB_SPEED_MASK_HIGH (1 << USB_SPEED_HIGH) -#define USB_SPEED_MASK_SUPER (1 << USB_SPEED_SUPER) - -#define USB_STATE_NOTATTACHED 0 -#define USB_STATE_ATTACHED 1 -//#define USB_STATE_POWERED 2 -#define USB_STATE_DEFAULT 3 -//#define USB_STATE_ADDRESS 4 -//#define USB_STATE_CONFIGURED 5 -#define USB_STATE_SUSPENDED 6 - -#define USB_CLASS_AUDIO 1 -#define USB_CLASS_COMM 2 -#define USB_CLASS_HID 3 -#define USB_CLASS_PHYSICAL 5 -#define USB_CLASS_STILL_IMAGE 6 -#define USB_CLASS_PRINTER 7 -#define USB_CLASS_MASS_STORAGE 8 -#define USB_CLASS_HUB 9 -#define USB_CLASS_CDC_DATA 0x0a -#define USB_CLASS_CSCID 0x0b -#define USB_CLASS_CONTENT_SEC 0x0d -#define USB_CLASS_APP_SPEC 0xfe -#define USB_CLASS_VENDOR_SPEC 0xff - -#define USB_DIR_OUT 0 -#define USB_DIR_IN 0x80 - -#define USB_TYPE_MASK (0x03 << 5) -#define USB_TYPE_STANDARD (0x00 << 5) -#define USB_TYPE_CLASS (0x01 << 5) -#define USB_TYPE_VENDOR (0x02 << 5) -#define USB_TYPE_RESERVED (0x03 << 5) - -#define USB_RECIP_MASK 0x1f -#define USB_RECIP_DEVICE 0x00 -#define USB_RECIP_INTERFACE 0x01 -#define USB_RECIP_ENDPOINT 0x02 -#define USB_RECIP_OTHER 0x03 - -#define DeviceRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) -#define DeviceOutRequest ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_DEVICE)<<8) -#define InterfaceRequest \ - ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) -#define InterfaceOutRequest \ - ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_INTERFACE)<<8) -#define EndpointRequest ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) -#define EndpointOutRequest \ - ((USB_DIR_OUT|USB_TYPE_STANDARD|USB_RECIP_ENDPOINT)<<8) -#define ClassInterfaceRequest \ - ((USB_DIR_IN|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) -#define ClassInterfaceOutRequest \ - ((USB_DIR_OUT|USB_TYPE_CLASS|USB_RECIP_INTERFACE)<<8) - -#define USB_REQ_GET_STATUS 0x00 -#define USB_REQ_CLEAR_FEATURE 0x01 -#define USB_REQ_SET_FEATURE 0x03 -#define USB_REQ_SET_ADDRESS 0x05 -#define USB_REQ_GET_DESCRIPTOR 0x06 -#define USB_REQ_SET_DESCRIPTOR 0x07 -#define USB_REQ_GET_CONFIGURATION 0x08 -#define USB_REQ_SET_CONFIGURATION 0x09 -#define USB_REQ_GET_INTERFACE 0x0A -#define USB_REQ_SET_INTERFACE 0x0B -#define USB_REQ_SYNCH_FRAME 0x0C - -#define USB_DEVICE_SELF_POWERED 0 -#define USB_DEVICE_REMOTE_WAKEUP 1 - -#define USB_DT_DEVICE 0x01 -#define USB_DT_CONFIG 0x02 -#define USB_DT_STRING 0x03 -#define USB_DT_INTERFACE 0x04 -#define USB_DT_ENDPOINT 0x05 -#define USB_DT_DEVICE_QUALIFIER 0x06 -#define USB_DT_OTHER_SPEED_CONFIG 0x07 -#define USB_DT_DEBUG 0x0A -#define USB_DT_INTERFACE_ASSOC 0x0B - -#define USB_ENDPOINT_XFER_CONTROL 0 -#define USB_ENDPOINT_XFER_ISOC 1 -#define USB_ENDPOINT_XFER_BULK 2 -#define USB_ENDPOINT_XFER_INT 3 - -typedef struct USBBus USBBus; -typedef struct USBBusOps USBBusOps; -typedef struct USBPort USBPort; -typedef struct USBDevice USBDevice; -typedef struct USBDeviceInfo USBDeviceInfo; -typedef struct USBPacket USBPacket; - -typedef struct USBDesc USBDesc; -typedef struct USBDescID USBDescID; -typedef struct USBDescDevice USBDescDevice; -typedef struct USBDescConfig USBDescConfig; -typedef struct USBDescIfaceAssoc USBDescIfaceAssoc; -typedef struct USBDescIface USBDescIface; -typedef struct USBDescEndpoint USBDescEndpoint; -typedef struct USBDescOther USBDescOther; -typedef struct USBDescString USBDescString; - -struct USBDescString { - uint8_t index; - char *str; - QLIST_ENTRY(USBDescString) next; -}; - -/* definition of a USB device */ -struct USBDevice { - //DeviceState qdev; - USBDeviceInfo *info; - USBPort *port; - char *port_path; - void *opaque; - - /* Actual connected speed */ - int speed; - /* Supported speeds, not in info because it may be variable (hostdevs) */ - int speedmask; - uint8_t addr; - char product_desc[32]; - int auto_attach; - int attached; - - int32_t state; - uint8_t setup_buf[8]; - uint8_t data_buf[4096]; - int32_t remote_wakeup; - int32_t setup_state; - int32_t setup_len; - int32_t setup_index; - - QLIST_HEAD(, USBDescString) strings; - const USBDescDevice *device; - const USBDescConfig *config; -}; - -struct USBDeviceInfo { - //DeviceInfo qdev; - int (*init)(USBDevice *dev); - - /* - * Process USB packet. - * Called by the HC (Host Controller). - * - * Returns length of the transaction - * or one of the USB_RET_XXX codes. - */ - int (*handle_packet)(USBDevice *dev, USBPacket *p); - - /* - * Called when a packet is canceled. - */ - void (*cancel_packet)(USBDevice *dev, USBPacket *p); - - /* - * Called when device is destroyed. - */ - void (*handle_destroy)(USBDevice *dev); - - /* - * Attach the device - */ - void (*handle_attach)(USBDevice *dev); - - /* - * Reset the device - */ - void (*handle_reset)(USBDevice *dev); - - /* - * Process control request. - * Called from handle_packet(). - * - * Returns length or one of the USB_RET_ codes. - */ - int (*handle_control)(USBDevice *dev, USBPacket *p, int request, int value, - int index, int length, uint8_t *data); - - /* - * Process data transfers (both BULK and ISOC). - * Called from handle_packet(). - * - * Returns length or one of the USB_RET_ codes. - */ - int (*handle_data)(USBDevice *dev, USBPacket *p); - - const char *product_desc; - const USBDesc *usb_desc; - - /* handle legacy -usbdevice command line options */ - const char *usbdevice_name; - USBDevice *(*usbdevice_init)(const char *params); -}; - -typedef struct USBPortOps { - void (*attach)(USBPort *port); - void (*detach)(USBPort *port); - /* - * This gets called when a device downstream from the device attached to - * the port (iow attached through a hub) gets detached. - */ - void (*child_detach)(USBPort *port, USBDevice *child); - void (*wakeup)(USBPort *port); - /* - * Note that port->dev will be different then the device from which - * the packet originated when a hub is involved, if you want the orginating - * device use p->owner - */ - void (*complete)(USBPort *port, USBPacket *p); -} USBPortOps; - -/* USB port on which a device can be connected */ -struct USBPort { - USBDevice *dev; - int speedmask; - char path[16]; - USBPortOps *ops; - void *opaque; - int index; /* internal port index, may be used with the opaque */ - QTAILQ_ENTRY(USBPort) next; -}; - -typedef void USBCallback(USBPacket * packet, void *opaque); - -/* Structure used to hold information about an active USB packet. */ -struct USBPacket { - /* Data fields for use by the driver. */ - int pid; - uint8_t devaddr; - uint8_t devep; - uint8_t *data; - int len; - /* Internal use by the USB layer. */ - USBDevice *owner; -}; - -int usb_handle_packet(USBDevice *dev, USBPacket *p); -void usb_packet_complete(USBDevice *dev, USBPacket *p); -void usb_cancel_packet(USBPacket * p); - -void usb_attach(USBPort *port, USBDevice *dev); -void usb_wakeup(USBDevice *dev); -int usb_generic_handle_packet(USBDevice *s, USBPacket *p); -void usb_generic_async_ctrl_complete(USBDevice *s, USBPacket *p); -int set_usb_string(uint8_t *buf, const char *str); -void usb_send_msg(USBDevice *dev, int msg); - -/* usb-linux.c */ -//USBDevice *usb_host_device_open(const char *devname); -//int usb_host_device_close(const char *devname); -//void usb_host_info(Monitor *mon); - -/* usb-hid.c */ -void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)); - -/* usb-bt.c */ -//USBDevice *usb_bt_init(HCIInfo *hci); - -/* usb ports of the VM */ - -#define VM_USB_HUB_SIZE 8 - -/* usb-musb.c */ -enum musb_irq_source_e { - musb_irq_suspend = 0, - musb_irq_resume, - musb_irq_rst_babble, - musb_irq_sof, - musb_irq_connect, - musb_irq_disconnect, - musb_irq_vbus_request, - musb_irq_vbus_error, - musb_irq_rx, - musb_irq_tx, - musb_set_vbus, - musb_set_session, - __musb_irq_max, -}; - -typedef struct MUSBState MUSBState; -//MUSBState *musb_init(qemu_irq *irqs); -uint32_t musb_core_intr_get(MUSBState *s); -void musb_core_intr_clear(MUSBState *s, uint32_t mask); -void musb_set_size(MUSBState *s, int epnum, int size, int is_tx); - -/* usb-bus.c */ - -struct USBBus { - //BusState qbus; - USBBusOps *ops; - int busnr; - int nfree; - int nused; - QTAILQ_HEAD(, USBPort) free; - QTAILQ_HEAD(, USBPort) used; - QTAILQ_ENTRY(USBBus) next; -}; - -struct USBBusOps { - int (*register_companion)(USBBus *bus, USBPort *ports[], - uint32_t portcount, uint32_t firstport); -}; - -//void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host); -USBBus *usb_bus_find(int busnr); -void usb_qdev_register(USBDeviceInfo *info); -void usb_qdev_register_many(USBDeviceInfo *info); -USBDevice *usb_create(USBBus *bus, const char *name); -USBDevice *usb_create_simple(USBBus *bus, const char *name); -USBDevice *usbdevice_create(const char *cmdline); -void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, - USBPortOps *ops, int speedmask); -int usb_register_companion(const char *masterbus, USBPort *ports[], - uint32_t portcount, uint32_t firstport, - void *opaque, USBPortOps *ops, int speedmask); -void usb_port_location(USBPort *downstream, USBPort *upstream, int portnr); -void usb_unregister_port(USBBus *bus, USBPort *port); -int usb_device_attach(USBDevice *dev); -int usb_device_detach(USBDevice *dev); -int usb_device_delete_addr(int busnr, int addr); -// -//static inline USBBus *usb_bus_from_device(USBDevice *d) -//{ -// return DO_UPCAST(USBBus, qbus, d->qdev.parent_bus); -//} - -USBDevice *usb_keyboard_init(void); diff --git a/plugins/USBqemu/qemu-usb/vl.cpp b/plugins/USBqemu/qemu-usb/vl.cpp deleted file mode 100644 index 08657eca74..0000000000 --- a/plugins/USBqemu/qemu-usb/vl.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include -#include "vl.h" - -void cpu_physical_memory_rw(uint32_t addr, uint8_t *buf, - int len, int is_write); - -/* compute with 96 bit intermediate result: (a*b)/c */ -uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c) -{ - union { - uint64_t ll; - struct { -#ifdef WORDS_BIGENDIAN - uint32_t high, low; -#else - uint32_t low, high; -#endif - } l; - } u, res; - uint64_t rl, rh; - - u.ll = a; - rl = (uint64_t)u.l.low * (uint64_t)b; - rh = (uint64_t)u.l.high * (uint64_t)b; - rh += (rl >> 32); - res.l.high = static_cast(rh / c); - res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c; - return res.ll; -} diff --git a/plugins/USBqemu/qemu-usb/vl.h b/plugins/USBqemu/qemu-usb/vl.h deleted file mode 100644 index 226862f07b..0000000000 --- a/plugins/USBqemu/qemu-usb/vl.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * QEMU System Emulator header - * - * Copyright (c) 2003 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#ifndef VL_H -#define VL_H - -/* we put basic includes here to avoid repeating them in device drivers */ -#include -#include -#include -#include - -typedef signed __int8 int8_t; -typedef signed __int16 int16_t; -typedef signed __int32 int32_t; -typedef signed __int64 int64_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; - -#include -#include -#include -#include -#include -#include - -#define inline __inline - -#ifndef O_LARGEFILE -#define O_LARGEFILE 0 -#endif -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -#ifdef _WIN32 -#include -#define fsync _commit -//#define lseek _lseeki64 -//#define ENOTSUP 4096 -extern int qemu_ftruncate64(int, int64_t); -#define ftruncate qemu_ftruncate64 - - -static inline char *realpath(const char *path, char *resolved_path) -{ - _fullpath(resolved_path, path, _MAX_PATH); - return resolved_path; -} - -#define PRId64 "I64d" -#define PRIx64 "I64x" -#define PRIu64 "I64u" -#define PRIo64 "I64o" -#endif - -#include "usb.h" - -#ifndef glue -#define xglue(x, y) x ## y -#define glue(x, y) xglue(x, y) -#define stringify(s) tostring(s) -#define tostring(s) #s -#endif - -#ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#endif - -/* vl.c */ -uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c); -void cpu_physical_memory_rw(uint32_t addr, uint8_t *buf, int len, int is_write); -static inline void cpu_physical_memory_read(uint32_t addr, uint8_t *buf, int len) -{ - cpu_physical_memory_rw(addr, buf, len, 0); -} - -static inline void cpu_physical_memory_write(uint32_t addr, const uint8_t *buf, int len) -{ - cpu_physical_memory_rw(addr, (uint8_t *)buf, len, 1); -} - -void *qemu_mallocz(uint32_t size); - -#endif /* VL_H */ diff --git a/plugins/USBqemu/usb-eyetoy/usb-eyetoy.cpp b/plugins/USBqemu/usb-eyetoy/usb-eyetoy.cpp deleted file mode 100644 index a8b7c5f9e3..0000000000 --- a/plugins/USBqemu/usb-eyetoy/usb-eyetoy.cpp +++ /dev/null @@ -1,7873 +0,0 @@ -/* - * QEMU USB HUB emulation - * - * Copyright (c) 2005 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -//#define DEBUG - -#define MAX_PORTS 8 - -#include "../qemu-usb/vl.h" - -/* HID interface requests */ -#define GET_REPORT 0xa101 -#define GET_IDLE 0xa102 -#define GET_PROTOCOL 0xa103 -#define SET_IDLE 0x210a -#define SET_PROTOCOL 0x210b - -typedef struct EYETOYState { - USBDevice dev; - //nothing yet -} EYETOYState; - -/* same as Linux kernel root hubs */ - -/* mostly the same values as the Bochs USB Mouse device */ -static const uint8_t eyetoy_dev_descriptor[] = { - 0x12, /* bLength */ - 0x01, /* bDescriptorType */ - 0x10, 0x01, /* bcdUSB */ - 0x00, /* bDeviceClass */ - 0x00, /* bDeviceSubClass */ - 0x00, /* bDeviceProtocol */ - 0x08, /* bMaxPacketSize0 */ - 0x4c, 0x05, /* idVendor */ - 0x55, 0x01, /* idProduct */ - 0x00, 0x01, /* bcdDevice */ - 0x01, /* iManufacturer */ - 0x02, /* iProduct */ - 0x00, /* iSerialNumber */ - 0x01, /* bNumConfigurations */ -}; - -/* XXX: patch interrupt size */ -static const uint8_t eyetoy_config_descriptor[] = { - - /* one configuration */ - 0x09, /* u8 bLength; */ - 0x02, /* u8 bDescriptorType; Configuration */ - 0xb4, 0x00, /* u16 wTotalLength; */ - 0x03, /* u8 bNumInterfaces; (3) */ - 0x01, /* u8 bConfigurationValue; */ - 0x00, /* u8 iConfiguration; */ - 0x90, /* u8 bmAttributes; - Bit 7: must be set, - 6: Self-powered, - 5: Remote wakeup, - 4..0: resvd */ - 0xfa, /* u8 MaxPower; */ - - /* interface #0 alternate setting #0 */ - 0x09, /* u8 if_bLength; */ - 0x04, /* u8 if_bDescriptorType; Interface */ - 0x00, /* u8 if_bInterfaceNumber; */ - 0x00, /* u8 if_bAlternateSetting; */ - 0x01, /* u8 if_bNumEndpoints; */ - 0xff, /* u8 if_bInterfaceClass; Vendor Specific */ - 0x00, /* u8 if_bInterfaceSubClass; */ - 0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ - 0x00, /* u8 if_iInterface; */ - - /* interface #0 alternate setting #0 endpoint */ - 0x07, /* u8 ep_bLength; */ - 0x05, /* u8 ep_bDescriptorType; Endpoint */ - 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x01, /* u8 ep_bmAttributes; */ - 0x00, 0x00, /* u16 ep_wMaxPacketSize; 1 + (MAX_ROOT_PORTS / 8) */ - 0x01, /* u8 ep_bInterval; */ - - /* interface #0 alternate setting #1 */ - 0x09, 0x04, 0x00, 0x01, 0x01, 0xff, 0x00, 0x00, 0x00, - 0x07, 0x05, 0x81, 0x01, 0x80, 0x01, 0x01, - - /* interface #0 alternate setting #2*/ - 0x09, 0x04, 0x00, 0x02, 0x01, 0xff, 0x00, 0x00, 0x00, - 0x07, 0x05, 0x81, 0x01, 0x00, 0x02, 0x01, - - /* interface #0 alternate setting #3 */ - 0x09, 0x04, 0x00, 0x03, 0x01, 0xff, 0x00, 0x00, 0x00, - 0x07, 0x05, 0x81, 0x01, 0x00, 0x03, 0x01, - - /* interface #0 alternate setting #4 */ - 0x09, 0x04, 0x00, 0x04, 0x01, 0xff, 0x00, 0x00, 0x00, - 0x07, 0x05, 0x81, 0x01, 0x80, 0x03, 0x01, - - /* interface #1 alternate setting #0 */ - 0x09, /* u8 if_bLength; */ - 0x04, /* u8 if_bDescriptorType; Interface */ - 0x01, /* u8 if_bInterfaceNumber; */ - 0x00, /* u8 if_bAlternateSetting; */ - 0x00, /* u8 if_bNumEndpoints; */ - 0x01, /* u8 if_bInterfaceClass; AUDIO */ - 0x01, /* u8 if_bInterfaceSubClass; AUDIOCONTROL*/ - 0x00, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ - 0x00, /* u8 if_iInterface; */ - - /* interface #1 alternate setting #0 classes */ - 0x09, 0x24, 0x01, 0x00, 0x01, 0x1e, 0x00, 0x01, 0x02, - 0x0c, 0x24, 0x02, 0x01, 0x01, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x24, 0x03, 0x02, 0x01, 0x01, 0x00, 0x01, 0x00, - - /* interface #2 alternate setting #0 (AUDIO class, AUDIOSTREAMING subclass) */ - 0x09, 0x04, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, - - /* interface #2 alternate setting #1 (AUDIO class, AUDIOSTREAMING subclass) */ - 0x09, 0x04, 0x02, 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, - - /* interface #1 class-specific interface (HEADER) */ - 0x07, 0x24, 0x01, 0x02, 0x01, 0x01, 0x00, - - /* interface #1 class-specific interface (INPUT TERMINAL) */ - 0x0b, 0x24, 0x02, 0x01, 0x01, 0x02, 0x10, 0x01, 0x80, 0x3e, 0x00, - - /* interface #1 alternate setting #1 endpoint */ - 0x09, 0x05, 0x82, 0x05, 0x28, 0x00, 0x01, 0x00, 0x00, - - /* interface #1 class-specific endpoint */ - 0x07, 0x25, 0x01, 0x00, 0x00, 0x00, 0x00 -}; - -static void eyetoy_handle_reset(USBDevice *dev) -{ - /* XXX: do it */ - return; -} - -static int eyetoy_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) -{ - EYETOYState *s = (EYETOYState *)dev; - int ret = 0; - - switch(request) { - case DeviceRequest | USB_REQ_GET_STATUS: - data[0] = (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP); - data[1] = 0x00; - ret = 2; - break; - case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: - if (value == USB_DEVICE_REMOTE_WAKEUP) { - dev->remote_wakeup = 0; - } else { - goto fail; - } - ret = 0; - break; - case DeviceOutRequest | USB_REQ_SET_FEATURE: - if (value == USB_DEVICE_REMOTE_WAKEUP) { - dev->remote_wakeup = 1; - } else { - goto fail; - } - ret = 0; - break; - case DeviceOutRequest | USB_REQ_SET_ADDRESS: - dev->addr = value; - ret = 0; - break; - case DeviceRequest | USB_REQ_GET_DESCRIPTOR: - switch(value >> 8) { - case USB_DT_DEVICE: - memcpy(data, eyetoy_dev_descriptor, - sizeof(eyetoy_dev_descriptor)); - ret = sizeof(eyetoy_dev_descriptor); - break; - case USB_DT_CONFIG: - memcpy(data, eyetoy_config_descriptor, - sizeof(eyetoy_config_descriptor)); - ret = sizeof(eyetoy_config_descriptor); - break; - case USB_DT_STRING: - switch(value & 0xff) { - case 0: - /* language ids */ - data[0] = 4; - data[1] = 3; - data[2] = 0x09; - data[3] = 0x04; - ret = 4; - break; - case 1: - /* serial number */ - ret = set_usb_string(data, "3X0420811"); - break; - case 2: - /* product description */ - ret = set_usb_string(data, "EyeToy USB camera Namtai"); - break; - case 3: - /* vendor description */ - ret = set_usb_string(data, "PCSX2/QEMU"); - break; - default: - goto fail; - } - break; - default: - goto fail; - } - break; - case DeviceRequest | USB_REQ_GET_CONFIGURATION: - data[0] = 1; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: - ret = 0; - break; - case DeviceRequest | USB_REQ_GET_INTERFACE: - data[0] = 0; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_INTERFACE: - ret = 0; - break; - /* hid specific requests */ - case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: - //switch(value >> 8) { - //((case 0x22: - // memcpy(data, qemu_mouse_hid_report_descriptor, - // sizeof(qemu_mouse_hid_report_descriptor)); - // ret = sizeof(qemu_mouse_hid_report_descriptor); - // break; - //default: - goto fail; - //} - break; - case GET_REPORT: - ret = 0; - break; - case SET_IDLE: - ret = 0; - break; - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static int eyetoy_handle_data(USBDevice *dev, int pid, - uint8_t devep, uint8_t *data, int len) -{ - EYETOYState *s = (EYETOYState *)dev; - int ret = 0; - - switch(pid) { - case USB_TOKEN_IN: - if (devep == 1) { - goto fail; - } - break; - case USB_TOKEN_OUT: - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - - -static void eyetoy_handle_destroy(USBDevice *dev) -{ - EYETOYState *s = (EYETOYState *)dev; - - free(s); -} - -int eyetoy_handle_packet(USBDevice *s, int pid, - uint8_t devaddr, uint8_t devep, - uint8_t *data, int len) -{ - fprintf(stderr,"usb-eyetoy: packet received with pid=%x, devaddr=%x, devep=%x and len=%x\n",pid,devaddr,devep,len); - usb_generic_handle_packet(s,pid,devaddr,devep,data,len); -} - -USBDevice *eyetoy_init() -{ - EYETOYState *s; - - s = qemu_mallocz(sizeof(EYETOYState)); - if (!s) - return NULL; - s->dev.speed = USB_SPEED_FULL; - s->dev.handle_packet = eyetoy_handle_packet; - - s->dev.handle_reset = eyetoy_handle_reset; - s->dev.handle_control = eyetoy_handle_control; - s->dev.handle_data = eyetoy_handle_data; - s->dev.handle_destroy = eyetoy_handle_destroy; - - strncpy(s->dev.devname, "EyeToy USB camera Namtai", sizeof(s->dev.devname)); - - return (USBDevice *)s; - -} - -#ifdef X_DRIVER -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////// - -/* Video-to-USB Bridge Driver for OmniVision OV511/OV511+/OV518/OV518+/OV519 - * - * Copyright (c) 1999-2005 Mark W. McClelland - * Support for OV519, OV8610 Copyright (c) 2003 Joerg Heckenbach - * - * Original decompression code Copyright 1998-2000 OmniVision Technologies - * Many improvements by Bret Wallach - * Color fixes by by Orion Sky Lawlor (2/26/2000) - * Snapshot code by Kevin Moore - * OV7620 fixes by Charl P. Botha - * Changes by Claudio Matsuoka - * Original SAA7111A code by Dave Perks - * URB error messages from pwc driver by Nemosoft - * generic_ioctl() code from videodev.c by Gerd Knorr and Alan Cox - * Memory management (rvmalloc) code from bttv driver, by Gerd Knorr and others - * OV7x3x/7x4x detection by Franz Reinhardt - * 2004/01/25: Added OV7640 and EyeToy support (Mark McClelland) - * - * Based on the Linux CPiA driver written by Peter Pregler, - * Scott J. Bertin and Johannes Erdfelt. - * - * Please see the file: doc/ov51x.txt - * and the website at: http://alpha.dyndns.org/ov511 - * for more info. - * For Questions on OV519 or OV8610 please contact - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA. - */ - -#ifdef OV511_ALLOW_CONVERSION - /* Pixel count * 3 bytes for RGB */ - #define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3) -#else - /* Pixel count * bytes per YUV420 pixel (1.5) */ - #define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3 / 2) -#endif - -#define MAX_DATA_SIZE(w, h) (MAX_FRAME_SIZE(w, h) + sizeof(struct timeval)) - -/* Max size * bytes per YUV420 pixel (1.5) + one extra isoc frame for safety */ -#define MAX_RAW_DATA_SIZE(w, h) ((w) * (h) * 3 / 2 + 1024) - -#define FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM) - -/* URB error codes: */ -static struct symbolic_list urb_errlist[] = { - { -ENOSR, "Buffer error (overrun)" }, - { -EPIPE, "Stalled (device not responding)" }, - { -EOVERFLOW, "Babble (bad cable?)" }, - { -EPROTO, "Bit-stuff error (bad cable?)" }, - { -EILSEQ, "CRC/Timeout" }, - { -ETIMEDOUT, "NAK (device does not respond)" }, - { -1, NULL } -}; - - -/********************************************************************** - * /proc interface - * Based on the CPiA driver version 0.7.4 -claudio - **********************************************************************/ - -#if defined(CONFIG_VIDEO_PROC_FS) - -static struct proc_dir_entry *ov511_proc_entry = NULL; -extern struct proc_dir_entry *video_proc_entry; - -/* Prototypes */ -static void ov51x_clear_snapshot(struct usb_ov511 *); -static int sensor_get_picture(struct usb_ov511 *, struct video_picture *); -static int sensor_get_exposure(struct usb_ov511 *, unsigned char *); -static int ov51x_check_snapshot(struct usb_ov511 *); -static int ov51x_control_ioctl(struct inode *, struct file *, unsigned int, - unsigned long); - -static struct file_operations ov511_control_fops = { - .ioctl = ov51x_control_ioctl, -}; - -#define YES_NO(x) ((x) ? "yes" : "no") - - -/********************************************************************** - * - * Register I/O - * - **********************************************************************/ - -/* Write an OV51x register - - -ov->cbuf[0] = value; - -usb_control_msg: -pipe: ((PIPE_CONTROL << 30) | (dev->devnum << 8) | (0 << 15)), -request: 1, -requesttype: USB_TYPE_VENDOR | USB_RECIP_DEVICE, -value: 0, -index: (__u16)reg, -bytes: &ov->cbuf[0], -size: 1, -timeout: 1000 - -*/ - -/* Read from an OV51x register - -usb_control_msg: -pipe: ((PIPE_CONTROL << 30) | (dev->devnum << 8) | (0 << 15)), -request: 1, -requesttype: USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, -value: 0, -index: (__u16)reg, -bytes: &ov->cbuf[0], -size: 1, -timeout: 1000 - -if result<0 then error -else value = ov->cbuf[0]; - -*/ - -/* - * Writes a multbyte value to a single register. Only valid with certain - * registers (0x30 and 0xc4 - 0xce). - - ov->cbuf = value (in le order) - - rc = usb_control_msg(ov->dev, - usb_sndctrlpipe(ov->dev, 0) - 1 // REG_IO - USB_TYPE_VENDOR | USB_RECIP_DEVICE - 0 - (__u16)reg - ov->cbuf - n - 1000 - - */ - -static int -ov511_upload_quan_tables(struct usb_ov511 *ov) -{ - unsigned char *pYTable = yQuanTable511; - unsigned char *pUVTable = uvQuanTable511; - unsigned char val0, val1; - int i, rc, reg = R511_COMP_LUT_BEGIN; - - PDEBUG(4, "Uploading quantization tables"); - - for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) { - if (ENABLE_Y_QUANTABLE) { - val0 = *pYTable++; - val1 = *pYTable++; - val0 &= 0x0f; - val1 &= 0x0f; - val0 |= val1 << 4; - rc = reg_w(ov, reg, val0); - if (rc < 0) - return rc; - } - - if (ENABLE_UV_QUANTABLE) { - val0 = *pUVTable++; - val1 = *pUVTable++; - val0 &= 0x0f; - val1 &= 0x0f; - val0 |= val1 << 4; - rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0); - if (rc < 0) - return rc; - } - - reg++; - } - - return 0; -} - -/* OV518 quantization tables are 8x4 (instead of 8x8) */ -static int -ov518_upload_quan_tables(struct usb_ov511 *ov) -{ - unsigned char *pYTable = yQuanTable518; - unsigned char *pUVTable = uvQuanTable518; - unsigned char val0, val1; - int i, rc, reg = R511_COMP_LUT_BEGIN; - - PDEBUG(4, "Uploading quantization tables"); - - for (i = 0; i < OV518_QUANTABLESIZE / 2; i++) { - if (ENABLE_Y_QUANTABLE) { - val0 = *pYTable++; - val1 = *pYTable++; - val0 &= 0x0f; - val1 &= 0x0f; - val0 |= val1 << 4; - rc = reg_w(ov, reg, val0); - if (rc < 0) - return rc; - } - - if (ENABLE_UV_QUANTABLE) { - val0 = *pUVTable++; - val1 = *pUVTable++; - val0 &= 0x0f; - val1 &= 0x0f; - val0 |= val1 << 4; - rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0); - if (rc < 0) - return rc; - } - - reg++; - } - - return 0; -} - -static int -ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type) -{ - int rc = -1; - - if (ov->bclass == BCL_OV519) { - //~~~ - PDEBUG(1, "Reset: type=0x0f"); - switch (reset_type) { - case OV511_RESET_NOREGS: - rc = reg_w(ov, OV519_SYS_RESET1, 0x0f); -// rc = reg_w(ov, OV519_SYS_RESET0, 0xdc); -// rc = reg_w(ov, OV519_SYS_RESET0, 0); - rc = reg_w(ov, OV519_SYS_RESET1, 0); - break; - } - } else { - /* Setting bit 0 not allowed on 518/518Plus */ - if (ov->bclass == BCL_OV518) - reset_type &= 0xfe; - - PDEBUG(4, "Reset: type=0x%02X", reset_type); - - rc = reg_w(ov, R51x_SYS_RESET, reset_type); - rc = reg_w(ov, R51x_SYS_RESET, 0); - } - if (rc < 0) - err("reset: command failed"); - - return rc; -} - -/********************************************************************** - * - * Low-level I2C I/O functions - * - **********************************************************************/ - -/* NOTE: Do not call this function directly! - * The OV518 I2C I/O procedure is different, hence, this function. - * This is normally only called from i2c_w(). Note that this function - * always succeeds regardless of whether the sensor is present and working. - */ -static int -ov518_i2c_write_internal(struct usb_ov511 *ov, - unsigned char reg, - unsigned char value) -{ - int rc; - - PDEBUG(5, "0x%02X:0x%02X", reg, value); - - /* Select camera register */ - rc = reg_w(ov, R51x_I2C_SADDR_3, reg); - if (rc < 0) return rc; - - /* Write "value" to I2C data port of OV511 */ - rc = reg_w(ov, R51x_I2C_DATA, value); - if (rc < 0) return rc; - - /* Initiate 3-byte write cycle */ - rc = reg_w(ov, R518_I2C_CTL, 0x01); - if (rc < 0) return rc; - - return 0; -} - -/* NOTE: Do not call this function directly! */ -static int -ov511_i2c_write_internal(struct usb_ov511 *ov, - unsigned char reg, - unsigned char value) -{ - int rc, retries; - - PDEBUG(5, "0x%02X:0x%02X", reg, value); - - /* Three byte write cycle */ - for (retries = OV511_I2C_RETRIES; ; ) { - /* Select camera register */ - rc = reg_w(ov, R51x_I2C_SADDR_3, reg); - if (rc < 0) return rc; - - /* Write "value" to I2C data port of OV511 */ - rc = reg_w(ov, R51x_I2C_DATA, value); - if (rc < 0) return rc; - - /* Initiate 3-byte write cycle */ - rc = reg_w(ov, R511_I2C_CTL, 0x01); - if (rc < 0) return rc; - - do rc = reg_r(ov, R511_I2C_CTL); - while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */ - if (rc < 0) return rc; - - if ((rc&2) == 0) /* Ack? */ - break; -#if 0 - /* I2C abort */ - reg_w(ov, R511_I2C_CTL, 0x10); -#endif - if (--retries < 0) { - PDEBUG(5, "i2c write retries exhausted"); - return -1; - } - } - - return 0; -} - -/* NOTE: Do not call this function directly! - * The OV518 I2C I/O procedure is different, hence, this function. - * This is normally only called from i2c_r(). Note that this function - * always succeeds regardless of whether the sensor is present and working. - */ -static int -ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) -{ - int rc, value; - - /* Select camera register */ - rc = reg_w(ov, R51x_I2C_SADDR_2, reg); - if (rc < 0) return rc; - - /* Initiate 2-byte write cycle */ - rc = reg_w(ov, R518_I2C_CTL, 0x03); - if (rc < 0) return rc; - - /* Initiate 2-byte read cycle */ - rc = reg_w(ov, R518_I2C_CTL, 0x05); - if (rc < 0) return rc; - - value = reg_r(ov, R51x_I2C_DATA); - - PDEBUG(5, "0x%02X:0x%02X", reg, value); - - return value; -} - -/* NOTE: Do not call this function directly! - * returns: negative is error, pos or zero is data */ -static int -ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) -{ - int rc, value, retries; - - /* Two byte write cycle */ - for (retries = OV511_I2C_RETRIES; ; ) { - /* Select camera register */ - rc = reg_w(ov, R51x_I2C_SADDR_2, reg); - if (rc < 0) return rc; - - /* Initiate 2-byte write cycle */ - rc = reg_w(ov, R511_I2C_CTL, 0x03); - if (rc < 0) return rc; - - do rc = reg_r(ov, R511_I2C_CTL); - while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */ - if (rc < 0) return rc; - - if ((rc&2) == 0) /* Ack? */ - break; - - /* I2C abort */ - reg_w(ov, R511_I2C_CTL, 0x10); - - if (--retries < 0) { - PDEBUG(5, "i2c write retries exhausted"); - return -1; - } - } - - /* Two byte read cycle */ - for (retries = OV511_I2C_RETRIES; ; ) { - /* Initiate 2-byte read cycle */ - rc = reg_w(ov, R511_I2C_CTL, 0x05); - if (rc < 0) return rc; - - do rc = reg_r(ov, R511_I2C_CTL); - while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */ - if (rc < 0) return rc; - - if ((rc&2) == 0) /* Ack? */ - break; - - /* I2C abort */ - rc = reg_w(ov, R511_I2C_CTL, 0x10); - if (rc < 0) return rc; - - if (--retries < 0) { - PDEBUG(5, "i2c read retries exhausted"); - return -1; - } - } - - value = reg_r(ov, R51x_I2C_DATA); - - PDEBUG(5, "0x%02X:0x%02X", reg, value); - - /* This is needed to make i2c_w() work */ - rc = reg_w(ov, R511_I2C_CTL, 0x05); - if (rc < 0) - return rc; - - return value; -} - -/* returns: negative is error, pos or zero is data */ -static int -i2c_r(struct usb_ov511 *ov, unsigned char reg) -{ - int rc; - - down(&ov->i2c_lock); - - switch (ov->bclass) { - case BCL_OV511: - rc = ov511_i2c_read_internal(ov, reg); - break; - case BCL_OV518: - case BCL_OV519: - rc = ov518_i2c_read_internal(ov, reg); - break; - default: - err("i2c_r: Invalid bridge class"); - rc = -EINVAL; - } - up(&ov->i2c_lock); - - return rc; -} - -static int -i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) -{ - int rc; - - down(&ov->i2c_lock); - - switch (ov->bclass) { - case BCL_OV511: - rc = ov511_i2c_write_internal(ov, reg, value); - break; - case BCL_OV518: - case BCL_OV519: - rc = ov518_i2c_write_internal(ov, reg, value); - break; - default: - err("ic2_w: Invalid bridge class"); - rc = -EINVAL; - } - - up(&ov->i2c_lock); - - return rc; -} - -/* Do not call this function directly! */ -static int -ov51x_i2c_write_mask_internal(struct usb_ov511 *ov, - unsigned char reg, - unsigned char value, - unsigned char mask) -{ - int rc; - unsigned char oldval, newval; - - if (mask == 0xff) { - newval = value; - } else { - switch (ov->bclass) { - case BCL_OV511: - rc = ov511_i2c_read_internal(ov, reg); - break; - case BCL_OV518: - case BCL_OV519: - rc = ov518_i2c_read_internal(ov, reg); - break; - default: - err("ov51x_i2c_write_mask_internal: Invalid bridge class"); - rc = -EINVAL; - } - if (rc < 0) - return rc; - - oldval = (unsigned char) rc; - oldval &= (~mask); /* Clear the masked bits */ - value &= mask; /* Enforce mask on value */ - newval = oldval | value; /* Set the desired bits */ - } - - switch (ov->bclass) { - case BCL_OV511: - return (ov511_i2c_write_internal(ov, reg, newval)); - break; - case BCL_OV518: - case BCL_OV519: - return (ov518_i2c_write_internal(ov, reg, newval)); - break; - default: - return -EINVAL; - } -} - -/* Writes bits at positions specified by mask to an I2C reg. Bits that are in - * the same position as 1's in "mask" are cleared and set to "value". Bits - * that are in the same position as 0's in "mask" are preserved, regardless - * of their respective state in "value". - */ -static int -i2c_w_mask(struct usb_ov511 *ov, - unsigned char reg, - unsigned char value, - unsigned char mask) -{ - int rc; - - down(&ov->i2c_lock); - rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask); - up(&ov->i2c_lock); - - return rc; -} - -/* Do not call this function directly! */ -static int -ov51x_i2c_setbit_internal(struct usb_ov511 *ov, - unsigned char reg, - unsigned char value, - unsigned char bitaddr) -{ - int rc; - unsigned char newval; - - switch (ov->bclass) { - case BCL_OV511: - rc = ov511_i2c_read_internal(ov, reg); - break; - case BCL_OV518: - case BCL_OV519: - rc = ov518_i2c_read_internal(ov, reg); - break; - default: - err("ov51x_i2c_setbit_internal: Invalid bridge class"); - rc = -EINVAL; - } - if (rc < 0) - return rc; - - newval = ((unsigned char)rc & ~(1 << bitaddr)) | (value ? (1 << bitaddr) : 0); /* Set the desired bit */ - - switch (ov->bclass) { - case BCL_OV511: - return (ov511_i2c_write_internal(ov, reg, newval)); - break; - case BCL_OV518: - case BCL_OV519: - return (ov518_i2c_write_internal(ov, reg, newval)); - break; - default: - return -EINVAL; - } -} - -/* Writes bits at positions specified by bitaddr to an I2C reg. Bits are cleared - * if value = 0 and set if value = 1. - */ -static int -i2c_setbit(struct usb_ov511 *ov, - unsigned char reg, - unsigned char value, - unsigned char bitaddr) -{ - int rc; - - down(&ov->i2c_lock); - rc = ov51x_i2c_setbit_internal(ov, reg, value, bitaddr); - up(&ov->i2c_lock); - - return rc; -} - -/* Set the read and write slave IDs. The "slave" argument is the write slave, - * and the read slave will be set to (slave + 1). ov->i2c_lock should be held - * when calling this. This should not be called from outside the i2c I/O - * functions. - */ -static int -i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave) -{ - int rc; - - rc = reg_w(ov, R51x_I2C_W_SID, slave); - if (rc < 0) return rc; - - rc = reg_w(ov, R51x_I2C_R_SID, slave + 1); - if (rc < 0) return rc; - - return 0; -} - -/* Write to a specific I2C slave ID and register, using the specified mask */ -static int -i2c_w_slave(struct usb_ov511 *ov, - unsigned char slave, - unsigned char reg, - unsigned char value, - unsigned char mask) -{ - int rc = 0; - - down(&ov->i2c_lock); - - /* Set new slave IDs */ - rc = i2c_set_slave_internal(ov, slave); - if (rc < 0) goto out; - - rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask); - -out: - /* Restore primary IDs */ - if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) - err("Couldn't restore primary I2C slave"); - - up(&ov->i2c_lock); - return rc; -} - -/* Read from a specific I2C slave ID and register */ -static int -i2c_r_slave(struct usb_ov511 *ov, - unsigned char slave, - unsigned char reg) -{ - int rc; - - down(&ov->i2c_lock); - - /* Set new slave IDs */ - rc = i2c_set_slave_internal(ov, slave); - if (rc < 0) goto out; - - switch (ov->bclass) { - case BCL_OV511: - rc = ov511_i2c_read_internal(ov, reg); - break; - case BCL_OV518: - case BCL_OV519: - rc = ov518_i2c_read_internal(ov, reg); - break; - default: - err("i2c_r_slave: Invalid bridge class"); - rc = -EINVAL; - } -out: - /* Restore primary IDs */ - if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) - err("Couldn't restore primary I2C slave"); - - up(&ov->i2c_lock); - return rc; -} - -/* Sets I2C read and write slave IDs. Returns <0 for error */ -static int -ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid) -{ - int rc; - - down(&ov->i2c_lock); - - rc = i2c_set_slave_internal(ov, sid); - if (rc < 0) goto out; - - // FIXME: Is this actually necessary? - if (ov->bclass != BCL_OV519) - rc = ov51x_reset(ov, OV511_RESET_NOREGS); - if (rc < 0) goto out; - -out: - up(&ov->i2c_lock); - return rc; -} - -static int -write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals) -{ - int rc; - - while (pRegvals->bus != OV511_DONE_BUS) { - if (pRegvals->bus == OV511_REG_BUS) { - if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0) - return rc; - } else if (pRegvals->bus == OV511_I2C_BUS) { - if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0) - return rc; - } else { - err("Bad regval array"); - return -1; - } - pRegvals++; - } - return 0; -} - -#ifdef OV511_DEBUG -static void -dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn) -{ - int i, rc; - - for (i = reg1; i <= regn; i++) { - rc = i2c_r(ov, i); - info("Sensor[0x%02X] = 0x%02X", i, rc); - } -} - -static void -dump_i2c_regs(struct usb_ov511 *ov) -{ - info("I2C REGS"); - dump_i2c_range(ov, 0x00, 0x7C); -} - -static void -dump_reg_range(struct usb_ov511 *ov, int reg1, int regn) -{ - int i, rc; - - for (i = reg1; i <= regn; i++) { - rc = reg_r(ov, i); - info("OV511[0x%02X] = 0x%02X", i, rc); - } -} - -static void -ov511_dump_regs(struct usb_ov511 *ov) -{ - info("CAMERA INTERFACE REGS"); - dump_reg_range(ov, 0x10, 0x1f); - info("DRAM INTERFACE REGS"); - dump_reg_range(ov, 0x20, 0x23); - info("ISO FIFO REGS"); - dump_reg_range(ov, 0x30, 0x31); - info("PIO REGS"); - dump_reg_range(ov, 0x38, 0x39); - dump_reg_range(ov, 0x3e, 0x3e); - info("I2C REGS"); - dump_reg_range(ov, 0x40, 0x49); - info("SYSTEM CONTROL REGS"); - dump_reg_range(ov, 0x50, 0x55); - dump_reg_range(ov, 0x5e, 0x5f); - info("OmniCE REGS"); - dump_reg_range(ov, 0x70, 0x79); - /* NOTE: Quantization tables are not readable. You will get the value - * in reg. 0x79 for every table register */ - dump_reg_range(ov, 0x80, 0x9f); - dump_reg_range(ov, 0xa0, 0xbf); - -} - -static void -ov518_dump_regs(struct usb_ov511 *ov) -{ - info("VIDEO MODE REGS"); - dump_reg_range(ov, 0x20, 0x2f); - info("DATA PUMP AND SNAPSHOT REGS"); - dump_reg_range(ov, 0x30, 0x3f); - info("I2C REGS"); - dump_reg_range(ov, 0x40, 0x4f); - info("SYSTEM CONTROL AND VENDOR REGS"); - dump_reg_range(ov, 0x50, 0x5f); - info("60 - 6F"); - dump_reg_range(ov, 0x60, 0x6f); - info("70 - 7F"); - dump_reg_range(ov, 0x70, 0x7f); - info("Y QUANTIZATION TABLE"); - dump_reg_range(ov, 0x80, 0x8f); - info("UV QUANTIZATION TABLE"); - dump_reg_range(ov, 0x90, 0x9f); - info("A0 - BF"); - dump_reg_range(ov, 0xa0, 0xbf); - info("CBR"); - dump_reg_range(ov, 0xc0, 0xcf); -} -#endif - -/*****************************************************************************/ - -/* Temporarily stops OV511 from functioning. Must do this before changing - * registers while the camera is streaming */ -static inline int -ov51x_stop(struct usb_ov511 *ov) -{ - PDEBUG(4, "stopping"); - ov->stopped = 1; - switch (ov->bclass) { - case BCL_OV511: - return (reg_w(ov, R51x_SYS_RESET, 0x3d)); - break; - case BCL_OV518: - return (reg_w_mask(ov, R51x_SYS_RESET, 0x3a, 0x3a)); - break; - case BCL_OV519: - return (reg_w(ov, OV519_SYS_RESET1, 0x0f)); - break; - default: - err("ov51x_stop: invalid bridge type"); - } - return -1; -} - -/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not - * actually stopped (for performance). */ -static inline int -ov51x_restart(struct usb_ov511 *ov) -{ - int rc = 0; - - if (ov->stopped) { - PDEBUG(4, "restarting"); - ov->stopped = 0; - - /* Reinitialize the stream */ - switch (ov->bclass) { - case BCL_OV511: - rc = reg_w(ov, R51x_SYS_RESET, 0x00); - break; - case BCL_OV518: - rc = reg_w(ov, 0x2f, 0x80); - rc = reg_w(ov, R51x_SYS_RESET, 0x00); - break; - case BCL_OV519: - rc = reg_w(ov, OV519_SYS_RESET1, 0x00); - break; - default: - err("ov51x_restart: invalid bridge type"); - rc = -EINVAL; - } - } - - return rc; -} - -/* Sleeps until no frames are active. Returns !0 if got signal */ -static int -ov51x_wait_frames_inactive(struct usb_ov511 *ov) -{ - return wait_event_interruptible(ov->wq, ov->curframe < 0); -} - -/* Resets the hardware snapshot button */ -static void -ov51x_clear_snapshot(struct usb_ov511 *ov) -{ - if (ov->bclass == BCL_OV511) { - reg_w(ov, R51x_SYS_SNAP, 0x00); - reg_w(ov, R51x_SYS_SNAP, 0x02); - reg_w(ov, R51x_SYS_SNAP, 0x00); - } else if (ov->bclass == BCL_OV518) { - warn("snapshot reset not supported yet on OV518(+)"); - } else { - err("clear snap: invalid bridge type"); - } -} - -#if defined(CONFIG_VIDEO_PROC_FS) -/* Checks the status of the snapshot button. Returns 1 if it was pressed since - * it was last cleared, and zero in all other cases (including errors) */ -static int -ov51x_check_snapshot(struct usb_ov511 *ov) -{ - int ret, status = 0; - - if (ov->bclass == BCL_OV511) { - ret = reg_r(ov, R51x_SYS_SNAP); - if (ret < 0) { - err("Error checking snspshot status (%d)", ret); - } else if (ret & 0x08) { - status = 1; - } - } else if (ov->bclass == BCL_OV518) { - warn("snapshot check not supported yet on OV518(+)"); - } else { - err("check snap: invalid bridge type"); - } - - return status; -} -#endif - -/* This does an initial reset of an OmniVision sensor and ensures that I2C - * is synchronized. Returns <0 for failure. - */ -static int -init_ov_sensor(struct usb_ov511 *ov) -{ - int i, success; - - /* Reset the sensor */ - if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO; - - /* Wait for it to initialize */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1 + 150 * HZ / 1000); -#else - msleep(150); -#endif - - for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { - if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) && - (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) { - success = 1; - continue; - } - - /* Reset the sensor */ - if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO; - /* Wait for it to initialize */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(1 + 150 * HZ / 1000); -#else - msleep(150); -#endif - /* Dummy read to sync I2C */ - if (i2c_r(ov, 0x00) < 0) return -EIO; - } - - if (!success) - return -EIO; - - PDEBUG(1, "I2C synced in %d attempt(s)", i); - - return 0; -} - -static int -ov511_set_packet_size(struct usb_ov511 *ov, int size) -{ - int alt, mult; - - if (ov51x_stop(ov) < 0) - return -EIO; - - mult = size >> 5; - - if (ov->bridge == BRG_OV511) { - if (size == 0) alt = OV511_ALT_SIZE_0; - else if (size == 257) alt = OV511_ALT_SIZE_257; - else if (size == 513) alt = OV511_ALT_SIZE_513; - else if (size == 769) alt = OV511_ALT_SIZE_769; - else if (size == 993) alt = OV511_ALT_SIZE_993; - else { - err("Set packet size: invalid size (%d)", size); - return -EINVAL; - } - } else if (ov->bridge == BRG_OV511PLUS) { - if (size == 0) alt = OV511PLUS_ALT_SIZE_0; - else if (size == 33) alt = OV511PLUS_ALT_SIZE_33; - else if (size == 129) alt = OV511PLUS_ALT_SIZE_129; - else if (size == 257) alt = OV511PLUS_ALT_SIZE_257; - else if (size == 385) alt = OV511PLUS_ALT_SIZE_385; - else if (size == 513) alt = OV511PLUS_ALT_SIZE_513; - else if (size == 769) alt = OV511PLUS_ALT_SIZE_769; - else if (size == 961) alt = OV511PLUS_ALT_SIZE_961; - else { - err("Set packet size: invalid size (%d)", size); - return -EINVAL; - } - } else { - err("Set packet size: Invalid bridge type"); - return -EINVAL; - } - - PDEBUG(3, "%d, mult=%d, alt=%d", size, mult, alt); - - if (reg_w(ov, R51x_FIFO_PSIZE, mult) < 0) - return -EIO; - - if (usb_set_interface(ov->dev, ov->iface, alt) < 0) { - err("Set packet size: set interface error"); - return -EBUSY; - } - - if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) - return -EIO; - - ov->packet_size = size; - - if (ov51x_restart(ov) < 0) - return -EIO; - - return 0; -} - -/* Note: Unlike the OV511/OV511+, the size argument does NOT include the - * optional packet number byte. The actual size *is* stored in ov->packet_size, - * though. */ -static int -ov518_set_packet_size(struct usb_ov511 *ov, int size) -{ - int alt; - - if (ov51x_stop(ov) < 0) - return -EIO; - - if (ov->bclass == BCL_OV518) { - if (size == 0) alt = OV518_ALT_SIZE_0; - else if (size == 128) alt = OV518_ALT_SIZE_128; - else if (size == 256) alt = OV518_ALT_SIZE_256; - else if (size == 384) alt = OV518_ALT_SIZE_384; - else if (size == 512) alt = OV518_ALT_SIZE_512; - else if (size == 640) alt = OV518_ALT_SIZE_640; - else if (size == 768) alt = OV518_ALT_SIZE_768; - else if (size == 896) alt = OV518_ALT_SIZE_896; - else { - err("Set packet size: invalid size (%d)", size); - return -EINVAL; - } - } else { - err("Set packet size: Invalid bridge type"); - return -EINVAL; - } - - PDEBUG(3, "%d, alt=%d", size, alt); - - ov->packet_size = size; - if (size > 0) { - /* Program ISO FIFO size reg (packet number isn't included) */ - ov518_reg_w32(ov, 0x30, size, 2); - - if (ov->packet_numbering) - ++ov->packet_size; - } - - if (usb_set_interface(ov->dev, ov->iface, alt) < 0) { - err("Set packet size: set interface error"); - return -EBUSY; - } - - /* Initialize the stream */ - if (reg_w(ov, 0x2f, 0x80) < 0) - return -EIO; - - if (ov51x_restart(ov) < 0) - return -EIO; - - if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) - return -EIO; - - return 0; -} - -/* Note: Unlike the OV511/OV511+, the size argument does NOT include the - * optional packet number byte. The actual size *is* stored in ov->packet_size, - * though. */ -static int -ov519_set_packet_size(struct usb_ov511 *ov, int size) -{ - int alt; - - if (ov51x_stop(ov) < 0) - return -EIO; - - if (ov->bclass == BCL_OV519) { - if (size == 0) alt = OV519_ALT_SIZE_0; - else if (size == 384) alt = OV519_ALT_SIZE_384; - else if (size == 512) alt = OV519_ALT_SIZE_512; - else if (size == 768) alt = OV519_ALT_SIZE_768; - else if (size == 896) alt = OV519_ALT_SIZE_896; - else { - err("Set packet size: invalid size (%d)", size); - return -EINVAL; - } - } else { - err("Set packet size: Invalid bridge class"); - return -EINVAL; - } - - PDEBUG(3, "%d, alt=%d", size, alt); - - ov->packet_size = size; - if (size > 0) { - /* Program ISO FIFO size reg (packet number isn't included) */ - //~~~ is this nessecary? ov518_reg_w32(ov, 0x30, size, 2); - - if (ov->packet_numbering) - ++ov->packet_size; - } - - if (usb_set_interface(ov->dev, ov->iface, alt) < 0) { - err("Set packet size: set interface error"); - return -EBUSY; - } - - /* Initialize the stream */ - - if (size > 0) { - if (ov51x_restart(ov) < 0) - return -EIO; - } - -// if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) -// return -EIO; - - return 0; -} - -/* Upload compression params and quantization tables. Returns 0 for success. */ -static int -ov511_init_compression(struct usb_ov511 *ov) -{ - int rc = 0; - - if (!ov->compress_inited) { - reg_w(ov, 0x70, phy); - reg_w(ov, 0x71, phuv); - reg_w(ov, 0x72, pvy); - reg_w(ov, 0x73, pvuv); - reg_w(ov, 0x74, qhy); - reg_w(ov, 0x75, qhuv); - reg_w(ov, 0x76, qvy); - reg_w(ov, 0x77, qvuv); - - if (ov511_upload_quan_tables(ov) < 0) { - err("Error uploading quantization tables"); - rc = -EIO; - goto out; - } - } - - ov->compress_inited = 1; -out: - return rc; -} - -/* Upload compression params and quantization tables. Returns 0 for success. */ -static int -ov518_init_compression(struct usb_ov511 *ov) -{ - int rc = 0; - - if (!ov->compress_inited) { - if (ov518_upload_quan_tables(ov) < 0) { - err("Error uploading quantization tables"); - rc = -EIO; - goto out; - } - } - - ov->compress_inited = 1; -out: - return rc; -} - -/* Switch on standard JPEG compression. Returns 0 for success. */ -static int -ov519_init_compression(struct usb_ov511 *ov) -{ - int rc = 0; - - if (!ov->compress_inited) { - if (reg_setbit(ov, OV519_SYS_EN_CLK1, 1, 2 ) < 0) { - err("Error switching to compressed mode"); - rc = -EIO; - goto out; - } - } - - ov->compress_inited = 1; -out: - return rc; -} - -/* -------------------------------------------------------------------------- */ - -/* Sets sensor's contrast setting to "val" */ -static int -sensor_set_contrast(struct usb_ov511 *ov, unsigned short val) -{ - int rc; - - PDEBUG(3, "%d", val); - - if (ov->stop_during_set) - if (ov51x_stop(ov) < 0) - return -EIO; - - switch (ov->sensor) { - case SEN_OV7610: - case SEN_OV6620: - { - rc = i2c_w(ov, OV7610_REG_CNT, val >> 8); - if (rc < 0) - goto out; - break; - } - case SEN_OV6630: - { - rc = i2c_w_mask(ov, OV7610_REG_CNT, val >> 12, 0x0f); - if (rc < 0) - goto out; - break; - } - case SEN_OV8610: - { - static unsigned char ctab[] = { - 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f - }; - - /* Use Y gamma control instead. Bit 0 enables it. */ - rc = i2c_w(ov, 0x64, ctab[val>>13]); - if (rc < 0) - goto out; - break; - } - case SEN_OV7620: - { - static unsigned char ctab[] = { - 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, - 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff - }; - - /* Use Y gamma control instead. Bit 0 enables it. */ - rc = i2c_w(ov, 0x64, ctab[val>>12]); - if (rc < 0) - goto out; - break; - } - case SEN_OV7640: - { - /* Use gain control instead. */ - rc = i2c_w(ov, OV7610_REG_GAIN, val>>10); - if (rc < 0) - goto out; - break; - } - case SEN_SAA7111A: - { - rc = i2c_w(ov, 0x0b, val >> 9); - if (rc < 0) - goto out; - break; - } - default: - { - PDEBUG(3, "Unsupported with this sensor"); - rc = -EPERM; - goto out; - } - } - - rc = 0; /* Success */ - ov->contrast = val; -out: - if (ov51x_restart(ov) < 0) - return -EIO; - - return rc; -} - -/* Gets sensor's contrast setting */ -static int -sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val) -{ - int rc; - - switch (ov->sensor) { - case SEN_OV7610: - case SEN_OV6620: - rc = i2c_r(ov, OV7610_REG_CNT); - if (rc < 0) - return rc; - else - *val = rc << 8; - break; - case SEN_OV6630: - rc = i2c_r(ov, OV7610_REG_CNT); - if (rc < 0) - return rc; - else - *val = rc << 12; - break; - case SEN_OV8610: - { - static unsigned char ctab[] = { - 0x03, 0x09, 0x0b, 0x0f, 0x53, 0x6f, 0x35, 0x7f - }; - static int cidx = 0; - - /* Use Y gamma control instead. Bit 0 enables it. */ - rc = i2c_r(ov, 0x64); - if (rc < 0) { - return rc; - } else { - for (cidx = 0; cidx < 8; cidx++) { - if (ctab[cidx] == rc) { - *val = cidx << 13; - break; - } - } - if (cidx == 8) // could not find value in table - return -EINVAL; - } - break; - } - case SEN_OV7620: - /* Use Y gamma reg instead. Bit 0 is the enable bit. */ - rc = i2c_r(ov, 0x64); - if (rc < 0) - return rc; - else - *val = (rc & 0xfe) << 8; - break; - case SEN_OV7640: - /* Use gain control instead. */ - rc = i2c_r(ov, OV7610_REG_GAIN); - if (rc < 0) - return rc; - else - *val = rc << 10; - break; - - case SEN_SAA7111A: - *val = ov->contrast; - break; - default: - PDEBUG(3, "Unsupported with this sensor"); - return -EPERM; - } - - PDEBUG(3, "%d", *val); - ov->contrast = *val; - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -/* Sets sensor's brightness setting to "val" */ -static int -sensor_set_brightness(struct usb_ov511 *ov, unsigned short val) -{ - int rc; - - PDEBUG(4, "%d", val); - - if (ov->stop_during_set) - if (ov51x_stop(ov) < 0) - return -EIO; - - switch (ov->sensor) { - case SEN_OV8610: - case SEN_OV7610: - case SEN_OV76BE: - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV7640: - rc = i2c_w(ov, OV7610_REG_BRT, val >> 8); - if (rc < 0) - goto out; - break; - case SEN_OV7620: - /* 7620 doesn't like manual changes when in auto mode */ - if (!ov->auto_brt) { - rc = i2c_w(ov, OV7610_REG_BRT, val >> 8); - if (rc < 0) - goto out; - } - break; - case SEN_SAA7111A: - rc = i2c_w(ov, 0x0a, val >> 8); - if (rc < 0) - goto out; - break; - default: - PDEBUG(3, "Unsupported with this sensor"); - rc = -EPERM; - goto out; - } - - rc = 0; /* Success */ - ov->brightness = val; -out: - if (ov51x_restart(ov) < 0) - return -EIO; - - return rc; -} - -/* Gets sensor's brightness setting */ -static int -sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val) -{ - int rc; - - switch (ov->sensor) { - case SEN_OV8610: - case SEN_OV7610: - case SEN_OV76BE: - case SEN_OV7620: - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV7640: - rc = i2c_r(ov, OV7610_REG_BRT); - if (rc < 0) - return rc; - else - *val = rc << 8; - break; - case SEN_SAA7111A: - *val = ov->brightness; - break; - default: - PDEBUG(3, "Unsupported with this sensor"); - return -EPERM; - } - - PDEBUG(3, "%d", *val); - ov->brightness = *val; - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -/* Sets sensor's saturation (color intensity) setting to "val" */ -static int -sensor_set_saturation(struct usb_ov511 *ov, unsigned short val) -{ - int rc; - - PDEBUG(3, "%d", val); - - if (ov->stop_during_set) - if (ov51x_stop(ov) < 0) - return -EIO; - - switch (ov->sensor) { - case SEN_OV8610: - case SEN_OV7610: - case SEN_OV76BE: - case SEN_OV6620: - case SEN_OV6630: - rc = i2c_w(ov, OV7610_REG_SAT, val >> 8); - if (rc < 0) - goto out; - break; - case SEN_OV7620: -// /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ -// rc = ov_i2c_write(ov->dev, 0x62, (val >> 9) & 0x7e); -// if (rc < 0) -// goto out; - rc = i2c_w(ov, OV7610_REG_SAT, val >> 8); - if (rc < 0) - goto out; - break; - case SEN_OV7640: - rc = i2c_w(ov, OV7610_REG_SAT, (val >> 8) & 0xf0); - if (rc < 0) - goto out; - case SEN_SAA7111A: - rc = i2c_w(ov, 0x0c, val >> 9); - if (rc < 0) - goto out; - break; - default: - PDEBUG(3, "Unsupported with this sensor"); - rc = -EPERM; - goto out; - } - - rc = 0; /* Success */ - ov->colour = val; -out: - if (ov51x_restart(ov) < 0) - return -EIO; - - return rc; -} - -/* Gets sensor's saturation (color intensity) setting */ -static int -sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val) -{ - int rc; - - switch (ov->sensor) { - case SEN_OV8610: - case SEN_OV7610: - case SEN_OV76BE: - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV7640: - rc = i2c_r(ov, OV7610_REG_SAT); - if (rc < 0) - return rc; - else - *val = rc << 8; - break; - case SEN_OV7620: -// /* Use UV gamma reg instead. Bits 0 & 7 are reserved. */ -// rc = i2c_r(ov, 0x62); -// if (rc < 0) -// return rc; -// else -// *val = (rc & 0x7e) << 9; - rc = i2c_r(ov, OV7610_REG_SAT); - if (rc < 0) - return rc; - else - *val = rc << 8; - break; - case SEN_SAA7111A: - *val = ov->colour; - break; - default: - PDEBUG(3, "Unsupported with this sensor"); - return -EPERM; - } - - PDEBUG(3, "%d", *val); - ov->colour = *val; - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -/* Sets sensor's hue (red/blue balance) setting to "val" */ -static int -sensor_set_hue(struct usb_ov511 *ov, unsigned short val) -{ - int rc; - - PDEBUG(3, "%d", val); - - if (ov->stop_during_set) - if (ov51x_stop(ov) < 0) - return -EIO; - - switch (ov->sensor) { - case SEN_OV7610: - case SEN_OV6620: - case SEN_OV6630: - rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8)); - if (rc < 0) - goto out; - - rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8); - if (rc < 0) - goto out; - break; - case SEN_OV8610: - case SEN_OV7640: - rc = i2c_w(ov, OV8610_REG_HUE, (val >> 11) | 0x20); - if (rc < 0) - goto out; - break; - case SEN_OV7620: -// Hue control is causing problems. I will enable it once it's fixed. -#if 0 - rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb); - if (rc < 0) - goto out; - - rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb); - if (rc < 0) - goto out; -#endif - break; - case SEN_SAA7111A: - rc = i2c_w(ov, 0x0d, (val + 32768) >> 8); - if (rc < 0) - goto out; - break; - default: - PDEBUG(3, "Unsupported with this sensor"); - rc = -EPERM; - goto out; - } - - rc = 0; /* Success */ - ov->hue = val; -out: - if (ov51x_restart(ov) < 0) - return -EIO; - - return rc; -} - -/* Gets sensor's hue (red/blue balance) setting */ -static int -sensor_get_hue(struct usb_ov511 *ov, unsigned short *val) -{ - int rc; - - switch (ov->sensor) { - case SEN_OV7610: - case SEN_OV6620: - case SEN_OV6630: - rc = i2c_r(ov, OV7610_REG_BLUE); - if (rc < 0) - return rc; - else - *val = rc << 8; - break; - case SEN_OV8610: - case SEN_OV7640: - rc = i2c_r(ov, OV8610_REG_HUE); - if (rc < 0) - return rc; - else - *val = (rc & 0x1f) << 11; - break; - case SEN_OV7620: - rc = i2c_r(ov, 0x7a); - if (rc < 0) - return rc; - else - *val = rc << 8; - break; - case SEN_SAA7111A: - *val = ov->hue; - break; - default: - PDEBUG(3, "Unsupported with this sensor"); - return -EPERM; - } - - PDEBUG(3, "%d", *val); - ov->hue = *val; - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -static int -sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p) -{ - int rc; - - PDEBUG(4, "sensor_set_picture"); - - ov->whiteness = p->whiteness; - - /* Don't return error if a setting is unsupported, or rest of settings - * will not be performed */ - - rc = sensor_set_contrast(ov, p->contrast); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_set_brightness(ov, p->brightness); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_set_saturation(ov, p->colour); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_set_hue(ov, p->hue); - if (FATAL_ERROR(rc)) - return rc; - - return 0; -} - -static int -sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p) -{ - int rc; - - PDEBUG(4, "sensor_get_picture"); - - /* Don't return error if a setting is unsupported, or rest of settings - * will not be performed */ - - rc = sensor_get_contrast(ov, &(p->contrast)); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_get_brightness(ov, &(p->brightness)); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_get_saturation(ov, &(p->colour)); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_get_hue(ov, &(p->hue)); - if (FATAL_ERROR(rc)) - return rc; - - p->whiteness = 105 << 8; - - return 0; -} - -#if defined(CONFIG_VIDEO_PROC_FS) -// FIXME: Exposure range is only 0x00-0x7f in interlace mode -/* Sets current exposure for sensor. This only has an effect if auto-exposure - * is off */ -static inline int -sensor_set_exposure(struct usb_ov511 *ov, unsigned char val) -{ - int rc; - - PDEBUG(3, "%d", val); - - if (ov->stop_during_set) - if (ov51x_stop(ov) < 0) - return -EIO; - - switch (ov->sensor) { - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV7610: - case SEN_OV7620: - case SEN_OV7640: - case SEN_OV76BE: - case SEN_OV8600: - case SEN_OV8610: - rc = i2c_w(ov, 0x10, val); - if (rc < 0) - goto out; - - break; - case SEN_SAA7111A: - PDEBUG(3, "Unsupported with this sensor"); - return -EPERM; - default: - err("Sensor not supported for set_exposure"); - return -EINVAL; - } - - rc = 0; /* Success */ - ov->exposure = val; -out: - if (ov51x_restart(ov) < 0) - return -EIO; - - return rc; -} - -/* Gets current exposure level from sensor, regardless of whether it is under - * manual control. */ -static int -sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val) -{ - int rc; - - switch (ov->sensor) { - case SEN_OV7610: - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV7620: - case SEN_OV7640: - case SEN_OV76BE: - case SEN_OV8600: - case SEN_OV8610: - rc = i2c_r(ov, 0x10); - if (rc < 0) - return rc; - else - *val = rc; - break; - case SEN_SAA7111A: - val = 0; - PDEBUG(3, "Unsupported with this sensor"); - return -EPERM; - default: - err("Sensor not supported for get_exposure"); - return -EINVAL; - } - - PDEBUG(3, "%d", *val); - ov->exposure = *val; - - return 0; -} -#endif /* CONFIG_VIDEO_PROC_FS */ - -/* Turns on or off the LED. Only has an effect with OV511+/OV518(+)/OV519 */ -static void -ov51x_led_control(struct usb_ov511 *ov, int on) -{ - PDEBUG(4, " (%s)", on ? "turn on" : "turn off"); - - if (ov->bridge == BRG_OV511PLUS) - reg_w(ov, R511_SYS_LED_CTL, on ? 1 : 0); - else if (ov->bridge == BRG_OV519) - reg_w_mask(ov, OV519_GPIO_DATA_OUT0, on ? 0x01 : 0x00, 0x01); - else if (ov->bclass == BCL_OV518) - reg_w_mask(ov, R518_GPIO_OUT, on ? 0x02 : 0x00, 0x02); - - return; -} - -/* Matches the sensor's internal frame rate to the lighting frequency. - * Valid frequencies are: - * 50 - 50Hz, for European and Asian lighting - * 60 - 60Hz, for American lighting - * - * Tested with: OV7610, OV7620, OV76BE, OV6620 - * Unsupported: KS0127, KS0127B, SAA7111A - * Returns: 0 for success - */ -static int -sensor_set_light_freq(struct usb_ov511 *ov, int freq) -{ - int sixty; - - PDEBUG(4, "%d Hz", freq); - - if (freq == 60) - sixty = 1; - else if (freq == 50) - sixty = 0; - else { - err("Invalid light freq (%d Hz)", freq); - return -EINVAL; - } - - switch (ov->sensor) { - case SEN_OV8610: - i2c_w(ov, 0x2b, sixty?0xcc:0xc0); - i2c_w(ov, 0x2a, sixty?0x80:0xa0); - break; - case SEN_OV7610: - i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80); - i2c_w(ov, 0x2b, sixty?0x00:0xac); - i2c_w_mask(ov, 0x13, 0x10, 0x10); - i2c_w_mask(ov, 0x13, 0x00, 0x10); - break; - case SEN_OV7620: - case SEN_OV76BE: - case SEN_OV8600: - i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80); - i2c_w(ov, 0x2b, sixty?0x00:0xac); - i2c_w_mask(ov, 0x76, 0x01, 0x01); - break; - case SEN_OV7640: - i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80); - i2c_w(ov, 0x2b, sixty?0x00:0xac); - case SEN_OV6620: - case SEN_OV6630: - i2c_w(ov, 0x2b, sixty?0xa8:0x28); - i2c_w(ov, 0x2a, sixty?0x84:0xa4); - break; - case SEN_SAA7111A: - PDEBUG(5, "Unsupported with this sensor"); - return -EPERM; - default: - err("Sensor not supported for set_light_freq"); - return -EINVAL; - } - - ov->lightfreq = freq; - - return 0; -} - -/* If enable is true, turn on the sensor's banding filter, otherwise turn it - * off. This filter tries to reduce the pattern of horizontal light/dark bands - * caused by some (usually fluorescent) lighting. The light frequency must be - * set either before or after enabling it with ov51x_set_light_freq(). - * - * Tested with: OV7610, OV7620, OV76BE, OV6620. - * Unsupported: KS0127, KS0127B, SAA7111A - * Returns: 0 for success - */ -static int -sensor_set_banding_filter(struct usb_ov511 *ov, int enable) -{ - int rc; - - PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); - - if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B - || ov->sensor == SEN_SAA7111A) { - PDEBUG(5, "Unsupported with this sensor"); - return -EPERM; - } - - rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04); - if (rc < 0) - return rc; - - ov->bandfilt = enable; - - return 0; -} - -/* If enable is true, turn on the sensor's auto brightness control, otherwise - * turn it off. - * - * Unsupported: KS0127, KS0127B, SAA7111A, OV7640 - * Returns: 0 for success - */ -static int -sensor_set_auto_brightness(struct usb_ov511 *ov, int enable) -{ - int rc; - - PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); - - if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B - || ov->sensor == SEN_SAA7111A || ov->sensor == SEN_OV7640) { - PDEBUG(5, "Unsupported with this sensor"); - return -EPERM; - } - - rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10); - if (rc < 0) - return rc; - - ov->auto_brt = enable; - - return 0; -} - -/* If enable is true, turn on the sensor's auto exposure control, otherwise - * turn it off. - * - * Unsupported: KS0127, KS0127B, SAA7111A - * Returns: 0 for success - */ -static int -sensor_set_auto_exposure(struct usb_ov511 *ov, int enable) -{ - PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); - - switch (ov->sensor) { - case SEN_OV7610: - i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80); - break; - case SEN_OV6620: - case SEN_OV7620: - case SEN_OV7640: - case SEN_OV76BE: - case SEN_OV8600: - i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01); - break; - case SEN_OV6630: - case SEN_OV8610: - i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10); - break; - case SEN_SAA7111A: - PDEBUG(5, "Unsupported with this sensor"); - return -EPERM; - default: - err("Sensor not supported for set_auto_exposure"); - return -EINVAL; - } - - ov->auto_exp = enable; - - return 0; -} - -/* If enable is true, turn on the sensor's auto gain control, otherwise - * turn it off. - * - * Returns: 0 for success - */ -static int -sensor_set_auto_gain(struct usb_ov511 *ov, int enable) -{ - PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); - - switch (ov->sensor) { - case SEN_OV7640: - i2c_w_mask(ov, 0x13, enable?0x02:0x00, 0x02); - break; - default: - PDEBUG(5, "Unsupported with this sensor"); - return -EPERM; -// default: -// err("Sensor not supported for set_auto_gain"); -// return -EINVAL; - } - - ov->auto_gain = enable; - - return 0; -} - -/* Modifies the sensor's exposure algorithm to allow proper exposure of objects - * that are illuminated from behind. - * - * Tested with: OV6620, OV7620 - * Unsupported: OV7610, OV7640, OV76BE, KS0127, KS0127B, SAA7111A - * Returns: 0 for success - */ -static int -sensor_set_backlight(struct usb_ov511 *ov, int enable) -{ - PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); - - switch (ov->sensor) { - case SEN_OV8610: - // change AEC/AGC Reference level - i2c_w_mask(ov, 0x68, enable?0xef:0xcf, 0xff); - // select central 1/4 image to calculate AEC/AGC - i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); - // increase gain 3dB - i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02); - break; - case SEN_OV7620: - case SEN_OV8600: - // change AEC/AGC Reference level - i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0); - // select central 1/4 image to calculate AEC/AGC - i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); - // increase gain 3dB - i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02); - break; - case SEN_OV6620: - i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0); - i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); - i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80); - break; - case SEN_OV6630: - i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0); - i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); - i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02); - break; - case SEN_OV7610: - case SEN_OV7640: - case SEN_OV76BE: - case SEN_SAA7111A: - PDEBUG(5, "Unsupported with this sensor"); - return -EPERM; - default: - err("Sensor not supported for set_backlight"); - return -EINVAL; - } - - ov->backlight = enable; - - return 0; -} - -static int -sensor_set_mirror(struct usb_ov511 *ov, int enable) -{ - PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); - - switch (ov->sensor) { - case SEN_OV6620: - case SEN_OV6630: - case SEN_OV7610: - case SEN_OV7620: - case SEN_OV76BE: - case SEN_OV7640: - case SEN_OV8600: - case SEN_OV8610: - i2c_w_mask(ov, 0x12, enable?0x40:0x00, 0x40); - break; - case SEN_SAA7111A: - PDEBUG(5, "Unsupported with this sensor"); - return -EPERM; - default: - err("Sensor not supported for set_mirror"); - return -EINVAL; - } - - ov->mirror = enable; - - return 0; -} - -/* Returns number of bits per pixel (regardless of where they are located; - * planar or not), or zero for unsupported format. - */ -static inline int -get_depth(int palette) -{ - switch (palette) { - case VIDEO_PALETTE_GREY: return 8; - case VIDEO_PALETTE_YUV420: return 12; - case VIDEO_PALETTE_YUV420P: return 12; /* Planar */ -#ifdef OV511_ALLOW_CONVERSION - case VIDEO_PALETTE_RGB565: return 16; - case VIDEO_PALETTE_RGB24: return 24; - case VIDEO_PALETTE_YUV422: return 16; - case VIDEO_PALETTE_YUYV: return 16; - case VIDEO_PALETTE_YUV422P: return 16; /* Planar */ -#endif - default: return 0; /* Invalid format */ - } -} - -/* Bytes per frame. Used by read(). Return of 0 indicates error */ -static inline long int -get_frame_length(struct usb_ov511 *ov, struct ov511_frame *frame) -{ - if (!frame) { - return 0; - } else { - if (ov->bclass == BCL_OV519) { - return (frame->bytes_recvd); - } else { - return ((frame->width * frame->height - * get_depth(frame->format)) >> 3); - } - } -} - -static int -mode_init_ov_sensor_regs(struct usb_ov511 *ov, struct ovsensor_window *win) -{ - int qvga = win->quarter; - - /******** Mode (VGA/QVGA) and sensor specific regs ********/ - - switch (ov->sensor) { - case SEN_OV8610: - // For OV8610 qvga means qsvga - i2c_setbit(ov, OV7610_REG_COM_C, qvga?1:0, 5); - // FIXME: Does this improve the image quality or frame rate? -#if 0 - i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); - i2c_w(ov, 0x24, 0x10); - i2c_w(ov, 0x25, qvga?0x40:0x8a); - i2c_w(ov, 0x2f, qvga?0x30:0xb0); - i2c_w(ov, 0x35, qvga?0x1c:0x9c); -#endif - break; - case SEN_OV7610: - i2c_w_mask(ov, 0x14, qvga?0x20:0x00, 0x20); -// FIXME: Does this improve the image quality or frame rate? -#if 0 - i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); - i2c_w(ov, 0x24, 0x10); - i2c_w(ov, 0x25, qvga?0x40:0x8a); - i2c_w(ov, 0x2f, qvga?0x30:0xb0); - i2c_w(ov, 0x35, qvga?0x1c:0x9c); -#endif - break; - case SEN_OV7620: -// i2c_w(ov, 0x2b, 0x00); - i2c_w_mask(ov, 0x14, qvga?0x20:0x00, 0x20); - i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); - i2c_w(ov, 0x24, qvga?0x20:0x3a); - i2c_w(ov, 0x25, qvga?0x30:0x60); - i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40); - i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0); - i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20); - break; - case SEN_OV76BE: -// i2c_w(ov, 0x2b, 0x00); - i2c_w_mask(ov, 0x14, qvga?0x20:0x00, 0x20); -// FIXME: Enable this once 7620AE uses 7620 initial settings -#if 0 - i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); - i2c_w(ov, 0x24, qvga?0x20:0x3a); - i2c_w(ov, 0x25, qvga?0x30:0x60); - i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40); - i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0); - i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20); -#endif - break; - case SEN_OV7640: -// i2c_w(ov, 0x2b, 0x00); - i2c_w_mask(ov, 0x14, qvga?0x20:0x00, 0x20); - i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); -// i2c_w(ov, 0x24, qvga?0x20:0x3a); -// i2c_w(ov, 0x25, qvga?0x30:0x60); -// i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40); -// i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0); -// i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20); - break; - case SEN_OV6620: - i2c_w_mask(ov, 0x14, qvga?0x20:0x00, 0x20); - break; - case SEN_OV6630: - i2c_w_mask(ov, 0x14, qvga?0x20:0x00, 0x20); - break; - default: - return -EINVAL; - } - - /******** Palette-specific regs ********/ - - if (win->format == VIDEO_PALETTE_GREY) { - if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) { - /* these aren't valid on the OV6620/OV7620/6630? */ - i2c_w_mask(ov, 0x0e, 0x40, 0x40); - } - - /* OV6630 default reg 0x13 value is always right */ - /* OV7640 is 8-bit only */ - if (ov->sensor != SEN_OV6630 && ov->sensor != SEN_OV7640) - i2c_w_mask(ov, 0x13, 0x20, 0x20); - else - return -EINVAL; /* No OV6630 greyscale support yet */ - } else { - if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) { - /* not valid on the OV6620/OV7620/6630? */ - i2c_w_mask(ov, 0x0e, 0x00, 0x40); - } - - /* The OV518 needs special treatment. Although both the OV518 - * and the OV6630 support a 16-bit video bus, only the 8 bit Y - * bus is actually used. The UV bus is tied to ground. - * Therefore, the OV6630 needs to be in 8-bit multiplexed - * output mode */ - - /* OV7640 is 8-bit only */ - - if (ov->sensor != SEN_OV6630 && ov->sensor != SEN_OV7640) - i2c_w_mask(ov, 0x13, 0x00, 0x20); - } - - /******** Clock programming ********/ - - /* The OV6620 needs special handling. This prevents the - * severe banding that normally occurs */ - if (ov->sensor == SEN_OV6620) { - /* Clock down */ - - i2c_w(ov, 0x2a, 0x04); - i2c_w(ov, 0x11, win->clockdiv); - i2c_w(ov, 0x2a, 0x84); - /* This next setting is critical. It seems to improve - * the gain or the contrast. The "reserved" bits seem - * to have some effect in this case. */ - i2c_w(ov, 0x2d, 0x85); - } else if (win->clockdiv >= 0) { - i2c_w(ov, 0x11, win->clockdiv); - } - - /******** Special Features ********/ - - if (framedrop >= 0 && ov->sensor != SEN_OV7640) - i2c_w(ov, 0x16, framedrop); - - /* Test Pattern */ - if (ov->sensor != SEN_OV7640) - i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02); - - /* Enable auto white balance */ - i2c_w_mask(ov, 0x12, 0x04, 0x04); - - // This will go away as soon as ov51x_mode_init_sensor_regs() - // is fully tested. - /* 7620/6620/6630? don't have register 0x35, so play it safe */ - if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) { - if (win->width == 640 && win->height == 480) - i2c_w(ov, 0x35, 0x9e); - else - i2c_w(ov, 0x35, 0x1e); - } - - return 0; -} - -static int -set_ov_sensor_window(struct usb_ov511 *ov, struct ovsensor_window *win) -{ - int hwsbase, hwebase, vwsbase, vwebase, hwscale, vwscale, ret; - - /* The different sensor ICs handle setting up of window differently. - * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!!! */ - switch (ov->sensor) { - case SEN_OV8610: - hwsbase = 0x1e; - hwebase = 0x1e; - vwsbase = 0x02; - vwebase = 0x02; - break; - case SEN_OV7610: - case SEN_OV76BE: - hwsbase = 0x38; - hwebase = 0x3a; - vwsbase = vwebase = 0x05; - break; - case SEN_OV6620: - case SEN_OV6630: - hwsbase = 0x38; - hwebase = 0x3a; - vwsbase = 0x05; - vwebase = 0x06; - break; - case SEN_OV7620: - hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ - hwebase = 0x2f; - vwsbase = vwebase = 0x05; - break; - case SEN_OV7640: - hwsbase = 0x1a; - hwebase = 0x1a; - vwsbase = vwebase = 0x03; - break; - default: - return -EINVAL; - } - - switch (ov->sensor) { - case SEN_OV6620: - case SEN_OV6630: - if (win->quarter) { /* QCIF */ - hwscale = 0; - vwscale = 0; - } else { /* CIF */ - hwscale = 1; - vwscale = 1; /* The datasheet says 0; it's wrong */ - } - break; - case SEN_OV8610: - if (win->quarter) { /* QSVGA */ - hwscale = 1; - vwscale = 1; - } else { /* SVGA */ - hwscale = 2; - vwscale = 2; - } - break; - default: //SEN_OV7xx0 - if (win->quarter) { /* QVGA */ - hwscale = 1; - vwscale = 0; - } else { /* VGA */ - hwscale = 2; - vwscale = 1; - } - } - - ret = mode_init_ov_sensor_regs(ov, win); - if (ret < 0) - return ret; - - if (ov->sensor == SEN_OV8610) { - i2c_w_mask(ov, 0x2d, 0x05, 0x40); /* old 0x95, new 0x05 from windrv 090403 *//* bits 5-7: reserved */ - i2c_w_mask(ov, 0x28, 0x20, 0x20); /* bit 5: progressive mode on */ - } - - i2c_w(ov, 0x17, hwsbase + (win->x >> hwscale)); - i2c_w(ov, 0x18, hwebase + ((win->x + win->width) >> hwscale)); - i2c_w(ov, 0x19, vwsbase + (win->y >> vwscale)); - i2c_w(ov, 0x1a, vwebase + ((win->y + win->height) >> vwscale)); - -#ifdef OV511_DEBUG - if (dump_sensor) - dump_i2c_regs(ov); -#endif - - return 0; -} - -static int -ov_sensor_mode_setup(struct usb_ov511 *ov, - int width, int height, int mode, int sub_flag) -{ - struct ovsensor_window win; - int half_w = ov->maxwidth / 2; - int half_h = ov->maxheight / 2; - - win.format = mode; - - /* Unless subcapture is enabled, center the image window and downsample - * if possible to increase the field of view */ - if (sub_flag) { - win.x = ov->subx; - win.y = ov->suby; - win.width = ov->subw; - win.height = ov->subh; - win.quarter = 0; - } else { - /* NOTE: OV518(+) and OV519 does downsampling on its own */ - if ((width > half_w && height > half_h) - || (ov->bclass == BCL_OV518) - || (ov->bclass == BCL_OV519)) { - win.width = ov->maxwidth; - win.height = ov->maxheight; - win.quarter = 0; - } else if (width > half_w || height > half_h) { - err("Illegal dimensions"); - return -EINVAL; - } else { - win.width = half_w; - win.height = half_h; - win.quarter = 1; - } - - /* Center it */ - win.x = (win.width - width) / 2; - win.y = (win.height - height) / 2; - } - - if (clockdiv >= 0) { - /* Manual override */ - win.clockdiv = clockdiv; - } else if (ov->bridge == BRG_OV518) { - /* OV518 controls the clock externally */ - win.clockdiv = 0; - } else if (ov->bridge == BRG_OV518PLUS) { - /* OV518+ controls the clock externally */ - win.clockdiv = 1; - } else if (ov->bridge == BRG_OV519) { - /* Clock is determined by OV519 frame rate code */ - win.clockdiv = ov->clockdiv; - } else if (ov->compress) { - /* Use the highest possible rate, to maximize FPS */ - switch (ov->sensor) { - case SEN_OV6620: - /* ...except with this sensor, which doesn't like - * higher rates yet */ - win.clockdiv = 3; - break; - case SEN_OV6630: - win.clockdiv = 0; - break; - case SEN_OV76BE: - case SEN_OV7610: - case SEN_OV7620: - win.clockdiv = 1; - break; - case SEN_OV8610: - win.clockdiv = 0; - break; - default: - err("Invalid sensor"); - return -EINVAL; - } - } else { - switch (ov->sensor) { - case SEN_OV6620: - case SEN_OV6630: - win.clockdiv = 3; - break; - case SEN_OV76BE: - case SEN_OV7610: - case SEN_OV7620: - /* Use slowest possible clock without sacrificing - * frame rate */ - win.clockdiv = ((sub_flag ? ov->subw * ov->subh - : width * height) - * (win.format == VIDEO_PALETTE_GREY ? 2 : 3) / 2) - / 66000; - break; - default: - err("Invalid sensor"); - return -EINVAL; - } - } - - PDEBUG(4, "Setting clock divider to %d", win.clockdiv); - - return set_ov_sensor_window(ov, &win); -} - -/* Set up the OV511/OV511+ with the given image parameters. - * - * Do not put any sensor-specific code in here (including I2C I/O functions) - */ -static int -ov511_mode_init_regs(struct usb_ov511 *ov, - int width, int height, int mode, int sub_flag) -{ - int hsegs, vsegs; - - if (sub_flag) { - width = ov->subw; - height = ov->subh; - } - - PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d", - width, height, mode, sub_flag); - - // FIXME: This should be moved to a 7111a-specific function once - // subcapture is dealt with properly - if (ov->sensor == SEN_SAA7111A) { - if (width == 320 && height == 240) { - /* No need to do anything special */ - } else if (width == 640 && height == 480) { - /* Set the OV511 up as 320x480, but keep the - * V4L resolution as 640x480 */ - width = 320; - } else { - err("SAA7111A only allows 320x240 or 640x480"); - return -EINVAL; - } - } - - /* Make sure width and height are a multiple of 8 */ - if (width % 8 || height % 8) { - err("Invalid size (%d, %d) (mode = %d)", width, height, mode); - return -EINVAL; - } - - if (width < ov->minwidth || height < ov->minheight) { - err("Requested dimensions are too small"); - return -EINVAL; - } - - if (ov51x_stop(ov) < 0) - return -EIO; - - if (mode == VIDEO_PALETTE_GREY) { - reg_w(ov, R511_CAM_UV_EN, 0x00); - reg_w(ov, R511_SNAP_UV_EN, 0x00); - reg_w(ov, R511_SNAP_OPTS, 0x01); - } else { - reg_w(ov, R511_CAM_UV_EN, 0x01); - reg_w(ov, R511_SNAP_UV_EN, 0x01); - reg_w(ov, R511_SNAP_OPTS, 0x03); - } - - /* Here I'm assuming that snapshot size == image size. - * I hope that's always true. --claudio - */ - hsegs = (width >> 3) - 1; - vsegs = (height >> 3) - 1; - - reg_w(ov, R511_CAM_PXCNT, hsegs); - reg_w(ov, R511_CAM_LNCNT, vsegs); - reg_w(ov, R511_CAM_PXDIV, 0x00); - reg_w(ov, R511_CAM_LNDIV, 0x00); - - /* YUV420, low pass filter on */ - reg_w(ov, R511_CAM_OPTS, 0x03); - - /* Snapshot additions */ - reg_w(ov, R511_SNAP_PXCNT, hsegs); - reg_w(ov, R511_SNAP_LNCNT, vsegs); - reg_w(ov, R511_SNAP_PXDIV, 0x00); - reg_w(ov, R511_SNAP_LNDIV, 0x00); - - if (ov->compress) { - /* Enable Y and UV quantization and compression */ - reg_w(ov, R511_COMP_EN, 0x07); - reg_w(ov, R511_COMP_LUT_EN, 0x03); - ov51x_reset(ov, OV511_RESET_OMNICE); - } - - if (ov51x_restart(ov) < 0) - return -EIO; - - return 0; -} - -/* Sets up the OV518/OV518+ with the given image parameters - * - * OV518 needs a completely different approach, until we can figure out what - * the individual registers do. Also, only 15 FPS is supported now. - * - * Do not put any sensor-specific code in here (including I2C I/O functions) - */ -static int -ov518_mode_init_regs(struct usb_ov511 *ov, - int width, int height, int mode, int sub_flag) -{ - int hsegs, vsegs, hi_res; - - if (sub_flag) { - width = ov->subw; - height = ov->subh; - } - - PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d", - width, height, mode, sub_flag); - - if (width % 16 || height % 8) { - err("Invalid size (%d, %d)", width, height); - return -EINVAL; - } - - if (width < ov->minwidth || height < ov->minheight) { - err("Requested dimensions are too small"); - return -EINVAL; - } - - if (width >= 320 && height >= 240) { - hi_res = 1; - } else if (width >= 320 || height >= 240) { - err("Invalid width/height combination (%d, %d)", width, height); - return -EINVAL; - } else { - hi_res = 0; - } - - if (ov51x_stop(ov) < 0) - return -EIO; - - /******** Set the mode ********/ - - reg_w(ov, 0x2b, 0); - reg_w(ov, 0x2c, 0); - reg_w(ov, 0x2d, 0); - reg_w(ov, 0x2e, 0); - reg_w(ov, 0x3b, 0); - reg_w(ov, 0x3c, 0); - reg_w(ov, 0x3d, 0); - reg_w(ov, 0x3e, 0); - - if (ov->bridge == BRG_OV518 && ov518_color) { - if (mode == VIDEO_PALETTE_GREY) { - /* Set 16-bit input format (UV data are ignored) */ - reg_w_mask(ov, 0x20, 0x00, 0x08); - - /* Set 8-bit (4:0:0) output format */ - reg_w_mask(ov, 0x28, 0x00, 0xf0); - reg_w_mask(ov, 0x38, 0x00, 0xf0); - } else { - /* Set 8-bit (YVYU) input format */ - reg_w_mask(ov, 0x20, 0x08, 0x08); - - /* Set 12-bit (4:2:0) output format */ - reg_w_mask(ov, 0x28, 0x80, 0xf0); - reg_w_mask(ov, 0x38, 0x80, 0xf0); - } - } else { - reg_w(ov, 0x28, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80); - reg_w(ov, 0x38, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80); - } - - hsegs = width / 16; - vsegs = height / 4; - - reg_w(ov, 0x29, hsegs); - reg_w(ov, 0x2a, vsegs); - - reg_w(ov, 0x39, hsegs); - reg_w(ov, 0x3a, vsegs); - - /* Windows driver does this here; who knows why */ - reg_w(ov, 0x2f, 0x80); - - /******** Set the framerate (to 30 FPS) ********/ - - /* Mode independent, but framerate dependent, regs */ - reg_w(ov, 0x51, 0x04); /* Clock divider; lower==faster */ - reg_w(ov, 0x22, 0x18); - reg_w(ov, 0x23, 0xff); - - if (ov->bridge == BRG_OV518PLUS) - reg_w(ov, 0x21, 0x19); - else - reg_w(ov, 0x71, 0x17); /* Compression-related? */ - - // FIXME: Sensor-specific - /* Bit 5 is what matters here. Of course, it is "reserved" */ - i2c_w(ov, 0x54, 0x23); - - reg_w(ov, 0x2f, 0x80); - - if (ov->bridge == BRG_OV518PLUS) { - reg_w(ov, 0x24, 0x94); - reg_w(ov, 0x25, 0x90); - ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */ - ov518_reg_w32(ov, 0xc6, 540, 2); /* 21ch */ - ov518_reg_w32(ov, 0xc7, 540, 2); /* 21ch */ - ov518_reg_w32(ov, 0xc8, 108, 2); /* 6ch */ - ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */ - ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */ - ov518_reg_w32(ov, 0xcc, 2400, 2); /* 960h */ - ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */ - ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */ - } else { - reg_w(ov, 0x24, 0x9f); - reg_w(ov, 0x25, 0x90); - ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */ - ov518_reg_w32(ov, 0xc6, 381, 2); /* 17dh */ - ov518_reg_w32(ov, 0xc7, 381, 2); /* 17dh */ - ov518_reg_w32(ov, 0xc8, 128, 2); /* 80h */ - ov518_reg_w32(ov, 0xca, 183331, 3); /* 2cc23h */ - ov518_reg_w32(ov, 0xcb, 746, 2); /* 2eah */ - ov518_reg_w32(ov, 0xcc, 1750, 2); /* 6d6h */ - ov518_reg_w32(ov, 0xcd, 45, 2); /* 2dh */ - ov518_reg_w32(ov, 0xce, 851, 2); /* 353h */ - } - - reg_w(ov, 0x2f, 0x80); - - if (ov51x_restart(ov) < 0) - return -EIO; - - /* Reset it just for good measure */ - if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) - return -EIO; - - return 0; -} - -/* Sets up the OV519 with the given image parameters - * - * OV519 needs a completely different approach, until we can figure out what - * the individual registers do. - * - * Do not put any sensor-specific code in here (including I2C I/O functions) - */ -static int -ov519_mode_init_regs(struct usb_ov511 *ov, - int width, int height, int mode, int sub_flag) -{ - static struct ov511_regvals regvals_mode_init_519[] = { - { OV511_REG_BUS, 0x5d, 0x03 }, /* Turn off suspend mode */ - { OV511_REG_BUS, 0x53, 0x9f }, /* was 9b in 1.65-1.08 */ - { OV511_REG_BUS, 0x54, 0x0f }, /* bit2 (jpeg enable) */ - { OV511_REG_BUS, 0xa2, 0x20 }, /* a2-a5 are undocumented */ - { OV511_REG_BUS, 0xa3, 0x18 }, - { OV511_REG_BUS, 0xa4, 0x04 }, - { OV511_REG_BUS, 0xa5, 0x28 }, - { OV511_REG_BUS, 0x37, 0x00 }, /* SetUsbInit */ - { OV511_REG_BUS, 0x55, 0x02 }, /* 4.096 Mhz audio clock */ - /* Enable both fields, YUV Input, disable defect comp (why?) */ - { OV511_REG_BUS, 0x22, 0x1d }, - { OV511_REG_BUS, 0x17, 0x50 }, /* undocumented */ - { OV511_REG_BUS, 0x37, 0x00 }, /* undocumented */ - { OV511_REG_BUS, 0x40, 0xff }, /* I2C timeout counter */ - { OV511_REG_BUS, 0x46, 0x00 }, /* I2C clock prescaler */ - { OV511_REG_BUS, 0x59, 0x04 }, /* new from windrv 090403 */ - { OV511_REG_BUS, 0xff, 0x00 }, /* undocumented */ - /* windows reads 0x55 at this point, why? */ - { OV511_DONE_BUS, 0x0, 0x00}, - }; - -// int hi_res; - - if (sub_flag) { - width = ov->subw; - height = ov->subh; - } - - PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d", - width, height, mode, sub_flag); - - if ((width % 16) || (height % 8)) { - err("Invalid size (%d, %d)", width, height); - return -EINVAL; - } - - if (width < ov->minwidth || height < ov->minheight) { - err("Requested dimensions are too small %dx%d", width, height); - return -EINVAL; - } - -// if (width >= 800 && height >= 600) { -// hi_res = 1; -// } else - if (width > ov->maxwidth || height > ov->maxheight) { - err("Requested dimensions are too big %dx%d", width, height); - return -EINVAL; - } -// else { -// hi_res = 0; -// } - - if (ov51x_stop(ov) < 0) - return -EIO; - - /******** Set the mode ********/ - - if (write_regvals(ov, regvals_mode_init_519)) - return -EIO; - - if (ov->sensor == SEN_OV7640) { - /* Select 8-bit input mode */ - reg_w_mask(ov, OV519_CAM_DFR, 0x10, 0x10); - } - - reg_w(ov, OV519_CAM_H_SIZE, width>>4); - reg_w(ov, OV519_CAM_V_SIZE, height>>3); - reg_w(ov, OV519_CAM_X_OFFSETL, 0x00); - reg_w(ov, OV519_CAM_X_OFFSETH, 0x00); - reg_w(ov, OV519_CAM_Y_OFFSETL, 0x00); - reg_w(ov, OV519_CAM_Y_OFFSETH, 0x00); - reg_w(ov, OV519_CAM_DIVIDER, 0x00); - reg_w(ov, OV519_CAM_FORMAT, 0x03); /* YUV422 */ - reg_w(ov, 0x26, 0x00); /* Undocumented */ - - - /******** Set the framerate ********/ - if (framerate > 0) { - ov->framerate = framerate; - } - -// FIXME: These are only valid at the max resolution. - if (ov->sensor == SEN_OV7640) { - switch (ov->framerate) { - case 30: - reg_w(ov, 0xa4, 0x0c); - reg_w(ov, 0x23, 0xff); - ov->clockdiv = 0; - break; - case 25: - reg_w(ov, 0xa4, 0x0c); - reg_w(ov, 0x23, 0x1f); - ov->clockdiv = 0; - break; - case 20: - reg_w(ov, 0xa4, 0x0c); - reg_w(ov, 0x23, 0x1b); - ov->clockdiv = 0; - break; - case 15: - reg_w(ov, 0xa4, 0x04); - reg_w(ov, 0x23, 0xff); - ov->clockdiv = 1; - break; - case 10: - reg_w(ov, 0xa4, 0x04); - reg_w(ov, 0x23, 0x1f); - ov->clockdiv = 1; - break; - case 5: - reg_w(ov, 0xa4, 0x04); - reg_w(ov, 0x23, 0x1b); - ov->clockdiv = 1; - break; - default: // 30 fps - reg_w(ov, 0xa4, 0x0c); - reg_w(ov, 0x23, 0xff); - ov->clockdiv = 0; - } - } else if (ov->sensor == SEN_OV8610) { - switch (ov->framerate) { - case 15: - reg_w(ov, 0xa4, 0x06); - reg_w(ov, 0x23, 0xff); - break; - case 10: - reg_w(ov, 0xa4, 0x06); - reg_w(ov, 0x23, 0x1f); - break; - case 5: - reg_w(ov, 0xa4, 0x06); - reg_w(ov, 0x23, 0x1b); - break; - default: // 15 fps - reg_w(ov, 0xa4, 0x06); - reg_w(ov, 0x23, 0xff); - } - - ov->clockdiv = 0; - } else { - err("Sensor not supported for OV519!"); - return -EINVAL; - } - - if (ov51x_restart(ov) < 0) - return -EIO; - - /* Reset it just for good measure */ - if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) - return -EIO; - - return 0; -} - -/* This is a wrapper around the OV511, OV518, and sensor specific functions */ -static int -mode_init_regs(struct usb_ov511 *ov, - int width, int height, int mode, int sub_flag) -{ - int rc = 0; - - if (!ov || !ov->dev) - return -EFAULT; - - switch (ov->bclass) { - case BCL_OV511: - rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag); - break; - case BCL_OV518: - rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag); - break; - case BCL_OV519: - rc = ov519_mode_init_regs(ov, width, height, mode, sub_flag); - break; - default: - err("mode_init_regs: Invalid bridge class"); - rc = -EINVAL; - } - - if (FATAL_ERROR(rc)) - return rc; - - switch (ov->sensor) { - case SEN_OV8610: - case SEN_OV7610: - case SEN_OV7620: - case SEN_OV76BE: - case SEN_OV7640: - case SEN_OV8600: - case SEN_OV6620: - case SEN_OV6630: - rc = ov_sensor_mode_setup(ov, width, height, mode, sub_flag); - break; - - case SEN_SAA7111A: -// rc = mode_init_saa_sensor_regs(ov, width, height, mode, -// sub_flag); - - PDEBUG(1, "SAA status = 0x%02X", i2c_r(ov, 0x1f)); - break; - default: - rc = -EINVAL; - } - - if (FATAL_ERROR(rc)) - return rc; - - /* Sensor-independent settings */ - rc = sensor_set_auto_brightness(ov, ov->auto_brt); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_set_auto_exposure(ov, ov->auto_exp); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_set_auto_gain(ov, ov->auto_gain); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_set_banding_filter(ov, bandingfilter); - if (FATAL_ERROR(rc)) - return rc; - - if (ov->lightfreq) { - rc = sensor_set_light_freq(ov, lightfreq); - if (FATAL_ERROR(rc)) - return rc; - } - - rc = sensor_set_backlight(ov, ov->backlight); - if (FATAL_ERROR(rc)) - return rc; - - rc = sensor_set_mirror(ov, ov->mirror); - if (FATAL_ERROR(rc)) - return rc; - - return 0; -} - -/* This sets the default image parameters. This is useful for apps that use - * read() and do not set these. - */ -static int -ov51x_set_default_params(struct usb_ov511 *ov) -{ - int i; - - /* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used - * (using read() instead). */ - for (i = 0; i < OV511_NUMFRAMES; i++) { - ov->frame[i].width = ov->maxwidth; - ov->frame[i].height = ov->maxheight; - ov->frame[i].bytes_read = 0; - if (force_palette) - ov->frame[i].format = force_palette; - else -#ifdef OV511_ALLOW_CONVERSION - ov->frame[i].format = VIDEO_PALETTE_RGB24; -#else - ov->frame[i].format = VIDEO_PALETTE_YUV420; -#endif - ov->frame[i].depth = get_depth(ov->frame[i].format); - } - - PDEBUG(3, "%dx%d, %s", ov->maxwidth, ov->maxheight, - symbolic(v4l1_plist, ov->frame[0].format)); - - /* Initialize to max width/height, YUV420 or RGB24 (if supported) */ - if (mode_init_regs(ov, ov->maxwidth, ov->maxheight, - ov->frame[0].format, 0) < 0) - return -EINVAL; - - return 0; -} - -/********************************************************************** - * - * Video decoder stuff - * - **********************************************************************/ - -/* Set analog input port of decoder */ -static int -decoder_set_input(struct usb_ov511 *ov, int input) -{ - PDEBUG(4, "port %d", input); - - switch (ov->sensor) { - case SEN_SAA7111A: - { - /* Select mode */ - i2c_w_mask(ov, 0x02, input, 0x07); - /* Bypass chrominance trap for modes 4..7 */ - i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80); - break; - } - default: - return -EINVAL; - } - - return 0; -} - -/* Get ASCII name of video input */ -static int -decoder_get_input_name(struct usb_ov511 *ov, int input, char *name) -{ - switch (ov->sensor) { - case SEN_SAA7111A: - { - if (input < 0 || input > 7) - return -EINVAL; - else if (input < 4) - sprintf(name, "CVBS-%d", input); - else // if (input < 8) - sprintf(name, "S-Video-%d", input - 4); - break; - } - default: - sprintf(name, "%s", "Camera"); - } - - return 0; -} - -/* Set norm (NTSC, PAL, SECAM, AUTO) */ -static int -decoder_set_norm(struct usb_ov511 *ov, int norm) -{ - PDEBUG(4, "%d", norm); - - switch (ov->sensor) { - case SEN_SAA7111A: - { - int reg_8, reg_e; - - if (norm == VIDEO_MODE_NTSC) { - reg_8 = 0x40; /* 60 Hz */ - reg_e = 0x00; /* NTSC M / PAL BGHI */ - } else if (norm == VIDEO_MODE_PAL) { - reg_8 = 0x00; /* 50 Hz */ - reg_e = 0x00; /* NTSC M / PAL BGHI */ - } else if (norm == VIDEO_MODE_AUTO) { - reg_8 = 0x80; /* Auto field detect */ - reg_e = 0x00; /* NTSC M / PAL BGHI */ - } else if (norm == VIDEO_MODE_SECAM) { - reg_8 = 0x00; /* 50 Hz */ - reg_e = 0x50; /* SECAM / PAL 4.43 */ - } else { - return -EINVAL; - } - - i2c_w_mask(ov, 0x08, reg_8, 0xc0); - i2c_w_mask(ov, 0x0e, reg_e, 0x70); - break; - } - default: - return -EINVAL; - } - - return 0; -} - -#ifdef OV511_ALLOW_CONVERSION -/********************************************************************** - * - * Color correction functions - * - **********************************************************************/ - -/* - * Turn a YUV4:2:0 block into an RGB block - * - * Video4Linux seems to use the blue, green, red channel - * order convention-- rgb[0] is blue, rgb[1] is green, rgb[2] is red. - * - * Color space conversion coefficients taken from the excellent - * http://www.inforamp.net/~poynton/ColorFAQ.html - * In his terminology, this is a CCIR 601.1 YCbCr -> RGB. - * Y values are given for all 4 pixels, but the U (Pb) - * and V (Pr) are assumed constant over the 2x2 block. - * - * To avoid floating point arithmetic, the color conversion - * coefficients are scaled into 16.16 fixed-point integers. - * They were determined as follows: - * - * double brightness = 1.0; (0->black; 1->full scale) - * double saturation = 1.0; (0->greyscale; 1->full color) - * double fixScale = brightness * 256 * 256; - * int rvScale = (int)(1.402 * saturation * fixScale); - * int guScale = (int)(-0.344136 * saturation * fixScale); - * int gvScale = (int)(-0.714136 * saturation * fixScale); - * int buScale = (int)(1.772 * saturation * fixScale); - * int yScale = (int)(fixScale); - */ - -/* LIMIT: convert a 16.16 fixed-point value to a byte, with clipping. */ -#define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16))) - -static inline void -move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v, - int rowPixels, unsigned char * rgb, int bits) -{ - const int rvScale = 91881; - const int guScale = -22553; - const int gvScale = -46801; - const int buScale = 116129; - const int yScale = 65536; - int r, g, b; - - g = guScale * u + gvScale * v; - if (force_rgb) { - r = buScale * u; - b = rvScale * v; - } else { - r = rvScale * v; - b = buScale * u; - } - - yTL *= yScale; yTR *= yScale; - yBL *= yScale; yBR *= yScale; - - if (bits == 24) { - /* Write out top two pixels */ - rgb[0] = LIMIT(b+yTL); rgb[1] = LIMIT(g+yTL); - rgb[2] = LIMIT(r+yTL); - - rgb[3] = LIMIT(b+yTR); rgb[4] = LIMIT(g+yTR); - rgb[5] = LIMIT(r+yTR); - - /* Skip down to next line to write out bottom two pixels */ - rgb += 3 * rowPixels; - rgb[0] = LIMIT(b+yBL); rgb[1] = LIMIT(g+yBL); - rgb[2] = LIMIT(r+yBL); - - rgb[3] = LIMIT(b+yBR); rgb[4] = LIMIT(g+yBR); - rgb[5] = LIMIT(r+yBR); - } else if (bits == 16) { - /* Write out top two pixels */ - rgb[0] = ((LIMIT(b+yTL) >> 3) & 0x1F) - | ((LIMIT(g+yTL) << 3) & 0xE0); - rgb[1] = ((LIMIT(g+yTL) >> 5) & 0x07) - | (LIMIT(r+yTL) & 0xF8); - - rgb[2] = ((LIMIT(b+yTR) >> 3) & 0x1F) - | ((LIMIT(g+yTR) << 3) & 0xE0); - rgb[3] = ((LIMIT(g+yTR) >> 5) & 0x07) - | (LIMIT(r+yTR) & 0xF8); - - /* Skip down to next line to write out bottom two pixels */ - rgb += 2 * rowPixels; - - rgb[0] = ((LIMIT(b+yBL) >> 3) & 0x1F) - | ((LIMIT(g+yBL) << 3) & 0xE0); - rgb[1] = ((LIMIT(g+yBL) >> 5) & 0x07) - | (LIMIT(r+yBL) & 0xF8); - - rgb[2] = ((LIMIT(b+yBR) >> 3) & 0x1F) - | ((LIMIT(g+yBR) << 3) & 0xE0); - rgb[3] = ((LIMIT(g+yBR) >> 5) & 0x07) - | (LIMIT(r+yBR) & 0xF8); - } -} - -#endif /* OV511_ALLOW_CONVERSION */ - -/********************************************************************** - * - * Raw data parsing - * - **********************************************************************/ - -/* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the - * image at pOut is specified by w. - */ -static inline void -make_8x8(unsigned char *pIn, unsigned char *pOut, int w) -{ - unsigned char *pOut1 = pOut; - int x, y; - - for (y = 0; y < 8; y++) { - pOut1 = pOut; - for (x = 0; x < 8; x++) { - *pOut1++ = *pIn++; - } - pOut += w; - } -} - -/* - * For RAW BW (YUV 4:0:0) images, data show up in 256 byte segments. - * The segments represent 4 squares of 8x8 pixels as follows: - * - * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199 - * 8 9 ... 15 72 73 ... 79 200 201 ... 207 - * ... ... ... - * 56 57 ... 63 120 121 ... 127 248 249 ... 255 - * - */ -static void -yuv400raw_to_yuv400p(struct ov511_frame *frame, - unsigned char *pIn0, unsigned char *pOut0) -{ - int x, y; - unsigned char *pIn, *pOut, *pOutLine; - - /* Copy Y */ - pIn = pIn0; - pOutLine = pOut0; - for (y = 0; y < frame->rawheight - 1; y += 8) { - pOut = pOutLine; - for (x = 0; x < frame->rawwidth - 1; x += 8) { - make_8x8(pIn, pOut, frame->rawwidth); - pIn += 64; - pOut += 8; - } - pOutLine += 8 * frame->rawwidth; - } -} - -/* - * For YUV 4:2:0 images, the data show up in 384 byte segments. - * The first 64 bytes of each segment are U, the next 64 are V. The U and - * V are arranged as follows: - * - * 0 1 ... 7 - * 8 9 ... 15 - * ... - * 56 57 ... 63 - * - * U and V are shipped at half resolution (1 U,V sample -> one 2x2 block). - * - * The next 256 bytes are full resolution Y data and represent 4 squares - * of 8x8 pixels as follows: - * - * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199 - * 8 9 ... 15 72 73 ... 79 200 201 ... 207 - * ... ... ... - * 56 57 ... 63 120 121 ... 127 ... 248 249 ... 255 - * - * Note that the U and V data in one segment represent a 16 x 16 pixel - * area, but the Y data represent a 32 x 8 pixel area. If the width is not an - * even multiple of 32, the extra 8x8 blocks within a 32x8 block belong to the - * next horizontal stripe. - * - * If dumppix module param is set, _parse_data just dumps the incoming segments, - * verbatim, in order, into the frame. When used with vidcat -f ppm -s 640x480 - * this puts the data on the standard output and can be analyzed with the - * parseppm.c utility I wrote. That's a much faster way for figuring out how - * these data are scrambled. - */ - -/* Converts from raw, uncompressed segments at pIn0 to a YUV420P frame at pOut0. - * - * FIXME: Currently only handles width and height that are multiples of 16 - */ -static void -yuv420raw_to_yuv420p(struct ov511_frame *frame, - unsigned char *pIn0, unsigned char *pOut0) -{ - int k, x, y; - unsigned char *pIn, *pOut, *pOutLine; - const unsigned int a = frame->rawwidth * frame->rawheight; - const unsigned int w = frame->rawwidth / 2; - - /* Copy U and V */ - pIn = pIn0; - pOutLine = pOut0 + a; - for (y = 0; y < frame->rawheight - 1; y += 16) { - pOut = pOutLine; - for (x = 0; x < frame->rawwidth - 1; x += 16) { - make_8x8(pIn, pOut, w); - make_8x8(pIn + 64, pOut + a/4, w); - pIn += 384; - pOut += 8; - } - pOutLine += 8 * w; - } - - /* Copy Y */ - pIn = pIn0 + 128; - pOutLine = pOut0; - k = 0; - for (y = 0; y < frame->rawheight - 1; y += 8) { - pOut = pOutLine; - for (x = 0; x < frame->rawwidth - 1; x += 8) { - make_8x8(pIn, pOut, frame->rawwidth); - pIn += 64; - pOut += 8; - if ((++k) > 3) { - k = 0; - pIn += 128; - } - } - pOutLine += 8 * frame->rawwidth; - } -} - -#ifdef OV511_ALLOW_CONVERSION -/* - * fixFrameRGBoffset-- - * My camera seems to return the red channel about 1 pixel - * low, and the blue channel about 1 pixel high. After YUV->RGB - * conversion, we can correct this easily. OSL 2/24/2000. - */ -static void -fixFrameRGBoffset(struct ov511_frame *frame) -{ - int x, y; - int rowBytes = frame->width*3, w = frame->width; - unsigned char *rgb = frame->data; - const int shift = 1; /* Distance to shift pixels by, vertically */ - - /* Don't bother with little images */ - if (frame->width < 400) - return; - - /* This only works with RGB24 */ - if (frame->format != VIDEO_PALETTE_RGB24) - return; - - /* Shift red channel up */ - for (y = shift; y < frame->height; y++) { - int lp = (y-shift)*rowBytes; /* Previous line offset */ - int lc = y*rowBytes; /* Current line offset */ - for (x = 0; x < w; x++) - rgb[lp+x*3+2] = rgb[lc+x*3+2]; /* Shift red up */ - } - - /* Shift blue channel down */ - for (y = frame->height-shift-1; y >= 0; y--) { - int ln = (y + shift) * rowBytes; /* Next line offset */ - int lc = y * rowBytes; /* Current line offset */ - for (x = 0; x < w; x++) - rgb[ln+x*3+0] = rgb[lc+x*3+0]; /* Shift blue down */ - } -} -#endif - -/********************************************************************** - * - * Decompression - * - **********************************************************************/ - -/* Chooses a decompression module, locks it, and sets ov->decomp_ops - * accordingly. Returns -ENXIO if decompressor is not available, otherwise - * returns 0 if no other error. - */ -static int -request_decompressor(struct usb_ov511 *ov) -{ - if (!ov) - return -ENODEV; - - if (ov->decomp_ops) { - err("ERROR: Decompressor already requested!"); - return -EINVAL; - } - - lock_kernel(); - - /* Try to get MMX, and fall back on no-MMX if necessary */ - if (ov->bclass == BCL_OV511) { - if (ov511_mmx_decomp_ops) { - PDEBUG(3, "Using OV511 MMX decompressor"); - ov->decomp_ops = ov511_mmx_decomp_ops; - } else if (ov511_decomp_ops) { - PDEBUG(3, "Using OV511 decompressor"); - ov->decomp_ops = ov511_decomp_ops; - } else { - err("No decompressor available"); - } - } else if (ov->bclass == BCL_OV518) { - if (ov518_mmx_decomp_ops) { - PDEBUG(3, "Using OV518 MMX decompressor"); - ov->decomp_ops = ov518_mmx_decomp_ops; - } else if (ov518_decomp_ops) { - PDEBUG(3, "Using OV518 decompressor"); - ov->decomp_ops = ov518_decomp_ops; - } else { - err("No decompressor available"); - } - } else if (ov->bclass == BCL_OV519) { - info("OV519 doesn't need proprietary decompressor. It uses standard JPEG"); - } else { - err("Decompressor: Unknown bridge"); - } - - if (ov->decomp_ops) { - if (!ov->decomp_ops->owner) { - ov->decomp_ops = NULL; - unlock_kernel(); - return -ENOSYS; - } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - if (! try_module_get (ov->decomp_ops->owner)) { - ov->decomp_ops = NULL; - unlock_kernel(); - return -ENOSYS; - } -#else - __MOD_INC_USE_COUNT(ov->decomp_ops->owner); -#endif - unlock_kernel(); - return 0; - } else { - unlock_kernel(); - if (ov->bclass == BCL_OV519) - return 0; - else - return -ENOSYS; - } -} - -/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even - * if ov->decomp_ops is NULL. - */ -static void -release_decompressor(struct usb_ov511 *ov) -{ - int released = 0; /* Did we actually do anything? */ - - if (!ov) - return; - - if (ov->bclass == BCL_OV519) { - ov->compress_inited = 0; - return; - } - - lock_kernel(); - - if (ov->decomp_ops && ov->decomp_ops->owner) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - module_put(ov->decomp_ops->owner); -#else - __MOD_DEC_USE_COUNT(ov->decomp_ops->owner); -#endif - released = 1; - } - - ov->decomp_ops = NULL; - - unlock_kernel(); - - if (released) - PDEBUG(3, "Decompressor released"); -} - -static void -decompress(struct usb_ov511 *ov, struct ov511_frame *frame, - unsigned char *pIn0, unsigned char *pOut0) -{ - if (!ov->decomp_ops) - if (request_decompressor(ov)) - return; - - PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd); - - if (frame->format == VIDEO_PALETTE_GREY - && ov->decomp_ops->decomp_400) { - int ret = ov->decomp_ops->decomp_400( - pIn0, - pOut0, - frame->compbuf, - frame->rawwidth, - frame->rawheight, - frame->bytes_recvd); - PDEBUG(4, "DEBUG: decomp_400 returned %d", ret); - } else if (frame->format != VIDEO_PALETTE_GREY - && ov->decomp_ops->decomp_420) { - int ret = ov->decomp_ops->decomp_420( - pIn0, - pOut0, - frame->compbuf, - frame->rawwidth, - frame->rawheight, - frame->bytes_recvd); - PDEBUG(4, "DEBUG: decomp_420 returned %d", ret); - } else { - err("Decompressor does not support this format"); - } -} - -/********************************************************************** - * - * Format conversion - * - **********************************************************************/ - -#ifdef OV511_ALLOW_CONVERSION - -/* Converts from planar YUV420 to RGB24. */ -static void -yuv420p_to_rgb(struct ov511_frame *frame, - unsigned char *pIn0, unsigned char *pOut0, int bits) -{ - const int numpix = frame->width * frame->height; - const int bytes = bits >> 3; - int i, j, y00, y01, y10, y11, u, v; - unsigned char *pY = pIn0; - unsigned char *pU = pY + numpix; - unsigned char *pV = pU + numpix / 4; - unsigned char *pOut = pOut0; - - for (j = 0; j <= frame->height - 2; j += 2) { - for (i = 0; i <= frame->width - 2; i += 2) { - y00 = *pY; - y01 = *(pY + 1); - y10 = *(pY + frame->width); - y11 = *(pY + frame->width + 1); - u = (*pU++) - 128; - v = (*pV++) - 128; - - move_420_block(y00, y01, y10, y11, u, v, - frame->width, pOut, bits); - - pY += 2; - pOut += 2 * bytes; - } - pY += frame->width; - pOut += frame->width * bytes; - } -} - -/* Converts from planar YUV420 to YUV422 (YUYV). */ -static void -yuv420p_to_yuv422(struct ov511_frame *frame, - unsigned char *pIn0, unsigned char *pOut0) -{ - const int numpix = frame->width * frame->height; - int i, j; - unsigned char *pY = pIn0; - unsigned char *pU = pY + numpix; - unsigned char *pV = pU + numpix / 4; - unsigned char *pOut = pOut0; - - for (i = 0; i < numpix; i++) { - *pOut = *(pY + i); - pOut += 2; - } - - pOut = pOut0 + 1; - for (j = 0; j <= frame->height - 2 ; j += 2) { - for (i = 0; i <= frame->width - 2; i += 2) { - int u = *pU++; - int v = *pV++; - - *pOut = u; - *(pOut+2) = v; - *(pOut+frame->width*2) = u; - *(pOut+frame->width*2+2) = v; - pOut += 4; - } - pOut += (frame->width * 2); - } -} - -/* Converts pData from planar YUV420 to planar YUV422 **in place**. */ -static void -yuv420p_to_yuv422p(struct ov511_frame *frame, unsigned char *pData) -{ - const int numpix = frame->width * frame->height; - const int w = frame->width; - int j; - unsigned char *pIn, *pOut; - - /* Clear U and V */ - memset(pData + numpix + numpix / 2, 127, numpix / 2); - - /* Convert V starting from beginning and working forward */ - pIn = pData + numpix + numpix / 4; - pOut = pData + numpix +numpix / 2; - for (j = 0; j <= frame->height - 2; j += 2) { - memmove(pOut, pIn, w/2); - memmove(pOut + w/2, pIn, w/2); - pIn += w/2; - pOut += w; - } - - /* Convert U, starting from end and working backward */ - pIn = pData + numpix + numpix / 4; - pOut = pData + numpix + numpix / 2; - for (j = 0; j <= frame->height - 2; j += 2) { - pIn -= w/2; - pOut -= w; - memmove(pOut, pIn, w/2); - memmove(pOut + w/2, pIn, w/2); - } -} - -#endif /* OV511_ALLOW_CONVERSION */ - -/* Fuses even and odd fields together, and doubles width. - * INPUT: an odd field followed by an even field at pIn0, in YUV planar format - * OUTPUT: a normal YUV planar image, with correct aspect ratio - */ -static void -deinterlace(struct ov511_frame *frame, int rawformat, - unsigned char *pIn0, unsigned char *pOut0) -{ - const int fieldheight = frame->rawheight / 2; - const int fieldpix = fieldheight * frame->rawwidth; - const int w = frame->width; - int x, y; - unsigned char *pInEven, *pInOdd, *pOut; - - PDEBUG(5, "fieldheight=%d", fieldheight); - - if (frame->rawheight != frame->height) { - err("invalid height"); - return; - } - - if ((frame->rawwidth * 2) != frame->width) { - err("invalid width"); - return; - } - - /* Y */ - pInOdd = pIn0; - pInEven = pInOdd + fieldpix; - pOut = pOut0; - for (y = 0; y < fieldheight; y++) { - for (x = 0; x < frame->rawwidth; x++) { - *pOut = *pInEven; - *(pOut+1) = *pInEven++; - *(pOut+w) = *pInOdd; - *(pOut+w+1) = *pInOdd++; - pOut += 2; - } - pOut += w; - } - - if (rawformat == RAWFMT_YUV420) { - /* U */ - pInOdd = pIn0 + fieldpix * 2; - pInEven = pInOdd + fieldpix / 4; - for (y = 0; y < fieldheight / 2; y++) { - for (x = 0; x < frame->rawwidth / 2; x++) { - *pOut = *pInEven; - *(pOut+1) = *pInEven++; - *(pOut+w/2) = *pInOdd; - *(pOut+w/2+1) = *pInOdd++; - pOut += 2; - } - pOut += w/2; - } - /* V */ - pInOdd = pIn0 + fieldpix * 2 + fieldpix / 2; - pInEven = pInOdd + fieldpix / 4; - for (y = 0; y < fieldheight / 2; y++) { - for (x = 0; x < frame->rawwidth / 2; x++) { - *pOut = *pInEven; - *(pOut+1) = *pInEven++; - *(pOut+w/2) = *pInOdd; - *(pOut+w/2+1) = *pInOdd++; - pOut += 2; - } - pOut += w/2; - } - } -} - -static void -ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame) -{ - /* Deinterlace frame, if necessary */ - if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) { - if (frame->compressed) - decompress(ov, frame, frame->rawdata, - frame->tempdata); - else - yuv400raw_to_yuv400p(frame, frame->rawdata, - frame->tempdata); - - deinterlace(frame, RAWFMT_YUV400, frame->tempdata, - frame->data); - } else { - if (frame->compressed) - decompress(ov, frame, frame->rawdata, - frame->data); - else - yuv400raw_to_yuv400p(frame, frame->rawdata, - frame->data); - } -} - -#ifdef OV511_ALLOW_CONVERSION -/* Process raw YUV420 data into the format requested by the app. Conversion - * between V4L formats is allowed. - */ -static void -ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame) -{ - /* Process frame->rawdata to frame->tempdata */ - if (frame->compressed) - decompress(ov, frame, frame->rawdata, frame->tempdata); - else - yuv420raw_to_yuv420p(frame, frame->rawdata, frame->tempdata); - - /* Deinterlace frame, if necessary */ - if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) { - memcpy(frame->rawdata, frame->tempdata, - MAX_RAW_DATA_SIZE(frame->width, frame->height)); - deinterlace(frame, RAWFMT_YUV420, frame->rawdata, - frame->tempdata); - } - - /* Frame should be (width x height) and not (rawwidth x rawheight) at - * this point. */ - - /* Process frame->tempdata to frame->data */ - switch (frame->format) { - case VIDEO_PALETTE_RGB565: - yuv420p_to_rgb(frame, frame->tempdata, frame->data, 16); - break; - case VIDEO_PALETTE_RGB24: - yuv420p_to_rgb(frame, frame->tempdata, frame->data, 24); - break; - case VIDEO_PALETTE_YUV422: - case VIDEO_PALETTE_YUYV: - yuv420p_to_yuv422(frame, frame->tempdata, frame->data); - break; - case VIDEO_PALETTE_YUV420: - case VIDEO_PALETTE_YUV420P: - memcpy(frame->data, frame->tempdata, - MAX_RAW_DATA_SIZE(frame->width, frame->height)); - break; - case VIDEO_PALETTE_YUV422P: - /* Data is converted in place, so copy it in advance */ - memcpy(frame->data, frame->tempdata, - MAX_RAW_DATA_SIZE(frame->width, frame->height)); - - yuv420p_to_yuv422p(frame, frame->data); - break; - default: - err("Cannot convert YUV420 to %s", - symbolic(v4l1_plist, frame->format)); - } - - if (fix_rgb_offset) - fixFrameRGBoffset(frame); -} - -#else /* if conversion not allowed */ - -/* Process raw YUV420 data into standard YUV420P */ -static void -ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame) -{ - /* Deinterlace frame, if necessary */ - if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) { - if (frame->compressed) - decompress(ov, frame, frame->rawdata, frame->tempdata); - else - yuv420raw_to_yuv420p(frame, frame->rawdata, - frame->tempdata); - - deinterlace(frame, RAWFMT_YUV420, frame->tempdata, - frame->data); - } else { - if (frame->compressed) - decompress(ov, frame, frame->rawdata, frame->data); - else - yuv420raw_to_yuv420p(frame, frame->rawdata, - frame->data); - } -} -#endif /* OV511_ALLOW_CONVERSION */ - -/* Post-processes the specified frame. This consists of: - * 1. Decompress frame, if necessary - * 2. Deinterlace frame and scale to proper size, if necessary - * 3. Convert from YUV planar to destination format, if necessary - * 4. Fix the RGB offset, if necessary - */ -static void -ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame) -{ - if (dumppix) { - memset(frame->data, 0, - MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)); - PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd); - memcpy(frame->data, frame->rawdata, frame->bytes_recvd); - } else { - switch (frame->format) { - case VIDEO_PALETTE_GREY: - ov51x_postprocess_grey(ov, frame); - break; - case VIDEO_PALETTE_YUV420: - case VIDEO_PALETTE_YUV420P: -#ifdef OV511_ALLOW_CONVERSION - case VIDEO_PALETTE_RGB565: - case VIDEO_PALETTE_RGB24: - case VIDEO_PALETTE_YUV422: - case VIDEO_PALETTE_YUYV: - case VIDEO_PALETTE_YUV422P: -#endif - ov51x_postprocess_yuv420(ov, frame); - break; - default: - err("Cannot convert data to %s", - symbolic(v4l1_plist, frame->format)); - } - } -} - -/********************************************************************** - * - * OV51x data transfer, IRQ handler - * - **********************************************************************/ - -static inline void -ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) -{ - int num, offset; - int pnum = in[ov->packet_size - 1]; /* Get packet number */ - int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight); - struct ov511_frame *frame = &ov->frame[ov->curframe]; - struct timeval *ts; - - /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th - * byte non-zero. The EOF packet has image width/height in the - * 10th and 11th bytes. The 9th byte is given as follows: - * - * bit 7: EOF - * 6: compression enabled - * 5: 422/420/400 modes - * 4: 422/420/400 modes - * 3: 1 - * 2: snapshot button on - * 1: snapshot frame - * 0: even/odd field - */ - - if (printph) { - info("ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", - pnum, in[0], in[1], in[2], in[3], in[4], in[5], in[6], - in[7], in[8], in[9], in[10], in[11]); - } - - /* Check for SOF/EOF packet */ - if ((in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) || - (~in[8] & 0x08)) - goto check_middle; - - /* Frame end */ - if (in[8] & 0x80) { - ts = (struct timeval *)(frame->data - + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight)); - do_gettimeofday(ts); - - /* Get the actual frame size from the EOF header */ - frame->rawwidth = ((int)(in[9]) + 1) * 8; - frame->rawheight = ((int)(in[10]) + 1) * 8; - - PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d", - ov->curframe, pnum, frame->rawwidth, frame->rawheight, - frame->bytes_recvd); - - /* Validate the header data */ - RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth); - RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, - ov->maxheight); - - /* Don't allow byte count to exceed buffer size */ - RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); - - if (frame->scanstate == STATE_LINES) { - int nextf; - - frame->grabstate = FRAME_DONE; - wake_up_interruptible(&frame->wq); - - /* If next frame is ready or grabbing, - * point to it */ - nextf = (ov->curframe + 1) % OV511_NUMFRAMES; - if (ov->frame[nextf].grabstate == FRAME_READY - || ov->frame[nextf].grabstate == FRAME_GRABBING) { - ov->curframe = nextf; - ov->frame[nextf].scanstate = STATE_SCANNING; - } else { - if (ov->frame[nextf].grabstate == FRAME_DONE) { - PDEBUG(4, "No empty frames left"); - } else { - PDEBUG(4, "Frame not ready? state = %d", - ov->frame[nextf].grabstate); - } - - ov->curframe = -1; - } - } else { - PDEBUG(5, "Frame done, but not scanning"); - } - /* Image corruption caused by misplaced frame->segment = 0 - * fixed by carlosf@conectiva.com.br - */ - } else { - /* Frame start */ - PDEBUG(4, "Frame start, framenum = %d", ov->curframe); - - /* Check to see if it's a snapshot frame */ - /* FIXME?? Should the snapshot reset go here? Performance? */ - if (in[8] & 0x02) { - frame->snapshot = 1; - PDEBUG(3, "snapshot detected"); - } - - frame->scanstate = STATE_LINES; - frame->bytes_recvd = 0; - frame->compressed = in[8] & 0x40; - } - -check_middle: - /* Are we in a frame? */ - if (frame->scanstate != STATE_LINES) { - PDEBUG(5, "Not in a frame; packet skipped"); - return; - } - - /* If frame start, skip header */ - if (frame->bytes_recvd == 0) - offset = 9; - else - offset = 0; - - num = n - offset - 1; - - /* Dump all data exactly as received */ - if (dumppix == 2) { - frame->bytes_recvd += n - 1; - if (frame->bytes_recvd <= max_raw) - memcpy(frame->rawdata + frame->bytes_recvd - (n - 1), - in, n - 1); - else - PDEBUG(3, "Raw data buffer overrun!! (%d)", - frame->bytes_recvd - max_raw); - } else if (!frame->compressed && !remove_zeros) { - frame->bytes_recvd += num; - if (frame->bytes_recvd <= max_raw) - memcpy(frame->rawdata + frame->bytes_recvd - num, - in + offset, num); - else - PDEBUG(3, "Raw data buffer overrun!! (%d)", - frame->bytes_recvd - max_raw); - } else { /* Remove all-zero FIFO lines (aligned 32-byte blocks) */ - int b, read = 0, allzero, copied = 0; - if (offset) { - frame->bytes_recvd += 32 - offset; // Bytes out - memcpy(frame->rawdata, in + offset, 32 - offset); - read += 32; - } - - while (read < n - 1) { - allzero = 1; - for (b = 0; b < 32; b++) { - if (in[read + b]) { - allzero = 0; - break; - } - } - - if (allzero) { - /* Don't copy it */ - } else { - if (frame->bytes_recvd + copied + 32 <= max_raw) - { - memcpy(frame->rawdata - + frame->bytes_recvd + copied, - in + read, 32); - copied += 32; - } else { - PDEBUG(3, "Raw data buffer overrun!!"); - } - } - read += 32; - } - - frame->bytes_recvd += copied; - } -} - -static inline void -ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n) -{ - int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight); - struct ov511_frame *frame = &ov->frame[ov->curframe]; - struct timeval *ts; - - /* Don't copy the packet number byte */ - if (ov->packet_numbering) - --n; - - /* A false positive here is likely, until OVT gives me - * the definitive SOF/EOF format */ - if ((!(in[0] | in[1] | in[2] | in[3] | in[5])) && in[6]) { - if (printph) { - info("ph: %2x %2x %2x %2x %2x %2x %2x %2x", in[0], - in[1], in[2], in[3], in[4], in[5], in[6], in[7]); - } - - if (frame->scanstate == STATE_LINES) { - PDEBUG(4, "Detected frame end/start"); - goto eof; - } else { //scanstate == STATE_SCANNING - /* Frame start */ - PDEBUG(4, "Frame start, framenum = %d", ov->curframe); - goto sof; - } - } else { - goto check_middle; - } - -eof: - ts = (struct timeval *)(frame->data - + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight)); - do_gettimeofday(ts); - - PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d", - ov->curframe, - (int)(in[9]), (int)(in[10]), frame->bytes_recvd); - - // FIXME: Since we don't know the header formats yet, - // there is no way to know what the actual image size is - frame->rawwidth = frame->width; - frame->rawheight = frame->height; - - /* Validate the header data */ - RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth); - RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight); - - /* Don't allow byte count to exceed buffer size */ - RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); - - if (frame->scanstate == STATE_LINES) { - int nextf; - - frame->grabstate = FRAME_DONE; - wake_up_interruptible(&frame->wq); - - /* If next frame is ready or grabbing, - * point to it */ - nextf = (ov->curframe + 1) % OV511_NUMFRAMES; - if (ov->frame[nextf].grabstate == FRAME_READY - || ov->frame[nextf].grabstate == FRAME_GRABBING) { - ov->curframe = nextf; - ov->frame[nextf].scanstate = STATE_SCANNING; - frame = &ov->frame[nextf]; - } else { - if (ov->frame[nextf].grabstate == FRAME_DONE) { - PDEBUG(4, "No empty frames left"); - } else { - PDEBUG(4, "Frame not ready? state = %d", - ov->frame[nextf].grabstate); - } - - ov->curframe = -1; - PDEBUG(4, "SOF dropped (no active frame)"); - return; /* Nowhere to store this frame */ - } - } -sof: - PDEBUG(4, "Starting capture on frame %d", frame->framenum); - -// Snapshot not reverse-engineered yet. -#if 0 - /* Check to see if it's a snapshot frame */ - /* FIXME?? Should the snapshot reset go here? Performance? */ - if (in[8] & 0x02) { - frame->snapshot = 1; - PDEBUG(3, "snapshot detected"); - } -#endif - frame->scanstate = STATE_LINES; - frame->bytes_recvd = 0; - frame->compressed = 1; - -check_middle: - /* Are we in a frame? */ - if (frame->scanstate != STATE_LINES) { - PDEBUG(4, "scanstate: no SOF yet"); - return; - } - - /* Dump all data exactly as received */ - if (dumppix == 2) { - frame->bytes_recvd += n; - if (frame->bytes_recvd <= max_raw) - memcpy(frame->rawdata + frame->bytes_recvd - n, in, n); - else - PDEBUG(3, "Raw data buffer overrun!! (%d)", - frame->bytes_recvd - max_raw); - } else { - /* All incoming data are divided into 8-byte segments. If the - * segment contains all zero bytes, it must be skipped. These - * zero-segments allow the OV518 to mainain a constant data rate - * regardless of the effectiveness of the compression. Segments - * are aligned relative to the beginning of each isochronous - * packet. The first segment in each image is a header (the - * decompressor skips it later). - */ - - int b, read = 0, allzero, copied = 0; - - while (read < n) { - allzero = 1; - for (b = 0; b < 8; b++) { - if (in[read + b]) { - allzero = 0; - break; - } - } - - if (allzero) { - /* Don't copy it */ - } else { - if (frame->bytes_recvd + copied + 8 <= max_raw) - { - memcpy(frame->rawdata - + frame->bytes_recvd + copied, - in + read, 8); - copied += 8; - } else { - PDEBUG(3, "Raw data buffer overrun!!"); - } - } - read += 8; - } - frame->bytes_recvd += copied; - } -} - -static inline void -ov519_move_data(struct usb_ov511 *ov, unsigned char *in, int n) -{ - int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight); - struct ov511_frame *frame = &ov->frame[ov->curframe]; - struct timeval *ts; - - /* Don't copy the packet number byte */ -// if (ov->packet_numbering) -// --n; -/* Header of ov519 is 16 bytes: - * Byte Value Description - * 0 0xff magic - * 1 0xff magic - * 2 0xff magic - * 3 0xXX 0x50 = SOF, 0x51 = EOF - * 9 0xXX 0x01 initial frame without data, 0x00 standard frame with image - * 14 Lo in EOF: length of image data / 8 - * 15 Hi - */ - - // Start Of Frame - if ((in[0]==0xff) && (in[1]==0xff) && (in[2]==0xff)) { - - if (printph) { - info("ph: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", - in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7], - in[8], in[9], in[10], in[11], in[12], in[13], in[14], in[15]); - } - - if (in[3]==0x50) { - PDEBUG(4, "Start Of Frame, framenum = %d", ov->curframe); - goto sof; - } else if (in[3]==0x51) { - PDEBUG(4, "End Of Frame"); - goto eof; - } else { - goto check_middle; - } - } else { - goto check_middle; - } - -eof: - ts = (struct timeval *)(frame->data - + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight)); - do_gettimeofday(ts); - PDEBUG(4, "Frame end, curframe=%d, length=%d, recvd=%d", - ov->curframe, (int)((in[14]) + ((int)(in[15])<<8))<<3, frame->bytes_recvd - (jpeginfo?2:0)); - - - if (in[9]) { - PDEBUG(1, "initial frame"); - frame->scanstate = STATE_SCANNING; - return; - } - - // FIXME: Since we don't know the header formats yet, - // there is no way to know what the actual image size is - frame->rawwidth = frame->width; - frame->rawheight = frame->height; - - /* Validate the header data */ - RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth); - RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight); - - /* Don't allow byte count to exceed buffer size */ - //RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); - - if (frame->scanstate == STATE_LINES) { - int nextf; - - if (((int)((in[14]) + ((int)(in[15])<<8))<<3) != (frame->bytes_recvd - (jpeginfo?2:0))) { - info("Data length in header and number of received bytes differ"); - frame->scanstate = STATE_SCANNING; - return; - } - - if (jpeginfo) { - frame->data[0] = in[14]; - frame->data[1] = in[15]; - } - frame->grabstate = FRAME_DONE; - wake_up_interruptible(&frame->wq); - - /* If next frame is ready or grabbing, - * point to it */ - nextf = (ov->curframe + 1) % OV511_NUMFRAMES; - if (ov->frame[nextf].grabstate == FRAME_READY - || ov->frame[nextf].grabstate == FRAME_GRABBING) { - ov->curframe = nextf; - ov->frame[nextf].scanstate = STATE_SCANNING; - } else { - ov->curframe = -1; - } - } else { - info("EOF without SOF"); // This happens if there was no active frame when SOF arrived - } - return; - -sof: - PDEBUG(4, "Starting capture on frame %d", frame->framenum); - - // Skip SOF Header: - in += 16; - n -= 16; - - frame->scanstate = STATE_LINES; - if (jpeginfo) { - frame->bytes_recvd = 2; // Space for length bytes. Will be written at EOF - frame->data[0] = 0; - frame->data[1] = 0; - } else { - frame->bytes_recvd = 0; - } - frame->compressed = 1; - -check_middle: - /* Are we in a frame? */ - if (frame->scanstate != STATE_LINES) { - PDEBUG(4, "scanstate: no SOF yet"); - return; - } - - /* Dump all data exactly as received. It is standard JPEG */ - frame->bytes_recvd += n; - if (frame->bytes_recvd <= max_raw) { - memcpy(frame->data + frame->bytes_recvd - n, in, n); - } else { - PDEBUG(3, "Raw data buffer overrun!! (%d)", frame->bytes_recvd - max_raw); - } -} - -static void -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 51) -ov51x_isoc_irq(struct urb *urb, struct pt_regs *regs) -#else -ov51x_isoc_irq(struct urb *urb) -#endif -{ - int i; - struct usb_ov511 *ov; - struct ov511_sbuf *sbuf; - - if (!urb->context) { - PDEBUG(4, "no context"); - return; - } - - sbuf = urb->context; - ov = sbuf->ov; - - if (!ov || !ov->dev || !ov->user) { - PDEBUG(4, "no device, or not open"); - return; - } - - if (!ov->streaming) { - PDEBUG(4, "hmmm... not streaming, but got interrupt"); - return; - } - - if (urb->status == -ENOENT || urb->status == -ECONNRESET) { - PDEBUG(4, "URB unlinked"); - return; - } - - if (urb->status != -EINPROGRESS && urb->status != 0) { - err("ERROR: urb->status=%d: %s", urb->status, - symbolic(urb_errlist, urb->status)); - } - - /* Copy the data received into our frame buffer */ - PDEBUG(5, "sbuf[%d]: Moving %d packets", sbuf->n, - urb->number_of_packets); - for (i = 0; i < urb->number_of_packets; i++) { - /* Warning: Don't call *_move_data() if no frame active! */ - if (ov->curframe >= 0) { - int n = urb->iso_frame_desc[i].actual_length; - int st = urb->iso_frame_desc[i].status; - unsigned char *cdata; - - urb->iso_frame_desc[i].actual_length = 0; - urb->iso_frame_desc[i].status = 0; - - cdata = urb->transfer_buffer - + urb->iso_frame_desc[i].offset; - - if (!n) { - PDEBUG(4, "Zero-length packet"); - continue; - } - - if (st) - PDEBUG(2, "data error: [%d] len=%d, status=%d", - i, n, st); - - switch (ov->bclass) { - case BCL_OV511: - ov511_move_data(ov, cdata, n); - break; - case BCL_OV518: - ov518_move_data(ov, cdata, n); - break; - case BCL_OV519: - ov519_move_data(ov, cdata, n); - break; - default: - err("Unknown bridge device (%d)", ov->bridge); - } - } else if (waitqueue_active(&ov->wq)) { - wake_up_interruptible(&ov->wq); - } - } - - /* Resubmit this URB */ - urb->dev = ov->dev; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 4) - if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0) -#else - if ((i = usb_submit_urb(urb)) != 0) -#endif - err("usb_submit_urb() ret %d", i); - - return; -} - -/**************************************************************************** - * - * Stream initialization and termination - * - ***************************************************************************/ - -static int -ov51x_init_isoc(struct usb_ov511 *ov) -{ - struct urb *urb; - int fx, err, n, size; - - PDEBUG(3, "*** Initializing capture ***"); - - ov->curframe = -1; - - switch (ov->bridge) { - case BRG_OV511: - if (cams == 1) size = 993; - else if (cams == 2) size = 513; - else if (cams == 3 || cams == 4) size = 257; - else { - err("\"cams\" parameter too high!"); - return -1; - } - break; - case BRG_OV511PLUS: - if (cams == 1) size = 961; - else if (cams == 2) size = 513; - else if (cams == 3 || cams == 4) size = 257; - else if (cams >= 5 && cams <= 8) size = 129; - else if (cams >= 9 && cams <= 31) size = 33; - else { - err("\"cams\" parameter too high!"); - return -1; - } - break; - case BRG_OV518: - case BRG_OV518PLUS: - if (cams == 1) size = 896; - else if (cams == 2) size = 512; - else if (cams == 3 || cams == 4) size = 256; - else if (cams >= 5 && cams <= 8) size = 128; - else { - err("\"cams\" parameter too high!"); - return -1; - } - break; - case BRG_OV519: - if (cams == 1) size = 896; - else if (cams == 2) size = 512; - else { - err("\"cams\" parameter too high!"); - return -1; - } - break; - default: - err("invalid bridge type"); - return -1; - } - - // FIXME: OV518+ is hardcoded to 15 FPS (alternate 5) for now - if (ov->bridge == BRG_OV518PLUS) { - if (packetsize == -1) { - ov518_set_packet_size(ov, 640); - } else { - info("Forcing packet size to %d", packetsize); - ov518_set_packet_size(ov, packetsize); - } - } else if (ov->bridge == BRG_OV518) { - if (packetsize == -1) { - ov518_set_packet_size(ov, 896); - } else { - info("Forcing packet size to %d", packetsize); - ov518_set_packet_size(ov, packetsize); - } - } else if (ov->bridge == BRG_OV519) { - if (packetsize == -1) { - ov519_set_packet_size(ov, size); - } else { - info("Forcing packet size to %d", packetsize); - ov519_set_packet_size(ov, packetsize); - } - } else { - if (packetsize == -1) { - ov511_set_packet_size(ov, size); - } else { - info("Forcing packet size to %d", packetsize); - ov511_set_packet_size(ov, packetsize); - } - } - - for (n = 0; n < OV511_NUMSBUF; n++) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5) - urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); -#else - urb = usb_alloc_urb(FRAMES_PER_DESC); -#endif - if (!urb) { - err("init isoc: usb_alloc_urb ret. NULL"); - return -ENOMEM; - } - ov->sbuf[n].urb = urb; - urb->dev = ov->dev; - urb->context = &ov->sbuf[n]; - urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 45) - urb->transfer_flags = URB_ISO_ASAP; -#else - urb->transfer_flags = USB_ISO_ASAP; -#endif - urb->transfer_buffer = ov->sbuf[n].data; - urb->complete = ov51x_isoc_irq; - urb->number_of_packets = FRAMES_PER_DESC; - urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC; - urb->interval = 1; - for (fx = 0; fx < FRAMES_PER_DESC; fx++) { - urb->iso_frame_desc[fx].offset = ov->packet_size * fx; - urb->iso_frame_desc[fx].length = ov->packet_size; - } - } - - ov->streaming = 1; - - for (n = 0; n < OV511_NUMSBUF; n++) { - ov->sbuf[n].urb->dev = ov->dev; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 4) - err = usb_submit_urb(ov->sbuf[n].urb, GFP_KERNEL); -#else - err = usb_submit_urb(ov->sbuf[n].urb); -#endif - if (err) { - err("init isoc: usb_submit_urb(%d) ret %d", n, err); - return err; - } - } - - return 0; -} - -static void -ov51x_unlink_isoc(struct usb_ov511 *ov) -{ - int n; - - /* Unschedule all of the iso td's */ - for (n = OV511_NUMSBUF - 1; n >= 0; n--) { - if (ov->sbuf[n].urb) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) - usb_unlink_urb(ov->sbuf[n].urb); -#else - usb_kill_urb(ov->sbuf[n].urb); -#endif - usb_free_urb(ov->sbuf[n].urb); - ov->sbuf[n].urb = NULL; - } - } -} - -static void -ov51x_stop_isoc(struct usb_ov511 *ov) -{ - if (!ov->streaming || !ov->dev) - return; - - PDEBUG(3, "*** Stopping capture ***"); - - switch (ov->bclass) { - case BCL_OV511: - ov511_set_packet_size(ov, 0); - break; - case BCL_OV518: - ov518_set_packet_size(ov, 0); - break; - case BCL_OV519: - ov519_set_packet_size(ov, 0); - break; - } - ov->streaming = 0; - - ov51x_unlink_isoc(ov); -} - -static int -ov51x_new_frame(struct usb_ov511 *ov, int framenum) -{ - struct ov511_frame *frame; - int newnum; - - PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum); - - if (!ov->dev) - return -1; - - /* If we're not grabbing a frame right now and the other frame is */ - /* ready to be grabbed into, then use it instead */ - if (ov->curframe == -1) { - newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES; - if (ov->frame[newnum].grabstate == FRAME_READY) - framenum = newnum; - } else - return 0; - - frame = &ov->frame[framenum]; - - PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum, - frame->width, frame->height); - - frame->grabstate = FRAME_GRABBING; - frame->scanstate = STATE_SCANNING; - frame->snapshot = 0; - - ov->curframe = framenum; - - /* Make sure it's not too big */ - if (frame->width > ov->maxwidth) - frame->width = ov->maxwidth; - - frame->width &= ~7L; /* Multiple of 8 */ - - if (frame->height > ov->maxheight) - frame->height = ov->maxheight; - - frame->height &= ~3L; /* Multiple of 4 */ - - return 0; -} - -/**************************************************************************** - * - * Buffer management - * - ***************************************************************************/ - -/* - * - You must acquire buf_lock before entering this function. - * - Because this code will free any non-null pointer, you must be sure to null - * them if you explicitly free them somewhere else! - */ -static void -ov51x_do_dealloc(struct usb_ov511 *ov) -{ - int i; - PDEBUG(4, "entered"); - - if (ov->fbuf) { - rvfree(ov->fbuf, OV511_NUMFRAMES - * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)); - ov->fbuf = NULL; - } - - vfree(ov->rawfbuf); - ov->rawfbuf = NULL; - - vfree(ov->tempfbuf); - ov->tempfbuf = NULL; - - for (i = 0; i < OV511_NUMSBUF; i++) { - kfree(ov->sbuf[i].data); - ov->sbuf[i].data = NULL; - } - - for (i = 0; i < OV511_NUMFRAMES; i++) { - ov->frame[i].data = NULL; - ov->frame[i].rawdata = NULL; - ov->frame[i].tempdata = NULL; - if (ov->frame[i].compbuf) { - free_page((unsigned long) ov->frame[i].compbuf); - ov->frame[i].compbuf = NULL; - } - } - - PDEBUG(4, "buffer memory deallocated"); - ov->buf_state = BUF_NOT_ALLOCATED; - PDEBUG(4, "leaving"); -} - -static int -ov51x_alloc(struct usb_ov511 *ov) -{ - int i; - const int w = ov->maxwidth; - const int h = ov->maxheight; - const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h); - const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h); - - PDEBUG(4, "entered"); - down(&ov->buf_lock); - - if (ov->buf_state == BUF_ALLOCATED) - goto out; - - ov->fbuf = rvmalloc(data_bufsize); - if (!ov->fbuf) - goto error; - - ov->rawfbuf = vmalloc(raw_bufsize); - if (!ov->rawfbuf) - goto error; - - memset(ov->rawfbuf, 0, raw_bufsize); - - ov->tempfbuf = vmalloc(raw_bufsize); - if (!ov->tempfbuf) - goto error; - - memset(ov->tempfbuf, 0, raw_bufsize); - - for (i = 0; i < OV511_NUMSBUF; i++) { - ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC * - MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL); - if (!ov->sbuf[i].data) - goto error; - - PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data); - } - - for (i = 0; i < OV511_NUMFRAMES; i++) { - ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h); - ov->frame[i].rawdata = ov->rawfbuf - + i * MAX_RAW_DATA_SIZE(w, h); - ov->frame[i].tempdata = ov->tempfbuf - + i * MAX_RAW_DATA_SIZE(w, h); - - ov->frame[i].compbuf = - (unsigned char *) __get_free_page(GFP_KERNEL); - if (!ov->frame[i].compbuf) - goto error; - - PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data); - } - - ov->buf_state = BUF_ALLOCATED; -out: - up(&ov->buf_lock); - PDEBUG(4, "leaving"); - return 0; -error: - ov51x_do_dealloc(ov); - up(&ov->buf_lock); - PDEBUG(4, "errored"); - return -ENOMEM; -} - -static void -ov51x_dealloc(struct usb_ov511 *ov) -{ - PDEBUG(4, "entered"); - down(&ov->buf_lock); - ov51x_do_dealloc(ov); - up(&ov->buf_lock); - PDEBUG(4, "leaving"); -} - -/**************************************************************************** - * - * V4L 1 API - * - ***************************************************************************/ - -#ifdef OV511_OLD_V4L -static int -ov51x_v4l1_open(struct video_device *vdev, int flags) -{ -#else -static int -ov51x_v4l1_open(struct inode *inode, struct file *file) -{ - struct video_device *vdev = video_devdata(file); -#endif - struct usb_ov511 *ov = video_get_drvdata(vdev); - int err, i; - -/* 2.2.x needs explicit module-locking */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17) - MOD_INC_USE_COUNT; -#endif - - PDEBUG(4, "opening"); - - down(&ov->lock); - - err = -EBUSY; - if (ov->user) - goto out; - - ov->sub_flag = 0; - - /* In case app doesn't set them... */ - err = ov51x_set_default_params(ov); - if (err < 0) - goto out; - - /* Make sure frames are reset */ - for (i = 0; i < OV511_NUMFRAMES; i++) { - ov->frame[i].grabstate = FRAME_UNUSED; - ov->frame[i].bytes_read = 0; - } - - /* If compression is on, make sure now that a - * decompressor can be loaded */ - if (ov->compress && !ov->decomp_ops) { - err = request_decompressor(ov); - if (err && !dumppix) - goto out; - } - - err = ov51x_alloc(ov); - if (err < 0) - goto out; - - err = ov51x_init_isoc(ov); - if (err) { - ov51x_dealloc(ov); - goto out; - } - - ov->user++; -// If using _NEW_ V4L... -#if !defined(OV511_OLD_V4L) - file->private_data = vdev; -#endif - - if (ov->led_policy == LED_AUTO) - ov51x_led_control(ov, 1); - -out: - up(&ov->lock); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17) - if (err) - MOD_DEC_USE_COUNT; -#endif - - return err; -} - -#ifdef OV511_OLD_V4L -static void -ov51x_v4l1_close(struct video_device *vdev) -{ -#else -static int -ov51x_v4l1_close(struct inode *inode, struct file *file) -{ - struct video_device *vdev = file->private_data; -#endif - struct usb_ov511 *ov = video_get_drvdata(vdev); - - PDEBUG(4, "ov511_close"); - - down(&ov->lock); - - ov->user--; - ov51x_stop_isoc(ov); - - release_decompressor(ov); - - if (ov->led_policy == LED_AUTO) - ov51x_led_control(ov, 0); - - if (ov->dev) - ov51x_dealloc(ov); - - up(&ov->lock); - - /* Device unplugged while open. Only a minimum of unregistration is done - * here; the disconnect callback already did the rest. */ - if (!ov->dev) { - down(&ov->cbuf_lock); - kfree(ov->cbuf); - ov->cbuf = NULL; - up(&ov->cbuf_lock); - - ov51x_dealloc(ov); -#ifdef OV511_OLD_V4L - video_unregister_device(&ov->vdev); -#endif - kfree(ov); - ov = NULL; - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 17) - MOD_DEC_USE_COUNT; -#endif - -#ifdef OV511_OLD_V4L - return; -#else - file->private_data = NULL; - return 0; -#endif -} - -/* Do not call this function directly! */ -static int -#ifdef OV511_OLD_V4L -ov51x_v4l1_ioctl_internal(struct usb_ov511 *ov, unsigned int cmd, - void *arg) -{ -#else -ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct video_device *vdev = file->private_data; - struct usb_ov511 *ov = video_get_drvdata(vdev); -#endif - PDEBUG(5, "IOCtl: 0x%X", cmd); - - if (!ov->dev) - return -EIO; - - switch (cmd) { - case VIDIOCGCAP: - { - struct video_capability *b = arg; - - PDEBUG(4, "VIDIOCGCAP"); - - memset(b, 0, sizeof(struct video_capability)); - sprintf(b->name, "%s USB Camera", - symbolic(brglist, ov->bridge)); - b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE; - b->channels = ov->num_inputs; - b->audios = 0; - b->maxwidth = ov->maxwidth; - b->maxheight = ov->maxheight; - b->minwidth = ov->minwidth; - b->minheight = ov->minheight; - - return 0; - } - case VIDIOCGCHAN: - { - struct video_channel *v = arg; - - PDEBUG(4, "VIDIOCGCHAN"); - - if ((unsigned)(v->channel) >= ov->num_inputs) { - err("Invalid channel (%d)", v->channel); - return -EINVAL; - } - - v->norm = ov->norm; - v->type = VIDEO_TYPE_CAMERA; - v->flags = 0; -// v->flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0; - v->tuners = 0; - decoder_get_input_name(ov, v->channel, v->name); - - return 0; - } - case VIDIOCSCHAN: - { - struct video_channel *v = arg; - int err; - - PDEBUG(4, "VIDIOCSCHAN"); - - /* Make sure it's not a camera */ - if (!ov->has_decoder) { - if (v->channel == 0) - return 0; - else - return -EINVAL; - } - - if (v->norm != VIDEO_MODE_PAL && - v->norm != VIDEO_MODE_NTSC && - v->norm != VIDEO_MODE_SECAM && - v->norm != VIDEO_MODE_AUTO) { - err("Invalid norm (%d)", v->norm); - return -EINVAL; - } - - if ((unsigned)(v->channel) >= ov->num_inputs) { - err("Invalid channel (%d)", v->channel); - return -EINVAL; - } - - err = decoder_set_input(ov, v->channel); - if (err) - return err; - - err = decoder_set_norm(ov, v->norm); - if (err) - return err; - - return 0; - } - case VIDIOCGPICT: - { - struct video_picture *p = arg; - - PDEBUG(4, "VIDIOCGPICT"); - - memset(p, 0, sizeof(struct video_picture)); - if (sensor_get_picture(ov, p)) - return -EIO; - - /* Can we get these from frame[0]? -claudio? */ - p->depth = ov->frame[0].depth; - p->palette = ov->frame[0].format; - - return 0; - } - case VIDIOCSPICT: - { - struct video_picture *p = arg; - int i, rc; - - PDEBUG(4, "VIDIOCSPICT"); - - if (!get_depth(p->palette)) - return -EINVAL; - - if (sensor_set_picture(ov, p)) - return -EIO; - - if (force_palette && p->palette != force_palette) { - info("Palette rejected (%s)", - symbolic(v4l1_plist, p->palette)); - return -EINVAL; - } - - // FIXME: Format should be independent of frames - if (p->palette != ov->frame[0].format) { - PDEBUG(4, "Detected format change"); - - rc = ov51x_wait_frames_inactive(ov); - if (rc) - return rc; - - mode_init_regs(ov, ov->frame[0].width, - ov->frame[0].height, p->palette, ov->sub_flag); - } - - PDEBUG(4, "Setting depth=%d, palette=%s", - p->depth, symbolic(v4l1_plist, p->palette)); - - for (i = 0; i < OV511_NUMFRAMES; i++) { - ov->frame[i].depth = p->depth; - ov->frame[i].format = p->palette; - } - - return 0; - } - case VIDIOCGCAPTURE: - { - int *vf = arg; - - PDEBUG(4, "VIDIOCGCAPTURE"); - - ov->sub_flag = *vf; - return 0; - } - case VIDIOCSCAPTURE: - { - struct video_capture *vc = arg; - - PDEBUG(4, "VIDIOCSCAPTURE"); - - if (vc->flags) - return -EINVAL; - if (vc->decimation) - return -EINVAL; - - vc->x &= ~3L; - vc->y &= ~1L; - vc->y &= ~31L; - - if (vc->width == 0) - vc->width = 32; - - vc->height /= 16; - vc->height *= 16; - if (vc->height == 0) - vc->height = 16; - - ov->subx = vc->x; - ov->suby = vc->y; - ov->subw = vc->width; - ov->subh = vc->height; - - return 0; - } - case VIDIOCSWIN: - { - struct video_window *vw = arg; - int i, rc; - - PDEBUG(4, "VIDIOCSWIN: %dx%d", vw->width, vw->height); - -#if 0 - if (vw->flags) - return -EINVAL; - if (vw->clipcount) - return -EINVAL; - if (vw->height != ov->maxheight) - return -EINVAL; - if (vw->width != ov->maxwidth) - return -EINVAL; -#endif - - rc = ov51x_wait_frames_inactive(ov); - if (rc) - return rc; - - rc = mode_init_regs(ov, vw->width, vw->height, - ov->frame[0].format, ov->sub_flag); - if (rc < 0) - return rc; - - for (i = 0; i < OV511_NUMFRAMES; i++) { - ov->frame[i].width = vw->width; - ov->frame[i].height = vw->height; - } - - return 0; - } - case VIDIOCGWIN: - { - struct video_window *vw = arg; - - memset(vw, 0, sizeof(struct video_window)); - vw->x = 0; /* FIXME */ - vw->y = 0; - vw->width = ov->frame[0].width; - vw->height = ov->frame[0].height; - vw->flags = 30; - - PDEBUG(4, "VIDIOCGWIN: %dx%d", vw->width, vw->height); - - return 0; - } - case VIDIOCGMBUF: - { - struct video_mbuf *vm = arg; - int i; - - PDEBUG(4, "VIDIOCGMBUF"); - - memset(vm, 0, sizeof(struct video_mbuf)); - vm->size = OV511_NUMFRAMES - * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight); - vm->frames = OV511_NUMFRAMES; - - vm->offsets[0] = 0; - for (i = 1; i < OV511_NUMFRAMES; i++) { - vm->offsets[i] = vm->offsets[i-1] - + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight); - } - - return 0; - } - case VIDIOCMCAPTURE: - { - struct video_mmap *vm = arg; - int rc, depth; - unsigned int f = vm->frame; - - PDEBUG(4, "VIDIOCMCAPTURE: frame: %d, %dx%d, %s", f, vm->width, - vm->height, symbolic(v4l1_plist, vm->format)); - - depth = get_depth(vm->format); - if (!depth) { - PDEBUG(2, "VIDIOCMCAPTURE: invalid format (%s)", - symbolic(v4l1_plist, vm->format)); - return -EINVAL; - } - - if (f >= OV511_NUMFRAMES) { - err("VIDIOCMCAPTURE: invalid frame (%d)", f); - return -EINVAL; - } - - if (vm->width > ov->maxwidth - || vm->height > ov->maxheight) { - err("VIDIOCMCAPTURE: requested dimensions too big"); - return -EINVAL; - } - - if (ov->frame[f].grabstate == FRAME_GRABBING) { - PDEBUG(4, "VIDIOCMCAPTURE: already grabbing"); - return -EBUSY; - } - - if (force_palette && (vm->format != force_palette)) { - PDEBUG(2, "palette rejected (%s)", - symbolic(v4l1_plist, vm->format)); - return -EINVAL; - } - - if ((ov->frame[f].width != vm->width) || - (ov->frame[f].height != vm->height) || - (ov->frame[f].format != vm->format) || - (ov->frame[f].sub_flag != ov->sub_flag) || - (ov->frame[f].depth != depth)) { - PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters"); - - rc = ov51x_wait_frames_inactive(ov); - if (rc) - return rc; - - rc = mode_init_regs(ov, vm->width, vm->height, - vm->format, ov->sub_flag); -#if 0 - if (rc < 0) { - PDEBUG(1, "Got error while initializing regs "); - return ret; - } -#endif - ov->frame[f].width = vm->width; - ov->frame[f].height = vm->height; - ov->frame[f].format = vm->format; - ov->frame[f].sub_flag = ov->sub_flag; - ov->frame[f].depth = depth; - } - - /* Mark it as ready */ - ov->frame[f].grabstate = FRAME_READY; - - PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", f); - - return ov51x_new_frame(ov, f); - } - case VIDIOCSYNC: - { - unsigned int fnum = *((unsigned int *) arg); - struct ov511_frame *frame; - int rc; - - if (fnum >= OV511_NUMFRAMES) { - err("VIDIOCSYNC: invalid frame (%d)", fnum); - return -EINVAL; - } - - frame = &ov->frame[fnum]; - - PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum, - frame->grabstate); - - switch (frame->grabstate) { - case FRAME_UNUSED: - return -EINVAL; - case FRAME_READY: - case FRAME_GRABBING: - case FRAME_ERROR: -redo: - if (!ov->dev) - return -EIO; - - rc = wait_event_interruptible(frame->wq, - (frame->grabstate == FRAME_DONE) - || (frame->grabstate == FRAME_ERROR)); - - if (rc) - return rc; - - if (frame->grabstate == FRAME_ERROR) { - if ((rc = ov51x_new_frame(ov, fnum)) < 0) - return rc; - goto redo; - } - /* Fall through */ - case FRAME_DONE: - if (ov->snap_enabled && !frame->snapshot) { - if ((rc = ov51x_new_frame(ov, fnum)) < 0) - return rc; - goto redo; - } - - frame->grabstate = FRAME_UNUSED; - - /* Reset the hardware snapshot button */ - /* FIXME - Is this the best place for this? */ - if ((ov->snap_enabled) && (frame->snapshot)) { - frame->snapshot = 0; - ov51x_clear_snapshot(ov); - } - - /* Decompression, format conversion, etc... */ - if (ov->bclass != BCL_OV519) { - ov51x_postprocess(ov, frame); - } - - break; - } /* end switch */ - - return 0; - } - case VIDIOCGFBUF: - { - struct video_buffer *vb = arg; - - PDEBUG(4, "VIDIOCGFBUF"); - - memset(vb, 0, sizeof(struct video_buffer)); - - return 0; - } - case VIDIOCGUNIT: - { - struct video_unit *vu = arg; - - PDEBUG(4, "VIDIOCGUNIT"); - - memset(vu, 0, sizeof(struct video_unit)); - - vu->video = ov->vdev->minor; - vu->vbi = VIDEO_NO_UNIT; - vu->radio = VIDEO_NO_UNIT; - vu->audio = VIDEO_NO_UNIT; - vu->teletext = VIDEO_NO_UNIT; - - return 0; - } - case OV511IOC_WI2C: - { - struct ov511_i2c_struct *w = arg; - - return i2c_w_slave(ov, w->slave, w->reg, w->value, w->mask); - } - case OV511IOC_RI2C: - { - struct ov511_i2c_struct *r = arg; - int rc; - - rc = i2c_r_slave(ov, r->slave, r->reg); - if (rc < 0) - return rc; - - r->value = rc; - return 0; - } - default: - PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd); - return -ENOIOCTLCMD; - } /* end switch */ - - return 0; -} - -#ifdef OV511_OLD_V4L -/* This is implemented as video_generic_ioctl() in the new V4L's videodev.c */ -static int -ov51x_v4l1_generic_ioctl(struct video_device *vdev, unsigned int cmd, void *arg) -{ - char sbuf[128]; - void *mbuf = NULL; - void *parg = NULL; - int err = -EINVAL; - - /* Copy arguments into temp kernel buffer */ - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: - parg = arg; - break; - case _IOC_READ: /* some v4l ioctls are marked wrong ... */ - case _IOC_WRITE: - case (_IOC_WRITE | _IOC_READ): - if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { - parg = sbuf; - } else { - /* too big to allocate from stack */ - mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); - if (NULL == mbuf) - return -ENOMEM; - parg = mbuf; - } - - err = -EFAULT; - if (copy_from_user(parg, arg, _IOC_SIZE(cmd))) - goto out; - break; - } - - err = ov51x_v4l1_ioctl_internal(vdev->priv, cmd, parg); - if (err == -ENOIOCTLCMD) - err = -EINVAL; - if (err < 0) - goto out; - - /* Copy results into user buffer */ - switch (_IOC_DIR(cmd)) - { - case _IOC_READ: - case (_IOC_WRITE | _IOC_READ): - if (copy_to_user(arg, parg, _IOC_SIZE(cmd))) - err = -EFAULT; - break; - } - -out: - if (mbuf) - kfree(mbuf); - return err; -} - -static int -ov51x_v4l1_ioctl(struct video_device *vdev, unsigned int cmd, void *arg) -{ - struct usb_ov511 *ov = vdev->priv; - int rc; - - if (down_interruptible(&ov->lock)) - return -EINTR; - - rc = ov51x_v4l1_generic_ioctl(vdev, cmd, arg); - - up(&ov->lock); - return rc; -} - -#else /* If new V4L API */ - -static int -ov51x_v4l1_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct video_device *vdev = file->private_data; - struct usb_ov511 *ov = video_get_drvdata(vdev); - int rc; - - if (down_interruptible(&ov->lock)) - return -EINTR; - - rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal); - - up(&ov->lock); - return rc; -} -#endif /* OV511_OLD_V4L */ - -#ifdef OV511_OLD_V4L -static long -ov51x_v4l1_read(struct video_device *vdev, char *buf, unsigned long count, - int noblock) -{ -#else -static ssize_t -ov51x_v4l1_read(struct file *file, char *buf, size_t cnt, loff_t *ppos) -{ - struct video_device *vdev = file->private_data; - int noblock = file->f_flags&O_NONBLOCK; - unsigned long count = cnt; -#endif - struct usb_ov511 *ov = video_get_drvdata(vdev); - int i, rc = 0, frmx = -1; - struct ov511_frame *frame; - - if (down_interruptible(&ov->lock)) - return -EINTR; - - PDEBUG(4, "%ld bytes, noblock=%d", count, noblock); - - if (!vdev || !buf) { - rc = -EFAULT; - goto error; - } - - if (!ov->dev) { - rc = -EIO; - goto error; - } - -// FIXME: Only supports two frames - /* See if a frame is completed, then use it. */ - if (ov->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */ - frmx = 0; - else if (ov->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */ - frmx = 1; - - /* If nonblocking we return immediately */ - if (noblock && (frmx == -1)) { - rc = -EAGAIN; - goto error; - } - - /* If no FRAME_DONE, look for a FRAME_GRABBING state. */ - /* See if a frame is in process (grabbing), then use it. */ - if (frmx == -1) { - if (ov->frame[0].grabstate == FRAME_GRABBING) - frmx = 0; - else if (ov->frame[1].grabstate == FRAME_GRABBING) - frmx = 1; - } - - /* If no frame is active, start one. */ - if (frmx == -1) { - if ((rc = ov51x_new_frame(ov, frmx = 0))) { - err("read: ov51x_new_frame error"); - goto error; - } - } - - frame = &ov->frame[frmx]; - -restart: - if (!ov->dev) { - rc = -EIO; - goto error; - } - - /* Wait while we're grabbing the image */ - PDEBUG(4, "Waiting image grabbing"); - rc = wait_event_interruptible(frame->wq, - (frame->grabstate == FRAME_DONE) - || (frame->grabstate == FRAME_ERROR)); - - if (rc) - goto error; - - PDEBUG(4, "Got image, frame->grabstate = %d", frame->grabstate); - PDEBUG(4, "bytes_recvd = %d", frame->bytes_recvd); - - if (frame->grabstate == FRAME_ERROR) { - frame->bytes_read = 0; - err("** ick! ** Errored frame %d", ov->curframe); - if (ov51x_new_frame(ov, frmx)) { - err("read: ov51x_new_frame error"); - goto error; - } - goto restart; - } - - - /* Repeat until we get a snapshot frame */ - if (ov->snap_enabled) - PDEBUG(4, "Waiting snapshot frame"); - if (ov->snap_enabled && !frame->snapshot) { - frame->bytes_read = 0; - if ((rc = ov51x_new_frame(ov, frmx))) { - err("read: ov51x_new_frame error"); - goto error; - } - goto restart; - } - - /* Clear the snapshot */ - if (ov->snap_enabled && frame->snapshot) { - frame->snapshot = 0; - ov51x_clear_snapshot(ov); - } - - /* Decompression, format conversion, etc... */ - if (ov->bclass != BCL_OV519) { - ov51x_postprocess(ov, frame); - } - - PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx, - frame->bytes_read, - get_frame_length(ov, frame)); - - /* copy bytes to user space; we allow for partials reads */ - if ((count + frame->bytes_read) > get_frame_length(ov, (struct ov511_frame *)frame)) { - count = frame->bytes_recvd - frame->bytes_read; - PDEBUG(4, "set count to %d", (int)count); - } - - /* FIXME - count hardwired to be one frame... */ - //count = get_frame_length(ov, frame); - - PDEBUG(4, "Copy to user space: %ld bytes", count); - if ((i = copy_to_user(buf, frame->data + frame->bytes_read, count))) { - PDEBUG(4, "Copy failed! %d bytes not copied", i); - rc = -EFAULT; - goto error; - } - - frame->bytes_read += count; - PDEBUG(4, "{copy} count used=%ld, new bytes_read=%ld", - count, frame->bytes_read); - - /* If all data have been read... */ - if (frame->bytes_read >= get_frame_length(ov, frame)) { - frame->bytes_read = 0; - -// FIXME: Only supports two frames - /* Mark it as available to be used again. */ - ov->frame[frmx].grabstate = FRAME_UNUSED; - if ((rc = ov51x_new_frame(ov, !frmx))) { - err("ov51x_new_frame returned error"); - goto error; - } - } - - PDEBUG(4, "read finished, returning %ld (sweet)", count); - - up(&ov->lock); - return count; - -error: - up(&ov->lock); - return rc; -} - -static int -#ifdef OV511_OLD_V4L - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 3) -ov51x_v4l1_mmap(struct vm_area_struct *vma, struct video_device *vdev, - const char *adr, unsigned long size) - #else -ov51x_v4l1_mmap(struct video_device *vdev, const char *adr, unsigned long size) - #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 3) */ -{ - unsigned long start = (unsigned long)adr; - -#else /* New V4L API */ - -ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct video_device *vdev = file->private_data; - unsigned long start = vma->vm_start; - unsigned long size = vma->vm_end - vma->vm_start; -#endif /* OV511_OLD_V4L */ - - struct usb_ov511 *ov = video_get_drvdata(vdev); - unsigned long page, pos; - - if (ov->dev == NULL) - return -EIO; - - PDEBUG(4, "mmap: %ld (%lX) bytes", size, size); - - if (size > (((OV511_NUMFRAMES - * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight) - + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))) - return -EINVAL; - - if (down_interruptible(&ov->lock)) - return -EINTR; - - pos = (unsigned long)ov->fbuf; - while (size > 0) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10) - page = vmalloc_to_pfn((void *)pos); - if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 3) || defined(RH9_REMAP) - page = kvirt_to_pa(pos); - if (remap_page_range(vma, start, page, PAGE_SIZE, - PAGE_SHARED)) { -#else - page = kvirt_to_pa(pos); - if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) { -#endif - up(&ov->lock); - return -EAGAIN; - } - start += PAGE_SIZE; - pos += PAGE_SIZE; - if (size > PAGE_SIZE) - size -= PAGE_SIZE; - else - size = 0; - } - - up(&ov->lock); - return 0; -} - -#ifdef OV511_OLD_V4L -static struct video_device vdev_template = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 17) - .owner = THIS_MODULE, -#endif - .name = "OV511 USB Camera", - .type = VID_TYPE_CAPTURE, - .hardware = VID_HARDWARE_OV511, - .open = ov51x_v4l1_open, - .close = ov51x_v4l1_close, - .read = ov51x_v4l1_read, - .ioctl = ov51x_v4l1_ioctl, - .mmap = ov51x_v4l1_mmap, -}; - -#else /* New V4L API */ - -static struct file_operations ov511_fops = { - .owner = THIS_MODULE, - .open = ov51x_v4l1_open, - .release = ov51x_v4l1_close, - .read = ov51x_v4l1_read, - .mmap = ov51x_v4l1_mmap, - .ioctl = ov51x_v4l1_ioctl, - .llseek = no_llseek, -}; - -static struct video_device vdev_template = { - .owner = THIS_MODULE, - .name = "OV51x USB Camera", - .type = VID_TYPE_CAPTURE, - .hardware = VID_HARDWARE_OV511, - .fops = &ov511_fops, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - .release = video_device_release, -#endif - .minor = -1, -}; -#endif /* OV511_OLD_V4L */ - -#if defined(CONFIG_VIDEO_PROC_FS) -static int -ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, - unsigned long ularg) -{ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 5) - struct proc_dir_entry *pde = PDE(inode); -#else - struct proc_dir_entry *pde = inode->u.generic_ip; -#endif - struct usb_ov511 *ov; - void *arg = (void *) ularg; - int rc; - - if (!pde) - return -ENOENT; - - ov = pde->data; - if (!ov) - return -ENODEV; - - if (!ov->dev) - return -EIO; - - /* Should we pass through standard V4L IOCTLs? */ - - switch (cmd) { - case OV511IOC_GINTVER: - { - return OV511_INTERFACE_VER; - } - case OV511IOC_GUSHORT: - { - struct ov511_ushort_opt opt; - - if (copy_from_user(&opt, arg, sizeof(opt))) - return -EFAULT; - - switch (opt.optnum) { - case OV511_USOPT_BRIGHT: - rc = sensor_get_brightness(ov, &(opt.val)); - if (rc) return rc; - break; - case OV511_USOPT_SAT: - rc = sensor_get_saturation(ov, &(opt.val)); - if (rc) return rc; - break; - case OV511_USOPT_HUE: - rc = sensor_get_hue(ov, &(opt.val)); - if (rc) return rc; - break; - case OV511_USOPT_CONTRAST: - rc = sensor_get_contrast(ov, &(opt.val)); - if (rc) return rc; - break; - default: - err("Invalid get short option number"); - return -EINVAL; - } - - if (copy_to_user(arg, &opt, sizeof(opt))) - return -EFAULT; - - return 0; - } - case OV511IOC_SUSHORT: - { - struct ov511_ushort_opt opt; - - if (copy_from_user(&opt, arg, sizeof(opt))) - return -EFAULT; - - switch (opt.optnum) { - case OV511_USOPT_BRIGHT: - rc = sensor_set_brightness(ov, opt.val); - if (rc) return rc; - break; - case OV511_USOPT_SAT: - rc = sensor_set_saturation(ov, opt.val); - if (rc) return rc; - break; - case OV511_USOPT_HUE: - rc = sensor_set_hue(ov, opt.val); - if (rc) return rc; - break; - case OV511_USOPT_CONTRAST: - rc = sensor_set_contrast(ov, opt.val); - if (rc) return rc; - break; - default: - err("Invalid set short option number"); - return -EINVAL; - } - - return 0; - } - case OV511IOC_GUINT: - { - struct ov511_uint_opt opt; - - if (copy_from_user(&opt, arg, sizeof(opt))) - return -EFAULT; - - switch (opt.optnum) { - case OV511_UIOPT_POWER_FREQ: - opt.val = ov->lightfreq; - break; - case OV511_UIOPT_BFILTER: - opt.val = ov->bandfilt; - break; - case OV511_UIOPT_LED: - opt.val = ov->led_policy; - break; - case OV511_UIOPT_LED2: - opt.val = ov->led2_policy; - break; - case OV511_UIOPT_DEBUG: - opt.val = debug; - break; - case OV511_UIOPT_COMPRESS: - opt.val = ov->compress; - break; - default: - err("Invalid get int option number"); - return -EINVAL; - } - - if (copy_to_user(arg, &opt, sizeof(opt))) - return -EFAULT; - - return 0; - } - case OV511IOC_SUINT: - { - struct ov511_uint_opt opt; - - if (copy_from_user(&opt, arg, sizeof(opt))) - return -EFAULT; - - switch (opt.optnum) { - case OV511_UIOPT_POWER_FREQ: - rc = sensor_set_light_freq(ov, opt.val); - if (rc) return rc; - break; - case OV511_UIOPT_BFILTER: - rc = sensor_set_banding_filter(ov, opt.val); - if (rc) return rc; - break; - case OV511_UIOPT_LED: - if (opt.val <= 2) { - ov->led_policy = opt.val; - if (ov->led_policy == LED_OFF) - ov51x_led_control(ov, 0); - else if (ov->led_policy == LED_ON) - ov51x_led_control(ov, 1); - } else { - return -EINVAL; - } - break; - case OV511_UIOPT_LED2: - if (opt.val <= 2) { - ov->led2_policy = opt.val; - if (ov->led2_policy == LED_OFF) - ov51x_led_control(ov, 0); - else if (ov->led2_policy == LED_ON) - ov51x_led_control(ov, 1); - } else { - return -EINVAL; - } - break; - case OV511_UIOPT_DEBUG: - if (opt.val <= 5) - debug = opt.val; - else - return -EINVAL; - break; - case OV511_UIOPT_COMPRESS: - ov->compress = opt.val; - if (ov->compress) { - if (ov->bclass == BCL_OV511) - ov511_init_compression(ov); - else if (ov->bclass == BCL_OV518) - ov518_init_compression(ov); - else if (ov->bclass == BCL_OV519) - ov519_init_compression(ov); - } - break; - default: - err("Invalid get int option number"); - return -EINVAL; - } - - return 0; - } - case OV511IOC_WI2C: - { - struct ov511_i2c_struct w; - - if (copy_from_user(&w, arg, sizeof(w))) - return -EFAULT; - - return i2c_w_slave(ov, w.slave, w.reg, w.value, w.mask); - } - case OV511IOC_RI2C: - { - struct ov511_i2c_struct r; - - if (copy_from_user(&r, arg, sizeof(r))) - return -EFAULT; - - rc = i2c_r_slave(ov, r.slave, r.reg); - if (rc < 0) - return rc; - - r.value = rc; - - if (copy_to_user(arg, &r, sizeof(r))) - return -EFAULT; - - return 0; - } - default: - return -EINVAL; - } - - return 0; -} -#endif - -/**************************************************************************** - * - * OV511 and sensor configuration - * - ***************************************************************************/ - -/* This initializes the OV8110, OV8610 sensor. The OV8110 uses - * the same register settings as the OV8610, since they are very similar. - */ -static int -ov8xx0_configure(struct usb_ov511 *ov) -{ - int rc; - - static struct ov511_regvals regvals_norm_8610[] = { - { OV511_I2C_BUS, 0x12, 0x80 }, - { OV511_I2C_BUS, 0x00, 0x00 }, - { OV511_I2C_BUS, 0x01, 0x80 }, - { OV511_I2C_BUS, 0x02, 0x80 }, - { OV511_I2C_BUS, 0x03, 0xc0 }, - { OV511_I2C_BUS, 0x04, 0x30 }, - { OV511_I2C_BUS, 0x05, 0x30 }, /* was 0x10, new from windrv 090403 */ - { OV511_I2C_BUS, 0x06, 0x70 }, /* was 0x80, new from windrv 090403 */ - { OV511_I2C_BUS, 0x0a, 0x86 }, - { OV511_I2C_BUS, 0x0b, 0xb0 }, - { OV511_I2C_BUS, 0x0c, 0x20 }, - { OV511_I2C_BUS, 0x0d, 0x20 }, - { OV511_I2C_BUS, 0x11, 0x01 }, - { OV511_I2C_BUS, 0x12, 0x25 }, - { OV511_I2C_BUS, 0x13, 0x01 }, - { OV511_I2C_BUS, 0x14, 0x04 }, - { OV511_I2C_BUS, 0x15, 0x01 }, /* Lin and Win think different about UV order */ - { OV511_I2C_BUS, 0x16, 0x03 }, - { OV511_I2C_BUS, 0x17, 0x38 }, /* was 0x2f, new from windrv 090403 */ - { OV511_I2C_BUS, 0x18, 0xea }, /* was 0xcf, new from windrv 090403 */ - { OV511_I2C_BUS, 0x19, 0x02 }, /* was 0x06, new from windrv 090403 */ - { OV511_I2C_BUS, 0x1a, 0xf5 }, - { OV511_I2C_BUS, 0x1b, 0x00 }, - { OV511_I2C_BUS, 0x20, 0xd0 }, /* was 0x90, new from windrv 090403 */ - { OV511_I2C_BUS, 0x23, 0xc0 }, /* was 0x00, new from windrv 090403 */ - { OV511_I2C_BUS, 0x24, 0x30 }, /* was 0x1d, new from windrv 090403 */ - { OV511_I2C_BUS, 0x25, 0x50 }, /* was 0x57, new from windrv 090403 */ - { OV511_I2C_BUS, 0x26, 0xa2 }, - { OV511_I2C_BUS, 0x27, 0xea }, - { OV511_I2C_BUS, 0x28, 0x00 }, - { OV511_I2C_BUS, 0x29, 0x00 }, - { OV511_I2C_BUS, 0x2a, 0x80 }, - { OV511_I2C_BUS, 0x2b, 0xc8 }, /* was 0xcc, new from windrv 090403 */ - { OV511_I2C_BUS, 0x2c, 0xac }, - { OV511_I2C_BUS, 0x2d, 0x45 }, /* was 0xd5, new from windrv 090403 */ - { OV511_I2C_BUS, 0x2e, 0x80 }, - { OV511_I2C_BUS, 0x2f, 0x14 }, /* was 0x01, new from windrv 090403 */ - { OV511_I2C_BUS, 0x4c, 0x00 }, - { OV511_I2C_BUS, 0x4d, 0x30 }, /* was 0x10, new from windrv 090403 */ - { OV511_I2C_BUS, 0x60, 0x02 }, /* was 0x01, new from windrv 090403 */ - { OV511_I2C_BUS, 0x61, 0x00 }, /* was 0x09, new from windrv 090403 */ - { OV511_I2C_BUS, 0x62, 0x5f }, /* was 0xd7, new from windrv 090403 */ - { OV511_I2C_BUS, 0x63, 0xff }, - { OV511_I2C_BUS, 0x64, 0x53 }, /* new windrv 090403 says 0x57, maybe thats wrong */ - { OV511_I2C_BUS, 0x65, 0x00 }, - { OV511_I2C_BUS, 0x66, 0x55 }, - { OV511_I2C_BUS, 0x67, 0xb0 }, - { OV511_I2C_BUS, 0x68, 0xc0 }, /* was 0xaf, new from windrv 090403 */ - { OV511_I2C_BUS, 0x69, 0x02 }, - { OV511_I2C_BUS, 0x6a, 0x22 }, - { OV511_I2C_BUS, 0x6b, 0x00 }, - { OV511_I2C_BUS, 0x6c, 0x99 }, /* was 0x80, old windrv says 0x00, but deleting bit7 colors the first images red */ - { OV511_I2C_BUS, 0x6d, 0x11 }, /* was 0x00, new from windrv 090403 */ - { OV511_I2C_BUS, 0x6e, 0x11 }, /* was 0x00, new from windrv 090403 */ - { OV511_I2C_BUS, 0x6f, 0x01 }, - { OV511_I2C_BUS, 0x70, 0x8b }, - { OV511_I2C_BUS, 0x71, 0x00 }, - { OV511_I2C_BUS, 0x72, 0x14 }, - { OV511_I2C_BUS, 0x73, 0x54 }, - { OV511_I2C_BUS, 0x74, 0x00 },//0x60? /* was 0x00, new from windrv 090403 */ - { OV511_I2C_BUS, 0x75, 0x0e }, - { OV511_I2C_BUS, 0x76, 0x02 }, /* was 0x02, new from windrv 090403 */ - { OV511_I2C_BUS, 0x77, 0xff }, - { OV511_I2C_BUS, 0x78, 0x80 }, - { OV511_I2C_BUS, 0x79, 0x80 }, - { OV511_I2C_BUS, 0x7a, 0x80 }, - { OV511_I2C_BUS, 0x7b, 0x10 }, /* was 0x13, new from windrv 090403 */ - { OV511_I2C_BUS, 0x7c, 0x00 }, - { OV511_I2C_BUS, 0x7d, 0x08 }, /* was 0x09, new from windrv 090403 */ - { OV511_I2C_BUS, 0x7e, 0x08 }, /* was 0xc0, new from windrv 090403 */ - { OV511_I2C_BUS, 0x7f, 0xfb }, - { OV511_I2C_BUS, 0x80, 0x28 }, - { OV511_I2C_BUS, 0x81, 0x00 }, - { OV511_I2C_BUS, 0x82, 0x23 }, - { OV511_I2C_BUS, 0x83, 0x0b }, - { OV511_I2C_BUS, 0x84, 0x00 }, - { OV511_I2C_BUS, 0x85, 0x62 }, /* was 0x61, new from windrv 090403 */ - { OV511_I2C_BUS, 0x86, 0xc9 }, - { OV511_I2C_BUS, 0x87, 0x00 }, - { OV511_I2C_BUS, 0x88, 0x00 }, - { OV511_I2C_BUS, 0x89, 0x01 }, - { OV511_I2C_BUS, 0x12, 0x20 }, - { OV511_I2C_BUS, 0x12, 0x25 }, /* was 0x24, new from windrv 090403 */ - { OV511_DONE_BUS, 0x0, 0x00 }, - }; - - PDEBUG(4, "starting configuration"); - - if (init_ov_sensor(ov) < 0) { - err("Failed to read sensor ID. You might not have an"); - err("OV8600/10, or it might not be responding. Report"); - err("this to sensor = SEN_OV8610; - } else { - err("Unknown image sensor version: %d", rc & 3); - return -1; - } - - PDEBUG(4, "Writing 8610 registers"); - if (write_regvals(ov, regvals_norm_8610)) - return -1; - - /* Set sensor-specific vars */ - ov->maxwidth = 800; - ov->maxheight = 600; - ov->minwidth = 64; - ov->minheight = 48; - - // FIXME: These do not match the actual settings yet - ov->brightness = 0x80 << 8; - ov->contrast = 0x80 << 8; - ov->colour = 0x80 << 8; - ov->hue = 0x80 << 8; - - return 0; -} - -/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses - * the same register settings as the OV7610, since they are very similar. - */ -static int -ov7xx0_configure(struct usb_ov511 *ov) -{ - int rc, high, low; - - /* Lawrence Glaister reports: - * - * Register 0x0f in the 7610 has the following effects: - * - * 0x85 (AEC method 1): Best overall, good contrast range - * 0x45 (AEC method 2): Very overexposed - * 0xa5 (spec sheet default): Ok, but the black level is - * shifted resulting in loss of contrast - * 0x05 (old driver setting): very overexposed, too much - * contrast - */ - static struct ov511_regvals regvals_norm_7610[] = { - { OV511_I2C_BUS, 0x10, 0xff }, - { OV511_I2C_BUS, 0x16, 0x06 }, - { OV511_I2C_BUS, 0x28, 0x24 }, - { OV511_I2C_BUS, 0x2b, 0xac }, - { OV511_I2C_BUS, 0x12, 0x00 }, - { OV511_I2C_BUS, 0x38, 0x81 }, - { OV511_I2C_BUS, 0x28, 0x24 }, /* 0c */ - { OV511_I2C_BUS, 0x0f, 0x85 }, /* lg's setting */ - { OV511_I2C_BUS, 0x15, 0x01 }, - { OV511_I2C_BUS, 0x20, 0x1c }, - { OV511_I2C_BUS, 0x23, 0x2a }, - { OV511_I2C_BUS, 0x24, 0x10 }, - { OV511_I2C_BUS, 0x25, 0x8a }, - { OV511_I2C_BUS, 0x26, 0xa2 }, - { OV511_I2C_BUS, 0x27, 0xc2 }, - { OV511_I2C_BUS, 0x2a, 0x04 }, - { OV511_I2C_BUS, 0x2c, 0xfe }, - { OV511_I2C_BUS, 0x2d, 0x93 }, - { OV511_I2C_BUS, 0x30, 0x71 }, - { OV511_I2C_BUS, 0x31, 0x60 }, - { OV511_I2C_BUS, 0x32, 0x26 }, - { OV511_I2C_BUS, 0x33, 0x20 }, - { OV511_I2C_BUS, 0x34, 0x48 }, - { OV511_I2C_BUS, 0x12, 0x24 }, - { OV511_I2C_BUS, 0x11, 0x01 }, - { OV511_I2C_BUS, 0x0c, 0x24 }, - { OV511_I2C_BUS, 0x0d, 0x24 }, - { OV511_DONE_BUS, 0x0, 0x00 }, - }; - - static struct ov511_regvals regvals_norm_7620[] = { - { OV511_I2C_BUS, 0x00, 0x00 }, - { OV511_I2C_BUS, 0x01, 0x80 }, - { OV511_I2C_BUS, 0x02, 0x80 }, - { OV511_I2C_BUS, 0x03, 0xc0 }, - { OV511_I2C_BUS, 0x06, 0x60 }, - { OV511_I2C_BUS, 0x07, 0x00 }, - { OV511_I2C_BUS, 0x0c, 0x24 }, - { OV511_I2C_BUS, 0x0c, 0x24 }, - { OV511_I2C_BUS, 0x0d, 0x24 }, - { OV511_I2C_BUS, 0x11, 0x01 }, - { OV511_I2C_BUS, 0x12, 0x24 }, - { OV511_I2C_BUS, 0x13, 0x01 }, - { OV511_I2C_BUS, 0x14, 0x84 }, - { OV511_I2C_BUS, 0x15, 0x01 }, - { OV511_I2C_BUS, 0x16, 0x03 }, - { OV511_I2C_BUS, 0x17, 0x2f }, - { OV511_I2C_BUS, 0x18, 0xcf }, - { OV511_I2C_BUS, 0x19, 0x06 }, - { OV511_I2C_BUS, 0x1a, 0xf5 }, - { OV511_I2C_BUS, 0x1b, 0x00 }, - { OV511_I2C_BUS, 0x20, 0x18 }, - { OV511_I2C_BUS, 0x21, 0x80 }, - { OV511_I2C_BUS, 0x22, 0x80 }, - { OV511_I2C_BUS, 0x23, 0x00 }, - { OV511_I2C_BUS, 0x26, 0xa2 }, - { OV511_I2C_BUS, 0x27, 0xea }, - { OV511_I2C_BUS, 0x28, 0x20 }, - { OV511_I2C_BUS, 0x29, 0x00 }, - { OV511_I2C_BUS, 0x2a, 0x10 }, - { OV511_I2C_BUS, 0x2b, 0x00 }, - { OV511_I2C_BUS, 0x2c, 0x88 }, - { OV511_I2C_BUS, 0x2d, 0x91 }, - { OV511_I2C_BUS, 0x2e, 0x80 }, - { OV511_I2C_BUS, 0x2f, 0x44 }, - { OV511_I2C_BUS, 0x60, 0x27 }, - { OV511_I2C_BUS, 0x61, 0x02 }, - { OV511_I2C_BUS, 0x62, 0x5f }, - { OV511_I2C_BUS, 0x63, 0xd5 }, - { OV511_I2C_BUS, 0x64, 0x57 }, - { OV511_I2C_BUS, 0x65, 0x83 }, - { OV511_I2C_BUS, 0x66, 0x55 }, - { OV511_I2C_BUS, 0x67, 0x92 }, - { OV511_I2C_BUS, 0x68, 0xcf }, - { OV511_I2C_BUS, 0x69, 0x76 }, - { OV511_I2C_BUS, 0x6a, 0x22 }, - { OV511_I2C_BUS, 0x6b, 0x00 }, - { OV511_I2C_BUS, 0x6c, 0x02 }, - { OV511_I2C_BUS, 0x6d, 0x44 }, - { OV511_I2C_BUS, 0x6e, 0x80 }, - { OV511_I2C_BUS, 0x6f, 0x1d }, - { OV511_I2C_BUS, 0x70, 0x8b }, - { OV511_I2C_BUS, 0x71, 0x00 }, - { OV511_I2C_BUS, 0x72, 0x14 }, - { OV511_I2C_BUS, 0x73, 0x54 }, - { OV511_I2C_BUS, 0x74, 0x00 }, - { OV511_I2C_BUS, 0x75, 0x8e }, - { OV511_I2C_BUS, 0x76, 0x00 }, - { OV511_I2C_BUS, 0x77, 0xff }, - { OV511_I2C_BUS, 0x78, 0x80 }, - { OV511_I2C_BUS, 0x79, 0x80 }, - { OV511_I2C_BUS, 0x7a, 0x80 }, - { OV511_I2C_BUS, 0x7b, 0xe2 }, - { OV511_I2C_BUS, 0x7c, 0x00 }, - { OV511_DONE_BUS, 0x0, 0x00 }, - }; - - /* 7640 and 7648. The defaults should be OK for most registers. */ - static struct ov511_regvals regvals_norm_7640[] = { - { OV511_I2C_BUS, 0x12, 0x80 }, - { OV511_I2C_BUS, 0x12, 0x14 }, - { OV511_DONE_BUS, 0x0, 0x00 }, - }; - - PDEBUG(4, "starting configuration"); - - if (init_ov_sensor(ov) < 0) { - err("Failed to read sensor ID. You might not have an"); - err("OV76xx, or it might not be responding. Report"); - err("this to " EMAIL); - err("This is only a warning. You can attempt to use"); - err("your camera anyway"); - } else { - PDEBUG(1, "OV7xx0 initialized"); - } - - /* Detect sensor (sub)type */ - rc = i2c_r(ov, OV7610_REG_COM_I); - - if (rc < 0) { - err("Error detecting sensor type"); - return -1; - } else if ((rc & 3) == 3) { - info("Sensor is an OV7610"); - ov->sensor = SEN_OV7610; - } else if ((rc & 3) == 1) { - /* I don't know what's different about the 76BE yet. */ - if (i2c_r(ov, 0x15) & 1) - info("Sensor is an OV7620AE"); - else - info("Sensor is an OV76BE"); - - /* OV511+ will return all zero isoc data unless we - * configure the sensor as a 7620. Someone needs to - * find the exact reg. setting that causes this. */ - if (ov->bridge == BRG_OV511PLUS) - ov->sensor = SEN_OV7620; - else - ov->sensor = SEN_OV76BE; - } else if ((rc & 3) == 0) { - /* try to read product id registers */ - high = i2c_r(ov, 0x0a); - if (high < 0) { - err("Error detecting camera chip PID"); - return high; - } - low = i2c_r(ov, 0x0b); - if (low < 0) { - err("Error detecting camera chip VER"); - return low; - } - if (high == 0x76) { - if (low == 0x30) { - info("Sensor is an OV7630/OV7635"); - ov->sensor = SEN_OV7630; - } - else if (low == 0x40) { - info("Sensor is an OV7645"); - ov->sensor = SEN_OV7640; // FIXME - } - else if (low == 0x45) { - info("Sensor is an OV7645B"); - ov->sensor = SEN_OV7640; // FIXME - } - else if (low == 0x48) { - info("Sensor is an OV7648"); - ov->sensor = SEN_OV7640; // FIXME - } - else { - err("Unknown sensor: 0x76%X", low); - return -1; - } - } else { - info("Sensor is an OV7620"); - ov->sensor = SEN_OV7620; - } - } else { - err("Unknown image sensor version: %d", rc & 3); - return -1; - } - - if (ov->sensor == SEN_OV7620) { - PDEBUG(4, "Writing 7620 registers"); - if (write_regvals(ov, regvals_norm_7620)) - return -1; - } else if (ov->sensor == SEN_OV7630) { - PDEBUG(4, "7630 is not supported by this driver version"); - return -1; - } else if (ov->sensor == SEN_OV7640) { - PDEBUG(4, "Writing 7640 registers"); - if (write_regvals(ov, regvals_norm_7640)) - return -1; - } else { - PDEBUG(4, "Writing 7610 registers"); - if (write_regvals(ov, regvals_norm_7610)) - return -1; - } - - /* Set sensor-specific vars */ - ov->maxwidth = 640; - ov->maxheight = 480; - ov->minwidth = 64; - ov->minheight = 48; - - // FIXME: These do not match the actual settings yet - ov->brightness = 0x80 << 8; - ov->contrast = 0x80 << 8; - ov->colour = 0x80 << 8; - ov->hue = 0x80 << 8; - - return 0; -} - -/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ -static int -ov6xx0_configure(struct usb_ov511 *ov) -{ - int rc; - - static struct ov511_regvals regvals_norm_6x20[] = { - { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */ - { OV511_I2C_BUS, 0x11, 0x01 }, - { OV511_I2C_BUS, 0x03, 0x60 }, - { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */ - { OV511_I2C_BUS, 0x07, 0xa8 }, - /* The ratio of 0x0c and 0x0d controls the white point */ - { OV511_I2C_BUS, 0x0c, 0x24 }, - { OV511_I2C_BUS, 0x0d, 0x24 }, - { OV511_I2C_BUS, 0x0f, 0x15 }, /* COMS */ - { OV511_I2C_BUS, 0x10, 0x75 }, /* AEC Exposure time */ - { OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC */ - { OV511_I2C_BUS, 0x14, 0x04 }, - /* 0x16: 0x06 helps frame stability with moving objects */ - { OV511_I2C_BUS, 0x16, 0x06 }, -// { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */ - { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */ - /* 0x28: 0x05 Selects RGB format if RGB on */ - { OV511_I2C_BUS, 0x28, 0x05 }, - { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */ -// { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */ - { OV511_I2C_BUS, 0x2d, 0x99 }, - { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Processing Parameter */ - { OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */ - { OV511_I2C_BUS, 0x38, 0x8b }, - { OV511_I2C_BUS, 0x39, 0x40 }, - - { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */ - { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */ - { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */ - - { OV511_I2C_BUS, 0x3d, 0x80 }, - /* These next two registers (0x4a, 0x4b) are undocumented. They - * control the color balance */ - { OV511_I2C_BUS, 0x4a, 0x80 }, - { OV511_I2C_BUS, 0x4b, 0x80 }, - { OV511_I2C_BUS, 0x4d, 0xd2 }, /* This reduces noise a bit */ - { OV511_I2C_BUS, 0x4e, 0xc1 }, - { OV511_I2C_BUS, 0x4f, 0x04 }, -// Do 50-53 have any effect? -// Toggle 0x12[2] off and on here? - { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */ - }; - - static struct ov511_regvals regvals_norm_6x30[] = { - { OV511_I2C_BUS, 0x12, 0x80 }, /* Reset */ - { OV511_I2C_BUS, 0x00, 0x1f }, /* Gain */ - { OV511_I2C_BUS, 0x01, 0x99 }, /* Blue gain */ - { OV511_I2C_BUS, 0x02, 0x7c }, /* Red gain */ - { OV511_I2C_BUS, 0x03, 0xc0 }, /* Saturation */ - { OV511_I2C_BUS, 0x05, 0x0a }, /* Contrast */ - { OV511_I2C_BUS, 0x06, 0x95 }, /* Brightness */ - { OV511_I2C_BUS, 0x07, 0x2d }, /* Sharpness */ - { OV511_I2C_BUS, 0x0c, 0x20 }, - { OV511_I2C_BUS, 0x0d, 0x20 }, - { OV511_I2C_BUS, 0x0e, 0x20 }, - { OV511_I2C_BUS, 0x0f, 0x05 }, - { OV511_I2C_BUS, 0x10, 0x9a }, - { OV511_I2C_BUS, 0x11, 0x00 }, /* Pixel clock = fastest */ - { OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC and AWB */ - { OV511_I2C_BUS, 0x13, 0x21 }, - { OV511_I2C_BUS, 0x14, 0x80 }, - { OV511_I2C_BUS, 0x15, 0x01 }, - { OV511_I2C_BUS, 0x16, 0x03 }, - { OV511_I2C_BUS, 0x17, 0x38 }, - { OV511_I2C_BUS, 0x18, 0xea }, - { OV511_I2C_BUS, 0x19, 0x04 }, - { OV511_I2C_BUS, 0x1a, 0x93 }, - { OV511_I2C_BUS, 0x1b, 0x00 }, - { OV511_I2C_BUS, 0x1e, 0xc4 }, - { OV511_I2C_BUS, 0x1f, 0x04 }, - { OV511_I2C_BUS, 0x20, 0x20 }, - { OV511_I2C_BUS, 0x21, 0x10 }, - { OV511_I2C_BUS, 0x22, 0x88 }, - { OV511_I2C_BUS, 0x23, 0xc0 }, /* Crystal circuit power level */ - { OV511_I2C_BUS, 0x25, 0x9a }, /* Increase AEC black ratio */ - { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */ - { OV511_I2C_BUS, 0x27, 0xa2 }, - { OV511_I2C_BUS, 0x28, 0x00 }, - { OV511_I2C_BUS, 0x29, 0x00 }, - { OV511_I2C_BUS, 0x2a, 0x84 }, /* 60 Hz power */ - { OV511_I2C_BUS, 0x2b, 0xa8 }, /* 60 Hz power */ - { OV511_I2C_BUS, 0x2c, 0xa0 }, - { OV511_I2C_BUS, 0x2d, 0x95 }, /* Enable auto-brightness */ - { OV511_I2C_BUS, 0x2e, 0x88 }, - { OV511_I2C_BUS, 0x33, 0x26 }, - { OV511_I2C_BUS, 0x34, 0x03 }, - { OV511_I2C_BUS, 0x36, 0x8f }, - { OV511_I2C_BUS, 0x37, 0x80 }, - { OV511_I2C_BUS, 0x38, 0x83 }, - { OV511_I2C_BUS, 0x39, 0x80 }, - { OV511_I2C_BUS, 0x3a, 0x0f }, - { OV511_I2C_BUS, 0x3b, 0x3c }, - { OV511_I2C_BUS, 0x3c, 0x1a }, - { OV511_I2C_BUS, 0x3d, 0x80 }, - { OV511_I2C_BUS, 0x3e, 0x80 }, - { OV511_I2C_BUS, 0x3f, 0x0e }, - { OV511_I2C_BUS, 0x40, 0x00 }, /* White bal */ - { OV511_I2C_BUS, 0x41, 0x00 }, /* White bal */ - { OV511_I2C_BUS, 0x42, 0x80 }, - { OV511_I2C_BUS, 0x43, 0x3f }, /* White bal */ - { OV511_I2C_BUS, 0x44, 0x80 }, - { OV511_I2C_BUS, 0x45, 0x20 }, - { OV511_I2C_BUS, 0x46, 0x20 }, - { OV511_I2C_BUS, 0x47, 0x80 }, - { OV511_I2C_BUS, 0x48, 0x7f }, - { OV511_I2C_BUS, 0x49, 0x00 }, - { OV511_I2C_BUS, 0x4a, 0x00 }, - { OV511_I2C_BUS, 0x4b, 0x80 }, - { OV511_I2C_BUS, 0x4c, 0xd0 }, - { OV511_I2C_BUS, 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */ - { OV511_I2C_BUS, 0x4e, 0x40 }, - { OV511_I2C_BUS, 0x4f, 0x07 }, /* UV avg., col. killer: max */ - { OV511_I2C_BUS, 0x50, 0xff }, - { OV511_I2C_BUS, 0x54, 0x23 }, /* Max AGC gain: 18dB */ - { OV511_I2C_BUS, 0x55, 0xff }, - { OV511_I2C_BUS, 0x56, 0x12 }, - { OV511_I2C_BUS, 0x57, 0x81 }, - { OV511_I2C_BUS, 0x58, 0x75 }, - { OV511_I2C_BUS, 0x59, 0x01 }, /* AGC dark current comp.: +1 */ - { OV511_I2C_BUS, 0x5a, 0x2c }, - { OV511_I2C_BUS, 0x5b, 0x0f }, /* AWB chrominance levels */ - { OV511_I2C_BUS, 0x5c, 0x10 }, - { OV511_I2C_BUS, 0x3d, 0x80 }, - { OV511_I2C_BUS, 0x27, 0xa6 }, - { OV511_I2C_BUS, 0x12, 0x20 }, /* Toggle AWB */ - { OV511_I2C_BUS, 0x12, 0x24 }, - { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */ - }; - - PDEBUG(4, "starting sensor configuration"); - - if (init_ov_sensor(ov) < 0) { - err("Failed to read sensor ID. You might not have an OV6xx0,"); - err("or it may be not responding. Report this to " EMAIL); - return -1; - } else { - PDEBUG(1, "OV6xx0 sensor detected"); - } - - /* Detect sensor (sub)type */ - rc = i2c_r(ov, OV7610_REG_COM_I); - - if (rc < 0) { - err("Error detecting sensor type"); - return -1; - } - - /* Ugh. The first two bits are the version bits, but the entire register - * value must be used. I guess OVT underestimated how many variants - * they would make. */ - if (rc == 0x00) { - ov->sensor = SEN_OV6630; - info("WARNING: Sensor is an OV66308. Your camera may have"); - info("been misdetected in previous driver versions. Please"); - info("report this to Mark."); - } else if (rc == 0x01) { - ov->sensor = SEN_OV6620; - info("Sensor is an OV6620"); - } else if (rc == 0x02) { - ov->sensor = SEN_OV6630; - info("Sensor is an OV66308AE"); - } else if (rc == 0x03) { - ov->sensor = SEN_OV6630; - info("Sensor is an OV66308AF"); - } else if (rc == 0x90) { - ov->sensor = SEN_OV6630; - info("WARNING: Sensor is an OV66307. Your camera may have"); - info("been misdetected in previous driver versions. Please"); - info("report this to Mark."); - } else { - err("FATAL: Unknown sensor version: 0x%02x", rc); - return -1; - } - - /* Set sensor-specific vars */ - ov->maxwidth = 352; - ov->maxheight = 288; - ov->minwidth = 64; - ov->minheight = 48; - - // FIXME: These do not match the actual settings yet - ov->brightness = 0x80 << 8; - ov->contrast = 0x80 << 8; - ov->colour = 0x80 << 8; - ov->hue = 0x80 << 8; - - if (ov->sensor == SEN_OV6620) { - PDEBUG(4, "Writing 6x20 registers"); - if (write_regvals(ov, regvals_norm_6x20)) - return -1; - } else { - PDEBUG(4, "Writing 6x30 registers"); - if (write_regvals(ov, regvals_norm_6x30)) - return -1; - } - - return 0; -} - -/* This initializes the KS0127 and KS0127B video decoders. */ -static int -ks0127_configure(struct usb_ov511 *ov) -{ - int rc; - - /* Detect decoder subtype */ - rc = i2c_r(ov, 0x00); - if (rc < 0) { - err("Error detecting sensor type"); - return -1; - } else if (rc & 0x08) { - rc = i2c_r(ov, 0x3d); - if (rc < 0) { - err("Error detecting sensor type"); - return -1; - } else if ((rc & 0x0f) == 0) { - info("Sensor is a KS0127"); - } else if ((rc & 0x0f) == 9) { - info("Sensor is a KS0127B Rev. A"); - } - } else { - info("Sensor is a KS0122"); - } - - /* This device is not supported yet. Bail out now... */ - err("This sensor is not supported yet."); - return -1; -} - -/* This initializes the SAA7111A video decoder. */ -static int -saa7111a_configure(struct usb_ov511 *ov) -{ - int rc; - - /* Since there is no register reset command, all registers must be - * written, otherwise gives erratic results */ - static struct ov511_regvals regvals_norm_SAA7111A[] = { - { OV511_I2C_BUS, 0x06, 0xce }, - { OV511_I2C_BUS, 0x07, 0x00 }, - { OV511_I2C_BUS, 0x10, 0x44 }, /* YUV422, 240/286 lines */ - { OV511_I2C_BUS, 0x0e, 0x01 }, /* NTSC M or PAL BGHI */ - { OV511_I2C_BUS, 0x00, 0x00 }, - { OV511_I2C_BUS, 0x01, 0x00 }, - { OV511_I2C_BUS, 0x03, 0x23 }, - { OV511_I2C_BUS, 0x04, 0x00 }, - { OV511_I2C_BUS, 0x05, 0x00 }, - { OV511_I2C_BUS, 0x08, 0xc8 }, /* Auto field freq */ - { OV511_I2C_BUS, 0x09, 0x01 }, /* Chrom. trap off, APER=0.25 */ - { OV511_I2C_BUS, 0x0a, 0x80 }, /* BRIG=128 */ - { OV511_I2C_BUS, 0x0b, 0x40 }, /* CONT=1.0 */ - { OV511_I2C_BUS, 0x0c, 0x40 }, /* SATN=1.0 */ - { OV511_I2C_BUS, 0x0d, 0x00 }, /* HUE=0 */ - { OV511_I2C_BUS, 0x0f, 0x00 }, - { OV511_I2C_BUS, 0x11, 0x0c }, - { OV511_I2C_BUS, 0x12, 0x00 }, - { OV511_I2C_BUS, 0x13, 0x00 }, - { OV511_I2C_BUS, 0x14, 0x00 }, - { OV511_I2C_BUS, 0x15, 0x00 }, - { OV511_I2C_BUS, 0x16, 0x00 }, - { OV511_I2C_BUS, 0x17, 0x00 }, - { OV511_I2C_BUS, 0x02, 0xc0 }, /* Composite input 0 */ - { OV511_DONE_BUS, 0x0, 0x00 }, - }; - - /* 640x480 not supported with PAL */ - if (ov->pal) { - ov->maxwidth = 320; - ov->maxheight = 240; /* Even field only */ - } else { - ov->maxwidth = 640; - ov->maxheight = 480; /* Even/Odd fields */ - } - - ov->minwidth = 320; - ov->minheight = 240; /* Even field only */ - - ov->has_decoder = 1; - ov->num_inputs = 8; - ov->norm = VIDEO_MODE_AUTO; - ov->stop_during_set = 0; /* Decoder guarantees stable image */ - - /* Decoder doesn't change these values, so we use these instead of - * acutally reading the registers (which doesn't work) */ - ov->brightness = 0x80 << 8; - ov->contrast = 0x40 << 9; - ov->colour = 0x40 << 9; - ov->hue = 32768; - - PDEBUG(4, "Writing SAA7111A registers"); - if (write_regvals(ov, regvals_norm_SAA7111A)) - return -1; - - /* Detect version of decoder. This must be done after writing the - * initial regs or the decoder will lock up. */ - rc = i2c_r(ov, 0x00); - - if (rc < 0) { - err("Error detecting sensor version"); - return -1; - } else { - info("Sensor is an SAA7111A (version 0x%x)", rc); - ov->sensor = SEN_SAA7111A; - } - - /* Latch to negative edge of clock. Otherwise, we get incorrect - * colors and jitter in the digital signal. */ - if (ov->bclass == BCL_OV511) - reg_w(ov, 0x11, 0x00); - else - warn("SAA7111A not yet supported with OV518/OV518+"); - - return 0; -} - -/* This initializes the OV511/OV511+ and the sensor */ -static int -ov511_configure(struct usb_ov511 *ov) -{ - static struct ov511_regvals regvals_init_511[] = { - { OV511_REG_BUS, R51x_SYS_RESET, 0x7f }, - { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, - { OV511_REG_BUS, R51x_SYS_RESET, 0x7f }, - { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, - { OV511_REG_BUS, R51x_SYS_RESET, 0x3f }, - { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, - { OV511_REG_BUS, R51x_SYS_RESET, 0x3d }, - { OV511_DONE_BUS, 0x0, 0x00}, - }; - - static struct ov511_regvals regvals_norm_511[] = { - { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, - { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f }, - { OV511_REG_BUS, R511_COMP_EN, 0x00 }, - { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 }, - { OV511_DONE_BUS, 0x0, 0x00 }, - }; - - static struct ov511_regvals regvals_norm_511_plus[] = { - { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, - { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, - { OV511_REG_BUS, R511_FIFO_OPTS, 0xff }, - { OV511_REG_BUS, R511_COMP_EN, 0x00 }, - { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 }, - { OV511_DONE_BUS, 0x0, 0x00 }, - }; - - PDEBUG(4, ""); - - ov->customid = reg_r(ov, R511_SYS_CUST_ID); - if (ov->customid < 0) { - err("Unable to read camera bridge registers"); - goto error; - } - - PDEBUG (1, "CustomID = %d", ov->customid); - ov->desc = symbolic(camlist, ov->customid); - info("model: %s", ov->desc); - - if (0 == strcmp(ov->desc, NOT_DEFINED_STR)) { - err("Camera type (%d) not recognized", ov->customid); - err("Please notify " EMAIL " of the name,"); - err("manufacturer, model, and this number of your camera."); - err("Also include the output of the detection process."); - } - - if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */ - ov->pal = 1; - - if (write_regvals(ov, regvals_init_511)) goto error; - - if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO) - ov51x_led_control(ov, 0); - - /* The OV511+ has undocumented bits in the flow control register. - * Setting it to 0xff fixes the corruption with moving objects. */ - if (ov->bridge == BRG_OV511) { - if (write_regvals(ov, regvals_norm_511)) goto error; - } else if (ov->bridge == BRG_OV511PLUS) { - if (write_regvals(ov, regvals_norm_511_plus)) goto error; - } else { - err("Invalid bridge"); - } - - if (ov511_init_compression(ov)) goto error; - - ov->packet_numbering = 1; - ov511_set_packet_size(ov, 0); - - ov->snap_enabled = snapshot; - - /* Test for 7xx0 */ - PDEBUG(3, "Testing for 0V7xx0"); - ov->primary_i2c_slave = OV7xx0_SID; - if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0) - goto error; - - if (i2c_w(ov, 0x12, 0x80) < 0) { - /* Test for 6xx0 */ - PDEBUG(3, "Testing for 0V6xx0"); - ov->primary_i2c_slave = OV6xx0_SID; - if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0) - goto error; - - if (i2c_w(ov, 0x12, 0x80) < 0) { - /* Test for 8xx0 */ - PDEBUG(3, "Testing for 0V8xx0"); - ov->primary_i2c_slave = OV8xx0_SID; - if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0) - goto error; - - if (i2c_w(ov, 0x12, 0x80) < 0) { - /* Test for SAA7111A */ - PDEBUG(3, "Testing for SAA7111A"); - ov->primary_i2c_slave = SAA7111A_SID; - if (ov51x_set_slave_ids(ov, SAA7111A_SID) < 0) - goto error; - - if (i2c_w(ov, 0x0d, 0x00) < 0) { - /* Test for KS0127 */ - PDEBUG(3, "Testing for KS0127"); - ov->primary_i2c_slave = KS0127_SID; - if (ov51x_set_slave_ids(ov, KS0127_SID) < 0) - goto error; - - if (i2c_w(ov, 0x10, 0x00) < 0) { - err("Can't determine sensor slave IDs"); - goto error; - } else { - if (ks0127_configure(ov) < 0) { - err("Failed to configure KS0127"); - goto error; - } - } - } else { - if (saa7111a_configure(ov) < 0) { - err("Failed to configure SAA7111A"); - goto error; - } - } - } else { - if (ov8xx0_configure(ov) < 0) { - err("Failed to configure OV8xx0 sensor"); - goto error; - } - } - } else { - if (ov6xx0_configure(ov) < 0) { - err("Failed to configure OV6xx0"); - goto error; - } - } - } else { - if (ov7xx0_configure(ov) < 0) { - err("Failed to configure OV7xx0"); - goto error; - } - } - - return 0; - -error: - err("OV511 Config failed"); - - return -EBUSY; -} - -/* This initializes the OV518/OV518+ and the sensor */ -static int -ov518_configure(struct usb_ov511 *ov) -{ - /* For 518 and 518+ */ - static struct ov511_regvals regvals_init_518[] = { - { OV511_REG_BUS, R51x_SYS_RESET, 0x40 }, - { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, - { OV511_REG_BUS, R51x_SYS_RESET, 0x3e }, - { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, - { OV511_REG_BUS, R51x_SYS_RESET, 0x00 }, - { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, - { OV511_REG_BUS, 0x46, 0x00 }, - { OV511_REG_BUS, 0x5d, 0x03 }, - { OV511_DONE_BUS, 0x0, 0x00}, - }; - - static struct ov511_regvals regvals_norm_518[] = { - { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */ - { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */ - { OV511_REG_BUS, 0x31, 0x0f }, - { OV511_REG_BUS, 0x5d, 0x03 }, - { OV511_REG_BUS, 0x24, 0x9f }, - { OV511_REG_BUS, 0x25, 0x90 }, - { OV511_REG_BUS, 0x20, 0x00 }, - { OV511_REG_BUS, 0x51, 0x04 }, - { OV511_REG_BUS, 0x71, 0x19 }, - { OV511_REG_BUS, 0x2f, 0x80 }, - { OV511_DONE_BUS, 0x0, 0x00 }, - }; - - static struct ov511_regvals regvals_norm_518_plus[] = { - { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */ - { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */ - { OV511_REG_BUS, 0x31, 0x0f }, - { OV511_REG_BUS, 0x5d, 0x03 }, - { OV511_REG_BUS, 0x24, 0x9f }, - { OV511_REG_BUS, 0x25, 0x90 }, - { OV511_REG_BUS, 0x20, 0x60 }, - { OV511_REG_BUS, 0x51, 0x02 }, - { OV511_REG_BUS, 0x71, 0x19 }, - { OV511_REG_BUS, 0x40, 0xff }, - { OV511_REG_BUS, 0x41, 0x42 }, - { OV511_REG_BUS, 0x46, 0x00 }, - { OV511_REG_BUS, 0x33, 0x04 }, - { OV511_REG_BUS, 0x21, 0x19 }, - { OV511_REG_BUS, 0x3f, 0x10 }, - { OV511_REG_BUS, 0x2f, 0x80 }, - { OV511_DONE_BUS, 0x0, 0x00 }, - }; - - PDEBUG(4, ""); - - /* First 5 bits of custom ID reg are a revision ID on OV518 */ - info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID)); - - /* Give it the default description */ - ov->desc = symbolic(camlist, 0); - - if (write_regvals(ov, regvals_init_518)) goto error; - - /* Set LED GPIO pin to output mode */ - if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0) goto error; - - /* LED is off by default with OV518; have to explicitly turn it on */ - if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO) - ov51x_led_control(ov, 0); - else - ov51x_led_control(ov, 1); - - /* Don't require compression if dumppix is enabled; otherwise it's - * required. OV518 has no uncompressed mode, to save RAM. */ - if (!dumppix && !ov->compress) { - ov->compress = 1; - warn("Compression required with OV518...enabling"); - } - - if (ov->bridge == BRG_OV518) { - if (write_regvals(ov, regvals_norm_518)) goto error; - } else if (ov->bridge == BRG_OV518PLUS) { - if (write_regvals(ov, regvals_norm_518_plus)) goto error; - } else { - err("Invalid bridge"); - } - - if (ov518_init_compression(ov)) goto error; - - if (ov->bridge == BRG_OV518) - { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7) - struct usb_interface *ifp; - struct usb_host_interface *alt; - __u16 mxps = 0; - - ifp = usb_ifnum_to_if(ov->dev, 0); - if (ifp) { - alt = usb_altnum_to_altsetting(ifp, 7); - if (alt) -# if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) - mxps = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); -# else - mxps = alt->endpoint[0].desc.wMaxPacketSize; -# endif - } -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - struct usb_interface *ifp = ov->dev->config[0].interface[0]; - __u16 mxps = ifp->altsetting[7].endpoint[0].desc.wMaxPacketSize; -#else - struct usb_interface *ifp = &ov->dev->config[0].interface[0]; - __u16 mxps = ifp->altsetting[7].endpoint[0].wMaxPacketSize; -#endif - /* Some OV518s have packet numbering by default, some don't */ - if (mxps == 897) - ov->packet_numbering = 1; - else - ov->packet_numbering = 0; - } else { - /* OV518+ has packet numbering turned on by default */ - ov->packet_numbering = 1; - } - - ov518_set_packet_size(ov, 0); - - ov->snap_enabled = snapshot; - - /* Test for 76xx */ - ov->primary_i2c_slave = OV7xx0_SID; - if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0) - goto error; - - /* The OV518 must be more aggressive about sensor detection since - * I2C write will never fail if the sensor is not present. We have - * to try to initialize the sensor to detect its presence */ - - if (init_ov_sensor(ov) < 0) { - /* Test for 6xx0 */ - ov->primary_i2c_slave = OV6xx0_SID; - if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0) - goto error; - - if (init_ov_sensor(ov) < 0) { - /* Test for 8xx0 */ - ov->primary_i2c_slave = OV8xx0_SID; - if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0) - goto error; - - if (init_ov_sensor(ov) < 0) { - err("Can't determine sensor slave IDs"); - goto error; - } else { - if (ov8xx0_configure(ov) < 0) { - err("Failed to configure OV8xx0 sensor"); - goto error; - } - } - } else { - if (ov6xx0_configure(ov) < 0) { - err("Failed to configure OV6xx0"); - goto error; - } - } - } else { - if (ov7xx0_configure(ov) < 0) { - err("Failed to configure OV7xx0"); - goto error; - } - } - - ov->maxwidth = 352; - ov->maxheight = 288; - - // The OV518 cannot go as low as the sensor can - ov->minwidth = 160; - ov->minheight = 120; - - return 0; - -error: - err("OV518 Config failed"); - - return -EBUSY; -} - -/* This initializes the OV518/OV518+ and the sensor */ -static int -ov519_configure(struct usb_ov511 *ov) -{ - - static struct ov511_regvals regvals_init_519[] = { - { OV511_REG_BUS, 0x5a, 0x6d }, /* EnableSystem */ - /* windows reads 0x53 at this point*/ - { OV511_REG_BUS, 0x53, 0x9b }, - { OV511_REG_BUS, 0x54, 0x0f }, // set bit2 to enable jpeg - { OV511_REG_BUS, 0x5d, 0x03 }, - { OV511_REG_BUS, 0x49, 0x01 }, - { OV511_REG_BUS, 0x48, 0x00 }, - - /* Set LED pin to output mode. Bit 4 must be cleared or sensor - * detection will fail. This deserves further investigation. */ - { OV511_REG_BUS, OV519_GPIO_IO_CTRL0, 0xee }, - - { OV511_REG_BUS, 0x51, 0x0f }, /* SetUsbInit */ - { OV511_REG_BUS, 0x51, 0x00 }, - { OV511_REG_BUS, 0x22, 0x00 }, - /* windows reads 0x55 at this point*/ - { OV511_DONE_BUS, 0x0, 0x00}, - }; - - PDEBUG(4, ""); - - /* Give it the default description */ - ov->desc = symbolic(camlist, 0); - - if (write_regvals(ov, regvals_init_519)) - goto error; - - if (ov519_init_compression(ov)) - goto error; - - if (ov->imp == IMP_EYETOY) { - /* LED is annoyingly bright. Only turn it on if requested to. */ - if (ov->led2_policy == LED_ON) - ov51x_led_control(ov, 1); - else - ov51x_led_control(ov, 0); - } else { - /* LED might be off by default */ - if (ov->led_policy == LED_ON) - ov51x_led_control(ov, 1); - else - ov51x_led_control(ov, 0); - } - - /* Don't require compression if dumppix is enabled; otherwise it's - * required. OV519 probably has no uncompressed mode, to save RAM. */ - if (!dumppix && !ov->compress) - ov->compress = 1; - - ov->packet_numbering = 0; - - ov519_set_packet_size(ov, 0); - - ov->snap_enabled = snapshot; - - /* Test for 76xx */ - ov->primary_i2c_slave = OV7xx0_SID; - if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0) - goto error; - - /* The OV519 must be more aggressive about sensor detection since - * I2C write will never fail if the sensor is not present. We have - * to try to initialize the sensor to detect its presence */ - - if (init_ov_sensor(ov) < 0) { - /* Test for 6xx0 */ - ov->primary_i2c_slave = OV6xx0_SID; - if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0) - goto error; - - if (init_ov_sensor(ov) < 0) { - /* Test for 8xx0 */ - ov->primary_i2c_slave = OV8xx0_SID; - if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0) - goto error; - - if (init_ov_sensor(ov) < 0) { - err("Can't determine sensor slave IDs"); - goto error; - } else { - if (ov8xx0_configure(ov) < 0) { - err("Failed to configure OV8xx0 sensor"); - goto error; - } - } - } else { - if (ov6xx0_configure(ov) < 0) { - err("Failed to configure OV6xx0"); - goto error; - } - } - } else { - if (ov7xx0_configure(ov) < 0) { - err("Failed to configure OV7xx0"); - goto error; - } - } - - return 0; - -error: - err("OV519 Config failed"); - - return -EBUSY; -} - -/**************************************************************************** - * - * USB routines - * - ***************************************************************************/ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 36) -static int -ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) -{ - struct usb_device *dev = interface_to_usbdev(intf); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) -static void * -ov51x_probe(struct usb_device *dev, unsigned int ifnum, - const struct usb_device_id *id) -{ -#else -static void * -ov51x_probe(struct usb_device *dev, unsigned int ifnum) -{ -#endif - struct usb_interface_descriptor *idesc; - struct usb_ov511 *ov; - int i; - u16 vendor, product; - - PDEBUG(1, "probing for device..."); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 36) - /* We don't handle multi-config cameras */ - if (dev->descriptor.bNumConfigurations != 1) - return -ENODEV; -#else - /* We don't handle multi-config cameras */ - if (dev->descriptor.bNumConfigurations != 1) - return NULL; -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 7) - idesc = &intf->cur_altsetting->desc; -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 36) - idesc = &intf->altsetting[0].desc; -#else - idesc = &dev->actconfig->interface[ifnum].altsetting[0]; -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) - vendor = le16_to_cpu(dev->descriptor.idVendor); - product = le16_to_cpu(dev->descriptor.idProduct); -#else - vendor = dev->descriptor.idVendor; - product = dev->descriptor.idProduct; -#endif - -/* 2.2.x compatibility */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) - /* Is it an OV511/OV511+? */ - if (vendor != VEND_OMNIVISION - && vendor != VEND_MATTEL - && vendor != VEND_SONY) - return NULL; - - if (vendor == VEND_OMNIVISION - && product != PROD_OV511 - && product != PROD_OV518 - && product != PROD_OV511PLUS - && product != PROD_OV518PLUS - && product != PROD_OV519 - && product != PROD_OV1519 - && product != PROD_OV2519 - && product != PROD_OV3519 - && product != PROD_OV4519 - && product != PROD_OV5519 - && product != PROD_OV6519 - && product != PROD_OV7519 - && product != PROD_OV8519 - && product != PROD_OV9519 - && product != PROD_OVA519 - && product != PROD_OVB519 - && product != PROD_OVC519 - && product != PROD_OVD519 - && product != PROD_OVE519 - && product != PROD_OVF519 - && product != PROD_OV530) - return NULL; - - if (vendor == VEND_MATTEL - && product != PROD_ME2CAM) - return NULL; - - if (vendor == VEND_SONY - && product != PROD_EYETOY4 - && product != PROD_EYETOY5) - return NULL; - - if (vendor == VEND_MICROSOFT - && product != PROD_XBOX_CAM) - return NULL; -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 36) - if (idesc->bInterfaceClass != 0xFF) - return -ENODEV; - if (idesc->bInterfaceSubClass != 0x00) - return -ENODEV; -#else - if (idesc->bInterfaceClass != 0xFF) - return NULL; - if (idesc->bInterfaceSubClass != 0x00) - return NULL; -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20) - /* Since code below may sleep, we use this as a lock */ - MOD_INC_USE_COUNT; -#endif - - if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) { - err("couldn't kmalloc ov struct"); - goto error_out; - } - - memset(ov, 0, sizeof(*ov)); - - ov->dev = dev; - ov->iface = idesc->bInterfaceNumber; - ov->led_policy = led; - ov->led2_policy = led2; - ov->compress = compress; - ov->lightfreq = lightfreq; - ov->num_inputs = 1; /* Video decoder init functs. change this */ - ov->stop_during_set = !fastset; - ov->backlight = backlight; - ov->mirror = mirror; - ov->auto_brt = autobright; - ov->auto_gain = autogain; - ov->auto_exp = autoexp; - ov->imp = IMP_GENERIC; - - switch (product) { - case PROD_OV511: - ov->bridge = BRG_OV511; - ov->bclass = BCL_OV511; - break; - case PROD_OV511PLUS: - ov->bridge = BRG_OV511PLUS; - ov->bclass = BCL_OV511; - break; - case PROD_OV518: - ov->bridge = BRG_OV518; - ov->bclass = BCL_OV518; - break; - case PROD_OV518PLUS: - ov->bridge = BRG_OV518PLUS; - ov->bclass = BCL_OV518; - break; - case PROD_OV519: - case PROD_OV4519: - case PROD_OV8519: - case PROD_OV530: - case PROD_XBOX_CAM: - ov->bridge = BRG_OV519; - ov->bclass = BCL_OV519; - break; - case PROD_OV1519: - case PROD_OV2519: - case PROD_OV3519: - case PROD_OV5519: - case PROD_OV6519: - case PROD_OV7519: - case PROD_OV9519: - case PROD_OVA519: - case PROD_OVB519: - case PROD_OVC519: - case PROD_OVD519: - case PROD_OVE519: - case PROD_OVF519: - info("Device has Product ID that hasn't been seen yet. It"); - info("will probably work anyway, but please send"); - info("/proc/bus/usb/devices, your dmesg log, and any info you"); - info("have about this device to mark@alpha.dyndns.org"); - ov->bridge = BRG_OV519; - ov->bclass = BCL_OV519; - break; - case PROD_EYETOY4: - case PROD_EYETOY5: - /* These two should work, but they are untested */ -// case PROD_EYETOY6: -// case PROD_EYETOY7: - ov->bridge = BRG_OV519; - ov->bclass = BCL_OV519; - ov->imp = IMP_EYETOY; - break; - case PROD_ME2CAM: - if (vendor != VEND_MATTEL) - goto error; - ov->bridge = BRG_OV511PLUS; - ov->bclass = BCL_OV511; - break; - default: - err("Unknown product ID 0x%04x", product); - goto error; - } - - info("USB %s video device found", symbolic(brglist, ov->bridge)); - -#ifdef OV511_ALLOW_CONVERSION - /* Workaround for some applications that want data in RGB - * instead of BGR. */ - if (force_rgb) - info("data format set to RGB"); -#endif - - init_waitqueue_head(&ov->wq); - - init_MUTEX(&ov->lock); /* to 1 == available */ - init_MUTEX(&ov->buf_lock); - init_MUTEX(&ov->param_lock); - init_MUTEX(&ov->i2c_lock); - init_MUTEX(&ov->cbuf_lock); - - ov->buf_state = BUF_NOT_ALLOCATED; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 20) - if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) { - err("usb_make_path error"); - goto error; - } -#endif - - /* Allocate control transfer buffer. */ - /* Must be kmalloc()'ed, for DMA compatibility */ - ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL); - if (!ov->cbuf) - goto error; - - switch (ov->bclass) { - case BCL_OV511: - if (ov511_configure(ov) < 0) - goto error; - break; - case BCL_OV518: - if (ov518_configure(ov) < 0) - goto error; - break; - case BCL_OV519: - if (ov519_configure(ov) < 0) - goto error; - break; - default: - goto error; - } - - for (i = 0; i < OV511_NUMFRAMES; i++) { - ov->frame[i].framenum = i; - init_waitqueue_head(&ov->frame[i].wq); - } - - for (i = 0; i < OV511_NUMSBUF; i++) { - ov->sbuf[i].ov = ov; - spin_lock_init(&ov->sbuf[i].lock); - ov->sbuf[i].n = i; - } - - /* Unnecessary? (This is done on open(). Need to make sure variables - * are properly initialized without this before removing it, though). */ - if (ov51x_set_default_params(ov) < 0) - goto error; - -#ifdef OV511_DEBUG - if (dump_bridge) { - if (ov->bclass == BCL_OV511) - ov511_dump_regs(ov); - else - ov518_dump_regs(ov); - } -#endif - - ov->vdev = video_device_alloc(); - if (!ov->vdev) - goto error; - - memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev)); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - ov->vdev->dev = &dev->dev; -#endif - video_set_drvdata(ov->vdev, ov); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 5) - for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { - /* Minor 0 cannot be specified; assume user wants autodetect */ - if (unit_video[i] == 0) - break; - - if (video_register_device(ov->vdev, VFL_TYPE_GRABBER, - unit_video[i]) >= 0) { - break; - } - } - - /* Use the next available one */ - if ((ov->vdev->minor == -1) && - video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) { -#else - if (video_register_device(ov->vdev, VFL_TYPE_GRABBER) < 0) { -#endif - err("video_register_device failed"); - goto error; - } - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 20) - info("Device at %s registered to minor %d", ov->usb_path, - ov->vdev->minor); -#else - info("Device %d on bus %d registered to minor %d", dev->devnum, - dev->bus->busnum, ov->vdev->minor); -#endif - - create_proc_ov511_cam(ov); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20) - MOD_DEC_USE_COUNT; -#endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 36) - usb_set_intfdata(intf, ov); - return 0; -#else - return ov; -#endif - -error: - destroy_proc_ov511_cam(ov); - - if (ov->vdev) { - if (-1 == ov->vdev->minor) - video_device_release(ov->vdev); - else - video_unregister_device(ov->vdev); - ov->vdev = NULL; - } - - if (ov->cbuf) { - down(&ov->cbuf_lock); - kfree(ov->cbuf); - ov->cbuf = NULL; - up(&ov->cbuf_lock); - } - - kfree(ov); - ov = NULL; - -error_out: -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20) - MOD_DEC_USE_COUNT; -#endif - err("Camera initialization failed"); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 36) - return -EIO; -#else - return NULL; -#endif -} - -static void -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) -ov51x_disconnect(struct usb_interface *intf) -{ - struct usb_ov511 *ov = usb_get_intfdata(intf); -#else -ov51x_disconnect(struct usb_device *dev, void *ptr) -{ - struct usb_ov511 *ov = (struct usb_ov511 *) ptr; -#endif - int n; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20) - MOD_INC_USE_COUNT; -#endif - - PDEBUG(3, ""); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - usb_set_intfdata(intf, NULL); -#endif - if (!ov) - return; - -#ifdef OV511_OLD_V4L - /* We don't want people trying to open up the device */ - if (!ov->user) - video_unregister_device(ov->vdev); - else - PDEBUG(3, "Device open...deferring video_unregister_device"); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) - if (ov->vdev) - video_unregister_device(ov->vdev); -#else - video_unregister_device(ov->vdev); - if (ov->user) - PDEBUG(3, "Device open...deferring video_unregister_device"); -#endif - - for (n = 0; n < OV511_NUMFRAMES; n++) - ov->frame[n].grabstate = FRAME_ERROR; - - ov->curframe = -1; - - /* This will cause the process to request another frame */ - for (n = 0; n < OV511_NUMFRAMES; n++) - wake_up_interruptible(&ov->frame[n].wq); - - wake_up_interruptible(&ov->wq); - - ov->streaming = 0; - ov51x_unlink_isoc(ov); - - destroy_proc_ov511_cam(ov); - - ov->dev = NULL; - - /* Free the memory */ - if (ov && !ov->user) { - down(&ov->cbuf_lock); - kfree(ov->cbuf); - ov->cbuf = NULL; - up(&ov->cbuf_lock); - - ov51x_dealloc(ov); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) - if (ov->vdev) - video_device_release(ov->vdev); -#endif - kfree(ov); - ov = NULL; - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 20) - MOD_DEC_USE_COUNT; -#endif - PDEBUG(3, "Disconnect complete"); -} - -static struct usb_driver ov511_driver = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 20) - .owner = THIS_MODULE, -#endif - .name = "ov51x", -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) - .id_table = device_table, -#endif - .probe = ov51x_probe, - .disconnect = ov51x_disconnect -}; - - - -module_init(usb_ov511_init); -module_exit(usb_ov511_exit); -#endif -#endif diff --git a/plugins/USBqemu/usb-mic/adcuser.h b/plugins/USBqemu/usb-mic/adcuser.h deleted file mode 100644 index 48f1af8ff1..0000000000 --- a/plugins/USBqemu/usb-mic/adcuser.h +++ /dev/null @@ -1,30 +0,0 @@ -/*---------------------------------------------------------------------------- - * U S B - K e r n e l - *---------------------------------------------------------------------------- - * Name: ADCUSER.H - * Purpose: Audio Device Class Custom User Definitions - * Version: V1.10 - *---------------------------------------------------------------------------- - * This software is supplied "AS IS" without any warranties, express, - * implied or statutory, including but not limited to the implied - * warranties of fitness for purpose, satisfactory quality and - * noninfringement. Keil extends you a royalty-free right to reproduce - * and distribute executable files created using this software for use - * on Philips LPC2xxx microcontroller devices only. Nothing else gives - * you the right to use this software. - * - * Copyright (c) 2005-2006 Keil Software. - *---------------------------------------------------------------------------*/ - -#ifndef __ADCUSER_H__ -#define __ADCUSER_H__ - - -/* Audio Device Class Requests Callback Functions */ -extern BOOL ADC_IF_GetRequest (void); -extern BOOL ADC_IF_SetRequest (void); -extern BOOL ADC_EP_GetRequest (void); -extern BOOL ADC_EP_SetRequest (void); - - -#endif /* __ADCUSER_H__ */ diff --git a/plugins/USBqemu/usb-mic/audio.h b/plugins/USBqemu/usb-mic/audio.h deleted file mode 100644 index ccd7fae398..0000000000 --- a/plugins/USBqemu/usb-mic/audio.h +++ /dev/null @@ -1,372 +0,0 @@ -/*---------------------------------------------------------------------------- - * U S B - K e r n e l - *---------------------------------------------------------------------------- - * Name: AUDIO.H - * Purpose: USB Audio Device Class Definitions - * Version: V1.10 - *---------------------------------------------------------------------------- - * This software is supplied "AS IS" without any warranties, express, - * implied or statutory, including but not limited to the implied - * warranties of fitness for purpose, satisfactory quality and - * noninfringement. Keil extends you a royalty-free right to reproduce - * and distribute executable files created using this software for use - * on Philips LPC2xxx microcontroller devices only. Nothing else gives - * you the right to use this software. - * - * Copyright (c) 2005-2006 Keil Software. - *---------------------------------------------------------------------------*/ - -#ifndef __AUDIO_H__ -#define __AUDIO_H__ - - -/* Audio Interface Subclass Codes */ -#define AUDIO_SUBCLASS_UNDEFINED 0x00 -#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01 -#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 -#define AUDIO_SUBCLASS_MIDISTREAMING 0x03 - -/* Audio Interface Protocol Codes */ -#define AUDIO_PROTOCOL_UNDEFINED 0x00 - - -/* Audio Descriptor Types */ -#define AUDIO_UNDEFINED_DESCRIPTOR_TYPE 0x20 -#define AUDIO_DEVICE_DESCRIPTOR_TYPE 0x21 -#define AUDIO_CONFIGURATION_DESCRIPTOR_TYPE 0x22 -#define AUDIO_STRING_DESCRIPTOR_TYPE 0x23 -#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24 -#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25 - - -/* Audio Control Interface Descriptor Subtypes */ -#define AUDIO_CONTROL_UNDEFINED 0x00 -#define AUDIO_CONTROL_HEADER 0x01 -#define AUDIO_CONTROL_INPUT_TERMINAL 0x02 -#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03 -#define AUDIO_CONTROL_MIXER_UNIT 0x04 -#define AUDIO_CONTROL_SELECTOR_UNIT 0x05 -#define AUDIO_CONTROL_FEATURE_UNIT 0x06 -#define AUDIO_CONTROL_PROCESSING_UNIT 0x07 -#define AUDIO_CONTROL_EXTENSION_UNIT 0x08 - -/* Audio Streaming Interface Descriptor Subtypes */ -#define AUDIO_STREAMING_UNDEFINED 0x00 -#define AUDIO_STREAMING_GENERAL 0x01 -#define AUDIO_STREAMING_FORMAT_TYPE 0x02 -#define AUDIO_STREAMING_FORMAT_SPECIFIC 0x03 - -/* Audio Endpoint Descriptor Subtypes */ -#define AUDIO_ENDPOINT_UNDEFINED 0x00 -#define AUDIO_ENDPOINT_GENERAL 0x01 - - -/* Audio Descriptor Sizes */ -#define AUDIO_CONTROL_INTERFACE_DESC_SZ(n) 0x08+n -#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07 -#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C -#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09 -#define AUDIO_MIXER_UNIT_DESC_SZ(p,n) 0x0A+p+n -#define AUDIO_SELECTOR_UNIT_DESC_SZ(p) 0x06+p -#define AUDIO_FEATURE_UNIT_DESC_SZ(ch,n) 0x07+(ch+1)*n -#define AUDIO_PROCESSING_UNIT_DESC_SZ(p,n,x) 0x0D+p+n+x -#define AUDIO_EXTENSION_UNIT_DESC_SZ(p,n) 0x0D+p+n -#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09 -#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07 - - -/* Audio Processing Unit Process Types */ -#define AUDIO_UNDEFINED_PROCESS 0x00 -#define AUDIO_UP_DOWN_MIX_PROCESS 0x01 -#define AUDIO_DOLBY_PROLOGIC_PROCESS 0x02 -#define AUDIO_3D_STEREO_PROCESS 0x03 -#define AUDIO_REVERBERATION_PROCESS 0x04 -#define AUDIO_CHORUS_PROCESS 0x05 -#define AUDIO_DYN_RANGE_COMP_PROCESS 0x06 - - -/* Audio Request Codes */ -#define AUDIO_REQUEST_UNDEFINED 0x00 -#define AUDIO_REQUEST_SET_CUR 0x01 -#define AUDIO_REQUEST_GET_CUR 0x81 -#define AUDIO_REQUEST_SET_MIN 0x02 -#define AUDIO_REQUEST_GET_MIN 0x82 -#define AUDIO_REQUEST_SET_MAX 0x03 -#define AUDIO_REQUEST_GET_MAX 0x83 -#define AUDIO_REQUEST_SET_RES 0x04 -#define AUDIO_REQUEST_GET_RES 0x84 -#define AUDIO_REQUEST_SET_MEM 0x05 -#define AUDIO_REQUEST_GET_MEM 0x85 -#define AUDIO_REQUEST_GET_STAT 0xFF - - -/* Audio Control Selector Codes */ -#define AUDIO_CONTROL_UNDEFINED 0x00 /* Common Selector */ - -/* Terminal Control Selectors */ -#define AUDIO_COPY_PROTECT_CONTROL 0x01 - -/* Feature Unit Control Selectors */ -#define AUDIO_MUTE_CONTROL 0x01 -#define AUDIO_VOLUME_CONTROL 0x02 -#define AUDIO_BASS_CONTROL 0x03 -#define AUDIO_MID_CONTROL 0x04 -#define AUDIO_TREBLE_CONTROL 0x05 -#define AUDIO_GRAPHIC_EQUALIZER_CONTROL 0x06 -#define AUDIO_AUTOMATIC_GAIN_CONTROL 0x07 -#define AUDIO_DELAY_CONTROL 0x08 -#define AUDIO_BASS_BOOST_CONTROL 0x09 -#define AUDIO_LOUDNESS_CONTROL 0x0A - -/* Processing Unit Control Selectors: */ -#define AUDIO_ENABLE_CONTROL 0x01 /* Common Selector */ -#define AUDIO_MODE_SELECT_CONTROL 0x02 /* Common Selector */ - -/* - Up/Down-mix Control Selectors */ -/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ -/* AUDIO_MODE_SELECT_CONTROL 0x02 Common Selector */ - -/* - Dolby Prologic Control Selectors */ -/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ -/* AUDIO_MODE_SELECT_CONTROL 0x02 Common Selector */ - -/* - 3D Stereo Extender Control Selectors */ -/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ -#define AUDIO_SPACIOUSNESS_CONTROL 0x02 - -/* - Reverberation Control Selectors */ -/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ -#define AUDIO_REVERB_LEVEL_CONTROL 0x02 -#define AUDIO_REVERB_TIME_CONTROL 0x03 -#define AUDIO_REVERB_FEEDBACK_CONTROL 0x04 - -/* - Chorus Control Selectors */ -/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ -#define AUDIO_CHORUS_LEVEL_CONTROL 0x02 -#define AUDIO_SHORUS_RATE_CONTROL 0x03 -#define AUDIO_CHORUS_DEPTH_CONTROL 0x04 - -/* - Dynamic Range Compressor Control Selectors */ -/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ -#define AUDIO_COMPRESSION_RATE_CONTROL 0x02 -#define AUDIO_MAX_AMPL_CONTROL 0x03 -#define AUDIO_THRESHOLD_CONTROL 0x04 -#define AUDIO_ATTACK_TIME_CONTROL 0x05 -#define AUDIO_RELEASE_TIME_CONTROL 0x06 - -/* Extension Unit Control Selectors */ -/* AUDIO_ENABLE_CONTROL 0x01 Common Selector */ - -/* Endpoint Control Selectors */ -#define AUDIO_SAMPLING_FREQ_CONTROL 0x01 -#define AUDIO_PITCH_CONTROL 0x02 - - -/* Audio Format Specific Control Selectors */ - -/* MPEG Control Selectors */ -#define AUDIO_MPEG_CONTROL_UNDEFINED 0x00 -#define AUDIO_MPEG_DUAL_CHANNEL_CONTROL 0x01 -#define AUDIO_MPEG_SECOND_STEREO_CONTROL 0x02 -#define AUDIO_MPEG_MULTILINGUAL_CONTROL 0x03 -#define AUDIO_MPEG_DYN_RANGE_CONTROL 0x04 -#define AUDIO_MPEG_SCALING_CONTROL 0x05 -#define AUDIO_MPEG_HILO_SCALING_CONTROL 0x06 - -/* AC-3 Control Selectors */ -#define AUDIO_AC3_CONTROL_UNDEFINED 0x00 -#define AUDIO_AC3_MODE_CONTROL 0x01 -#define AUDIO_AC3_DYN_RANGE_CONTROL 0x02 -#define AUDIO_AC3_SCALING_CONTROL 0x03 -#define AUDIO_AC3_HILO_SCALING_CONTROL 0x04 - - -/* Audio Format Types */ -#define AUDIO_FORMAT_TYPE_UNDEFINED 0x00 -#define AUDIO_FORMAT_TYPE_I 0x01 -#define AUDIO_FORMAT_TYPE_II 0x02 -#define AUDIO_FORMAT_TYPE_III 0x03 - - -/* Audio Format Type Descriptor Sizes */ -#define AUDIO_FORMAT_TYPE_I_DESC_SZ(n) 0x08+(n*3) -#define AUDIO_FORMAT_TYPE_II_DESC_SZ(n) 0x09+(n*3) -#define AUDIO_FORMAT_TYPE_III_DESC_SZ(n) 0x08+(n*3) -#define AUDIO_FORMAT_MPEG_DESC_SIZE 0x09 -#define AUDIO_FORMAT_AC3_DESC_SIZE 0x0A - - -/* Audio Data Format Codes */ - -/* Audio Data Format Type I Codes */ -#define AUDIO_FORMAT_TYPE_I_UNDEFINED 0x0000 -#define AUDIO_FORMAT_PCM 0x0001 -#define AUDIO_FORMAT_PCM8 0x0002 -#define AUDIO_FORMAT_IEEE_FLOAT 0x0003 -#define AUDIO_FORMAT_ALAW 0x0004 -#define AUDIO_FORMAT_MULAW 0x0005 - -/* Audio Data Format Type II Codes */ -#define AUDIO_FORMAT_TYPE_II_UNDEFINED 0x1000 -#define AUDIO_FORMAT_MPEG 0x1001 -#define AUDIO_FORMAT_AC3 0x1002 - -/* Audio Data Format Type III Codes */ -#define AUDIO_FORMAT_TYPE_III_UNDEFINED 0x2000 -#define AUDIO_FORMAT_IEC1937_AC3 0x2001 -#define AUDIO_FORMAT_IEC1937_MPEG1_L1 0x2002 -#define AUDIO_FORMAT_IEC1937_MPEG1_L2_3 0x2003 -#define AUDIO_FORMAT_IEC1937_MPEG2_NOEXT 0x2003 -#define AUDIO_FORMAT_IEC1937_MPEG2_EXT 0x2004 -#define AUDIO_FORMAT_IEC1937_MPEG2_L1_LS 0x2005 -#define AUDIO_FORMAT_IEC1937_MPEG2_L2_3 0x2006 - - -/* Predefined Audio Channel Configuration Bits */ -#define AUDIO_CHANNEL_M 0x0000 /* Mono */ -#define AUDIO_CHANNEL_L 0x0001 /* Left Front */ -#define AUDIO_CHANNEL_R 0x0002 /* Right Front */ -#define AUDIO_CHANNEL_C 0x0004 /* Center Front */ -#define AUDIO_CHANNEL_LFE 0x0008 /* Low Freq. Enhance. */ -#define AUDIO_CHANNEL_LS 0x0010 /* Left Surround */ -#define AUDIO_CHANNEL_RS 0x0020 /* Right Surround */ -#define AUDIO_CHANNEL_LC 0x0040 /* Left of Center */ -#define AUDIO_CHANNEL_RC 0x0080 /* Right of Center */ -#define AUDIO_CHANNEL_S 0x0100 /* Surround */ -#define AUDIO_CHANNEL_SL 0x0200 /* Side Left */ -#define AUDIO_CHANNEL_SR 0x0400 /* Side Right */ -#define AUDIO_CHANNEL_T 0x0800 /* Top */ - - -/* Feature Unit Control Bits */ -#define AUDIO_CONTROL_MUTE 0x0001 -#define AUDIO_CONTROL_VOLUME 0x0002 -#define AUDIO_CONTROL_BASS 0x0004 -#define AUDIO_CONTROL_MID 0x0008 -#define AUDIO_CONTROL_TREBLE 0x0010 -#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020 -#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040 -#define AUDIO_CONTROL_DEALY 0x0080 -#define AUDIO_CONTROL_BASS_BOOST 0x0100 -#define AUDIO_CONTROL_LOUDNESS 0x0200 - -/* Processing Unit Control Bits: */ -#define AUDIO_CONTROL_ENABLE 0x0001 /* Common Bit */ -#define AUDIO_CONTROL_MODE_SELECT 0x0002 /* Common Bit */ - -/* - Up/Down-mix Control Bits */ -/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ -/* AUDIO_CONTROL_MODE_SELECT 0x0002 Common Bit */ - -/* - Dolby Prologic Control Bits */ -/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ -/* AUDIO_CONTROL_MODE_SELECT 0x0002 Common Bit */ - -/* - 3D Stereo Extender Control Bits */ -/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ -#define AUDIO_CONTROL_SPACIOUSNESS 0x0002 - -/* - Reverberation Control Bits */ -/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ -#define AUDIO_CONTROL_REVERB_TYPE 0x0002 -#define AUDIO_CONTROL_REVERB_LEVEL 0x0004 -#define AUDIO_CONTROL_REVERB_TIME 0x0008 -#define AUDIO_CONTROL_REVERB_FEEDBACK 0x0010 - -/* - Chorus Control Bits */ -/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ -#define AUDIO_CONTROL_CHORUS_LEVEL 0x0002 -#define AUDIO_CONTROL_SHORUS_RATE 0x0004 -#define AUDIO_CONTROL_CHORUS_DEPTH 0x0008 - -/* - Dynamic Range Compressor Control Bits */ -/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ -#define AUDIO_CONTROL_COMPRESSION_RATE 0x0002 -#define AUDIO_CONTROL_MAX_AMPL 0x0004 -#define AUDIO_CONTROL_THRESHOLD 0x0008 -#define AUDIO_CONTROL_ATTACK_TIME 0x0010 -#define AUDIO_CONTROL_RELEASE_TIME 0x0020 - -/* Extension Unit Control Bits */ -/* AUDIO_CONTROL_ENABLE 0x0001 Common Bit */ - -/* Endpoint Control Bits */ -#define AUDIO_CONTROL_SAMPLING_FREQ 0x01 -#define AUDIO_CONTROL_PITCH 0x02 -#define AUDIO_MAX_PACKETS_ONLY 0x80 - - -/* Audio Terminal Types */ - -/* USB Terminal Types */ -#define AUDIO_TERMINAL_USB_UNDEFINED 0x0100 -#define AUDIO_TERMINAL_USB_STREAMING 0x0101 -#define AUDIO_TERMINAL_USB_VENDOR_SPECIFIC 0x01FF - -/* Input Terminal Types */ -#define AUDIO_TERMINAL_INPUT_UNDEFINED 0x0200 -#define AUDIO_TERMINAL_MICROPHONE 0x0201 -#define AUDIO_TERMINAL_DESKTOP_MICROPHONE 0x0202 -#define AUDIO_TERMINAL_PERSONAL_MICROPHONE 0x0203 -#define AUDIO_TERMINAL_OMNI_DIR_MICROPHONE 0x0204 -#define AUDIO_TERMINAL_MICROPHONE_ARRAY 0x0205 -#define AUDIO_TERMINAL_PROCESSING_MIC_ARRAY 0x0206 - -/* Output Terminal Types */ -#define AUDIO_TERMINAL_OUTPUT_UNDEFINED 0x0300 -#define AUDIO_TERMINAL_SPEAKER 0x0301 -#define AUDIO_TERMINAL_HEADPHONES 0x0302 -#define AUDIO_TERMINAL_HEAD_MOUNTED_AUDIO 0x0303 -#define AUDIO_TERMINAL_DESKTOP_SPEAKER 0x0304 -#define AUDIO_TERMINAL_ROOM_SPEAKER 0x0305 -#define AUDIO_TERMINAL_COMMUNICATION_SPEAKER 0x0306 -#define AUDIO_TERMINAL_LOW_FREQ_SPEAKER 0x0307 - -/* Bi-directional Terminal Types */ -#define AUDIO_TERMINAL_BIDIRECTIONAL_UNDEFINED 0x0400 -#define AUDIO_TERMINAL_HANDSET 0x0401 -#define AUDIO_TERMINAL_HEAD_MOUNTED_HANDSET 0x0402 -#define AUDIO_TERMINAL_SPEAKERPHONE 0x0403 -#define AUDIO_TERMINAL_SPEAKERPHONE_ECHOSUPRESS 0x0404 -#define AUDIO_TERMINAL_SPEAKERPHONE_ECHOCANCEL 0x0405 - -/* Telephony Terminal Types */ -#define AUDIO_TERMINAL_TELEPHONY_UNDEFINED 0x0500 -#define AUDIO_TERMINAL_PHONE_LINE 0x0501 -#define AUDIO_TERMINAL_TELEPHONE 0x0502 -#define AUDIO_TERMINAL_DOWN_LINE_PHONE 0x0503 - -/* External Terminal Types */ -#define AUDIO_TERMINAL_EXTERNAL_UNDEFINED 0x0600 -#define AUDIO_TERMINAL_ANALOG_CONNECTOR 0x0601 -#define AUDIO_TERMINAL_DIGITAL_AUDIO_INTERFACE 0x0602 -#define AUDIO_TERMINAL_LINE_CONNECTOR 0x0603 -#define AUDIO_TERMINAL_LEGACY_AUDIO_CONNECTOR 0x0604 -#define AUDIO_TERMINAL_SPDIF_INTERFACE 0x0605 -#define AUDIO_TERMINAL_1394_DA_STREAM 0x0606 -#define AUDIO_TERMINAL_1394_DA_STREAM_TRACK 0x0607 - -/* Embedded Function Terminal Types */ -#define AUDIO_TERMINAL_EMBEDDED_UNDEFINED 0x0700 -#define AUDIO_TERMINAL_CALIBRATION_NOISE 0x0701 -#define AUDIO_TERMINAL_EQUALIZATION_NOISE 0x0702 -#define AUDIO_TERMINAL_CD_PLAYER 0x0703 -#define AUDIO_TERMINAL_DAT 0x0704 -#define AUDIO_TERMINAL_DCC 0x0705 -#define AUDIO_TERMINAL_MINI_DISK 0x0706 -#define AUDIO_TERMINAL_ANALOG_TAPE 0x0707 -#define AUDIO_TERMINAL_PHONOGRAPH 0x0708 -#define AUDIO_TERMINAL_VCR_AUDIO 0x0709 -#define AUDIO_TERMINAL_VIDEO_DISC_AUDIO 0x070A -#define AUDIO_TERMINAL_DVD_AUDIO 0x070B -#define AUDIO_TERMINAL_TV_TUNER_AUDIO 0x070C -#define AUDIO_TERMINAL_SATELLITE_RECEIVER_AUDIO 0x070D -#define AUDIO_TERMINAL_CABLE_TUNER_AUDIO 0x070E -#define AUDIO_TERMINAL_DSS_AUDIO 0x070F -#define AUDIO_TERMINAL_RADIO_RECEIVER 0x0710 -#define AUDIO_TERMINAL_RADIO_TRANSMITTER 0x0711 -#define AUDIO_TERMINAL_MULTI_TRACK_RECORDER 0x0712 -#define AUDIO_TERMINAL_SYNTHESIZER 0x0713 - - -#endif /* __AUDIO_H__ */ diff --git a/plugins/USBqemu/usb-mic/demo.h b/plugins/USBqemu/usb-mic/demo.h deleted file mode 100644 index ac5ae21b08..0000000000 --- a/plugins/USBqemu/usb-mic/demo.h +++ /dev/null @@ -1,45 +0,0 @@ -/*---------------------------------------------------------------------------- - * Name: DEMO.H - * Purpose: USB Audio Demo Definitions - * Version: V1.10 - *---------------------------------------------------------------------------- - * This software is supplied "AS IS" without any warranties, express, - * implied or statutory, including but not limited to the implied - * warranties of fitness for purpose, satisfactory quality and - * noninfringement. Keil extends you a royalty-free right to reproduce - * and distribute executable files created using this software for use - * on Philips LPC2xxx microcontroller devices only. Nothing else gives - * you the right to use this software. - * - * Copyright (c) 2005-2006 Keil Software. - *---------------------------------------------------------------------------*/ - -/* Clock Definitions */ -#define CPU_CLOCK 60000000 /* CPU Clock */ -#define VPB_CLOCK (CPU_CLOCK/1) /* VPB Clock */ - -/* Audio Definitions */ -#define DATA_FREQ 32000 /* Audio Data Frequency */ -#define P_S 32 /* Packet Size */ -#if USB_DMA -#define P_C 4 /* Packet Count */ -#else -#define P_C 1 /* Packet Count */ -#endif -#define B_S (8*P_C*P_S) /* Buffer Size */ - -/* Push Button Definitions */ -#define PBINT 0x00004000 /* P0.14 */ - -/* LED Definitions */ -#define LEDMSK 0x00FF0000 /* P1.16..23 */ - -/* Audio Demo Variables */ -extern BYTE Mute; /* Mute State */ -extern DWORD Volume; /* Volume Level */ -extern WORD VolCur; /* Volume Current Value */ -extern DWORD InfoBuf[P_C]; /* Packet Info Buffer */ -extern short DataBuf[B_S]; /* Data Buffer */ -extern WORD DataOut; /* Data Out Index */ -extern WORD DataIn; /* Data In Index */ -extern BYTE DataRun; /* Data Stream Run State */ diff --git a/plugins/USBqemu/usb-mic/type.h b/plugins/USBqemu/usb-mic/type.h deleted file mode 100644 index b2fe61d77c..0000000000 --- a/plugins/USBqemu/usb-mic/type.h +++ /dev/null @@ -1,22 +0,0 @@ - -#ifndef __TYPE_H__ -#define __TYPE_H__ - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (1) -#endif - -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long DWORD; -//typedef unsigned int BOOL; - -#endif /* __TYPE_H__ */ diff --git a/plugins/USBqemu/usb-mic/usb-mic-dummy.cpp b/plugins/USBqemu/usb-mic/usb-mic-dummy.cpp deleted file mode 100644 index 113c819133..0000000000 --- a/plugins/USBqemu/usb-mic/usb-mic-dummy.cpp +++ /dev/null @@ -1,431 +0,0 @@ -/* - * QEMU USB HID devices - * - * Copyright (c) 2005 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "../qemu-usb/vl.h" - -/* HID interface requests */ -#define GET_REPORT 0xa101 -#define GET_IDLE 0xa102 -#define GET_PROTOCOL 0xa103 -#define SET_IDLE 0x210a -#define SET_PROTOCOL 0x210b - -#define USB_MOUSE 1 -#define USB_TABLET 2 - -#include "type.h" - -#include "usb.h" -#include "audio.h" -#include "usbcfg.h" -#include "usbdesc.h" - -typedef struct SINGSTARMICState { - USBDevice dev; - //nothing yet -} SINGSTARMICState; - -/* descriptor dumped from a real singstar MIC adapter */ -static const uint8_t singstar_mic_dev_descriptor[] = { - /* bLength */ 0x12, //(18) - /* bDescriptorType */ 0x01, //(1) - /* bcdUSB */ WBVAL(0x0110), //(272) - /* bDeviceClass */ 0x00, //(0) - /* bDeviceSubClass */ 0x00, //(0) - /* bDeviceProtocol */ 0x00, //(0) - /* bMaxPacketSize0 */ 0x08, //(8) - /* idVendor */ WBVAL(0x1415), //(5141) - /* idProduct */ WBVAL(0x0000), //(0) - /* bcdDevice */ WBVAL(0x0001), //(1) - /* iManufacturer */ 0x01, //(1) - /* iProduct */ 0x02, //(2) - /* iSerialNumber */ 0x00, //(0) - /* bNumConfigurations */ 0x01, //(1) - -}; - -static const uint8_t singstar_mic_config_descriptor[] = { - -/* Configuration 1 */ - 0x09, /* bLength */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ - WBVAL(0x00b1), /* wTotalLength */ - 0x02, /* bNumInterfaces */ - 0x01, /* bConfigurationValue */ - 0x00, /* iConfiguration */ - USB_CONFIG_BUS_POWERED, /* bmAttributes */ - USB_CONFIG_POWER_MA(90), /* bMaxPower */ - -/* Interface 0, Alternate Setting 0, Audio Control */ - USB_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x00, /* bInterfaceNumber */ - 0x00, /* bAlternateSetting */ - 0x00, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - -/* Audio Control Interface */ - AUDIO_CONTROL_INTERFACE_DESC_SZ(1), /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ - WBVAL(0x0100), /* 1.00 */ /* bcdADC */ - WBVAL(0x0028), /* wTotalLength */ - 0x01, /* bInCollection */ - 0x01, /* baInterfaceNr */ - -/* Audio Input Terminal */ - AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */ - 0x01, /* bTerminalID */ - WBVAL(AUDIO_TERMINAL_MICROPHONE), /* wTerminalType */ - 0x02, /* bAssocTerminal */ - 0x02, /* bNrChannels */ - WBVAL(AUDIO_CHANNEL_L - |AUDIO_CHANNEL_R), /* wChannelConfig */ - 0x00, /* iChannelNames */ - 0x00, /* iTerminal */ - -/* Audio Output Terminal */ - AUDIO_OUTPUT_TERMINAL_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ - 0x02, /* bTerminalID */ - WBVAL(AUDIO_TERMINAL_USB_STREAMING), /* wTerminalType */ - 0x01, /* bAssocTerminal */ - 0x03, /* bSourceID */ - 0x00, /* iTerminal */ - -/* Audio Feature Unit */ - AUDIO_FEATURE_UNIT_DESC_SZ(2,1), /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */ - 0x03, /* bUnitID */ - 0x01, /* bSourceID */ - 0x01, /* bControlSize */ - 0x01, /* bmaControls(0) */ - 0x02, /* bmaControls(1) */ - 0x02, /* bmaControls(2) */ - 0x00, /* iTerminal */ - -/* Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith */ - USB_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x01, /* bInterfaceNumber */ - 0x00, /* bAlternateSetting */ - 0x00, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - -/* Interface 1, Alternate Setting 1, Audio Streaming - Operational */ - USB_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x01, /* bInterfaceNumber */ - 0x01, /* bAlternateSetting */ - 0x01, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - -/* Audio Streaming Interface */ - AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ - 0x02, /* bTerminalLink */ - 0x01, /* bDelay */ - WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag */ - -/* Audio Type I Format */ - AUDIO_FORMAT_TYPE_I_DESC_SZ(5), /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ - AUDIO_FORMAT_TYPE_I, /* bFormatType */ - 0x01, /* bNrChannels */ - 0x02, /* bSubFrameSize */ - 0x10, /* bBitResolution */ - 0x05, /* bSamFreqType */ - B3VAL(8000), /* tSamFreq 1 */ - B3VAL(11025), /* tSamFreq 2 */ - B3VAL(22050), /* tSamFreq 3 */ - B3VAL(44100), /* tSamFreq 4 */ - B3VAL(48000), /* tSamFreq 5 */ - -/* Endpoint - Standard Descriptor */ - AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - USB_ENDPOINT_OUT(0x81), /* bEndpointAddress */ - USB_ENDPOINT_TYPE_ISOCHRONOUS - | USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */ - WBVAL(0x0064), /* wMaxPacketSize */ - 0x01, /* bInterval */ - 0x00, /* bRefresh */ - 0x00, /* bSynchAddress */ - -/* Endpoint - Audio Streaming */ - AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ - AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ - 0x01, /* bmAttributes */ - 0x00, /* bLockDelayUnits */ - WBVAL(0x0000), /* wLockDelay */ - -/* Interface 1, Alternate Setting 2, Audio Streaming - ? */ - USB_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x01, /* bInterfaceNumber */ - 0x02, /* bAlternateSetting */ - 0x01, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ - -/* Audio Streaming Interface */ - AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ - 0x02, /* bTerminalLink */ - 0x01, /* bDelay */ - WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag */ - -/* Audio Type I Format */ - AUDIO_FORMAT_TYPE_I_DESC_SZ(5), /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ - AUDIO_FORMAT_TYPE_I, /* bFormatType */ - 0x02, /* bNrChannels */ - 0x02, /* bSubFrameSize */ - 0x10, /* bBitResolution */ - 0x05, /* bSamFreqType */ - B3VAL(8000), /* tSamFreq 1 */ - B3VAL(11025), /* tSamFreq 2 */ - B3VAL(22050), /* tSamFreq 3 */ - B3VAL(44100), /* tSamFreq 4 */ - B3VAL(48000), /* tSamFreq 5 */ - -/* Endpoint - Standard Descriptor */ - AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - USB_ENDPOINT_OUT(0x81), /* bEndpointAddress */ - USB_ENDPOINT_TYPE_ISOCHRONOUS - | USB_ENDPOINT_SYNC_ASYNCHRONOUS, /* bmAttributes */ - WBVAL(0x00c8), /* wMaxPacketSize */ - 0x01, /* bInterval */ - 0x00, /* bRefresh */ - 0x00, /* bSynchAddress */ - -/* Endpoint - Audio Streaming */ - AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ - AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ - 0x01, /* bmAttributes */ - 0x00, /* bLockDelayUnits */ - WBVAL(0x0000), /* wLockDelay */ - -/* Terminator */ - 0 /* bLength */ -}; - - -static void singstar_mic_handle_reset(USBDevice *dev) -{ - /* XXX: do it */ - return; -} - -static int singstar_mic_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) -{ - SINGSTARMICState *s = (SINGSTARMICState *)dev; - int ret = 0; - - switch(request) { - case DeviceRequest | USB_REQ_GET_STATUS: - data[0] = (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP); - data[1] = 0x00; - ret = 2; - break; - case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: - if (value == USB_DEVICE_REMOTE_WAKEUP) { - dev->remote_wakeup = 0; - } else { - goto fail; - } - ret = 0; - break; - case DeviceOutRequest | USB_REQ_SET_FEATURE: - if (value == USB_DEVICE_REMOTE_WAKEUP) { - dev->remote_wakeup = 1; - } else { - goto fail; - } - ret = 0; - break; - case DeviceOutRequest | USB_REQ_SET_ADDRESS: - dev->addr = value; - ret = 0; - break; - case DeviceRequest | USB_REQ_GET_DESCRIPTOR: - switch(value >> 8) { - case USB_DT_DEVICE: - memcpy(data, singstar_mic_dev_descriptor, - sizeof(singstar_mic_dev_descriptor)); - ret = sizeof(singstar_mic_dev_descriptor); - break; - case USB_DT_CONFIG: - memcpy(data, singstar_mic_config_descriptor, - sizeof(singstar_mic_config_descriptor)); - ret = sizeof(singstar_mic_config_descriptor); - break; - case USB_DT_STRING: - switch(value & 0xff) { - case 0: - /* language ids */ - data[0] = 4; - data[1] = 3; - data[2] = 0x09; - data[3] = 0x04; - ret = 4; - break; - case 1: - /* serial number */ - ret = set_usb_string(data, "3X0420811"); - break; - case 2: - /* product description */ - ret = set_usb_string(data, "EyeToy USB camera Namtai"); - break; - case 3: - /* vendor description */ - ret = set_usb_string(data, "PCSX2/QEMU"); - break; - default: - goto fail; - } - break; - default: - goto fail; - } - break; - case DeviceRequest | USB_REQ_GET_CONFIGURATION: - data[0] = 1; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: - ret = 0; - break; - case DeviceRequest | USB_REQ_GET_INTERFACE: - data[0] = 0; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_INTERFACE: - ret = 0; - break; - /* hid specific requests */ - case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: - //switch(value >> 8) { - //((case 0x22: - // memcpy(data, qemu_mouse_hid_report_descriptor, - // sizeof(qemu_mouse_hid_report_descriptor)); - // ret = sizeof(qemu_mouse_hid_report_descriptor); - // break; - //default: - goto fail; - //} - break; - case GET_REPORT: - ret = 0; - break; - case SET_IDLE: - ret = 0; - break; - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static int singstar_mic_handle_data(USBDevice *dev, int pid, - uint8_t devep, uint8_t *data, int len) -{ - SINGSTARMICState *s = (SINGSTARMICState *)dev; - int ret = 0; - - switch(pid) { - case USB_TOKEN_IN: - if (devep == 1) { - goto fail; - } - break; - case USB_TOKEN_OUT: - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - - -static void singstar_mic_handle_destroy(USBDevice *dev) -{ - SINGSTARMICState *s = (SINGSTARMICState *)dev; - - free(s); -} - -int singstar_mic_handle_packet(USBDevice *s, int pid, - uint8_t devaddr, uint8_t devep, - uint8_t *data, int len) -{ - fprintf(stderr,"usb-singstar_mic: packet received with pid=%x, devaddr=%x, devep=%x and len=%x\n",pid,devaddr,devep,len); - return usb_generic_handle_packet(s,pid,devaddr,devep,data,len); -} - -USBDevice *singstar_mic_init() -{ - SINGSTARMICState *s; - - s = (SINGSTARMICState *)qemu_mallocz(sizeof(SINGSTARMICState)); - if (!s) - return NULL; - s->dev.speed = USB_SPEED_FULL; - s->dev.handle_packet = singstar_mic_handle_packet; - s->dev.handle_reset = singstar_mic_handle_reset; - s->dev.handle_control = singstar_mic_handle_control; - s->dev.handle_data = singstar_mic_handle_data; - s->dev.handle_destroy = singstar_mic_handle_destroy; - - strncpy(s->dev.devname, "EyeToy USB camera Namtai", sizeof(s->dev.devname)); - - return (USBDevice *)s; - -} diff --git a/plugins/USBqemu/usb-mic/usb-mic.c b/plugins/USBqemu/usb-mic/usb-mic.c deleted file mode 100644 index a93705a5dc..0000000000 --- a/plugins/USBqemu/usb-mic/usb-mic.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * QEMU USB HID devices - * - * Copyright (c) 2005 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "vl.h" - -/* HID interface requests */ -#define GET_REPORT 0xa101 -#define GET_IDLE 0xa102 -#define GET_PROTOCOL 0xa103 -#define SET_IDLE 0x210a -#define SET_PROTOCOL 0x210b - -#define USB_MOUSE 1 -#define USB_TABLET 2 - -#include "type.h" - -#include "usb.h" -#include "audio.h" -#include "usbcfg.h" -#include "usbdesc.h" - -/* mostly the same values as the Bochs USB Mouse device */ -static const uint8_t qemu_mic_dev_descriptor[] = { - sizeof(qemu_mic_dev_descriptor), /* bLength */ - 1, /* bDescriptorType */ - WBVAL(0x0110), /* 1.10 */ /* bcdUSB */ - 0x00, /* bDeviceClass */ - 0x00, /* bDeviceSubClass */ - 0x00, /* bDeviceProtocol */ - USB_MAX_PACKET0, /* bMaxPacketSize0 */ - WBVAL(0xC251), /* idVendor */ - WBVAL(0x1304), /* idProduct */ - WBVAL(0x0100), /* 1.00 */ /* bcdDevice */ - 0x04, /* iManufacturer */ - 0x20, /* iProduct */ - 0x4A, /* iSerialNumber */ - 0x01 /* bNumConfigurations */ -}; - -static const uint8_t qemu_mic_config_descriptor[] = { -/* Configuration 1 */ - sizeof(qemu_mic_config_descriptor), /* bLength */ - USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ - WBVAL( /* wTotalLength */ - USB_CONFIGUARTION_DESC_SIZE + - USB_INTERFACE_DESC_SIZE + - AUDIO_CONTROL_INTERFACE_DESC_SZ(1) + - AUDIO_INPUT_TERMINAL_DESC_SIZE + - AUDIO_FEATURE_UNIT_DESC_SZ(1,1) + - AUDIO_OUTPUT_TERMINAL_DESC_SIZE + - USB_INTERFACE_DESC_SIZE + - USB_INTERFACE_DESC_SIZE + - AUDIO_STREAMING_INTERFACE_DESC_SIZE + - AUDIO_FORMAT_TYPE_I_DESC_SZ(1) + - AUDIO_STANDARD_ENDPOINT_DESC_SIZE + - AUDIO_STREAMING_ENDPOINT_DESC_SIZE - ), - 0x02, /* bNumInterfaces */ - 0x01, /* bConfigurationValue */ - 0x00, /* iConfiguration */ - USB_CONFIG_BUS_POWERED, /* bmAttributes */ - USB_CONFIG_POWER_MA(100), /* bMaxPower */ -/* Interface 0, Alternate Setting 0, Audio Control */ - USB_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x00, /* bInterfaceNumber */ - 0x00, /* bAlternateSetting */ - 0x00, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ -/* Audio Control Interface */ - AUDIO_CONTROL_INTERFACE_DESC_SZ(1), /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ - WBVAL(0x0100), /* 1.00 */ /* bcdADC */ - WBVAL( /* wTotalLength */ - AUDIO_CONTROL_INTERFACE_DESC_SZ(1) + - AUDIO_INPUT_TERMINAL_DESC_SIZE + - AUDIO_FEATURE_UNIT_DESC_SZ(1,1) + - AUDIO_OUTPUT_TERMINAL_DESC_SIZE - ), - 0x01, /* bInCollection */ - 0x01, /* baInterfaceNr */ -/* Audio Input Terminal */ - AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */ - 0x01, /* bTerminalID */ - WBVAL(AUDIO_TERMINAL_USB_STREAMING), /* wTerminalType */ - 0x00, /* bAssocTerminal */ - 0x01, /* bNrChannels */ - WBVAL(AUDIO_CHANNEL_M), /* wChannelConfig */ - 0x00, /* iChannelNames */ - 0x00, /* iTerminal */ -/* Audio Feature Unit */ - AUDIO_FEATURE_UNIT_DESC_SZ(1,1), /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */ - 0x02, /* bUnitID */ - 0x01, /* bSourceID */ - 0x01, /* bControlSize */ - AUDIO_CONTROL_MUTE | - AUDIO_CONTROL_VOLUME, /* bmaControls(0) */ - 0x00, /* bmaControls(1) */ - 0x00, /* iTerminal */ -/* Audio Output Terminal */ - AUDIO_OUTPUT_TERMINAL_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ - 0x03, /* bTerminalID */ - WBVAL(AUDIO_TERMINAL_SPEAKER), /* wTerminalType */ - 0x00, /* bAssocTerminal */ - 0x02, /* bSourceID */ - 0x00, /* iTerminal */ -/* Interface 1, Alternate Setting 0, Audio Streaming - Zero Bandwith */ - USB_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x01, /* bInterfaceNumber */ - 0x00, /* bAlternateSetting */ - 0x00, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ -/* Interface 1, Alternate Setting 1, Audio Streaming - Operational */ - USB_INTERFACE_DESC_SIZE, /* bLength */ - USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - 0x01, /* bInterfaceNumber */ - 0x01, /* bAlternateSetting */ - 0x01, /* bNumEndpoints */ - USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ - AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ - AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ - 0x00, /* iInterface */ -/* Audio Streaming Interface */ - AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ - 0x01, /* bTerminalLink */ - 0x01, /* bDelay */ - WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag */ -/* Audio Type I Format */ - AUDIO_FORMAT_TYPE_I_DESC_SZ(1), /* bLength */ - AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ - AUDIO_FORMAT_TYPE_I, /* bFormatType */ - 0x01, /* bNrChannels */ - 0x02, /* bSubFrameSize */ - 16, /* bBitResolution */ - 0x01, /* bSamFreqType */ - B3VAL(32000), /* tSamFreq */ -/* Endpoint - Standard Descriptor */ - AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ - USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - USB_ENDPOINT_OUT(3), /* bEndpointAddress */ - USB_ENDPOINT_TYPE_ISOCHRONOUS, /* bmAttributes */ - WBVAL(64), /* wMaxPacketSize */ - 0x01, /* bInterval */ - 0x00, /* bRefresh */ - 0x00, /* bSynchAddress */ -/* Endpoint - Audio Streaming */ - AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ - AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ - AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ - 0x00, /* bmAttributes */ - 0x00, /* bLockDelayUnits */ - WBVAL(0x0000), /* wLockDelay */ -/* Terminator */ - 0 /* bLength */ -}; - -static const uint8_t qemu_tablet_config_descriptor[] = { - /* one configuration */ - 0x09, /* u8 bLength; */ - 0x02, /* u8 bDescriptorType; Configuration */ - 0x22, 0x00, /* u16 wTotalLength; */ - 0x01, /* u8 bNumInterfaces; (1) */ - 0x01, /* u8 bConfigurationValue; */ - 0x04, /* u8 iConfiguration; */ - 0xa0, /* u8 bmAttributes; - Bit 7: must be set, - 6: Self-powered, - 5: Remote wakeup, - 4..0: resvd */ - 50, /* u8 MaxPower; */ - - /* USB 1.1: - * USB 2.0, single TT organization (mandatory): - * one interface, protocol 0 - * - * USB 2.0, multiple TT organization (optional): - * two interfaces, protocols 1 (like single TT) - * and 2 (multiple TT mode) ... config is - * sometimes settable - * NOT IMPLEMENTED - */ - - /* one interface */ - 0x09, /* u8 if_bLength; */ - 0x04, /* u8 if_bDescriptorType; Interface */ - 0x00, /* u8 if_bInterfaceNumber; */ - 0x00, /* u8 if_bAlternateSetting; */ - 0x01, /* u8 if_bNumEndpoints; */ - 0x03, /* u8 if_bInterfaceClass; */ - 0x01, /* u8 if_bInterfaceSubClass; */ - 0x02, /* u8 if_bInterfaceProtocol; [usb1.1 or single tt] */ - 0x05, /* u8 if_iInterface; */ - - /* HID descriptor */ - 0x09, /* u8 bLength; */ - 0x21, /* u8 bDescriptorType; */ - 0x01, 0x00, /* u16 HID_class */ - 0x00, /* u8 country_code */ - 0x01, /* u8 num_descriptors */ - 0x22, /* u8 type; Report */ - 74, 0, /* u16 len */ - - /* one endpoint (status change endpoint) */ - 0x07, /* u8 ep_bLength; */ - 0x05, /* u8 ep_bDescriptorType; Endpoint */ - 0x81, /* u8 ep_bEndpointAddress; IN Endpoint 1 */ - 0x03, /* u8 ep_bmAttributes; Interrupt */ - 0x08, 0x00, /* u16 ep_wMaxPacketSize; */ - 0x03, /* u8 ep_bInterval; (255ms -- usb 2.0 spec) */ -}; - -static const uint8_t qemu_mouse_hid_report_descriptor[] = { - 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, - 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, - 0x15, 0x00, 0x25, 0x01, 0x95, 0x03, 0x75, 0x01, - 0x81, 0x02, 0x95, 0x01, 0x75, 0x05, 0x81, 0x01, - 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x81, - 0x25, 0x7F, 0x75, 0x08, 0x95, 0x02, 0x81, 0x06, - 0xC0, 0xC0, -}; - -static const uint8_t qemu_tablet_hid_report_descriptor[] = { - 0x05, 0x01, /* Usage Page Generic Desktop */ - 0x09, 0x01, /* Usage Mouse */ - 0xA1, 0x01, /* Collection Application */ - 0x09, 0x01, /* Usage Pointer */ - 0xA1, 0x00, /* Collection Physical */ - 0x05, 0x09, /* Usage Page Button */ - 0x19, 0x01, /* Usage Minimum Button 1 */ - 0x29, 0x03, /* Usage Maximum Button 3 */ - 0x15, 0x00, /* Logical Minimum 0 */ - 0x25, 0x01, /* Logical Maximum 1 */ - 0x95, 0x03, /* Report Count 3 */ - 0x75, 0x01, /* Report Size 1 */ - 0x81, 0x02, /* Input (Data, Var, Abs) */ - 0x95, 0x01, /* Report Count 1 */ - 0x75, 0x05, /* Report Size 5 */ - 0x81, 0x01, /* Input (Cnst, Var, Abs) */ - 0x05, 0x01, /* Usage Page Generic Desktop */ - 0x09, 0x30, /* Usage X */ - 0x09, 0x31, /* Usage Y */ - 0x15, 0x00, /* Logical Minimum 0 */ - 0x26, 0xFF, 0x7F, /* Logical Maximum 0x7fff */ - 0x35, 0x00, /* Physical Minimum 0 */ - 0x46, 0xFE, 0x7F, /* Physical Maximum 0x7fff */ - 0x75, 0x10, /* Report Size 16 */ - 0x95, 0x02, /* Report Count 2 */ - 0x81, 0x02, /* Input (Data, Var, Abs) */ - 0x05, 0x01, /* Usage Page Generic Desktop */ - 0x09, 0x38, /* Usage Wheel */ - 0x15, 0x81, /* Logical Minimum -127 */ - 0x25, 0x7F, /* Logical Maximum 127 */ - 0x35, 0x00, /* Physical Minimum 0 (same as logical) */ - 0x45, 0x00, /* Physical Maximum 0 (same as logical) */ - 0x75, 0x08, /* Report Size 8 */ - 0x95, 0x01, /* Report Count 1 */ - 0x81, 0x02, /* Input (Data, Var, Rel) */ - 0xC0, /* End Collection */ - 0xC0, /* End Collection */ -}; - -static void usb_mouse_event(void *opaque, - int dx1, int dy1, int dz1, int buttons_state) -{ - USBMouseState *s = opaque; - - s->dx += dx1; - s->dy += dy1; - s->dz += dz1; - s->buttons_state = buttons_state; -} - -static void usb_tablet_event(void *opaque, - int x, int y, int dz, int buttons_state) -{ - USBMouseState *s = opaque; - - s->x = x; - s->y = y; - s->dz += dz; - s->buttons_state = buttons_state; -} - -static inline int int_clamp(int val, int vmin, int vmax) -{ - if (val < vmin) - return vmin; - else if (val > vmax) - return vmax; - else - return val; -} - -static int usb_mouse_poll(USBMouseState *s, uint8_t *buf, int len) -{ - int dx, dy, dz, b, l; - - if (!s->mouse_grabbed) { - qemu_add_mouse_event_handler(usb_mouse_event, s, 0); - s->mouse_grabbed = 1; - } - - dx = int_clamp(s->dx, -128, 127); - dy = int_clamp(s->dy, -128, 127); - dz = int_clamp(s->dz, -128, 127); - - s->dx -= dx; - s->dy -= dy; - s->dz -= dz; - - b = 0; - if (s->buttons_state & MOUSE_EVENT_LBUTTON) - b |= 0x01; - if (s->buttons_state & MOUSE_EVENT_RBUTTON) - b |= 0x02; - if (s->buttons_state & MOUSE_EVENT_MBUTTON) - b |= 0x04; - - buf[0] = b; - buf[1] = dx; - buf[2] = dy; - l = 3; - if (len >= 4) { - buf[3] = dz; - l = 4; - } - return l; -} - -static int usb_tablet_poll(USBMouseState *s, uint8_t *buf, int len) -{ - int dz, b, l; - - if (!s->mouse_grabbed) { - qemu_add_mouse_event_handler(usb_tablet_event, s, 1); - s->mouse_grabbed = 1; - } - - dz = int_clamp(s->dz, -128, 127); - s->dz -= dz; - - /* Appears we have to invert the wheel direction */ - dz = 0 - dz; - b = 0; - if (s->buttons_state & MOUSE_EVENT_LBUTTON) - b |= 0x01; - if (s->buttons_state & MOUSE_EVENT_RBUTTON) - b |= 0x02; - if (s->buttons_state & MOUSE_EVENT_MBUTTON) - b |= 0x04; - - buf[0] = b; - buf[1] = s->x & 0xff; - buf[2] = s->x >> 8; - buf[3] = s->y & 0xff; - buf[4] = s->y >> 8; - buf[5] = dz; - l = 6; - - return l; -} - -static void usb_mouse_handle_reset(USBDevice *dev) -{ - USBMouseState *s = (USBMouseState *)dev; - - s->dx = 0; - s->dy = 0; - s->dz = 0; - s->x = 0; - s->y = 0; - s->buttons_state = 0; -} - -static int usb_mouse_handle_control(USBDevice *dev, int request, int value, - int index, int length, uint8_t *data) -{ - USBMouseState *s = (USBMouseState *)dev; - int ret = 0; - - switch(request) { - case DeviceRequest | USB_REQ_GET_STATUS: - data[0] = (1 << USB_DEVICE_SELF_POWERED) | - (dev->remote_wakeup << USB_DEVICE_REMOTE_WAKEUP); - data[1] = 0x00; - ret = 2; - break; - case DeviceOutRequest | USB_REQ_CLEAR_FEATURE: - if (value == USB_DEVICE_REMOTE_WAKEUP) { - dev->remote_wakeup = 0; - } else { - goto fail; - } - ret = 0; - break; - case DeviceOutRequest | USB_REQ_SET_FEATURE: - if (value == USB_DEVICE_REMOTE_WAKEUP) { - dev->remote_wakeup = 1; - } else { - goto fail; - } - ret = 0; - break; - case DeviceOutRequest | USB_REQ_SET_ADDRESS: - dev->addr = value; - ret = 0; - break; - case DeviceRequest | USB_REQ_GET_DESCRIPTOR: - switch(value >> 8) { - case USB_DT_DEVICE: - memcpy(data, qemu_mouse_dev_descriptor, - sizeof(qemu_mouse_dev_descriptor)); - ret = sizeof(qemu_mouse_dev_descriptor); - break; - case USB_DT_CONFIG: - if (s->kind == USB_MOUSE) { - memcpy(data, qemu_mouse_config_descriptor, - sizeof(qemu_mouse_config_descriptor)); - ret = sizeof(qemu_mouse_config_descriptor); - } else if (s->kind == USB_TABLET) { - memcpy(data, qemu_tablet_config_descriptor, - sizeof(qemu_tablet_config_descriptor)); - ret = sizeof(qemu_tablet_config_descriptor); - } - break; - case USB_DT_STRING: - switch(value & 0xff) { - case 0: - /* language ids */ - data[0] = 4; - data[1] = 3; - data[2] = 0x09; - data[3] = 0x04; - ret = 4; - break; - case 1: - /* serial number */ - ret = set_usb_string(data, "1"); - break; - case 2: - /* product description */ - if (s->kind == USB_MOUSE) - ret = set_usb_string(data, "QEMU USB Mouse"); - else if (s->kind == USB_TABLET) - ret = set_usb_string(data, "QEMU USB Tablet"); - break; - case 3: - /* vendor description */ - ret = set_usb_string(data, "PCSX2/QEMU"); - break; - case 4: - ret = set_usb_string(data, "HID Mouse"); - break; - case 5: - ret = set_usb_string(data, "Endpoint1 Interrupt Pipe"); - break; - default: - goto fail; - } - break; - default: - goto fail; - } - break; - case DeviceRequest | USB_REQ_GET_CONFIGURATION: - data[0] = 1; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_CONFIGURATION: - ret = 0; - break; - case DeviceRequest | USB_REQ_GET_INTERFACE: - data[0] = 0; - ret = 1; - break; - case DeviceOutRequest | USB_REQ_SET_INTERFACE: - ret = 0; - break; - /* hid specific requests */ - case InterfaceRequest | USB_REQ_GET_DESCRIPTOR: - switch(value >> 8) { - case 0x22: - if (s->kind == USB_MOUSE) { - memcpy(data, qemu_mouse_hid_report_descriptor, - sizeof(qemu_mouse_hid_report_descriptor)); - ret = sizeof(qemu_mouse_hid_report_descriptor); - } else if (s->kind == USB_TABLET) { - memcpy(data, qemu_tablet_hid_report_descriptor, - sizeof(qemu_tablet_hid_report_descriptor)); - ret = sizeof(qemu_tablet_hid_report_descriptor); - } - break; - default: - goto fail; - } - break; - case GET_REPORT: - if (s->kind == USB_MOUSE) - ret = usb_mouse_poll(s, data, length); - else if (s->kind == USB_TABLET) - ret = usb_tablet_poll(s, data, length); - break; - case SET_IDLE: - ret = 0; - break; - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static int usb_mouse_handle_data(USBDevice *dev, int pid, - uint8_t devep, uint8_t *data, int len) -{ - USBMouseState *s = (USBMouseState *)dev; - int ret = 0; - - switch(pid) { - case USB_TOKEN_IN: - if (devep == 1) { - if (s->kind == USB_MOUSE) - ret = usb_mouse_poll(s, data, len); - else if (s->kind == USB_TABLET) - ret = usb_tablet_poll(s, data, len); - } else { - goto fail; - } - break; - case USB_TOKEN_OUT: - default: - fail: - ret = USB_RET_STALL; - break; - } - return ret; -} - -static void usb_mouse_handle_destroy(USBDevice *dev) -{ - USBMouseState *s = (USBMouseState *)dev; - - qemu_add_mouse_event_handler(NULL, NULL, 0); - free(s); -} - -USBDevice *usb_tablet_init(void) -{ - USBMouseState *s; - - s = qemu_mallocz(sizeof(USBMouseState)); - if (!s) - return NULL; - s->dev.speed = USB_SPEED_FULL; - s->dev.handle_packet = usb_generic_handle_packet; - - s->dev.handle_reset = usb_mouse_handle_reset; - s->dev.handle_control = usb_mouse_handle_control; - s->dev.handle_data = usb_mouse_handle_data; - s->dev.handle_destroy = usb_mouse_handle_destroy; - s->kind = USB_TABLET; - - pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Tablet"); - - return (USBDevice *)s; -} - -USBDevice *usb_mouse_init(void) -{ - USBMouseState *s; - - s = qemu_mallocz(sizeof(USBMouseState)); - if (!s) - return NULL; - s->dev.speed = USB_SPEED_FULL; - s->dev.handle_packet = usb_generic_handle_packet; - - s->dev.handle_reset = usb_mouse_handle_reset; - s->dev.handle_control = usb_mouse_handle_control; - s->dev.handle_data = usb_mouse_handle_data; - s->dev.handle_destroy = usb_mouse_handle_destroy; - s->kind = USB_MOUSE; - - pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Mouse"); - - return (USBDevice *)s; -} diff --git a/plugins/USBqemu/usb-mic/usb.h b/plugins/USBqemu/usb-mic/usb.h deleted file mode 100644 index e0a0a0e677..0000000000 --- a/plugins/USBqemu/usb-mic/usb.h +++ /dev/null @@ -1,230 +0,0 @@ -/*---------------------------------------------------------------------------- - * U S B - K e r n e l - *---------------------------------------------------------------------------- - * Name: USB.H - * Purpose: USB Definitions - * Version: V1.10 - *---------------------------------------------------------------------------- - * This software is supplied "AS IS" without any warranties, express, - * implied or statutory, including but not limited to the implied - * warranties of fitness for purpose, satisfactory quality and - * noninfringement. Keil extends you a royalty-free right to reproduce - * and distribute executable files created using this software for use - * on Philips LPC2xxx microcontroller devices only. Nothing else gives - * you the right to use this software. - * - * Copyright (c) 2005-2006 Keil Software. - *---------------------------------------------------------------------------*/ - -#ifndef __USB_H__ -#define __USB_H__ - - -#pragma pack(1) - - -typedef union { - WORD W; - struct { - BYTE L; - BYTE H; - } WB; -} WORD_BYTE; - - -/* bmRequestType.Dir */ -#define REQUEST_HOST_TO_DEVICE 0 -#define REQUEST_DEVICE_TO_HOST 1 - -/* bmRequestType.Type */ -#define REQUEST_STANDARD 0 -#define REQUEST_CLASS 1 -#define REQUEST_VENDOR 2 -#define REQUEST_RESERVED 3 - -/* bmRequestType.Recipient */ -#define REQUEST_TO_DEVICE 0 -#define REQUEST_TO_INTERFACE 1 -#define REQUEST_TO_ENDPOINT 2 -#define REQUEST_TO_OTHER 3 - -/* bmRequestType Definition */ -typedef union _REQUEST_TYPE { - struct _BM { - BYTE Recipient : 5; - BYTE Type : 2; - BYTE Dir : 1; - } BM; - BYTE B; -} REQUEST_TYPE; - -/* USB Standard Request Codes */ -#define USB_REQUEST_GET_STATUS 0 -#define USB_REQUEST_CLEAR_FEATURE 1 -#define USB_REQUEST_SET_FEATURE 3 -#define USB_REQUEST_SET_ADDRESS 5 -#define USB_REQUEST_GET_DESCRIPTOR 6 -#define USB_REQUEST_SET_DESCRIPTOR 7 -#define USB_REQUEST_GET_CONFIGURATION 8 -#define USB_REQUEST_SET_CONFIGURATION 9 -#define USB_REQUEST_GET_INTERFACE 10 -#define USB_REQUEST_SET_INTERFACE 11 -#define USB_REQUEST_SYNC_FRAME 12 - -/* USB GET_STATUS Bit Values */ -#define USB_GETSTATUS_SELF_POWERED 0x01 -#define USB_GETSTATUS_REMOTE_WAKEUP 0x02 -#define USB_GETSTATUS_ENDPOINT_STALL 0x01 - -/* USB Standard Feature selectors */ -#define USB_FEATURE_ENDPOINT_STALL 0 -#define USB_FEATURE_REMOTE_WAKEUP 1 - -/* USB Default Control Pipe Setup Packet */ -typedef struct _USB_SETUP_PACKET { - REQUEST_TYPE bmRequestType; - BYTE bRequest; - WORD_BYTE wValue; - WORD_BYTE wIndex; - WORD wLength; -} USB_SETUP_PACKET; - - -/* USB Descriptor Types */ -#define USB_DEVICE_DESCRIPTOR_TYPE 1 -#define USB_CONFIGURATION_DESCRIPTOR_TYPE 2 -#define USB_STRING_DESCRIPTOR_TYPE 3 -#define USB_INTERFACE_DESCRIPTOR_TYPE 4 -#define USB_ENDPOINT_DESCRIPTOR_TYPE 5 -#define USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE 6 -#define USB_OTHER_SPEED_CONFIG_DESCRIPTOR_TYPE 7 -#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 8 - -/* USB Device Classes */ -#define USB_DEVICE_CLASS_RESERVED 0x00 -#define USB_DEVICE_CLASS_AUDIO 0x01 -#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02 -#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03 -#define USB_DEVICE_CLASS_MONITOR 0x04 -#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05 -#define USB_DEVICE_CLASS_POWER 0x06 -#define USB_DEVICE_CLASS_PRINTER 0x07 -#define USB_DEVICE_CLASS_STORAGE 0x08 -#define USB_DEVICE_CLASS_HUB 0x09 -#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF - -/* bmAttributes in Configuration Descriptor */ -#define USB_CONFIG_POWERED_MASK 0xC0 -#define USB_CONFIG_BUS_POWERED 0x80 -#define USB_CONFIG_SELF_POWERED 0x40 -#define USB_CONFIG_REMOTE_WAKEUP 0x20 - -/* bMaxPower in Configuration Descriptor */ -#define USB_CONFIG_POWER_MA(mA) ((mA)/2) - -/* bEndpointAddress in Endpoint Descriptor */ -#define USB_ENDPOINT_DIRECTION_MASK 0x80 -#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00) -#define USB_ENDPOINT_IN(addr) ((addr) | 0x80) - -/* bmAttributes in Endpoint Descriptor */ -#define USB_ENDPOINT_TYPE_MASK 0x03 -#define USB_ENDPOINT_TYPE_CONTROL 0x00 -#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01 -#define USB_ENDPOINT_TYPE_BULK 0x02 -#define USB_ENDPOINT_TYPE_INTERRUPT 0x03 -#define USB_ENDPOINT_SYNC_MASK 0x0C -#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00 -#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04 -#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08 -#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C -#define USB_ENDPOINT_USAGE_MASK 0x30 -#define USB_ENDPOINT_USAGE_DATA 0x00 -#define USB_ENDPOINT_USAGE_FEEDBACK 0x10 -#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20 -#define USB_ENDPOINT_USAGE_RESERVED 0x30 - -/* USB Standard Device Descriptor */ -typedef struct _USB_DEVICE_DESCRIPTOR { - BYTE bLength; - BYTE bDescriptorType; - WORD bcdUSB; - BYTE bDeviceClass; - BYTE bDeviceSubClass; - BYTE bDeviceProtocol; - BYTE bMaxPacketSize0; - WORD idVendor; - WORD idProduct; - WORD bcdDevice; - BYTE iManufacturer; - BYTE iProduct; - BYTE iSerialNumber; - BYTE bNumConfigurations; -} USB_DEVICE_DESCRIPTOR; - -/* USB 2.0 Device Qualifier Descriptor */ -typedef struct _USB_DEVICE_QUALIFIER_DESCRIPTOR { - BYTE bLength; - BYTE bDescriptorType; - WORD bcdUSB; - BYTE bDeviceClass; - BYTE bDeviceSubClass; - BYTE bDeviceProtocol; - BYTE bMaxPacketSize0; - BYTE bNumConfigurations; - BYTE bReserved; -} USB_DEVICE_QUALIFIER_DESCRIPTOR; - -/* USB Standard Configuration Descriptor */ -typedef struct _USB_CONFIGURATION_DESCRIPTOR { - BYTE bLength; - BYTE bDescriptorType; - WORD wTotalLength; - BYTE bNumInterfaces; - BYTE bConfigurationValue; - BYTE iConfiguration; - BYTE bmAttributes; - BYTE MaxPower; -} USB_CONFIGURATION_DESCRIPTOR; - -/* USB Standard Interface Descriptor */ -typedef struct _USB_INTERFACE_DESCRIPTOR { - BYTE bLength; - BYTE bDescriptorType; - BYTE bInterfaceNumber; - BYTE bAlternateSetting; - BYTE bNumEndpoints; - BYTE bInterfaceClass; - BYTE bInterfaceSubClass; - BYTE bInterfaceProtocol; - BYTE iInterface; -} USB_INTERFACE_DESCRIPTOR; - -/* USB Standard Endpoint Descriptor */ -typedef struct _USB_ENDPOINT_DESCRIPTOR { - BYTE bLength; - BYTE bDescriptorType; - BYTE bEndpointAddress; - BYTE bmAttributes; - WORD wMaxPacketSize; - BYTE bInterval; -} USB_ENDPOINT_DESCRIPTOR; - -/* USB String Descriptor */ -typedef struct _USB_STRING_DESCRIPTOR { - BYTE bLength; - BYTE bDescriptorType; - WORD bString/*[]*/; -} USB_STRING_DESCRIPTOR; - -/* USB Common Descriptor */ -typedef struct _USB_COMMON_DESCRIPTOR { - BYTE bLength; - BYTE bDescriptorType; -} USB_COMMON_DESCRIPTOR; - - -#pragma pack() - - -#endif /* __USB_H__ */ diff --git a/plugins/USBqemu/usb-mic/usbcfg.h b/plugins/USBqemu/usb-mic/usbcfg.h deleted file mode 100644 index 6275a4a107..0000000000 --- a/plugins/USBqemu/usb-mic/usbcfg.h +++ /dev/null @@ -1,161 +0,0 @@ -/*---------------------------------------------------------------------------- - * U S B - K e r n e l - *---------------------------------------------------------------------------- - * Name: USBCFG.H - * Purpose: USB Custom Configuration - * Version: V1.10 - *---------------------------------------------------------------------------- - * This software is supplied "AS IS" without any warranties, express, - * implied or statutory, including but not limited to the implied - * warranties of fitness for purpose, satisfactory quality and - * noninfringement. Keil extends you a royalty-free right to reproduce - * and distribute executable files created using this software for use - * on Philips LPC2xxx microcontroller devices only. Nothing else gives - * you the right to use this software. - * - * Copyright (c) 2005-2006 Keil Software. - *---------------------------------------------------------------------------*/ - -#ifndef __USBCFG_H__ -#define __USBCFG_H__ - - -/* -//*** <<< Use Configuration Wizard in Context Menu >>> *** -*/ - - -/* -// USB Configuration -// USB Power -// Default Power Setting -// <0=> Bus-powered -// <1=> Self-powered -// Max Number of Interfaces <1-256> -// Max Number of Endpoints <1-32> -// Max Endpoint 0 Packet Size -// <8=> 8 Bytes <16=> 16 Bytes <32=> 32 Bytes <64=> 64 Bytes -// DMA Transfer -// Use DMA for selected Endpoints -// Endpoint 0 Out -// Endpoint 0 In -// Endpoint 1 Out -// Endpoint 1 In -// Endpoint 2 Out -// Endpoint 2 In -// Endpoint 3 Out -// Endpoint 3 In -// Endpoint 4 Out -// Endpoint 4 In -// Endpoint 5 Out -// Endpoint 5 In -// Endpoint 6 Out -// Endpoint 6 In -// Endpoint 7 Out -// Endpoint 7 In -// Endpoint 8 Out -// Endpoint 8 In -// Endpoint 9 Out -// Endpoint 9 In -// Endpoint 10 Out -// Endpoint 10 In -// Endpoint 11 Out -// Endpoint 11 In -// Endpoint 12 Out -// Endpoint 12 In -// Endpoint 13 Out -// Endpoint 13 In -// Endpoint 14 Out -// Endpoint 14 In -// Endpoint 15 Out -// Endpoint 15 In -// -// -*/ - -#define USB_POWER 0 -#define USB_IF_NUM 4 -#define USB_EP_NUM 32 -#define USB_MAX_PACKET0 64 -#define USB_DMA 0 -#define USB_DMA_EP 0x00000040 - - -/* -// USB Event Handlers -// Device Events -// Power Event -// Reset Event -// Suspend Event -// Resume Event -// Remote Wakeup Event -// Start of Frame Event -// Error Event -// -// Endpoint Events -// Endpoint 0 Event -// Endpoint 1 Event -// Endpoint 2 Event -// Endpoint 3 Event -// Endpoint 4 Event -// Endpoint 5 Event -// Endpoint 6 Event -// Endpoint 7 Event -// Endpoint 8 Event -// Endpoint 9 Event -// Endpoint 10 Event -// Endpoint 11 Event -// Endpoint 12 Event -// Endpoint 13 Event -// Endpoint 14 Event -// Endpoint 15 Event -// -// USB Core Events -// Set Configuration Event -// Set Interface Event -// Set/Clear Feature Event -// -// -*/ - -#define USB_POWER_EVENT 0 -#define USB_RESET_EVENT 1 -#define USB_SUSPEND_EVENT 0 -#define USB_RESUME_EVENT 0 -#define USB_WAKEUP_EVENT 0 -#define USB_SOF_EVENT 1 -#define USB_ERROR_EVENT 0 -#define USB_EP_EVENT 0x0009 -#define USB_CONFIGURE_EVENT 0 -#define USB_INTERFACE_EVENT 0 -#define USB_FEATURE_EVENT 0 - - -/* -// USB Class Support -// Human Interface Device (HID) -// Interface Number <0-255> -// -// Mass Storage -// Interface Number <0-255> -// -// Audio Device -// Control Interface Number <0-255> -// Streaming Interface 1 Number <0-255> -// Streaming Interface 2 Number <0-255> -// -// -*/ - -#define USB_CLASS 1 -#define USB_HID 0 -#define USB_HID_IF_NUM 0 -#define USB_MSC 0 -#define USB_MSC_IF_NUM 0 -#define USB_AUDIO 1 -#define USB_ADC_CIF_NUM 0 -#define USB_ADC_SIF1_NUM 1 -#define USB_ADC_SIF2_NUM 2 - - -#endif /* __USBCFG_H__ */ diff --git a/plugins/USBqemu/usb-mic/usbcore.h b/plugins/USBqemu/usb-mic/usbcore.h deleted file mode 100644 index eb27f4a3df..0000000000 --- a/plugins/USBqemu/usb-mic/usbcore.h +++ /dev/null @@ -1,50 +0,0 @@ -/*---------------------------------------------------------------------------- - * U S B - K e r n e l - *---------------------------------------------------------------------------- - * Name: USBCORE.H - * Purpose: USB Core Definitions - * Version: V1.10 - *---------------------------------------------------------------------------- - * This software is supplied "AS IS" without any warranties, express, - * implied or statutory, including but not limited to the implied - * warranties of fitness for purpose, satisfactory quality and - * noninfringement. Keil extends you a royalty-free right to reproduce - * and distribute executable files created using this software for use - * on Philips LPC2xxx microcontroller devices only. Nothing else gives - * you the right to use this software. - * - * Copyright (c) 2005-2006 Keil Software. - *---------------------------------------------------------------------------*/ - -#ifndef __USBCORE_H__ -#define __USBCORE_H__ - - -/* USB Endpoint Data Structure */ -typedef struct _USB_EP_DATA { - BYTE *pData; - WORD Count; -} USB_EP_DATA; - -/* USB Core Global Variables */ -extern WORD USB_DeviceStatus; -extern BYTE USB_DeviceAddress; -extern BYTE USB_Configuration; -extern DWORD USB_EndPointMask; -extern DWORD USB_EndPointHalt; -extern BYTE USB_AltSetting[USB_IF_NUM]; - -/* USB Endpoint 0 Buffer */ -extern BYTE EP0Buf[USB_MAX_PACKET0]; - -/* USB Endpoint 0 Data Info */ -extern USB_EP_DATA EP0Data; - -/* USB Setup Packet */ -extern USB_SETUP_PACKET SetupPacket; - -/* USB Core Functions */ -extern void USB_ResetCore (void); - - -#endif /* __USBCORE_H__ */ diff --git a/plugins/USBqemu/usb-mic/usbdesc.h b/plugins/USBqemu/usb-mic/usbdesc.h deleted file mode 100644 index e7e22da8e5..0000000000 --- a/plugins/USBqemu/usb-mic/usbdesc.h +++ /dev/null @@ -1,36 +0,0 @@ -/*---------------------------------------------------------------------------- - * U S B - K e r n e l - *---------------------------------------------------------------------------- - * Name: USBDESC.C - * Purpose: USB Descriptors Definitions - * Version: V1.10 - *---------------------------------------------------------------------------- - * This software is supplied "AS IS" without any warranties, express, - * implied or statutory, including but not limited to the implied - * warranties of fitness for purpose, satisfactory quality and - * noninfringement. Keil extends you a royalty-free right to reproduce - * and distribute executable files created using this software for use - * on Philips LPC2xxx microcontroller devices only. Nothing else gives - * you the right to use this software. - * - * Copyright (c) 2005-2006 Keil Software. - *---------------------------------------------------------------------------*/ - -#ifndef __USBDESC_H__ -#define __USBDESC_H__ - - -#define WBVAL(x) (x & 0xFF),((x >> 8) & 0xFF) -#define B3VAL(x) (x & 0xFF),((x >> 8) & 0xFF),((x >> 16) & 0xFF) - -#define USB_DEVICE_DESC_SIZE (sizeof(USB_DEVICE_DESCRIPTOR)) -#define USB_CONFIGUARTION_DESC_SIZE (sizeof(USB_CONFIGURATION_DESCRIPTOR)) -#define USB_INTERFACE_DESC_SIZE (sizeof(USB_INTERFACE_DESCRIPTOR)) -#define USB_ENDPOINT_DESC_SIZE (sizeof(USB_ENDPOINT_DESCRIPTOR)) - -extern const BYTE USB_DeviceDescriptor[]; -extern const BYTE USB_ConfigDescriptor[]; -extern const BYTE USB_StringDescriptor[]; - - -#endif /* __USBDESC_H__ */ diff --git a/plugins/USBqemu/usb-mic/usbhw.h b/plugins/USBqemu/usb-mic/usbhw.h deleted file mode 100644 index 55953976e7..0000000000 --- a/plugins/USBqemu/usb-mic/usbhw.h +++ /dev/null @@ -1,107 +0,0 @@ -/*---------------------------------------------------------------------------- - * U S B - K e r n e l - *---------------------------------------------------------------------------- - * Name: USBHW.H - * Purpose: USB Hardware Layer Definitions - * Version: V1.10 - *---------------------------------------------------------------------------- - * This software is supplied "AS IS" without any warranties, express, - * implied or statutory, including but not limited to the implied - * warranties of fitness for purpose, satisfactory quality and - * noninfringement. Keil extends you a royalty-free right to reproduce - * and distribute executable files created using this software for use - * on Philips LPC2xxx microcontroller devices only. Nothing else gives - * you the right to use this software. - * - * Copyright (c) 2005-2006 Keil Software. - *---------------------------------------------------------------------------*/ - -#ifndef __USBHW_H__ -#define __USBHW_H__ - - -/* USB RAM Definitions */ -#define USB_RAM_ADR 0x7FD00000 /* USB RAM Start Address */ -#define USB_RAM_SZ 0x00002000 /* USB RAM Size (8kB) */ - -/* DMA Endpoint Descriptors */ -#define DD_NISO_CNT 16 /* Non-Iso EP DMA Descr. Count (max. 32) */ -#define DD_ISO_CNT 8 /* Iso EP DMA Descriptor Count (max. 32) */ -#define DD_NISO_SZ (DD_NISO_CNT * 16) /* Non-Iso DMA Descr. Size */ -#define DD_ISO_SZ (DD_ISO_CNT * 20) /* Iso DMA Descriptor Size */ -#define DD_NISO_ADR (USB_RAM_ADR + 128) /* Non-Iso DMA Descr. Address */ -#define DD_ISO_ADR (DD_NISO_ADR + DD_NISO_SZ) /* Iso DMA Descr. Address */ -#define DD_SZ (128 + DD_NISO_SZ + DD_ISO_SZ) /* Descr. Size */ - -/* DMA Buffer Memory Definitions */ -#define DMA_BUF_ADR (USB_RAM_ADR + DD_SZ) /* DMA Buffer Start Address */ -#define DMA_BUF_SZ (USB_RAM_SZ - DD_SZ) /* DMA Buffer Size */ - -/* USB Error Codes */ -#define USB_ERR_PID 0x0001 /* PID Error */ -#define USB_ERR_UEPKT 0x0002 /* Unexpected Packet */ -#define USB_ERR_DCRC 0x0004 /* Data CRC Error */ -#define USB_ERR_TIMOUT 0x0008 /* Bus Time-out Error */ -#define USB_ERR_EOP 0x0010 /* End of Packet Error */ -#define USB_ERR_B_OVRN 0x0020 /* Buffer Overrun */ -#define USB_ERR_BTSTF 0x0040 /* Bit Stuff Error */ -#define USB_ERR_TGL 0x0080 /* Toggle Bit Error */ - -/* USB DMA Status Codes */ -#define USB_DMA_INVALID 0x0000 /* DMA Invalid - Not Configured */ -#define USB_DMA_IDLE 0x0001 /* DMA Idle - Waiting for Trigger */ -#define USB_DMA_BUSY 0x0002 /* DMA Busy - Transfer in progress */ -#define USB_DMA_DONE 0x0003 /* DMA Transfer Done (no Errors)*/ -#define USB_DMA_OVER_RUN 0x0004 /* Data Over Run */ -#define USB_DMA_UNDER_RUN 0x0005 /* Data Under Run (Short Packet) */ -#define USB_DMA_ERROR 0x0006 /* Error */ -#define USB_DMA_UNKNOWN 0xFFFF /* Unknown State */ - -/* USB DMA Descriptor */ -typedef struct _USB_DMA_DESCRIPTOR { - DWORD BufAdr; /* DMA Buffer Address */ - WORD BufLen; /* DMA Buffer Length */ - WORD MaxSize; /* Maximum Packet Size */ - DWORD InfoAdr; /* Packet Info Memory Address */ - union { /* DMA Configuration */ - struct { - DWORD Link : 1; /* Link to existing Descriptors */ - DWORD IsoEP : 1; /* Isonchronous Endpoint */ - DWORD ATLE : 1; /* ATLE (Auto Transfer Length Extract) */ - DWORD Rsrvd : 5; /* Reserved */ - DWORD LenPos : 8; /* Length Position (ATLE) */ - } Type; - DWORD Val; - } Cfg; -} USB_DMA_DESCRIPTOR; - -/* USB Hardware Functions */ -extern void USB_Init (void); -extern void USB_Connect (BOOL con); -extern void USB_Reset (void); -extern void USB_Suspend (void); -extern void USB_Resume (void); -extern void USB_WakeUp (void); -extern void USB_WakeUpCfg (BOOL cfg); -extern void USB_SetAddress (DWORD adr); -extern void USB_Configure (BOOL cfg); -extern void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD); -extern void USB_DirCtrlEP (DWORD dir); -extern void USB_EnableEP (DWORD EPNum); -extern void USB_DisableEP (DWORD EPNum); -extern void USB_ResetEP (DWORD EPNum); -extern void USB_SetStallEP (DWORD EPNum); -extern void USB_ClrStallEP (DWORD EPNum); -extern DWORD USB_ReadEP (DWORD EPNum, BYTE *pData); -extern DWORD USB_WriteEP (DWORD EPNum, BYTE *pData, DWORD cnt); -extern BOOL USB_DMA_Setup (DWORD EPNum, USB_DMA_DESCRIPTOR *pDD); -extern void USB_DMA_Enable (DWORD EPNum); -extern void USB_DMA_Disable(DWORD EPNum); -extern DWORD USB_DMA_Status (DWORD EPNum); -extern DWORD USB_DMA_BufAdr (DWORD EPNum); -extern DWORD USB_DMA_BufCnt (DWORD EPNum); -extern DWORD USB_GetFrame (void); -extern void USB_ISR (void) __irq; - - -#endif /* __USBHW_H__ */ diff --git a/plugins/USBqemu/usb-mic/usbreg.h b/plugins/USBqemu/usb-mic/usbreg.h deleted file mode 100644 index e075cb96f3..0000000000 --- a/plugins/USBqemu/usb-mic/usbreg.h +++ /dev/null @@ -1,195 +0,0 @@ -/***********************************************************************/ -/* This file is part of the uVision/ARM development tools */ -/* Copyright KEIL ELEKTRONIK GmbH 2002-2006 */ -/***********************************************************************/ -/* */ -/* USBREG.H: Header file for Philips LPC214X USB */ -/* */ -/***********************************************************************/ - -#ifndef __USBREG_H -#define __USBREG_H - - -#define SCB_BASE_ADDR 0xE01FC000 /* System Control Block */ - -/* PLL48 Registers */ -#define PLL48CON (*(volatile unsigned int*)(SCB_BASE_ADDR + 0xA0)) -#define PLL48CFG (*(volatile unsigned int*)(SCB_BASE_ADDR + 0xA4)) -#define PLL48STAT (*(volatile unsigned int*)(SCB_BASE_ADDR + 0xA8)) -#define PLL48FEED (*(volatile unsigned int*)(SCB_BASE_ADDR + 0xAC)) - -/* PLL48 Bit Definitions */ -#define PLLCON_PLLE (1<<0) /* PLL Enable */ -#define PLLCON_PLLC (1<<1) /* PLL Connect */ -#define PLLCFG_MSEL (0x1F<<0) /* PLL Multiplier */ -#define PLLCFG_PSEL (0x03<<5) /* PLL Divider */ -#define PLLSTAT_PLOCK (1<<10) /* PLL Lock Status */ - - -#define USB_BASE_ADDR 0xE0090000 /* USB Base Address */ - -/* Device Interrupt Registers */ -#define DEV_INT_STAT (*(volatile unsigned int*)(USB_BASE_ADDR + 0x00)) -#define DEV_INT_EN (*(volatile unsigned int*)(USB_BASE_ADDR + 0x04)) -#define DEV_INT_CLR (*(volatile unsigned int*)(USB_BASE_ADDR + 0x08)) -#define DEV_INT_SET (*(volatile unsigned int*)(USB_BASE_ADDR + 0x0C)) -#define DEV_INT_PRIO (*(volatile unsigned int*)(USB_BASE_ADDR + 0x2C)) - -/* Endpoint Interrupt Registers */ -#define EP_INT_STAT (*(volatile unsigned int*)(USB_BASE_ADDR + 0x30)) -#define EP_INT_EN (*(volatile unsigned int*)(USB_BASE_ADDR + 0x34)) -#define EP_INT_CLR (*(volatile unsigned int*)(USB_BASE_ADDR + 0x38)) -#define EP_INT_SET (*(volatile unsigned int*)(USB_BASE_ADDR + 0x3C)) -#define EP_INT_PRIO (*(volatile unsigned int*)(USB_BASE_ADDR + 0x40)) - -/* Endpoint Realization Registers */ -#define REALIZE_EP (*(volatile unsigned int*)(USB_BASE_ADDR + 0x44)) -#define EP_INDEX (*(volatile unsigned int*)(USB_BASE_ADDR + 0x48)) -#define MAXPACKET_SIZE (*(volatile unsigned int*)(USB_BASE_ADDR + 0x4C)) - -/* Command Reagisters */ -#define CMD_CODE (*(volatile unsigned int*)(USB_BASE_ADDR + 0x10)) -#define CMD_DATA (*(volatile unsigned int*)(USB_BASE_ADDR + 0x14)) - -/* Data Transfer Registers */ -#define RX_DATA (*(volatile unsigned int*)(USB_BASE_ADDR + 0x18)) -#define TX_DATA (*(volatile unsigned int*)(USB_BASE_ADDR + 0x1C)) -#define RX_PLENGTH (*(volatile unsigned int*)(USB_BASE_ADDR + 0x20)) -#define TX_PLENGTH (*(volatile unsigned int*)(USB_BASE_ADDR + 0x24)) -#define USB_CTRL (*(volatile unsigned int*)(USB_BASE_ADDR + 0x28)) - -/* System Register */ -#define DC_REVISION (*(volatile unsigned int*)(USB_BASE_ADDR + 0x7C)) - -/* DMA Registers */ -#define DMA_REQ_STAT (*(volatile unsigned int*)(USB_BASE_ADDR + 0x50)) -#define DMA_REQ_CLR (*(volatile unsigned int*)(USB_BASE_ADDR + 0x54)) -#define DMA_REQ_SET (*(volatile unsigned int*)(USB_BASE_ADDR + 0x58)) -#define UDCA_HEAD (*(volatile unsigned int*)(USB_BASE_ADDR + 0x80)) -#define EP_DMA_STAT (*(volatile unsigned int*)(USB_BASE_ADDR + 0x84)) -#define EP_DMA_EN (*(volatile unsigned int*)(USB_BASE_ADDR + 0x88)) -#define EP_DMA_DIS (*(volatile unsigned int*)(USB_BASE_ADDR + 0x8C)) -#define DMA_INT_STAT (*(volatile unsigned int*)(USB_BASE_ADDR + 0x90)) -#define DMA_INT_EN (*(volatile unsigned int*)(USB_BASE_ADDR + 0x94)) -#define EOT_INT_STAT (*(volatile unsigned int*)(USB_BASE_ADDR + 0xA0)) -#define EOT_INT_CLR (*(volatile unsigned int*)(USB_BASE_ADDR + 0xA4)) -#define EOT_INT_SET (*(volatile unsigned int*)(USB_BASE_ADDR + 0xA8)) -#define NDD_REQ_INT_STAT (*(volatile unsigned int*)(USB_BASE_ADDR + 0xAC)) -#define NDD_REQ_INT_CLR (*(volatile unsigned int*)(USB_BASE_ADDR + 0xB0)) -#define NDD_REQ_INT_SET (*(volatile unsigned int*)(USB_BASE_ADDR + 0xB4)) -#define SYS_ERR_INT_STAT (*(volatile unsigned int*)(USB_BASE_ADDR + 0xB8)) -#define SYS_ERR_INT_CLR (*(volatile unsigned int*)(USB_BASE_ADDR + 0xBC)) -#define SYS_ERR_INT_SET (*(volatile unsigned int*)(USB_BASE_ADDR + 0xC0)) -#define MODULE_ID (*(volatile unsigned int*)(USB_BASE_ADDR + 0xFC)) - - -/* Device Interrupt Bit Definitions */ -#define FRAME_INT 0x00000001 -#define EP_FAST_INT 0x00000002 -#define EP_SLOW_INT 0x00000004 -#define DEV_STAT_INT 0x00000008 -#define CCEMTY_INT 0x00000010 -#define CDFULL_INT 0x00000020 -#define RxENDPKT_INT 0x00000040 -#define TxENDPKT_INT 0x00000080 -#define EP_RLZED_INT 0x00000100 -#define ERR_INT 0x00000200 - -/* Rx & Tx Packet Length Definitions */ -#define PKT_LNGTH_MASK 0x000003FF -#define PKT_DV 0x00000400 -#define PKT_RDY 0x00000800 - -/* USB Control Definitions */ -#define CTRL_RD_EN 0x00000001 -#define CTRL_WR_EN 0x00000002 - -/* Command Codes */ -#define CMD_SET_ADDR 0x00D00500 -#define CMD_CFG_DEV 0x00D80500 -#define CMD_SET_MODE 0x00F30500 -#define CMD_RD_FRAME 0x00F50500 -#define DAT_RD_FRAME 0x00F50200 -#define CMD_RD_TEST 0x00FD0500 -#define DAT_RD_TEST 0x00FD0200 -#define CMD_SET_DEV_STAT 0x00FE0500 -#define CMD_GET_DEV_STAT 0x00FE0500 -#define DAT_GET_DEV_STAT 0x00FE0200 -#define CMD_GET_ERR_CODE 0x00FF0500 -#define DAT_GET_ERR_CODE 0x00FF0200 -#define CMD_RD_ERR_STAT 0x00FB0500 -#define DAT_RD_ERR_STAT 0x00FB0200 -#define DAT_WR_BYTE(x) (0x00000100 | ((x) << 16)) -#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16)) -#define DAT_SEL_EP(x) (0x00000200 | ((x) << 16)) -#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16)) -#define DAT_SEL_EP_CLRI(x) (0x00400200 | ((x) << 16)) -#define CMD_SET_EP_STAT(x) (0x00400500 | ((x) << 16)) -#define CMD_CLR_BUF 0x00F20500 -#define DAT_CLR_BUF 0x00F20200 -#define CMD_VALID_BUF 0x00FA0500 - -/* Device Address Register Definitions */ -#define DEV_ADDR_MASK 0x7F -#define DEV_EN 0x80 - -/* Device Configure Register Definitions */ -#define CONF_DVICE 0x01 - -/* Device Mode Register Definitions */ -#define AP_CLK 0x01 -#define INAK_CI 0x02 -#define INAK_CO 0x04 -#define INAK_II 0x08 -#define INAK_IO 0x10 -#define INAK_BI 0x20 -#define INAK_BO 0x40 - -/* Device Status Register Definitions */ -#define DEV_CON 0x01 -#define DEV_CON_CH 0x02 -#define DEV_SUS 0x04 -#define DEV_SUS_CH 0x08 -#define DEV_RST 0x10 - -/* Error Code Register Definitions */ -#define ERR_EC_MASK 0x0F -#define ERR_EA 0x10 - -/* Error Status Register Definitions */ -#define ERR_PID 0x01 -#define ERR_UEPKT 0x02 -#define ERR_DCRC 0x04 -#define ERR_TIMOUT 0x08 -#define ERR_EOP 0x10 -#define ERR_B_OVRN 0x20 -#define ERR_BTSTF 0x40 -#define ERR_TGL 0x80 - -/* Endpoint Select Register Definitions */ -#define EP_SEL_F 0x01 -#define EP_SEL_ST 0x02 -#define EP_SEL_STP 0x04 -#define EP_SEL_PO 0x08 -#define EP_SEL_EPN 0x10 -#define EP_SEL_B_1_FULL 0x20 -#define EP_SEL_B_2_FULL 0x40 - -/* Endpoint Status Register Definitions */ -#define EP_STAT_ST 0x01 -#define EP_STAT_DA 0x20 -#define EP_STAT_RF_MO 0x40 -#define EP_STAT_CND_ST 0x80 - -/* Clear Buffer Register Definitions */ -#define CLR_BUF_PO 0x01 - - -/* DMA Interrupt Bit Definitions */ -#define EOT_INT 0x01 -#define NDD_REQ_INT 0x02 -#define SYS_ERR_INT 0x04 - - -#endif /* __USBREG_H */ diff --git a/plugins/USBqemu/usb-mic/usbuser.h b/plugins/USBqemu/usb-mic/usbuser.h deleted file mode 100644 index 3c226f2fad..0000000000 --- a/plugins/USBqemu/usb-mic/usbuser.h +++ /dev/null @@ -1,74 +0,0 @@ -/*---------------------------------------------------------------------------- - * U S B - K e r n e l - *---------------------------------------------------------------------------- - * Name: USBUSER.H - * Purpose: USB Custom User Definitions - * Version: V1.10 - *---------------------------------------------------------------------------- - * This software is supplied "AS IS" without any warranties, express, - * implied or statutory, including but not limited to the implied - * warranties of fitness for purpose, satisfactory quality and - * noninfringement. Keil extends you a royalty-free right to reproduce - * and distribute executable files created using this software for use - * on Philips LPC2xxx microcontroller devices only. Nothing else gives - * you the right to use this software. - * - * Copyright (c) 2005-2006 Keil Software. - *---------------------------------------------------------------------------*/ - -#ifndef __USBUSER_H__ -#define __USBUSER_H__ - - -/* USB Device Events Callback Functions */ -extern void USB_Power_Event (BOOL power); -extern void USB_Reset_Event (void); -extern void USB_Suspend_Event (void); -extern void USB_Resume_Event (void); -extern void USB_WakeUp_Event (void); -extern void USB_SOF_Event (void); -extern void USB_Error_Event (DWORD error); - -/* USB Endpoint Callback Events */ -#define USB_EVT_SETUP 1 /* Setup Packet */ -#define USB_EVT_OUT 2 /* OUT Packet */ -#define USB_EVT_IN 3 /* IN Packet */ -#define USB_EVT_OUT_NAK 4 /* OUT Packet - Not Acknowledged */ -#define USB_EVT_IN_NAK 5 /* IN Packet - Not Acknowledged */ -#define USB_EVT_OUT_STALL 6 /* OUT Packet - Stalled */ -#define USB_EVT_IN_STALL 7 /* IN Packet - Stalled */ -#define USB_EVT_OUT_DMA_EOT 8 /* DMA OUT EP - End of Transfer */ -#define USB_EVT_IN_DMA_EOT 9 /* DMA IN EP - End of Transfer */ -#define USB_EVT_OUT_DMA_NDR 10 /* DMA OUT EP - New Descriptor Request */ -#define USB_EVT_IN_DMA_NDR 11 /* DMA IN EP - New Descriptor Request */ -#define USB_EVT_OUT_DMA_ERR 12 /* DMA OUT EP - Error */ -#define USB_EVT_IN_DMA_ERR 13 /* DMA IN EP - Error */ - -/* USB Endpoint Events Callback Pointers */ -extern void (* const USB_P_EP[16])(DWORD event); - -/* USB Endpoint Events Callback Functions */ -extern void USB_EndPoint0 (DWORD event); -extern void USB_EndPoint1 (DWORD event); -extern void USB_EndPoint2 (DWORD event); -extern void USB_EndPoint3 (DWORD event); -extern void USB_EndPoint4 (DWORD event); -extern void USB_EndPoint5 (DWORD event); -extern void USB_EndPoint6 (DWORD event); -extern void USB_EndPoint7 (DWORD event); -extern void USB_EndPoint8 (DWORD event); -extern void USB_EndPoint9 (DWORD event); -extern void USB_EndPoint10 (DWORD event); -extern void USB_EndPoint11 (DWORD event); -extern void USB_EndPoint12 (DWORD event); -extern void USB_EndPoint13 (DWORD event); -extern void USB_EndPoint14 (DWORD event); -extern void USB_EndPoint15 (DWORD event); - -/* USB Core Events Callback Functions */ -extern void USB_Configure_Event (void); -extern void USB_Interface_Event (void); -extern void USB_Feature_Event (void); - - -#endif /* __USBUSER_H__ */