diff options
| author | Koen Kooi <koen@openembedded.org> | 2008-09-04 16:39:33 +0000 |
|---|---|---|
| committer | Koen Kooi <koen@openembedded.org> | 2008-09-04 16:39:33 +0000 |
| commit | 7a66e7a528dd38a5ea363c30f7110967b6cdd03c (patch) | |
| tree | b1bfa7bb4555aec907eea4cd17377829d0894964 | |
| parent | 474a816e54c0c5e3135e05eb91022024e1e437b5 (diff) | |
linux-omap: a new recipe to build omap1, omap2 and omap3 kernels
44 files changed, 5068 insertions, 0 deletions
diff --git a/packages/linux/linux-omap/.mtn2git_empty b/packages/linux/linux-omap/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-omap/.mtn2git_empty diff --git a/packages/linux/linux-omap/000-mru-make-video-mode-selcatable.diff b/packages/linux/linux-omap/000-mru-make-video-mode-selcatable.diff new file mode 100644 index 0000000000..e36aeb5cff --- /dev/null +++ b/packages/linux/linux-omap/000-mru-make-video-mode-selcatable.diff @@ -0,0 +1,155 @@ +From: Mans Rullgard <mans@mansr.com> +Date: Mon, 18 Aug 2008 22:55:09 +0000 (+0100) +Subject: OMAP: Make video mode commandline-selectable from pre-defined list +X-Git-Tag: beagle-9 +X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=c76a61167997a1dc680c421b1cdb753dfd492b0a + +OMAP: Make video mode commandline-selectable from pre-defined list + +This adds a (small) list of video modes and allows one to be +selected with video=omapfb:mode:name on the command line, +overriding the defaults from lcd_*.c. + +Signed-off-by: Mans Rullgard <mans@mansr.com> +--- + +diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h +index a4a84f3..92e9ffd 100644 +--- a/arch/arm/plat-omap/include/mach/omapfb.h ++++ b/arch/arm/plat-omap/include/mach/omapfb.h +@@ -192,6 +192,20 @@ enum omapfb_update_mode { + + struct omapfb_device; + ++struct video_mode { ++ const char *name; ++ int x_res, y_res; ++ int pixel_clock; /* In kHz */ ++ int hsw; /* Horizontal synchronization ++ pulse width */ ++ int hfp; /* Horizontal front porch */ ++ int hbp; /* Horizontal back porch */ ++ int vsw; /* Vertical synchronization ++ pulse width */ ++ int vfp; /* Vertical front porch */ ++ int vbp; /* Vertical back porch */ ++}; ++ + struct lcd_panel { + const char *name; + int config; /* TFT/STN, signal inversion */ +diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c +index 24242b9..f2229b1 100644 +--- a/drivers/video/omap/omapfb_main.c ++++ b/drivers/video/omap/omapfb_main.c +@@ -40,6 +40,7 @@ static unsigned long def_vxres; + static unsigned long def_vyres; + static unsigned int def_rotate; + static unsigned int def_mirror; ++static int def_mode = -1; + + #ifdef CONFIG_FB_OMAP_MANUAL_UPDATE + static int manual_update = 1; +@@ -80,6 +81,57 @@ static struct caps_table_struct color_caps[] = { + { 1 << OMAPFB_COLOR_YUY422, "YUY422", }, + }; + ++static const struct video_mode video_modes[] = { ++ { ++ .name = "1280x720@50", ++ .x_res = 1280, ++ .y_res = 720, ++ .hfp = 440, ++ .hsw = 40, ++ .hbp = 220, ++ .vfp = 20, ++ .vsw = 5, ++ .vbp = 5, ++ .pixel_clock = 74250, ++ }, ++ { ++ .name = "1280x720@60", ++ .x_res = 1280, ++ .y_res = 720, ++ .hfp = 110, ++ .hsw = 40, ++ .hbp = 220, ++ .vfp = 20, ++ .vsw = 5, ++ .vbp = 5, ++ .pixel_clock = 74250, ++ }, ++ { ++ .name = "1920x1080@24", ++ .x_res = 1920, ++ .y_res = 1080, ++ .hfp = 148, ++ .hsw = 44, ++ .hbp = 638, ++ .vfp = 36, ++ .vsw = 5, ++ .vbp = 4, ++ .pixel_clock = 74160, ++ }, ++ { ++ .name = "1920x1080@25", ++ .x_res = 1920, ++ .y_res = 1080, ++ .hfp = 148, ++ .hsw = 44, ++ .hbp = 528, ++ .vfp = 36, ++ .vsw = 5, ++ .vbp = 4, ++ .pixel_clock = 74250, ++ } ++}; ++ + /* + * --------------------------------------------------------------------------- + * LCD panel +@@ -1711,6 +1763,18 @@ static int omapfb_do_probe(struct platform_device *pdev, + goto cleanup; + } + ++ if (def_mode != -1) { ++ fbdev->panel->x_res = video_modes[def_mode].x_res; ++ fbdev->panel->y_res = video_modes[def_mode].y_res; ++ fbdev->panel->pixel_clock = video_modes[def_mode].pixel_clock; ++ fbdev->panel->hsw = video_modes[def_mode].hsw; ++ fbdev->panel->hfp = video_modes[def_mode].hfp; ++ fbdev->panel->hbp = video_modes[def_mode].hbp; ++ fbdev->panel->vsw = video_modes[def_mode].vsw; ++ fbdev->panel->vfp = video_modes[def_mode].vfp; ++ fbdev->panel->vbp = video_modes[def_mode].vbp; ++ } ++ + r = fbdev->panel->init(fbdev->panel, fbdev); + if (r) + goto cleanup; +@@ -1867,6 +1931,16 @@ static struct platform_driver omapfb_driver = { + }, + }; + ++static int __init omapfb_find_mode(char *mode) ++{ ++ int i; ++ ++ for (i = 0; i < sizeof(video_modes)/sizeof(video_modes[0]); i++) ++ if (!strcmp(mode, video_modes[i].name)) ++ return i; ++ return -1; ++} ++ + #ifndef MODULE + + /* Process kernel command line parameters */ +@@ -1915,6 +1989,8 @@ static int __init omapfb_setup(char *options) + def_mirror = (simple_strtoul(this_opt + 7, NULL, 0)); + else if (!strncmp(this_opt, "manual_update", 13)) + manual_update = 1; ++ else if (!strncmp(this_opt, "mode:", 5)) ++ def_mode = omapfb_find_mode(this_opt + 5); + else { + pr_debug("omapfb: invalid option\n"); + r = -1; diff --git a/packages/linux/linux-omap/0001-ASoC-OMAP-Add-basic-support-for-OMAP34xx-in-McBSP.patch b/packages/linux/linux-omap/0001-ASoC-OMAP-Add-basic-support-for-OMAP34xx-in-McBSP.patch new file mode 100644 index 0000000000..6e31ead2bd --- /dev/null +++ b/packages/linux/linux-omap/0001-ASoC-OMAP-Add-basic-support-for-OMAP34xx-in-McBSP.patch @@ -0,0 +1,55 @@ +From a1dbb6dd28e9815a307b87b8d96dcf371d6cfd58 Mon Sep 17 00:00:00 2001 +From: Jarkko Nikula <jarkko.nikula@nokia.com> +Date: Mon, 19 May 2008 13:24:41 +0300 +Subject: [PATCH] ASoC: OMAP: Add basic support for OMAP34xx in McBSP DAI driver + +This adds support for OMAP34xx McBSP port 1 and 2. + +Signed-off-by: Jarkko Nikula <jarkko.nikula@nokia.com> +--- + sound/soc/omap/omap-mcbsp.c | 20 +++++++++++++++++++- + 1 files changed, 19 insertions(+), 1 deletions(-) + +diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c +index 40d87e6..8e6ec9d 100644 +--- a/sound/soc/omap/omap-mcbsp.c ++++ b/sound/soc/omap/omap-mcbsp.c +@@ -99,6 +99,21 @@ static const unsigned long omap2420_mcbsp_port[][2] = { + static const int omap2420_dma_reqs[][2] = {}; + static const unsigned long omap2420_mcbsp_port[][2] = {}; + #endif ++#if defined(CONFIG_ARCH_OMAP34XX) ++static const int omap34xx_dma_reqs[][2] = { ++ { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX }, ++ { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX }, ++}; ++static const unsigned long omap34xx_mcbsp_port[][2] = { ++ { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR2, ++ OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR2 }, ++ { OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR2, ++ OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR2 }, ++}; ++#else ++static const int omap34xx_dma_reqs[][2] = {}; ++static const unsigned long omap34xx_mcbsp_port[][2] = {}; ++#endif + + static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) + { +@@ -169,9 +184,12 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, + } else if (cpu_is_omap2420()) { + dma = omap2420_dma_reqs[bus_id][substream->stream]; + port = omap2420_mcbsp_port[bus_id][substream->stream]; ++ } else if (cpu_is_omap343x()) { ++ dma = omap34xx_dma_reqs[bus_id][substream->stream]; ++ port = omap34xx_mcbsp_port[bus_id][substream->stream]; + } else { + /* +- * TODO: Add support for 2430 and 3430 ++ * TODO: Add support for 2430 + */ + return -ENODEV; + } +-- +1.5.5.1 + diff --git a/packages/linux/linux-omap/001-mru-enable-overlay.diff b/packages/linux/linux-omap/001-mru-enable-overlay.diff new file mode 100644 index 0000000000..8666c4ac9a --- /dev/null +++ b/packages/linux/linux-omap/001-mru-enable-overlay.diff @@ -0,0 +1,113 @@ +From: Mans Rullgard <mans@mansr.com> +Date: Thu, 28 Aug 2008 21:20:39 +0000 (+0100) +Subject: OMAP: Enable overlay optimisation when possible +X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=5a7378bb691e76ce247f39f79e1a928166f1aed9 + +OMAP: Enable overlay optimisation when possible +--- + +diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c +index 7c525f5..1d56ee0 100644 +--- a/drivers/video/omap/dispc.c ++++ b/drivers/video/omap/dispc.c +@@ -315,6 +315,60 @@ void omap_dispc_enable_digit_out(int enable) + } + EXPORT_SYMBOL(omap_dispc_enable_digit_out); + ++#define MIN(a, b) ((a)<(b)?(a):(b)) ++#define MAX(a, b) ((a)>(b)?(a):(b)) ++ ++static void setup_overlay_opt(void) ++{ ++ struct fb_info **fbi = dispc.fbdev->fb_info; ++ struct omapfb_plane_struct *gfx, *vid; ++ struct fb_var_screeninfo *gvar; ++ unsigned gx, gx2, gy, gy2, gw, gh; ++ unsigned vx, vx2, vy, vy2, vw, vh; ++ unsigned bpp, skip; ++ static unsigned last_skip; ++ ++ if (!fbi[0] || !fbi[1]) ++ return; ++ ++ gfx = fbi[0]->par; ++ vid = fbi[1]->par; ++ gvar = &fbi[0]->var; ++ ++ gx = gfx->info.pos_x; ++ gy = gfx->info.pos_y; ++ gw = gfx->info.out_width; ++ gh = gfx->info.out_height; ++ vx = vid->info.pos_x; ++ vy = vid->info.pos_y; ++ vw = vid->info.out_width; ++ vh = vid->info.out_height; ++ gx2 = gx + gw; ++ gy2 = gy + gh; ++ vx2 = vx + vw; ++ vy2 = vy + vh; ++ bpp = gvar->bits_per_pixel / 8; ++ ++ if (!gfx->info.enabled || !vid->info.enabled || ++ dispc.color_key.key_type != OMAPFB_COLOR_KEY_DISABLED) { ++ skip = 0; ++ } else if (vx <= gx && vx2 >= gx2) { ++ unsigned y = MIN(gy2, vy2) - MAX(gy, vy); ++ skip = y * gvar->xres_virtual * bpp; ++ } else if (vx <= gx || vx2 >= gx2) { ++ unsigned x = MIN(gx2, vx2) - MAX(gx, vx); ++ skip = x * bpp; ++ } else { ++ skip = vw * bpp + 1; ++ } ++ ++ if (skip != last_skip) { ++ last_skip = skip; ++ dispc_write_reg(DISPC_GFX_WINDOW_SKIP, skip); ++ MOD_REG_FLD(DISPC_CONTROL, 1<<12, !!skip<<12); ++ } ++} ++ + static inline int _setup_plane(int plane, int channel_out, + u32 paddr, int screen_width, + int pos_x, int pos_y, int width, int height, +@@ -437,6 +491,9 @@ static inline int _setup_plane(int plane, int channel_out, + + dispc_write_reg(ri_reg[plane], (screen_width - width) * bpp / 8 + 1); + ++ if (plane < 2) ++ setup_overlay_opt(); ++ + MOD_REG_FLD(DISPC_CONTROL, 1<<5, 1<<5); + + return height * screen_width * bpp / 8; +@@ -586,13 +643,19 @@ static int omap_dispc_enable_plane(int plane, int enable) + const u32 at_reg[] = { DISPC_GFX_ATTRIBUTES, + DISPC_VID1_BASE + DISPC_VID_ATTRIBUTES, + DISPC_VID2_BASE + DISPC_VID_ATTRIBUTES }; +- unsigned overlay_opt = plane & !!enable & !dispc.color_key.key_type; ++ struct omapfb_plane_struct *pi; ++ + if ((unsigned int)plane > dispc.mem_desc.region_cnt) + return -EINVAL; + ++ pi = dispc.fbdev->fb_info[plane]->par; ++ pi->info.enabled = enable; ++ + enable_lcd_clocks(1); + MOD_REG_FLD(at_reg[plane], 1, enable ? 1 : 0); +- MOD_REG_FLD(DISPC_CONTROL, 1<<12 | 1<<5, overlay_opt<<12 | 1<<5); ++ if (plane < 2) ++ setup_overlay_opt(); ++ MOD_REG_FLD(DISPC_CONTROL, 1<<5, 1<<5); + enable_lcd_clocks(0); + + return 0; +@@ -636,6 +699,7 @@ static int omap_dispc_set_color_key(struct omapfb_color_key *ck) + if (val != 0) + dispc_write_reg(tr_reg, ck->trans_key); + dispc_write_reg(df_reg, ck->background); ++ setup_overlay_opt(); + enable_lcd_clocks(0); + + dispc.color_key = *ck; diff --git a/packages/linux/linux-omap/001-sakoman-twl4030-asoc.diff b/packages/linux/linux-omap/001-sakoman-twl4030-asoc.diff new file mode 100644 index 0000000000..d9f028a90c --- /dev/null +++ b/packages/linux/linux-omap/001-sakoman-twl4030-asoc.diff @@ -0,0 +1,875 @@ +From: Steve Sakoman <steve@sakoman.com> +Date: Thu, 4 Sep 2008 04:32:11 +0000 (-0700) +Subject: SOUND: SOC: CODECS: Add support for the TWL4030 audio codec +X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=16fc70d77268043edb76946e86a3d776bad26a45 + +SOUND: SOC: CODECS: Add support for the TWL4030 audio codec +--- + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 1db04a2..2f00e1e 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -50,3 +50,8 @@ config SND_SOC_CS4270_VD33_ERRATA + config SND_SOC_TLV320AIC3X + tristate + depends on I2C ++ ++config SND_SOC_TWL4030 ++ tristate ++ depends on SND_SOC && I2C ++ +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index d7b97ab..a519ced 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -10,6 +10,7 @@ snd-soc-wm9712-objs := wm9712.o + snd-soc-wm9713-objs := wm9713.o + snd-soc-cs4270-objs := cs4270.o + snd-soc-tlv320aic3x-objs := tlv320aic3x.o ++snd-soc-twl4030-objs := twl4030.o + + obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o + obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o +@@ -23,3 +24,4 @@ obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o + obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o + obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o + obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o ++obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o +diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c +new file mode 100644 +index 0000000..683b8a1 +--- /dev/null ++++ b/sound/soc/codecs/twl4030.c +@@ -0,0 +1,628 @@ ++/* ++ * ALSA SoC TWL4030 codec driver ++ * ++ * Author: Steve Sakoman, <steve@sakoman.com> ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * 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., 51 Franklin St, Fifth Floor, Boston, MA ++ * 02110-1301 USA ++ * ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <linux/pm.h> ++#include <linux/i2c.h> ++#include <linux/platform_device.h> ++#include <linux/i2c/twl4030.h> ++#include <sound/core.h> ++#include <sound/pcm.h> ++#include <sound/pcm_params.h> ++#include <sound/soc.h> ++#include <sound/soc-dapm.h> ++#include <sound/initval.h> ++ ++#include "twl4030.h" ++ ++/* ++ * twl4030 register cache & default register settings ++ */ ++static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { ++ 0x00, /* this register not used */ ++ 0x93, /* REG_CODEC_MODE (0x1) */ ++ 0xc3, /* REG_OPTION (0x2) */ ++ 0x00, /* REG_UNKNOWN (0x3) */ ++ 0x00, /* REG_MICBIAS_CTL (0x4) */ ++ 0x24, /* REG_ANAMICL (0x5) */ ++ 0x04, /* REG_ANAMICR (0x6) */ ++ 0x0a, /* REG_AVADC_CTL (0x7) */ ++ 0x00, /* REG_ADCMICSEL (0x8) */ ++ 0x00, /* REG_DIGMIXING (0x9) */ ++ 0x0c, /* REG_ATXL1PGA (0xA) */ ++ 0x0c, /* REG_ATXR1PGA (0xB) */ ++ 0x00, /* REG_AVTXL2PGA (0xC) */ ++ 0x00, /* REG_AVTXR2PGA (0xD) */ ++ 0x01, /* REG_AUDIO_IF (0xE) */ ++ 0x00, /* REG_VOICE_IF (0xF) */ ++ 0x00, /* REG_ARXR1PGA (0x10) */ ++ 0x00, /* REG_ARXL1PGA (0x11) */ ++ 0x6c, /* REG_ARXR2PGA (0x12) */ ++ 0x6c, /* REG_ARXL2PGA (0x13) */ ++ 0x00, /* REG_VRXPGA (0x14) */ ++ 0x00, /* REG_VSTPGA (0x15) */ ++ 0x00, /* REG_VRX2ARXPGA (0x16) */ ++ 0x0c, /* REG_AVDAC_CTL (0x17) */ ++ 0x00, /* REG_ARX2VTXPGA (0x18) */ ++ 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ ++ 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ ++ 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */ ++ 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */ ++ 0x00, /* REG_ATX2ARXPGA (0x1D) */ ++ 0x00, /* REG_BT_IF (0x1E) */ ++ 0x00, /* REG_BTPGA (0x1F) */ ++ 0x00, /* REG_BTSTPGA (0x20) */ ++ 0x00, /* REG_EAR_CTL (0x21) */ ++ 0x24, /* REG_HS_SEL (0x22) */ ++ 0x0a, /* REG_HS_GAIN_SET (0x23) */ ++ 0x00, /* REG_HS_POPN_SET (0x24) */ ++ 0x00, /* REG_PREDL_CTL (0x25) */ ++ 0x00, /* REG_PREDR_CTL (0x26) */ ++ 0x00, /* REG_PRECKL_CTL (0x27) */ ++ 0x00, /* REG_PRECKR_CTL (0x28) */ ++ 0x00, /* REG_HFL_CTL (0x29) */ ++ 0x00, /* REG_HFR_CTL (0x2A) */ ++ 0x00, /* REG_ALC_CTL (0x2B) */ ++ 0x00, /* REG_ALC_SET1 (0x2C) */ ++ 0x00, /* REG_ALC_SET2 (0x2D) */ ++ 0x00, /* REG_BOOST_CTL (0x2E) */ ++ 0x01, /* REG_SOFTVOL_CTL (0x2F) */ ++ 0x00, /* REG_DTMF_FREQSEL (0x30) */ ++ 0x00, /* REG_DTMF_TONEXT1H (0x31) */ ++ 0x00, /* REG_DTMF_TONEXT1L (0x32) */ ++ 0x00, /* REG_DTMF_TONEXT2H (0x33) */ ++ 0x00, /* REG_DTMF_TONEXT2L (0x34) */ ++ 0x00, /* REG_DTMF_TONOFF (0x35) */ ++ 0x00, /* REG_DTMF_WANONOFF (0x36) */ ++ 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ ++ 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ ++ 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ ++ 0x16, /* REG_APLL_CTL (0x3A) */ ++ 0x00, /* REG_DTMF_CTL (0x3B) */ ++ 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */ ++ 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */ ++ 0x00, /* REG_MISC_SET_1 (0x3E) */ ++ 0x00, /* REG_PCMBTMUX (0x3F) */ ++ 0x00, /* not used (0x40) */ ++ 0x00, /* not used (0x41) */ ++ 0x00, /* not used (0x42) */ ++ 0x00, /* REG_RX_PATH_SEL (0x43) */ ++ 0x00, /* REG_VDL_APGA_CTL (0x44) */ ++ 0x00, /* REG_VIBRA_CTL (0x45) */ ++ 0x00, /* REG_VIBRA_SET (0x46) */ ++ 0x00, /* REG_VIBRA_PWM_SET (0x47) */ ++ 0x00, /* REG_ANAMIC_GAIN (0x48) */ ++ 0x00, /* REG_MISC_SET_2 (0x49) */ ++}; ++ ++static void twl4030_dump_registers(void) ++{ ++ int i = 0; ++ u8 data; ++ ++ printk(KERN_INFO "TWL 4030 Register dump for Audio Module\n"); ++ ++ for (i = REG_CODEC_MODE; i <= REG_MISC_SET_2; i++) { ++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &data, i); ++ printk(KERN_INFO "Register[0x%02x]=0x%02x\n", i, data); ++ } ++} ++ ++/* ++ * read twl4030 register cache ++ */ ++static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec, ++ unsigned int reg) ++{ ++ u8 *cache = codec->reg_cache; ++ ++ return cache[reg]; ++} ++ ++/* ++ * write twl4030 register cache ++ */ ++static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec, ++ u8 reg, u8 value) ++{ ++ u8 *cache = codec->reg_cache; ++ ++ if (reg >= TWL4030_CACHEREGNUM) ++ return; ++ cache[reg] = value; ++} ++ ++/* ++ * write to the twl4030 register space ++ */ ++static int twl4030_write(struct snd_soc_codec *codec, ++ unsigned int reg, unsigned int value) ++{ ++ twl4030_write_reg_cache(codec, reg, value); ++ return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); ++} ++ ++static void twl4030_init_chip(struct snd_soc_codec *codec) ++{ ++ int i; ++ u8 byte; ++ ++ /* clear CODECPDZ prior to setting register defaults */ ++ twl4030_write(codec, REG_CODEC_MODE, ++ twl4030_reg[REG_CODEC_MODE] & ~CODECPDZ); ++ ++ udelay(10); ++ ++ /* set all audio section registers to reasonable defaults */ ++ for (i = REG_OPTION; i <= REG_MISC_SET_2; i++) ++ twl4030_write(codec, i, twl4030_reg[i]); ++ ++} ++ ++static const struct snd_kcontrol_new twl4030_snd_controls[] = { ++ SOC_DOUBLE_R("Master Playback Volume", ++ REG_ARXL2PGA, REG_ARXR2PGA, ++ 0, 127, 0), ++ SOC_DOUBLE_R("Capture Volume", ++ REG_ATXL1PGA, REG_ATXR1PGA, ++ 0, 127, 0), ++}; ++ ++/* add non dapm controls */ ++static int twl4030_add_controls(struct snd_soc_codec *codec) ++{ ++ int err, i; ++ ++ for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) { ++ err = snd_ctl_add(codec->card, ++ snd_soc_cnew(&twl4030_snd_controls[i], ++ codec, NULL)); ++ if (err < 0) ++ return err; ++ } ++ ++ return 0; ++} ++ ++static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { ++ SND_SOC_DAPM_INPUT("INL"), ++ SND_SOC_DAPM_INPUT("INR"), ++ ++ SND_SOC_DAPM_OUTPUT("OUTL"), ++ SND_SOC_DAPM_OUTPUT("OUTR"), ++ ++ SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0), ++ ++ SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0), ++ SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0), ++}; ++ ++static const struct snd_soc_dapm_route intercon[] = { ++ /* outputs */ ++ {"OUTL", NULL, "DACL"}, ++ {"OUTR", NULL, "DACR"}, ++ ++ /* inputs */ ++ {"ADCL", NULL, "INL"}, ++ {"ADCR", NULL, "INR"}, ++}; ++ ++static int twl4030_add_widgets(struct snd_soc_codec *codec) ++{ ++ snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets, ++ ARRAY_SIZE(twl4030_dapm_widgets)); ++ ++ snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); ++ ++ snd_soc_dapm_new_widgets(codec); ++ return 0; ++} ++ ++static void twl4030_power_up(struct snd_soc_codec *codec) ++{ ++ u8 mode, byte, popn, hsgain; ++ ++ /* set CODECPDZ to turn on codec */ ++ mode = twl4030_read_reg_cache(codec, REG_CODEC_MODE); ++ twl4030_write(codec, REG_CODEC_MODE, mode | CODECPDZ); ++ udelay(10); ++ ++ /* initiate offset cancellation */ ++ twl4030_write(codec, REG_ANAMICL, ++ twl4030_reg[REG_ANAMICL] | CNCL_OFFSET_START); ++ ++ /* wait for offset cancellation to complete */ ++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, REG_ANAMICL); ++ while ((byte & CNCL_OFFSET_START) == CNCL_OFFSET_START) ++ twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, ++ &byte, REG_ANAMICL); ++ ++ /* anti-pop when changing analog gain */ ++ twl4030_write(codec, REG_MISC_SET_1, ++ twl4030_reg[REG_MISC_SET_1] | SMOOTH_ANAVOL_EN); ++ ++ /* toggle CODECPDZ as per TRM */ ++ twl4030_write(codec, REG_CODEC_MODE, mode & ~CODECPDZ); ++ udelay(10); ++ ++ twl4030_write(codec, REG_CODEC_MODE, mode | CODECPDZ); ++ udelay(10); ++ ++ /* program anti-pop with bias ramp delay */ ++ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET); ++ popn &= RAMP_DELAY; ++ popn |= RAMP_DELAY_645MS; ++ twl4030_write(codec, REG_HS_POPN_SET, popn); ++ popn |= VMID_EN; ++ twl4030_write(codec, REG_HS_POPN_SET, popn); ++ ++ /* enable output stage and gain setting */ ++ hsgain = HSR_GAIN_0DB | HSL_GAIN_0DB; ++ twl4030_write(codec, REG_HS_GAIN_SET, hsgain); ++ ++ /* enable anti-pop ramp */ ++ popn |= RAMP_EN; ++ twl4030_write(codec, REG_HS_POPN_SET, popn); ++} ++ ++static void twl4030_power_down(struct snd_soc_codec *codec) ++{ ++ u8 popn, hsgain, mode; ++ ++ /* disable anti-pop ramp */ ++ popn = twl4030_read_reg_cache(codec, REG_HS_POPN_SET); ++ popn &= ~RAMP_EN; ++ twl4030_write(codec, REG_HS_POPN_SET, popn); ++ ++ /* disable output stage and gain setting */ |
