Lines Matching +full:enable +full:- +full:cdm +full:- +full:check

1 // SPDX-License-Identifier: GPL-2.0-only
9 * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de)
15 * - DBRI: AT&T T5900FX Dual Basic Rates ISDN Interface. It is a 32 channel
20 * - "STP 4000SBus Dual Basic Rate ISDN (DBRI) Transceiver" from
22 * - Data sheet of the T7903, a newer but very similar ISA bus equivalent
25 * - https://www.freesoft.org/Linux/DBRI/
26 * - MMCODEC: Crystal Semiconductor CS4215 16 bit Multimedia Audio Codec
31 * memory and a serial device (long pipes, no. 0-15) or between two serial
32 * devices (short pipes, no. 16-31), or simply send a fixed data to a serial
34 * A timeslot defines the bit-offset and no. of bits read from a serial device.
44 * the same CHI bus, so I thought perhaps it is possible to use the on-board
45 * & the speakerbox codec simultaneously, giving 2 (not very independent :-)
53 * dbri_* DBRI high-level stuff
54 * other DBRI low-level stuff
61 #include <linux/dma-mapping.h>
80 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
82 /* Enable this card */
83 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; variable
89 module_param_array(enable, bool, NULL, 0444);
90 MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard.");
108 "SSP", "CHI", "NT", "TE", "CDEC", "TEST", "CDM", "RESRV"
127 __u8 data[4]; /* Data mode: Time slots 5-8 */
128 __u8 ctrl[4]; /* Ctrl mode: Time slots 1-4 */
183 #define CS4215_XEN (1<<0) /* 0: Enable serial output */
195 #define CS4215_DAD (1<<0) /* 0:Digital-Dig loop, 1:Dig-Analog-Dig loop */
196 #define CS4215_ENL (1<<1) /* Enable Loopback Testing */
211 /* Time Slot 1-2: Left Channel Data, 2-3: Right Channel Data */
214 #define CS4215_LO(v) v /* Left Output Attenuation 0x3f: -94.5 dB */
215 #define CS4215_LE (1<<6) /* Line Out Enable */
216 #define CS4215_HE (1<<7) /* Headphone Enable */
219 #define CS4215_RO(v) v /* Right Output Attenuation 0x3f: -94.5 dB */
220 #define CS4215_SE (1<<6) /* Speaker Enable */
250 #define DBRI_MAX_PIPE (DBRI_NO_PIPES - 1)
276 (&(((struct dbri_dma *)0)->member[elem])))
313 int next_desc[DBRI_NO_DESCS]; /* Index of next desc, or -1 */
327 /* DBRI Reg0 - Status Control Register - defines. (Page 17) */
329 #define D_G (1<<14) /* Allow 4-Word SBus Burst */
330 #define D_S (1<<13) /* Allow 16-Word SBus Burst */
331 #define D_E (1<<12) /* Allow 8-Word SBus Burst */
336 #define D_F (1<<3) /* Force Sanity Timer Time-Out */
341 /* DBRI Reg1 - Mode and Interrupt Register - defines. (Page 18) */
350 /* DBRI Reg2 - Parallel IO Register - defines. (Page 18) */
351 #define D_ENPIO3 (1<<7) /* Enable Pin 3 */
352 #define D_ENPIO2 (1<<6) /* Enable Pin 2 */
353 #define D_ENPIO1 (1<<5) /* Enable Pin 1 */
354 #define D_ENPIO0 (1<<4) /* Enable Pin 0 */
355 #define D_ENPIO (0xf0) /* Enable all the pins */
379 #define D_PIPE(v) ((v)<<0) /* Pipe No.: 0-15 long, 16-21 short */
386 #define D_SDP_EOL (1<<17) /* EOL interrupt enable */
387 #define D_SDP_IDLE (1<<16) /* HDLC idle interrupt enable */
406 #define D_DTS_VI (1<<17) /* Valid Input Time-Slot Descriptor */
407 #define D_DTS_VO (1<<16) /* Valid Output Time-Slot Descriptor */
422 #define D_TS_NEXT(v) ((v)<<0) /* Pipe no.: 0-15 long, 16-21 short */
428 #define D_CHI_OD (1<<13) /* Open Drain Enable */
437 #define D_NT_IRM_EN (1<<14) /* Interrupt Report & Mask: Enable */
443 #define D_NT_MFE (1<<8) /* Multiframe Enable */
459 #define D_TEST_SER 0x7 /* Serial-Controller test */
462 #define D_TEST_RAMBIST 0xa /* RAM Built-In Self Test */
463 #define D_TEST_MCBIST 0xb /* Microcontroller Built-In Self Test */
471 #define D_CDM_XEN (1 << 1) /* Transmit Highway Enable */
472 #define D_CDM_REN (1 << 0) /* Receive Highway Enable */
485 #define D_INTR_COLL 11 /* Unrecoverable D-Channel collision */
548 #define DBRI_TD_MAXCNT ((1 << 13) - 4)
566 (substream->stream == \
571 &dbri->stream_info[DBRI_STREAMNO(substream)]
628 dbri->dma->cmd buffer. After this, the commands can be written to
644 spin_lock_irqsave(&dbri->lock, flags); in dbri_cmdwait()
645 while ((--maxloops) > 0 && (sbus_readl(dbri->regs + REG0) & D_P)) { in dbri_cmdwait()
646 spin_unlock_irqrestore(&dbri->lock, flags); in dbri_cmdwait()
648 spin_lock_irqsave(&dbri->lock, flags); in dbri_cmdwait()
650 spin_unlock_irqrestore(&dbri->lock, flags); in dbri_cmdwait()
656 MAXLOOPS - maxloops - 1); in dbri_cmdwait()
664 u32 dvma_addr = (u32)dbri->dma_dvma; in dbri_cmdlock()
668 spin_lock(&dbri->cmdlock); in dbri_cmdlock()
669 if (dbri->cmdptr - dbri->dma->cmd + len < DBRI_NO_CMDS - 2) in dbri_cmdlock()
670 return dbri->cmdptr + 2; in dbri_cmdlock()
671 else if (len < sbus_readl(dbri->regs + REG8) - dvma_addr) in dbri_cmdlock()
672 return dbri->dma->cmd; in dbri_cmdlock()
689 u32 dvma_addr = (u32)dbri->dma_dvma; in dbri_cmdsend()
699 addr = dvma_addr + (cmd - len - dbri->dma->cmd) * sizeof(s32); in dbri_cmdsend()
700 *(dbri->cmdptr+1) = addr; in dbri_cmdsend()
701 *(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0); in dbri_cmdsend()
704 if (cmd > dbri->cmdptr) { in dbri_cmdsend()
707 for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++) in dbri_cmdsend()
711 s32 *ptr = dbri->cmdptr; in dbri_cmdsend()
716 for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++) in dbri_cmdsend()
723 tmp = sbus_readl(dbri->regs + REG0); in dbri_cmdsend()
725 sbus_writel(tmp, dbri->regs + REG0); in dbri_cmdsend()
727 dbri->cmdptr = cmd; in dbri_cmdsend()
728 spin_unlock(&dbri->cmdlock); in dbri_cmdsend()
738 sbus_readl(dbri->regs + REG0), in dbri_reset()
739 sbus_readl(dbri->regs + REG2), in dbri_reset()
740 sbus_readl(dbri->regs + REG8), sbus_readl(dbri->regs + REG9)); in dbri_reset()
742 sbus_writel(D_R, dbri->regs + REG0); /* Soft Reset */ in dbri_reset()
743 for (i = 0; (sbus_readl(dbri->regs + REG0) & D_R) && i < 64; i++) in dbri_reset()
746 /* A brute approach - DBRI falls back to working burst size by itself in dbri_reset()
748 tmp = sbus_readl(dbri->regs + REG0); in dbri_reset()
751 sbus_writel(tmp, dbri->regs + REG0); in dbri_reset()
757 u32 dvma_addr = (u32)dbri->dma_dvma; in dbri_initialize()
763 spin_lock_irqsave(&dbri->lock, flags); in dbri_initialize()
769 dbri->pipes[n].desc = dbri->pipes[n].first_desc = -1; in dbri_initialize()
771 spin_lock_init(&dbri->cmdlock); in dbri_initialize()
776 dbri->dma->intr[0] = dma_addr; in dbri_initialize()
777 dbri->dbri_irqp = 1; in dbri_initialize()
781 spin_lock(&dbri->cmdlock); in dbri_initialize()
782 cmd = dbri->cmdptr = dbri->dma->cmd; in dbri_initialize()
786 dbri->cmdptr = cmd; in dbri_initialize()
790 sbus_writel(dma_addr, dbri->regs + REG8); in dbri_initialize()
791 spin_unlock(&dbri->cmdlock); in dbri_initialize()
793 spin_unlock_irqrestore(&dbri->lock, flags); in dbri_initialize()
813 return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1)); in pipe_active()
818 * Called on an in-use pipe to clear anything being transmitted or received
833 sdp = dbri->pipes[pipe].sdp; in reset_pipe()
846 desc = dbri->pipes[pipe].first_desc; in reset_pipe()
849 dbri->dma->desc[desc].ba = 0; in reset_pipe()
850 dbri->dma->desc[desc].nda = 0; in reset_pipe()
851 desc = dbri->next_desc[desc]; in reset_pipe()
852 } while (desc != -1 && desc != dbri->pipes[pipe].first_desc); in reset_pipe()
854 dbri->pipes[pipe].desc = -1; in reset_pipe()
855 dbri->pipes[pipe].first_desc = -1; in reset_pipe()
882 dbri->pipes[pipe].sdp = sdp; in setup_pipe()
883 dbri->pipes[pipe].desc = -1; in setup_pipe()
884 dbri->pipes[pipe].first_desc = -1; in setup_pipe()
907 if (dbri->pipes[pipe].sdp == 0 in link_time_slot()
908 || dbri->pipes[prevpipe].sdp == 0 in link_time_slot()
909 || dbri->pipes[nextpipe].sdp == 0) { in link_time_slot()
915 dbri->pipes[prevpipe].nextpipe = pipe; in link_time_slot()
916 dbri->pipes[pipe].nextpipe = nextpipe; in link_time_slot()
917 dbri->pipes[pipe].length = length; in link_time_slot()
921 if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { in link_time_slot()
925 * - DBRI data sheet, page 11 in link_time_slot()
928 cycle = dbri->chi_bpf; in link_time_slot()
987 * Transmit/receive data on a "fixed" pipe - i.e, one whose contents are not
991 * Only short pipes (numbers 16-31) can be used in fixed data mode.
993 * These function operate on a 32-bit field, no matter how large
995 * ordering and alignment. An 8-bit time slot will always end up
996 * in the low-order 8 bits, filled either MSB-first or LSB-first,
1011 if (D_SDP_MODE(dbri->pipes[pipe].sdp) == 0) { in xmit_fixed()
1017 if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { in xmit_fixed()
1018 printk(KERN_ERR "DBRI: xmit_fixed: Non-fixed pipe %d\n", pipe); in xmit_fixed()
1022 if (!(dbri->pipes[pipe].sdp & D_SDP_TO_SER)) { in xmit_fixed()
1030 if (dbri->pipes[pipe].sdp & D_SDP_MSB) in xmit_fixed()
1031 data = reverse_bytes(data, dbri->pipes[pipe].length); in xmit_fixed()
1039 spin_lock_irqsave(&dbri->lock, flags); in xmit_fixed()
1041 spin_unlock_irqrestore(&dbri->lock, flags); in xmit_fixed()
1054 if (D_SDP_MODE(dbri->pipes[pipe].sdp) != D_SDP_FIXED) { in recv_fixed()
1056 "non-fixed pipe %d\n", pipe); in recv_fixed()
1060 if (dbri->pipes[pipe].sdp & D_SDP_TO_SER) { in recv_fixed()
1066 dbri->pipes[pipe].recv_fixed_ptr = ptr; in recv_fixed()
1071 * Setup transmit/receive data on a "long" pipe - i.e, one associated
1074 * Only pipe numbers 0-15 can be used in this mode.
1087 struct dbri_streaminfo *info = &dbri->stream_info[streamno]; in setup_descs()
1088 u32 dvma_addr = (u32)dbri->dma_dvma; in setup_descs()
1092 int first_desc = -1; in setup_descs()
1093 int last_desc = -1; in setup_descs()
1095 if (info->pipe < 0 || info->pipe > 15) { in setup_descs()
1097 return -2; in setup_descs()
1100 if (dbri->pipes[info->pipe].sdp == 0) { in setup_descs()
1102 info->pipe); in setup_descs()
1103 return -2; in setup_descs()
1106 dvma_buffer = info->dvma_buffer; in setup_descs()
1107 len = info->size; in setup_descs()
1110 if (!(dbri->pipes[info->pipe].sdp & D_SDP_TO_SER)) { in setup_descs()
1112 "Called on receive pipe %d\n", info->pipe); in setup_descs()
1113 return -2; in setup_descs()
1116 if (dbri->pipes[info->pipe].sdp & D_SDP_TO_SER) { in setup_descs()
1119 info->pipe); in setup_descs()
1120 return -2; in setup_descs()
1125 if (pipe_active(dbri, info->pipe)) { in setup_descs()
1127 "Called on active pipe %d\n", info->pipe); in setup_descs()
1128 return -2; in setup_descs()
1136 desc = dbri->pipes[info->pipe].first_desc; in setup_descs()
1139 dbri->dma->desc[desc].ba = 0; in setup_descs()
1140 dbri->dma->desc[desc].nda = 0; in setup_descs()
1141 desc = dbri->next_desc[desc]; in setup_descs()
1142 } while (desc != -1 && in setup_descs()
1143 desc != dbri->pipes[info->pipe].first_desc); in setup_descs()
1145 dbri->pipes[info->pipe].desc = -1; in setup_descs()
1146 dbri->pipes[info->pipe].first_desc = -1; in setup_descs()
1153 if (!dbri->dma->desc[desc].ba) in setup_descs()
1159 return -1; in setup_descs()
1163 mylen = DBRI_TD_MAXCNT; /* 8KB - 4 */ in setup_descs()
1170 dbri->next_desc[desc] = -1; in setup_descs()
1171 dbri->dma->desc[desc].ba = dvma_buffer; in setup_descs()
1172 dbri->dma->desc[desc].nda = 0; in setup_descs()
1175 dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); in setup_descs()
1176 dbri->dma->desc[desc].word4 = 0; in setup_descs()
1177 dbri->dma->desc[desc].word1 |= DBRI_TD_F | DBRI_TD_B; in setup_descs()
1179 dbri->dma->desc[desc].word1 = 0; in setup_descs()
1180 dbri->dma->desc[desc].word4 = in setup_descs()
1184 if (first_desc == -1) in setup_descs()
1187 dbri->next_desc[last_desc] = desc; in setup_descs()
1188 dbri->dma->desc[last_desc].nda = in setup_descs()
1194 len -= mylen; in setup_descs()
1197 if (first_desc == -1 || last_desc == -1) { in setup_descs()
1200 return -1; in setup_descs()
1203 dbri->dma->desc[last_desc].nda = in setup_descs()
1205 dbri->next_desc[last_desc] = first_desc; in setup_descs()
1206 dbri->pipes[info->pipe].first_desc = first_desc; in setup_descs()
1207 dbri->pipes[info->pipe].desc = first_desc; in setup_descs()
1210 for (desc = first_desc; desc != -1;) { in setup_descs()
1213 dbri->dma->desc[desc].word1, in setup_descs()
1214 dbri->dma->desc[desc].ba, in setup_descs()
1215 dbri->dma->desc[desc].nda, dbri->dma->desc[desc].word4); in setup_descs()
1216 desc = dbri->next_desc[desc]; in setup_descs()
1226 ************************** DBRI - CHI interface ****************************
1229 The CHI is a four-wire (clock, frame sync, data in, data out) time-division
1258 dbri->pipes[16].sdp = 1; in reset_chi()
1259 dbri->pipes[16].nextpipe = 16; in reset_chi()
1264 /* Setup DBRI for CHI Slave - receive clock, frame sync (FS) in reset_chi()
1272 /* Setup DBRI for CHI Master - generate clock, FS in reset_chi()
1276 * FD = 1 - drive CHIFS on rising edge of CHICK in reset_chi()
1289 dbri->chi_bpf = bits_per_frame; in reset_chi()
1293 * RCE = 0 - receive on falling edge of CHICK in reset_chi()
1294 * XCE = 1 - transmit on rising edge of CHICK in reset_chi()
1295 * XEN = 1 - enable transmitter in reset_chi()
1296 * REN = 1 - enable receiver in reset_chi()
1321 spin_lock_irqsave(&dbri->lock, flags); in cs4215_setup_pipes()
1324 * Pipe 4: Send timeslots 1-4 (audio data) in cs4215_setup_pipes()
1325 * Pipe 20: Send timeslots 5-8 (part of ctrl data) in cs4215_setup_pipes()
1326 * Pipe 6: Receive timeslots 1-4 (audio data) in cs4215_setup_pipes()
1327 * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via in cs4215_setup_pipes()
1332 * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only) in cs4215_setup_pipes()
1345 spin_unlock_irqrestore(&dbri->lock, flags); in cs4215_setup_pipes()
1355 * Data Time Slot 5-8 in cs4215_init_data()
1356 * Speaker,Line and Headphone enable. Gain set to the half. in cs4215_init_data()
1359 mm->data[0] = CS4215_LO(0x20) | CS4215_HE | CS4215_LE; in cs4215_init_data()
1360 mm->data[1] = CS4215_RO(0x20) | CS4215_SE; in cs4215_init_data()
1361 mm->data[2] = CS4215_LG(0x8) | CS4215_IS | CS4215_PIO0 | CS4215_PIO1; in cs4215_init_data()
1362 mm->data[3] = CS4215_RG(0x8) | CS4215_MA(0xf); in cs4215_init_data()
1365 * Control Time Slot 1-4 in cs4215_init_data()
1368 * 2: Serial enable, CHI master, 128 bits per frame, clock 1 in cs4215_init_data()
1371 mm->ctrl[0] = CS4215_RSRVD_1 | CS4215_MLB; in cs4215_init_data()
1372 mm->ctrl[1] = CS4215_DFR_ULAW | CS4215_FREQ[0].csval; in cs4215_init_data()
1373 mm->ctrl[2] = CS4215_XCLK | CS4215_BSEL_128 | CS4215_FREQ[0].xtal; in cs4215_init_data()
1374 mm->ctrl[3] = 0; in cs4215_init_data()
1376 mm->status = 0; in cs4215_init_data()
1377 mm->version = 0xff; in cs4215_init_data()
1378 mm->precision = 8; /* For ULAW */ in cs4215_init_data()
1379 mm->channels = 1; in cs4215_init_data()
1387 dbri->mm.data[0] |= 63; in cs4215_setdata()
1388 dbri->mm.data[1] |= 63; in cs4215_setdata()
1389 dbri->mm.data[2] &= ~15; in cs4215_setdata()
1390 dbri->mm.data[3] &= ~15; in cs4215_setdata()
1393 struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY]; in cs4215_setdata()
1394 int left_gain = info->left_gain & 0x3f; in cs4215_setdata()
1395 int right_gain = info->right_gain & 0x3f; in cs4215_setdata()
1397 dbri->mm.data[0] &= ~0x3f; /* Reset the volume bits */ in cs4215_setdata()
1398 dbri->mm.data[1] &= ~0x3f; in cs4215_setdata()
1399 dbri->mm.data[0] |= (DBRI_MAX_VOLUME - left_gain); in cs4215_setdata()
1400 dbri->mm.data[1] |= (DBRI_MAX_VOLUME - right_gain); in cs4215_setdata()
1403 info = &dbri->stream_info[DBRI_REC]; in cs4215_setdata()
1404 left_gain = info->left_gain & 0xf; in cs4215_setdata()
1405 right_gain = info->right_gain & 0xf; in cs4215_setdata()
1406 dbri->mm.data[2] |= CS4215_LG(left_gain); in cs4215_setdata()
1407 dbri->mm.data[3] |= CS4215_RG(right_gain); in cs4215_setdata()
1410 xmit_fixed(dbri, 20, *(int *)dbri->mm.data); in cs4215_setdata()
1423 dbri->mm.channels, dbri->mm.precision); in cs4215_open()
1434 * Pipe 4: Send timeslots 1-4 (audio data) in cs4215_open()
1435 * Pipe 20: Send timeslots 5-8 (part of ctrl data) in cs4215_open()
1436 * Pipe 6: Receive timeslots 1-4 (audio data) in cs4215_open()
1437 * Pipe 21: Receive timeslots 6-7. We can only receive 20 bits via in cs4215_open()
1445 spin_lock_irqsave(&dbri->lock, flags); in cs4215_open()
1446 tmp = sbus_readl(dbri->regs + REG0); in cs4215_open()
1448 sbus_writel(tmp, dbri->regs + REG0); in cs4215_open()
1450 /* Switch CS4215 to data mode - set PIO3 to 1 */ in cs4215_open()
1452 (dbri->mm.onboard ? D_PIO0 : D_PIO2), dbri->regs + REG2); in cs4215_open()
1456 /* Note: this next doesn't work for 8-bit stereo, because the two in cs4215_open()
1460 * DBRI non-contiguous mode would be required to make this work. in cs4215_open()
1462 data_width = dbri->mm.channels * dbri->mm.precision; in cs4215_open()
1464 link_time_slot(dbri, 4, 16, 16, data_width, dbri->mm.offset); in cs4215_open()
1465 link_time_slot(dbri, 20, 4, 16, 32, dbri->mm.offset + 32); in cs4215_open()
1466 link_time_slot(dbri, 6, 16, 16, data_width, dbri->mm.offset); in cs4215_open()
1467 link_time_slot(dbri, 21, 6, 16, 16, dbri->mm.offset + 40); in cs4215_open()
1469 /* FIXME: enable CHI after _setdata? */ in cs4215_open()
1470 tmp = sbus_readl(dbri->regs + REG0); in cs4215_open()
1471 tmp |= D_C; /* Enable CHI */ in cs4215_open()
1472 sbus_writel(tmp, dbri->regs + REG0); in cs4215_open()
1473 spin_unlock_irqrestore(&dbri->lock, flags); in cs4215_open()
1487 /* FIXME - let the CPU do something useful during these delays */ in cs4215_setctrl()
1496 * Enable Control mode: Set DBRI's PIO3 (4215's D/~C) to 0, then wait in cs4215_setctrl()
1499 val = D_ENPIO | D_PIO1 | (dbri->mm.onboard ? D_PIO0 : D_PIO2); in cs4215_setctrl()
1500 sbus_writel(val, dbri->regs + REG2); in cs4215_setctrl()
1519 * done in hardware by a TI 248 that delays the DBRI->4215 in cs4215_setctrl()
1522 spin_lock_irqsave(&dbri->lock, flags); in cs4215_setctrl()
1523 tmp = sbus_readl(dbri->regs + REG0); in cs4215_setctrl()
1525 sbus_writel(tmp, dbri->regs + REG0); in cs4215_setctrl()
1531 * Pipe 17: Send timeslots 1-4 (slots 5-8 are read only) in cs4215_setctrl()
1536 link_time_slot(dbri, 17, 16, 16, 32, dbri->mm.offset); in cs4215_setctrl()
1537 link_time_slot(dbri, 18, 16, 16, 8, dbri->mm.offset); in cs4215_setctrl()
1538 link_time_slot(dbri, 19, 18, 16, 8, dbri->mm.offset + 48); in cs4215_setctrl()
1539 spin_unlock_irqrestore(&dbri->lock, flags); in cs4215_setctrl()
1542 dbri->mm.ctrl[0] &= ~CS4215_CLB; in cs4215_setctrl()
1543 xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl); in cs4215_setctrl()
1545 spin_lock_irqsave(&dbri->lock, flags); in cs4215_setctrl()
1546 tmp = sbus_readl(dbri->regs + REG0); in cs4215_setctrl()
1547 tmp |= D_C; /* Enable CHI */ in cs4215_setctrl()
1548 sbus_writel(tmp, dbri->regs + REG0); in cs4215_setctrl()
1549 spin_unlock_irqrestore(&dbri->lock, flags); in cs4215_setctrl()
1551 for (i = 10; ((dbri->mm.status & 0xe4) != 0x20); --i) in cs4215_setctrl()
1556 dbri->mm.status); in cs4215_setctrl()
1557 return -1; in cs4215_setctrl()
1565 /* Terminate CS4215 control mode - data sheet says in cs4215_setctrl()
1568 dbri->mm.ctrl[0] |= CS4215_CLB; in cs4215_setctrl()
1569 xmit_fixed(dbri, 17, *(int *)dbri->mm.ctrl); in cs4215_setctrl()
1598 return -1; in cs4215_prepare()
1603 dbri->mm.ctrl[1] = CS4215_DFR_ULAW; in cs4215_prepare()
1604 dbri->mm.precision = 8; in cs4215_prepare()
1607 dbri->mm.ctrl[1] = CS4215_DFR_ALAW; in cs4215_prepare()
1608 dbri->mm.precision = 8; in cs4215_prepare()
1611 dbri->mm.ctrl[1] = CS4215_DFR_LINEAR8; in cs4215_prepare()
1612 dbri->mm.precision = 8; in cs4215_prepare()
1615 dbri->mm.ctrl[1] = CS4215_DFR_LINEAR16; in cs4215_prepare()
1616 dbri->mm.precision = 16; in cs4215_prepare()
1620 return -1; in cs4215_prepare()
1624 dbri->mm.ctrl[1] |= CS4215_FREQ[freq_idx].csval; in cs4215_prepare()
1625 dbri->mm.ctrl[2] = CS4215_XCLK | in cs4215_prepare()
1628 dbri->mm.channels = channels; in cs4215_prepare()
1630 dbri->mm.ctrl[1] |= CS4215_DFR_STEREO; in cs4215_prepare()
1644 u32 reg2 = sbus_readl(dbri->regs + REG2); in cs4215_init()
1650 dbri->mm.onboard = 1; in cs4215_init()
1654 dbri->mm.onboard = 0; in cs4215_init()
1659 sbus_writel(D_ENPIO2, dbri->regs + REG2); in cs4215_init()
1665 return -EIO; in cs4215_init()
1669 cs4215_init_data(&dbri->mm); in cs4215_init()
1671 /* Enable capture of the status & version timeslots. */ in cs4215_init()
1672 recv_fixed(dbri, 18, &dbri->mm.status); in cs4215_init()
1673 recv_fixed(dbri, 19, &dbri->mm.version); in cs4215_init()
1675 dbri->mm.offset = dbri->mm.onboard ? 0 : 8; in cs4215_init()
1676 if (cs4215_setctrl(dbri) == -1 || dbri->mm.version == 0xff) { in cs4215_init()
1678 dbri->mm.offset); in cs4215_init()
1679 return -EIO; in cs4215_init()
1681 dprintk(D_MM, "Found CS4215 at offset %d\n", dbri->mm.offset); in cs4215_init()
1717 dvma_addr = (u32)dbri->dma_dvma; in xmit_descs()
1718 info = &dbri->stream_info[DBRI_REC]; in xmit_descs()
1719 spin_lock_irqsave(&dbri->lock, flags); in xmit_descs()
1721 if (info->pipe >= 0) { in xmit_descs()
1722 first_td = dbri->pipes[info->pipe].first_desc; in xmit_descs()
1730 dbri->pipes[info->pipe].sdp in xmit_descs()
1737 dbri->pipes[info->pipe].desc = first_td; in xmit_descs()
1741 info = &dbri->stream_info[DBRI_PLAY]; in xmit_descs()
1743 if (info->pipe >= 0) { in xmit_descs()
1744 first_td = dbri->pipes[info->pipe].first_desc; in xmit_descs()
1752 dbri->pipes[info->pipe].sdp in xmit_descs()
1759 dbri->pipes[info->pipe].desc = first_td; in xmit_descs()
1763 spin_unlock_irqrestore(&dbri->lock, flags); in xmit_descs()
1782 struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY]; in transmission_complete_intr()
1783 int td = dbri->pipes[pipe].desc; in transmission_complete_intr()
1792 status = DBRI_TD_STATUS(dbri->dma->desc[td].word4); in transmission_complete_intr()
1798 dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */ in transmission_complete_intr()
1799 info->offset += DBRI_RD_CNT(dbri->dma->desc[td].word1); in transmission_complete_intr()
1801 td = dbri->next_desc[td]; in transmission_complete_intr()
1802 dbri->pipes[pipe].desc = td; in transmission_complete_intr()
1806 spin_unlock(&dbri->lock); in transmission_complete_intr()
1807 snd_pcm_period_elapsed(info->substream); in transmission_complete_intr()
1808 spin_lock(&dbri->lock); in transmission_complete_intr()
1814 int rd = dbri->pipes[pipe].desc; in reception_complete_intr()
1822 dbri->pipes[pipe].desc = dbri->next_desc[rd]; in reception_complete_intr()
1823 status = dbri->dma->desc[rd].word1; in reception_complete_intr()
1824 dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */ in reception_complete_intr()
1826 info = &dbri->stream_info[DBRI_REC]; in reception_complete_intr()
1827 info->offset += DBRI_RD_CNT(status); in reception_complete_intr()
1829 /* FIXME: Check status */ in reception_complete_intr()
1835 spin_unlock(&dbri->lock); in reception_complete_intr()
1836 snd_pcm_period_elapsed(info->substream); in reception_complete_intr()
1837 spin_lock(&dbri->lock); in reception_complete_intr()
1851 dprintk(D_CMD, "INTR: Command: %-5s Value:%d\n", in dbri_process_one_interrupt()
1871 /* UNDR - Transmission underrun in dbri_process_one_interrupt()
1880 int td = dbri->pipes[pipe].desc; in dbri_process_one_interrupt()
1882 dbri->dma->desc[td].word4 = 0; in dbri_process_one_interrupt()
1885 dbri->pipes[pipe].sdp in dbri_process_one_interrupt()
1887 *(cmd++) = dbri->dma_dvma + dbri_dma_off(desc, td); in dbri_process_one_interrupt()
1893 /* FXDT - Fixed data change */ in dbri_process_one_interrupt()
1894 if (dbri->pipes[channel].sdp & D_SDP_MSB) in dbri_process_one_interrupt()
1895 val = reverse_bytes(val, dbri->pipes[channel].length); in dbri_process_one_interrupt()
1897 if (dbri->pipes[channel].recv_fixed_ptr) in dbri_process_one_interrupt()
1898 *(dbri->pipes[channel].recv_fixed_ptr) = val; in dbri_process_one_interrupt()
1909 * right now). Non-zero words require processing and are handed off
1916 while ((x = dbri->dma->intr[dbri->dbri_irqp]) != 0) { in dbri_process_interrupt_buffer()
1917 dbri->dma->intr[dbri->dbri_irqp] = 0; in dbri_process_interrupt_buffer()
1918 dbri->dbri_irqp++; in dbri_process_interrupt_buffer()
1919 if (dbri->dbri_irqp == DBRI_INT_BLK) in dbri_process_interrupt_buffer()
1920 dbri->dbri_irqp = 1; in dbri_process_interrupt_buffer()
1934 spin_lock(&dbri->lock); in snd_dbri_interrupt()
1939 x = sbus_readl(dbri->regs + REG1); in snd_dbri_interrupt()
1960 * to be disabled, so just re-enable and try to keep going. in snd_dbri_interrupt()
1971 tmp = sbus_readl(dbri->regs + REG0); in snd_dbri_interrupt()
1973 sbus_writel(tmp, dbri->regs + REG0); in snd_dbri_interrupt()
1979 spin_unlock(&dbri->lock); in snd_dbri_interrupt()
2018 if (c->min > 1) { in snd_hw_rule_format()
2034 if (!(f->bits[0] & SNDRV_PCM_FMTBIT_S16_BE)) { in snd_hw_rule_channels()
2046 struct snd_pcm_runtime *runtime = substream->runtime; in snd_dbri_open()
2051 runtime->hw = snd_dbri_pcm_hw; in snd_dbri_open()
2053 spin_lock_irqsave(&dbri->lock, flags); in snd_dbri_open()
2054 info->substream = substream; in snd_dbri_open()
2055 info->offset = 0; in snd_dbri_open()
2056 info->dvma_buffer = 0; in snd_dbri_open()
2057 info->pipe = -1; in snd_dbri_open()
2058 spin_unlock_irqrestore(&dbri->lock, flags); in snd_dbri_open()
2062 -1); in snd_dbri_open()
2066 -1); in snd_dbri_open()
2079 info->substream = NULL; in snd_dbri_close()
2080 info->offset = 0; in snd_dbri_close()
2088 struct snd_pcm_runtime *runtime = substream->runtime; in snd_dbri_hw_params()
2103 if (info->dvma_buffer == 0) { in snd_dbri_hw_params()
2109 info->dvma_buffer = in snd_dbri_hw_params()
2110 dma_map_single(&dbri->op->dev, in snd_dbri_hw_params()
2111 runtime->dma_area, in snd_dbri_hw_params()
2118 direction, info->dvma_buffer); in snd_dbri_hw_params()
2132 if (info->dvma_buffer) { in snd_dbri_hw_free()
2138 dma_unmap_single(&dbri->op->dev, info->dvma_buffer, in snd_dbri_hw_free()
2139 substream->runtime->buffer_size, direction); in snd_dbri_hw_free()
2140 info->dvma_buffer = 0; in snd_dbri_hw_free()
2142 if (info->pipe != -1) { in snd_dbri_hw_free()
2143 reset_pipe(dbri, info->pipe); in snd_dbri_hw_free()
2144 info->pipe = -1; in snd_dbri_hw_free()
2156 info->size = snd_pcm_lib_buffer_bytes(substream); in snd_dbri_prepare()
2158 info->pipe = 4; /* Send pipe */ in snd_dbri_prepare()
2160 info->pipe = 6; /* Receive pipe */ in snd_dbri_prepare()
2162 spin_lock_irq(&dbri->lock); in snd_dbri_prepare()
2163 info->offset = 0; in snd_dbri_prepare()
2171 spin_unlock_irq(&dbri->lock); in snd_dbri_prepare()
2173 dprintk(D_USR, "prepare audio output. %d bytes\n", info->size); in snd_dbri_prepare()
2187 /* Re-submit the TDs. */ in snd_dbri_trigger()
2192 reset_pipe(dbri, info->pipe); in snd_dbri_trigger()
2195 ret = -EINVAL; in snd_dbri_trigger()
2207 ret = bytes_to_frames(substream->runtime, info->offset) in snd_dbri_pointer()
2208 % substream->runtime->buffer_size; in snd_dbri_pointer()
2210 ret, substream->runtime->buffer_size); in snd_dbri_pointer()
2240 pcm->private_data = card->private_data; in snd_dbri_pcm()
2241 pcm->info_flags = 0; in snd_dbri_pcm()
2242 strcpy(pcm->name, card->shortname); in snd_dbri_pcm()
2256 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in snd_cs4215_info_volume()
2257 uinfo->count = 2; in snd_cs4215_info_volume()
2258 uinfo->value.integer.min = 0; in snd_cs4215_info_volume()
2259 if (kcontrol->private_value == DBRI_PLAY) in snd_cs4215_info_volume()
2260 uinfo->value.integer.max = DBRI_MAX_VOLUME; in snd_cs4215_info_volume()
2262 uinfo->value.integer.max = DBRI_MAX_GAIN; in snd_cs4215_info_volume()
2273 return -EINVAL; in snd_cs4215_get_volume()
2274 info = &dbri->stream_info[kcontrol->private_value]; in snd_cs4215_get_volume()
2276 ucontrol->value.integer.value[0] = info->left_gain; in snd_cs4215_get_volume()
2277 ucontrol->value.integer.value[1] = info->right_gain; in snd_cs4215_get_volume()
2286 &dbri->stream_info[kcontrol->private_value]; in snd_cs4215_put_volume()
2290 vol[0] = ucontrol->value.integer.value[0]; in snd_cs4215_put_volume()
2291 vol[1] = ucontrol->value.integer.value[1]; in snd_cs4215_put_volume()
2292 if (kcontrol->private_value == DBRI_PLAY) { in snd_cs4215_put_volume()
2294 return -EINVAL; in snd_cs4215_put_volume()
2297 return -EINVAL; in snd_cs4215_put_volume()
2300 if (info->left_gain != vol[0]) { in snd_cs4215_put_volume()
2301 info->left_gain = vol[0]; in snd_cs4215_put_volume()
2304 if (info->right_gain != vol[1]) { in snd_cs4215_put_volume()
2305 info->right_gain = vol[1]; in snd_cs4215_put_volume()
2322 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_cs4215_info_single()
2324 uinfo->type = (mask == 1) ? in snd_cs4215_info_single()
2326 uinfo->count = 1; in snd_cs4215_info_single()
2327 uinfo->value.integer.min = 0; in snd_cs4215_info_single()
2328 uinfo->value.integer.max = mask; in snd_cs4215_info_single()
2336 int elem = kcontrol->private_value & 0xff; in snd_cs4215_get_single()
2337 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_cs4215_get_single()
2338 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_cs4215_get_single()
2339 int invert = (kcontrol->private_value >> 24) & 1; in snd_cs4215_get_single()
2342 return -EINVAL; in snd_cs4215_get_single()
2345 ucontrol->value.integer.value[0] = in snd_cs4215_get_single()
2346 (dbri->mm.data[elem] >> shift) & mask; in snd_cs4215_get_single()
2348 ucontrol->value.integer.value[0] = in snd_cs4215_get_single()
2349 (dbri->mm.ctrl[elem - 4] >> shift) & mask; in snd_cs4215_get_single()
2352 ucontrol->value.integer.value[0] = in snd_cs4215_get_single()
2353 mask - ucontrol->value.integer.value[0]; in snd_cs4215_get_single()
2361 int elem = kcontrol->private_value & 0xff; in snd_cs4215_put_single()
2362 int shift = (kcontrol->private_value >> 8) & 0xff; in snd_cs4215_put_single()
2363 int mask = (kcontrol->private_value >> 16) & 0xff; in snd_cs4215_put_single()
2364 int invert = (kcontrol->private_value >> 24) & 1; in snd_cs4215_put_single()
2369 return -EINVAL; in snd_cs4215_put_single()
2371 val = (ucontrol->value.integer.value[0] & mask); in snd_cs4215_put_single()
2373 val = mask - val; in snd_cs4215_put_single()
2377 dbri->mm.data[elem] = (dbri->mm.data[elem] & in snd_cs4215_put_single()
2379 changed = (val != dbri->mm.data[elem]); in snd_cs4215_put_single()
2381 dbri->mm.ctrl[elem - 4] = (dbri->mm.ctrl[elem - 4] & in snd_cs4215_put_single()
2383 changed = (val != dbri->mm.ctrl[elem - 4]); in snd_cs4215_put_single()
2387 "mixer-value=%ld, mm-value=0x%x\n", in snd_cs4215_put_single()
2388 mask, changed, ucontrol->value.integer.value[0], in snd_cs4215_put_single()
2389 dbri->mm.data[elem & 3]); in snd_cs4215_put_single()
2402 /* Entries 0-3 map to the 4 data timeslots, entries 4-7 map to the 4 control
2445 if (snd_BUG_ON(!card || !card->private_data)) in snd_dbri_mixer()
2446 return -EINVAL; in snd_dbri_mixer()
2447 dbri = card->private_data; in snd_dbri_mixer()
2449 strcpy(card->mixername, card->shortname); in snd_dbri_mixer()
2459 dbri->stream_info[idx].left_gain = 0; in snd_dbri_mixer()
2460 dbri->stream_info[idx].right_gain = 0; in snd_dbri_mixer()
2472 struct snd_dbri *dbri = entry->private_data; in dbri_regs_read()
2474 snd_iprintf(buffer, "REG0: 0x%x\n", sbus_readl(dbri->regs + REG0)); in dbri_regs_read()
2475 snd_iprintf(buffer, "REG2: 0x%x\n", sbus_readl(dbri->regs + REG2)); in dbri_regs_read()
2476 snd_iprintf(buffer, "REG8: 0x%x\n", sbus_readl(dbri->regs + REG8)); in dbri_regs_read()
2477 snd_iprintf(buffer, "REG9: 0x%x\n", sbus_readl(dbri->regs + REG9)); in dbri_regs_read()
2484 struct snd_dbri *dbri = entry->private_data; in dbri_debug_read()
2490 struct dbri_pipe *pptr = &dbri->pipes[pipe]; in dbri_debug_read()
2495 (pptr->sdp & D_SDP_TO_SER) ? "output" : in dbri_debug_read()
2497 pptr->sdp, pptr->desc, in dbri_debug_read()
2498 pptr->length, pptr->nextpipe); in dbri_debug_read()
2506 struct snd_dbri *dbri = card->private_data; in snd_dbri_proc()
2525 struct snd_dbri *dbri = card->private_data; in snd_dbri_create()
2528 spin_lock_init(&dbri->lock); in snd_dbri_create()
2529 dbri->op = op; in snd_dbri_create()
2530 dbri->irq = irq; in snd_dbri_create()
2532 dbri->dma = dma_alloc_coherent(&op->dev, sizeof(struct dbri_dma), in snd_dbri_create()
2533 &dbri->dma_dvma, GFP_KERNEL); in snd_dbri_create()
2534 if (!dbri->dma) in snd_dbri_create()
2535 return -ENOMEM; in snd_dbri_create()
2538 dbri->dma, dbri->dma_dvma); in snd_dbri_create()
2541 dbri->regs_size = resource_size(&op->resource[0]); in snd_dbri_create()
2542 dbri->regs = of_ioremap(&op->resource[0], 0, in snd_dbri_create()
2543 dbri->regs_size, "DBRI Registers"); in snd_dbri_create()
2544 if (!dbri->regs) { in snd_dbri_create()
2546 dma_free_coherent(&op->dev, sizeof(struct dbri_dma), in snd_dbri_create()
2547 (void *)dbri->dma, dbri->dma_dvma); in snd_dbri_create()
2548 return -EIO; in snd_dbri_create()
2551 err = request_irq(dbri->irq, snd_dbri_interrupt, IRQF_SHARED, in snd_dbri_create()
2554 printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq); in snd_dbri_create()
2555 of_iounmap(&op->resource[0], dbri->regs, dbri->regs_size); in snd_dbri_create()
2556 dma_free_coherent(&op->dev, sizeof(struct dbri_dma), in snd_dbri_create()
2557 (void *)dbri->dma, dbri->dma_dvma); in snd_dbri_create()
2577 if (dbri->irq) in snd_dbri_free()
2578 free_irq(dbri->irq, dbri); in snd_dbri_free()
2580 if (dbri->regs) in snd_dbri_free()
2581 of_iounmap(&dbri->op->resource[0], dbri->regs, dbri->regs_size); in snd_dbri_free()
2583 if (dbri->dma) in snd_dbri_free()
2584 dma_free_coherent(&dbri->op->dev, in snd_dbri_free()
2586 (void *)dbri->dma, dbri->dma_dvma); in snd_dbri_free()
2599 return -ENODEV; in dbri_probe()
2600 if (!enable[dev]) { in dbri_probe()
2602 return -ENOENT; in dbri_probe()
2605 irq = op->archdata.irqs[0]; in dbri_probe()
2607 printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev); in dbri_probe()
2608 return -ENODEV; in dbri_probe()
2611 err = snd_card_new(&op->dev, index[dev], id[dev], THIS_MODULE, in dbri_probe()
2616 strcpy(card->driver, "DBRI"); in dbri_probe()
2617 strcpy(card->shortname, "Sun DBRI"); in dbri_probe()
2618 rp = &op->resource[0]; in dbri_probe()
2619 sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d", in dbri_probe()
2620 card->shortname, in dbri_probe()
2621 rp->flags & 0xffL, (unsigned long long)rp->start, irq); in dbri_probe()
2629 dbri = card->private_data; in dbri_probe()
2640 dev_set_drvdata(&op->dev, card); in dbri_probe()
2647 dev, dbri->regs, in dbri_probe()
2648 dbri->irq, op->dev.of_node->name[9], dbri->mm.version); in dbri_probe()
2661 struct snd_card *card = dev_get_drvdata(&op->dev); in dbri_remove()
2663 snd_dbri_free(card->private_data); in dbri_remove()