static int mv88fx_initalize_machine_data(struct platform_device *pdev) { struct resource *r = NULL; int err = 0; mv88fx_snd_debug(""); mv88fx_machine_data.port = pdev->id; mv88fx_machine_data.pdata = (struct orion_i2s_platform_data *)pdev->dev.platform_data; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { mv88fx_snd_error(""); err = -ENXIO; goto error; } r = request_mem_region(r->start, SZ_16K, DRIVER_NAME); if (!r) { mv88fx_snd_error(""); err = -EBUSY; goto error; } mv88fx_machine_data.res = r; mv88fx_machine_data.base = ioremap(r->start, SZ_16K); if (!mv88fx_machine_data.base) { mv88fx_snd_error("ioremap failed"); err = -ENOMEM; goto error; } mv88fx_machine_data.base -= AUDIO_REG_BASE(mv88fx_machine_data.port); mv88fx_machine_data.irq = platform_get_irq(pdev, 0); if (mv88fx_machine_data.irq == NO_IRQ) { mv88fx_snd_error(""); err = -ENXIO; goto error; } #if defined(CONFIG_HAVE_CLK) mv88fx_machine_data.clk = clk_get(&pdev->dev, NULL); if (IS_ERR(mv88fx_machine_data.clk)) dev_notice(&pdev->dev, "cannot get clkdev\n"); else clk_enable(mv88fx_machine_data.clk); #endif return 0; error: if (mv88fx_machine_data.base) { iounmap(mv88fx_machine_data.base); mv88fx_machine_data.base = NULL; } release_mem_region(mv88fx_machine_data.res->start, SZ_16K); return err; }
static int mv88fx_i2_hw_init(int port) { mv88fx_snd_debug(""); mv88fx_snd_writel(mv88fx_i2s_info[port].base, MV_AUDIO_INT_CAUSE_REG(port), 0xffffffff); mv88fx_snd_writel(mv88fx_i2s_info[port].base, MV_AUDIO_INT_MASK_REG(port), 0); mv88fx_snd_writel(mv88fx_i2s_info[port].base, MV_AUDIO_SPDIF_REC_INT_CAUSE_MASK_REG(port), 0); // if (MV_OK != mvAudioInit(mv88fx_i2s_info.port)) // return -EIO; mvSysAudioInit(port); /* Disable all playback/recording */ mv88fx_snd_bitreset(mv88fx_i2s_info[port].base, MV_AUDIO_PLAYBACK_CTRL_REG(port), (APCR_PLAY_I2S_ENABLE_MASK | APCR_PLAY_SPDIF_ENABLE_MASK)); mv88fx_snd_bitreset(mv88fx_i2s_info[port].base, MV_AUDIO_RECORD_CTRL_REG(port), (ARCR_RECORD_SPDIF_EN_MASK | ARCR_RECORD_I2S_EN_MASK)); if (MV_OK != mvSPDIFRecordTclockSet(port)) { mv88fx_snd_error("mvSPDIFRecordTclockSet failed"); return -ENOMEM; } return 0; }
static int mv88fx_snd_probe(struct platform_device *pdev) { int ret = 0; mv88fx_snd_debug("mv88fx_snd_probe"); if (mv88fx_initalize_machine_data(pdev) != 0) goto error; mv88fx_machine_data.snd_dev = platform_device_alloc("soc-audio", 0); if (!mv88fx_machine_data.snd_dev) { ret = -ENOMEM; goto error; } if(machine_is_dove_avng_v3()) { platform_set_drvdata(mv88fx_machine_data.snd_dev, &mv88fx_snd_devdata_avd1_v3); mv88fx_snd_devdata_avd1_v3.dev = &mv88fx_machine_data.snd_dev->dev; } else { platform_set_drvdata(mv88fx_machine_data.snd_dev, &mv88fx_snd_devdata); mv88fx_snd_devdata.dev = &mv88fx_machine_data.snd_dev->dev; } mv88fx_machine_data.snd_dev->dev.platform_data = &mv88fx_machine_data; ret = platform_device_add(mv88fx_machine_data.snd_dev); if(ret) { platform_device_put(mv88fx_machine_data.snd_dev); } ret = platform_device_register(&rt5630_codec_dev); if(ret) platform_device_unregister(&rt5630_codec_dev); return ret; error: mv88fx_snd_error(""); #if defined(CONFIG_HAVE_CLK) if (!IS_ERR(mv88fx_machine_data.clk)) { clk_disable(mv88fx_machine_data.clk); clk_put(mv88fx_machine_data.clk); } #endif if (mv88fx_machine_data.snd_dev) platform_device_unregister(mv88fx_machine_data.snd_dev); return ret; }
static int mv88fx_snd_probe(struct platform_device *pdev) { int ret = 0; mv88fx_snd_debug(""); if (mv88fx_initalize_machine_data(pdev) != 0) goto error; mv88fx_machine_data.snd_dev = platform_device_alloc("soc-audio", 1); if (!mv88fx_machine_data.snd_dev) { ret = -ENOMEM; goto error; } platform_set_drvdata(mv88fx_machine_data.snd_dev, &mv88fx_snd_devdata); mv88fx_snd_devdata.dev = &mv88fx_machine_data.snd_dev->dev; mv88fx_machine_data.snd_dev->dev.platform_data = &mv88fx_machine_data; ret = platform_device_add(mv88fx_machine_data.snd_dev); mv88fx_snd_debug(""); return 0; error: mv88fx_snd_error(""); #if defined(CONFIG_HAVE_CLK) if (!IS_ERR(mv88fx_machine_data.clk)) { clk_disable(mv88fx_machine_data.clk); clk_put(mv88fx_machine_data.clk); } #endif if (mv88fx_machine_data.snd_dev) platform_device_unregister(mv88fx_machine_data.snd_dev); return ret; }
static int mv88fx_i2s_snd_hw_playback_set(struct mv88fx_snd_chip *chip, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct mv88fx_snd_stream *audio_stream = runtime->private_data; MV_AUDIO_PLAYBACK_CTRL pcm_play_ctrl; MV_I2S_PLAYBACK_CTRL i2s_play_ctrl; MV_SPDIF_PLAYBACK_CTRL spdif_play_ctrl; MV_AUDIO_FREQ_DATA dco_ctrl; mv88fx_snd_debug("chip=%p chip->base=%p", chip, chip->base); memset(&pcm_play_ctrl, 0, sizeof(pcm_play_ctrl)); memset(&dco_ctrl, 0, sizeof(dco_ctrl)); memset(&i2s_play_ctrl, 0, sizeof(i2s_play_ctrl)); memset(&spdif_play_ctrl, 0, sizeof(spdif_play_ctrl)); dco_ctrl.offset = chip->dco_ctrl_offst; mv88fx_snd_debug("rate: %u ", runtime->rate); switch (runtime->rate) { case 44100: dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH; break; case 48000: dco_ctrl.baseFreq = AUDIO_FREQ_48KH; break; case 96000: dco_ctrl.baseFreq = AUDIO_FREQ_96KH; break; default: mv88fx_snd_error("Requested rate %d is not supported", runtime->rate); return -1; } pcm_play_ctrl.burst = (chip->burst == 128) ? AUDIO_128BYTE_BURST : AUDIO_32BYTE_BURST; pcm_play_ctrl.loopBack = chip->loopback; if (mv88fx_pcm_is_stereo(runtime)) { pcm_play_ctrl.monoMode = AUDIO_PLAY_MONO_OFF; } else { switch (audio_stream->mono_mode) { case MONO_LEFT: pcm_play_ctrl.monoMode = AUDIO_PLAY_LEFT_MONO; break; case MONO_RIGHT: pcm_play_ctrl.monoMode = AUDIO_PLAY_RIGHT_MONO; break; case MONO_BOTH: default: pcm_play_ctrl.monoMode = AUDIO_PLAY_BOTH_MONO; break; } } if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { pcm_play_ctrl.sampleSize = SAMPLE_16BIT; i2s_play_ctrl.sampleSize = SAMPLE_16BIT; } else if (runtime->format == SNDRV_PCM_FORMAT_S24_LE) { pcm_play_ctrl.sampleSize = SAMPLE_24BIT; i2s_play_ctrl.sampleSize = SAMPLE_24BIT; } else if (runtime->format == SNDRV_PCM_FORMAT_S32_LE) { pcm_play_ctrl.sampleSize = SAMPLE_32BIT; i2s_play_ctrl.sampleSize = SAMPLE_32BIT; } else { mv88fx_snd_error("Requested format %d is not supported", runtime->format); return -1; } /* buffer and period sizes in frame */ pcm_play_ctrl.bufferPhyBase = runtime->dma_addr; pcm_play_ctrl.bufferSize = frames_to_bytes(runtime, runtime->buffer_size); pcm_play_ctrl.intByteCount = frames_to_bytes(runtime, runtime->period_size); /* I2S playback streem stuff */ /*i2s_play_ctrl.sampleSize = pcm_play_ctrl.sampleSize; */ i2s_play_ctrl.justification = I2S_JUSTIFIED; i2s_play_ctrl.sendLastFrame = 0; spdif_play_ctrl.nonPcm = MV_FALSE; spdif_play_ctrl.validity = chip->ch_stat_valid; if (audio_stream->stat_mem) { spdif_play_ctrl.userBitsFromMemory = MV_TRUE; spdif_play_ctrl.validityFromMemory = MV_TRUE; spdif_play_ctrl.blockStartInternally = MV_FALSE; } else { spdif_play_ctrl.userBitsFromMemory = MV_FALSE; spdif_play_ctrl.validityFromMemory = MV_FALSE; spdif_play_ctrl.blockStartInternally = MV_TRUE; } mv88fx_snd_debug(""); /* If this is non-PCM sound, mute I2S channel */ spin_lock_irq(&chip->reg_lock); mv88fx_snd_debug("chip=%p chip->base=%p port=%d", chip, chip->base, chip->port); if (!(mv88fx_snd_readl(chip->base, MV_AUDIO_PLAYBACK_CTRL_REG(chip->port)) & (APCR_PLAY_I2S_ENABLE_MASK | APCR_PLAY_SPDIF_ENABLE_MASK))) { mv88fx_snd_debug(""); if (MV_OK != mvAudioDCOCtrlSet(chip->port, &dco_ctrl)) { mv88fx_snd_error ("Failed to initialize DCO clock control."); return -1; mv88fx_snd_debug(""); } } mv88fx_snd_debug(""); if (audio_stream->clock_src == DCO_CLOCK) while ((mv88fx_snd_readl(chip->base, MV_AUDIO_SPCR_DCO_STATUS_REG(chip->port)) & ASDSR_DCO_LOCK_MASK) == 0) ; else if (audio_stream->clock_src == SPCR_CLOCK) while ((mv88fx_snd_readl(chip->base, MV_AUDIO_SPCR_DCO_STATUS_REG(chip->port)) & ASDSR_SPCR_LOCK_MASK) == 0) ; mv88fx_snd_debug(""); if (MV_OK != mvAudioPlaybackControlSet(chip->port, &pcm_play_ctrl)) { mv88fx_snd_error("Failed to initialize PCM playback control."); return -1; } mv88fx_snd_debug(""); if (MV_OK != mvI2SPlaybackCtrlSet(chip->port, &i2s_play_ctrl)) { mv88fx_snd_error("Failed to initialize I2S playback control."); return -1; } mv88fx_snd_debug(""); mvSPDIFPlaybackCtrlSet(chip->port, &spdif_play_ctrl); mv88fx_snd_debug(""); spin_unlock_irq(&chip->reg_lock); return 0; }
static int mv88fx_i2s_snd_hw_capture_set(struct mv88fx_snd_chip *chip, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct mv88fx_snd_stream *audio_stream = runtime->private_data; MV_AUDIO_RECORD_CTRL pcm_rec_ctrl; MV_I2S_RECORD_CTRL i2s_rec_ctrl; MV_AUDIO_FREQ_DATA dco_ctrl; //#ifdef CONFIG_MACH_DOVE_RD_AVNG // int phoneInDetected; //#endif mv88fx_snd_debug("chip=%p chip->base=%p", chip, chip->base); dco_ctrl.offset = chip->dco_ctrl_offst; switch (runtime->rate) { case 44100: dco_ctrl.baseFreq = AUDIO_FREQ_44_1KH; break; case 48000: dco_ctrl.baseFreq = AUDIO_FREQ_48KH; break; case 96000: dco_ctrl.baseFreq = AUDIO_FREQ_96KH; break; default: mv88fx_snd_debug("ERROR"); mv88fx_snd_error("Requested rate %d is not supported", runtime->rate); return -1; } pcm_rec_ctrl.burst = (chip->burst == 128) ? AUDIO_128BYTE_BURST : AUDIO_32BYTE_BURST; if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) { pcm_rec_ctrl.sampleSize = SAMPLE_16BIT; } else if (runtime->format == SNDRV_PCM_FORMAT_S24_LE) { pcm_rec_ctrl.sampleSize = SAMPLE_24BIT; } else if (runtime->format == SNDRV_PCM_FORMAT_S32_LE) { pcm_rec_ctrl.sampleSize = SAMPLE_32BIT; } else { mv88fx_snd_error("Requested format %d is not supported", runtime->format); return -1; } pcm_rec_ctrl.mono = (mv88fx_pcm_is_stereo(runtime)) ? MV_FALSE : MV_TRUE; if (pcm_rec_ctrl.mono) { switch (audio_stream->mono_mode) { case MONO_LEFT: pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO; break; default: case MONO_RIGHT: pcm_rec_ctrl.monoChannel = AUDIO_REC_RIGHT_MONO; break; } } else pcm_rec_ctrl.monoChannel = AUDIO_REC_LEFT_MONO; pcm_rec_ctrl.bufferPhyBase = runtime->dma_addr; pcm_rec_ctrl.bufferSize = frames_to_bytes(runtime, runtime->buffer_size); pcm_rec_ctrl.intByteCount = frames_to_bytes(runtime, runtime->period_size); /* I2S record streem stuff */ i2s_rec_ctrl.sample = pcm_rec_ctrl.sampleSize; i2s_rec_ctrl.justf = I2S_JUSTIFIED; spin_lock_irq(&chip->reg_lock); /* set clock only if record is not enabled */ if (!(mv88fx_snd_readl(chip->base, MV_AUDIO_RECORD_CTRL_REG(chip->port)) & (ARCR_RECORD_SPDIF_EN_MASK | ARCR_RECORD_I2S_EN_MASK))) { if (MV_OK != mvAudioDCOCtrlSet(chip->port, &dco_ctrl)) { mv88fx_snd_debug("ERROR"); mv88fx_snd_error ("Failed to initialize DCO clock control."); return -1; } } mv88fx_snd_debug(""); if (MV_OK != mvAudioRecordControlSet(chip->port, &pcm_rec_ctrl)) { mv88fx_snd_error("Failed to initialize PCM record control."); return -1; } if (MV_OK != mvI2SRecordCntrlSet(chip->port, &i2s_rec_ctrl)) { mv88fx_snd_error("Failed to initialize I2S record control."); return -1; } mv88fx_snd_debug(""); //#ifdef CONFIG_MACH_DOVE_RD_AVNG // if (machine_is_dove_rd_avng()) { // phoneInDetected = gpio_get_value(53); // if (phoneInDetected < 0) // mv88fx_snd_error("Failed to detect phone-in."); // else { // int input_type; // mv88fx_snd_error("detect phone-in."); // if (!phoneInDetected) // input_type = 2; /* external MIC */ // else // input_type = 1; /* internal MIC */ // } // } //#endif mv88fx_snd_debug(""); spin_unlock_irq(&chip->reg_lock); mv88fx_snd_debug(""); return 0; }