^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for DBRI sound chip found on Sparcs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2004, 2005 Martin Habets (mhabets@users.sourceforge.net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Converted to ring buffered version by Krzysztof Helt (krzysztof.h1@wp.pl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Based entirely upon drivers/sbus/audio/dbri.c which is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 1998, 1999 Brent Baccala (baccala@freesoft.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * This is the low level driver for the DBRI & MMCODEC duo used for ISDN & AUDIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * on Sun SPARCStation 10, 20, LX and Voyager models.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * - DBRI: AT&T T5900FX Dual Basic Rates ISDN Interface. It is a 32 channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * data time multiplexer with ISDN support (aka T7259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Interfaces: SBus,ISDN NT & TE, CHI, 4 bits parallel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * CHI: (spelled ki) Concentration Highway Interface (AT&T or Intel bus ?).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Documentation:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Transceiver" from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Sparc Technology Business (courtesy of Sun Support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * - Data sheet of the T7903, a newer but very similar ISA bus equivalent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * available from the Lucent (formerly AT&T microelectronics) home
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * - https://www.freesoft.org/Linux/DBRI/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Interfaces: CHI, Audio In & Out, 2 bits parallel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Documentation: from the Crystal Semiconductor home page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * The DBRI is a 32 pipe machine, each pipe can transfer some bits between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * memory and a serial device (long pipes, no. 0-15) or between two serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * devices (short pipes, no. 16-31), or simply send a fixed data to a serial
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * device (short pipes).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * A timeslot defines the bit-offset and no. of bits read from a serial device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * The timeslots are linked to 6 circular lists, one for each direction for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * each serial device (NT,TE,CHI). A timeslot is associated to 1 or 2 pipes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * (the second one is a monitor/tee pipe, valid only for serial input).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * The mmcodec is connected via the CHI bus and needs the data & some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * parameters (volume, output selection) time multiplexed in 8 byte
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * chunks. It also has a control mode, which serves for audio format setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Looking at the CS4215 data sheet it is easy to set up 2 or 4 codecs on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * the same CHI bus, so I thought perhaps it is possible to use the on-board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * & the speakerbox codec simultaneously, giving 2 (not very independent :-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * audio devices. But the SUN HW group decided against it, at least on my
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * LX the speakerbox connector has at least 1 pin missing and 1 wrongly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * connected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * I've tried to stick to the following function naming conventions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * snd_* ALSA stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * cs4215_* CS4215 codec specific stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * dbri_* DBRI high-level stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * other DBRI low-level stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include <linux/gfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #include <sound/control.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) MODULE_DESCRIPTION("Sun DBRI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MODULE_SUPPORTED_DEVICE("{{Sun,DBRI}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Enable this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) module_param_array(index, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) MODULE_PARM_DESC(index, "Index value for Sun DBRI soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) module_param_array(id, charp, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) MODULE_PARM_DESC(id, "ID string for Sun DBRI soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) module_param_array(enable, bool, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #undef DBRI_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define D_INT (1<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define D_GEN (1<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define D_CMD (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define D_MM (1<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define D_USR (1<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define D_DESC (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static int dbri_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) module_param(dbri_debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MODULE_PARM_DESC(dbri_debug, "Debug value for Sun DBRI soundcard.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #ifdef DBRI_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static const char * const cmds[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) "WAIT", "PAUSE", "JUMP", "IIQ", "REX", "SDP", "CDP", "DTS",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) "SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define dprintk(a, x...) if (dbri_debug & a) printk(KERN_DEBUG x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define dprintk(a, x...) do { } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #endif /* DBRI_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define DBRI_CMD(cmd, intr, value) ((cmd << 28) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) (intr << 27) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /***************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) CS4215 specific definitions and structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct cs4215 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) __u8 data[4]; /* Data mode: Time slots 5-8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) __u8 ctrl[4]; /* Ctrl mode: Time slots 1-4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) __u8 onboard;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) __u8 offset; /* Bit offset from frame sync to time slot 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) volatile __u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) volatile __u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) __u8 precision; /* In bits, either 8 or 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) __u8 channels; /* 1 or 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) * Control mode first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) /* Time Slot 1, Status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define CS4215_CLB (1<<2) /* Control Latch Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define CS4215_OLB (1<<3) /* 1: line: 2.0V, speaker 4V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* 0: line: 2.8V, speaker 8V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define CS4215_MLB (1<<4) /* 1: Microphone: 20dB gain disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define CS4215_RSRVD_1 (1<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Time Slot 2, Data Format Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define CS4215_DFR_LINEAR16 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define CS4215_DFR_ULAW 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define CS4215_DFR_ALAW 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define CS4215_DFR_LINEAR8 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define CS4215_DFR_STEREO (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned short freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned char xtal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) unsigned char csval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) } CS4215_FREQ[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) { 8000, (1 << 4), (0 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) { 16000, (1 << 4), (1 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) { 27429, (1 << 4), (2 << 3) }, /* Actually 24428.57 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) { 32000, (1 << 4), (3 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /* { NA, (1 << 4), (4 << 3) }, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* { NA, (1 << 4), (5 << 3) }, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { 48000, (1 << 4), (6 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) { 9600, (1 << 4), (7 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) { 5512, (2 << 4), (0 << 3) }, /* Actually 5512.5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) { 11025, (2 << 4), (1 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) { 18900, (2 << 4), (2 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) { 22050, (2 << 4), (3 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) { 37800, (2 << 4), (4 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) { 44100, (2 << 4), (5 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { 33075, (2 << 4), (6 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) { 6615, (2 << 4), (7 << 3) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { 0, 0, 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define CS4215_HPF (1<<7) /* High Pass Filter, 1: Enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define CS4215_12_MASK 0xfcbf /* Mask off reserved bits in slot 1 & 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* Time Slot 3, Serial Port Control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define CS4215_XEN (1<<0) /* 0: Enable serial output */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define CS4215_XCLK (1<<1) /* 1: Master mode: Generate SCLK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define CS4215_BSEL_64 (0<<2) /* Bitrate: 64 bits per frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define CS4215_BSEL_128 (1<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #define CS4215_BSEL_256 (2<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define CS4215_MCK_MAST (0<<4) /* Master clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define CS4215_MCK_XTL1 (1<<4) /* 24.576 MHz clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define CS4215_MCK_XTL2 (2<<4) /* 16.9344 MHz clock source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define CS4215_MCK_CLK1 (3<<4) /* Clockin, 256 x Fs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define CS4215_MCK_CLK2 (4<<4) /* Clockin, see DFR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* Time Slot 4, Test Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define CS4215_DAD (1<<0) /* 0:Digital-Dig loop, 1:Dig-Analog-Dig loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define CS4215_ENL (1<<1) /* Enable Loopback Testing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) /* Time Slot 5, Parallel Port Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* Read only here and the same as the in data mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* Time Slot 6, Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* Time Slot 7, Version Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define CS4215_VERSION_MASK 0xf /* Known versions 0/C, 1/D, 2/E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* Time Slot 8, Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Data mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /* Time Slot 1-2: Left Channel Data, 2-3: Right Channel Data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Time Slot 5, Output Setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define CS4215_LO(v) v /* Left Output Attenuation 0x3f: -94.5 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define CS4215_LE (1<<6) /* Line Out Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define CS4215_HE (1<<7) /* Headphone Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Time Slot 6, Output Setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define CS4215_RO(v) v /* Right Output Attenuation 0x3f: -94.5 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define CS4215_SE (1<<6) /* Speaker Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define CS4215_ADI (1<<7) /* A/D Data Invalid: Busy in calibration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Time Slot 7, Input Setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define CS4215_LG(v) v /* Left Gain Setting 0xf: 22.5 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define CS4215_IS (1<<4) /* Input Select: 1=Microphone, 0=Line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define CS4215_OVR (1<<5) /* 1: Over range condition occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #define CS4215_PIO0 (1<<6) /* Parallel I/O 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) #define CS4215_PIO1 (1<<7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* Time Slot 8, Input Setting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #define CS4215_RG(v) v /* Right Gain Setting 0xf: 22.5 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) #define CS4215_MA(v) (v<<4) /* Monitor Path Attenuation 0xf: mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /***************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) DBRI specific definitions and structures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* DBRI main registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) #define REG0 0x00 /* Status and Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #define REG1 0x04 /* Mode and Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #define REG2 0x08 /* Parallel IO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #define REG3 0x0c /* Test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define REG8 0x20 /* Command Queue Pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #define REG9 0x24 /* Interrupt Queue Pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) #define DBRI_NO_CMDS 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) #define DBRI_INT_BLK 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) #define DBRI_NO_DESCS 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) #define DBRI_NO_PIPES 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) #define DBRI_MAX_PIPE (DBRI_NO_PIPES - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) #define DBRI_REC 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #define DBRI_PLAY 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #define DBRI_NO_STREAMS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* One transmit/receive descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* When ba != 0 descriptor is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct dbri_mem {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) volatile __u32 word1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) __u32 ba; /* Transmit/Receive Buffer Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) __u32 nda; /* Next Descriptor Address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) volatile __u32 word4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* This structure is in a DMA region where it can accessed by both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * the CPU and the DBRI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct dbri_dma {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) s32 cmd[DBRI_NO_CMDS]; /* Place for commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) volatile s32 intr[DBRI_INT_BLK]; /* Interrupt field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct dbri_mem desc[DBRI_NO_DESCS]; /* Xmit/receive descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) #define dbri_dma_off(member, elem) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) ((u32)(unsigned long) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) (&(((struct dbri_dma *)0)->member[elem])))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) enum in_or_out { PIPEinput, PIPEoutput };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct dbri_pipe {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u32 sdp; /* SDP command word */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int nextpipe; /* Next pipe in linked list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int length; /* Length of timeslot (bits) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int first_desc; /* Index of first descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int desc; /* Index of active descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) volatile __u32 *recv_fixed_ptr; /* Ptr to receive fixed data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* Per stream (playback or record) information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct dbri_streaminfo {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct snd_pcm_substream *substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 dvma_buffer; /* Device view of ALSA DMA buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) int size; /* Size of DMA buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) size_t offset; /* offset in user buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int pipe; /* Data pipe used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int left_gain; /* mixer elements */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int right_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) /* This structure holds the information for both chips (DBRI & CS4215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct snd_dbri {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int regs_size, irq; /* Needed for unload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct platform_device *op; /* OF device info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct dbri_dma *dma; /* Pointer to our DMA block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) dma_addr_t dma_dvma; /* DBRI visible DMA address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) void __iomem *regs; /* dbri HW regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int dbri_irqp; /* intr queue pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int next_desc[DBRI_NO_DESCS]; /* Index of next desc, or -1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) spinlock_t cmdlock; /* Protects cmd queue accesses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) s32 *cmdptr; /* Pointer to the last queued cmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int chi_bpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct cs4215 mm; /* mmcodec special info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /* per stream (playback/record) info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct dbri_streaminfo stream_info[DBRI_NO_STREAMS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) #define DBRI_MAX_VOLUME 63 /* Output volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) #define DBRI_MAX_GAIN 15 /* Input gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* DBRI Reg0 - Status Control Register - defines. (Page 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) #define D_P (1<<15) /* Program command & queue pointer valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #define D_G (1<<14) /* Allow 4-Word SBus Burst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) #define D_S (1<<13) /* Allow 16-Word SBus Burst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) #define D_E (1<<12) /* Allow 8-Word SBus Burst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #define D_X (1<<7) /* Sanity Timer Disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) #define D_T (1<<6) /* Permit activation of the TE interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #define D_N (1<<5) /* Permit activation of the NT interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) #define D_C (1<<4) /* Permit activation of the CHI interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #define D_F (1<<3) /* Force Sanity Timer Time-Out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) #define D_D (1<<2) /* Disable Master Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #define D_H (1<<1) /* Halt for Analysis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #define D_R (1<<0) /* Soft Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* DBRI Reg1 - Mode and Interrupt Register - defines. (Page 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) #define D_LITTLE_END (1<<8) /* Byte Order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #define D_BIG_END (0<<8) /* Byte Order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) #define D_MRR (1<<4) /* Multiple Error Ack on SBus (read only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) #define D_MLE (1<<3) /* Multiple Late Error on SBus (read only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) #define D_LBG (1<<2) /* Lost Bus Grant on SBus (read only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) #define D_MBE (1<<1) /* Burst Error on SBus (read only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) #define D_IR (1<<0) /* Interrupt Indicator (read only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) /* DBRI Reg2 - Parallel IO Register - defines. (Page 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) #define D_ENPIO3 (1<<7) /* Enable Pin 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #define D_ENPIO2 (1<<6) /* Enable Pin 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #define D_ENPIO1 (1<<5) /* Enable Pin 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) #define D_ENPIO0 (1<<4) /* Enable Pin 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) #define D_ENPIO (0xf0) /* Enable all the pins */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) #define D_PIO3 (1<<3) /* Pin 3: 1: Data mode, 0: Ctrl mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) #define D_PIO2 (1<<2) /* Pin 2: 1: Onboard PDN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) #define D_PIO1 (1<<1) /* Pin 1: 0: Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) #define D_PIO0 (1<<0) /* Pin 0: 1: Speakerbox PDN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* DBRI Commands (Page 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) #define D_WAIT 0x0 /* Stop execution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) #define D_PAUSE 0x1 /* Flush long pipes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #define D_JUMP 0x2 /* New command queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) #define D_IIQ 0x3 /* Initialize Interrupt Queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) #define D_REX 0x4 /* Report command execution via interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) #define D_SDP 0x5 /* Setup Data Pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) #define D_CDP 0x6 /* Continue Data Pipe (reread NULL Pointer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) #define D_DTS 0x7 /* Define Time Slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) #define D_SSP 0x8 /* Set short Data Pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #define D_CHI 0x9 /* Set CHI Global Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) #define D_NT 0xa /* NT Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) #define D_TE 0xb /* TE Command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) #define D_CDEC 0xc /* Codec setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) #define D_TEST 0xd /* No comment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) #define D_CDM 0xe /* CHI Data mode command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* Special bits for some commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) #define D_PIPE(v) ((v)<<0) /* Pipe No.: 0-15 long, 16-21 short */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) /* Setup Data Pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* IRM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) #define D_SDP_2SAME (1<<18) /* Report 2nd time in a row value received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) #define D_SDP_CHANGE (2<<18) /* Report any changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #define D_SDP_EVERY (3<<18) /* Report any changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) #define D_SDP_EOL (1<<17) /* EOL interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) #define D_SDP_IDLE (1<<16) /* HDLC idle interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* Pipe data MODE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #define D_SDP_MEM (0<<13) /* To/from memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) #define D_SDP_HDLC (2<<13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) #define D_SDP_HDLC_D (3<<13) /* D Channel (prio control) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) #define D_SDP_SER (4<<13) /* Serial to serial */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) #define D_SDP_FIXED (6<<13) /* Short only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) #define D_SDP_MODE(v) ((v)&(7<<13))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) #define D_SDP_TO_SER (1<<12) /* Direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) #define D_SDP_FROM_SER (0<<12) /* Direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) #define D_SDP_MSB (1<<11) /* Bit order within Byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) #define D_SDP_LSB (0<<11) /* Bit order within Byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) #define D_SDP_P (1<<10) /* Pointer Valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) #define D_SDP_A (1<<8) /* Abort */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) #define D_SDP_C (1<<7) /* Clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* Define Time Slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) #define D_DTS_VI (1<<17) /* Valid Input Time-Slot Descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) #define D_DTS_VO (1<<16) /* Valid Output Time-Slot Descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) #define D_DTS_INS (1<<15) /* Insert Time Slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) #define D_DTS_DEL (0<<15) /* Delete Time Slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) #define D_DTS_PRVIN(v) ((v)<<10) /* Previous In Pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) #define D_DTS_PRVOUT(v) ((v)<<5) /* Previous Out Pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /* Time Slot defines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) #define D_TS_LEN(v) ((v)<<24) /* Number of bits in this time slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) #define D_TS_CYCLE(v) ((v)<<14) /* Bit Count at start of TS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #define D_TS_DI (1<<13) /* Data Invert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) #define D_TS_1CHANNEL (0<<10) /* Single Channel / Normal mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) #define D_TS_MONITOR (2<<10) /* Monitor pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) #define D_TS_NONCONTIG (3<<10) /* Non contiguous mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) #define D_TS_ANCHOR (7<<10) /* Starting short pipes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) #define D_TS_MON(v) ((v)<<5) /* Monitor Pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) #define D_TS_NEXT(v) ((v)<<0) /* Pipe no.: 0-15 long, 16-21 short */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* Concentration Highway Interface Modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) #define D_CHI_CHICM(v) ((v)<<16) /* Clock mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) #define D_CHI_IR (1<<15) /* Immediate Interrupt Report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) #define D_CHI_EN (1<<14) /* CHIL Interrupt enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #define D_CHI_OD (1<<13) /* Open Drain Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) #define D_CHI_FE (1<<12) /* Sample CHIFS on Rising Frame Edge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #define D_CHI_FD (1<<11) /* Frame Drive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) #define D_CHI_BPF(v) ((v)<<0) /* Bits per Frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* NT: These are here for completeness */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) #define D_NT_FBIT (1<<17) /* Frame Bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #define D_NT_NBF (1<<16) /* Number of bad frames to loose framing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) #define D_NT_IRM_IMM (1<<15) /* Interrupt Report & Mask: Immediate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) #define D_NT_IRM_EN (1<<14) /* Interrupt Report & Mask: Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) #define D_NT_ISNT (1<<13) /* Configure interface as NT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) #define D_NT_FT (1<<12) /* Fixed Timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) #define D_NT_EZ (1<<11) /* Echo Channel is Zeros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) #define D_NT_IFA (1<<10) /* Inhibit Final Activation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) #define D_NT_ACT (1<<9) /* Activate Interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) #define D_NT_MFE (1<<8) /* Multiframe Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) #define D_NT_RLB(v) ((v)<<5) /* Remote Loopback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) #define D_NT_LLB(v) ((v)<<2) /* Local Loopback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) #define D_NT_FACT (1<<1) /* Force Activation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) #define D_NT_ABV (1<<0) /* Activate Bipolar Violation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* Codec Setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) #define D_CDEC_CK(v) ((v)<<24) /* Clock Select */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) #define D_CDEC_FED(v) ((v)<<12) /* FSCOD Falling Edge Delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) #define D_CDEC_RED(v) ((v)<<0) /* FSCOD Rising Edge Delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* Test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) #define D_TEST_RAM(v) ((v)<<16) /* RAM Pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) #define D_TEST_SIZE(v) ((v)<<11) /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) #define D_TEST_ROMONOFF 0x5 /* Toggle ROM opcode monitor on/off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) #define D_TEST_PROC 0x6 /* Microprocessor test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) #define D_TEST_SER 0x7 /* Serial-Controller test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #define D_TEST_RAMREAD 0x8 /* Copy from Ram to system memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) #define D_TEST_RAMWRITE 0x9 /* Copy into Ram from system memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) #define D_TEST_RAMBIST 0xa /* RAM Built-In Self Test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) #define D_TEST_MCBIST 0xb /* Microcontroller Built-In Self Test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) #define D_TEST_DUMP 0xe /* ROM Dump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* CHI Data Mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) #define D_CDM_THI (1 << 8) /* Transmit Data on CHIDR Pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) #define D_CDM_RHI (1 << 7) /* Receive Data on CHIDX Pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) #define D_CDM_RCE (1 << 6) /* Receive on Rising Edge of CHICK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) #define D_CDM_XCE (1 << 2) /* Transmit Data on Rising Edge of CHICK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) #define D_CDM_XEN (1 << 1) /* Transmit Highway Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) #define D_CDM_REN (1 << 0) /* Receive Highway Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* The Interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) #define D_INTR_BRDY 1 /* Buffer Ready for processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) #define D_INTR_MINT 2 /* Marked Interrupt in RD/TD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) #define D_INTR_IBEG 3 /* Flag to idle transition detected (HDLC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) #define D_INTR_IEND 4 /* Idle to flag transition detected (HDLC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) #define D_INTR_EOL 5 /* End of List */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) #define D_INTR_CMDI 6 /* Command has bean read */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) #define D_INTR_XCMP 8 /* Transmission of frame complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #define D_INTR_SBRI 9 /* BRI status change info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) #define D_INTR_FXDT 10 /* Fixed data change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) #define D_INTR_CHIL 11 /* CHI lost frame sync (channel 36 only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) #define D_INTR_COLL 11 /* Unrecoverable D-Channel collision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) #define D_INTR_DBYT 12 /* Dropped by frame slip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) #define D_INTR_RBYT 13 /* Repeated by frame slip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) #define D_INTR_LINT 14 /* Lost Interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) #define D_INTR_UNDR 15 /* DMA underrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) #define D_INTR_TE 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) #define D_INTR_NT 34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) #define D_INTR_CHI 36
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) #define D_INTR_CMD 38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) #define D_INTR_GETCHAN(v) (((v) >> 24) & 0x3f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) #define D_INTR_GETCODE(v) (((v) >> 20) & 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #define D_INTR_GETCMD(v) (((v) >> 16) & 0xf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) #define D_INTR_GETVAL(v) ((v) & 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #define D_INTR_GETRVAL(v) ((v) & 0xfffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #define D_P_0 0 /* TE receive anchor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #define D_P_1 1 /* TE transmit anchor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) #define D_P_2 2 /* NT transmit anchor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #define D_P_3 3 /* NT receive anchor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) #define D_P_4 4 /* CHI send data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #define D_P_5 5 /* CHI receive data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) #define D_P_6 6 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) #define D_P_7 7 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) #define D_P_8 8 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) #define D_P_9 9 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) #define D_P_10 10 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) #define D_P_11 11 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) #define D_P_12 12 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) #define D_P_13 13 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) #define D_P_14 14 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) #define D_P_15 15 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) #define D_P_16 16 /* CHI anchor pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) #define D_P_17 17 /* CHI send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) #define D_P_18 18 /* CHI receive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) #define D_P_19 19 /* CHI receive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) #define D_P_20 20 /* CHI receive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) #define D_P_21 21 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #define D_P_22 22 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) #define D_P_23 23 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) #define D_P_24 24 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) #define D_P_25 25 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) #define D_P_26 26 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) #define D_P_27 27 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #define D_P_28 28 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) #define D_P_29 29 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) #define D_P_30 30 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) #define D_P_31 31 /* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* Transmit descriptor defines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #define DBRI_TD_F (1 << 31) /* End of Frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) #define DBRI_TD_D (1 << 30) /* Do not append CRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) #define DBRI_TD_CNT(v) ((v) << 16) /* Number of valid bytes in the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) #define DBRI_TD_B (1 << 15) /* Final interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) #define DBRI_TD_M (1 << 14) /* Marker interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) #define DBRI_TD_I (1 << 13) /* Transmit Idle Characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) #define DBRI_TD_FCNT(v) (v) /* Flag Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) #define DBRI_TD_UNR (1 << 3) /* Underrun: transmitter is out of data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) #define DBRI_TD_ABT (1 << 2) /* Abort: frame aborted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) #define DBRI_TD_TBC (1 << 0) /* Transmit buffer Complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) #define DBRI_TD_STATUS(v) ((v) & 0xff) /* Transmit status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Maximum buffer size per TD: almost 8KB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) #define DBRI_TD_MAXCNT ((1 << 13) - 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) /* Receive descriptor defines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) #define DBRI_RD_F (1 << 31) /* End of Frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) #define DBRI_RD_C (1 << 30) /* Completed buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) #define DBRI_RD_B (1 << 15) /* Final interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) #define DBRI_RD_M (1 << 14) /* Marker interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) #define DBRI_RD_BCNT(v) (v) /* Buffer size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) #define DBRI_RD_CRC (1 << 7) /* 0: CRC is correct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) #define DBRI_RD_BBC (1 << 6) /* 1: Bad Byte received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) #define DBRI_RD_ABT (1 << 5) /* Abort: frame aborted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) #define DBRI_RD_OVRN (1 << 3) /* Overrun: data lost */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) #define DBRI_RD_STATUS(v) ((v) & 0xff) /* Receive status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) #define DBRI_RD_CNT(v) (((v) >> 16) & 0x1fff) /* Valid bytes in the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* stream_info[] access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Translate the ALSA direction into the array index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) #define DBRI_STREAMNO(substream) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) (substream->stream == \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) SNDRV_PCM_STREAM_PLAYBACK ? DBRI_PLAY: DBRI_REC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* Return a pointer to dbri_streaminfo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) #define DBRI_STREAM(dbri, substream) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) &dbri->stream_info[DBRI_STREAMNO(substream)]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * Short data pipes transmit LSB first. The CS4215 receives MSB first. Grrr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * So we have to reverse the bits. Note: not all bit lengths are supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static __u32 reverse_bytes(__u32 b, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) case 32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) b = ((b & 0xffff0000) >> 16) | ((b & 0x0000ffff) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) b = ((b & 0xff00ff00) >> 8) | ((b & 0x00ff00ff) << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) b = ((b & 0xf0f0f0f0) >> 4) | ((b & 0x0f0f0f0f) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) b = ((b & 0xcccccccc) >> 2) | ((b & 0x33333333) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) b = ((b & 0xaaaaaaaa) >> 1) | ((b & 0x55555555) << 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) printk(KERN_ERR "DBRI reverse_bytes: unsupported length\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) ************** DBRI initialization and command synchronization *************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) Commands are sent to the DBRI by building a list of them in memory,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) then writing the address of the first list item to DBRI register 8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) The list is terminated with a WAIT command, which generates a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) CPU interrupt to signal completion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) Since the DBRI can run in parallel with the CPU, several means of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) synchronization present themselves. The method implemented here uses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) the dbri_cmdwait() to wait for execution of batch of sent commands.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) A circular command buffer is used here. A new command is being added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) while another can be executed. The scheme works by adding two WAIT commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) after each sent batch of commands. When the next batch is prepared it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) added after the WAIT commands then the WAITs are replaced with single JUMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) command to the new batch. Then the DBRI is forced to reread the last WAIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) command (replaced by the JUMP by then). If the DBRI is still executing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) previous commands the request to reread the WAIT command is ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) Every time a routine wants to write commands to the DBRI, it must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) first call dbri_cmdlock() and get pointer to a free space in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) dbri->dma->cmd buffer. After this, the commands can be written to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) the buffer, and dbri_cmdsend() is called with the final pointer value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) to send them to the DBRI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) #define MAXLOOPS 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * Wait for the current command string to execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static void dbri_cmdwait(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) int maxloops = MAXLOOPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /* Delay if previous commands are still being processed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) msleep_interruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (maxloops == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) printk(KERN_ERR "DBRI: Chip never completed command buffer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) dprintk(D_CMD, "Chip completed command buffer (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) MAXLOOPS - maxloops - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * Lock the command queue and return pointer to space for len cmd words
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * It locks the cmdlock spinlock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) u32 dvma_addr = (u32)dbri->dma_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) /* Space for 2 WAIT cmds (replaced later by 1 JUMP cmd) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) len += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) spin_lock(&dbri->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (dbri->cmdptr - dbri->dma->cmd + len < DBRI_NO_CMDS - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return dbri->cmdptr + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) else if (len < sbus_readl(dbri->regs + REG8) - dvma_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return dbri->dma->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) printk(KERN_ERR "DBRI: no space for commands.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * Send prepared cmd string. It works by writing a JUMP cmd into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * the last WAIT cmd and force DBRI to reread the cmd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * The JUMP cmd points to the new cmd string.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * It also releases the cmdlock spinlock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * Lock must be held before calling this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static void dbri_cmdsend(struct snd_dbri *dbri, s32 *cmd, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) u32 dvma_addr = (u32)dbri->dma_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) s32 tmp, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int wait_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) wait_id++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) wait_id &= 0xffff; /* restrict it to a 16 bit counter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) *(cmd) = DBRI_CMD(D_WAIT, 1, wait_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) *(cmd+1) = DBRI_CMD(D_WAIT, 1, wait_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /* Replace the last command with JUMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) addr = dvma_addr + (cmd - len - dbri->dma->cmd) * sizeof(s32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) *(dbri->cmdptr+1) = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) *(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) #ifdef DBRI_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (cmd > dbri->cmdptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) s32 *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) dprintk(D_CMD, "cmd: %lx:%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) (unsigned long)ptr, *ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) s32 *ptr = dbri->cmdptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dprintk(D_CMD, "cmd: %lx:%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) (unsigned long)ptr, *ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) /* Reread the last command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) tmp = sbus_readl(dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) tmp |= D_P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) sbus_writel(tmp, dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) dbri->cmdptr = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) spin_unlock(&dbri->cmdlock);
^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) /* Lock must be held when calling this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static void dbri_reset(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) dprintk(D_GEN, "reset 0:%x 2:%x 8:%x 9:%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) sbus_readl(dbri->regs + REG0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) sbus_readl(dbri->regs + REG2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) sbus_readl(dbri->regs + REG8), sbus_readl(dbri->regs + REG9));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) sbus_writel(D_R, dbri->regs + REG0); /* Soft Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) for (i = 0; (sbus_readl(dbri->regs + REG0) & D_R) && i < 64; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* A brute approach - DBRI falls back to working burst size by itself
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * On SS20 D_S does not work, so do not try so high. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) tmp = sbus_readl(dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) tmp |= D_G | D_E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) tmp &= ~D_S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) sbus_writel(tmp, dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* Lock must not be held before calling this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static void dbri_initialize(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) u32 dvma_addr = (u32)dbri->dma_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) s32 *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) u32 dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) dbri_reset(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* Initialize pipes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) for (n = 0; n < DBRI_NO_PIPES; n++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) spin_lock_init(&dbri->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * Initialize the interrupt ring buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) dma_addr = dvma_addr + dbri_dma_off(intr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) dbri->dma->intr[0] = dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dbri->dbri_irqp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * Set up the interrupt queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) spin_lock(&dbri->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) cmd = dbri->cmdptr = dbri->dma->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) *(cmd++) = DBRI_CMD(D_IIQ, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) *(cmd++) = dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) dbri->cmdptr = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) *(cmd++) = DBRI_CMD(D_WAIT, 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dma_addr = dvma_addr + dbri_dma_off(cmd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) sbus_writel(dma_addr, dbri->regs + REG8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) spin_unlock(&dbri->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dbri_cmdwait(dbri);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) ************************** DBRI data pipe management ***********************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) While DBRI control functions use the command and interrupt buffers, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) main data path takes the form of data pipes, which can be short (command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) and interrupt driven), or long (attached to DMA buffers). These functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) provide a rudimentary means of setting up and managing the DBRI's pipes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) but the calling functions have to make sure they respect the pipes' linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) list ordering, among other things. The transmit and receive functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) here interface closely with the transmit and receive interrupt code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static inline int pipe_active(struct snd_dbri *dbri, int pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* reset_pipe(dbri, pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * Called on an in-use pipe to clear anything being transmitted or received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * Lock must be held before calling this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static void reset_pipe(struct snd_dbri *dbri, int pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int sdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) int desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) s32 *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (pipe < 0 || pipe > DBRI_MAX_PIPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) printk(KERN_ERR "DBRI: reset_pipe called with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) "illegal pipe number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) sdp = dbri->pipes[pipe].sdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (sdp == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) printk(KERN_ERR "DBRI: reset_pipe called "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) "on uninitialized pipe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) cmd = dbri_cmdlock(dbri, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) *(cmd++) = DBRI_CMD(D_SDP, 0, sdp | D_SDP_C | D_SDP_P);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) *(cmd++) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) dbri_cmdsend(dbri, cmd, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) desc = dbri->pipes[pipe].first_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (desc >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) dbri->dma->desc[desc].ba = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) dbri->dma->desc[desc].nda = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) desc = dbri->next_desc[desc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) } while (desc != -1 && desc != dbri->pipes[pipe].first_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) dbri->pipes[pipe].desc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) dbri->pipes[pipe].first_desc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) * Lock must be held before calling this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static void setup_pipe(struct snd_dbri *dbri, int pipe, int sdp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (pipe < 0 || pipe > DBRI_MAX_PIPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) printk(KERN_ERR "DBRI: setup_pipe called "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) "with illegal pipe number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if ((sdp & 0xf800) != sdp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) printk(KERN_ERR "DBRI: setup_pipe called "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) "with strange SDP value\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* sdp &= 0xf800; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /* If this is a fixed receive pipe, arrange for an interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * every time its data changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (D_SDP_MODE(sdp) == D_SDP_FIXED && !(sdp & D_SDP_TO_SER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) sdp |= D_SDP_CHANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) sdp |= D_PIPE(pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) dbri->pipes[pipe].sdp = sdp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) dbri->pipes[pipe].desc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) dbri->pipes[pipe].first_desc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) reset_pipe(dbri, pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * Lock must be held before calling this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static void link_time_slot(struct snd_dbri *dbri, int pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) int prevpipe, int nextpipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) int length, int cycle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) s32 *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (pipe < 0 || pipe > DBRI_MAX_PIPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) "DBRI: link_time_slot called with illegal pipe number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (dbri->pipes[pipe].sdp == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) || dbri->pipes[prevpipe].sdp == 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) || dbri->pipes[nextpipe].sdp == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) printk(KERN_ERR "DBRI: link_time_slot called "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) "on uninitialized pipe\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) dbri->pipes[prevpipe].nextpipe = pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) dbri->pipes[pipe].nextpipe = nextpipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) dbri->pipes[pipe].length = length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) cmd = dbri_cmdlock(dbri, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /* Deal with CHI special case:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * "If transmission on edges 0 or 1 is desired, then cycle n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * (where n = # of bit times per frame...) must be used."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) * - DBRI data sheet, page 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (prevpipe == 16 && cycle == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) cycle = dbri->chi_bpf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) val = D_DTS_VO | D_DTS_INS | D_DTS_PRVOUT(prevpipe) | pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) *(cmd++) = DBRI_CMD(D_DTS, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) *(cmd++) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) *(cmd++) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) val = D_DTS_VI | D_DTS_INS | D_DTS_PRVIN(prevpipe) | pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) *(cmd++) = DBRI_CMD(D_DTS, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) *(cmd++) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) D_TS_LEN(length) | D_TS_CYCLE(cycle) | D_TS_NEXT(nextpipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) *(cmd++) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) dbri_cmdsend(dbri, cmd, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * Lock must be held before calling this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static void unlink_time_slot(struct snd_dbri *dbri, int pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) enum in_or_out direction, int prevpipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) int nextpipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) s32 *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (pipe < 0 || pipe > DBRI_MAX_PIPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) || prevpipe < 0 || prevpipe > DBRI_MAX_PIPE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) || nextpipe < 0 || nextpipe > DBRI_MAX_PIPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) "DBRI: unlink_time_slot called with illegal pipe number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) cmd = dbri_cmdlock(dbri, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (direction == PIPEinput) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) val = D_DTS_VI | D_DTS_DEL | D_DTS_PRVIN(prevpipe) | pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) *(cmd++) = DBRI_CMD(D_DTS, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) *(cmd++) = D_TS_NEXT(nextpipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) *(cmd++) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) val = D_DTS_VO | D_DTS_DEL | D_DTS_PRVOUT(prevpipe) | pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) *(cmd++) = DBRI_CMD(D_DTS, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) *(cmd++) = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) *(cmd++) = D_TS_NEXT(nextpipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) dbri_cmdsend(dbri, cmd, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /* xmit_fixed() / recv_fixed()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) * Transmit/receive data on a "fixed" pipe - i.e, one whose contents are not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) * expected to change much, and which we don't need to buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) * The DBRI only interrupts us when the data changes (receive pipes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) * or only changes the data when this function is called (transmit pipes).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * Only short pipes (numbers 16-31) can be used in fixed data mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * These function operate on a 32-bit field, no matter how large
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * the actual time slot is. The interrupt handler takes care of bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * ordering and alignment. An 8-bit time slot will always end up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * in the low-order 8 bits, filled either MSB-first or LSB-first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * depending on the settings passed to setup_pipe().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * Lock must not be held before calling it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static void xmit_fixed(struct snd_dbri *dbri, int pipe, unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) s32 *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (pipe < 16 || pipe > DBRI_MAX_PIPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) printk(KERN_ERR "DBRI: xmit_fixed: Illegal pipe number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) printk(KERN_ERR "DBRI: xmit_fixed: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) "Uninitialized pipe %d\n", pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) printk(KERN_ERR "DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) printk(KERN_ERR "DBRI: xmit_fixed: Called on receive pipe %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /* DBRI short pipes always transmit LSB first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (dbri->pipes[pipe].sdp & D_SDP_MSB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) data = reverse_bytes(data, dbri->pipes[pipe].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) cmd = dbri_cmdlock(dbri, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) *(cmd++) = DBRI_CMD(D_SSP, 0, pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) *(cmd++) = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) dbri_cmdsend(dbri, cmd, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) dbri_cmdwait(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static void recv_fixed(struct snd_dbri *dbri, int pipe, volatile __u32 *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (pipe < 16 || pipe > DBRI_MAX_PIPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) printk(KERN_ERR "DBRI: recv_fixed called with "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) "illegal pipe number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) printk(KERN_ERR "DBRI: recv_fixed called on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) "non-fixed pipe %d\n", pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) printk(KERN_ERR "DBRI: recv_fixed called on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) "transmit pipe %d\n", pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) dbri->pipes[pipe].recv_fixed_ptr = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /* setup_descs()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) * Setup transmit/receive data on a "long" pipe - i.e, one associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) * with a DMA buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) * Only pipe numbers 0-15 can be used in this mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * This function takes a stream number pointing to a data buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) * and work by building chains of descriptors which identify the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * data buffers. Buffers too large for a single descriptor will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * be spread across multiple descriptors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * All descriptors create a ring buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) * Lock must be held before calling this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct dbri_streaminfo *info = &dbri->stream_info[streamno];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) u32 dvma_addr = (u32)dbri->dma_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) __u32 dvma_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) int desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) int first_desc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) int last_desc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (info->pipe < 0 || info->pipe > 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) printk(KERN_ERR "DBRI: setup_descs: Illegal pipe number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (dbri->pipes[info->pipe].sdp == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) printk(KERN_ERR "DBRI: setup_descs: Uninitialized pipe %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) info->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) return -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dvma_buffer = info->dvma_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) len = info->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (streamno == DBRI_PLAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) printk(KERN_ERR "DBRI: setup_descs: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) "Called on receive pipe %d\n", info->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) return -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) "DBRI: setup_descs: Called on transmit pipe %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) info->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* Should be able to queue multiple buffers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * to receive on a pipe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (pipe_active(dbri, info->pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) printk(KERN_ERR "DBRI: recv_on_pipe: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) "Called on active pipe %d\n", info->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return -2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) /* Make sure buffer size is multiple of four */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) len &= ~3;
^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) /* Free descriptors if pipe has any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) desc = dbri->pipes[info->pipe].first_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (desc >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) dbri->dma->desc[desc].ba = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) dbri->dma->desc[desc].nda = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) desc = dbri->next_desc[desc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) } while (desc != -1 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) desc != dbri->pipes[info->pipe].first_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) dbri->pipes[info->pipe].desc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) dbri->pipes[info->pipe].first_desc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) desc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) int mylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) for (; desc < DBRI_NO_DESCS; desc++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) if (!dbri->dma->desc[desc].ba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (desc == DBRI_NO_DESCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) printk(KERN_ERR "DBRI: setup_descs: No descriptors\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (len > DBRI_TD_MAXCNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) mylen = DBRI_TD_MAXCNT; /* 8KB - 4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) mylen = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (mylen > period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) mylen = period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) dbri->next_desc[desc] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) dbri->dma->desc[desc].ba = dvma_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) dbri->dma->desc[desc].nda = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (streamno == DBRI_PLAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) dbri->dma->desc[desc].word4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) dbri->dma->desc[desc].word1 |= DBRI_TD_F | DBRI_TD_B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) dbri->dma->desc[desc].word1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) dbri->dma->desc[desc].word4 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) DBRI_RD_B | DBRI_RD_BCNT(mylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) if (first_desc == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) first_desc = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) dbri->next_desc[last_desc] = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) dbri->dma->desc[last_desc].nda =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) dvma_addr + dbri_dma_off(desc, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) last_desc = desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) dvma_buffer += mylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) len -= mylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) if (first_desc == -1 || last_desc == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) printk(KERN_ERR "DBRI: setup_descs: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) " Not enough descriptors available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) dbri->dma->desc[last_desc].nda =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) dvma_addr + dbri_dma_off(desc, first_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) dbri->next_desc[last_desc] = first_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) dbri->pipes[info->pipe].first_desc = first_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) dbri->pipes[info->pipe].desc = first_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) #ifdef DBRI_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) for (desc = first_desc; desc != -1;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) dbri->dma->desc[desc].word1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) dbri->dma->desc[desc].ba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) desc = dbri->next_desc[desc];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (desc == first_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) }
^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) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) ************************** DBRI - CHI interface ****************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) The CHI is a four-wire (clock, frame sync, data in, data out) time-division
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) multiplexed serial interface which the DBRI can operate in either master
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) (give clock/frame sync) or slave (take clock/frame sync) mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) enum master_or_slave { CHImaster, CHIslave };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) * Lock must not be held before calling it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) static void reset_chi(struct snd_dbri *dbri,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) enum master_or_slave master_or_slave,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) int bits_per_frame)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) s32 *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /* Set CHI Anchor: Pipe 16 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) cmd = dbri_cmdlock(dbri, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) val = D_DTS_VO | D_DTS_VI | D_DTS_INS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) | D_DTS_PRVIN(16) | D_PIPE(16) | D_DTS_PRVOUT(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) *(cmd++) = DBRI_CMD(D_DTS, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) *(cmd++) = D_TS_ANCHOR | D_TS_NEXT(16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) dbri_cmdsend(dbri, cmd, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) dbri->pipes[16].sdp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) dbri->pipes[16].nextpipe = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) cmd = dbri_cmdlock(dbri, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (master_or_slave == CHIslave) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) /* Setup DBRI for CHI Slave - receive clock, frame sync (FS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * CHICM = 0 (slave mode, 8 kHz frame rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * IR = give immediate CHI status interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) * EN = give CHI status interrupt upon change
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) /* Setup DBRI for CHI Master - generate clock, FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) * BPF = bits per 8 kHz frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) * 12.288 MHz / CHICM_divisor = clock rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) * FD = 1 - drive CHIFS on rising edge of CHICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) int clockrate = bits_per_frame * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) int divisor = 12288 / clockrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) if (divisor > 255 || divisor * clockrate != 12288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) printk(KERN_ERR "DBRI: illegal bits_per_frame "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) "in setup_chi\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) *(cmd++) = DBRI_CMD(D_CHI, 0, D_CHI_CHICM(divisor) | D_CHI_FD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) | D_CHI_BPF(bits_per_frame));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) dbri->chi_bpf = bits_per_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /* CHI Data Mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * RCE = 0 - receive on falling edge of CHICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * XCE = 1 - transmit on rising edge of CHICK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * XEN = 1 - enable transmitter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) * REN = 1 - enable receiver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) *(cmd++) = DBRI_CMD(D_CDM, 0, D_CDM_XCE | D_CDM_XEN | D_CDM_REN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) *(cmd++) = DBRI_CMD(D_PAUSE, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) dbri_cmdsend(dbri, cmd, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) *********************** CS4215 audio codec management **********************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) In the standard SPARC audio configuration, the CS4215 codec is attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) to the DBRI via the CHI interface and few of the DBRI's PIO pins.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) * Lock must not be held before calling it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) static void cs4215_setup_pipes(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * Data mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * Pipe 4: Send timeslots 1-4 (audio data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * Pipe 20: Send timeslots 5-8 (part of ctrl data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * Pipe 6: Receive timeslots 1-4 (audio data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) * interrupt, and the rest of the data (slot 5 and 8) is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) * not relevant for us (only for doublechecking).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) * Control mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) * Pipe 18: Receive timeslot 1 (clb).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) * Pipe 19: Receive timeslot 7 (version).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) setup_pipe(dbri, 4, D_SDP_MEM | D_SDP_TO_SER | D_SDP_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) setup_pipe(dbri, 20, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) setup_pipe(dbri, 6, D_SDP_MEM | D_SDP_FROM_SER | D_SDP_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) setup_pipe(dbri, 21, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) setup_pipe(dbri, 17, D_SDP_FIXED | D_SDP_TO_SER | D_SDP_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) setup_pipe(dbri, 18, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) setup_pipe(dbri, 19, D_SDP_FIXED | D_SDP_FROM_SER | D_SDP_MSB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) dbri_cmdwait(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) static int cs4215_init_data(struct cs4215 *mm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) * No action, memory resetting only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) * Data Time Slot 5-8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) * Speaker,Line and Headphone enable. Gain set to the half.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) * Input is mike.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) mm->data[0] = CS4215_LO(0x20) | CS4215_HE | CS4215_LE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) mm->data[1] = CS4215_RO(0x20) | CS4215_SE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) mm->data[2] = CS4215_LG(0x8) | CS4215_IS | CS4215_PIO0 | CS4215_PIO1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) mm->data[3] = CS4215_RG(0x8) | CS4215_MA(0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * Control Time Slot 1-4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * 0: Default I/O voltage scale
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * 1: 8 bit ulaw, 8kHz, mono, high pass filter disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) * 2: Serial enable, CHI master, 128 bits per frame, clock 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) * 3: Tests disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) mm->ctrl[0] = CS4215_RSRVD_1 | CS4215_MLB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) mm->ctrl[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) mm->ctrl[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) mm->ctrl[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) mm->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) mm->version = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) mm->precision = 8; /* For ULAW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) mm->channels = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) static void cs4215_setdata(struct snd_dbri *dbri, int muted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (muted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) dbri->mm.data[0] |= 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) dbri->mm.data[1] |= 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) dbri->mm.data[2] &= ~15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) dbri->mm.data[3] &= ~15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) /* Start by setting the playback attenuation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) int left_gain = info->left_gain & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) int right_gain = info->right_gain & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) dbri->mm.data[0] &= ~0x3f; /* Reset the volume bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) dbri->mm.data[1] &= ~0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) dbri->mm.data[0] |= (DBRI_MAX_VOLUME - left_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) dbri->mm.data[1] |= (DBRI_MAX_VOLUME - right_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /* Now set the recording gain. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) info = &dbri->stream_info[DBRI_REC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) left_gain = info->left_gain & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) right_gain = info->right_gain & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) dbri->mm.data[2] |= CS4215_LG(left_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) dbri->mm.data[3] |= CS4215_RG(right_gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) xmit_fixed(dbri, 20, *(int *)dbri->mm.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) * Set the CS4215 to data mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) static void cs4215_open(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) int data_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) dprintk(D_MM, "cs4215_open: %d channels, %d bits\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) dbri->mm.channels, dbri->mm.precision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) /* Temporarily mute outputs, and wait 1/8000 sec (125 us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) * to make sure this takes. This avoids clicking noises.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) cs4215_setdata(dbri, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) udelay(125);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) * Data mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * Pipe 4: Send timeslots 1-4 (audio data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) * Pipe 20: Send timeslots 5-8 (part of ctrl data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) * Pipe 6: Receive timeslots 1-4 (audio data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * interrupt, and the rest of the data (slot 5 and 8) is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) * not relevant for us (only for doublechecking).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) * Just like in control mode, the time slots are all offset by eight
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) * bits. The CS4215, it seems, observes TSIN (the delayed signal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) * even if it's the CHI master. Don't ask me...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) tmp = sbus_readl(dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) tmp &= ~(D_C); /* Disable CHI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) sbus_writel(tmp, dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* Switch CS4215 to data mode - set PIO3 to 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) sbus_writel(D_ENPIO | D_PIO1 | D_PIO3 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) (dbri->mm.onboard ? D_PIO0 : D_PIO2), dbri->regs + REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) reset_chi(dbri, CHIslave, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) /* Note: this next doesn't work for 8-bit stereo, because the two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) * channels would be on timeslots 1 and 3, with 2 and 4 idle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) * (See CS4215 datasheet Fig 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) * DBRI non-contiguous mode would be required to make this work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) data_width = dbri->mm.channels * dbri->mm.precision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) link_time_slot(dbri, 4, 16, 16, data_width, dbri->mm.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) link_time_slot(dbri, 20, 4, 16, 32, dbri->mm.offset + 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) link_time_slot(dbri, 6, 16, 16, data_width, dbri->mm.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) link_time_slot(dbri, 21, 6, 16, 16, dbri->mm.offset + 40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) /* FIXME: enable CHI after _setdata? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) tmp = sbus_readl(dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) tmp |= D_C; /* Enable CHI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) sbus_writel(tmp, dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) cs4215_setdata(dbri, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) * Send the control information (i.e. audio format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) static int cs4215_setctrl(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) int i, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) /* FIXME - let the CPU do something useful during these delays */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) /* Temporarily mute outputs, and wait 1/8000 sec (125 us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) * to make sure this takes. This avoids clicking noises.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) cs4215_setdata(dbri, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) udelay(125);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) * Enable Control mode: Set DBRI's PIO3 (4215's D/~C) to 0, then wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) * 12 cycles <= 12/(5512.5*64) sec = 34.01 usec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) val = D_ENPIO | D_PIO1 | (dbri->mm.onboard ? D_PIO0 : D_PIO2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) sbus_writel(val, dbri->regs + REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) dprintk(D_MM, "cs4215_setctrl: reg2=0x%x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) udelay(34);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) /* In Control mode, the CS4215 is a slave device, so the DBRI must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * operate as CHI master, supplying clocking and frame synchronization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * In Data mode, however, the CS4215 must be CHI master to insure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * that its data stream is synchronous with its codec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * The upshot of all this? We start by putting the DBRI into master
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) * mode, program the CS4215 in Control mode, then switch the CS4215
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * into Data mode and put the DBRI into slave mode. Various timing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) * requirements must be observed along the way.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) * Oh, and one more thing, on a SPARCStation 20 (and maybe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) * others?), the addressing of the CS4215's time slots is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) * offset by eight bits, so we add eight to all the "cycle"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * values in the Define Time Slot (DTS) commands. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) * done in hardware by a TI 248 that delays the DBRI->4215
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) * frame sync signal by eight clock cycles. Anybody know why?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) tmp = sbus_readl(dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) tmp &= ~D_C; /* Disable CHI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) sbus_writel(tmp, dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) reset_chi(dbri, CHImaster, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) * Control mode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * Pipe 18: Receive timeslot 1 (clb).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) * Pipe 19: Receive timeslot 7 (version).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) link_time_slot(dbri, 18, 16, 16, 8, dbri->mm.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) link_time_slot(dbri, 19, 18, 16, 8, dbri->mm.offset + 48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) /* Wait for the chip to echo back CLB (Control Latch Bit) as zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) dbri->mm.ctrl[0] &= ~CS4215_CLB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) tmp = sbus_readl(dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) tmp |= D_C; /* Enable CHI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) sbus_writel(tmp, dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) msleep_interruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) dprintk(D_MM, "CS4215 didn't respond to CLB (0x%02x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) dbri->mm.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) /* Disable changes to our copy of the version number, as we are about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) * to leave control mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) recv_fixed(dbri, 19, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) /* Terminate CS4215 control mode - data sheet says
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) * "Set CLB=1 and send two more frames of valid control info"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) dbri->mm.ctrl[0] |= CS4215_CLB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) /* Two frames of control info @ 8kHz frame rate = 250 us delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) udelay(250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) cs4215_setdata(dbri, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * Setup the codec with the sampling rate, audio format and number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) * channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) * As part of the process we resend the settings for the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * timeslots as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) static int cs4215_prepare(struct snd_dbri *dbri, unsigned int rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) snd_pcm_format_t format, unsigned int channels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) int freq_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /* Lookup index for this rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) for (freq_idx = 0; CS4215_FREQ[freq_idx].freq != 0; freq_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) if (CS4215_FREQ[freq_idx].freq == rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) if (CS4215_FREQ[freq_idx].freq != rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) printk(KERN_WARNING "DBRI: Unsupported rate %d Hz\n", rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) switch (format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) case SNDRV_PCM_FORMAT_MU_LAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) dbri->mm.ctrl[1] = CS4215_DFR_ULAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) dbri->mm.precision = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) case SNDRV_PCM_FORMAT_A_LAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) dbri->mm.ctrl[1] = CS4215_DFR_ALAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) dbri->mm.precision = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) case SNDRV_PCM_FORMAT_U8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) dbri->mm.ctrl[1] = CS4215_DFR_LINEAR8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) dbri->mm.precision = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) case SNDRV_PCM_FORMAT_S16_BE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) dbri->mm.ctrl[1] = CS4215_DFR_LINEAR16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) dbri->mm.precision = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) printk(KERN_WARNING "DBRI: Unsupported format %d\n", format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) /* Add rate parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) dbri->mm.ctrl[1] |= CS4215_FREQ[freq_idx].csval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) dbri->mm.ctrl[2] = CS4215_XCLK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) dbri->mm.channels = channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (channels == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) dbri->mm.ctrl[1] |= CS4215_DFR_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) ret = cs4215_setctrl(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) cs4215_open(dbri); /* set codec to data mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static int cs4215_init(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) u32 reg2 = sbus_readl(dbri->regs + REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) /* Look for the cs4215 chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (reg2 & D_PIO2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) dprintk(D_MM, "Onboard CS4215 detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) dbri->mm.onboard = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) if (reg2 & D_PIO0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) dprintk(D_MM, "Speakerbox detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) dbri->mm.onboard = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) if (reg2 & D_PIO2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) printk(KERN_INFO "DBRI: Using speakerbox / "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) "ignoring onboard mmcodec.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) sbus_writel(D_ENPIO2, dbri->regs + REG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) if (!(reg2 & (D_PIO0 | D_PIO2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) printk(KERN_ERR "DBRI: no mmcodec found.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) cs4215_setup_pipes(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) cs4215_init_data(&dbri->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) /* Enable capture of the status & version timeslots. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) recv_fixed(dbri, 18, &dbri->mm.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) recv_fixed(dbri, 19, &dbri->mm.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) dbri->mm.offset = dbri->mm.onboard ? 0 : 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) if (cs4215_setctrl(dbri) == -1 || dbri->mm.version == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) dprintk(D_MM, "CS4215 failed probe at offset %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) dbri->mm.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) dprintk(D_MM, "Found CS4215 at offset %d\n", dbri->mm.offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) *************************** DBRI interrupt handler *************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) The DBRI communicates with the CPU mainly via a circular interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) buffer. When an interrupt is signaled, the CPU walks through the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) buffer and calls dbri_process_one_interrupt() for each interrupt word.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) Complicated interrupts are handled by dedicated functions (which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) appear first in this file). Any pending interrupts can be serviced by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) calling dbri_process_interrupt_buffer(), which works even if the CPU's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) interrupts are disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) /* xmit_descs()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) * Starts transmitting the current TD's for recording/playing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) * For playback, ALSA has filled the DMA memory with new data (we hope).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) static void xmit_descs(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) struct dbri_streaminfo *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) u32 dvma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) s32 *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) int first_td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) if (dbri == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) return; /* Disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) dvma_addr = (u32)dbri->dma_dvma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) info = &dbri->stream_info[DBRI_REC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) if (info->pipe >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) first_td = dbri->pipes[info->pipe].first_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) dprintk(D_DESC, "xmit_descs rec @ TD %d\n", first_td);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) /* Stream could be closed by the time we run. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) if (first_td >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) cmd = dbri_cmdlock(dbri, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) *(cmd++) = DBRI_CMD(D_SDP, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) dbri->pipes[info->pipe].sdp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) | D_SDP_P | D_SDP_EVERY | D_SDP_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) *(cmd++) = dvma_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) dbri_dma_off(desc, first_td);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) dbri_cmdsend(dbri, cmd, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) /* Reset our admin of the pipe. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) dbri->pipes[info->pipe].desc = first_td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) info = &dbri->stream_info[DBRI_PLAY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (info->pipe >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) first_td = dbri->pipes[info->pipe].first_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) dprintk(D_DESC, "xmit_descs play @ TD %d\n", first_td);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) /* Stream could be closed by the time we run. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (first_td >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) cmd = dbri_cmdlock(dbri, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) *(cmd++) = DBRI_CMD(D_SDP, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) dbri->pipes[info->pipe].sdp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) | D_SDP_P | D_SDP_EVERY | D_SDP_C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) *(cmd++) = dvma_addr +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) dbri_dma_off(desc, first_td);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) dbri_cmdsend(dbri, cmd, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) /* Reset our admin of the pipe. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) dbri->pipes[info->pipe].desc = first_td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) /* transmission_complete_intr()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) * Called by main interrupt handler when DBRI signals transmission complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) * on a pipe (interrupt triggered by the B bit in a transmit descriptor).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) * Walks through the pipe's list of transmit buffer descriptors and marks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) * them as available. Stops when the first descriptor is found without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) * TBC (Transmit Buffer Complete) set, or we've run through them all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) * The DMA buffers are not released. They form a ring buffer and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) * they are filled by ALSA while others are transmitted by DMA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) static void transmission_complete_intr(struct snd_dbri *dbri, int pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) int td = dbri->pipes[pipe].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) while (td >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (td >= DBRI_NO_DESCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) status = DBRI_TD_STATUS(dbri->dma->desc[td].word4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) if (!(status & DBRI_TD_TBC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) dprintk(D_INT, "TD %d, status 0x%02x\n", td, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) info->offset += DBRI_RD_CNT(dbri->dma->desc[td].word1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) td = dbri->next_desc[td];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) dbri->pipes[pipe].desc = td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) /* Notify ALSA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) spin_unlock(&dbri->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) snd_pcm_period_elapsed(info->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) spin_lock(&dbri->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) static void reception_complete_intr(struct snd_dbri *dbri, int pipe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) struct dbri_streaminfo *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) int rd = dbri->pipes[pipe].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) s32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) if (rd < 0 || rd >= DBRI_NO_DESCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) printk(KERN_ERR "DBRI: invalid rd on pipe %d\n", pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) dbri->pipes[pipe].desc = dbri->next_desc[rd];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) status = dbri->dma->desc[rd].word1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) info = &dbri->stream_info[DBRI_REC];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) info->offset += DBRI_RD_CNT(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) /* FIXME: Check status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) dprintk(D_INT, "Recv RD %d, status 0x%02x, len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) /* Notify ALSA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) spin_unlock(&dbri->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) snd_pcm_period_elapsed(info->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) spin_lock(&dbri->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) static void dbri_process_one_interrupt(struct snd_dbri *dbri, int x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) int val = D_INTR_GETVAL(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) int channel = D_INTR_GETCHAN(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) int command = D_INTR_GETCMD(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) int code = D_INTR_GETCODE(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) #ifdef DBRI_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) int rval = D_INTR_GETRVAL(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) if (channel == D_INTR_CMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) dprintk(D_CMD, "INTR: Command: %-5s Value:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) cmds[command], val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) dprintk(D_INT, "INTR: Chan:%d Code:%d Val:%#x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) channel, code, rval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) case D_INTR_CMDI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (command != D_WAIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) printk(KERN_ERR "DBRI: Command read interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) case D_INTR_BRDY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) reception_complete_intr(dbri, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) case D_INTR_XCMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) case D_INTR_MINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) transmission_complete_intr(dbri, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) case D_INTR_UNDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) /* UNDR - Transmission underrun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) * resend SDP command with clear pipe bit (C) set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) /* FIXME: do something useful in case of underrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) printk(KERN_ERR "DBRI: Underrun error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) s32 *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) int pipe = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) int td = dbri->pipes[pipe].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) dbri->dma->desc[td].word4 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) cmd = dbri_cmdlock(dbri, NoGetLock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) *(cmd++) = DBRI_CMD(D_SDP, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) dbri->pipes[pipe].sdp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) | D_SDP_P | D_SDP_C | D_SDP_2SAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) dbri_cmdsend(dbri, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) case D_INTR_FXDT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) /* FXDT - Fixed data change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (dbri->pipes[channel].sdp & D_SDP_MSB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) val = reverse_bytes(val, dbri->pipes[channel].length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) if (dbri->pipes[channel].recv_fixed_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) *(dbri->pipes[channel].recv_fixed_ptr) = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) if (channel != D_INTR_CMD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) printk(KERN_WARNING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) "DBRI: Ignored Interrupt: %d (0x%x)\n", code, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) /* dbri_process_interrupt_buffer advances through the DBRI's interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) * buffer until it finds a zero word (indicating nothing more to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) * right now). Non-zero words require processing and are handed off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) * to dbri_process_one_interrupt AFTER advancing the pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) static void dbri_process_interrupt_buffer(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) s32 x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) while ((x = dbri->dma->intr[dbri->dbri_irqp]) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) dbri->dma->intr[dbri->dbri_irqp] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) dbri->dbri_irqp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (dbri->dbri_irqp == DBRI_INT_BLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) dbri->dbri_irqp = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) dbri_process_one_interrupt(dbri, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) struct snd_dbri *dbri = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) static int errcnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) int x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) if (dbri == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) spin_lock(&dbri->lock);
^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) * Read it, so the interrupt goes away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) x = sbus_readl(dbri->regs + REG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) if (x & (D_MRR | D_MLE | D_LBG | D_MBE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) u32 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) if (x & D_MRR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) "DBRI: Multiple Error Ack on SBus reg1=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (x & D_MLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) "DBRI: Multiple Late Error on SBus reg1=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) if (x & D_LBG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) "DBRI: Lost Bus Grant on SBus reg1=0x%x\n", x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) if (x & D_MBE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) "DBRI: Burst Error on SBus reg1=0x%x\n", x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) /* Some of these SBus errors cause the chip's SBus circuitry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) * to be disabled, so just re-enable and try to keep going.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) * The only one I've seen is MRR, which will be triggered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) * if you let a transmit pipe underrun, then try to CDP it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) * If these things persist, we reset the chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) if ((++errcnt) % 10 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) dprintk(D_INT, "Interrupt errors exceeded.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) dbri_reset(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) tmp = sbus_readl(dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) tmp &= ~(D_D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) sbus_writel(tmp, dbri->regs + REG0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) dbri_process_interrupt_buffer(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) spin_unlock(&dbri->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) /****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) PCM Interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) static const struct snd_pcm_hardware snd_dbri_pcm_hw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) .info = SNDRV_PCM_INFO_MMAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) SNDRV_PCM_INFO_MMAP_VALID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) SNDRV_PCM_INFO_BATCH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) .formats = SNDRV_PCM_FMTBIT_MU_LAW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) SNDRV_PCM_FMTBIT_A_LAW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) SNDRV_PCM_FMTBIT_U8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) SNDRV_PCM_FMTBIT_S16_BE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_5512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) .rate_min = 5512,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) .rate_max = 48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) .buffer_bytes_max = 64 * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) .period_bytes_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) .period_bytes_max = DBRI_TD_MAXCNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) .periods_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) .periods_max = 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) static int snd_hw_rule_format(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) struct snd_interval *c = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) struct snd_mask fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) snd_mask_any(&fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) if (c->min > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_BE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) return snd_mask_refine(f, &fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) static int snd_hw_rule_channels(struct snd_pcm_hw_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) struct snd_pcm_hw_rule *rule)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) struct snd_interval *c = hw_param_interval(params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) SNDRV_PCM_HW_PARAM_CHANNELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) struct snd_interval ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) snd_interval_any(&ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) if (!(f->bits[0] & SNDRV_PCM_FMTBIT_S16_BE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) ch.min = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) ch.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) ch.integer = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) return snd_interval_refine(c, &ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) static int snd_dbri_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) dprintk(D_USR, "open audio output.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) runtime->hw = snd_dbri_pcm_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) spin_lock_irqsave(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) info->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) info->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) info->dvma_buffer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) info->pipe = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) spin_unlock_irqrestore(&dbri->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) snd_hw_rule_format, NULL, SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) snd_hw_rule_channels, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) SNDRV_PCM_HW_PARAM_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) cs4215_open(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) static int snd_dbri_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) dprintk(D_USR, "close audio output.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) info->substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) info->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) static int snd_dbri_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) int direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) /* set sampling rate, audio format and number of channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) ret = cs4215_prepare(dbri, params_rate(hw_params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) params_format(hw_params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) params_channels(hw_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) /* hw_params can get called multiple times. Only map the DMA once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) if (info->dvma_buffer == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) if (DBRI_STREAMNO(substream) == DBRI_PLAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) direction = DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) info->dvma_buffer =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) dma_map_single(&dbri->op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) runtime->dma_area,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) params_buffer_bytes(hw_params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) direction = params_buffer_bytes(hw_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) dprintk(D_USR, "hw_params: %d bytes, dvma=%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) direction, info->dvma_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) static int snd_dbri_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) int direction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) dprintk(D_USR, "hw_free.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) /* hw_free can get called multiple times. Only unmap the DMA once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) if (info->dvma_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) if (DBRI_STREAMNO(substream) == DBRI_PLAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) direction = DMA_TO_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) direction = DMA_FROM_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) dma_unmap_single(&dbri->op->dev, info->dvma_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) substream->runtime->buffer_size, direction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) info->dvma_buffer = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) if (info->pipe != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) reset_pipe(dbri, info->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) info->pipe = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) static int snd_dbri_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) info->size = snd_pcm_lib_buffer_bytes(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) if (DBRI_STREAMNO(substream) == DBRI_PLAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) info->pipe = 4; /* Send pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) info->pipe = 6; /* Receive pipe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) spin_lock_irq(&dbri->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) info->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) /* Setup the all the transmit/receive descriptors to cover the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) * whole DMA buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) ret = setup_descs(dbri, DBRI_STREAMNO(substream),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) snd_pcm_lib_period_bytes(substream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) spin_unlock_irq(&dbri->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) dprintk(D_USR, "prepare audio output. %d bytes\n", info->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) static int snd_dbri_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) dprintk(D_USR, "start audio, period is %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) (int)snd_pcm_lib_period_bytes(substream));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) /* Re-submit the TDs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) xmit_descs(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) dprintk(D_USR, "stop audio.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) reset_pipe(dbri, info->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) static snd_pcm_uframes_t snd_dbri_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) struct dbri_streaminfo *info = DBRI_STREAM(dbri, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) snd_pcm_uframes_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) ret = bytes_to_frames(substream->runtime, info->offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) % substream->runtime->buffer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) dprintk(D_USR, "I/O pointer: %ld frames of %ld.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) ret, substream->runtime->buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) static const struct snd_pcm_ops snd_dbri_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) .open = snd_dbri_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) .close = snd_dbri_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) .hw_params = snd_dbri_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) .hw_free = snd_dbri_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) .prepare = snd_dbri_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) .trigger = snd_dbri_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) .pointer = snd_dbri_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) static int snd_dbri_pcm(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) if ((err = snd_pcm_new(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) /* ID */ "sun_dbri",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) /* device */ 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) /* playback count */ 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) /* capture count */ 1, &pcm)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_dbri_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_dbri_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) pcm->private_data = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) pcm->info_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) strcpy(pcm->name, card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) NULL, 64 * 1024, 64 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) /*****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) Mixer interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static int snd_cs4215_info_volume(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) uinfo->count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) if (kcontrol->private_value == DBRI_PLAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) uinfo->value.integer.max = DBRI_MAX_VOLUME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) uinfo->value.integer.max = DBRI_MAX_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) static int snd_cs4215_get_volume(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) struct dbri_streaminfo *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) if (snd_BUG_ON(!dbri))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) info = &dbri->stream_info[kcontrol->private_value];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) ucontrol->value.integer.value[0] = info->left_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) ucontrol->value.integer.value[1] = info->right_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) struct dbri_streaminfo *info =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) &dbri->stream_info[kcontrol->private_value];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) unsigned int vol[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) vol[0] = ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) vol[1] = ucontrol->value.integer.value[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) if (kcontrol->private_value == DBRI_PLAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) if (vol[0] > DBRI_MAX_VOLUME || vol[1] > DBRI_MAX_VOLUME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) if (vol[0] > DBRI_MAX_GAIN || vol[1] > DBRI_MAX_GAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) if (info->left_gain != vol[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) info->left_gain = vol[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) if (info->right_gain != vol[1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) info->right_gain = vol[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) /* First mute outputs, and wait 1/8000 sec (125 us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) * to make sure this takes. This avoids clicking noises.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) cs4215_setdata(dbri, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) udelay(125);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) cs4215_setdata(dbri, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) static int snd_cs4215_info_single(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) uinfo->type = (mask == 1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) uinfo->value.integer.max = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) static int snd_cs4215_get_single(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) int elem = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) int invert = (kcontrol->private_value >> 24) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) if (snd_BUG_ON(!dbri))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) if (elem < 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) (dbri->mm.data[elem] >> shift) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) (dbri->mm.ctrl[elem - 4] >> shift) & mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) if (invert == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) ucontrol->value.integer.value[0] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) mask - ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) static int snd_cs4215_put_single(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) struct snd_dbri *dbri = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) int elem = kcontrol->private_value & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) int shift = (kcontrol->private_value >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) int mask = (kcontrol->private_value >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) int invert = (kcontrol->private_value >> 24) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) int changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) if (snd_BUG_ON(!dbri))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) val = (ucontrol->value.integer.value[0] & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) if (invert == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) val = mask - val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) val <<= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) if (elem < 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) dbri->mm.data[elem] = (dbri->mm.data[elem] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) ~(mask << shift)) | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) changed = (val != dbri->mm.data[elem]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) dbri->mm.ctrl[elem - 4] = (dbri->mm.ctrl[elem - 4] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) ~(mask << shift)) | val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) changed = (val != dbri->mm.ctrl[elem - 4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) dprintk(D_GEN, "put_single: mask=0x%x, changed=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) "mixer-value=%ld, mm-value=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) mask, changed, ucontrol->value.integer.value[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) dbri->mm.data[elem & 3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) if (changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) /* First mute outputs, and wait 1/8000 sec (125 us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) * to make sure this takes. This avoids clicking noises.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) cs4215_setdata(dbri, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) udelay(125);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) cs4215_setdata(dbri, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) /* Entries 0-3 map to the 4 data timeslots, entries 4-7 map to the 4 control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) timeslots. Shift is the bit offset in the timeslot, mask defines the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) number of bits. invert is a boolean for use with attenuation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) #define CS4215_SINGLE(xname, entry, shift, mask, invert) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) .info = snd_cs4215_info_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) .get = snd_cs4215_get_single, .put = snd_cs4215_put_single, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) .private_value = (entry) | ((shift) << 8) | ((mask) << 16) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) ((invert) << 24) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) static const struct snd_kcontrol_new dbri_controls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) .name = "Playback Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) .info = snd_cs4215_info_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) .get = snd_cs4215_get_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) .put = snd_cs4215_put_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) .private_value = DBRI_PLAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) CS4215_SINGLE("Headphone switch", 0, 7, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) CS4215_SINGLE("Line out switch", 0, 6, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) CS4215_SINGLE("Speaker switch", 1, 6, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) .name = "Capture Volume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) .info = snd_cs4215_info_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) .get = snd_cs4215_get_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) .put = snd_cs4215_put_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) .private_value = DBRI_REC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) /* FIXME: mic/line switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) CS4215_SINGLE("Line in switch", 2, 4, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) CS4215_SINGLE("High Pass Filter switch", 5, 7, 1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) CS4215_SINGLE("Monitor Volume", 3, 4, 0xf, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) CS4215_SINGLE("Mic boost", 4, 4, 1, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) static int snd_dbri_mixer(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) int idx, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) struct snd_dbri *dbri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) if (snd_BUG_ON(!card || !card->private_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) dbri = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) strcpy(card->mixername, card->shortname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) err = snd_ctl_add(card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) snd_ctl_new1(&dbri_controls[idx], dbri));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) for (idx = DBRI_REC; idx < DBRI_NO_STREAMS; idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) dbri->stream_info[idx].left_gain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) dbri->stream_info[idx].right_gain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) /****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) /proc interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) ****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) static void dbri_regs_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) struct snd_dbri *dbri = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) snd_iprintf(buffer, "REG0: 0x%x\n", sbus_readl(dbri->regs + REG0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) snd_iprintf(buffer, "REG2: 0x%x\n", sbus_readl(dbri->regs + REG2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) snd_iprintf(buffer, "REG8: 0x%x\n", sbus_readl(dbri->regs + REG8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) snd_iprintf(buffer, "REG9: 0x%x\n", sbus_readl(dbri->regs + REG9));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) #ifdef DBRI_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) static void dbri_debug_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) struct snd_dbri *dbri = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) int pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) snd_iprintf(buffer, "debug=%d\n", dbri_debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) for (pipe = 0; pipe < 32; pipe++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) if (pipe_active(dbri, pipe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) struct dbri_pipe *pptr = &dbri->pipes[pipe];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) snd_iprintf(buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) "Pipe %d: %s SDP=0x%x desc=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) "len=%d next %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) (pptr->sdp & D_SDP_TO_SER) ? "output" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) "input",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) pptr->sdp, pptr->desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) pptr->length, pptr->nextpipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) static void snd_dbri_proc(struct snd_card *card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) struct snd_dbri *dbri = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) snd_card_ro_proc_new(card, "regs", dbri, dbri_regs_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) #ifdef DBRI_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) snd_card_ro_proc_new(card, "debug", dbri, dbri_debug_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) **************************** Initialization ********************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) ****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) static void snd_dbri_free(struct snd_dbri *dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) static int snd_dbri_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) struct platform_device *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) int irq, int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) struct snd_dbri *dbri = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) spin_lock_init(&dbri->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) dbri->op = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) dbri->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) dbri->dma = dma_alloc_coherent(&op->dev, sizeof(struct dbri_dma),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) &dbri->dma_dvma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) if (!dbri->dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) dprintk(D_GEN, "DMA Cmd Block 0x%p (%pad)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) dbri->dma, dbri->dma_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) /* Map the registers into memory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) dbri->regs_size = resource_size(&op->resource[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) dbri->regs = of_ioremap(&op->resource[0], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) dbri->regs_size, "DBRI Registers");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) if (!dbri->regs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) printk(KERN_ERR "DBRI: could not allocate registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) (void *)dbri->dma, dbri->dma_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) err = request_irq(dbri->irq, snd_dbri_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) "DBRI audio", dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) of_iounmap(&op->resource[0], dbri->regs, dbri->regs_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) (void *)dbri->dma, dbri->dma_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) /* Do low level initialization of the DBRI and CS4215 chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) dbri_initialize(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) err = cs4215_init(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) snd_dbri_free(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) static void snd_dbri_free(struct snd_dbri *dbri)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) dprintk(D_GEN, "snd_dbri_free\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) dbri_reset(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) if (dbri->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) free_irq(dbri->irq, dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) if (dbri->regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) of_iounmap(&dbri->op->resource[0], dbri->regs, dbri->regs_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) if (dbri->dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) dma_free_coherent(&dbri->op->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) sizeof(struct dbri_dma),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) (void *)dbri->dma, dbri->dma_dvma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) static int dbri_probe(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) struct snd_dbri *dbri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) struct resource *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) static int dev = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) if (dev >= SNDRV_CARDS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) if (!enable[dev]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) irq = op->archdata.irqs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) if (irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) err = snd_card_new(&op->dev, index[dev], id[dev], THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) sizeof(struct snd_dbri), &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) strcpy(card->driver, "DBRI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) strcpy(card->shortname, "Sun DBRI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) rp = &op->resource[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) card->shortname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) rp->flags & 0xffL, (unsigned long long)rp->start, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) err = snd_dbri_create(card, op, irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) dbri = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) err = snd_dbri_pcm(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) goto _err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) err = snd_dbri_mixer(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) goto _err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) /* /proc file handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) snd_dbri_proc(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) dev_set_drvdata(&op->dev, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) err = snd_card_register(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) goto _err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) dev, dbri->regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) dbri->irq, op->dev.of_node->name[9], dbri->mm.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) dev++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) _err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) snd_dbri_free(dbri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) static int dbri_remove(struct platform_device *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) struct snd_card *card = dev_get_drvdata(&op->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) snd_dbri_free(card->private_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) static const struct of_device_id dbri_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) .name = "SUNW,DBRIe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) .name = "SUNW,DBRIf",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) MODULE_DEVICE_TABLE(of, dbri_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) static struct platform_driver dbri_sbus_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) .name = "dbri",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) .of_match_table = dbri_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) .probe = dbri_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) .remove = dbri_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) module_platform_driver(dbri_sbus_driver);