1*c454fd4eSMasakazu Mokuno /* 2*c454fd4eSMasakazu Mokuno * Audio support for PS3 3*c454fd4eSMasakazu Mokuno * Copyright (C) 2007 Sony Computer Entertainment Inc. 4*c454fd4eSMasakazu Mokuno * All rights reserved. 5*c454fd4eSMasakazu Mokuno * Copyright 2006, 2007 Sony Corporation 6*c454fd4eSMasakazu Mokuno * 7*c454fd4eSMasakazu Mokuno * This program is free software; you can redistribute it and/or modify 8*c454fd4eSMasakazu Mokuno * it under the terms of the GNU General Public License 9*c454fd4eSMasakazu Mokuno * as published by the Free Software Foundation; version 2 of the Licence. 10*c454fd4eSMasakazu Mokuno * 11*c454fd4eSMasakazu Mokuno * This program is distributed in the hope that it will be useful, 12*c454fd4eSMasakazu Mokuno * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*c454fd4eSMasakazu Mokuno * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*c454fd4eSMasakazu Mokuno * GNU General Public License for more details. 15*c454fd4eSMasakazu Mokuno * 16*c454fd4eSMasakazu Mokuno * You should have received a copy of the GNU General Public License 17*c454fd4eSMasakazu Mokuno * along with this program; if not, write to the Free Software 18*c454fd4eSMasakazu Mokuno * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19*c454fd4eSMasakazu Mokuno */ 20*c454fd4eSMasakazu Mokuno 21*c454fd4eSMasakazu Mokuno #include <linux/init.h> 22*c454fd4eSMasakazu Mokuno #include <linux/slab.h> 23*c454fd4eSMasakazu Mokuno #include <linux/io.h> 24*c454fd4eSMasakazu Mokuno #include <linux/interrupt.h> 25*c454fd4eSMasakazu Mokuno #include <sound/driver.h> 26*c454fd4eSMasakazu Mokuno #include <sound/core.h> 27*c454fd4eSMasakazu Mokuno #include <sound/initval.h> 28*c454fd4eSMasakazu Mokuno #include <sound/pcm.h> 29*c454fd4eSMasakazu Mokuno #include <sound/asound.h> 30*c454fd4eSMasakazu Mokuno #include <sound/memalloc.h> 31*c454fd4eSMasakazu Mokuno #include <sound/pcm_params.h> 32*c454fd4eSMasakazu Mokuno #include <sound/control.h> 33*c454fd4eSMasakazu Mokuno #include <linux/dmapool.h> 34*c454fd4eSMasakazu Mokuno #include <linux/dma-mapping.h> 35*c454fd4eSMasakazu Mokuno #include <asm/firmware.h> 36*c454fd4eSMasakazu Mokuno #include <linux/io.h> 37*c454fd4eSMasakazu Mokuno #include <asm/dma.h> 38*c454fd4eSMasakazu Mokuno #include <asm/lv1call.h> 39*c454fd4eSMasakazu Mokuno #include <asm/ps3.h> 40*c454fd4eSMasakazu Mokuno #include <asm/ps3av.h> 41*c454fd4eSMasakazu Mokuno 42*c454fd4eSMasakazu Mokuno #include "snd_ps3_reg.h" 43*c454fd4eSMasakazu Mokuno #include "snd_ps3.h" 44*c454fd4eSMasakazu Mokuno 45*c454fd4eSMasakazu Mokuno MODULE_LICENSE("GPL v2"); 46*c454fd4eSMasakazu Mokuno MODULE_DESCRIPTION("PS3 sound driver"); 47*c454fd4eSMasakazu Mokuno MODULE_AUTHOR("Sony Computer Entertainment Inc."); 48*c454fd4eSMasakazu Mokuno 49*c454fd4eSMasakazu Mokuno /* module entries */ 50*c454fd4eSMasakazu Mokuno static int __init snd_ps3_init(void); 51*c454fd4eSMasakazu Mokuno static void __exit snd_ps3_exit(void); 52*c454fd4eSMasakazu Mokuno 53*c454fd4eSMasakazu Mokuno /* ALSA snd driver ops */ 54*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_open(struct snd_pcm_substream *substream); 55*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_close(struct snd_pcm_substream *substream); 56*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream); 57*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream, 58*c454fd4eSMasakazu Mokuno int cmd); 59*c454fd4eSMasakazu Mokuno static snd_pcm_uframes_t snd_ps3_pcm_pointer(struct snd_pcm_substream 60*c454fd4eSMasakazu Mokuno *substream); 61*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, 62*c454fd4eSMasakazu Mokuno struct snd_pcm_hw_params *hw_params); 63*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream); 64*c454fd4eSMasakazu Mokuno 65*c454fd4eSMasakazu Mokuno 66*c454fd4eSMasakazu Mokuno /* ps3_system_bus_driver entries */ 67*c454fd4eSMasakazu Mokuno static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev); 68*c454fd4eSMasakazu Mokuno static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev); 69*c454fd4eSMasakazu Mokuno 70*c454fd4eSMasakazu Mokuno /* address setup */ 71*c454fd4eSMasakazu Mokuno static int snd_ps3_map_mmio(void); 72*c454fd4eSMasakazu Mokuno static void snd_ps3_unmap_mmio(void); 73*c454fd4eSMasakazu Mokuno static int snd_ps3_allocate_irq(void); 74*c454fd4eSMasakazu Mokuno static void snd_ps3_free_irq(void); 75*c454fd4eSMasakazu Mokuno static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start); 76*c454fd4eSMasakazu Mokuno 77*c454fd4eSMasakazu Mokuno /* interrupt handler */ 78*c454fd4eSMasakazu Mokuno static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id); 79*c454fd4eSMasakazu Mokuno 80*c454fd4eSMasakazu Mokuno 81*c454fd4eSMasakazu Mokuno /* set sampling rate/format */ 82*c454fd4eSMasakazu Mokuno static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream); 83*c454fd4eSMasakazu Mokuno /* take effect parameter change */ 84*c454fd4eSMasakazu Mokuno static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card); 85*c454fd4eSMasakazu Mokuno /* initialize avsetting and take it effect */ 86*c454fd4eSMasakazu Mokuno static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card); 87*c454fd4eSMasakazu Mokuno /* setup dma */ 88*c454fd4eSMasakazu Mokuno static int snd_ps3_program_dma(struct snd_ps3_card_info *card, 89*c454fd4eSMasakazu Mokuno enum snd_ps3_dma_filltype filltype); 90*c454fd4eSMasakazu Mokuno static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card); 91*c454fd4eSMasakazu Mokuno 92*c454fd4eSMasakazu Mokuno static dma_addr_t v_to_bus(struct snd_ps3_card_info *, void *vaddr, int ch); 93*c454fd4eSMasakazu Mokuno 94*c454fd4eSMasakazu Mokuno 95*c454fd4eSMasakazu Mokuno module_init(snd_ps3_init); 96*c454fd4eSMasakazu Mokuno module_exit(snd_ps3_exit); 97*c454fd4eSMasakazu Mokuno 98*c454fd4eSMasakazu Mokuno /* 99*c454fd4eSMasakazu Mokuno * global 100*c454fd4eSMasakazu Mokuno */ 101*c454fd4eSMasakazu Mokuno static struct snd_ps3_card_info the_card; 102*c454fd4eSMasakazu Mokuno 103*c454fd4eSMasakazu Mokuno static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY; 104*c454fd4eSMasakazu Mokuno 105*c454fd4eSMasakazu Mokuno module_param_named(start_delay, snd_ps3_start_delay, uint, 0644); 106*c454fd4eSMasakazu Mokuno MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec"); 107*c454fd4eSMasakazu Mokuno 108*c454fd4eSMasakazu Mokuno static int index = SNDRV_DEFAULT_IDX1; 109*c454fd4eSMasakazu Mokuno static char *id = SNDRV_DEFAULT_STR1; 110*c454fd4eSMasakazu Mokuno 111*c454fd4eSMasakazu Mokuno module_param(index, int, 0444); 112*c454fd4eSMasakazu Mokuno MODULE_PARM_DESC(index, "Index value for PS3 soundchip."); 113*c454fd4eSMasakazu Mokuno module_param(id, charp, 0444); 114*c454fd4eSMasakazu Mokuno MODULE_PARM_DESC(id, "ID string for PS3 soundchip."); 115*c454fd4eSMasakazu Mokuno 116*c454fd4eSMasakazu Mokuno 117*c454fd4eSMasakazu Mokuno /* 118*c454fd4eSMasakazu Mokuno * PS3 audio register access 119*c454fd4eSMasakazu Mokuno */ 120*c454fd4eSMasakazu Mokuno static inline u32 read_reg(unsigned int reg) 121*c454fd4eSMasakazu Mokuno { 122*c454fd4eSMasakazu Mokuno return in_be32(the_card.mapped_mmio_vaddr + reg); 123*c454fd4eSMasakazu Mokuno } 124*c454fd4eSMasakazu Mokuno static inline void write_reg(unsigned int reg, u32 val) 125*c454fd4eSMasakazu Mokuno { 126*c454fd4eSMasakazu Mokuno out_be32(the_card.mapped_mmio_vaddr + reg, val); 127*c454fd4eSMasakazu Mokuno } 128*c454fd4eSMasakazu Mokuno static inline void update_reg(unsigned int reg, u32 or_val) 129*c454fd4eSMasakazu Mokuno { 130*c454fd4eSMasakazu Mokuno u32 newval = read_reg(reg) | or_val; 131*c454fd4eSMasakazu Mokuno write_reg(reg, newval); 132*c454fd4eSMasakazu Mokuno } 133*c454fd4eSMasakazu Mokuno static inline void update_mask_reg(unsigned int reg, u32 mask, u32 or_val) 134*c454fd4eSMasakazu Mokuno { 135*c454fd4eSMasakazu Mokuno u32 newval = (read_reg(reg) & mask) | or_val; 136*c454fd4eSMasakazu Mokuno write_reg(reg, newval); 137*c454fd4eSMasakazu Mokuno } 138*c454fd4eSMasakazu Mokuno 139*c454fd4eSMasakazu Mokuno /* 140*c454fd4eSMasakazu Mokuno * ALSA defs 141*c454fd4eSMasakazu Mokuno */ 142*c454fd4eSMasakazu Mokuno const static struct snd_pcm_hardware snd_ps3_pcm_hw = { 143*c454fd4eSMasakazu Mokuno .info = (SNDRV_PCM_INFO_MMAP | 144*c454fd4eSMasakazu Mokuno SNDRV_PCM_INFO_NONINTERLEAVED | 145*c454fd4eSMasakazu Mokuno SNDRV_PCM_INFO_MMAP_VALID), 146*c454fd4eSMasakazu Mokuno .formats = (SNDRV_PCM_FMTBIT_S16_BE | 147*c454fd4eSMasakazu Mokuno SNDRV_PCM_FMTBIT_S24_BE), 148*c454fd4eSMasakazu Mokuno .rates = (SNDRV_PCM_RATE_44100 | 149*c454fd4eSMasakazu Mokuno SNDRV_PCM_RATE_48000 | 150*c454fd4eSMasakazu Mokuno SNDRV_PCM_RATE_88200 | 151*c454fd4eSMasakazu Mokuno SNDRV_PCM_RATE_96000), 152*c454fd4eSMasakazu Mokuno .rate_min = 44100, 153*c454fd4eSMasakazu Mokuno .rate_max = 96000, 154*c454fd4eSMasakazu Mokuno 155*c454fd4eSMasakazu Mokuno .channels_min = 2, /* stereo only */ 156*c454fd4eSMasakazu Mokuno .channels_max = 2, 157*c454fd4eSMasakazu Mokuno 158*c454fd4eSMasakazu Mokuno .buffer_bytes_max = PS3_AUDIO_FIFO_SIZE * 64, 159*c454fd4eSMasakazu Mokuno 160*c454fd4eSMasakazu Mokuno /* interrupt by four stages */ 161*c454fd4eSMasakazu Mokuno .period_bytes_min = PS3_AUDIO_FIFO_STAGE_SIZE * 4, 162*c454fd4eSMasakazu Mokuno .period_bytes_max = PS3_AUDIO_FIFO_STAGE_SIZE * 4, 163*c454fd4eSMasakazu Mokuno 164*c454fd4eSMasakazu Mokuno .periods_min = 16, 165*c454fd4eSMasakazu Mokuno .periods_max = 32, /* buffer_size_max/ period_bytes_max */ 166*c454fd4eSMasakazu Mokuno 167*c454fd4eSMasakazu Mokuno .fifo_size = PS3_AUDIO_FIFO_SIZE 168*c454fd4eSMasakazu Mokuno }; 169*c454fd4eSMasakazu Mokuno 170*c454fd4eSMasakazu Mokuno static struct snd_pcm_ops snd_ps3_pcm_spdif_ops = 171*c454fd4eSMasakazu Mokuno { 172*c454fd4eSMasakazu Mokuno .open = snd_ps3_pcm_open, 173*c454fd4eSMasakazu Mokuno .close = snd_ps3_pcm_close, 174*c454fd4eSMasakazu Mokuno .prepare = snd_ps3_pcm_prepare, 175*c454fd4eSMasakazu Mokuno .ioctl = snd_pcm_lib_ioctl, 176*c454fd4eSMasakazu Mokuno .trigger = snd_ps3_pcm_trigger, 177*c454fd4eSMasakazu Mokuno .pointer = snd_ps3_pcm_pointer, 178*c454fd4eSMasakazu Mokuno .hw_params = snd_ps3_pcm_hw_params, 179*c454fd4eSMasakazu Mokuno .hw_free = snd_ps3_pcm_hw_free 180*c454fd4eSMasakazu Mokuno }; 181*c454fd4eSMasakazu Mokuno 182*c454fd4eSMasakazu Mokuno static int snd_ps3_verify_dma_stop(struct snd_ps3_card_info *card, 183*c454fd4eSMasakazu Mokuno int count, int force_stop) 184*c454fd4eSMasakazu Mokuno { 185*c454fd4eSMasakazu Mokuno int dma_ch, done, retries, stop_forced = 0; 186*c454fd4eSMasakazu Mokuno uint32_t status; 187*c454fd4eSMasakazu Mokuno 188*c454fd4eSMasakazu Mokuno for (dma_ch = 0; dma_ch < 8; dma_ch ++) { 189*c454fd4eSMasakazu Mokuno retries = count; 190*c454fd4eSMasakazu Mokuno do { 191*c454fd4eSMasakazu Mokuno status = read_reg(PS3_AUDIO_KICK(dma_ch)) & 192*c454fd4eSMasakazu Mokuno PS3_AUDIO_KICK_STATUS_MASK; 193*c454fd4eSMasakazu Mokuno switch (status) { 194*c454fd4eSMasakazu Mokuno case PS3_AUDIO_KICK_STATUS_DONE: 195*c454fd4eSMasakazu Mokuno case PS3_AUDIO_KICK_STATUS_NOTIFY: 196*c454fd4eSMasakazu Mokuno case PS3_AUDIO_KICK_STATUS_CLEAR: 197*c454fd4eSMasakazu Mokuno case PS3_AUDIO_KICK_STATUS_ERROR: 198*c454fd4eSMasakazu Mokuno done = 1; 199*c454fd4eSMasakazu Mokuno break; 200*c454fd4eSMasakazu Mokuno default: 201*c454fd4eSMasakazu Mokuno done = 0; 202*c454fd4eSMasakazu Mokuno udelay(10); 203*c454fd4eSMasakazu Mokuno } 204*c454fd4eSMasakazu Mokuno } while (!done && --retries); 205*c454fd4eSMasakazu Mokuno if (!retries && force_stop) { 206*c454fd4eSMasakazu Mokuno pr_info("%s: DMA ch %d is not stopped.", 207*c454fd4eSMasakazu Mokuno __func__, dma_ch); 208*c454fd4eSMasakazu Mokuno /* last resort. force to stop dma. 209*c454fd4eSMasakazu Mokuno * NOTE: this cause DMA done interrupts 210*c454fd4eSMasakazu Mokuno */ 211*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_CONFIG, PS3_AUDIO_CONFIG_CLEAR); 212*c454fd4eSMasakazu Mokuno stop_forced = 1; 213*c454fd4eSMasakazu Mokuno } 214*c454fd4eSMasakazu Mokuno } 215*c454fd4eSMasakazu Mokuno return stop_forced; 216*c454fd4eSMasakazu Mokuno } 217*c454fd4eSMasakazu Mokuno 218*c454fd4eSMasakazu Mokuno /* 219*c454fd4eSMasakazu Mokuno * wait for all dma is done. 220*c454fd4eSMasakazu Mokuno * NOTE: caller should reset card->running before call. 221*c454fd4eSMasakazu Mokuno * If not, the interrupt handler will re-start DMA, 222*c454fd4eSMasakazu Mokuno * then DMA is never stopped. 223*c454fd4eSMasakazu Mokuno */ 224*c454fd4eSMasakazu Mokuno static void snd_ps3_wait_for_dma_stop(struct snd_ps3_card_info *card) 225*c454fd4eSMasakazu Mokuno { 226*c454fd4eSMasakazu Mokuno int stop_forced; 227*c454fd4eSMasakazu Mokuno /* 228*c454fd4eSMasakazu Mokuno * wait for the last dma is done 229*c454fd4eSMasakazu Mokuno */ 230*c454fd4eSMasakazu Mokuno 231*c454fd4eSMasakazu Mokuno /* 232*c454fd4eSMasakazu Mokuno * expected maximum DMA done time is 5.7ms + something (DMA itself). 233*c454fd4eSMasakazu Mokuno * 5.7ms is from 16bit/sample 2ch 44.1Khz; the time next 234*c454fd4eSMasakazu Mokuno * DMA kick event would occur. 235*c454fd4eSMasakazu Mokuno */ 236*c454fd4eSMasakazu Mokuno stop_forced = snd_ps3_verify_dma_stop(card, 700, 1); 237*c454fd4eSMasakazu Mokuno 238*c454fd4eSMasakazu Mokuno /* 239*c454fd4eSMasakazu Mokuno * clear outstanding interrupts. 240*c454fd4eSMasakazu Mokuno */ 241*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_INTR_0, 0); 242*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_AX_IS, 0); 243*c454fd4eSMasakazu Mokuno 244*c454fd4eSMasakazu Mokuno /* 245*c454fd4eSMasakazu Mokuno *revert CLEAR bit since it will not reset automatically after DMA stop 246*c454fd4eSMasakazu Mokuno */ 247*c454fd4eSMasakazu Mokuno if (stop_forced) 248*c454fd4eSMasakazu Mokuno update_mask_reg(PS3_AUDIO_CONFIG, ~PS3_AUDIO_CONFIG_CLEAR, 0); 249*c454fd4eSMasakazu Mokuno /* ensure the hardware sees changes */ 250*c454fd4eSMasakazu Mokuno wmb(); 251*c454fd4eSMasakazu Mokuno } 252*c454fd4eSMasakazu Mokuno 253*c454fd4eSMasakazu Mokuno static void snd_ps3_kick_dma(struct snd_ps3_card_info *card) 254*c454fd4eSMasakazu Mokuno { 255*c454fd4eSMasakazu Mokuno 256*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_KICK(0), PS3_AUDIO_KICK_REQUEST); 257*c454fd4eSMasakazu Mokuno /* ensure the hardware sees the change */ 258*c454fd4eSMasakazu Mokuno wmb(); 259*c454fd4eSMasakazu Mokuno } 260*c454fd4eSMasakazu Mokuno 261*c454fd4eSMasakazu Mokuno /* 262*c454fd4eSMasakazu Mokuno * convert virtual addr to ioif bus addr. 263*c454fd4eSMasakazu Mokuno */ 264*c454fd4eSMasakazu Mokuno static dma_addr_t v_to_bus(struct snd_ps3_card_info *card, 265*c454fd4eSMasakazu Mokuno void * paddr, 266*c454fd4eSMasakazu Mokuno int ch) 267*c454fd4eSMasakazu Mokuno { 268*c454fd4eSMasakazu Mokuno return card->dma_start_bus_addr[ch] + 269*c454fd4eSMasakazu Mokuno (paddr - card->dma_start_vaddr[ch]); 270*c454fd4eSMasakazu Mokuno }; 271*c454fd4eSMasakazu Mokuno 272*c454fd4eSMasakazu Mokuno 273*c454fd4eSMasakazu Mokuno /* 274*c454fd4eSMasakazu Mokuno * increment ring buffer pointer. 275*c454fd4eSMasakazu Mokuno * NOTE: caller must hold write spinlock 276*c454fd4eSMasakazu Mokuno */ 277*c454fd4eSMasakazu Mokuno static void snd_ps3_bump_buffer(struct snd_ps3_card_info *card, 278*c454fd4eSMasakazu Mokuno enum snd_ps3_ch ch, size_t byte_count, 279*c454fd4eSMasakazu Mokuno int stage) 280*c454fd4eSMasakazu Mokuno { 281*c454fd4eSMasakazu Mokuno if (!stage) 282*c454fd4eSMasakazu Mokuno card->dma_last_transfer_vaddr[ch] = 283*c454fd4eSMasakazu Mokuno card->dma_next_transfer_vaddr[ch]; 284*c454fd4eSMasakazu Mokuno card->dma_next_transfer_vaddr[ch] += byte_count; 285*c454fd4eSMasakazu Mokuno if ((card->dma_start_vaddr[ch] + (card->dma_buffer_size / 2)) <= 286*c454fd4eSMasakazu Mokuno card->dma_next_transfer_vaddr[ch]) { 287*c454fd4eSMasakazu Mokuno card->dma_next_transfer_vaddr[ch] = card->dma_start_vaddr[ch]; 288*c454fd4eSMasakazu Mokuno } 289*c454fd4eSMasakazu Mokuno } 290*c454fd4eSMasakazu Mokuno /* 291*c454fd4eSMasakazu Mokuno * setup dmac to send data to audio and attenuate samples on the ring buffer 292*c454fd4eSMasakazu Mokuno */ 293*c454fd4eSMasakazu Mokuno static int snd_ps3_program_dma(struct snd_ps3_card_info *card, 294*c454fd4eSMasakazu Mokuno enum snd_ps3_dma_filltype filltype) 295*c454fd4eSMasakazu Mokuno { 296*c454fd4eSMasakazu Mokuno /* this dmac does not support over 4G */ 297*c454fd4eSMasakazu Mokuno uint32_t dma_addr; 298*c454fd4eSMasakazu Mokuno int fill_stages, dma_ch, stage; 299*c454fd4eSMasakazu Mokuno enum snd_ps3_ch ch; 300*c454fd4eSMasakazu Mokuno uint32_t ch0_kick_event = 0; /* initialize to mute gcc */ 301*c454fd4eSMasakazu Mokuno void *start_vaddr; 302*c454fd4eSMasakazu Mokuno unsigned long irqsave; 303*c454fd4eSMasakazu Mokuno int silent = 0; 304*c454fd4eSMasakazu Mokuno 305*c454fd4eSMasakazu Mokuno switch (filltype) { 306*c454fd4eSMasakazu Mokuno case SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL: 307*c454fd4eSMasakazu Mokuno silent = 1; 308*c454fd4eSMasakazu Mokuno /* intentionally fall thru */ 309*c454fd4eSMasakazu Mokuno case SND_PS3_DMA_FILLTYPE_FIRSTFILL: 310*c454fd4eSMasakazu Mokuno ch0_kick_event = PS3_AUDIO_KICK_EVENT_ALWAYS; 311*c454fd4eSMasakazu Mokuno break; 312*c454fd4eSMasakazu Mokuno 313*c454fd4eSMasakazu Mokuno case SND_PS3_DMA_FILLTYPE_SILENT_RUNNING: 314*c454fd4eSMasakazu Mokuno silent = 1; 315*c454fd4eSMasakazu Mokuno /* intentionally fall thru */ 316*c454fd4eSMasakazu Mokuno case SND_PS3_DMA_FILLTYPE_RUNNING: 317*c454fd4eSMasakazu Mokuno ch0_kick_event = PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY; 318*c454fd4eSMasakazu Mokuno break; 319*c454fd4eSMasakazu Mokuno } 320*c454fd4eSMasakazu Mokuno 321*c454fd4eSMasakazu Mokuno snd_ps3_verify_dma_stop(card, 700, 0); 322*c454fd4eSMasakazu Mokuno fill_stages = 4; 323*c454fd4eSMasakazu Mokuno spin_lock_irqsave(&card->dma_lock, irqsave); 324*c454fd4eSMasakazu Mokuno for (ch = 0; ch < 2; ch++) { 325*c454fd4eSMasakazu Mokuno start_vaddr = card->dma_next_transfer_vaddr[0]; 326*c454fd4eSMasakazu Mokuno for (stage = 0; stage < fill_stages; stage ++) { 327*c454fd4eSMasakazu Mokuno dma_ch = stage * 2 + ch; 328*c454fd4eSMasakazu Mokuno if (silent) 329*c454fd4eSMasakazu Mokuno dma_addr = card->null_buffer_start_dma_addr; 330*c454fd4eSMasakazu Mokuno else 331*c454fd4eSMasakazu Mokuno dma_addr = 332*c454fd4eSMasakazu Mokuno v_to_bus(card, 333*c454fd4eSMasakazu Mokuno card->dma_next_transfer_vaddr[ch], 334*c454fd4eSMasakazu Mokuno ch); 335*c454fd4eSMasakazu Mokuno 336*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_SOURCE(dma_ch), 337*c454fd4eSMasakazu Mokuno (PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY | 338*c454fd4eSMasakazu Mokuno dma_addr)); 339*c454fd4eSMasakazu Mokuno 340*c454fd4eSMasakazu Mokuno /* dst: fixed to 3wire#0 */ 341*c454fd4eSMasakazu Mokuno if (ch == 0) 342*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_DEST(dma_ch), 343*c454fd4eSMasakazu Mokuno (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | 344*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3W_LDATA(0))); 345*c454fd4eSMasakazu Mokuno else 346*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_DEST(dma_ch), 347*c454fd4eSMasakazu Mokuno (PS3_AUDIO_DEST_TARGET_AUDIOFIFO | 348*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3W_RDATA(0))); 349*c454fd4eSMasakazu Mokuno 350*c454fd4eSMasakazu Mokuno /* count always 1 DMA block (1/2 stage = 128 bytes) */ 351*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_DMASIZE(dma_ch), 0); 352*c454fd4eSMasakazu Mokuno /* bump pointer if needed */ 353*c454fd4eSMasakazu Mokuno if (!silent) 354*c454fd4eSMasakazu Mokuno snd_ps3_bump_buffer(card, ch, 355*c454fd4eSMasakazu Mokuno PS3_AUDIO_DMAC_BLOCK_SIZE, 356*c454fd4eSMasakazu Mokuno stage); 357*c454fd4eSMasakazu Mokuno 358*c454fd4eSMasakazu Mokuno /* kick event */ 359*c454fd4eSMasakazu Mokuno if (dma_ch == 0) 360*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_KICK(dma_ch), 361*c454fd4eSMasakazu Mokuno ch0_kick_event); 362*c454fd4eSMasakazu Mokuno else 363*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_KICK(dma_ch), 364*c454fd4eSMasakazu Mokuno PS3_AUDIO_KICK_EVENT_AUDIO_DMA(dma_ch 365*c454fd4eSMasakazu Mokuno - 1) | 366*c454fd4eSMasakazu Mokuno PS3_AUDIO_KICK_REQUEST); 367*c454fd4eSMasakazu Mokuno } 368*c454fd4eSMasakazu Mokuno } 369*c454fd4eSMasakazu Mokuno /* ensure the hardware sees the change */ 370*c454fd4eSMasakazu Mokuno wmb(); 371*c454fd4eSMasakazu Mokuno spin_unlock_irqrestore(&card->dma_lock, irqsave); 372*c454fd4eSMasakazu Mokuno 373*c454fd4eSMasakazu Mokuno return 0; 374*c454fd4eSMasakazu Mokuno } 375*c454fd4eSMasakazu Mokuno 376*c454fd4eSMasakazu Mokuno /* 377*c454fd4eSMasakazu Mokuno * audio mute on/off 378*c454fd4eSMasakazu Mokuno * mute_on : 0 output enabled 379*c454fd4eSMasakazu Mokuno * 1 mute 380*c454fd4eSMasakazu Mokuno */ 381*c454fd4eSMasakazu Mokuno static int snd_ps3_mute(int mute_on) 382*c454fd4eSMasakazu Mokuno { 383*c454fd4eSMasakazu Mokuno return ps3av_audio_mute(mute_on); 384*c454fd4eSMasakazu Mokuno } 385*c454fd4eSMasakazu Mokuno 386*c454fd4eSMasakazu Mokuno /* 387*c454fd4eSMasakazu Mokuno * PCM operators 388*c454fd4eSMasakazu Mokuno */ 389*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_open(struct snd_pcm_substream *substream) 390*c454fd4eSMasakazu Mokuno { 391*c454fd4eSMasakazu Mokuno struct snd_pcm_runtime *runtime = substream->runtime; 392*c454fd4eSMasakazu Mokuno struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); 393*c454fd4eSMasakazu Mokuno int pcm_index; 394*c454fd4eSMasakazu Mokuno 395*c454fd4eSMasakazu Mokuno pcm_index = substream->pcm->device; 396*c454fd4eSMasakazu Mokuno /* to retrieve substream/runtime in interrupt handler */ 397*c454fd4eSMasakazu Mokuno card->substream = substream; 398*c454fd4eSMasakazu Mokuno 399*c454fd4eSMasakazu Mokuno runtime->hw = snd_ps3_pcm_hw; 400*c454fd4eSMasakazu Mokuno 401*c454fd4eSMasakazu Mokuno card->start_delay = snd_ps3_start_delay; 402*c454fd4eSMasakazu Mokuno 403*c454fd4eSMasakazu Mokuno /* mute off */ 404*c454fd4eSMasakazu Mokuno snd_ps3_mute(0); /* this function sleep */ 405*c454fd4eSMasakazu Mokuno 406*c454fd4eSMasakazu Mokuno snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 407*c454fd4eSMasakazu Mokuno PS3_AUDIO_FIFO_STAGE_SIZE * 4 * 2); 408*c454fd4eSMasakazu Mokuno return 0; 409*c454fd4eSMasakazu Mokuno }; 410*c454fd4eSMasakazu Mokuno 411*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_hw_params(struct snd_pcm_substream *substream, 412*c454fd4eSMasakazu Mokuno struct snd_pcm_hw_params *hw_params) 413*c454fd4eSMasakazu Mokuno { 414*c454fd4eSMasakazu Mokuno size_t size; 415*c454fd4eSMasakazu Mokuno 416*c454fd4eSMasakazu Mokuno /* alloc transport buffer */ 417*c454fd4eSMasakazu Mokuno size = params_buffer_bytes(hw_params); 418*c454fd4eSMasakazu Mokuno snd_pcm_lib_malloc_pages(substream, size); 419*c454fd4eSMasakazu Mokuno return 0; 420*c454fd4eSMasakazu Mokuno }; 421*c454fd4eSMasakazu Mokuno 422*c454fd4eSMasakazu Mokuno static int snd_ps3_delay_to_bytes(struct snd_pcm_substream *substream, 423*c454fd4eSMasakazu Mokuno unsigned int delay_ms) 424*c454fd4eSMasakazu Mokuno { 425*c454fd4eSMasakazu Mokuno int ret; 426*c454fd4eSMasakazu Mokuno int rate ; 427*c454fd4eSMasakazu Mokuno 428*c454fd4eSMasakazu Mokuno rate = substream->runtime->rate; 429*c454fd4eSMasakazu Mokuno ret = snd_pcm_format_size(substream->runtime->format, 430*c454fd4eSMasakazu Mokuno rate * delay_ms / 1000) 431*c454fd4eSMasakazu Mokuno * substream->runtime->channels; 432*c454fd4eSMasakazu Mokuno 433*c454fd4eSMasakazu Mokuno pr_debug(KERN_ERR "%s: time=%d rate=%d bytes=%ld, frames=%d, ret=%d\n", 434*c454fd4eSMasakazu Mokuno __func__, 435*c454fd4eSMasakazu Mokuno delay_ms, 436*c454fd4eSMasakazu Mokuno rate, 437*c454fd4eSMasakazu Mokuno snd_pcm_format_size(substream->runtime->format, rate), 438*c454fd4eSMasakazu Mokuno rate * delay_ms / 1000, 439*c454fd4eSMasakazu Mokuno ret); 440*c454fd4eSMasakazu Mokuno 441*c454fd4eSMasakazu Mokuno return ret; 442*c454fd4eSMasakazu Mokuno }; 443*c454fd4eSMasakazu Mokuno 444*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_prepare(struct snd_pcm_substream *substream) 445*c454fd4eSMasakazu Mokuno { 446*c454fd4eSMasakazu Mokuno struct snd_pcm_runtime *runtime = substream->runtime; 447*c454fd4eSMasakazu Mokuno struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); 448*c454fd4eSMasakazu Mokuno unsigned long irqsave; 449*c454fd4eSMasakazu Mokuno 450*c454fd4eSMasakazu Mokuno if (!snd_ps3_set_avsetting(substream)) { 451*c454fd4eSMasakazu Mokuno /* some parameter changed */ 452*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_AX_IE, 453*c454fd4eSMasakazu Mokuno PS3_AUDIO_AX_IE_ASOBEIE(0) | 454*c454fd4eSMasakazu Mokuno PS3_AUDIO_AX_IE_ASOBUIE(0)); 455*c454fd4eSMasakazu Mokuno /* 456*c454fd4eSMasakazu Mokuno * let SPDIF device re-lock with SPDIF signal, 457*c454fd4eSMasakazu Mokuno * start with some silence 458*c454fd4eSMasakazu Mokuno */ 459*c454fd4eSMasakazu Mokuno card->silent = snd_ps3_delay_to_bytes(substream, 460*c454fd4eSMasakazu Mokuno card->start_delay) / 461*c454fd4eSMasakazu Mokuno (PS3_AUDIO_FIFO_STAGE_SIZE * 4); /* every 4 times */ 462*c454fd4eSMasakazu Mokuno } 463*c454fd4eSMasakazu Mokuno 464*c454fd4eSMasakazu Mokuno /* restart ring buffer pointer */ 465*c454fd4eSMasakazu Mokuno spin_lock_irqsave(&card->dma_lock, irqsave); 466*c454fd4eSMasakazu Mokuno { 467*c454fd4eSMasakazu Mokuno card->dma_buffer_size = runtime->dma_bytes; 468*c454fd4eSMasakazu Mokuno 469*c454fd4eSMasakazu Mokuno card->dma_last_transfer_vaddr[SND_PS3_CH_L] = 470*c454fd4eSMasakazu Mokuno card->dma_next_transfer_vaddr[SND_PS3_CH_L] = 471*c454fd4eSMasakazu Mokuno card->dma_start_vaddr[SND_PS3_CH_L] = 472*c454fd4eSMasakazu Mokuno runtime->dma_area; 473*c454fd4eSMasakazu Mokuno card->dma_start_bus_addr[SND_PS3_CH_L] = runtime->dma_addr; 474*c454fd4eSMasakazu Mokuno 475*c454fd4eSMasakazu Mokuno card->dma_last_transfer_vaddr[SND_PS3_CH_R] = 476*c454fd4eSMasakazu Mokuno card->dma_next_transfer_vaddr[SND_PS3_CH_R] = 477*c454fd4eSMasakazu Mokuno card->dma_start_vaddr[SND_PS3_CH_R] = 478*c454fd4eSMasakazu Mokuno runtime->dma_area + (runtime->dma_bytes / 2); 479*c454fd4eSMasakazu Mokuno card->dma_start_bus_addr[SND_PS3_CH_R] = 480*c454fd4eSMasakazu Mokuno runtime->dma_addr + (runtime->dma_bytes / 2); 481*c454fd4eSMasakazu Mokuno 482*c454fd4eSMasakazu Mokuno pr_debug("%s: vaddr=%p bus=%#lx\n", __func__, 483*c454fd4eSMasakazu Mokuno card->dma_start_vaddr[SND_PS3_CH_L], 484*c454fd4eSMasakazu Mokuno card->dma_start_bus_addr[SND_PS3_CH_L]); 485*c454fd4eSMasakazu Mokuno 486*c454fd4eSMasakazu Mokuno } 487*c454fd4eSMasakazu Mokuno spin_unlock_irqrestore(&card->dma_lock, irqsave); 488*c454fd4eSMasakazu Mokuno 489*c454fd4eSMasakazu Mokuno /* ensure the hardware sees the change */ 490*c454fd4eSMasakazu Mokuno mb(); 491*c454fd4eSMasakazu Mokuno 492*c454fd4eSMasakazu Mokuno return 0; 493*c454fd4eSMasakazu Mokuno }; 494*c454fd4eSMasakazu Mokuno 495*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_trigger(struct snd_pcm_substream *substream, 496*c454fd4eSMasakazu Mokuno int cmd) 497*c454fd4eSMasakazu Mokuno { 498*c454fd4eSMasakazu Mokuno struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); 499*c454fd4eSMasakazu Mokuno int ret = 0; 500*c454fd4eSMasakazu Mokuno 501*c454fd4eSMasakazu Mokuno switch (cmd) { 502*c454fd4eSMasakazu Mokuno case SNDRV_PCM_TRIGGER_START: 503*c454fd4eSMasakazu Mokuno /* clear outstanding interrupts */ 504*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_AX_IS, 0); 505*c454fd4eSMasakazu Mokuno 506*c454fd4eSMasakazu Mokuno spin_lock(&card->dma_lock); 507*c454fd4eSMasakazu Mokuno { 508*c454fd4eSMasakazu Mokuno card->running = 1; 509*c454fd4eSMasakazu Mokuno } 510*c454fd4eSMasakazu Mokuno spin_unlock(&card->dma_lock); 511*c454fd4eSMasakazu Mokuno 512*c454fd4eSMasakazu Mokuno snd_ps3_program_dma(card, 513*c454fd4eSMasakazu Mokuno SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); 514*c454fd4eSMasakazu Mokuno snd_ps3_kick_dma(card); 515*c454fd4eSMasakazu Mokuno while (read_reg(PS3_AUDIO_KICK(7)) & 516*c454fd4eSMasakazu Mokuno PS3_AUDIO_KICK_STATUS_MASK) { 517*c454fd4eSMasakazu Mokuno udelay(1); 518*c454fd4eSMasakazu Mokuno } 519*c454fd4eSMasakazu Mokuno snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); 520*c454fd4eSMasakazu Mokuno snd_ps3_kick_dma(card); 521*c454fd4eSMasakazu Mokuno break; 522*c454fd4eSMasakazu Mokuno 523*c454fd4eSMasakazu Mokuno case SNDRV_PCM_TRIGGER_STOP: 524*c454fd4eSMasakazu Mokuno spin_lock(&card->dma_lock); 525*c454fd4eSMasakazu Mokuno { 526*c454fd4eSMasakazu Mokuno card->running = 0; 527*c454fd4eSMasakazu Mokuno } 528*c454fd4eSMasakazu Mokuno spin_unlock(&card->dma_lock); 529*c454fd4eSMasakazu Mokuno snd_ps3_wait_for_dma_stop(card); 530*c454fd4eSMasakazu Mokuno break; 531*c454fd4eSMasakazu Mokuno default: 532*c454fd4eSMasakazu Mokuno break; 533*c454fd4eSMasakazu Mokuno 534*c454fd4eSMasakazu Mokuno } 535*c454fd4eSMasakazu Mokuno 536*c454fd4eSMasakazu Mokuno return ret; 537*c454fd4eSMasakazu Mokuno }; 538*c454fd4eSMasakazu Mokuno 539*c454fd4eSMasakazu Mokuno /* 540*c454fd4eSMasakazu Mokuno * report current pointer 541*c454fd4eSMasakazu Mokuno */ 542*c454fd4eSMasakazu Mokuno static snd_pcm_uframes_t snd_ps3_pcm_pointer( 543*c454fd4eSMasakazu Mokuno struct snd_pcm_substream *substream) 544*c454fd4eSMasakazu Mokuno { 545*c454fd4eSMasakazu Mokuno struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); 546*c454fd4eSMasakazu Mokuno size_t bytes; 547*c454fd4eSMasakazu Mokuno snd_pcm_uframes_t ret; 548*c454fd4eSMasakazu Mokuno 549*c454fd4eSMasakazu Mokuno spin_lock(&card->dma_lock); 550*c454fd4eSMasakazu Mokuno { 551*c454fd4eSMasakazu Mokuno bytes = (size_t)(card->dma_last_transfer_vaddr[SND_PS3_CH_L] - 552*c454fd4eSMasakazu Mokuno card->dma_start_vaddr[SND_PS3_CH_L]); 553*c454fd4eSMasakazu Mokuno } 554*c454fd4eSMasakazu Mokuno spin_unlock(&card->dma_lock); 555*c454fd4eSMasakazu Mokuno 556*c454fd4eSMasakazu Mokuno ret = bytes_to_frames(substream->runtime, bytes * 2); 557*c454fd4eSMasakazu Mokuno 558*c454fd4eSMasakazu Mokuno return ret; 559*c454fd4eSMasakazu Mokuno }; 560*c454fd4eSMasakazu Mokuno 561*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_hw_free(struct snd_pcm_substream *substream) 562*c454fd4eSMasakazu Mokuno { 563*c454fd4eSMasakazu Mokuno int ret; 564*c454fd4eSMasakazu Mokuno ret = snd_pcm_lib_free_pages(substream); 565*c454fd4eSMasakazu Mokuno return ret; 566*c454fd4eSMasakazu Mokuno }; 567*c454fd4eSMasakazu Mokuno 568*c454fd4eSMasakazu Mokuno static int snd_ps3_pcm_close(struct snd_pcm_substream *substream) 569*c454fd4eSMasakazu Mokuno { 570*c454fd4eSMasakazu Mokuno /* mute on */ 571*c454fd4eSMasakazu Mokuno snd_ps3_mute(1); 572*c454fd4eSMasakazu Mokuno return 0; 573*c454fd4eSMasakazu Mokuno }; 574*c454fd4eSMasakazu Mokuno 575*c454fd4eSMasakazu Mokuno static void snd_ps3_audio_fixup(struct snd_ps3_card_info *card) 576*c454fd4eSMasakazu Mokuno { 577*c454fd4eSMasakazu Mokuno /* 578*c454fd4eSMasakazu Mokuno * avsetting driver seems to never change the followings 579*c454fd4eSMasakazu Mokuno * so, init them here once 580*c454fd4eSMasakazu Mokuno */ 581*c454fd4eSMasakazu Mokuno 582*c454fd4eSMasakazu Mokuno /* no dma interrupt needed */ 583*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_INTR_EN_0, 0); 584*c454fd4eSMasakazu Mokuno 585*c454fd4eSMasakazu Mokuno /* use every 4 buffer empty interrupt */ 586*c454fd4eSMasakazu Mokuno update_mask_reg(PS3_AUDIO_AX_IC, 587*c454fd4eSMasakazu Mokuno PS3_AUDIO_AX_IC_AASOIMD_MASK, 588*c454fd4eSMasakazu Mokuno PS3_AUDIO_AX_IC_AASOIMD_EVERY4); 589*c454fd4eSMasakazu Mokuno 590*c454fd4eSMasakazu Mokuno /* enable 3wire clocks */ 591*c454fd4eSMasakazu Mokuno update_mask_reg(PS3_AUDIO_AO_3WMCTRL, 592*c454fd4eSMasakazu Mokuno ~(PS3_AUDIO_AO_3WMCTRL_ASOBCLKD_DISABLED | 593*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WMCTRL_ASOLRCKD_DISABLED), 594*c454fd4eSMasakazu Mokuno 0); 595*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_AO_3WMCTRL, 596*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WMCTRL_ASOPLRCK_DEFAULT); 597*c454fd4eSMasakazu Mokuno } 598*c454fd4eSMasakazu Mokuno 599*c454fd4eSMasakazu Mokuno /* 600*c454fd4eSMasakazu Mokuno * av setting 601*c454fd4eSMasakazu Mokuno * NOTE: calling this function may generate audio interrupt. 602*c454fd4eSMasakazu Mokuno */ 603*c454fd4eSMasakazu Mokuno static int snd_ps3_change_avsetting(struct snd_ps3_card_info *card) 604*c454fd4eSMasakazu Mokuno { 605*c454fd4eSMasakazu Mokuno int ret, retries, i; 606*c454fd4eSMasakazu Mokuno pr_debug("%s: start\n", __func__); 607*c454fd4eSMasakazu Mokuno 608*c454fd4eSMasakazu Mokuno ret = ps3av_set_audio_mode(card->avs.avs_audio_ch, 609*c454fd4eSMasakazu Mokuno card->avs.avs_audio_rate, 610*c454fd4eSMasakazu Mokuno card->avs.avs_audio_width, 611*c454fd4eSMasakazu Mokuno card->avs.avs_audio_format, 612*c454fd4eSMasakazu Mokuno card->avs.avs_audio_source); 613*c454fd4eSMasakazu Mokuno /* 614*c454fd4eSMasakazu Mokuno * Reset the following unwanted settings: 615*c454fd4eSMasakazu Mokuno */ 616*c454fd4eSMasakazu Mokuno 617*c454fd4eSMasakazu Mokuno /* disable all 3wire buffers */ 618*c454fd4eSMasakazu Mokuno update_mask_reg(PS3_AUDIO_AO_3WMCTRL, 619*c454fd4eSMasakazu Mokuno ~(PS3_AUDIO_AO_3WMCTRL_ASOEN(0) | 620*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WMCTRL_ASOEN(1) | 621*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WMCTRL_ASOEN(2) | 622*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WMCTRL_ASOEN(3)), 623*c454fd4eSMasakazu Mokuno 0); 624*c454fd4eSMasakazu Mokuno wmb(); /* ensure the hardware sees the change */ 625*c454fd4eSMasakazu Mokuno /* wait for actually stopped */ 626*c454fd4eSMasakazu Mokuno retries = 1000; 627*c454fd4eSMasakazu Mokuno while ((read_reg(PS3_AUDIO_AO_3WMCTRL) & 628*c454fd4eSMasakazu Mokuno (PS3_AUDIO_AO_3WMCTRL_ASORUN(0) | 629*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WMCTRL_ASORUN(1) | 630*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WMCTRL_ASORUN(2) | 631*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WMCTRL_ASORUN(3))) && 632*c454fd4eSMasakazu Mokuno --retries) { 633*c454fd4eSMasakazu Mokuno udelay(1); 634*c454fd4eSMasakazu Mokuno } 635*c454fd4eSMasakazu Mokuno 636*c454fd4eSMasakazu Mokuno /* reset buffer pointer */ 637*c454fd4eSMasakazu Mokuno for (i = 0; i < 4; i++) { 638*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_AO_3WCTRL(i), 639*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WCTRL_ASOBRST_RESET); 640*c454fd4eSMasakazu Mokuno udelay(10); 641*c454fd4eSMasakazu Mokuno } 642*c454fd4eSMasakazu Mokuno wmb(); /* ensure the hardware actually start resetting */ 643*c454fd4eSMasakazu Mokuno 644*c454fd4eSMasakazu Mokuno /* enable 3wire#0 buffer */ 645*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_AO_3WMCTRL, PS3_AUDIO_AO_3WMCTRL_ASOEN(0)); 646*c454fd4eSMasakazu Mokuno 647*c454fd4eSMasakazu Mokuno 648*c454fd4eSMasakazu Mokuno /* In 24bit mode,ALSA inserts a zero byte at first byte of per sample */ 649*c454fd4eSMasakazu Mokuno update_mask_reg(PS3_AUDIO_AO_3WCTRL(0), 650*c454fd4eSMasakazu Mokuno ~PS3_AUDIO_AO_3WCTRL_ASODF, 651*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_3WCTRL_ASODF_LSB); 652*c454fd4eSMasakazu Mokuno update_mask_reg(PS3_AUDIO_AO_SPDCTRL(0), 653*c454fd4eSMasakazu Mokuno ~PS3_AUDIO_AO_SPDCTRL_SPODF, 654*c454fd4eSMasakazu Mokuno PS3_AUDIO_AO_SPDCTRL_SPODF_LSB); 655*c454fd4eSMasakazu Mokuno /* ensure all the setting above is written back to register */ 656*c454fd4eSMasakazu Mokuno wmb(); 657*c454fd4eSMasakazu Mokuno /* avsetting driver altered AX_IE, caller must reset it if you want */ 658*c454fd4eSMasakazu Mokuno pr_debug("%s: end\n", __func__); 659*c454fd4eSMasakazu Mokuno return ret; 660*c454fd4eSMasakazu Mokuno } 661*c454fd4eSMasakazu Mokuno 662*c454fd4eSMasakazu Mokuno static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card) 663*c454fd4eSMasakazu Mokuno { 664*c454fd4eSMasakazu Mokuno int ret; 665*c454fd4eSMasakazu Mokuno pr_debug("%s: start\n", __func__); 666*c454fd4eSMasakazu Mokuno card->avs.avs_audio_ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2; 667*c454fd4eSMasakazu Mokuno card->avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; 668*c454fd4eSMasakazu Mokuno card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; 669*c454fd4eSMasakazu Mokuno card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM; 670*c454fd4eSMasakazu Mokuno card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; 671*c454fd4eSMasakazu Mokuno 672*c454fd4eSMasakazu Mokuno ret = snd_ps3_change_avsetting(card); 673*c454fd4eSMasakazu Mokuno 674*c454fd4eSMasakazu Mokuno snd_ps3_audio_fixup(card); 675*c454fd4eSMasakazu Mokuno 676*c454fd4eSMasakazu Mokuno /* to start to generate SPDIF signal, fill data */ 677*c454fd4eSMasakazu Mokuno snd_ps3_program_dma(card, SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); 678*c454fd4eSMasakazu Mokuno snd_ps3_kick_dma(card); 679*c454fd4eSMasakazu Mokuno pr_debug("%s: end\n", __func__); 680*c454fd4eSMasakazu Mokuno return ret; 681*c454fd4eSMasakazu Mokuno } 682*c454fd4eSMasakazu Mokuno 683*c454fd4eSMasakazu Mokuno /* 684*c454fd4eSMasakazu Mokuno * set sampling rate according to the substream 685*c454fd4eSMasakazu Mokuno */ 686*c454fd4eSMasakazu Mokuno static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream) 687*c454fd4eSMasakazu Mokuno { 688*c454fd4eSMasakazu Mokuno struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); 689*c454fd4eSMasakazu Mokuno struct snd_ps3_avsetting_info avs; 690*c454fd4eSMasakazu Mokuno 691*c454fd4eSMasakazu Mokuno avs = card->avs; 692*c454fd4eSMasakazu Mokuno 693*c454fd4eSMasakazu Mokuno pr_debug("%s: called freq=%d width=%d\n", __func__, 694*c454fd4eSMasakazu Mokuno substream->runtime->rate, 695*c454fd4eSMasakazu Mokuno snd_pcm_format_width(substream->runtime->format)); 696*c454fd4eSMasakazu Mokuno 697*c454fd4eSMasakazu Mokuno pr_debug("%s: before freq=%d width=%d\n", __func__, 698*c454fd4eSMasakazu Mokuno card->avs.avs_audio_rate, card->avs.avs_audio_width); 699*c454fd4eSMasakazu Mokuno 700*c454fd4eSMasakazu Mokuno /* sample rate */ 701*c454fd4eSMasakazu Mokuno switch (substream->runtime->rate) { 702*c454fd4eSMasakazu Mokuno case 44100: 703*c454fd4eSMasakazu Mokuno avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_44K; 704*c454fd4eSMasakazu Mokuno break; 705*c454fd4eSMasakazu Mokuno case 48000: 706*c454fd4eSMasakazu Mokuno avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_48K; 707*c454fd4eSMasakazu Mokuno break; 708*c454fd4eSMasakazu Mokuno case 88200: 709*c454fd4eSMasakazu Mokuno avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_88K; 710*c454fd4eSMasakazu Mokuno break; 711*c454fd4eSMasakazu Mokuno case 96000: 712*c454fd4eSMasakazu Mokuno avs.avs_audio_rate = PS3AV_CMD_AUDIO_FS_96K; 713*c454fd4eSMasakazu Mokuno break; 714*c454fd4eSMasakazu Mokuno default: 715*c454fd4eSMasakazu Mokuno pr_info("%s: invalid rate %d\n", __func__, 716*c454fd4eSMasakazu Mokuno substream->runtime->rate); 717*c454fd4eSMasakazu Mokuno return 1; 718*c454fd4eSMasakazu Mokuno } 719*c454fd4eSMasakazu Mokuno 720*c454fd4eSMasakazu Mokuno /* width */ 721*c454fd4eSMasakazu Mokuno switch (snd_pcm_format_width(substream->runtime->format)) { 722*c454fd4eSMasakazu Mokuno case 16: 723*c454fd4eSMasakazu Mokuno avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; 724*c454fd4eSMasakazu Mokuno break; 725*c454fd4eSMasakazu Mokuno case 24: 726*c454fd4eSMasakazu Mokuno avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_24; 727*c454fd4eSMasakazu Mokuno break; 728*c454fd4eSMasakazu Mokuno default: 729*c454fd4eSMasakazu Mokuno pr_info("%s: invalid width %d\n", __func__, 730*c454fd4eSMasakazu Mokuno snd_pcm_format_width(substream->runtime->format)); 731*c454fd4eSMasakazu Mokuno return 1; 732*c454fd4eSMasakazu Mokuno } 733*c454fd4eSMasakazu Mokuno 734*c454fd4eSMasakazu Mokuno if ((card->avs.avs_audio_width != avs.avs_audio_width) || 735*c454fd4eSMasakazu Mokuno (card->avs.avs_audio_rate != avs.avs_audio_rate)) { 736*c454fd4eSMasakazu Mokuno card->avs = avs; 737*c454fd4eSMasakazu Mokuno snd_ps3_change_avsetting(card); 738*c454fd4eSMasakazu Mokuno 739*c454fd4eSMasakazu Mokuno pr_debug("%s: after freq=%d width=%d\n", __func__, 740*c454fd4eSMasakazu Mokuno card->avs.avs_audio_rate, card->avs.avs_audio_width); 741*c454fd4eSMasakazu Mokuno 742*c454fd4eSMasakazu Mokuno return 0; 743*c454fd4eSMasakazu Mokuno } else 744*c454fd4eSMasakazu Mokuno return 1; 745*c454fd4eSMasakazu Mokuno } 746*c454fd4eSMasakazu Mokuno 747*c454fd4eSMasakazu Mokuno 748*c454fd4eSMasakazu Mokuno 749*c454fd4eSMasakazu Mokuno static int snd_ps3_map_mmio(void) 750*c454fd4eSMasakazu Mokuno { 751*c454fd4eSMasakazu Mokuno the_card.mapped_mmio_vaddr = 752*c454fd4eSMasakazu Mokuno ioremap(the_card.ps3_dev->m_region->bus_addr, 753*c454fd4eSMasakazu Mokuno the_card.ps3_dev->m_region->len); 754*c454fd4eSMasakazu Mokuno 755*c454fd4eSMasakazu Mokuno if (!the_card.mapped_mmio_vaddr) { 756*c454fd4eSMasakazu Mokuno pr_info("%s: ioremap 0 failed p=%#lx l=%#lx \n", 757*c454fd4eSMasakazu Mokuno __func__, the_card.ps3_dev->m_region->lpar_addr, 758*c454fd4eSMasakazu Mokuno the_card.ps3_dev->m_region->len); 759*c454fd4eSMasakazu Mokuno return -ENXIO; 760*c454fd4eSMasakazu Mokuno } 761*c454fd4eSMasakazu Mokuno 762*c454fd4eSMasakazu Mokuno return 0; 763*c454fd4eSMasakazu Mokuno }; 764*c454fd4eSMasakazu Mokuno 765*c454fd4eSMasakazu Mokuno static void snd_ps3_unmap_mmio(void) 766*c454fd4eSMasakazu Mokuno { 767*c454fd4eSMasakazu Mokuno iounmap(the_card.mapped_mmio_vaddr); 768*c454fd4eSMasakazu Mokuno the_card.mapped_mmio_vaddr = NULL; 769*c454fd4eSMasakazu Mokuno } 770*c454fd4eSMasakazu Mokuno 771*c454fd4eSMasakazu Mokuno static int snd_ps3_allocate_irq(void) 772*c454fd4eSMasakazu Mokuno { 773*c454fd4eSMasakazu Mokuno int ret; 774*c454fd4eSMasakazu Mokuno u64 lpar_addr, lpar_size; 775*c454fd4eSMasakazu Mokuno u64 __iomem *mapped; 776*c454fd4eSMasakazu Mokuno 777*c454fd4eSMasakazu Mokuno /* FIXME: move this to device_init (H/W probe) */ 778*c454fd4eSMasakazu Mokuno 779*c454fd4eSMasakazu Mokuno /* get irq outlet */ 780*c454fd4eSMasakazu Mokuno ret = lv1_gpu_device_map(1, &lpar_addr, &lpar_size); 781*c454fd4eSMasakazu Mokuno if (ret) { 782*c454fd4eSMasakazu Mokuno pr_info("%s: device map 1 failed %d\n", __func__, 783*c454fd4eSMasakazu Mokuno ret); 784*c454fd4eSMasakazu Mokuno return -ENXIO; 785*c454fd4eSMasakazu Mokuno } 786*c454fd4eSMasakazu Mokuno 787*c454fd4eSMasakazu Mokuno mapped = ioremap(lpar_addr, lpar_size); 788*c454fd4eSMasakazu Mokuno if (!mapped) { 789*c454fd4eSMasakazu Mokuno pr_info("%s: ioremap 1 failed \n", __func__); 790*c454fd4eSMasakazu Mokuno return -ENXIO; 791*c454fd4eSMasakazu Mokuno } 792*c454fd4eSMasakazu Mokuno 793*c454fd4eSMasakazu Mokuno the_card.audio_irq_outlet = in_be64(mapped); 794*c454fd4eSMasakazu Mokuno 795*c454fd4eSMasakazu Mokuno iounmap(mapped); 796*c454fd4eSMasakazu Mokuno ret = lv1_gpu_device_unmap(1); 797*c454fd4eSMasakazu Mokuno if (ret) 798*c454fd4eSMasakazu Mokuno pr_info("%s: unmap 1 failed\n", __func__); 799*c454fd4eSMasakazu Mokuno 800*c454fd4eSMasakazu Mokuno /* irq */ 801*c454fd4eSMasakazu Mokuno ret = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, 802*c454fd4eSMasakazu Mokuno the_card.audio_irq_outlet, 803*c454fd4eSMasakazu Mokuno &the_card.irq_no); 804*c454fd4eSMasakazu Mokuno if (ret) { 805*c454fd4eSMasakazu Mokuno pr_info("%s:ps3_alloc_irq failed (%d)\n", __func__, ret); 806*c454fd4eSMasakazu Mokuno return ret; 807*c454fd4eSMasakazu Mokuno } 808*c454fd4eSMasakazu Mokuno 809*c454fd4eSMasakazu Mokuno ret = request_irq(the_card.irq_no, snd_ps3_interrupt, IRQF_DISABLED, 810*c454fd4eSMasakazu Mokuno SND_PS3_DRIVER_NAME, &the_card); 811*c454fd4eSMasakazu Mokuno if (ret) { 812*c454fd4eSMasakazu Mokuno pr_info("%s: request_irq failed (%d)\n", __func__, ret); 813*c454fd4eSMasakazu Mokuno goto cleanup_irq; 814*c454fd4eSMasakazu Mokuno } 815*c454fd4eSMasakazu Mokuno 816*c454fd4eSMasakazu Mokuno return 0; 817*c454fd4eSMasakazu Mokuno 818*c454fd4eSMasakazu Mokuno cleanup_irq: 819*c454fd4eSMasakazu Mokuno ps3_irq_plug_destroy(the_card.irq_no); 820*c454fd4eSMasakazu Mokuno return ret; 821*c454fd4eSMasakazu Mokuno }; 822*c454fd4eSMasakazu Mokuno 823*c454fd4eSMasakazu Mokuno static void snd_ps3_free_irq(void) 824*c454fd4eSMasakazu Mokuno { 825*c454fd4eSMasakazu Mokuno free_irq(the_card.irq_no, &the_card); 826*c454fd4eSMasakazu Mokuno ps3_irq_plug_destroy(the_card.irq_no); 827*c454fd4eSMasakazu Mokuno } 828*c454fd4eSMasakazu Mokuno 829*c454fd4eSMasakazu Mokuno static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) 830*c454fd4eSMasakazu Mokuno { 831*c454fd4eSMasakazu Mokuno uint64_t val; 832*c454fd4eSMasakazu Mokuno int ret; 833*c454fd4eSMasakazu Mokuno 834*c454fd4eSMasakazu Mokuno val = (ioaddr_start & (0x0fUL << 32)) >> (32 - 20) | 835*c454fd4eSMasakazu Mokuno (0x03UL << 24) | 836*c454fd4eSMasakazu Mokuno (0x0fUL << 12) | 837*c454fd4eSMasakazu Mokuno (PS3_AUDIO_IOID); 838*c454fd4eSMasakazu Mokuno 839*c454fd4eSMasakazu Mokuno ret = lv1_gpu_attribute(0x100, 0x007, val, 0, 0); 840*c454fd4eSMasakazu Mokuno if (ret) 841*c454fd4eSMasakazu Mokuno pr_info("%s: gpu_attribute failed %d\n", __func__, 842*c454fd4eSMasakazu Mokuno ret); 843*c454fd4eSMasakazu Mokuno } 844*c454fd4eSMasakazu Mokuno 845*c454fd4eSMasakazu Mokuno static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) 846*c454fd4eSMasakazu Mokuno { 847*c454fd4eSMasakazu Mokuno int ret; 848*c454fd4eSMasakazu Mokuno u64 lpar_addr, lpar_size; 849*c454fd4eSMasakazu Mokuno 850*c454fd4eSMasakazu Mokuno BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1)); 851*c454fd4eSMasakazu Mokuno BUG_ON(dev->match_id != PS3_MATCH_ID_SOUND); 852*c454fd4eSMasakazu Mokuno 853*c454fd4eSMasakazu Mokuno the_card.ps3_dev = dev; 854*c454fd4eSMasakazu Mokuno 855*c454fd4eSMasakazu Mokuno ret = ps3_open_hv_device(dev); 856*c454fd4eSMasakazu Mokuno 857*c454fd4eSMasakazu Mokuno if (ret) 858*c454fd4eSMasakazu Mokuno return -ENXIO; 859*c454fd4eSMasakazu Mokuno 860*c454fd4eSMasakazu Mokuno /* setup MMIO */ 861*c454fd4eSMasakazu Mokuno ret = lv1_gpu_device_map(2, &lpar_addr, &lpar_size); 862*c454fd4eSMasakazu Mokuno if (ret) { 863*c454fd4eSMasakazu Mokuno pr_info("%s: device map 2 failed %d\n", __func__, ret); 864*c454fd4eSMasakazu Mokuno goto clean_open; 865*c454fd4eSMasakazu Mokuno } 866*c454fd4eSMasakazu Mokuno ps3_mmio_region_init(dev, dev->m_region, lpar_addr, lpar_size, 867*c454fd4eSMasakazu Mokuno PAGE_SHIFT); 868*c454fd4eSMasakazu Mokuno 869*c454fd4eSMasakazu Mokuno ret = snd_ps3_map_mmio(); 870*c454fd4eSMasakazu Mokuno if (ret) 871*c454fd4eSMasakazu Mokuno goto clean_dev_map; 872*c454fd4eSMasakazu Mokuno 873*c454fd4eSMasakazu Mokuno /* setup DMA area */ 874*c454fd4eSMasakazu Mokuno ps3_dma_region_init(dev, dev->d_region, 875*c454fd4eSMasakazu Mokuno PAGE_SHIFT, /* use system page size */ 876*c454fd4eSMasakazu Mokuno 0, /* dma type; not used */ 877*c454fd4eSMasakazu Mokuno NULL, 878*c454fd4eSMasakazu Mokuno _ALIGN_UP(SND_PS3_DMA_REGION_SIZE, PAGE_SIZE)); 879*c454fd4eSMasakazu Mokuno dev->d_region->ioid = PS3_AUDIO_IOID; 880*c454fd4eSMasakazu Mokuno 881*c454fd4eSMasakazu Mokuno ret = ps3_dma_region_create(dev->d_region); 882*c454fd4eSMasakazu Mokuno if (ret) { 883*c454fd4eSMasakazu Mokuno pr_info("%s: region_create\n", __func__); 884*c454fd4eSMasakazu Mokuno goto clean_mmio; 885*c454fd4eSMasakazu Mokuno } 886*c454fd4eSMasakazu Mokuno 887*c454fd4eSMasakazu Mokuno snd_ps3_audio_set_base_addr(dev->d_region->bus_addr); 888*c454fd4eSMasakazu Mokuno 889*c454fd4eSMasakazu Mokuno /* CONFIG_SND_PS3_DEFAULT_START_DELAY */ 890*c454fd4eSMasakazu Mokuno the_card.start_delay = snd_ps3_start_delay; 891*c454fd4eSMasakazu Mokuno 892*c454fd4eSMasakazu Mokuno /* irq */ 893*c454fd4eSMasakazu Mokuno if (snd_ps3_allocate_irq()) { 894*c454fd4eSMasakazu Mokuno ret = -ENXIO; 895*c454fd4eSMasakazu Mokuno goto clean_dma_region; 896*c454fd4eSMasakazu Mokuno } 897*c454fd4eSMasakazu Mokuno 898*c454fd4eSMasakazu Mokuno /* create card instance */ 899*c454fd4eSMasakazu Mokuno the_card.card = snd_card_new(index, id, THIS_MODULE, 0); 900*c454fd4eSMasakazu Mokuno if (!the_card.card) { 901*c454fd4eSMasakazu Mokuno ret = -ENXIO; 902*c454fd4eSMasakazu Mokuno goto clean_irq; 903*c454fd4eSMasakazu Mokuno } 904*c454fd4eSMasakazu Mokuno 905*c454fd4eSMasakazu Mokuno strcpy(the_card.card->driver, "PS3"); 906*c454fd4eSMasakazu Mokuno strcpy(the_card.card->shortname, "PS3"); 907*c454fd4eSMasakazu Mokuno strcpy(the_card.card->longname, "PS3 sound"); 908*c454fd4eSMasakazu Mokuno /* create PCM devices instance */ 909*c454fd4eSMasakazu Mokuno /* NOTE:this driver works assuming pcm:substream = 1:1 */ 910*c454fd4eSMasakazu Mokuno ret = snd_pcm_new(the_card.card, 911*c454fd4eSMasakazu Mokuno "SPDIF", 912*c454fd4eSMasakazu Mokuno 0, /* instance index, will be stored pcm.device*/ 913*c454fd4eSMasakazu Mokuno 1, /* output substream */ 914*c454fd4eSMasakazu Mokuno 0, /* input substream */ 915*c454fd4eSMasakazu Mokuno &(the_card.pcm)); 916*c454fd4eSMasakazu Mokuno if (ret) 917*c454fd4eSMasakazu Mokuno goto clean_card; 918*c454fd4eSMasakazu Mokuno 919*c454fd4eSMasakazu Mokuno the_card.pcm->private_data = &the_card; 920*c454fd4eSMasakazu Mokuno strcpy(the_card.pcm->name, "SPDIF"); 921*c454fd4eSMasakazu Mokuno 922*c454fd4eSMasakazu Mokuno /* set pcm ops */ 923*c454fd4eSMasakazu Mokuno snd_pcm_set_ops(the_card.pcm, SNDRV_PCM_STREAM_PLAYBACK, 924*c454fd4eSMasakazu Mokuno &snd_ps3_pcm_spdif_ops); 925*c454fd4eSMasakazu Mokuno 926*c454fd4eSMasakazu Mokuno the_card.pcm->info_flags = SNDRV_PCM_INFO_NONINTERLEAVED; 927*c454fd4eSMasakazu Mokuno /* pre-alloc PCM DMA buffer*/ 928*c454fd4eSMasakazu Mokuno ret = snd_pcm_lib_preallocate_pages_for_all(the_card.pcm, 929*c454fd4eSMasakazu Mokuno SNDRV_DMA_TYPE_DEV, 930*c454fd4eSMasakazu Mokuno &dev->core, 931*c454fd4eSMasakazu Mokuno SND_PS3_PCM_PREALLOC_SIZE, 932*c454fd4eSMasakazu Mokuno SND_PS3_PCM_PREALLOC_SIZE); 933*c454fd4eSMasakazu Mokuno if (ret < 0) { 934*c454fd4eSMasakazu Mokuno pr_info("%s: prealloc failed\n", __func__); 935*c454fd4eSMasakazu Mokuno goto clean_card; 936*c454fd4eSMasakazu Mokuno } 937*c454fd4eSMasakazu Mokuno 938*c454fd4eSMasakazu Mokuno /* 939*c454fd4eSMasakazu Mokuno * allocate null buffer 940*c454fd4eSMasakazu Mokuno * its size should be lager than PS3_AUDIO_FIFO_STAGE_SIZE * 2 941*c454fd4eSMasakazu Mokuno * PAGE_SIZE is enogh 942*c454fd4eSMasakazu Mokuno */ 943*c454fd4eSMasakazu Mokuno if (!(the_card.null_buffer_start_vaddr = 944*c454fd4eSMasakazu Mokuno dma_alloc_coherent(&the_card.ps3_dev->core, 945*c454fd4eSMasakazu Mokuno PAGE_SIZE, 946*c454fd4eSMasakazu Mokuno &the_card.null_buffer_start_dma_addr, 947*c454fd4eSMasakazu Mokuno GFP_KERNEL))) { 948*c454fd4eSMasakazu Mokuno pr_info("%s: nullbuffer alloc failed\n", __func__); 949*c454fd4eSMasakazu Mokuno goto clean_preallocate; 950*c454fd4eSMasakazu Mokuno } 951*c454fd4eSMasakazu Mokuno pr_debug("%s: null vaddr=%p dma=%#lx\n", __func__, 952*c454fd4eSMasakazu Mokuno the_card.null_buffer_start_vaddr, 953*c454fd4eSMasakazu Mokuno the_card.null_buffer_start_dma_addr); 954*c454fd4eSMasakazu Mokuno /* set default sample rate/word width */ 955*c454fd4eSMasakazu Mokuno snd_ps3_init_avsetting(&the_card); 956*c454fd4eSMasakazu Mokuno 957*c454fd4eSMasakazu Mokuno /* register the card */ 958*c454fd4eSMasakazu Mokuno ret = snd_card_register(the_card.card); 959*c454fd4eSMasakazu Mokuno if (ret < 0) 960*c454fd4eSMasakazu Mokuno goto clean_dma_map; 961*c454fd4eSMasakazu Mokuno 962*c454fd4eSMasakazu Mokuno pr_info("%s started. start_delay=%dms\n", 963*c454fd4eSMasakazu Mokuno the_card.card->longname, the_card.start_delay); 964*c454fd4eSMasakazu Mokuno return 0; 965*c454fd4eSMasakazu Mokuno 966*c454fd4eSMasakazu Mokuno clean_dma_map: 967*c454fd4eSMasakazu Mokuno dma_free_coherent(&the_card.ps3_dev->core, 968*c454fd4eSMasakazu Mokuno PAGE_SIZE, 969*c454fd4eSMasakazu Mokuno the_card.null_buffer_start_vaddr, 970*c454fd4eSMasakazu Mokuno the_card.null_buffer_start_dma_addr); 971*c454fd4eSMasakazu Mokuno clean_preallocate: 972*c454fd4eSMasakazu Mokuno snd_pcm_lib_preallocate_free_for_all(the_card.pcm); 973*c454fd4eSMasakazu Mokuno clean_card: 974*c454fd4eSMasakazu Mokuno snd_card_free(the_card.card); 975*c454fd4eSMasakazu Mokuno clean_irq: 976*c454fd4eSMasakazu Mokuno snd_ps3_free_irq(); 977*c454fd4eSMasakazu Mokuno clean_dma_region: 978*c454fd4eSMasakazu Mokuno ps3_dma_region_free(dev->d_region); 979*c454fd4eSMasakazu Mokuno clean_mmio: 980*c454fd4eSMasakazu Mokuno snd_ps3_unmap_mmio(); 981*c454fd4eSMasakazu Mokuno clean_dev_map: 982*c454fd4eSMasakazu Mokuno lv1_gpu_device_unmap(2); 983*c454fd4eSMasakazu Mokuno clean_open: 984*c454fd4eSMasakazu Mokuno ps3_close_hv_device(dev); 985*c454fd4eSMasakazu Mokuno /* 986*c454fd4eSMasakazu Mokuno * there is no destructor function to pcm. 987*c454fd4eSMasakazu Mokuno * midlayer automatically releases if the card removed 988*c454fd4eSMasakazu Mokuno */ 989*c454fd4eSMasakazu Mokuno return ret; 990*c454fd4eSMasakazu Mokuno }; /* snd_ps3_probe */ 991*c454fd4eSMasakazu Mokuno 992*c454fd4eSMasakazu Mokuno /* called when module removal */ 993*c454fd4eSMasakazu Mokuno static int snd_ps3_driver_remove(struct ps3_system_bus_device *dev) 994*c454fd4eSMasakazu Mokuno { 995*c454fd4eSMasakazu Mokuno int ret; 996*c454fd4eSMasakazu Mokuno pr_info("%s:start id=%d\n", __func__, dev->match_id); 997*c454fd4eSMasakazu Mokuno if (dev->match_id != PS3_MATCH_ID_SOUND) 998*c454fd4eSMasakazu Mokuno return -ENXIO; 999*c454fd4eSMasakazu Mokuno 1000*c454fd4eSMasakazu Mokuno /* 1001*c454fd4eSMasakazu Mokuno * ctl and preallocate buffer will be freed in 1002*c454fd4eSMasakazu Mokuno * snd_card_free 1003*c454fd4eSMasakazu Mokuno */ 1004*c454fd4eSMasakazu Mokuno ret = snd_card_free(the_card.card); 1005*c454fd4eSMasakazu Mokuno if (ret) 1006*c454fd4eSMasakazu Mokuno pr_info("%s: ctl freecard=%d\n", __func__, ret); 1007*c454fd4eSMasakazu Mokuno 1008*c454fd4eSMasakazu Mokuno dma_free_coherent(&dev->core, 1009*c454fd4eSMasakazu Mokuno PAGE_SIZE, 1010*c454fd4eSMasakazu Mokuno the_card.null_buffer_start_vaddr, 1011*c454fd4eSMasakazu Mokuno the_card.null_buffer_start_dma_addr); 1012*c454fd4eSMasakazu Mokuno 1013*c454fd4eSMasakazu Mokuno ps3_dma_region_free(dev->d_region); 1014*c454fd4eSMasakazu Mokuno 1015*c454fd4eSMasakazu Mokuno snd_ps3_free_irq(); 1016*c454fd4eSMasakazu Mokuno snd_ps3_unmap_mmio(); 1017*c454fd4eSMasakazu Mokuno 1018*c454fd4eSMasakazu Mokuno lv1_gpu_device_unmap(2); 1019*c454fd4eSMasakazu Mokuno ps3_close_hv_device(dev); 1020*c454fd4eSMasakazu Mokuno pr_info("%s:end id=%d\n", __func__, dev->match_id); 1021*c454fd4eSMasakazu Mokuno return 0; 1022*c454fd4eSMasakazu Mokuno } /* snd_ps3_remove */ 1023*c454fd4eSMasakazu Mokuno 1024*c454fd4eSMasakazu Mokuno static struct ps3_system_bus_driver snd_ps3_bus_driver_info = { 1025*c454fd4eSMasakazu Mokuno .match_id = PS3_MATCH_ID_SOUND, 1026*c454fd4eSMasakazu Mokuno .probe = snd_ps3_driver_probe, 1027*c454fd4eSMasakazu Mokuno .remove = snd_ps3_driver_remove, 1028*c454fd4eSMasakazu Mokuno .shutdown = snd_ps3_driver_remove, 1029*c454fd4eSMasakazu Mokuno .core = { 1030*c454fd4eSMasakazu Mokuno .name = SND_PS3_DRIVER_NAME, 1031*c454fd4eSMasakazu Mokuno .owner = THIS_MODULE, 1032*c454fd4eSMasakazu Mokuno }, 1033*c454fd4eSMasakazu Mokuno }; 1034*c454fd4eSMasakazu Mokuno 1035*c454fd4eSMasakazu Mokuno 1036*c454fd4eSMasakazu Mokuno /* 1037*c454fd4eSMasakazu Mokuno * Interrupt handler 1038*c454fd4eSMasakazu Mokuno */ 1039*c454fd4eSMasakazu Mokuno static irqreturn_t snd_ps3_interrupt(int irq, void *dev_id) 1040*c454fd4eSMasakazu Mokuno { 1041*c454fd4eSMasakazu Mokuno 1042*c454fd4eSMasakazu Mokuno uint32_t port_intr; 1043*c454fd4eSMasakazu Mokuno int underflow_occured = 0; 1044*c454fd4eSMasakazu Mokuno struct snd_ps3_card_info *card = dev_id; 1045*c454fd4eSMasakazu Mokuno 1046*c454fd4eSMasakazu Mokuno if (!card->running) { 1047*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_AX_IS, 0); 1048*c454fd4eSMasakazu Mokuno update_reg(PS3_AUDIO_INTR_0, 0); 1049*c454fd4eSMasakazu Mokuno return IRQ_HANDLED; 1050*c454fd4eSMasakazu Mokuno } 1051*c454fd4eSMasakazu Mokuno 1052*c454fd4eSMasakazu Mokuno port_intr = read_reg(PS3_AUDIO_AX_IS); 1053*c454fd4eSMasakazu Mokuno /* 1054*c454fd4eSMasakazu Mokuno *serial buffer empty detected (every 4 times), 1055*c454fd4eSMasakazu Mokuno *program next dma and kick it 1056*c454fd4eSMasakazu Mokuno */ 1057*c454fd4eSMasakazu Mokuno if (port_intr & PS3_AUDIO_AX_IE_ASOBEIE(0)) { 1058*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBEIE(0)); 1059*c454fd4eSMasakazu Mokuno if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { 1060*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_AX_IS, port_intr); 1061*c454fd4eSMasakazu Mokuno underflow_occured = 1; 1062*c454fd4eSMasakazu Mokuno } 1063*c454fd4eSMasakazu Mokuno if (card->silent) { 1064*c454fd4eSMasakazu Mokuno /* we are still in silent time */ 1065*c454fd4eSMasakazu Mokuno snd_ps3_program_dma(card, 1066*c454fd4eSMasakazu Mokuno (underflow_occured) ? 1067*c454fd4eSMasakazu Mokuno SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL : 1068*c454fd4eSMasakazu Mokuno SND_PS3_DMA_FILLTYPE_SILENT_RUNNING); 1069*c454fd4eSMasakazu Mokuno snd_ps3_kick_dma(card); 1070*c454fd4eSMasakazu Mokuno card->silent --; 1071*c454fd4eSMasakazu Mokuno } else { 1072*c454fd4eSMasakazu Mokuno snd_ps3_program_dma(card, 1073*c454fd4eSMasakazu Mokuno (underflow_occured) ? 1074*c454fd4eSMasakazu Mokuno SND_PS3_DMA_FILLTYPE_FIRSTFILL : 1075*c454fd4eSMasakazu Mokuno SND_PS3_DMA_FILLTYPE_RUNNING); 1076*c454fd4eSMasakazu Mokuno snd_ps3_kick_dma(card); 1077*c454fd4eSMasakazu Mokuno snd_pcm_period_elapsed(card->substream); 1078*c454fd4eSMasakazu Mokuno } 1079*c454fd4eSMasakazu Mokuno } else if (port_intr & PS3_AUDIO_AX_IE_ASOBUIE(0)) { 1080*c454fd4eSMasakazu Mokuno write_reg(PS3_AUDIO_AX_IS, PS3_AUDIO_AX_IE_ASOBUIE(0)); 1081*c454fd4eSMasakazu Mokuno /* 1082*c454fd4eSMasakazu Mokuno * serial out underflow, but buffer empty not detected. 1083*c454fd4eSMasakazu Mokuno * in this case, fill fifo with 0 to recover. After 1084*c454fd4eSMasakazu Mokuno * filling dummy data, serial automatically start to 1085*c454fd4eSMasakazu Mokuno * consume them and then will generate normal buffer 1086*c454fd4eSMasakazu Mokuno * empty interrupts. 1087*c454fd4eSMasakazu Mokuno * If both buffer underflow and buffer empty are occured, 1088*c454fd4eSMasakazu Mokuno * it is better to do nomal data transfer than empty one 1089*c454fd4eSMasakazu Mokuno */ 1090*c454fd4eSMasakazu Mokuno snd_ps3_program_dma(card, 1091*c454fd4eSMasakazu Mokuno SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); 1092*c454fd4eSMasakazu Mokuno snd_ps3_kick_dma(card); 1093*c454fd4eSMasakazu Mokuno snd_ps3_program_dma(card, 1094*c454fd4eSMasakazu Mokuno SND_PS3_DMA_FILLTYPE_SILENT_FIRSTFILL); 1095*c454fd4eSMasakazu Mokuno snd_ps3_kick_dma(card); 1096*c454fd4eSMasakazu Mokuno } 1097*c454fd4eSMasakazu Mokuno /* clear interrupt cause */ 1098*c454fd4eSMasakazu Mokuno return IRQ_HANDLED; 1099*c454fd4eSMasakazu Mokuno }; 1100*c454fd4eSMasakazu Mokuno 1101*c454fd4eSMasakazu Mokuno /* 1102*c454fd4eSMasakazu Mokuno * module/subsystem initialize/terminate 1103*c454fd4eSMasakazu Mokuno */ 1104*c454fd4eSMasakazu Mokuno static int __init snd_ps3_init(void) 1105*c454fd4eSMasakazu Mokuno { 1106*c454fd4eSMasakazu Mokuno int ret; 1107*c454fd4eSMasakazu Mokuno 1108*c454fd4eSMasakazu Mokuno if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 1109*c454fd4eSMasakazu Mokuno return -ENXIO; 1110*c454fd4eSMasakazu Mokuno 1111*c454fd4eSMasakazu Mokuno memset(&the_card, 0, sizeof(the_card)); 1112*c454fd4eSMasakazu Mokuno spin_lock_init(&the_card.dma_lock); 1113*c454fd4eSMasakazu Mokuno 1114*c454fd4eSMasakazu Mokuno /* register systembus DRIVER, this calls our probe() func */ 1115*c454fd4eSMasakazu Mokuno ret = ps3_system_bus_driver_register(&snd_ps3_bus_driver_info); 1116*c454fd4eSMasakazu Mokuno 1117*c454fd4eSMasakazu Mokuno return ret; 1118*c454fd4eSMasakazu Mokuno } 1119*c454fd4eSMasakazu Mokuno 1120*c454fd4eSMasakazu Mokuno static void __exit snd_ps3_exit(void) 1121*c454fd4eSMasakazu Mokuno { 1122*c454fd4eSMasakazu Mokuno ps3_system_bus_driver_unregister(&snd_ps3_bus_driver_info); 1123*c454fd4eSMasakazu Mokuno } 1124*c454fd4eSMasakazu Mokuno 1125*c454fd4eSMasakazu Mokuno MODULE_ALIAS(PS3_MODULE_ALIAS_SOUND); 1126