Commit 878716ca authored by Andrzej Zaborowski's avatar Andrzej Zaborowski Committed by Tony Lindgren

SPI: TSC2102 OMAP audio driver

ALSA driver for OMAP boards with a TSC2102 chip. It is based on the
TSC2101 and AIC23 drivers. The chip has only one audio playback output
and no inputs. It can play stereo sound with 16-bit samples (only) and
supports different sampling rates between 8 and 48 kHz. The patch also
includes an ALSA mixer. The mixer controlls two volume levels, for
left and right channels, each with 128 steps. It can also toggle the
analog de-emphasis filter and bass boost filter which are incorporated
in the chip.

In addition to that the chip has an equaliser filter, but the mixer
doesn't use it because the coefficients of the filter are difficult to
map to other values used in normal equalisers. Maybe they should have
constant values per board.
Signed-off-by: default avatarAndrzej Zaborowski <balrog@zabor.org>
parent 51b8a1cd
...@@ -63,4 +63,16 @@ config SND_OMAP_TSC2101 ...@@ -63,4 +63,16 @@ config SND_OMAP_TSC2101
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called snd-omap-tsc2101. will be called snd-omap-tsc2101.
config SND_OMAP_TSC2102
tristate "OMAP TSC2102 alsa driver"
depends on ARCH_OMAP && SND
select SND_PCM
select TSC2102
help
Say Y here if you have an OMAP platform board
and want to use its TSC2102 audio chip.
To compile this driver as a module, choose M here: the module
will be called snd-omap-tsc2102.
endmenu endmenu
...@@ -7,3 +7,6 @@ snd-omap-alsa-aic23-objs := omap-alsa.o omap-alsa-dma.o omap-alsa-aic23.o omap-a ...@@ -7,3 +7,6 @@ snd-omap-alsa-aic23-objs := omap-alsa.o omap-alsa-dma.o omap-alsa-aic23.o omap-a
obj-$(CONFIG_SND_OMAP_TSC2101) += snd-omap-alsa-tsc2101.o obj-$(CONFIG_SND_OMAP_TSC2101) += snd-omap-alsa-tsc2101.o
snd-omap-alsa-tsc2101-objs := omap-alsa.o omap-alsa-dma.o omap-alsa-tsc2101.o omap-alsa-tsc2101-mixer.o snd-omap-alsa-tsc2101-objs := omap-alsa.o omap-alsa-dma.o omap-alsa-tsc2101.o omap-alsa-tsc2101-mixer.o
obj-$(CONFIG_SND_OMAP_TSC2102) += snd-omap-alsa-tsc2102.o
snd-omap-alsa-tsc2102-objs := omap-alsa.o omap-alsa-dma.o omap-alsa-tsc2102.o omap-alsa-tsc2102-mixer.o
/*
* sound/arm/omap/omap-alsa-tsc2102-mixer.c
*
* Alsa mixer driver for TSC2102 chip for OMAP platforms.
*
* Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
* Code based on the TSC2101 ALSA driver.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/spi/tsc2102.h>
#include <asm/arch/omap-alsa.h>
#include <sound/driver.h>
#include <sound/initval.h>
#include <sound/control.h>
#include "omap-alsa-tsc2102.h"
#include "omap-alsa-dma.h"
static int vol[2], mute[2], filter[2];
/*
* Converts the Alsa mixer volume (0 - 100) to actual Digital
* Gain Control (DGC) value that can be written or read from the
* TSC2102 registers.
*
* Note that the number "OUTPUT_VOLUME_MAX" is smaller than
* OUTPUT_VOLUME_MIN because DGC works as a volume decreaser. (The
* higher the value sent to DAC, the more the volume of controlled
* channel is decreased)
*/
static void set_dac_gain_stereo(int left_ch, int right_ch)
{
int lch, rch;
if (left_ch > 100)
vol[0] = 100;
else if (left_ch < 0)
vol[0] = 0;
else
vol[0] = left_ch;
lch = OUTPUT_VOLUME_MIN - vol[0] *
(OUTPUT_VOLUME_MIN - OUTPUT_VOLUME_MAX) / 100;
if (right_ch > 100)
vol[1] = 100;
else if (right_ch < 0)
vol[1] = 0;
else
vol[1] = right_ch;
rch = OUTPUT_VOLUME_MIN - vol[1] *
(OUTPUT_VOLUME_MIN - OUTPUT_VOLUME_MAX) / 100;
tsc2102_set_volume(lch, rch);
}
void init_playback_targets(void)
{
set_dac_gain_stereo(DEFAULT_OUTPUT_VOLUME, DEFAULT_OUTPUT_VOLUME);
/* Unmute */
tsc2102_set_mute(0, 0);
mute[0] = mute[1] = 0;
filter[0] = filter[1] = 0;
}
/*
* Initializes TSC 2102 and playback target.
*/
void snd_omap_init_mixer(void)
{
FN_IN;
init_playback_targets();
FN_OUT(0);
}
static int __pcm_playback_volume_info(
snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = 2;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 100;
return 0;
}
static int __pcm_playback_volume_get(
snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ucontrol->value.integer.value[0] = vol[0]; /* L */
ucontrol->value.integer.value[1] = vol[1]; /* R */
return 0;
}
static int __pcm_playback_volume_put(
snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
set_dac_gain_stereo(
ucontrol->value.integer.value[0], /* L */
ucontrol->value.integer.value[1]); /* R */
return 1;
}
static int __pcm_playback_switch_info(
snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 2;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
}
static int __pcm_playback_switch_get(
snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ucontrol->value.integer.value[0] = !mute[0]; /* L */
ucontrol->value.integer.value[1] = !mute[1]; /* R */
return 0;
}
static int __pcm_playback_switch_put(
snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
mute[0] = (ucontrol->value.integer.value[0] == 0); /* L */
mute[1] = (ucontrol->value.integer.value[1] == 0); /* R */
tsc2102_set_mute(mute[0], mute[1]);
return 1;
}
static int __pcm_playback_deemphasis_info(
snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
}
static int __pcm_playback_deemphasis_get(
snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ucontrol->value.integer.value[0] = filter[0];
return 0;
}
static int __pcm_playback_deemphasis_put(
snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
filter[0] = (ucontrol->value.integer.value[0] > 0);
tsc2102_set_deemphasis(filter[0]);
return 1;
}
static int __pcm_playback_bassboost_info(
snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
uinfo->count = 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = 1;
return 0;
}
static int __pcm_playback_bassboost_get(
snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
ucontrol->value.integer.value[0] = filter[1];
return 0;
}
static int __pcm_playback_bassboost_put(
snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
{
filter[1] = (ucontrol->value.integer.value[0] > 0);
tsc2102_set_bassboost(filter[1]);
return 1;
}
static snd_kcontrol_new_t tsc2102_control[] __devinitdata = {
{
.name = "Master Playback Volume",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.index = 0,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = __pcm_playback_volume_info,
.get = __pcm_playback_volume_get,
.put = __pcm_playback_volume_put,
},
{
.name = "Master Playback Switch",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.index = 0,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = __pcm_playback_switch_info,
.get = __pcm_playback_switch_get,
.put = __pcm_playback_switch_put,
},
{
.name = "De-emphasis Filter Switch",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.index = 0,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = __pcm_playback_deemphasis_info,
.get = __pcm_playback_deemphasis_get,
.put = __pcm_playback_deemphasis_put,
},
{
.name = "Bass-boost Filter Switch",
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.index = 0,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = __pcm_playback_bassboost_info,
.get = __pcm_playback_bassboost_get,
.put = __pcm_playback_bassboost_put,
},
};
#ifdef CONFIG_PM
void snd_omap_suspend_mixer(void)
{
/* Nothing to do */
}
void snd_omap_resume_mixer(void)
{
/* The chip was reset, restore the last used values */
set_dac_gain_stereo(vol[0], vol[1]);
tsc2102_set_mute(mute[0], mute[1]);
tsc2102_set_deemphasis(filter[0]);
tsc2102_set_bassboost(filter[1]);
}
#endif
int snd_omap_mixer(struct snd_card_omap_codec *tsc2102)
{
int i, err;
if (!tsc2102)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(tsc2102_control); i ++) {
err = snd_ctl_add(tsc2102->card,
snd_ctl_new1(&tsc2102_control[i],
tsc2102->card));
if (err < 0)
return err;
}
return 0;
}
/*
* sound/arm/omap/omap-alsa-tsc2102.c
*
* Alsa codec driver for TSC2102 chip for OMAP platforms.
*
* Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
* Code based on the TSC2101 ALSA driver.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/delay.h>
#include <linux/soundcard.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/spi/tsc2102.h>
#include <asm/arch/mcbsp.h>
#include <asm/arch/dma.h>
#include <asm/arch/clock.h>
#include <asm/arch/omap-alsa.h>
#include "omap-alsa-tsc2102.h"
static struct clk *tsc2102_bclk = 0;
/*
* Hardware capabilities
*/
/* DAC sampling rates (BCLK = 12 MHz) */
static unsigned int rates[] = {
7350, 8000, 8820, 9600, 11025, 12000, 14700,
16000, 22050, 24000, 29400, 32000, 44100, 48000,
};
static snd_pcm_hw_constraint_list_t tsc2102_hw_constraints_rates = {
.count = ARRAY_SIZE(rates),
.list = rates,
.mask = 0,
};
static snd_pcm_hardware_t tsc2102_snd_omap_alsa_playback = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_KNOT,
.rate_min = 7350,
.rate_max = 48000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = 128 * 1024,
.period_bytes_min = 32,
.period_bytes_max = 8 * 1024,
.periods_min = 16,
.periods_max = 255,
.fifo_size = 0,
};
#ifdef DUMP_TSC2102_AUDIO_REGISTERS
static void dump_tsc2102_audio_regs(void) {
printk("TSC2102_AUDIO1_CTRL = 0x%04x\n",
tsc2102_read_sync(TSC2102_AUDIO1_CTRL));
printk("TSC2102_DAC_GAIN_CTRL = 0x%04x\n",
tsc2102_read_sync(TSC2102_DAC_GAIN_CTRL));
printk("TSC2102_AUDIO2_CTRL = 0x%04x\n",
tsc2102_read_sync(TSC2102_AUDIO2_CTRL));
printk("TSC2102_DAC_POWER_CTRL = 0x%04x\n",
tsc2102_read_sync(TSC2102_DAC_POWER_CTRL));
printk("TSC2102_AUDIO3_CTRL = 0x%04x\n",
tsc2102_read_sync(TSC2102_AUDIO_CTRL_3));
printk("TSC2102_LCH_BASS_BOOST_N0 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_N0));
printk("TSC2102_LCH_BASS_BOOST_N1 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_N1));
printk("TSC2102_LCH_BASS_BOOST_N2 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_N2));
printk("TSC2102_LCH_BASS_BOOST_N3 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_N3));
printk("TSC2102_LCH_BASS_BOOST_N4 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_N4));
printk("TSC2102_LCH_BASS_BOOST_N5 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_N5));
printk("TSC2102_LCH_BASS_BOOST_D1 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_D1));
printk("TSC2102_LCH_BASS_BOOST_D2 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_D2));
printk("TSC2102_LCH_BASS_BOOST_D4 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_D4));
printk("TSC2102_LCH_BASS_BOOST_D5 = 0x%04x\n",
tsc2102_read_sync(TSC2102_LCH_BASS_BOOST_D5));
printk("TSC2102_RCH_BASS_BOOST_N0 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_N0));
printk("TSC2102_RCH_BASS_BOOST_N1 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_N1));
printk("TSC2102_RCH_BASS_BOOST_N2 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_N2));
printk("TSC2102_RCH_BASS_BOOST_N3 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_N3));
printk("TSC2102_RCH_BASS_BOOST_N4 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_N4));
printk("TSC2102_RCH_BASS_BOOST_N5 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_N5));
printk("TSC2102_RCH_BASS_BOOST_D1 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_D1));
printk("TSC2102_RCH_BASS_BOOST_D2 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_D2));
printk("TSC2102_RCH_BASS_BOOST_D4 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_D4));
printk("TSC2102_RCH_BASS_BOOST_D5 = 0x%04x\n",
tsc2102_read_sync(TSC2102_RCH_BASS_BOOST_D5));
printk("TSC2102_PLL1_CTRL = 0x%04x\n",
tsc2102_read_sync(TSC2102_PLL1_CTRL));
printk("TSC2102_PLL2_CTRL = 0x%04x\n",
tsc2102_read_sync(TSC2102_PLL2_CTRL));
printk("TSC2102_AUDIO4_CTRL = 0x%04x\n",
tsc2102_read_sync(TSC2102_AUDIO4_CTRL));
}
#endif
/*
* ALSA operations according to board file
*/
static long current_rate = 0;
/*
* Sample rate changing
*/
static void tsc2102_set_samplerate(long sample_rate)
{
int clkgdv = 0;
u16 srgr1, srgr2;
if (sample_rate == current_rate)
return;
current_rate = 0;
if (tsc2102_set_rate(sample_rate))
return;
/* Set the sample rate */
#ifndef TSC_MASTER
clkgdv = CODEC_CLOCK / (sample_rate * (DEFAULT_BITPERSAMPLE * 2 - 1));
if (clkgdv)
srgr1 = (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv));
else
return;
/* Stereo Mode */
srgr2 = CLKSM | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1);
#else
srgr1 = FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv);
srgr2 = GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1);
#endif
OMAP_MCBSP_WRITE(OMAP1510_MCBSP1_BASE, SRGR2, srgr2);
OMAP_MCBSP_WRITE(OMAP1510_MCBSP1_BASE, SRGR1, srgr1);
current_rate = sample_rate;
}
static void tsc2102_configure(void)
{
tsc2102_dac_power(1);
#ifdef TSC_MASTER
tsc2102_set_i2s_master(1);
#else
tsc2102_set_i2s_master(0);
#endif
}
/*
* Omap McBSP clock and Power Management configuration
*
* Here we have some functions that allow clock to be enabled and
* disabled only when needed. Besides doing clock configuration
* they allow turn audio on and off when necessary.
*/
/*
* Do clock framework bclk search
*/
static void tsc2102_clock_setup(void)
{
tsc2102_bclk = clk_get(0, "bclk");
}
/*
* Do some sanity checks, set clock rate, start it.
*/
static int tsc2102_clock_on(void)
{
int err;
if (clk_get_usecount(tsc2102_bclk) > 0 &&
clk_get_rate(tsc2102_bclk) != CODEC_CLOCK) {
/* BCLK is already in use */
printk(KERN_WARNING
"BCLK already in use at %d Hz. We change it to %d Hz\n",
(uint) clk_get_rate(tsc2102_bclk), CODEC_CLOCK);
err = clk_set_rate(tsc2102_bclk, CODEC_CLOCK);
if (err)
printk(KERN_WARNING "Cannot set BCLK clock rate "
"for TSC2102 codec, error code = %d\n", err);
}
clk_enable(tsc2102_bclk);
return 0;
}
/*
* Turn off the audio codec and then stop the clock.
*/
static int tsc2102_clock_off(void)
{
DPRINTK("clock use count = %d\n", clk_get_usecount(tsc2102_bclk));
clk_disable(tsc2102_bclk);
return 0;
}
static int tsc2102_get_default_samplerate(void)
{
return DEFAULT_SAMPLE_RATE;
}
static int snd_omap_alsa_tsc2102_suspend(
struct platform_device *pdev, pm_message_t state)
{
tsc2102_dac_power(0);
current_rate = 0;
return snd_omap_alsa_suspend(pdev, state);
}
static int snd_omap_alsa_tsc2102_resume(struct platform_device *pdev)
{
tsc2102_dac_power(1);
#ifdef TSC_MASTER
tsc2102_set_i2s_master(1);
#else
tsc2102_set_i2s_master(0);
#endif
return snd_omap_alsa_resume(pdev);
}
static int __init snd_omap_alsa_tsc2102_probe(struct platform_device *pdev)
{
int ret;
struct omap_alsa_codec_config *codec_cfg = pdev->dev.platform_data;
if (codec_cfg) {
codec_cfg->hw_constraints_rates =
&tsc2102_hw_constraints_rates;
codec_cfg->snd_omap_alsa_playback =
&tsc2102_snd_omap_alsa_playback;
codec_cfg->codec_configure_dev = tsc2102_configure;
codec_cfg->codec_set_samplerate = tsc2102_set_samplerate;
codec_cfg->codec_clock_setup = tsc2102_clock_setup;
codec_cfg->codec_clock_on = tsc2102_clock_on;
codec_cfg->codec_clock_off = tsc2102_clock_off;
codec_cfg->get_default_samplerate =
tsc2102_get_default_samplerate;
ret = snd_omap_alsa_post_probe(pdev, codec_cfg);
} else
ret = -ENODEV;
return ret;
}
static int snd_omap_alsa_tsc2102_remove(struct platform_device *pdev)
{
tsc2102_dac_power(0);
return snd_omap_alsa_remove(pdev);
}
static struct platform_driver omap_alsa_driver = {
.probe = snd_omap_alsa_tsc2102_probe,
.remove = snd_omap_alsa_tsc2102_remove,
.suspend = snd_omap_alsa_tsc2102_suspend,
.resume = snd_omap_alsa_tsc2102_resume,
.driver = {
.name = "tsc2102-alsa",
.owner = THIS_MODULE,
},
};
static int __init omap_alsa_tsc2102_init(void)
{
int err;
ADEBUG();
err = platform_driver_register(&omap_alsa_driver);
return err;
}
static void __exit omap_alsa_tsc2102_exit(void)
{
ADEBUG();
platform_driver_unregister(&omap_alsa_driver);
}
module_init(omap_alsa_tsc2102_init);
module_exit(omap_alsa_tsc2102_exit);
/*
* sound/arm/omap/omap-alsa-tsc2102.h
*
* Alsa codec driver for TSC2102 chip for OMAP platforms.
*
* Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
* Code based on the TSC2101 ALSA driver.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#ifndef OMAP_ALSA_TSC2102_H_
#define OMAP_ALSA_TSC2102_H_
/* Define to set the tsc as the master w.r.t McBSP */
#define TSC_MASTER
/*
* Audio related macros
*/
#ifndef DEFAULT_BITPERSAMPLE
#define DEFAULT_BITPERSAMPLE 16
#endif
#define DEFAULT_SAMPLE_RATE 44100
#define CODEC_CLOCK 12000000
#define AUDIO_MCBSP OMAP_MCBSP1
/*
* ALSA mixer related macros
*/
#define OUTPUT_VOLUME_MIN 0x7f /* 1111111 = -63.5 dB */
#define OUTPUT_VOLUME_MAX 0x00 /* 0000000 */
#define OUTPUT_VOLUME_RANGE (OUTPUT_VOLUME_MIN - OUTPUT_VOLUME_MAX)
#define DEFAULT_OUTPUT_VOLUME 90 /* Default output volume */
#endif /* OMAP_ALSA_TSC2102_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment