Path: blob/master/sound/soc/blackfin/bf5xx-ad73311.c
10817 views
/*1* File: sound/soc/blackfin/bf5xx-ad73311.c2* Author: Cliff Cai <[email protected]>3*4* Created: Thur Sep 25 20085* Description: Board driver for ad73311 sound chip6*7* Modified:8* Copyright 2008 Analog Devices Inc.9*10* Bugs: Enter bugs at http://blackfin.uclinux.org/11*12* This program is free software; you can redistribute it and/or modify13* it under the terms of the GNU General Public License as published by14* the Free Software Foundation; either version 2 of the License, or15* (at your option) any later version.16*17* This program is distributed in the hope that it will be useful,18* but WITHOUT ANY WARRANTY; without even the implied warranty of19* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the20* GNU General Public License for more details.21*22* You should have received a copy of the GNU General Public License23* along with this program; if not, see the file COPYING, or write24* to the Free Software Foundation, Inc.,25* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA26*/2728#include <linux/module.h>29#include <linux/moduleparam.h>30#include <linux/device.h>31#include <linux/delay.h>32#include <linux/gpio.h>3334#include <sound/core.h>35#include <sound/pcm.h>36#include <sound/soc.h>37#include <sound/pcm_params.h>3839#include <asm/blackfin.h>40#include <asm/cacheflush.h>41#include <asm/irq.h>42#include <asm/dma.h>43#include <asm/portmux.h>4445#include "../codecs/ad73311.h"46#include "bf5xx-sport.h"47#include "bf5xx-i2s-pcm.h"4849#if CONFIG_SND_BF5XX_SPORT_NUM == 050#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR151#define bfin_read_SPORT_TCR1 bfin_read_SPORT0_TCR152#define bfin_write_SPORT_TCR2 bfin_write_SPORT0_TCR253#define bfin_write_SPORT_TX16 bfin_write_SPORT0_TX1654#define bfin_read_SPORT_STAT bfin_read_SPORT0_STAT55#else56#define bfin_write_SPORT_TCR1 bfin_write_SPORT1_TCR157#define bfin_read_SPORT_TCR1 bfin_read_SPORT1_TCR158#define bfin_write_SPORT_TCR2 bfin_write_SPORT1_TCR259#define bfin_write_SPORT_TX16 bfin_write_SPORT1_TX1660#define bfin_read_SPORT_STAT bfin_read_SPORT1_STAT61#endif6263#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE6465static struct snd_soc_card bf5xx_ad73311;6667static int snd_ad73311_startup(void)68{69pr_debug("%s enter\n", __func__);7071/* Pull up SE pin on AD73311L */72gpio_set_value(GPIO_SE, 1);73return 0;74}7576static int snd_ad73311_configure(void)77{78unsigned short ctrl_regs[6];79unsigned short status = 0;80int count = 0;8182/* DMCLK = MCLK = 16.384 MHz83* SCLK = DMCLK/8 = 2.048 MHz84* Sample Rate = DMCLK/2048 = 8 KHz85*/86ctrl_regs[0] = AD_CONTROL | AD_WRITE | CTRL_REG_B | REGB_MCDIV(0) | \87REGB_SCDIV(0) | REGB_DIRATE(0);88ctrl_regs[1] = AD_CONTROL | AD_WRITE | CTRL_REG_C | REGC_PUDEV | \89REGC_PUADC | REGC_PUDAC | REGC_PUREF | REGC_REFUSE ;90ctrl_regs[2] = AD_CONTROL | AD_WRITE | CTRL_REG_D | REGD_OGS(2) | \91REGD_IGS(2);92ctrl_regs[3] = AD_CONTROL | AD_WRITE | CTRL_REG_E | REGE_DA(0x1f);93ctrl_regs[4] = AD_CONTROL | AD_WRITE | CTRL_REG_F | REGF_SEEN ;94ctrl_regs[5] = AD_CONTROL | AD_WRITE | CTRL_REG_A | REGA_MODE_DATA;9596local_irq_disable();97snd_ad73311_startup();98udelay(1);99100bfin_write_SPORT_TCR1(TFSR);101bfin_write_SPORT_TCR2(0xF);102SSYNC();103104/* SPORT Tx Register is a 8 x 16 FIFO, all the data can be put to105* FIFO before enable SPORT to transfer the data106*/107for (count = 0; count < 6; count++)108bfin_write_SPORT_TX16(ctrl_regs[count]);109SSYNC();110bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() | TSPEN);111SSYNC();112113/* When TUVF is set, the data is already send out */114while (!(status & TUVF) && ++count < 10000) {115udelay(1);116status = bfin_read_SPORT_STAT();117SSYNC();118}119bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() & ~TSPEN);120SSYNC();121local_irq_enable();122123if (count >= 10000) {124printk(KERN_ERR "ad73311: failed to configure codec\n");125return -1;126}127return 0;128}129130static int bf5xx_probe(struct platform_device *pdev)131{132int err;133if (gpio_request(GPIO_SE, "AD73311_SE")) {134printk(KERN_ERR "%s: Failed ro request GPIO_%d\n", __func__, GPIO_SE);135return -EBUSY;136}137138gpio_direction_output(GPIO_SE, 0);139140err = snd_ad73311_configure();141if (err < 0)142return -EFAULT;143144return 0;145}146147static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,148struct snd_pcm_hw_params *params)149{150struct snd_soc_pcm_runtime *rtd = substream->private_data;151struct snd_soc_dai *cpu_dai = rtd->cpu_dai;152int ret = 0;153154pr_debug("%s rate %d format %x\n", __func__, params_rate(params),155params_format(params));156157/* set cpu DAI configuration */158ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |159SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);160if (ret < 0)161return ret;162163return 0;164}165166167static struct snd_soc_ops bf5xx_ad73311_ops = {168.hw_params = bf5xx_ad73311_hw_params,169};170171static struct snd_soc_dai_link bf5xx_ad73311_dai[] = {172{173.name = "ad73311",174.stream_name = "AD73311",175.cpu_dai_name = "bfin-i2s.0",176.codec_dai_name = "ad73311-hifi",177.platform_name = "bfin-i2s-pcm-audio",178.codec_name = "ad73311",179.ops = &bf5xx_ad73311_ops,180},181{182.name = "ad73311",183.stream_name = "AD73311",184.cpu_dai_name = "bfin-i2s.1",185.codec_dai_name = "ad73311-hifi",186.platform_name = "bfin-i2s-pcm-audio",187.codec_name = "ad73311",188.ops = &bf5xx_ad73311_ops,189},190};191192static struct snd_soc_card bf5xx_ad73311 = {193.name = "bfin-ad73311",194.probe = bf5xx_probe,195.dai_link = &bf5xx_ad73311_dai[CONFIG_SND_BF5XX_SPORT_NUM],196.num_links = 1,197};198199static struct platform_device *bf5xx_ad73311_snd_device;200201static int __init bf5xx_ad73311_init(void)202{203int ret;204205pr_debug("%s enter\n", __func__);206bf5xx_ad73311_snd_device = platform_device_alloc("soc-audio", -1);207if (!bf5xx_ad73311_snd_device)208return -ENOMEM;209210platform_set_drvdata(bf5xx_ad73311_snd_device, &bf5xx_ad73311);211ret = platform_device_add(bf5xx_ad73311_snd_device);212213if (ret)214platform_device_put(bf5xx_ad73311_snd_device);215216return ret;217}218219static void __exit bf5xx_ad73311_exit(void)220{221pr_debug("%s enter\n", __func__);222platform_device_unregister(bf5xx_ad73311_snd_device);223}224225module_init(bf5xx_ad73311_init);226module_exit(bf5xx_ad73311_exit);227228/* Module information */229MODULE_AUTHOR("Cliff Cai");230MODULE_DESCRIPTION("ALSA SoC AD73311 Blackfin");231MODULE_LICENSE("GPL");232233234235