18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Driver for Sound Core PDAudioCF soundcard 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <sound/core.h> 98c2ecf20Sopenharmony_ci#include "pdaudiocf.h" 108c2ecf20Sopenharmony_ci#include <sound/initval.h> 118c2ecf20Sopenharmony_ci#include <asm/irq_regs.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci */ 168c2ecf20Sopenharmony_ciirqreturn_t pdacf_interrupt(int irq, void *dev) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci struct snd_pdacf *chip = dev; 198c2ecf20Sopenharmony_ci unsigned short stat; 208c2ecf20Sopenharmony_ci bool wake_thread = false; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci if ((chip->chip_status & (PDAUDIOCF_STAT_IS_STALE| 238c2ecf20Sopenharmony_ci PDAUDIOCF_STAT_IS_CONFIGURED| 248c2ecf20Sopenharmony_ci PDAUDIOCF_STAT_IS_SUSPENDED)) != PDAUDIOCF_STAT_IS_CONFIGURED) 258c2ecf20Sopenharmony_ci return IRQ_HANDLED; /* IRQ_NONE here? */ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci stat = inw(chip->port + PDAUDIOCF_REG_ISR); 288c2ecf20Sopenharmony_ci if (stat & (PDAUDIOCF_IRQLVL|PDAUDIOCF_IRQOVR)) { 298c2ecf20Sopenharmony_ci if (stat & PDAUDIOCF_IRQOVR) /* should never happen */ 308c2ecf20Sopenharmony_ci snd_printk(KERN_ERR "PDAUDIOCF SRAM buffer overrun detected!\n"); 318c2ecf20Sopenharmony_ci if (chip->pcm_substream) 328c2ecf20Sopenharmony_ci wake_thread = true; 338c2ecf20Sopenharmony_ci if (!(stat & PDAUDIOCF_IRQAKM)) 348c2ecf20Sopenharmony_ci stat |= PDAUDIOCF_IRQAKM; /* check rate */ 358c2ecf20Sopenharmony_ci } 368c2ecf20Sopenharmony_ci if (get_irq_regs() != NULL) 378c2ecf20Sopenharmony_ci snd_ak4117_check_rate_and_errors(chip->ak4117, 0); 388c2ecf20Sopenharmony_ci return wake_thread ? IRQ_WAKE_THREAD : IRQ_HANDLED; 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_mono16(u16 *dst, u16 xor, unsigned int size, unsigned long rdp_port) 428c2ecf20Sopenharmony_ci{ 438c2ecf20Sopenharmony_ci while (size-- > 0) { 448c2ecf20Sopenharmony_ci *dst++ = inw(rdp_port) ^ xor; 458c2ecf20Sopenharmony_ci inw(rdp_port); 468c2ecf20Sopenharmony_ci } 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_mono32(u32 *dst, u32 xor, unsigned int size, unsigned long rdp_port) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci register u16 val1, val2; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci while (size-- > 0) { 548c2ecf20Sopenharmony_ci val1 = inw(rdp_port); 558c2ecf20Sopenharmony_ci val2 = inw(rdp_port); 568c2ecf20Sopenharmony_ci inw(rdp_port); 578c2ecf20Sopenharmony_ci *dst++ = ((((u32)val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor; 588c2ecf20Sopenharmony_ci } 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_stereo16(u16 *dst, u16 xor, unsigned int size, unsigned long rdp_port) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci while (size-- > 0) { 648c2ecf20Sopenharmony_ci *dst++ = inw(rdp_port) ^ xor; 658c2ecf20Sopenharmony_ci *dst++ = inw(rdp_port) ^ xor; 668c2ecf20Sopenharmony_ci } 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_stereo32(u32 *dst, u32 xor, unsigned int size, unsigned long rdp_port) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci register u16 val1, val2, val3; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci while (size-- > 0) { 748c2ecf20Sopenharmony_ci val1 = inw(rdp_port); 758c2ecf20Sopenharmony_ci val2 = inw(rdp_port); 768c2ecf20Sopenharmony_ci val3 = inw(rdp_port); 778c2ecf20Sopenharmony_ci *dst++ = ((((u32)val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor; 788c2ecf20Sopenharmony_ci *dst++ = (((u32)val3 << 16) | (val2 & 0xff00)) ^ xor; 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_mono16sw(u16 *dst, u16 xor, unsigned int size, unsigned long rdp_port) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci while (size-- > 0) { 858c2ecf20Sopenharmony_ci *dst++ = swab16(inw(rdp_port) ^ xor); 868c2ecf20Sopenharmony_ci inw(rdp_port); 878c2ecf20Sopenharmony_ci } 888c2ecf20Sopenharmony_ci} 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_mono32sw(u32 *dst, u32 xor, unsigned int size, unsigned long rdp_port) 918c2ecf20Sopenharmony_ci{ 928c2ecf20Sopenharmony_ci register u16 val1, val2; 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci while (size-- > 0) { 958c2ecf20Sopenharmony_ci val1 = inw(rdp_port); 968c2ecf20Sopenharmony_ci val2 = inw(rdp_port); 978c2ecf20Sopenharmony_ci inw(rdp_port); 988c2ecf20Sopenharmony_ci *dst++ = swab32((((val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor); 998c2ecf20Sopenharmony_ci } 1008c2ecf20Sopenharmony_ci} 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_stereo16sw(u16 *dst, u16 xor, unsigned int size, unsigned long rdp_port) 1038c2ecf20Sopenharmony_ci{ 1048c2ecf20Sopenharmony_ci while (size-- > 0) { 1058c2ecf20Sopenharmony_ci *dst++ = swab16(inw(rdp_port) ^ xor); 1068c2ecf20Sopenharmony_ci *dst++ = swab16(inw(rdp_port) ^ xor); 1078c2ecf20Sopenharmony_ci } 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_stereo32sw(u32 *dst, u32 xor, unsigned int size, unsigned long rdp_port) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci register u16 val1, val2, val3; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci while (size-- > 0) { 1158c2ecf20Sopenharmony_ci val1 = inw(rdp_port); 1168c2ecf20Sopenharmony_ci val2 = inw(rdp_port); 1178c2ecf20Sopenharmony_ci val3 = inw(rdp_port); 1188c2ecf20Sopenharmony_ci *dst++ = swab32((((val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor); 1198c2ecf20Sopenharmony_ci *dst++ = swab32((((u32)val3 << 16) | (val2 & 0xff00)) ^ xor); 1208c2ecf20Sopenharmony_ci } 1218c2ecf20Sopenharmony_ci} 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_mono24le(u8 *dst, u16 xor, unsigned int size, unsigned long rdp_port) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci register u16 val1, val2; 1268c2ecf20Sopenharmony_ci register u32 xval1; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci while (size-- > 0) { 1298c2ecf20Sopenharmony_ci val1 = inw(rdp_port); 1308c2ecf20Sopenharmony_ci val2 = inw(rdp_port); 1318c2ecf20Sopenharmony_ci inw(rdp_port); 1328c2ecf20Sopenharmony_ci xval1 = (((val2 & 0xff) << 8) | (val1 << 16)) ^ xor; 1338c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 8); 1348c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 16); 1358c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 24); 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_mono24be(u8 *dst, u16 xor, unsigned int size, unsigned long rdp_port) 1408c2ecf20Sopenharmony_ci{ 1418c2ecf20Sopenharmony_ci register u16 val1, val2; 1428c2ecf20Sopenharmony_ci register u32 xval1; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci while (size-- > 0) { 1458c2ecf20Sopenharmony_ci val1 = inw(rdp_port); 1468c2ecf20Sopenharmony_ci val2 = inw(rdp_port); 1478c2ecf20Sopenharmony_ci inw(rdp_port); 1488c2ecf20Sopenharmony_ci xval1 = (((val2 & 0xff) << 8) | (val1 << 16)) ^ xor; 1498c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 24); 1508c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 16); 1518c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 8); 1528c2ecf20Sopenharmony_ci } 1538c2ecf20Sopenharmony_ci} 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_stereo24le(u8 *dst, u32 xor, unsigned int size, unsigned long rdp_port) 1568c2ecf20Sopenharmony_ci{ 1578c2ecf20Sopenharmony_ci register u16 val1, val2, val3; 1588c2ecf20Sopenharmony_ci register u32 xval1, xval2; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci while (size-- > 0) { 1618c2ecf20Sopenharmony_ci val1 = inw(rdp_port); 1628c2ecf20Sopenharmony_ci val2 = inw(rdp_port); 1638c2ecf20Sopenharmony_ci val3 = inw(rdp_port); 1648c2ecf20Sopenharmony_ci xval1 = ((((u32)val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor; 1658c2ecf20Sopenharmony_ci xval2 = (((u32)val3 << 16) | (val2 & 0xff00)) ^ xor; 1668c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 8); 1678c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 16); 1688c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 24); 1698c2ecf20Sopenharmony_ci *dst++ = (u8)(xval2 >> 8); 1708c2ecf20Sopenharmony_ci *dst++ = (u8)(xval2 >> 16); 1718c2ecf20Sopenharmony_ci *dst++ = (u8)(xval2 >> 24); 1728c2ecf20Sopenharmony_ci } 1738c2ecf20Sopenharmony_ci} 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistatic inline void pdacf_transfer_stereo24be(u8 *dst, u32 xor, unsigned int size, unsigned long rdp_port) 1768c2ecf20Sopenharmony_ci{ 1778c2ecf20Sopenharmony_ci register u16 val1, val2, val3; 1788c2ecf20Sopenharmony_ci register u32 xval1, xval2; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci while (size-- > 0) { 1818c2ecf20Sopenharmony_ci val1 = inw(rdp_port); 1828c2ecf20Sopenharmony_ci val2 = inw(rdp_port); 1838c2ecf20Sopenharmony_ci val3 = inw(rdp_port); 1848c2ecf20Sopenharmony_ci xval1 = ((((u32)val2 & 0xff) << 24) | ((u32)val1 << 8)) ^ xor; 1858c2ecf20Sopenharmony_ci xval2 = (((u32)val3 << 16) | (val2 & 0xff00)) ^ xor; 1868c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 24); 1878c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 16); 1888c2ecf20Sopenharmony_ci *dst++ = (u8)(xval1 >> 8); 1898c2ecf20Sopenharmony_ci *dst++ = (u8)(xval2 >> 24); 1908c2ecf20Sopenharmony_ci *dst++ = (u8)(xval2 >> 16); 1918c2ecf20Sopenharmony_ci *dst++ = (u8)(xval2 >> 8); 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_cistatic void pdacf_transfer(struct snd_pdacf *chip, unsigned int size, unsigned int off) 1968c2ecf20Sopenharmony_ci{ 1978c2ecf20Sopenharmony_ci unsigned long rdp_port = chip->port + PDAUDIOCF_REG_MD; 1988c2ecf20Sopenharmony_ci unsigned int xor = chip->pcm_xor; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci if (chip->pcm_sample == 3) { 2018c2ecf20Sopenharmony_ci if (chip->pcm_little) { 2028c2ecf20Sopenharmony_ci if (chip->pcm_channels == 1) { 2038c2ecf20Sopenharmony_ci pdacf_transfer_mono24le((char *)chip->pcm_area + (off * 3), xor, size, rdp_port); 2048c2ecf20Sopenharmony_ci } else { 2058c2ecf20Sopenharmony_ci pdacf_transfer_stereo24le((char *)chip->pcm_area + (off * 6), xor, size, rdp_port); 2068c2ecf20Sopenharmony_ci } 2078c2ecf20Sopenharmony_ci } else { 2088c2ecf20Sopenharmony_ci if (chip->pcm_channels == 1) { 2098c2ecf20Sopenharmony_ci pdacf_transfer_mono24be((char *)chip->pcm_area + (off * 3), xor, size, rdp_port); 2108c2ecf20Sopenharmony_ci } else { 2118c2ecf20Sopenharmony_ci pdacf_transfer_stereo24be((char *)chip->pcm_area + (off * 6), xor, size, rdp_port); 2128c2ecf20Sopenharmony_ci } 2138c2ecf20Sopenharmony_ci } 2148c2ecf20Sopenharmony_ci return; 2158c2ecf20Sopenharmony_ci } 2168c2ecf20Sopenharmony_ci if (chip->pcm_swab == 0) { 2178c2ecf20Sopenharmony_ci if (chip->pcm_channels == 1) { 2188c2ecf20Sopenharmony_ci if (chip->pcm_frame == 2) { 2198c2ecf20Sopenharmony_ci pdacf_transfer_mono16((u16 *)chip->pcm_area + off, xor, size, rdp_port); 2208c2ecf20Sopenharmony_ci } else { 2218c2ecf20Sopenharmony_ci pdacf_transfer_mono32((u32 *)chip->pcm_area + off, xor, size, rdp_port); 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci } else { 2248c2ecf20Sopenharmony_ci if (chip->pcm_frame == 2) { 2258c2ecf20Sopenharmony_ci pdacf_transfer_stereo16((u16 *)chip->pcm_area + (off * 2), xor, size, rdp_port); 2268c2ecf20Sopenharmony_ci } else { 2278c2ecf20Sopenharmony_ci pdacf_transfer_stereo32((u32 *)chip->pcm_area + (off * 2), xor, size, rdp_port); 2288c2ecf20Sopenharmony_ci } 2298c2ecf20Sopenharmony_ci } 2308c2ecf20Sopenharmony_ci } else { 2318c2ecf20Sopenharmony_ci if (chip->pcm_channels == 1) { 2328c2ecf20Sopenharmony_ci if (chip->pcm_frame == 2) { 2338c2ecf20Sopenharmony_ci pdacf_transfer_mono16sw((u16 *)chip->pcm_area + off, xor, size, rdp_port); 2348c2ecf20Sopenharmony_ci } else { 2358c2ecf20Sopenharmony_ci pdacf_transfer_mono32sw((u32 *)chip->pcm_area + off, xor, size, rdp_port); 2368c2ecf20Sopenharmony_ci } 2378c2ecf20Sopenharmony_ci } else { 2388c2ecf20Sopenharmony_ci if (chip->pcm_frame == 2) { 2398c2ecf20Sopenharmony_ci pdacf_transfer_stereo16sw((u16 *)chip->pcm_area + (off * 2), xor, size, rdp_port); 2408c2ecf20Sopenharmony_ci } else { 2418c2ecf20Sopenharmony_ci pdacf_transfer_stereo32sw((u32 *)chip->pcm_area + (off * 2), xor, size, rdp_port); 2428c2ecf20Sopenharmony_ci } 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci } 2458c2ecf20Sopenharmony_ci} 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ciirqreturn_t pdacf_threaded_irq(int irq, void *dev) 2488c2ecf20Sopenharmony_ci{ 2498c2ecf20Sopenharmony_ci struct snd_pdacf *chip = dev; 2508c2ecf20Sopenharmony_ci int size, off, cont, rdp, wdp; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci if ((chip->chip_status & (PDAUDIOCF_STAT_IS_STALE|PDAUDIOCF_STAT_IS_CONFIGURED)) != PDAUDIOCF_STAT_IS_CONFIGURED) 2538c2ecf20Sopenharmony_ci return IRQ_HANDLED; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci if (chip->pcm_substream == NULL || chip->pcm_substream->runtime == NULL || !snd_pcm_running(chip->pcm_substream)) 2568c2ecf20Sopenharmony_ci return IRQ_HANDLED; 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci rdp = inw(chip->port + PDAUDIOCF_REG_RDP); 2598c2ecf20Sopenharmony_ci wdp = inw(chip->port + PDAUDIOCF_REG_WDP); 2608c2ecf20Sopenharmony_ci /* printk(KERN_DEBUG "TASKLET: rdp = %x, wdp = %x\n", rdp, wdp); */ 2618c2ecf20Sopenharmony_ci size = wdp - rdp; 2628c2ecf20Sopenharmony_ci if (size < 0) 2638c2ecf20Sopenharmony_ci size += 0x10000; 2648c2ecf20Sopenharmony_ci if (size == 0) 2658c2ecf20Sopenharmony_ci size = 0x10000; 2668c2ecf20Sopenharmony_ci size /= chip->pcm_frame; 2678c2ecf20Sopenharmony_ci if (size > 64) 2688c2ecf20Sopenharmony_ci size -= 32; 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci#if 0 2718c2ecf20Sopenharmony_ci chip->pcm_hwptr += size; 2728c2ecf20Sopenharmony_ci chip->pcm_hwptr %= chip->pcm_size; 2738c2ecf20Sopenharmony_ci chip->pcm_tdone += size; 2748c2ecf20Sopenharmony_ci if (chip->pcm_frame == 2) { 2758c2ecf20Sopenharmony_ci unsigned long rdp_port = chip->port + PDAUDIOCF_REG_MD; 2768c2ecf20Sopenharmony_ci while (size-- > 0) { 2778c2ecf20Sopenharmony_ci inw(rdp_port); 2788c2ecf20Sopenharmony_ci inw(rdp_port); 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci } else { 2818c2ecf20Sopenharmony_ci unsigned long rdp_port = chip->port + PDAUDIOCF_REG_MD; 2828c2ecf20Sopenharmony_ci while (size-- > 0) { 2838c2ecf20Sopenharmony_ci inw(rdp_port); 2848c2ecf20Sopenharmony_ci inw(rdp_port); 2858c2ecf20Sopenharmony_ci inw(rdp_port); 2868c2ecf20Sopenharmony_ci } 2878c2ecf20Sopenharmony_ci } 2888c2ecf20Sopenharmony_ci#else 2898c2ecf20Sopenharmony_ci off = chip->pcm_hwptr + chip->pcm_tdone; 2908c2ecf20Sopenharmony_ci off %= chip->pcm_size; 2918c2ecf20Sopenharmony_ci chip->pcm_tdone += size; 2928c2ecf20Sopenharmony_ci while (size > 0) { 2938c2ecf20Sopenharmony_ci cont = chip->pcm_size - off; 2948c2ecf20Sopenharmony_ci if (cont > size) 2958c2ecf20Sopenharmony_ci cont = size; 2968c2ecf20Sopenharmony_ci pdacf_transfer(chip, cont, off); 2978c2ecf20Sopenharmony_ci off += cont; 2988c2ecf20Sopenharmony_ci off %= chip->pcm_size; 2998c2ecf20Sopenharmony_ci size -= cont; 3008c2ecf20Sopenharmony_ci } 3018c2ecf20Sopenharmony_ci#endif 3028c2ecf20Sopenharmony_ci mutex_lock(&chip->reg_lock); 3038c2ecf20Sopenharmony_ci while (chip->pcm_tdone >= chip->pcm_period) { 3048c2ecf20Sopenharmony_ci chip->pcm_hwptr += chip->pcm_period; 3058c2ecf20Sopenharmony_ci chip->pcm_hwptr %= chip->pcm_size; 3068c2ecf20Sopenharmony_ci chip->pcm_tdone -= chip->pcm_period; 3078c2ecf20Sopenharmony_ci mutex_unlock(&chip->reg_lock); 3088c2ecf20Sopenharmony_ci snd_pcm_period_elapsed(chip->pcm_substream); 3098c2ecf20Sopenharmony_ci mutex_lock(&chip->reg_lock); 3108c2ecf20Sopenharmony_ci } 3118c2ecf20Sopenharmony_ci mutex_unlock(&chip->reg_lock); 3128c2ecf20Sopenharmony_ci return IRQ_HANDLED; 3138c2ecf20Sopenharmony_ci} 314