From: lamikr <lamikr@cc.jyu.fi>
To: OMAP-Linux <linux-omap-open-source@linux.omap.com>
Subject: [PATCH] Alsa modularisations and support for tsc2101 6/7
Date: Mon, 20 Feb 2006 20:28:11 +0200 [thread overview]
Message-ID: <43FA0A3B.7070303@cc.jyu.fi> (raw)
[-- Attachment #1: Type: text/plain, Size: 243 bytes --]
ALSA Omap Patch
This patch creates support for tsc2101 codec for alsa omap. Tested with
boards H2 and iPAQ h6300.
signed-off by Mika Laitio <lamikr@cc.jyu.fi>
signed-off by Daniel Petrini <d.pensator@gmail.com>
----------------
Mika Laitio
[-- Attachment #2: alsa6-20060214.patch --]
[-- Type: text/x-patch, Size: 15119 bytes --]
ALSA Omap Patch
This patch only creates support for tsc2101 codec for alsa omap. Tested with
boards H2 and iPAQ h6300.
signed-off by Mika Laitio <lamikr@cc.jyu.fi>
signed-off by Daniel Petrini <d.pensator@gmail.com>
Index: linux-omap-2.6.git-q/sound/arm/Kconfig
===================================================================
--- linux-omap-2.6.git-q.orig/sound/arm/Kconfig 2006-02-16 08:51:16.000000000 -0400
+++ linux-omap-2.6.git-q/sound/arm/Kconfig 2006-02-16 08:52:45.000000000 -0400
@@ -44,5 +44,19 @@ config SND_OMAP_AIC23
To compile this driver as a module, choose M here: the module
will be called snd-omap-aic23.
+
+config SND_OMAP_TSC2101
+ tristate "OMAP TSC2101 alsa driver"
+ depends on ARCH_OMAP && SND
+ select SND_PCM
+ select OMAP_TSC2101
+ select OMAP_UWIRE if ARCH_OMAP
+ help
+ Say Y here if you have a OMAP platform board
+ and want to use its TSC2101 audio chip. Driver has
+ been tested with H2 and iPAQ h6300.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-omap-tsc2101.
endmenu
Index: linux-omap-2.6.git-q/arch/arm/mach-omap1/omap-alsa-tsc2101.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-omap-2.6.git-q/arch/arm/mach-omap1/omap-alsa-tsc2101.c 2006-02-16 08:57:48.000000000 -0400
@@ -0,0 +1,346 @@
+/*
+ * arch/arm/mach-omap1/omap-alsa-tsc2101.c
+ *
+ * Alsa codec Driver for TSC2101 chip for OMAP platform boards.
+ * Code obtained from oss omap drivers
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ * Written by Nishanth Menon and Sriram Kannan
+ *
+ * Copyright (C) 2006 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
+ * Alsa modularization by Daniel Petrini (d.pensator@gmail.com)
+ *
+ * Copyright (C) 2006 Mika Laitio (lamikr@cc.jyu.fi)
+ *
+ * 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.
+ *
+ * History:
+ *
+ * 2006-02-08 - Daniel Petrini - File creation. Support file for ALSA wrt codec
+ * tsc2101 that populates H2 and H3.
+ * 2006-02-10 Mika Laitio - Clock on/clock off routines fixed.
+ * tsc2101_set_samplerate() does not take samplerates
+ * that are acceptable as a parameter.
+ */
+/* routines extracted from file oss/omap-audio-tsc2101.c
+ * or called from drivers/ssi/omap-tsc2101.c */
+
+#ifdef CONFIG_SND
+
+#include <linux/delay.h>
+#include <linux/soundcard.h>
+#include <linux/clk.h>
+#include <asm/io.h>
+#include <asm/arch/mcbsp.h>
+
+#include <linux/slab.h>
+#ifdef CONFIG_PM
+#include <linux/pm.h>
+#endif
+#include <asm/mach-types.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/clock.h>
+
+#include <asm/hardware/tsc2101.h>
+#include <../drivers/ssi/omap-tsc2101.h>
+
+#include <asm/arch/omap-alsa.h>
+#include "omap-alsa-tsc2101.h"
+
+static struct clk *tsc2101_mclk = 0;
+
+//#define DUMP_TSC2101_AUDIO_REGISTERS
+#undef DUMP_TSC2101_AUDIO_REGISTERS
+
+static const struct tsc2101_samplerate_reg_info
+ rate_reg_info[NUMBER_SAMPLE_RATES_SUPPORTED] = {
+ /* Div 1 */
+ {48000, 0, 0},
+ {44100, 0, 1},
+ /* Div 1.5 */
+ {32000, 1, 0},
+ {29400, 1, 1},
+ /* Div 2 */
+ {24000, 2, 0},
+ {22050, 2, 1},
+ /* Div 3 */
+ {16000, 3, 0},
+ {14700, 3, 1},
+ /* Div 4 */
+ {12000, 4, 0},
+ {11025, 4, 1},
+ /* Div 5 */
+ {9600, 5, 0},
+ {8820, 5, 1},
+ /* Div 5.5 */
+ {8727, 6, 0},
+ {8018, 6, 1},
+ /* Div 6 */
+ {8000, 7, 0},
+ {7350, 7, 1},
+};
+
+/*
+ * Simplified write for tsc Audio
+ */
+inline void tsc2101_audio_write(u8 address, u16 data)
+{
+ omap_tsc2101_write(PAGE2_AUDIO_CODEC_REGISTERS, address, data);
+}
+
+/*
+ * Simplified read for tsc Audio
+ */
+inline u16 tsc2101_audio_read(u8 address)
+{
+ return (omap_tsc2101_read(PAGE2_AUDIO_CODEC_REGISTERS, address));
+}
+
+#ifdef DUMP_TSC2101_AUDIO_REGISTERS
+void dump_tsc2101_audio_reg(void) {
+ printk("TSC2101_AUDIO_CTRL_1 = 0x%04x\n", tsc2101_audio_read(TSC2101_AUDIO_CTRL_1));
+ printk("TSC2101_HEADSET_GAIN_CTRL = 0x%04x\n", tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL));
+ printk("TSC2101_DAC_GAIN_CTRL = 0x%04x\n", tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL));
+ printk("TSC2101_MIXER_PGA_CTRL = 0x%04x\n", tsc2101_audio_read(TSC2101_MIXER_PGA_CTRL));
+ printk("TSC2101_AUDIO_CTRL_2 = 0x%04x\n", tsc2101_audio_read(TSC2101_AUDIO_CTRL_2));
+ printk("TSC2101_CODEC_POWER_CTRL = 0x%04x\n", tsc2101_audio_read(TSC2101_CODEC_POWER_CTRL));
+ printk("TSC2101_AUDIO_CTRL_3 = 0x%04x\n", tsc2101_audio_read(TSC2101_AUDIO_CTRL_3));
+ printk("TSC2101_LCH_BASS_BOOST_N0 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N0));
+ printk("TSC2101_LCH_BASS_BOOST_N1 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N1));
+ printk("TSC2101_LCH_BASS_BOOST_N2 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N2));
+ printk("TSC2101_LCH_BASS_BOOST_N3 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N3));
+ printk("TSC2101_LCH_BASS_BOOST_N4 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N4));
+ printk("TSC2101_LCH_BASS_BOOST_N5 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_N5));
+ printk("TSC2101_LCH_BASS_BOOST_D1 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_D1));
+ printk("TSC2101_LCH_BASS_BOOST_D2 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_D2));
+ printk("TSC2101_LCH_BASS_BOOST_D4 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_D4));
+ printk("TSC2101_LCH_BASS_BOOST_D5 = 0x%04x\n", tsc2101_audio_read(TSC2101_LCH_BASS_BOOST_D5));
+
+ printk("TSC2101_RCH_BASS_BOOST_N0 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N0));
+ printk("TSC2101_RCH_BASS_BOOST_N1 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N1));
+ printk("TSC2101_RCH_BASS_BOOST_N2 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N2));
+ printk("TSC2101_RCH_BASS_BOOST_N3 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N3));
+ printk("TSC2101_RCH_BASS_BOOST_N4 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N4));
+ printk("TSC2101_RCH_BASS_BOOST_N5 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_N5));
+ printk("TSC2101_RCH_BASS_BOOST_D1 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_D1));
+ printk("TSC2101_RCH_BASS_BOOST_D2 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_D2));
+ printk("TSC2101_RCH_BASS_BOOST_D4 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_D4));
+ printk("TSC2101_RCH_BASS_BOOST_D5 = 0x%04x\n", tsc2101_audio_read(TSC2101_RCH_BASS_BOOST_D5));
+
+ printk("TSC2101_PLL_PROG_1 = 0x%04x\n", tsc2101_audio_read(TSC2101_PLL_PROG_1));
+ printk("TSC2101_PLL_PROG_1 = 0x%04x\n", tsc2101_audio_read(TSC2101_PLL_PROG_2));
+ printk("TSC2101_AUDIO_CTRL_4 = 0x%04x\n", tsc2101_audio_read(TSC2101_AUDIO_CTRL_4));
+ printk("TSC2101_HANDSET_GAIN_CTRL = 0x%04x\n", tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL));
+ printk("TSC2101_BUZZER_GAIN_CTRL = 0x%04x\n", tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL));
+ printk("TSC2101_AUDIO_CTRL_5 = 0x%04x\n", tsc2101_audio_read(TSC2101_AUDIO_CTRL_5));
+ printk("TSC2101_AUDIO_CTRL_6 = 0x%04x\n", tsc2101_audio_read(TSC2101_AUDIO_CTRL_6));
+ printk("TSC2101_AUDIO_CTRL_7 = 0x%04x\n", tsc2101_audio_read(TSC2101_AUDIO_CTRL_7));
+ printk("TSC2101_GPIO_CTRL = 0x%04x\n", tsc2101_audio_read(TSC2101_GPIO_CTRL));
+ printk("TSC2101_AGC_CTRL = 0x%04x\n", tsc2101_audio_read(TSC2101_AGC_CTRL));
+ printk("TSC2101_POWERDOWN_STS = 0x%04x\n", tsc2101_audio_read(TSC2101_POWERDOWN_STS));
+ printk("TSC2101_MIC_AGC_CONTROL = 0x%04x\n", tsc2101_audio_read(TSC2101_MIC_AGC_CONTROL));
+ printk("TSC2101_CELL_AGC_CONTROL = 0x%04x\n", tsc2101_audio_read(TSC2101_CELL_AGC_CONTROL));
+}
+#endif
+
+/*
+ * ALSA operations according to board file
+ */
+
+/*
+ * Sample rate changing
+ */
+void tsc2101_set_samplerate(long sample_rate)
+{
+ u8 count = 0;
+ u16 data = 0;
+ int clkgdv = 0;
+
+ u16 srgr1, srgr2;
+ /* wait for any frame to complete */
+ udelay(125);
+ ADEBUG();
+
+ sample_rate = sample_rate;
+ /* Search for the right sample rate */
+ while ((rate_reg_info[count].sample_rate != sample_rate) &&
+ (count < NUMBER_SAMPLE_RATES_SUPPORTED)) {
+ count++;
+ }
+ if (count == NUMBER_SAMPLE_RATES_SUPPORTED) {
+ printk(KERN_ERR "Invalid Sample Rate %d requested\n",
+ (int) sample_rate);
+ return; // -EPERM;
+ }
+
+ /* Set AC1 */
+ data = tsc2101_audio_read(TSC2101_AUDIO_CTRL_1);
+ /* Clear prev settings */
+ data &= ~(AC1_DACFS(0x07) | AC1_ADCFS(0x07));
+ data |= AC1_DACFS(rate_reg_info[count].divisor) |
+ AC1_ADCFS(rate_reg_info[count].divisor);
+ tsc2101_audio_write(TSC2101_AUDIO_CTRL_1, data);
+
+ /* Set the AC3 */
+ data = tsc2101_audio_read(TSC2101_AUDIO_CTRL_3);
+ /*Clear prev settings */
+ data &= ~(AC3_REFFS | AC3_SLVMS);
+ data |= (rate_reg_info[count].fs_44kHz) ? AC3_REFFS : 0;
+#ifdef TSC_MASTER
+ data |= AC3_SLVMS;
+#endif /* #ifdef TSC_MASTER */
+ tsc2101_audio_write(TSC2101_AUDIO_CTRL_3, data);
+
+ /* program the PLLs */
+ if (rate_reg_info[count].fs_44kHz) {
+ /* 44.1 khz - 12 MHz Mclk */
+ tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL |
+ PLL1_PVAL(1) | PLL1_I_VAL(7)); /* PVAL 1; I_VAL 7 */
+ tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x1490)); /* D_VAL 5264 */
+ } else {
+ /* 48 khz - 12 Mhz Mclk */
+ tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL |
+ PLL1_PVAL(1) | PLL1_I_VAL(8)); /* PVAL 1; I_VAL 8 */
+ tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x780)); /* D_VAL 1920 */
+ }
+
+ /* 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 (1);
+
+ /* 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 /* end of #ifdef TSC_MASTER */
+ OMAP_MCBSP_WRITE(OMAP1610_MCBSP1_BASE, SRGR2, srgr2);
+ OMAP_MCBSP_WRITE(OMAP1610_MCBSP1_BASE, SRGR1, srgr1);
+}
+
+void tsc2101_configure(void)
+{
+ //snd_omap_init_mixer();
+}
+
+/*
+ * Omap MCBSP clock and Power Management configuration
+ *
+ * Here we have some functions that allows clock to be enabled and
+ * disabled only when needed. Besides doing clock configuration
+ * it allows turn on/turn off audio when necessary.
+ */
+
+/*
+ * Do clock framework mclk search
+ */
+void tsc2101_clock_setup(void)
+{
+ tsc2101_mclk = clk_get(0, "mclk");
+}
+
+/*
+ * Do some sanity check, set clock rate, starts it and
+ * turn codec audio on
+ */
+int tsc2101_clock_on(void)
+{
+ int curUseCount;
+ uint curRate;
+ int err;
+
+ curUseCount = clk_get_usecount(tsc2101_mclk);
+ DPRINTK("clock use count = %d\n", curUseCount);
+ if (curUseCount > 0) {
+ // MCLK is already in use
+ printk(KERN_WARNING
+ "MCLK already in use at %d Hz. We change it to %d Hz\n",
+ (uint) clk_get_rate(tsc2101_mclk),
+ CODEC_CLOCK);
+ }
+ curRate = (uint)clk_get_rate(tsc2101_mclk);
+ DPRINTK("old clock rate = %d\n", curRate);
+ if (curRate != CODEC_CLOCK) {
+ err = clk_set_rate(tsc2101_mclk, CODEC_CLOCK);
+ if (err) {
+ printk(KERN_ERR
+ "Cannot set MCLK clock rate for TSC2101 CODEC, error code = %d\n", err);
+ return -ECANCELED;
+ }
+ }
+ else
+ {
+ printk(KERN_INFO
+ "omap_alsa_tsc2101_clock_on(), no need to change rate, no need to change clock rate, rate already %d Hz.\n",
+ CODEC_CLOCK);
+ }
+ err = clk_enable(tsc2101_mclk);
+ curRate = (uint)clk_get_rate(tsc2101_mclk);
+ curUseCount = clk_get_usecount(tsc2101_mclk);
+ DPRINTK("MCLK = %d [%d], usecount = %d, clk_enable retval = %d\n",
+ curRate,
+ CODEC_CLOCK,
+ curUseCount,
+ err);
+
+ // Now turn the audio on
+ omap_tsc2101_write(PAGE2_AUDIO_CODEC_REGISTERS,
+ TSC2101_CODEC_POWER_CTRL,
+ 0x0000);
+ return 0;
+}
+
+/*
+ * Do some sanity check, turn clock off and then turn
+ * codec audio off
+ */
+int tsc2101_clock_off(void)
+{
+ int curUseCount;
+ int curRate;
+
+ curUseCount = clk_get_usecount(tsc2101_mclk);
+ DPRINTK("clock use count = %d\n", curUseCount);
+ if (curUseCount > 0) {
+ curRate = clk_get_rate(tsc2101_mclk);
+ DPRINTK("clock rate = %d\n", curRate);
+ if (curRate != CODEC_CLOCK) {
+ printk(KERN_WARNING
+ "MCLK for audio should be %d Hz. But is %d Hz\n",
+ (uint) clk_get_rate(tsc2101_mclk),
+ CODEC_CLOCK);
+ }
+ clk_disable(tsc2101_mclk);
+ DPRINTK("clock disabled\n");
+ }
+ tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
+ ~(CPC_SP1PWDN | CPC_SP2PWDN | CPC_BASSBC));
+ DPRINTK("audio codec off\n");
+#ifdef DUMP_TSC2101_AUDIO_REGISTERS
+ printk("tsc2101_clock_off()\n");
+ dump_tsc2101_audio_reg();
+#endif
+ return 0;
+}
+
+int tsc2101_get_default_samplerate(void)
+{
+ return DEFAULT_SAMPLE_RATE;
+}
+
+#else
+void tsc2101_configure(void){}
+void tsc2101_set_samplerate(long rate){};
+void tsc2101_clock_setup(void){}
+int tsc2101_clock_on(void){return 0;}
+int tsc2101_clock_off(void){return 0;}
+void tsc2101_get_default_samplerate(void){}
+#endif
Index: linux-omap-2.6.git-q/arch/arm/mach-omap1/omap-alsa-tsc2101.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-omap-2.6.git-q/arch/arm/mach-omap1/omap-alsa-tsc2101.h 2006-02-16 09:02:46.000000000 -0400
@@ -0,0 +1,53 @@
+/*
+ * arch/arc/mach-omap1/omap-alsa-tsc2101.h
+ *
+ * Alsa Driver for TSC2101 codec for OMAP platform boards.
+ *
+ * Based on former omap-aic23.h and tsc2101 OSS drivers.
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ * Written by Nishanth Menon and Sriram Kannan
+ *
+ * Copyright (C) 2006 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
+ * Alsa modularization by Daniel Petrini (d.pensator@gmail.com)
+ *
+ * Copyright (C) 2006 Mika Laitio (lamikr@cc.jyu.fi)
+ *
+ * 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.
+ *
+ * History:
+ *
+ * 2006-02-08 File creation. Support file for codec tsc2101 that populates
+ * H2 and H3.
+ * 2006-02-10 Cleaned unneed variables, moved sample rate reg-info to here.
+ */
+
+#ifndef OMAP_ALSA_TSC2101_H_
+#define OMAP_ALSA_TSC2101_H_
+
+#include <linux/types.h>
+
+/* Define to set the tsc as the master w.r.t McBSP */
+#define TSC_MASTER
+
+#define NUMBER_SAMPLE_RATES_SUPPORTED 16
+
+/*
+ * AUDIO related MACROS
+ */
+#define DEFAULT_BITPERSAMPLE 16
+#define DEFAULT_SAMPLE_RATE 44100
+#define CODEC_CLOCK 12000000
+#define AUDIO_MCBSP OMAP_MCBSP1
+
+#define PAGE2_AUDIO_CODEC_REGISTERS (2)
+
+struct tsc2101_samplerate_reg_info {
+ u16 sample_rate;
+ u8 divisor;
+ u8 fs_44kHz; /* if 0 48 khz, if 1 44.1 khz fsref */
+};
+
+#endif /*OMAP_ALSA_TSC2101_H_*/
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
next reply other threads:[~2006-02-20 18:28 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-20 18:28 lamikr [this message]
2006-02-21 13:39 ` [PATCH] Alsa modularisations and support for tsc2101 6/7 Menon, Nishanth
2006-03-01 22:09 ` lamikr
-- strict thread matches above, loose matches on Subject: below --
2006-03-01 22:18 Menon, Nishanth
2006-03-01 22:28 Khasim, Syed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=43FA0A3B.7070303@cc.jyu.fi \
--to=lamikr@cc.jyu.fi \
--cc=linux-omap-open-source@linux.omap.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox