^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for the Conexant Riptide Soundchip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2004 Peter Gruber <nokos@gmx.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) History:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) - 02/15/2004 first release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) This Driver is based on the OSS Driver version from Linuxant (riptide-0.6lnxtbeta03111100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) credits from the original files:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) MODULE NAME: cnxt_rt.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) AUTHOR: K. Lazarev (Transcribed by KNL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) HISTORY: Major Revision Date By
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) ----------------------------- -------- -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) Created 02/1/2000 KNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) MODULE NAME: int_mdl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) AUTHOR: Konstantin Lazarev (Transcribed by KNL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) HISTORY: Major Revision Date By
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ----------------------------- -------- -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) Created 10/01/99 KNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) MODULE NAME: riptide.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) AUTHOR: O. Druzhinin (Transcribed by OLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) HISTORY: Major Revision Date By
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ----------------------------- -------- -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) Created 10/16/97 OLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) MODULE NAME: Rp_Cmdif.cpp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) AUTHOR: O. Druzhinin (Transcribed by OLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) K. Lazarev (Transcribed by KNL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) HISTORY: Major Revision Date By
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) ----------------------------- -------- -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) Adopted from NT4 driver 6/22/99 OLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) Ported to Linux 9/01/99 KNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) MODULE NAME: rt_hw.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) AUTHOR: O. Druzhinin (Transcribed by OLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) C. Lazarev (Transcribed by CNL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) HISTORY: Major Revision Date By
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ----------------------------- -------- -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) Created 11/18/97 OLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) Hardware functions for RipTide 11/24/97 CNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) (ES1) are coded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) Hardware functions for RipTide 12/24/97 CNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) (A0) are coded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) Hardware functions for RipTide 03/20/98 CNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) (A1) are coded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) Boot loader is included 05/07/98 CNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) Redesigned for WDM 07/27/98 CNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) Redesigned for Linux 09/01/99 CNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) MODULE NAME: rt_hw.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) AUTHOR: C. Lazarev (Transcribed by CNL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) HISTORY: Major Revision Date By
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ----------------------------- -------- -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) Created 11/18/97 CNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) MODULE NAME: rt_mdl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) AUTHOR: Konstantin Lazarev (Transcribed by KNL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) HISTORY: Major Revision Date By
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ----------------------------- -------- -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) Created 10/01/99 KNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MODULE NAME: mixer.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) AUTHOR: K. Kenney
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) HISTORY: Major Revision Date By
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ----------------------------- -------- -----
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) Created from MS W95 Sample 11/28/95 KRS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) RipTide 10/15/97 KRS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) Adopted for Windows NT driver 01/20/98 CNL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #include <linux/gameport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #include <sound/ac97_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #include <sound/mpu401.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #include <sound/opl3.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #if IS_REACHABLE(CONFIG_GAMEPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define SUPPORT_JOYSTICK 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) MODULE_AUTHOR("Peter Gruber <nokos@gmx.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MODULE_DESCRIPTION("riptide");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) MODULE_FIRMWARE("riptide.hex");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int joystick_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x200 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static int mpu_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x330 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int opl3_port[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS - 1)] = 0x388 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) MODULE_PARM_DESC(index, "Index value for Riptide soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) MODULE_PARM_DESC(id, "ID string for Riptide soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) MODULE_PARM_DESC(enable, "Enable Riptide soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) module_param_hw_array(joystick_port, int, ioport, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) MODULE_PARM_DESC(joystick_port, "Joystick port # for Riptide soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) module_param_hw_array(mpu_port, int, ioport, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) MODULE_PARM_DESC(mpu_port, "MPU401 port # for Riptide driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) module_param_hw_array(opl3_port, int, ioport, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define MPU401_HW_RIPTIDE MPU401_HW_MPU401
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define OPL3_HW_RIPTIDE OPL3_HW_OPL3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define PCI_EXT_CapId 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define PCI_EXT_NextCapPrt 0x41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define PCI_EXT_PWMC 0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define PCI_EXT_PWSCR 0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define PCI_EXT_Data00 0x46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define PCI_EXT_PMSCR_BSE 0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define PCI_EXT_SB_Base 0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define PCI_EXT_FM_Base 0x4a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define PCI_EXT_MPU_Base 0x4C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define PCI_EXT_Game_Base 0x4E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define PCI_EXT_Legacy_Mask 0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define PCI_EXT_AsicRev 0x52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define PCI_EXT_Reserved3 0x53
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define LEGACY_ENABLE_ALL 0x8000 /* legacy device options */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define LEGACY_ENABLE_SB 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define LEGACY_ENABLE_FM 0x2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define LEGACY_ENABLE_MPU_INT 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define LEGACY_ENABLE_MPU 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define LEGACY_ENABLE_GAMEPORT 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define MAX_WRITE_RETRY 10 /* cmd interface limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define MAX_ERROR_COUNT 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define CMDIF_TIMEOUT 50000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define RESET_TRIES 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define READ_PORT_ULONG(p) inl((unsigned long)&(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define WRITE_PORT_ULONG(p,x) outl(x,(unsigned long)&(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define READ_AUDIO_CONTROL(p) READ_PORT_ULONG(p->audio_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define WRITE_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define UMASK_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)|x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define MASK_AUDIO_CONTROL(p,x) WRITE_PORT_ULONG(p->audio_control,READ_PORT_ULONG(p->audio_control)&x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define READ_AUDIO_STATUS(p) READ_PORT_ULONG(p->audio_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define SET_GRESET(p) UMASK_AUDIO_CONTROL(p,0x0001) /* global reset switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define UNSET_GRESET(p) MASK_AUDIO_CONTROL(p,~0x0001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define SET_AIE(p) UMASK_AUDIO_CONTROL(p,0x0004) /* interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define UNSET_AIE(p) MASK_AUDIO_CONTROL(p,~0x0004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define SET_AIACK(p) UMASK_AUDIO_CONTROL(p,0x0008) /* interrupt acknowledge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define UNSET_AIACKT(p) MASKAUDIO_CONTROL(p,~0x0008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define SET_ECMDAE(p) UMASK_AUDIO_CONTROL(p,0x0010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define UNSET_ECMDAE(p) MASK_AUDIO_CONTROL(p,~0x0010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define SET_ECMDBE(p) UMASK_AUDIO_CONTROL(p,0x0020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define UNSET_ECMDBE(p) MASK_AUDIO_CONTROL(p,~0x0020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define SET_EDATAF(p) UMASK_AUDIO_CONTROL(p,0x0040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define UNSET_EDATAF(p) MASK_AUDIO_CONTROL(p,~0x0040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define SET_EDATBF(p) UMASK_AUDIO_CONTROL(p,0x0080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define UNSET_EDATBF(p) MASK_AUDIO_CONTROL(p,~0x0080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define SET_ESBIRQON(p) UMASK_AUDIO_CONTROL(p,0x0100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define UNSET_ESBIRQON(p) MASK_AUDIO_CONTROL(p,~0x0100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define SET_EMPUIRQ(p) UMASK_AUDIO_CONTROL(p,0x0200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define UNSET_EMPUIRQ(p) MASK_AUDIO_CONTROL(p,~0x0200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define IS_CMDE(a) (READ_PORT_ULONG(a->stat)&0x1) /* cmd empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define IS_DATF(a) (READ_PORT_ULONG(a->stat)&0x2) /* data filled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define IS_READY(p) (READ_AUDIO_STATUS(p)&0x0001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define IS_DLREADY(p) (READ_AUDIO_STATUS(p)&0x0002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define IS_DLERR(p) (READ_AUDIO_STATUS(p)&0x0004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define IS_GERR(p) (READ_AUDIO_STATUS(p)&0x0008) /* error ! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define IS_CMDAEIRQ(p) (READ_AUDIO_STATUS(p)&0x0010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define IS_CMDBEIRQ(p) (READ_AUDIO_STATUS(p)&0x0020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define IS_DATAFIRQ(p) (READ_AUDIO_STATUS(p)&0x0040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define IS_DATBFIRQ(p) (READ_AUDIO_STATUS(p)&0x0080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define IS_EOBIRQ(p) (READ_AUDIO_STATUS(p)&0x0100) /* interrupt status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define IS_EOSIRQ(p) (READ_AUDIO_STATUS(p)&0x0200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define IS_EOCIRQ(p) (READ_AUDIO_STATUS(p)&0x0400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define IS_UNSLIRQ(p) (READ_AUDIO_STATUS(p)&0x0800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define IS_SBIRQ(p) (READ_AUDIO_STATUS(p)&0x1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define IS_MPUIRQ(p) (READ_AUDIO_STATUS(p)&0x2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define RESP 0x00000001 /* command flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define PARM 0x00000002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define CMDA 0x00000004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define CMDB 0x00000008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define NILL 0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define LONG0(a) ((u32)a) /* shifts and masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define BYTE0(a) (LONG0(a)&0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define BYTE1(a) (BYTE0(a)<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define BYTE2(a) (BYTE0(a)<<16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define BYTE3(a) (BYTE0(a)<<24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define WORD0(a) (LONG0(a)&0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define WORD1(a) (WORD0(a)<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #define WORD2(a) (WORD0(a)<<16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define TRINIB0(a) (LONG0(a)&0xffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define TRINIB1(a) (TRINIB0(a)<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define RET(a) ((union cmdret *)(a))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define SEND_GETV(p,b) sendcmd(p,RESP,GETV,0,RET(b)) /* get version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define SEND_GETC(p,b,c) sendcmd(p,PARM|RESP,GETC,c,RET(b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define SEND_GUNS(p,b) sendcmd(p,RESP,GUNS,0,RET(b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #define SEND_SCID(p,b) sendcmd(p,RESP,SCID,0,RET(b))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define SEND_RMEM(p,b,c,d) sendcmd(p,PARM|RESP,RMEM|BYTE1(b),LONG0(c),RET(d)) /* memory access for firmware write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #define SEND_SMEM(p,b,c) sendcmd(p,PARM,SMEM|BYTE1(b),LONG0(c),RET(0)) /* memory access for firmware write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) #define SEND_WMEM(p,b,c) sendcmd(p,PARM,WMEM|BYTE1(b),LONG0(c),RET(0)) /* memory access for firmware write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) #define SEND_SDTM(p,b,c) sendcmd(p,PARM|RESP,SDTM|TRINIB1(b),0,RET(c)) /* memory access for firmware write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) #define SEND_GOTO(p,b) sendcmd(p,PARM,GOTO,LONG0(b),RET(0)) /* memory access for firmware write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #define SEND_SETDPLL(p) sendcmd(p,0,ARM_SETDPLL,0,RET(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #define SEND_SSTR(p,b,c) sendcmd(p,PARM,SSTR|BYTE3(b),LONG0(c),RET(0)) /* start stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #define SEND_PSTR(p,b) sendcmd(p,PARM,PSTR,BYTE3(b),RET(0)) /* pause stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define SEND_KSTR(p,b) sendcmd(p,PARM,KSTR,BYTE3(b),RET(0)) /* stop stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define SEND_KDMA(p) sendcmd(p,0,KDMA,0,RET(0)) /* stop all dma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define SEND_GPOS(p,b,c,d) sendcmd(p,PARM|RESP,GPOS,BYTE3(c)|BYTE2(b),RET(d)) /* get position in dma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define SEND_SETF(p,b,c,d,e,f,g) sendcmd(p,PARM,SETF|WORD1(b)|BYTE3(c),d|BYTE1(e)|BYTE2(f)|BYTE3(g),RET(0)) /* set sample format at mixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define SEND_GSTS(p,b,c,d) sendcmd(p,PARM|RESP,GSTS,BYTE3(c)|BYTE2(b),RET(d))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #define SEND_NGPOS(p,b,c,d) sendcmd(p,PARM|RESP,NGPOS,BYTE3(c)|BYTE2(b),RET(d))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define SEND_PSEL(p,b,c) sendcmd(p,PARM,PSEL,BYTE2(b)|BYTE3(c),RET(0)) /* activate lbus path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define SEND_PCLR(p,b,c) sendcmd(p,PARM,PCLR,BYTE2(b)|BYTE3(c),RET(0)) /* deactivate lbus path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define SEND_PLST(p,b) sendcmd(p,PARM,PLST,BYTE3(b),RET(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define SEND_RSSV(p,b,c,d) sendcmd(p,PARM|RESP,RSSV,BYTE2(b)|BYTE3(c),RET(d))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define SEND_LSEL(p,b,c,d,e,f,g,h) sendcmd(p,PARM,LSEL|BYTE1(b)|BYTE2(c)|BYTE3(d),BYTE0(e)|BYTE1(f)|BYTE2(g)|BYTE3(h),RET(0)) /* select paths for internal connections */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) #define SEND_SSRC(p,b,c,d,e) sendcmd(p,PARM,SSRC|BYTE1(b)|WORD2(c),WORD0(d)|WORD2(e),RET(0)) /* configure source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define SEND_SLST(p,b) sendcmd(p,PARM,SLST,BYTE3(b),RET(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define SEND_RSRC(p,b,c) sendcmd(p,RESP,RSRC|BYTE1(b),0,RET(c)) /* read source config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #define SEND_SSRB(p,b,c) sendcmd(p,PARM,SSRB|BYTE1(b),WORD2(c),RET(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) #define SEND_SDGV(p,b,c,d,e) sendcmd(p,PARM,SDGV|BYTE2(b)|BYTE3(c),WORD0(d)|WORD2(e),RET(0)) /* set digital mixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #define SEND_RDGV(p,b,c,d) sendcmd(p,PARM|RESP,RDGV|BYTE2(b)|BYTE3(c),0,RET(d)) /* read digital mixer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) #define SEND_DLST(p,b) sendcmd(p,PARM,DLST,BYTE3(b),RET(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define SEND_SACR(p,b,c) sendcmd(p,PARM,SACR,WORD0(b)|WORD2(c),RET(0)) /* set AC97 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #define SEND_RACR(p,b,c) sendcmd(p,PARM|RESP,RACR,WORD2(b),RET(c)) /* get AC97 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) #define SEND_ALST(p,b) sendcmd(p,PARM,ALST,BYTE3(b),RET(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #define SEND_TXAC(p,b,c,d,e,f) sendcmd(p,PARM,TXAC|BYTE1(b)|WORD2(c),WORD0(d)|BYTE2(e)|BYTE3(f),RET(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #define SEND_RXAC(p,b,c,d) sendcmd(p,PARM|RESP,RXAC,BYTE2(b)|BYTE3(c),RET(d))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) #define SEND_SI2S(p,b) sendcmd(p,PARM,SI2S,WORD2(b),RET(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) #define EOB_STATUS 0x80000000 /* status flags : block boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) #define EOS_STATUS 0x40000000 /* : stoppped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) #define EOC_STATUS 0x20000000 /* : stream end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #define ERR_STATUS 0x10000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) #define EMPTY_STATUS 0x08000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) #define IEOB_ENABLE 0x1 /* enable interrupts for status notification above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) #define IEOS_ENABLE 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) #define IEOC_ENABLE 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #define RDONCE 0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define DESC_MAX_MASK 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) #define ST_PLAY 0x1 /* stream states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) #define ST_STOP 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #define ST_PAUSE 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #define I2S_INTDEC 3 /* config for I2S link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #define I2S_MERGER 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #define I2S_SPLITTER 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #define I2S_MIXER 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) #define I2S_RATE 44100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) #define MODEM_INTDEC 4 /* config for modem link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #define MODEM_MERGER 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #define MODEM_SPLITTER 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) #define MODEM_MIXER 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) #define FM_INTDEC 3 /* config for FM/OPL3 link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) #define FM_MERGER 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) #define FM_SPLITTER 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) #define FM_MIXER 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) #define SPLIT_PATH 0x80 /* path splitting flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) enum FIRMWARE {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) DATA_REC = 0, EXT_END_OF_FILE, EXT_SEG_ADDR_REC, EXT_GOTO_CMD_REC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) EXT_LIN_ADDR_REC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) enum CMDS {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) GETV = 0x00, GETC, GUNS, SCID, RMEM =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 0x10, SMEM, WMEM, SDTM, GOTO, SSTR =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 0x20, PSTR, KSTR, KDMA, GPOS, SETF, GSTS, NGPOS, PSEL =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 0x30, PCLR, PLST, RSSV, LSEL, SSRC = 0x40, SLST, RSRC, SSRB, SDGV =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 0x50, RDGV, DLST, SACR = 0x60, RACR, ALST, TXAC, RXAC, SI2S =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 0x70, ARM_SETDPLL = 0x72,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) enum E1SOURCE {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) ARM2LBUS_FIFO0 = 0, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2, ARM2LBUS_FIFO3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ARM2LBUS_FIFO4, ARM2LBUS_FIFO5, ARM2LBUS_FIFO6, ARM2LBUS_FIFO7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) ARM2LBUS_FIFO8, ARM2LBUS_FIFO9, ARM2LBUS_FIFO10, ARM2LBUS_FIFO11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) ARM2LBUS_FIFO12, ARM2LBUS_FIFO13, ARM2LBUS_FIFO14, ARM2LBUS_FIFO15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) INTER0_OUT, INTER1_OUT, INTER2_OUT, INTER3_OUT, INTER4_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) INTERM0_OUT, INTERM1_OUT, INTERM2_OUT, INTERM3_OUT, INTERM4_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) INTERM5_OUT, INTERM6_OUT, DECIMM0_OUT, DECIMM1_OUT, DECIMM2_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) DECIMM3_OUT, DECIM0_OUT, SR3_4_OUT, OPL3_SAMPLE, ASRC0, ASRC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ACLNK2PADC, ACLNK2MODEM0RX, ACLNK2MIC, ACLNK2MODEM1RX, ACLNK2HNDMIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) DIGITAL_MIXER_OUT0, GAINFUNC0_OUT, GAINFUNC1_OUT, GAINFUNC2_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) GAINFUNC3_OUT, GAINFUNC4_OUT, SOFTMODEMTX, SPLITTER0_OUTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) SPLITTER0_OUTR, SPLITTER1_OUTL, SPLITTER1_OUTR, SPLITTER2_OUTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) SPLITTER2_OUTR, SPLITTER3_OUTL, SPLITTER3_OUTR, MERGER0_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) MERGER1_OUT, MERGER2_OUT, MERGER3_OUT, ARM2LBUS_FIFO_DIRECT, NO_OUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) enum E2SINK {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) LBUS2ARM_FIFO0 = 0, LBUS2ARM_FIFO1, LBUS2ARM_FIFO2, LBUS2ARM_FIFO3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) LBUS2ARM_FIFO4, LBUS2ARM_FIFO5, LBUS2ARM_FIFO6, LBUS2ARM_FIFO7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) INTER0_IN, INTER1_IN, INTER2_IN, INTER3_IN, INTER4_IN, INTERM0_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) INTERM1_IN, INTERM2_IN, INTERM3_IN, INTERM4_IN, INTERM5_IN, INTERM6_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) DECIMM0_IN, DECIMM1_IN, DECIMM2_IN, DECIMM3_IN, DECIM0_IN, SR3_4_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) PDAC2ACLNK, MODEM0TX2ACLNK, MODEM1TX2ACLNK, HNDSPK2ACLNK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) DIGITAL_MIXER_IN0, DIGITAL_MIXER_IN1, DIGITAL_MIXER_IN2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) DIGITAL_MIXER_IN3, DIGITAL_MIXER_IN4, DIGITAL_MIXER_IN5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) DIGITAL_MIXER_IN6, DIGITAL_MIXER_IN7, DIGITAL_MIXER_IN8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) DIGITAL_MIXER_IN9, DIGITAL_MIXER_IN10, DIGITAL_MIXER_IN11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) GAINFUNC0_IN, GAINFUNC1_IN, GAINFUNC2_IN, GAINFUNC3_IN, GAINFUNC4_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) SOFTMODEMRX, SPLITTER0_IN, SPLITTER1_IN, SPLITTER2_IN, SPLITTER3_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) MERGER0_INL, MERGER0_INR, MERGER1_INL, MERGER1_INR, MERGER2_INL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) MERGER2_INR, MERGER3_INL, MERGER3_INR, E2SINK_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) enum LBUS_SINK {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) LS_SRC_INTERPOLATOR = 0, LS_SRC_INTERPOLATORM, LS_SRC_DECIMATOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) LS_SRC_DECIMATORM, LS_MIXER_IN, LS_MIXER_GAIN_FUNCTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) LS_SRC_SPLITTER, LS_SRC_MERGER, LS_NONE1, LS_NONE2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) enum RT_CHANNEL_IDS {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) M0TX = 0, M1TX, TAMTX, HSSPKR, PDAC, DSNDTX0, DSNDTX1, DSNDTX2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) DSNDTX3, DSNDTX4, DSNDTX5, DSNDTX6, DSNDTX7, WVSTRTX, COP3DTX, SPARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) M0RX, HSMIC, M1RX, CLEANRX, MICADC, PADC, COPRX1, COPRX2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) CHANNEL_ID_COUNTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) enum { SB_CMD = 0, MODEM_CMD, I2S_CMD0, I2S_CMD1, FM_CMD, MAX_CMD };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) struct lbuspath {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) const unsigned char *noconv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) const unsigned char *stereo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) const unsigned char *mono;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct cmdport {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) u32 data1; /* cmd,param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) u32 data2; /* param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) u32 stat; /* status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) u32 pad[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct riptideport {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) u32 audio_control; /* status registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) u32 audio_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) u32 pad[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct cmdport port[2]; /* command ports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct cmdif {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) struct riptideport *hwport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) unsigned int cmdcnt; /* cmd statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) unsigned int cmdtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) unsigned int cmdtimemax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) unsigned int cmdtimemin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) unsigned int errcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) int is_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct riptide_firmware {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u16 ASIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) u16 CODEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) u16 AUXDSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) u16 PROG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) union cmdret {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) u8 retbytes[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) u16 retwords[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) u32 retlongs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) union firmware_version {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) union cmdret ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct riptide_firmware firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #define get_pcmhwdev(substream) (struct pcmhw *)(substream->runtime->private_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) #define PLAYBACK_SUBSTREAMS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct snd_riptide {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct pci_dev *pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) const struct firmware *fw_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct cmdif *cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct snd_pcm *pcm_i2s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct snd_rawmidi *rmidi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct snd_opl3 *opl3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct snd_ac97 *ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct snd_ac97_bus *ac97_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct snd_pcm_substream *playback_substream[PLAYBACK_SUBSTREAMS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct snd_pcm_substream *capture_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) int openstreams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) unsigned long port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) unsigned short mpuaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) unsigned short opladdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) unsigned short gameaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct resource *res_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) unsigned short device_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) union firmware_version firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) struct snd_info_entry *proc_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) unsigned long received_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) unsigned long handled_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) int in_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct sgd { /* scatter gather desriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) __le32 dwNextLink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) __le32 dwSegPtrPhys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) __le32 dwSegLen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) __le32 dwStat_Ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct pcmhw { /* pcm descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct lbuspath paths;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) const unsigned char *lbuspath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) unsigned char source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) unsigned char intdec[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) unsigned char mixer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) unsigned char id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) unsigned char state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) unsigned int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) unsigned int channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) snd_pcm_format_t format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct snd_dma_buffer sgdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct sgd *sgdbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) unsigned int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) unsigned int pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) unsigned int oldpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) unsigned int pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #define CMDRET_ZERO (union cmdret){{(u32)0, (u32) 0}}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) union cmdret *ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static int getsourcesink(struct cmdif *cif, unsigned char source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) unsigned char sink, unsigned char *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) unsigned char *b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static int snd_riptide_initialize(struct snd_riptide *chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static const struct pci_device_id snd_riptide_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) { PCI_DEVICE(0x127a, 0x4310) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) { PCI_DEVICE(0x127a, 0x4320) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) { PCI_DEVICE(0x127a, 0x4330) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) { PCI_DEVICE(0x127a, 0x4340) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {0,},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static const struct pci_device_id snd_riptide_joystick_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) { PCI_DEVICE(0x127a, 0x4312) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) { PCI_DEVICE(0x127a, 0x4322) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) { PCI_DEVICE(0x127a, 0x4332) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) { PCI_DEVICE(0x127a, 0x4342) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {0,},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) MODULE_DEVICE_TABLE(pci, snd_riptide_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static const unsigned char lbusin2out[E2SINK_MAX + 1][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) LS_NONE2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1}, {NO_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) LS_NONE2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {INTER0_OUT, LS_SRC_INTERPOLATOR}, {INTER1_OUT, LS_SRC_INTERPOLATOR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) {INTER2_OUT, LS_SRC_INTERPOLATOR}, {INTER3_OUT, LS_SRC_INTERPOLATOR},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {INTER4_OUT, LS_SRC_INTERPOLATOR}, {INTERM0_OUT, LS_SRC_INTERPOLATORM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {INTERM1_OUT, LS_SRC_INTERPOLATORM}, {INTERM2_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) LS_SRC_INTERPOLATORM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {INTERM3_OUT, LS_SRC_INTERPOLATORM}, {INTERM4_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) LS_SRC_INTERPOLATORM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {INTERM5_OUT, LS_SRC_INTERPOLATORM}, {INTERM6_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) LS_SRC_INTERPOLATORM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {DECIMM0_OUT, LS_SRC_DECIMATORM}, {DECIMM1_OUT, LS_SRC_DECIMATORM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {DECIMM2_OUT, LS_SRC_DECIMATORM}, {DECIMM3_OUT, LS_SRC_DECIMATORM},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {DECIM0_OUT, LS_SRC_DECIMATOR}, {SR3_4_OUT, LS_NONE1}, {NO_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) LS_NONE2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {NO_OUT, LS_NONE1}, {NO_OUT, LS_NONE2}, {NO_OUT, LS_NONE1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {DIGITAL_MIXER_OUT0, LS_MIXER_IN}, {DIGITAL_MIXER_OUT0, LS_MIXER_IN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {GAINFUNC0_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC1_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) LS_MIXER_GAIN_FUNCTION},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) {GAINFUNC2_OUT, LS_MIXER_GAIN_FUNCTION}, {GAINFUNC3_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) LS_MIXER_GAIN_FUNCTION},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {GAINFUNC4_OUT, LS_MIXER_GAIN_FUNCTION}, {SOFTMODEMTX, LS_NONE1},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {SPLITTER0_OUTL, LS_SRC_SPLITTER}, {SPLITTER1_OUTL, LS_SRC_SPLITTER},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {SPLITTER2_OUTL, LS_SRC_SPLITTER}, {SPLITTER3_OUTL, LS_SRC_SPLITTER},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {MERGER0_OUT, LS_SRC_MERGER}, {MERGER0_OUT, LS_SRC_MERGER},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) {MERGER1_OUT, LS_SRC_MERGER},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {MERGER1_OUT, LS_SRC_MERGER}, {MERGER2_OUT, LS_SRC_MERGER},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) {MERGER2_OUT, LS_SRC_MERGER},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {MERGER3_OUT, LS_SRC_MERGER}, {MERGER3_OUT, LS_SRC_MERGER}, {NO_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) LS_NONE2},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static const unsigned char lbus_play_opl3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) DIGITAL_MIXER_IN0 + FM_MIXER, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static const unsigned char lbus_play_modem[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) DIGITAL_MIXER_IN0 + MODEM_MIXER, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static const unsigned char lbus_play_i2s[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) INTER0_IN + I2S_INTDEC, DIGITAL_MIXER_IN0 + I2S_MIXER, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) static const unsigned char lbus_play_out[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) PDAC2ACLNK, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static const unsigned char lbus_play_outhp[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) HNDSPK2ACLNK, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) static const unsigned char lbus_play_noconv1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) DIGITAL_MIXER_IN0, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static const unsigned char lbus_play_stereo1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) INTER0_IN, DIGITAL_MIXER_IN0, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) static const unsigned char lbus_play_mono1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) INTERM0_IN, DIGITAL_MIXER_IN0, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static const unsigned char lbus_play_noconv2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) DIGITAL_MIXER_IN1, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static const unsigned char lbus_play_stereo2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) INTER1_IN, DIGITAL_MIXER_IN1, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static const unsigned char lbus_play_mono2[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) INTERM1_IN, DIGITAL_MIXER_IN1, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static const unsigned char lbus_play_noconv3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) DIGITAL_MIXER_IN2, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static const unsigned char lbus_play_stereo3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) INTER2_IN, DIGITAL_MIXER_IN2, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static const unsigned char lbus_play_mono3[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) INTERM2_IN, DIGITAL_MIXER_IN2, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static const unsigned char lbus_rec_noconv1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) LBUS2ARM_FIFO5, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) static const unsigned char lbus_rec_stereo1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) DECIM0_IN, LBUS2ARM_FIFO5, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static const unsigned char lbus_rec_mono1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) DECIMM3_IN, LBUS2ARM_FIFO5, 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static const unsigned char play_ids[] = { 4, 1, 2, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static const unsigned char play_sources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ARM2LBUS_FIFO4, ARM2LBUS_FIFO1, ARM2LBUS_FIFO2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static const struct lbuspath lbus_play_paths[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) .noconv = lbus_play_noconv1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .stereo = lbus_play_stereo1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .mono = lbus_play_mono1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .noconv = lbus_play_noconv2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .stereo = lbus_play_stereo2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) .mono = lbus_play_mono2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .noconv = lbus_play_noconv3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .stereo = lbus_play_stereo3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .mono = lbus_play_mono3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static const struct lbuspath lbus_rec_path = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) .noconv = lbus_rec_noconv1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) .stereo = lbus_rec_stereo1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) .mono = lbus_rec_mono1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) #define FIRMWARE_VERSIONS 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static union firmware_version firmware_versions[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) .firmware = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) .ASIC = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .CODEC = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .AUXDSP = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .PROG = 773,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static u32 atoh(const unsigned char *in, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) u32 sum = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) unsigned int mult = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) unsigned char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) while (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) c = in[len - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) value = hex_to_bin(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (value >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) sum += mult * value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) mult *= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) --len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return sum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) static int senddata(struct cmdif *cif, const unsigned char *in, u32 offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) u32 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) const unsigned char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) i = atoh(&in[1], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) addr = offset + atoh(&in[3], 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (SEND_SMEM(cif, 0, addr) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) p = in + 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) while (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) data = atoh(p, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (SEND_WMEM(cif, 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ((data & 0x0f0f0f0f) << 4) | ((data & 0xf0f0f0f0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) >> 4)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) i -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) p += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) static int loadfirmware(struct cmdif *cif, const unsigned char *img,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) unsigned int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) const unsigned char *in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) u32 laddr, saddr, t, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) laddr = saddr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) while (size > 0 && err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) in = img;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (in[0] == ':') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) t = atoh(&in[7], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) switch (t) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) case DATA_REC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) err = senddata(cif, in, laddr + saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) case EXT_SEG_ADDR_REC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) saddr = atoh(&in[9], 4) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) case EXT_LIN_ADDR_REC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) laddr = atoh(&in[9], 4) << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) case EXT_GOTO_CMD_REC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) val = atoh(&in[9], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) if (SEND_GOTO(cif, val) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) err = -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) case EXT_END_OF_FILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) while (size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) size--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (*img++ == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) snd_printdd("load firmware return %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) alloclbuspath(struct cmdif *cif, unsigned char source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) const unsigned char *path, unsigned char *mixer, unsigned char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) while (*path != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) unsigned char sink, type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) sink = *path & (~SPLIT_PATH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (sink != E2SINK_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) snd_printdd("alloc path 0x%x->0x%x\n", source, sink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) SEND_PSEL(cif, source, sink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) source = lbusin2out[sink][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) type = lbusin2out[sink][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (type == LS_MIXER_IN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (mixer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) *mixer = sink - DIGITAL_MIXER_IN0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (type == LS_SRC_DECIMATORM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) type == LS_SRC_DECIMATOR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) type == LS_SRC_INTERPOLATORM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) type == LS_SRC_INTERPOLATOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (s) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (s[0] != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) s[1] = sink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) s[0] = sink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (*path++ & SPLIT_PATH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) const unsigned char *npath = path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) while (*npath != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) npath++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) alloclbuspath(cif, source + 1, ++npath, mixer, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) freelbuspath(struct cmdif *cif, unsigned char source, const unsigned char *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) while (*path != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) unsigned char sink;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) sink = *path & (~SPLIT_PATH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (sink != E2SINK_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) snd_printdd("free path 0x%x->0x%x\n", source, sink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) SEND_PCLR(cif, source, sink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) source = lbusin2out[sink][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (*path++ & SPLIT_PATH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) const unsigned char *npath = path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) while (*npath != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) npath++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) freelbuspath(cif, source + 1, ++npath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) static int writearm(struct cmdif *cif, u32 addr, u32 data, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unsigned int i = MAX_WRITE_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) int flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) SEND_RMEM(cif, 0x02, addr, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) rptr.retlongs[0] &= (~mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) while (--i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) SEND_SMEM(cif, 0x01, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) SEND_WMEM(cif, 0x02, (rptr.retlongs[0] | data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) SEND_RMEM(cif, 0x02, addr, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if ((rptr.retlongs[0] & data) == data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) rptr.retlongs[0] &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) snd_printdd("send arm 0x%x 0x%x 0x%x return %d\n", addr, data, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) union cmdret *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) unsigned int time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) unsigned long irqflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct riptideport *hwport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct cmdport *cmdport = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (snd_BUG_ON(!cif))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) hwport = cif->hwport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (cif->errcnt > MAX_ERROR_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (cif->is_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) snd_printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) "Riptide: Too many failed cmds, reinitializing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (riptide_reset(cif, NULL) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) cif->errcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) snd_printk(KERN_ERR "Riptide: Initialization failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) ret->retlongs[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ret->retlongs[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) spin_lock_irqsave(&cif->lock, irqflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) while (i++ < CMDIF_TIMEOUT && !IS_READY(cif->hwport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (i > CMDIF_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) for (j = 0, time = 0; time < CMDIF_TIMEOUT; j++, time += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) cmdport = &(hwport->port[j % 2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (IS_DATF(cmdport)) { /* free pending data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) READ_PORT_ULONG(cmdport->data1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) READ_PORT_ULONG(cmdport->data2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (IS_CMDE(cmdport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (flags & PARM) /* put data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) WRITE_PORT_ULONG(cmdport->data2, parm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) WRITE_PORT_ULONG(cmdport->data1, cmd); /* write cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if ((flags & RESP) && ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) while (!IS_DATF(cmdport) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) time < CMDIF_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) time++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (time < CMDIF_TIMEOUT) { /* read response */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) ret->retlongs[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) READ_PORT_ULONG(cmdport->data1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) ret->retlongs[1] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) READ_PORT_ULONG(cmdport->data2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) err = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) udelay(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (time == CMDIF_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) err = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) goto errout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) spin_unlock_irqrestore(&cif->lock, irqflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) cif->cmdcnt++; /* update command statistics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) cif->cmdtime += time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (time > cif->cmdtimemax)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) cif->cmdtimemax = time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) if (time < cif->cmdtimemin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) cif->cmdtimemin = time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if ((cif->cmdcnt) % 1000 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) snd_printdd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) ("send cmd %d time: %d mintime: %d maxtime %d err: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) cif->cmdcnt, cif->cmdtime, cif->cmdtimemin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) cif->cmdtimemax, cif->errcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) errout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) cif->errcnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) spin_unlock_irqrestore(&cif->lock, irqflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) snd_printdd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ("send cmd %d hw: 0x%x flag: 0x%x cmd: 0x%x parm: 0x%x ret: 0x%x 0x%x CMDE: %d DATF: %d failed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) cif->cmdcnt, (int)((void *)&(cmdport->stat) - (void *)hwport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) flags, cmd, parm, ret ? ret->retlongs[0] : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ret ? ret->retlongs[1] : 0, IS_CMDE(cmdport), IS_DATF(cmdport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) setmixer(struct cmdif *cif, short num, unsigned short rval, unsigned short lval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) snd_printdd("sent mixer %d: 0x%x 0x%x\n", num, rval, lval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) SEND_SDGV(cif, num, num, rval, lval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) SEND_RDGV(cif, num, num, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (rptr.retwords[0] == lval && rptr.retwords[1] == rval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) } while (i++ < MAX_WRITE_RETRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) snd_printdd("sent mixer failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static int getpaths(struct cmdif *cif, unsigned char *o)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) unsigned char src[E2SINK_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) unsigned char sink[E2SINK_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) int i, j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) for (i = 0; i < E2SINK_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) getsourcesink(cif, i, i, &src[i], &sink[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (sink[i] < E2SINK_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) o[j++] = sink[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) o[j++] = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) getsourcesink(struct cmdif *cif, unsigned char source, unsigned char sink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) unsigned char *a, unsigned char *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (SEND_RSSV(cif, source, sink, &rptr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) SEND_RSSV(cif, source, sink, &rptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) *a = rptr.retbytes[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) *b = rptr.retbytes[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) snd_printdd("getsourcesink 0x%x 0x%x\n", *a, *b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) getsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int *rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) unsigned char *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) unsigned int p[2] = { 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) s = intdec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (*s != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (SEND_RSRC(cif, *s, &rptr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) SEND_RSRC(cif, *s, &rptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) p[i] += rptr.retwords[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) p[i] *= rptr.retwords[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) p[i] += rptr.retwords[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) p[i] /= 65536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) s++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (p[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (p[1] != p[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) snd_printdd("rates differ %d %d\n", p[0], p[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) *rate = (unsigned int)p[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) *rate = (unsigned int)p[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) snd_printdd("getsampleformat %d %d %d\n", intdec[0], intdec[1], *rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) setsampleformat(struct cmdif *cif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) unsigned char mixer, unsigned char id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) unsigned char channels, snd_pcm_format_t format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) unsigned char w, ch, sig, order;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) snd_printdd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ("setsampleformat mixer: %d id: %d channels: %d format: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) mixer, id, channels, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ch = channels == 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) w = snd_pcm_format_width(format) == 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) sig = snd_pcm_format_unsigned(format) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) order = snd_pcm_format_big_endian(format) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) if (SEND_SETF(cif, mixer, w, ch, order, sig, id) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) SEND_SETF(cif, mixer, w, ch, order, sig, id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) snd_printdd("setsampleformat failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) setsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) u32 D, M, N;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) snd_printdd("setsamplerate intdec: %d,%d rate: %d\n", intdec[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) intdec[1], rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) D = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) M = ((rate == 48000) ? 47999 : rate) * 65536;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) N = M % D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) M /= D;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (*intdec != 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) SEND_SSRC(cif, *intdec, D, M, N);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) SEND_RSRC(cif, *intdec, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) } while (rptr.retwords[1] != D &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) rptr.retwords[2] != M &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) rptr.retwords[3] != N &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) i++ < MAX_WRITE_RETRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (i > MAX_WRITE_RETRY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) snd_printdd("sent samplerate %d: %d failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) *intdec, rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) intdec++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) getmixer(struct cmdif *cif, short num, unsigned short *rval,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) unsigned short *lval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (SEND_RDGV(cif, num, num, &rptr) && SEND_RDGV(cif, num, num, &rptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) *rval = rptr.retwords[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) *lval = rptr.retwords[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) snd_printdd("got mixer %d: 0x%x 0x%x\n", num, *rval, *lval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static irqreturn_t riptide_handleirq(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct snd_riptide *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct cmdif *cif = chip->cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct snd_pcm_substream *substream[PLAYBACK_SUBSTREAMS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct snd_pcm_runtime *runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) struct pcmhw *data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) unsigned int pos, period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct sgd *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) unsigned int flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) if (!cif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) for (i = 0; i < PLAYBACK_SUBSTREAMS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) substream[i] = chip->playback_substream[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) substream[i] = chip->capture_substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) for (i = 0; i < PLAYBACK_SUBSTREAMS + 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (substream[i] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) (runtime = substream[i]->runtime) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) (data = runtime->private_data) && data->state != ST_STOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) for (j = 0; j < data->pages; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) c = &data->sgdbuf[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) flag = le32_to_cpu(c->dwStat_Ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (flag & EOB_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) pos += le32_to_cpu(c->dwSegLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) if (flag & EOC_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) pos += le32_to_cpu(c->dwSegLen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if ((flag & EOS_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) && (data->state == ST_PLAY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) data->state = ST_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) snd_printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) "Riptide: DMA stopped unexpectedly\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) c->dwStat_Ctl =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) cpu_to_le32(flag &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) ~(EOS_STATUS | EOB_STATUS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) EOC_STATUS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) data->pointer += pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) pos += data->oldpos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (data->state != ST_STOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) period_bytes =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) frames_to_bytes(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) runtime->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) snd_printdd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) ("interrupt 0x%x after 0x%lx of 0x%lx frames in period\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) READ_AUDIO_STATUS(cif->hwport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) bytes_to_frames(runtime, pos),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) runtime->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (pos >= period_bytes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) while (pos >= period_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) pos -= period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) data->oldpos = pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (j > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) snd_pcm_period_elapsed(substream[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) static int riptide_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) struct snd_riptide *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) chip->in_suspend = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) snd_ac97_suspend(chip->ac97);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static int riptide_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct snd_riptide *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) snd_riptide_initialize(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) snd_ac97_resume(chip->ac97);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) snd_power_change_state(card, SNDRV_CTL_POWER_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) chip->in_suspend = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) static SIMPLE_DEV_PM_OPS(riptide_pm, riptide_suspend, riptide_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) #define RIPTIDE_PM_OPS &riptide_pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) #define RIPTIDE_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) union firmware_version firmware = { .ret = CMDRET_ZERO };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) int i, timeout, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) for (i = 0; i < 2; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) WRITE_PORT_ULONG(cif->hwport->port[i].data1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) WRITE_PORT_ULONG(cif->hwport->port[i].data2, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) SET_GRESET(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) UNSET_GRESET(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) for (timeout = 100000; --timeout; udelay(10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (IS_READY(cif->hwport) && !IS_GERR(cif->hwport))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (!timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) snd_printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) "Riptide: device not ready, audio status: 0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) "ready: %d gerr: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) READ_AUDIO_STATUS(cif->hwport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) IS_READY(cif->hwport), IS_GERR(cif->hwport));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) snd_printdd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) ("Riptide: audio status: 0x%x ready: %d gerr: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) READ_AUDIO_STATUS(cif->hwport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) IS_READY(cif->hwport), IS_GERR(cif->hwport));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) SEND_GETV(cif, &firmware.ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) snd_printdd("Firmware version: ASIC: %d CODEC %d AUXDSP %d PROG %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) firmware.firmware.ASIC, firmware.firmware.CODEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) firmware.firmware.AUXDSP, firmware.firmware.PROG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) for (i = 0; i < FIRMWARE_VERSIONS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (!memcmp(&firmware_versions[i], &firmware, sizeof(firmware)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) return 1; /* OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) snd_printdd("Writing Firmware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) if (!chip->fw_entry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) err = request_firmware(&chip->fw_entry, "riptide.hex",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) &chip->pci->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) snd_printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) "Riptide: Firmware not available %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) err = loadfirmware(cif, chip->fw_entry->data, chip->fw_entry->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) snd_printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) "Riptide: Could not load firmware %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) chip->firmware = firmware;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return 1; /* OK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) int err, tries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (!cif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) cif->cmdcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) cif->cmdtime = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) cif->cmdtimemax = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) cif->cmdtimemin = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) cif->errcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) cif->is_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) tries = RESET_TRIES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) err = try_to_load_firmware(cif, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) } while (!err && --tries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) SEND_SACR(cif, 0, AC97_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) SEND_RACR(cif, AC97_RESET, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) snd_printdd("AC97: 0x%x 0x%x\n", rptr.retlongs[0], rptr.retlongs[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) SEND_PLST(cif, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) SEND_SLST(cif, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) SEND_DLST(cif, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) SEND_ALST(cif, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) SEND_KDMA(cif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) writearm(cif, 0x301F8, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) writearm(cif, 0x301F4, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) SEND_LSEL(cif, MODEM_CMD, 0, 0, MODEM_INTDEC, MODEM_MERGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) MODEM_SPLITTER, MODEM_MIXER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) setmixer(cif, MODEM_MIXER, 0x7fff, 0x7fff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) alloclbuspath(cif, ARM2LBUS_FIFO13, lbus_play_modem, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) SEND_LSEL(cif, FM_CMD, 0, 0, FM_INTDEC, FM_MERGER, FM_SPLITTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) FM_MIXER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) setmixer(cif, FM_MIXER, 0x7fff, 0x7fff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) writearm(cif, 0x30648 + FM_MIXER * 4, 0x01, 0x00000005);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) writearm(cif, 0x301A8, 0x02, 0x00000002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) writearm(cif, 0x30264, 0x08, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) alloclbuspath(cif, OPL3_SAMPLE, lbus_play_opl3, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) SEND_SSRC(cif, I2S_INTDEC, 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) ((u32) I2S_RATE * 65536) / 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) ((u32) I2S_RATE * 65536) % 48000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) SEND_LSEL(cif, I2S_CMD0, 0, 0, I2S_INTDEC, I2S_MERGER, I2S_SPLITTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) I2S_MIXER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) SEND_SI2S(cif, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) alloclbuspath(cif, ARM2LBUS_FIFO0, lbus_play_i2s, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) alloclbuspath(cif, DIGITAL_MIXER_OUT0, lbus_play_out, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) alloclbuspath(cif, DIGITAL_MIXER_OUT0, lbus_play_outhp, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) SET_AIACK(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) SET_AIE(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) SET_AIACK(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) cif->is_reset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) static const struct snd_pcm_hardware snd_riptide_playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) .formats =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) | SNDRV_PCM_FMTBIT_U16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) .rate_min = 5500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .buffer_bytes_max = (64 * 1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) .period_bytes_min = PAGE_SIZE >> 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) .period_bytes_max = PAGE_SIZE << 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) .periods_max = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static const struct snd_pcm_hardware snd_riptide_capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) .formats =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) | SNDRV_PCM_FMTBIT_U16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) .rates = SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) .rate_min = 5500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) .buffer_bytes_max = (64 * 1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) .period_bytes_min = PAGE_SIZE >> 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) .period_bytes_max = PAGE_SIZE << 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) .periods_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) .periods_max = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) .fifo_size = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) static snd_pcm_uframes_t snd_riptide_pointer(struct snd_pcm_substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) struct snd_riptide *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) struct pcmhw *data = get_pcmhwdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) struct cmdif *cif = chip->cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) snd_pcm_uframes_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) SEND_GPOS(cif, 0, data->id, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (data->size && runtime->period_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) snd_printdd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) ("pointer stream %d position 0x%x(0x%x in buffer) bytes 0x%lx(0x%lx in period) frames\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) data->id, rptr.retlongs[1], rptr.retlongs[1] % data->size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) bytes_to_frames(runtime, rptr.retlongs[1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) bytes_to_frames(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) rptr.retlongs[1]) % runtime->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (rptr.retlongs[1] > data->pointer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) bytes_to_frames(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) rptr.retlongs[1] % data->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ret =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) bytes_to_frames(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) data->pointer % data->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) snd_printdd("stream not started or strange parms (%d %ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) data->size, runtime->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) ret = bytes_to_frames(runtime, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) static int snd_riptide_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) struct snd_riptide *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) struct pcmhw *data = get_pcmhwdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) struct cmdif *cif = chip->cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) spin_lock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (!(data->state & ST_PLAY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) SEND_SSTR(cif, data->id, data->sgdlist.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) SET_AIE(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) data->state = ST_PLAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (data->mixer != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) setmixer(cif, data->mixer, 0x7fff, 0x7fff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) chip->openstreams++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) data->oldpos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) data->pointer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (data->mixer != 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) setmixer(cif, data->mixer, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) setmixer(cif, data->mixer, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) SEND_KSTR(cif, data->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) data->state = ST_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) chip->openstreams--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) i = rptr.retlongs[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) SEND_GPOS(cif, 0, data->id, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) } while (i != rptr.retlongs[1] && j++ < MAX_WRITE_RETRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) if (j > MAX_WRITE_RETRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) snd_printk(KERN_ERR "Riptide: Could not stop stream!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) if (!(data->state & ST_PAUSE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) SEND_PSTR(cif, data->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) data->state |= ST_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) chip->openstreams--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (data->state & ST_PAUSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) SEND_SSTR(cif, data->id, data->sgdlist.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) data->state &= ~ST_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) chip->openstreams++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) spin_unlock(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) static int snd_riptide_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) struct snd_riptide *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) struct pcmhw *data = get_pcmhwdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) struct cmdif *cif = chip->cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) const unsigned char *lbuspath = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) unsigned int rate, channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) snd_pcm_format_t format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) if (snd_BUG_ON(!cif || !data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) snd_printdd("prepare id %d ch: %d f:0x%x r:%d\n", data->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) runtime->channels, runtime->format, runtime->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) spin_lock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) channels = runtime->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) format = runtime->format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) rate = runtime->rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) switch (channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) if (rate == 48000 && format == SNDRV_PCM_FORMAT_S16_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) lbuspath = data->paths.noconv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) lbuspath = data->paths.mono;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (rate == 48000 && format == SNDRV_PCM_FORMAT_S16_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) lbuspath = data->paths.noconv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) lbuspath = data->paths.stereo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) snd_printdd("use sgdlist at 0x%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) data->sgdlist.area);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (data->sgdlist.area) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) unsigned int i, j, size, pages, f, pt, period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct sgd *c, *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) size = frames_to_bytes(runtime, runtime->buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) period = frames_to_bytes(runtime, runtime->period_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) f = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) while ((size + (f >> 1) - 1) <= (f << 7) && (f << 1) > period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) f = f >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) pages = DIV_ROUND_UP(size, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) data->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) data->pages = pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) snd_printdd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) ("create sgd size: 0x%x pages %d of size 0x%x for period 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) size, pages, f, period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) pt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) for (i = 0; i < pages; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) unsigned int ofs, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) c = &data->sgdbuf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) p->dwNextLink = cpu_to_le32(data->sgdlist.addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) (i *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) sizeof(struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) sgd)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) c->dwNextLink = cpu_to_le32(data->sgdlist.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) ofs = j << PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) addr = snd_pcm_sgbuf_get_addr(substream, ofs) + pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) c->dwSegPtrPhys = cpu_to_le32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) pt = (pt + f) % PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (pt == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) c->dwSegLen = cpu_to_le32(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) c->dwStat_Ctl =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) cpu_to_le32(IEOB_ENABLE | IEOS_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) IEOC_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) p = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) size -= f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) data->sgdbuf[i].dwSegLen = cpu_to_le32(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) if (lbuspath && lbuspath != data->lbuspath) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (data->lbuspath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) freelbuspath(cif, data->source, data->lbuspath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) alloclbuspath(cif, data->source, lbuspath,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) &data->mixer, data->intdec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) data->lbuspath = lbuspath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) data->rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (data->rate != rate || data->format != format ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) data->channels != channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) data->rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) data->format = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) data->channels = channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if (setsampleformat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) (cif, data->mixer, data->id, channels, format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) || setsamplerate(cif, data->intdec, rate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) spin_unlock_irq(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) snd_riptide_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) struct snd_riptide *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) struct pcmhw *data = get_pcmhwdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) struct snd_dma_buffer *sgdlist = &data->sgdlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) snd_printdd("hw params id %d (sgdlist: 0x%p 0x%lx %d)\n", data->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) sgdlist->area, (unsigned long)sgdlist->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) (int)sgdlist->bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) if (sgdlist->area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) snd_dma_free_pages(sgdlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) &chip->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) sizeof(struct sgd) * (DESC_MAX_MASK + 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) sgdlist)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) snd_printk(KERN_ERR "Riptide: failed to alloc %d dma bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) (int)sizeof(struct sgd) * (DESC_MAX_MASK + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) data->sgdbuf = (struct sgd *)sgdlist->area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) static int snd_riptide_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) struct snd_riptide *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) struct pcmhw *data = get_pcmhwdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) struct cmdif *cif = chip->cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) if (cif && data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (data->lbuspath)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) freelbuspath(cif, data->source, data->lbuspath);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) data->lbuspath = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) data->source = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) data->intdec[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) data->intdec[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) if (data->sgdlist.area) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) snd_dma_free_pages(&data->sgdlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) data->sgdlist.area = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) static int snd_riptide_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) struct snd_riptide *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) struct pcmhw *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) int sub_num = substream->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) chip->playback_substream[sub_num] = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) runtime->hw = snd_riptide_playback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) data->paths = lbus_play_paths[sub_num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) data->id = play_ids[sub_num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) data->source = play_sources[sub_num];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) data->intdec[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) data->intdec[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) data->state = ST_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) runtime->private_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) return snd_pcm_hw_constraint_integer(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) SNDRV_PCM_HW_PARAM_PERIODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) static int snd_riptide_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) struct snd_riptide *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) struct pcmhw *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) chip->capture_substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) runtime->hw = snd_riptide_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) if (data == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) data->paths = lbus_rec_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) data->id = PADC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) data->source = ACLNK2PADC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) data->intdec[0] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) data->intdec[1] = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) data->state = ST_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) runtime->private_data = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) return snd_pcm_hw_constraint_integer(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) SNDRV_PCM_HW_PARAM_PERIODS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) static int snd_riptide_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) struct snd_riptide *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) struct pcmhw *data = get_pcmhwdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) int sub_num = substream->number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) substream->runtime->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) chip->playback_substream[sub_num] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) static int snd_riptide_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) struct snd_riptide *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) struct pcmhw *data = get_pcmhwdev(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) substream->runtime->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) chip->capture_substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) kfree(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) static const struct snd_pcm_ops snd_riptide_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) .open = snd_riptide_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) .close = snd_riptide_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) .hw_params = snd_riptide_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) .hw_free = snd_riptide_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) .prepare = snd_riptide_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) .trigger = snd_riptide_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) .pointer = snd_riptide_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) static const struct snd_pcm_ops snd_riptide_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) .open = snd_riptide_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) .close = snd_riptide_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) .hw_params = snd_riptide_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) .hw_free = snd_riptide_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) .prepare = snd_riptide_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) .trigger = snd_riptide_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) .pointer = snd_riptide_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) static int snd_riptide_pcm(struct snd_riptide *chip, int device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if ((err =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) snd_pcm_new(chip->card, "RIPTIDE", device, PLAYBACK_SUBSTREAMS, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) &pcm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) &snd_riptide_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) &snd_riptide_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) strcpy(pcm->name, "RIPTIDE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) chip->pcm = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) &chip->pci->dev, 64 * 1024, 128 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) snd_riptide_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) struct snd_riptide *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) struct cmdif *cif = chip->cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) irqreturn_t ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if (cif) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) chip->received_irqs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) IS_EOCIRQ(cif->hwport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) chip->handled_irqs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) ret = IRQ_WAKE_THREAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (chip->rmidi && IS_MPUIRQ(cif->hwport)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) chip->handled_irqs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) snd_mpu401_uart_interrupt(irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) chip->rmidi->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) SET_AIACK(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) snd_riptide_codec_write(struct snd_ac97 *ac97, unsigned short reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) struct snd_riptide *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) struct cmdif *cif = chip->cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (snd_BUG_ON(!cif))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) snd_printdd("Write AC97 reg 0x%x 0x%x\n", reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) SEND_SACR(cif, val, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) SEND_RACR(cif, reg, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) } while (rptr.retwords[1] != val && i++ < MAX_WRITE_RETRY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if (i > MAX_WRITE_RETRY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) snd_printdd("Write AC97 reg failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) static unsigned short snd_riptide_codec_read(struct snd_ac97 *ac97,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) unsigned short reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) struct snd_riptide *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) struct cmdif *cif = chip->cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) union cmdret rptr = CMDRET_ZERO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (snd_BUG_ON(!cif))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (SEND_RACR(cif, reg, &rptr) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) SEND_RACR(cif, reg, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) snd_printdd("Read AC97 reg 0x%x got 0x%x\n", reg, rptr.retwords[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return rptr.retwords[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) static int snd_riptide_initialize(struct snd_riptide *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) struct cmdif *cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) unsigned int device_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) if (snd_BUG_ON(!chip))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) cif = chip->cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) if (!cif) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if ((cif = kzalloc(sizeof(struct cmdif), GFP_KERNEL)) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) cif->hwport = (struct riptideport *)chip->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) spin_lock_init(&cif->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) chip->cif = cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) cif->is_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) if ((err = riptide_reset(cif, chip)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) device_id = chip->device_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) switch (device_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) case 0x4310:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) case 0x4320:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) case 0x4330:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) snd_printdd("Modem enable?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) SEND_SETDPLL(cif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) snd_printdd("Enabling MPU IRQs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) if (chip->rmidi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) SET_EMPUIRQ(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) static int snd_riptide_free(struct snd_riptide *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) struct cmdif *cif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) if ((cif = chip->cif)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) SET_GRESET(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) UNSET_GRESET(cif->hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) kfree(chip->cif);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) release_firmware(chip->fw_entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) release_and_free_resource(chip->res_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) static int snd_riptide_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) struct snd_riptide *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) return snd_riptide_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) struct snd_riptide **rchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) struct snd_riptide *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) struct riptideport *hwport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) .dev_free = snd_riptide_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) *rchip = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if ((err = pci_enable_device(pci)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (!(chip = kzalloc(sizeof(struct snd_riptide), GFP_KERNEL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) spin_lock_init(&chip->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) chip->pci = pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) chip->openstreams = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) chip->port = pci_resource_start(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) chip->received_irqs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) chip->handled_irqs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) chip->cif = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if ((chip->res_port =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) request_region(chip->port, 64, "RIPTIDE")) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) snd_printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) "Riptide: unable to grab region 0x%lx-0x%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) chip->port, chip->port + 64 - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) snd_riptide_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) hwport = (struct riptideport *)chip->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) UNSET_AIE(hwport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (request_threaded_irq(pci->irq, snd_riptide_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) riptide_handleirq, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) snd_riptide_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) chip->device_id = pci->device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) pci_set_master(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) if ((err = snd_riptide_initialize(chip)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) snd_riptide_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) snd_riptide_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) *rchip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) snd_riptide_proc_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) struct snd_riptide *chip = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) struct pcmhw *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) struct cmdif *cif = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) unsigned char p[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) unsigned short rval = 0, lval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) unsigned int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) snd_iprintf(buffer, "%s\n\n", chip->card->longname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) snd_iprintf(buffer, "Device ID: 0x%x\nReceived IRQs: (%ld)%ld\nPorts:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) chip->device_id, chip->handled_irqs, chip->received_irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) for (i = 0; i < 64; i += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) snd_iprintf(buffer, "%c%02x: %08x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) (i % 16) ? ' ' : '\n', i, inl(chip->port + i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if ((cif = chip->cif)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) "\nVersion: ASIC: %d CODEC: %d AUXDSP: %d PROG: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) chip->firmware.firmware.ASIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) chip->firmware.firmware.CODEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) chip->firmware.firmware.AUXDSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) chip->firmware.firmware.PROG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) snd_iprintf(buffer, "\nDigital mixer:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) for (i = 0; i < 12; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) getmixer(cif, i, &rval, &lval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) snd_iprintf(buffer, "\n %d: %d %d", i, rval, lval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) "\nARM Commands num: %d failed: %d time: %d max: %d min: %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) cif->cmdcnt, cif->errcnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) cif->cmdtime, cif->cmdtimemax, cif->cmdtimemin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) snd_iprintf(buffer, "\nOpen streams %d:\n", chip->openstreams);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) for (i = 0; i < PLAYBACK_SUBSTREAMS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) if (chip->playback_substream[i]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) && chip->playback_substream[i]->runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) && (data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) chip->playback_substream[i]->runtime->private_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) "stream: %d mixer: %d source: %d (%d,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) data->id, data->mixer, data->source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) data->intdec[0], data->intdec[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) if (!(getsamplerate(cif, data->intdec, &rate)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) snd_iprintf(buffer, "rate: %d\n", rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) if (chip->capture_substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) && chip->capture_substream->runtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) && (data = chip->capture_substream->runtime->private_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) "stream: %d mixer: %d source: %d (%d,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) data->id, data->mixer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) data->source, data->intdec[0], data->intdec[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) if (!(getsamplerate(cif, data->intdec, &rate)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) snd_iprintf(buffer, "rate: %d\n", rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) snd_iprintf(buffer, "Paths:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) i = getpaths(cif, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) while (i >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) i -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) snd_iprintf(buffer, "%x->%x ", p[i], p[i + 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) snd_iprintf(buffer, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) static void snd_riptide_proc_init(struct snd_riptide *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) snd_card_ro_proc_new(chip->card, "riptide", chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) snd_riptide_proc_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) static int snd_riptide_mixer(struct snd_riptide *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) struct snd_ac97_bus *pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) struct snd_ac97_template ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) static const struct snd_ac97_bus_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) .write = snd_riptide_codec_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) .read = snd_riptide_codec_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) memset(&ac97, 0, sizeof(ac97));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) ac97.private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) ac97.scaps = AC97_SCAP_SKIP_MODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) chip->ac97_bus = pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) ac97.pci = chip->pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) snd_riptide_joystick_probe(struct pci_dev *pci, const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) struct gameport *gameport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) goto inc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) if (!joystick_port[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) goto inc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) gameport = gameport_allocate_port();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) if (!gameport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) goto inc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) if (!request_region(joystick_port[dev], 8, "Riptide gameport")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) snd_printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) "Riptide: cannot grab gameport 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) joystick_port[dev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) gameport_free_port(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) goto inc_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) gameport->io = joystick_port[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) gameport_register_port(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) pci_set_drvdata(pci, gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) inc_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) static void snd_riptide_joystick_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) struct gameport *gameport = pci_get_drvdata(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) if (gameport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) release_region(gameport->io, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) gameport_unregister_port(gameport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) static int dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) struct snd_riptide *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) err = snd_riptide_create(card, pci, &chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) card->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) err = snd_riptide_pcm(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) err = snd_riptide_mixer(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) val = LEGACY_ENABLE_ALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) if (opl3_port[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) val |= LEGACY_ENABLE_FM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) if (joystick_port[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) val |= LEGACY_ENABLE_GAMEPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) if (mpu_port[dev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) val |= LEGACY_ENABLE_MPU_INT | LEGACY_ENABLE_MPU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) val |= (chip->irq << 4) & 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) pci_write_config_word(chip->pci, PCI_EXT_Legacy_Mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) if (mpu_port[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) val = mpu_port[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) val, MPU401_INFO_IRQ_HOOK, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) &chip->rmidi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) snd_printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) "Riptide: Can't Allocate MPU at 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) chip->mpuaddr = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) if (opl3_port[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) val = opl3_port[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) pci_write_config_word(chip->pci, PCI_EXT_FM_Base, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) err = snd_opl3_create(card, val, val + 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) OPL3_HW_RIPTIDE, 0, &chip->opl3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) snd_printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) "Riptide: Can't Allocate OPL3 at 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) chip->opladdr = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) err = snd_opl3_hwdep_new(chip->opl3, 0, 1, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) snd_printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) "Riptide: Can't Allocate OPL3-HWDEP\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) if (joystick_port[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) val = joystick_port[dev];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) pci_write_config_word(chip->pci, PCI_EXT_Game_Base, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) chip->gameaddr = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) strcpy(card->driver, "RIPTIDE");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) strcpy(card->shortname, "Riptide");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) snprintf(card->longname, sizeof(card->longname),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x gameport 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) card->shortname, chip->port, chip->irq, chip->mpuaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) chip->opladdr, chip->gameaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) snprintf(card->longname, sizeof(card->longname),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) "%s at 0x%lx, irq %i mpu 0x%x opl3 0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) card->shortname, chip->port, chip->irq, chip->mpuaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) chip->opladdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) snd_riptide_proc_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) pci_set_drvdata(pci, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) static void snd_card_riptide_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) snd_card_free(pci_get_drvdata(pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) static struct pci_driver driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) .id_table = snd_riptide_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) .probe = snd_card_riptide_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) .remove = snd_card_riptide_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) .pm = RIPTIDE_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) #ifdef SUPPORT_JOYSTICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) static struct pci_driver joystick_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) .name = KBUILD_MODNAME "-joystick",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) .id_table = snd_riptide_joystick_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) .probe = snd_riptide_joystick_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) .remove = snd_riptide_joystick_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) static int __init alsa_card_riptide_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) err = pci_register_driver(&driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) #if defined(SUPPORT_JOYSTICK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) err = pci_register_driver(&joystick_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) /* On failure unregister formerly registered audio driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) pci_unregister_driver(&driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) static void __exit alsa_card_riptide_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) pci_unregister_driver(&driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) #if defined(SUPPORT_JOYSTICK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) pci_unregister_driver(&joystick_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) module_init(alsa_card_riptide_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) module_exit(alsa_card_riptide_exit);