[Armadeus-commitlog] SF.net SVN: armadeus:[846] trunk/target/linux
Brought to you by:
sszy
|
From: <ar...@us...> - 2008-07-21 17:56:07
|
Revision: 846
http://armadeus.svn.sourceforge.net/armadeus/?rev=846&view=rev
Author: artemys
Date: 2008-07-21 17:56:15 +0000 (Mon, 21 Jul 2008)
Log Message:
-----------
[LINUX] Add very first stage of tools to easily manage our Linux kernel patches generation/maintenance
Added Paths:
-----------
trunk/target/linux/Makefile
trunk/target/linux/arch/
trunk/target/linux/arch/arm/
trunk/target/linux/arch/arm/mach-imx/
trunk/target/linux/arch/arm/mach-imx/apf9328.c
trunk/target/linux/arch/arm/mach-imx/apf9328_lcd_config.h
trunk/target/linux/generate_patch.sh
trunk/target/linux/include/
trunk/target/linux/include/asm-arm/
trunk/target/linux/include/asm-arm/arch-imx/
trunk/target/linux/include/asm-arm/arch-imx/apf9328.h
trunk/target/linux/include/asm-arm/arch-imx/imx-alsa.h
trunk/target/linux/sound/
trunk/target/linux/sound/arm/
trunk/target/linux/sound/arm/imx-alsa-dma.h
trunk/target/linux/sound/arm/imx-alsa-tsc2102-mixer.c
trunk/target/linux/sound/arm/imx-alsa-tsc2102.c
trunk/target/linux/sound/arm/imx-alsa-tsc2102.h
trunk/target/linux/sound/arm/imx-alsa.c
Added: trunk/target/linux/Makefile
===================================================================
--- trunk/target/linux/Makefile (rev 0)
+++ trunk/target/linux/Makefile 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,77 @@
+# To get from Buildroot:
+LINUX_VERSION=2.6.23.1
+TARBALL_DIR=/local/downloads
+BUILD_DIR=../../buildroot/build_arm
+
+LINUX_NAME=linux-$(LINUX_VERSION)
+LINUX_ARCHIVE=$(LINUX_NAME).tar.bz2
+# Working Linux:
+LINUX_DIR=$(BUILD_DIR)/$(LINUX_NAME)
+# Original Linux:
+LINUX_DIR_TO_DIFF=$(LINUX_DIR).original
+
+PATCH_DIR=../../buildroot/target/device/armadeus/linux/kernel-patches/$(LINUX_VERSION)
+TMP_DIR=./tmp
+PATCH_CMD=./generate_patch.sh
+CLEAN_PATCH_CMD=sed --in-place "s,$(LINUX_DIR),$(LINUX_NAME)," $@ && sed --in-place=.bak "s,\.\./linux/,$(LINUX_NAME).mod/," $@
+START_CMD=echo "*** Generating patch: $@"
+
+### ALSA Patches:
+
+$(TMP_DIR)/090-alsa-create-imx-alsa_h.diff: include/asm-arm/arch-imx/imx-alsa.h
+ @$(START_CMD)
+ $(PATCH_CMD) $(LINUX_DIR_TO_DIFF)/$< ../linux/$< $@
+ $(CLEAN_PATCH_CMD)
+ @echo
+PATCHES+=$(TMP_DIR)/090-alsa-create-imx-alsa_h.diff
+
+$(TMP_DIR)/091-alsa-add-imx-ssi-tsc2102-driver.diff: sound/arm/imx-alsa.c sound/arm/imx-alsa-dma.h sound/arm/imx-alsa-tsc2102.c sound/arm/imx-alsa-tsc2102.h sound/arm/imx-alsa-tsc2102-mixer.c
+ @$(START_CMD)
+ for patch in $^; do $(PATCH_CMD) --append $(LINUX_DIR_TO_DIFF)/$$patch ../linux/$$patch $@; done
+ $(CLEAN_PATCH_CMD)
+ @echo
+PATCHES+=$(TMP_DIR)/091-alsa-add-imx-ssi-tsc2102-driver.diff
+
+
+### APF9328 Patches:
+$(TMP_DIR)/021-linux-2.6.23.1-apf9328.diff: arch/arm/mach-imx/apf9328.c arch/arm/mach-imx/apf9328_lcd_config.h include/asm-arm/arch-imx/apf9328.h
+ @$(START_CMD)
+ for patch in $^; do $(PATCH_CMD) --append $(LINUX_DIR_TO_DIFF)/$$patch ../linux/$$patch $@; done
+ $(CLEAN_PATCH_CMD)
+ @echo
+PATCHES+=$(TMP_DIR)/021-linux-2.6.23.1-apf9328.diff
+
+
+### Other Patches:
+
+
+### Patches generation:
+
+.PHONY: clean all help
+
+$(LINUX_DIR_TO_DIFF)/.unpacked:
+ @echo "***Installing original kernel in $(BUILD_DIR)"
+ mv $(LINUX_DIR) $(LINUX_DIR).modified
+ tar jxf $(TARBALL_DIR)/$(LINUX_ARCHIVE) -C $(BUILD_DIR)/
+ mv $(LINUX_DIR) $(LINUX_DIR_TO_DIFF)
+ mv $(LINUX_DIR).modified $(LINUX_DIR)
+ touch $@
+
+patch: $(LINUX_DIR_TO_DIFF)/.unpacked $(PATCHES)
+ mkdir -p ./tmp
+
+patch_install: patch
+ echo $(PATCHES)
+ cp -a $(PATCHES) $(PATCH_DIR)/
+
+help:
+ @echo "make [patch|patch_install|clean|help]"
+ @echo " help: this help"
+ @echo " patch: generate all patches in $(TMP_DIR) directory"
+ @echo " patch_install: install patch in $(PATCH_DIR)"
+
+all: patch
+
+clean:
+ rm -f $(TMP_DIR)/*
+
Added: trunk/target/linux/arch/arm/mach-imx/apf9328.c
===================================================================
--- trunk/target/linux/arch/arm/mach-imx/apf9328.c (rev 0)
+++ trunk/target/linux/arch/arm/mach-imx/apf9328.c 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,570 @@
+/*
+ * linux/arch/arm/mach-imx/apf9328.c
+ *
+ * Copyright (c) 2005 Armadeus
+ * This work is based on scb9328.c from Sascha Hauer
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/serial_8250.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/tsc2102.h>
+#include "../../../drivers/net/can/mcp251x.h"
+
+#include <asm/system.h>
+#include <asm/hardware.h>
+#include <linux/irq.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+
+#include <asm/mach/map.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/arch/imx-uart.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/spi_imx.h>
+#include <asm/arch/imx-regs.h> // imx_gpio_mode()
+#include <asm/arch/imx-alsa.h>
+
+#ifdef CONFIG_DM9000
+#include <linux/dm9000.h>
+#endif // CONFIG_DM9000
+
+#include "generic.h"
+
+#ifdef CONFIG_SENSORS_MAX1027_MODULE
+#define CONFIG_SENSORS_MAX1027 1
+#endif
+#ifdef CONFIG_SPI_IMX_MODULE
+#define CONFIG_SPI_IMX 1
+#endif
+#ifdef CONFIG_SPI_TSC2102_MODULE
+#define CONFIG_SPI_TSC2102 1
+#endif
+#ifdef CONFIG_CAN_MCP251X_MODULE
+#define CONFIG_CAN_MCP251X 1
+#endif
+#ifdef CONFIG_IMX_BACKLIGHT_MODULE
+#define CONFIG_IMX_BACKLIGHT 1
+#endif
+
+// --- ETHERNET RESSOURCE ---
+#ifdef CONFIG_DM9000
+static struct resource dm9000_resources[] = {
+ [0] = {
+ .start = (APF9328_ETH_PHYS + 0),
+ .end = (APF9328_ETH_PHYS + 1),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (APF9328_ETH_PHYS + 2),
+ .end = (APF9328_ETH_PHYS + 3),
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = (APF9328_ETH_IRQ),
+ .end = (APF9328_ETH_IRQ),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct dm9000_plat_data dm9000_setup = {
+ .flags = DM9000_PLATF_16BITONLY
+};
+
+static struct platform_device dm9000x_device = {
+ .name = "dm9000",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(dm9000_resources),
+ .resource = dm9000_resources,
+ .dev = { .platform_data = &dm9000_setup, },
+};
+#endif // CONFIG_DM9000
+
+// --- PWM RESSOURCE ---
+// I don't think it needs an ifdef - JB
+static struct resource pwm_resources[] = {
+ [0] = {
+ .start = (IMX_PWM_BASE),
+ .end = (IMX_PWM_BASE + 0x0C),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (PWM_INT),
+ .end = (PWM_INT),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device imx_pwm_device = {
+ .name = "imx-pwm", // Should be the same as the driver name
+ .id = 0,
+ .num_resources = ARRAY_SIZE(pwm_resources),
+ .resource = pwm_resources,
+};
+
+#if defined(CONFIG_SND_IMX_TSC2102) || defined(CONFIG_SND_IMX_TSC2102_MODULE)
+static struct imx_alsa_codec_config tsc2102_alsa_pdata;
+
+static struct resource ssi_resources[] = {
+ [0] = {
+ .start = (IMX_SSI_BASE),
+ .end = (IMX_SSI_BASE + 0x28),
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device tsc2102_alsa_device = {
+ .name = "tsc2102-alsa", // Should be the same as the driver name
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ssi_resources),
+ .resource = ssi_resources,
+ .dev = {
+ .platform_data = &tsc2102_alsa_pdata,
+ }
+};
+#endif // defined(CONFIG_SND_IMX_TSC2102) || defined(CONFIG_SND_IMX_TSC2102_MODULE)
+
+
+// --- SERIAL RESSOURCE ---
+static struct imxuart_platform_data uart_pdata = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct resource imx_uart1_resources[] = {
+ [0] = {
+ .start = 0x00206000,
+ .end = 0x002060FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (UART1_MINT_RX),
+ .end = (UART1_MINT_RX),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = (UART1_MINT_TX),
+ .end = (UART1_MINT_TX),
+ .flags = IORESOURCE_IRQ,
+},
+};
+
+static struct platform_device imx_uart1_device = {
+ .name = "imx-uart",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(imx_uart1_resources),
+ .resource = imx_uart1_resources,
+ .dev = {
+ .platform_data = &uart_pdata,
+ }
+};
+
+static struct resource imx_uart2_resources[] = {
+ [0] = {
+ .start = 0x00207000,
+ .end = 0x002070FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = (UART2_MINT_RX),
+ .end = (UART2_MINT_RX),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = (UART2_MINT_TX),
+ .end = (UART2_MINT_TX),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device imx_uart2_device = {
+ .name = "imx-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(imx_uart2_resources),
+ .resource = imx_uart2_resources,
+ .dev = {
+ .platform_data = &uart_pdata,
+ }
+};
+
+#ifdef CONFIG_SPI_IMX
+static struct resource imx_spi1_resource[] = {
+ [0] = {
+ .start = 0x00213000,
+ .end = 0x00213fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CSPI_INT,
+ .end = CSPI_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct spi_imx_master imx_spi1_master_info = {
+ .num_chipselect = 1,
+ .enable_dma = 0,
+};
+
+static struct platform_device imx_spi1 = {
+ .name = "spi_imx",
+ .id = 1,
+ .resource = imx_spi1_resource,
+ .num_resources = ARRAY_SIZE(imx_spi1_resource),
+ .dev = {
+ .platform_data = &imx_spi1_master_info,
+ },
+};
+
+static struct resource imx_spi2_resource[] = {
+ [0] = {
+ .start = 0x00219000,
+ .end = 0x00219fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = SPI2_INT,
+ .end = SPI2_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct spi_imx_master imx_spi2_master_info = {
+ .num_chipselect = 1,
+ .enable_dma = 0,
+};
+
+static struct platform_device imx_spi2 = {
+ .name = "spi_imx",
+ .id = 2,
+ .resource = imx_spi2_resource,
+ .num_resources = ARRAY_SIZE(imx_spi2_resource),
+ .dev = {
+ .platform_data = &imx_spi2_master_info,
+ },
+};
+
+#endif //CONFIG_SPI_IMX
+
+#ifdef CONFIG_SENSORS_MAX1027
+#define IMX_SPI1_SS_PIN 15
+#define IMX_SPI1_SS (1<<15)
+static void max1027_init_cs(void)
+{
+ // SPI CSn is used as chip select but in GPIO mode
+ OCR1(2) |= 3<<(IMX_SPI1_SS_PIN*2);
+ DDIR(2) |= IMX_SPI1_SS;
+ DR(2) |= IMX_SPI1_SS;
+ GIUS(2) |= IMX_SPI1_SS;
+ GIUS(2) &= ~(1<<14 | 1<<16 | 1<< 17); // Set SPI primary functions
+}
+static void max1027_cs(u32 command)
+{
+ if( command == SPI_CS_DEASSERT )
+ DR(2) |= IMX_SPI1_SS;
+ else
+ DR(2) &= ~IMX_SPI1_SS;
+}
+
+static struct spi_imx_chip max1027_hw = {
+ .cs_control = max1027_cs,
+};
+
+#endif // CONFIG_SENSORS_MAX1027
+
+#ifdef CONFIG_SPI_TSC2102
+#define TSC2102_CS_GPIOB 17
+#define TSC2102_INT_GPIOD 8
+
+static void tsc2102_init_gpio(void)
+{
+ // Activate SPI2 port ----
+ // PortB 17 is used as chip select (in GPIO mode)
+ DR(1) |= 1 << TSC2102_CS_GPIOB; // Initializes it High
+ imx_gpio_mode( GPIO_PORTB | TSC2102_CS_GPIOB | GPIO_OUT | GPIO_GIUS | GPIO_DR );
+ // Configure SPI2 outputs
+ imx_gpio_mode( PD7_AIN_SPI2_SCLK );
+ imx_gpio_mode( PD10_AIN_SPI2_TXD );
+ imx_gpio_mode( PD9_AOUT_SPI2_RXD );
+ FMCR |= SPI2_RXD_SEL; // RX is AOUT on PORTD
+
+ // PortD 8 is used as PINTDAV interrupt
+ imx_gpio_mode( GPIO_PORTD | TSC2102_INT_GPIOD | GPIO_IN | GPIO_GIUS );
+ //imx_gpio_irq_type( IRQ_GPIOD(8), __IRQT_FALEDGE );
+
+ // Activate SSI on PortC ----
+ imx_gpio_mode( PC3_PF_SSI_RXFS );
+ FMCR &= ~(SSI_RXFS_SEL);
+ imx_gpio_mode( PC4_PF_SSI_RXCLK );
+ FMCR &= ~(SSI_RXCLK_SEL);
+ imx_gpio_mode( PC5_PF_SSI_RXDAT );
+ FMCR &= ~(SSI_RXDAT_SEL);
+ imx_gpio_mode( PC6_PF_SSI_TXDAT );
+ imx_gpio_mode( PC7_PF_SSI_TXFS );
+ FMCR &= ~(SSI_TXFS_SEL);
+ imx_gpio_mode( PC8_PF_SSI_TXCLK );
+ FMCR &= ~(SSI_TXCLK_SEL);
+
+ printk("TSC2102 GPIOs initialized\n");
+}
+
+// Chip select command for TSC2102
+static void tsc2102_cs(u32 command)
+{
+ // PortB 19 is used as chip select
+ if( command == SPI_CS_DEASSERT )
+ DR(1) |= 1<< TSC2102_CS_GPIOB;
+ else
+ DR(1) &= ~(1<< TSC2102_CS_GPIOB);
+}
+
+static struct spi_imx_chip tsc2102_hw = {
+ .cs_control = tsc2102_cs,
+};
+
+static struct tsc2102_config apf9328_tsc2102_config = {
+ .use_internal = 1, // -> use internal voltage reference
+ .monitor = TSC_BAT1 | TSC_AUX | TSC_TEMP,
+ .temp_at25c = 2200,
+/* .apm_report = palmte_get_power_status,
+ .alsa_config = &palmte_alsa_config,*/
+};
+
+#endif // CONFIG_SPI_TSC2102
+
+#ifdef CONFIG_CAN_MCP251X
+#define CAN_MPC251X_CS_GPIOB 19
+#define CAN_MPC251X_INT_GPIOC 13
+
+// Chip select command for MCP251X
+static void mcp251X_cs(u32 command)
+{
+ // PortB 19 is used as chip select
+ if( command == SPI_CS_DEASSERT )
+ DR(1) |= 1<< CAN_MPC251X_CS_GPIOB;
+ else
+ DR(1) &= ~(1<< CAN_MPC251X_CS_GPIOB);
+}
+
+static struct spi_imx_chip mcp251X_hw = {
+ .cs_control = mcp251X_cs,
+};
+
+static void mcp251X_init_gpio(void)
+{
+ // Activate SPI2 port ----
+ // PortB 19 is used as chip select (in GPIO mode)
+ DR(1) |= 1 << CAN_MPC251X_CS_GPIOB; // Initializes it High
+ imx_gpio_mode( GPIO_PORTB | CAN_MPC251X_CS_GPIOB | GPIO_OUT | GPIO_GIUS | GPIO_DR );
+
+ // PortC 13 is used as CAN interrupt
+ imx_gpio_mode( GPIO_PORTC | CAN_MPC251X_INT_GPIOC | GPIO_IN | GPIO_GIUS );
+
+ // Configure SPI2 outputs
+ imx_gpio_mode( PD7_AIN_SPI2_SCLK );
+ imx_gpio_mode( PD10_AIN_SPI2_TXD );
+ imx_gpio_mode( PD9_AOUT_SPI2_RXD );
+ FMCR |= SPI2_RXD_SEL; // RX is AOUT on PORTD
+}
+
+static struct mcp251x_platform_data apf9328_mcp251x_config = {
+ .oscillator_frequency = 16000000,
+ .board_specific_setup = NULL,
+ .device_reset = NULL,
+ .transceiver_enable = NULL,
+};
+
+#endif
+
+
+static struct spi_board_info spi_board_info[] __initdata = {
+#ifdef CONFIG_SENSORS_MAX1027
+{
+ .modalias = "max1027",
+ .controller_data = &max1027_hw,
+ .max_speed_hz = 8000000,
+ .bus_num = 1, // SPI1
+ .chip_select = 0,
+ .mode = 0,
+},
+#endif // CONFIG_SENSORS_MAX1027
+#ifdef CONFIG_SPI_TSC2102
+{
+ .modalias = "tsc2102",
+ .controller_data = &tsc2102_hw,
+ .max_speed_hz = 8000000,
+ .bus_num = 2, // SPI2
+ .irq = IRQ_GPIOD(TSC2102_INT_GPIOD),
+ .chip_select = 0,
+ .mode = 0,
+ .platform_data = &apf9328_tsc2102_config,
+},
+#endif // CONFIG_SPI_TSC2102
+#ifdef CONFIG_CAN_MCP251X
+ {
+ .modalias = "mcp251x",
+ .max_speed_hz = 8000000, /* 8MHz */
+ .controller_data = &mcp251X_hw,
+ .bus_num = 2,
+ .mode = SPI_MODE_0,
+ .chip_select = 0,
+ .irq = IRQ_GPIOC( CAN_MPC251X_INT_GPIOC ),
+ .platform_data = &apf9328_mcp251x_config,
+ },
+#endif // CONFIG_CAN_MCP251X
+};
+
+// --- LCD RESSOURCE ---
+#ifdef CONFIG_FB_IMX
+// all custom LCD configuration is deported to this file for clarity purpose:
+#include "apf9328_lcd_config.h"
+#define IMX_FB_PHYS (0x0C000000 - 0x40000)
+#endif // CONFIG_FB_IMX
+
+#ifdef CONFIG_IMX_BACKLIGHT
+static struct imxbl_machinfo imx_bl_machinfo = {
+ .max_intensity = 0xff,
+ .default_intensity = 0x90,
+ .limit_mask = 0x7f, // When battery is low
+// set_bl_intensity = put a function here if you want to overload default one,
+};
+//extern struct platform_device imxfb_device; // filled in generic.c
+static struct platform_device imxbl_device = {
+ .name = "imxl-bl",
+ .dev = {
+// .parent = &imxfb_device.dev, crash kernel even if EXPORT_SYMBOL() is done in generic.c
+ .platform_data = &imx_bl_machinfo,
+ },
+ .id = 0,
+};
+#endif // CONFIG_IMX_BACKLIGHT
+
+static struct platform_device *devices[] __initdata = {
+ &imx_uart1_device,
+ &imx_uart2_device,
+#ifdef CONFIG_DM9000
+ &dm9000x_device,
+#endif // CONFIG_DM9000
+#ifdef CONFIG_SPI_IMX
+ &imx_spi1,
+ &imx_spi2,
+#endif //CONFIG_SPI_IMX
+ &imx_pwm_device,
+#ifdef CONFIG_IMX_BACKLIGHT
+ &imxbl_device,
+#endif // CONFIG_IMX_BACKLIGHT
+#if defined(CONFIG_SND_IMX_TSC2102) || defined(CONFIG_SND_IMX_TSC2102_MODULE)
+ &tsc2102_alsa_device,
+#endif // CONFIG_SND_IMX_TSC2102 || CONFIG_SND_IMX_TSC2102_MODULE
+};
+
+static void __init apf9328_init(void)
+{
+ printk("--- Registering APF9328 ressources\n");
+
+ // Serial
+ /*UFCR(IMX_UART1_BASE) = 0xa81; To be removed
+ UFCR(IMX_UART2_BASE) = 0xa81;*/
+ // LCD
+#ifdef CONFIG_FB_IMX
+ set_imx_fb_info(&apf9328_fb_info);
+ printk("Set apf9328_fb_info\n");
+ // init PORTD ....//
+ imx_fb_set_gpios();
+#endif // CONFIG_FB_IMX
+
+#ifdef CONFIG_SENSORS_MAX1027
+ max1027_init_cs();
+#endif //CONFIG_SENSORS_MAX1027
+#ifdef CONFIG_SPI_TSC2102
+ tsc2102_init_gpio();
+#endif // CONFIG_SPI_TSC2102
+#ifdef CONFIG_CAN_MCP251X
+ mcp251X_init_gpio();
+#endif // CONFIG_CAN_MCP251X
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+#if defined (CONFIG_SENSORS_MAX1027) || defined (CONFIG_SPI_TSC2102) || defined (CONFIG_CAN_MCP251X)
+ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+#endif
+
+#ifdef CONFIG_ARMADEUS_FPGA_DRIVERS
+ request_mem_region(IMX_CS1_PHYS,IMX_CS1_SIZE,"FPGA");
+#endif // CONFIG_ARMADEUS_FPGA_DRIVERS
+
+ printk("--- APF9328 ressources registered\n");
+}
+
+/*
+ * Register here the memory addresses we want to access from our drivers and
+ * which are not already registerd in generic.c
+ */
+static struct map_desc apf9328_io_desc[] __initdata = {
+#ifdef CONFIG_FB_IMX
+ {
+ .virtual = IMX_FB_VIRT,
+ .pfn = __phys_to_pfn(IMX_FB_PHYS),
+ .length = IMX_FB_SIZE,
+ .type = MT_DEVICE
+ },
+#endif // CONFIG_FB_IMX
+ // FPGA Memory mapping
+ {.virtual = IMX_CS1_VIRT, .pfn = __phys_to_pfn(IMX_CS1_PHYS), .length = IMX_CS1_SIZE, .type = MT_DEVICE},
+};
+
+void __init apf9328_map_io(void)
+{
+ imx_map_io();
+ iotable_init(apf9328_io_desc, ARRAY_SIZE(apf9328_io_desc));
+}
+
+static void __init apf9328_init_irq(void)
+{
+ // Init generic IRQs
+ imx_init_irq();
+ // Init our custom IRQs
+ set_irq_type(APF9328_UART1_IRQ, IRQF_TRIGGER_FALLING);
+#ifdef CONFIG_DM9000
+ set_irq_type(APF9328_ETH_IRQ, IRQF_TRIGGER_FALLING);
+#endif // CONFIG_DM9000
+#ifdef CONFIG_SPI_TSC2102
+ set_irq_type( IRQ_GPIOD(TSC2102_INT_GPIOD), IRQF_TRIGGER_FALLING );
+#endif // CONFIG_SPI_TSC2102
+#ifdef CONFIG_CAN_MCP251X
+ set_irq_type( IRQ_GPIOC(CAN_MPC251X_INT_GPIOC), IRQF_TRIGGER_FALLING );
+#endif // CONFIG_CAN_MCP251X
+
+#ifdef CONFIG_ARMADEUS_FPGA_DRIVERS
+#define FPGA_INT_GPIOA 1
+ set_irq_type(IRQ_GPIOA(FPGA_INT_GPIOA),IRQF_TRIGGER_RISING);
+#endif // CONFIG_ARMADEUS_FPGA_DRIVERS
+
+}
+
+
+MACHINE_START(APF9328, "Armadeus APF9328")
+ /* Maintainer: Julien Boibessot, Armadeus */
+ .phys_io = 0x00200000,
+ .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc,
+ .boot_params = 0x08000100,
+ .map_io = apf9328_map_io,
+ .init_irq = apf9328_init_irq,
+ .timer = &imx_timer,
+ .init_machine = apf9328_init,
+MACHINE_END
Added: trunk/target/linux/arch/arm/mach-imx/apf9328_lcd_config.h
===================================================================
--- trunk/target/linux/arch/arm/mach-imx/apf9328_lcd_config.h (rev 0)
+++ trunk/target/linux/arch/arm/mach-imx/apf9328_lcd_config.h 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,199 @@
+/*
+ *
+ * Armadeus LCD configuration file
+ *
+ * Put here all that is needed to configure the Hardware
+ * interface to your LCD
+ *
+ *
+ */
+
+#ifndef APF9328_LCD_CONFIG_H
+#define APF9328_LCD_CONFIG_H
+
+
+#ifdef CONFIG_FB_IMX
+#include <asm/arch/imxfb.h>
+#include <linux/delay.h>
+
+#define LCD_PORT 3 /* Port D */
+
+#define OPTREX_F51900_POWER_DOWN 7 /* PD7_REV line */
+#define SHARP_LQ043_POWER_DOWN 12 /* PD12_ACD_OE line */
+#define CONTRAST_LINE 11 /* PD11_CONTRAST */
+
+#define BACKLIGHT_ON 0x000000ff
+#define DEFAULT_DMA_SETTINGS (DMACR_BURST | DMACR_HM(8) | DMACR_TM(4))
+
+/*
+ * Power on/off LCD's internal logic
+ */
+static void apf9328_lcd_power(int on)
+{
+ pr_debug("apf9328_lcd_power: %s\n", on ? "on":"off");
+#ifdef CONFIG_FB_IMX_OPTREX_F51900_CSTN
+ if(on)
+ DR(LCD_PORT) |= (1 << OPTREX_F51900_POWER_DOWN);
+ else
+ DR(LCD_PORT) &= ~(1 << OPTREX_F51900_POWER_DOWN);
+#elif CONFIG_FB_IMX_MICROTIPS_MTF_T035_TFT
+ // No LCD powerdown yet
+#elif CONFIG_FB_IMX_SHARP_LQ043_TFT
+ if(on) {
+ mdelay(200); // at least ten frames have to be processed before
+ // enabling the display
+ DR(LCD_PORT) |= (1 << SHARP_LQ043_POWER_DOWN);
+ }
+ else
+ DR(LCD_PORT) &= ~(1 << SHARP_LQ043_POWER_DOWN);
+#else
+ if(on)
+ DR(LCD_PORT) &= ~(1 << CONTRAST_LINE);
+ else
+ DR(LCD_PORT) |= (1 << CONTRAST_LINE);
+#endif // CONFIG_FB_IMX_OPTREX_F51900_CSTN
+}
+
+/*
+ * Power on/off LCD's backlight
+ */
+static void apf9328_lcd_backlight_power(int on)
+{
+ if(on)
+ LCDC_PWMR |= BACKLIGHT_ON;
+ else
+ LCDC_PWMR &= ~BACKLIGHT_ON;
+}
+
+
+#ifdef CONFIG_FB_IMX_SHARP_LQ043_TFT
+static struct imxfb_mach_info apf9328_fb_info __initdata = {
+ .pixclock = 62500,
+ .bpp = 16,
+ .xres = 480,
+ .yres = 272,
+
+ .hsync_len = 10,
+ .vsync_len = 3,
+ .left_margin = 2,
+ .upper_margin = 2,
+ .right_margin = 0,
+ .lower_margin = 3,
+
+ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_16 | PCR_FLMPOL | PCR_LPPOL |
+ PCR_CLKPOL | PCR_SCLKIDLE | PCR_SCLK_SEL | PCR_PCD(5),
+ .pwmr = 0x00000100, // Contrast with PWM @ Line_Pulse, min by default
+ .dmacr = DEFAULT_DMA_SETTINGS,
+ .backlight_power = apf9328_lcd_backlight_power,
+ .lcd_power = apf9328_lcd_power,
+};
+#elif CONFIG_FB_IMX_MICROTIPS_MTF_T035_TFT
+static struct imxfb_mach_info apf9328_fb_info __initdata = {
+ .pixclock = 62500,
+ .bpp = 16,
+ .xres = 320,
+ .yres = 240,
+
+ .hsync_len = 30,
+ .vsync_len = 3,
+ .left_margin = 1,
+ .upper_margin = 20,
+ .right_margin = 68,
+ .lower_margin = 20,
+
+ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_16 | PCR_FLMPOL | PCR_LPPOL |
+ PCR_SCLKIDLE | PCR_SCLK_SEL | PCR_PCD(7),
+ .pwmr = 0x000001ff, // Contrast with PWM @ Line_Pulse, max by default
+ .dmacr = DEFAULT_DMA_SETTINGS,
+ .backlight_power = apf9328_lcd_backlight_power,
+};
+#elif CONFIG_FB_IMX_SHARP_LQ057_TFT
+static struct imxfb_mach_info apf9328_fb_info __initdata = {
+ .pixclock = 62500,
+ .bpp = 16,
+ .xres = 320,
+ .yres = 240,
+
+ .hsync_len = 9,
+ .vsync_len = 2,
+ .left_margin = 9,
+ .upper_margin = 0,
+ .right_margin = 27,
+ .lower_margin = 7,
+
+ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_16 | /*PCR_CLKPOL |*/
+ PCR_SCLKIDLE | PCR_SCLK_SEL | PCR_PCD(9),
+ .pwmr = 0, // No contrast management
+ .dmacr = DEFAULT_DMA_SETTINGS,
+ .lcd_power = apf9328_lcd_power,
+};
+#elif CONFIG_FB_IMX_OPTREX_F51900_CSTN
+static struct imxfb_mach_info apf9328_fb_info __initdata = {
+ .pixclock = 62500,
+ .bpp = 8,
+ .xres = 320,
+ .yres = 240,
+
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .left_margin = 2,
+ .upper_margin = 2,
+ .right_margin = 2,
+ .lower_margin = 2,
+
+ .pcr = PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_8 | PCR_ACD(5) |
+ PCR_END_BYTE_SWAP | PCR_PCD(3),
+ .dmacr = DEFAULT_DMA_SETTINGS,
+ .lcd_power = apf9328_lcd_power,
+};
+#elif CONFIG_FB_IMX_MOTOROLA_A910_TFT
+static struct imxfb_mach_info apf9328_fb_info __initdata = {
+ .pixclock = 62500,
+ .bpp = 16,
+ .xres = 240,
+ .yres = 320,
+
+ .hsync_len = 9,
+ .vsync_len = 2,
+ .left_margin = 9,
+ .upper_margin = 2,
+ .right_margin = 27,
+ .lower_margin = 4,
+
+ .pcr = PCR_TFT | PCR_COLOR | PCR_PBSIZ_8 | PCR_BPIX_16 | PCR_CLKPOL |
+ PCR_SCLKIDLE | PCR_SCLK_SEL | PCR_PCD(9),
+ .dmacr = DEFAULT_DMA_SETTINGS,
+ .pwmr = 0, // No contrast management
+ .lcd_power = apf9328_lcd_power,
+};
+#else
+#error Please define a imxfb_mach_info structure with your LCD parameters here
+#endif
+
+/*
+ * Configure custom GPIOs needed by LCDs
+ */
+static void imx_fb_set_gpios(void)
+{
+
+#ifdef CONFIG_FB_IMX_OPTREX_F51900_CSTN
+ DR(LCD_PORT) |= (1 << OPTREX_F51900_POWER_DOWN); // Initializes it High
+ imx_gpio_mode( GPIO_PORTD | OPTREX_F51900_POWER_DOWN | GPIO_OUT | GPIO_DR );
+#else
+ DR(LCD_PORT) &= ~(1 << CONTRAST_LINE); // Initializes it low
+ // GPIO Function for CONTRAST pin (changed in imxfb if contrast is activated)
+ imx_gpio_mode( GPIO_PORTD | CONTRAST_LINE | GPIO_OUT | GPIO_GIUS | GPIO_DR );
+#endif
+
+#ifdef CONFIG_FB_IMX_SHARP_LQ043_TFT
+ // ACD_OE (SHARP_LQ043_POWER_DOWN) used as power down signal
+ DR(LCD_PORT) &= ~(1 << SHARP_LQ043_POWER_DOWN); // Initializes it Low
+ imx_gpio_mode( GPIO_PORTD | SHARP_LQ043_POWER_DOWN | GPIO_OUT | GPIO_GIUS | GPIO_DR );
+#else
+ // otherwise use ACD_OE as standard LCD controller signal
+ imx_gpio_mode(PD12_PF_ACD_OE);
+#endif // CONFIG_FB_IMX_SHARP_LQ043_TFT
+}
+#endif // CONFIG_FB_IMX
+
+#endif // APF9328_LCD_CONFIG_H
Added: trunk/target/linux/generate_patch.sh
===================================================================
--- trunk/target/linux/generate_patch.sh (rev 0)
+++ trunk/target/linux/generate_patch.sh 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+if [ $# -lt 2 ]; then
+ echo "Usage: $0 [options] <source> <dest> <patchname>"
+ echo " options: --append"
+ exit 1
+fi
+
+if [ "$1" == "--append" ]; then
+ shift
+ echo "PATCH AUTOMATICALLY GENERATED" >> $3
+else
+ echo "PATCH AUTOMATICALLY GENERATED" > $3
+fi
+echo "DON'T EDIT IT OR YOUR MODIFICATIONS WILL BE LOST" >> $3
+echo "(Take a look at armadeus/target/linux/ directory to know how to generate it)" >> $3
+
+diff -urN $1 $2 >> $3
+exit 0
Property changes on: trunk/target/linux/generate_patch.sh
___________________________________________________________________
Added: svn:executable
+ *
Added: trunk/target/linux/include/asm-arm/arch-imx/apf9328.h
===================================================================
--- trunk/target/linux/include/asm-arm/arch-imx/apf9328.h (rev 0)
+++ trunk/target/linux/include/asm-arm/arch-imx/apf9328.h 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,60 @@
+/*
+ * linux/include/asm-arm/arch-imx/apf9328.h
+ *
+ * Copyright (c) 2005 Armadeus
+ * This work is based on scb9328.h from Sascha Hauer
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __ASM_ARCH_APF9328_H
+#define __ASM_ARCH_APF9328_H
+
+/* ------------------------------------------------------------------------ */
+/* Memory Map for the APF9328 Board */
+/* ------------------------------------------------------------------------ */
+
+// Serial ports
+#define APF9328_UART1_VIRT ( IMX_CS3_VIRT + 0x30000 )
+#define APF9328_UART1_PHYS ( IMX_CS3_PHYS + 0x30000 )
+#define APF9328_UART1_IRQ ( IRQ_GPIOA(1) )
+#define APF9328_UART2_VIRT ( IMX_CS3_VIRT + 0x10000 )
+#define APF9328_UART2_PHYS ( IMX_CS3_PHYS + 0x10000 )
+#define APF9328_UART2_IRQ ( IRQ_GPIOA(1) )
+
+// Ethernet
+#define APF9328_ETH_VIRT ( IMX_CS4_VIRT + 0x00C00000 )
+#define APF9328_ETH_PHYS ( IMX_CS4_PHYS + 0x00C00000 )
+#define APF9328_ETH_IRQ ( IRQ_GPIOB(14) )
+
+// FLASH
+#define APF9328_FLASH_PHYS IMX_CS0_PHYS
+#ifdef CONFIG_IMX_APF9328_FLASH_8MB
+# define APF9328_FLASH_SIZE 0x00800000
+#endif
+#ifdef CONFIG_IMX_APF9328_FLASH_16MB
+# define APF9328_FLASH_SIZE 0x01000000
+#endif
+#define APF9328_FLASH_BASE IMX_CS0_VIRT
+
+// RAM
+// Usefull ?
+
+// FPGA
+// TBDL
+
+#define CLK32 32768
+
+#endif // __ASM_ARCH_APF9328_H
Added: trunk/target/linux/include/asm-arm/arch-imx/imx-alsa.h
===================================================================
--- trunk/target/linux/include/asm-arm/arch-imx/imx-alsa.h (rev 0)
+++ trunk/target/linux/include/asm-arm/arch-imx/imx-alsa.h 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,131 @@
+/*
+ * linux/include/asm-arm/arch-imx/imx-alsa.h
+ *
+ * Alsa Driver for AIC23 and TSC2101 codecs on iMX platform boards.
+ *
+ * Copyright (C) 2008 Armadeus <nic...@ar...>
+ * Based on the omap 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.
+ *
+ */
+
+#ifndef __IMX_ALSA_H
+#define __IMX_ALSA_H
+
+#include <sound/driver.h>
+#include <asm/arch/dma.h>
+#include <asm/arch/imx-dma.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+/*#include <asm/arch/ssi.h>*/
+#include <linux/platform_device.h>
+/*
+ * Debug functions
+ */
+#undef DEBUG
+//#define DEBUG
+
+#define ERR(ARGS...) printk(KERN_ERR "{%s}-ERROR: ", __FUNCTION__);printk(ARGS);
+
+#ifdef DEBUG
+#define DPRINTK(ARGS...) printk(KERN_INFO "<%s>: ",__FUNCTION__);printk(ARGS)
+#define ADEBUG() printk("XXX Alsa debug f:%s, l:%d\n", __FUNCTION__, __LINE__)
+#define FN_IN printk(KERN_INFO "[%s]: start\n", __FUNCTION__)
+#define FN_OUT(n) printk(KERN_INFO "[%s]: end(%u)\n",__FUNCTION__, n)
+#else
+#define DPRINTK(ARGS...) /* nop */
+#define ADEBUG() /* nop */
+#define FN_IN /* nop */
+#define FN_OUT(n) /* nop */
+#endif
+
+#define DMA_BUF_SIZE (1024 * 8)
+
+/*
+ * Buffer management for alsa and dma
+ */
+struct audio_stream {
+ char *id; /* identification string */
+ int stream_id; /* numeric identification */
+// int dma_dev; /* dma number of that device */
+ imx_dmach_t dma_dev; /* device identifier for DMA */
+ int dma_in_progress;
+ int offset; /* store start position of the last period in the alsa buffer */
+ int active:1; /* we are using this stream for transfer now */
+ int period; /* current transfer period */
+ int periods; /* current count of periods registered in the DMA engine */
+ spinlock_t dma_lock; /* for locking in DMA operations */
+ struct snd_pcm_substream *stream; /* the pcm stream */
+ int (*hw_start)(void); /* interface to start HW interface, e.g. McBSP */
+ int (*hw_stop)(void); /* interface to stop HW interface, e.g. McBSP */
+};
+
+
+/*
+ * Alsa card structure
+ */
+struct snd_card_imx_codec {
+ struct snd_card *card;
+ struct snd_pcm *pcm;
+ long samplerate;
+ struct audio_stream s[2]; /* playback & capture */
+};
+
+/* Codec specific information and function pointers.
+ * Codec imx-alsa-tsc2101.c
+ * is responsible for defining the function pointers.
+ */
+struct imx_alsa_codec_config {
+ char *name;
+ struct imx_ssi_reg_cfg *mcbsp_regs_alsa;
+ struct snd_pcm_hw_constraint_list *hw_constraints_rates;
+ struct snd_pcm_hardware *snd_imx_alsa_playback;
+ struct snd_pcm_hardware *snd_imx_alsa_capture;
+ void (*codec_configure_dev)(void);
+ void (*codec_set_samplerate)(long);
+ void (*codec_clock_setup)(void);
+ int (*codec_clock_on)(void);
+ int (*codec_clock_off)(void);
+ int (*get_default_samplerate)(void);
+};
+
+/*********** Mixer function prototypes *************************/
+int snd_imx_mixer(struct snd_card_imx_codec *);
+void snd_imx_init_mixer(void);
+
+#ifdef CONFIG_PM
+void snd_imx_suspend_mixer(void);
+void snd_imx_resume_mixer(void);
+#endif
+
+int snd_imx_alsa_post_probe(struct platform_device *pdev, struct imx_alsa_codec_config *config);
+int snd_imx_alsa_remove(struct platform_device *pdev);
+#ifdef CONFIG_PM
+int snd_imx_alsa_suspend(struct platform_device *pdev, pm_message_t state);
+int snd_imx_alsa_resume(struct platform_device *pdev);
+#else
+#define snd_imx_alsa_suspend NULL
+#define snd_imx_alsa_resume NULL
+#endif
+void snd_imx_alsa_dma_interrupt(int, void *);
+
+#endif
Added: trunk/target/linux/sound/arm/imx-alsa-dma.h
===================================================================
--- trunk/target/linux/sound/arm/imx-alsa-dma.h (rev 0)
+++ trunk/target/linux/sound/arm/imx-alsa-dma.h 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,50 @@
+/*
+ * linux/sound/arm/imx/imx-alsa-dma.h
+ *
+ * Common audio DMA handling for the iMX processors
+ *
+ * Copyright (C) 2008 Nicolas Colombain <nic...@ar...>
+ *
+ * Copyright (C) 2006 Mika Laitio <la...@cc...>
+ *
+ * Copyright (C) 2005 Instituto Nokia de Tecnologia - INdT - Manaus Brazil
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ *
+ * Copyright (C) 2000, 2001 Nicolas Pitre <ni...@ca...>
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __IMX_AUDIO_ALSA_DMA_H
+#define __IMX_AUDIO_ALSA_DMA_H
+
+/************************** INCLUDES *************************************/
+
+#include <asm/arch/imx-alsa.h>
+
+/************************** GLOBAL DATA STRUCTURES *********************************/
+
+typedef void (*dma_callback_t) (int lch, u16 ch_status, void *data);
+
+/**************** ARCH SPECIFIC FUNCIONS *******************************************/
+
+void imx_clear_alsa_sound_dma(struct audio_stream * s);
+
+/*int imx_request_alsa_sound_dma(int device_id, const char *device_name,
+ void *data, int **channels);*/
+//int imx_free_alsa_sound_dma(void *data, int **channels);
+
+int imx_start_alsa_sound_dma(struct audio_stream *s, dma_addr_t dma_ptr, u_int dma_size);
+
+void imx_stop_alsa_sound_dma(struct audio_stream *s);
+
+#endif
+
Added: trunk/target/linux/sound/arm/imx-alsa-tsc2102-mixer.c
===================================================================
--- trunk/target/linux/sound/arm/imx-alsa-tsc2102-mixer.c (rev 0)
+++ trunk/target/linux/sound/arm/imx-alsa-tsc2102-mixer.c 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,288 @@
+/*
+ * sound/arm/imx-alsa-tsc2102-mixer.c
+ *
+ * Alsa codec driver for TSC2102 chip for iMXL platforms.
+ *
+ * Copyright (c) 2008 Jorasse <jo...@ar...>
+ * Code based on the TSC2101 ALSA driver for omap platforms.
+ * Copyright (c) 2006 Andrzej Zaborowski <ba...@za...>
+ * 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/imx-alsa.h>
+
+#include <sound/driver.h>
+#include <sound/initval.h>
+#include <sound/control.h>
+
+#include "imx-alsa-tsc2102.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_imx_init_mixer(void)
+{
+ FN_IN;
+
+ init_playback_targets();
+
+ FN_OUT(0);
+}
+
+static int __pcm_playback_volume_info(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *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(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *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(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *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(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *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(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *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(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *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(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *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(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = filter[0];
+ return 0;
+}
+
+static int __pcm_playback_deemphasis_put(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ filter[0] = (ucontrol->value.integer.value[0] > 0);
+
+ tsc2102_set_deemphasis(filter[0]);
+ return 1;
+}
+
+static int __pcm_playback_bassboost_info(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *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(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = filter[1];
+ return 0;
+}
+
+static int __pcm_playback_bassboost_put(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ filter[1] = (ucontrol->value.integer.value[0] > 0);
+
+ tsc2102_set_bassboost(filter[1]);
+ return 1;
+}
+
+static struct snd_kcontrol_new 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_imx_suspend_mixer(void)
+{
+ /* Nothing to do */
+}
+
+void snd_imx_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_imx_mixer(struct snd_card_imx_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;
+}
+
+MODULE_DESCRIPTION("Interface driver for TI TSC2102 chips.");
+MODULE_LICENSE("GPL");
+
Added: trunk/target/linux/sound/arm/imx-alsa-tsc2102.c
===================================================================
--- trunk/target/linux/sound/arm/imx-alsa-tsc2102.c (rev 0)
+++ trunk/target/linux/sound/arm/imx-alsa-tsc2102.c 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,345 @@
+/*
+ * sound/arm/imx-alsa-tsc2102.c
+ *
+ * Alsa codec driver for TSC2102 chip for iMXL platforms.
+ *
+ * Copyright (c) 2008 Jorasse <jo...@ar...>
+ * Code based on the TSC2101 ALSA driver for omap platforms.
+ * Copyright (c) 2006 Andrzej Zaborowski <ba...@za...>
+ * 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/slab.h>
+#ifdef CONFIG_PM
+#include <linux/pm.h>
+#endif
+#include <linux/spi/tsc2102.h>
+
+#include <asm/arch/hardware.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/imx-alsa.h>
+
+#include "imx-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 struct snd_pcm_hw_constraint_list tsc2102_hw_constraints_rates = {
+ .count = ARRAY_SIZE(rates),
+ .list = rates,
+ .mask = 0,
+};
+
+#define IMX_SSI_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)
+
+static struct snd_pcm_hardware tsc2102_snd_imx_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 = IMX_SSI_RATES,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 32 * 1024,
+ .period_bytes_min = 64,
+ .period_bytes_max = 8 * 1024, //test
+ .periods_min = 2,
+ .periods_max = 255,
+ .fifo_size = 0,
+};
+
+#define DUMP_TSC2102_AUDIO_REGISTERS 1
+#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_AUDIO3_CTRL));
+ 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 0
+ /* Wait for any frames to complete */
+ udelay(125);
+#endif
+ /* Set the sample rate on the TSC */
+ if (tsc2102_set_rate(sample_rate)) {
+ printk("error setting TSC at %d Hz sample rate\n", sample_rate);
+ return;
+ }
+
+#ifdef TSC_MASTER
+
+#else
+ /* Set the sample rate on the i.MXL SSI */
+ printk("erreur 1");
+ imx_get_perclk3();
+ clkgdv = CODEC_CLOCK / (sample_rate * (DEFAULT_BITPERSAMPLE * 2 - 1));
+ if (clkgdv)
+ srgr1 = (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv));
+ else
+ return;
+ xxxxx
+ /* Stereo Mode */
+ srgr2 = (CLKSM | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1));
+#endif
+
+ current_rate = sample_rate;
+ dump_tsc2102_audio_regs();
+}
+
+static void tsc2102_configure(void)
+{
+ tsc2102_dac_power(1);
+
+#ifdef TSC_MASTER
+ tsc2102_set_i2s_master(1);
+#else
+#error "to be implemented"
+ tsc2102_set_i2s_master(0);
+#endif
+}
+
+/*
+ * Do clock framework bclk search
+ */
+static void tsc2102_clock_setup(void)
+{
+ /*tsc2102_bclk = clk_get(0, "bclk"); no clock management*/
+}
+
+/*
+ * Do some sanity checks, set clock rate, start it.
+ */
+static int tsc2102_clock_on(void)
+{
+/* int err;
+no clock management*/
+
+#ifdef TSC_MASTER
+
+#endif
+
+/* if (clk_get_usecount(tsc2102_bclk) > 0 &&
+ clk_get_rate(tsc2102_bclk) != CODEC_CLOCK) {
+ 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);
+no clock management*/
+
+ /* Clock disabled when SSI disabled */
+ //?? SSI_SOR |= 0x40;
+
+ 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);
+no clock management */
+
+ /* Clock enabled when SSI disabled */
+ //?? SSI_SOR &= ~0x40;
+
+ return 0;
+}
+
+static int tsc2102_get_default_samplerate(void)
+{
+ return DEFAULT_SAMPLE_RATE;
+}
+
+#ifdef CONFIG_PM
+static int snd_imx_alsa_tsc2102_suspend(
+ struct platform_device *pdev, pm_message_t state)
+{
+ tsc2102_dac_power(0);
+ current_rate = 0;
+
+ return snd_imx_alsa_suspend(pdev, state);
+}
+
+static int snd_imx_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_imx_alsa_resume(pdev);
+}
+#endif // CONFIG_PM
+
+static int __init snd_imx_alsa_tsc2102_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct imx_alsa_codec_config *codec_cfg = pdev->dev.platform_data;
+
+ if (codec_cfg) {
+ codec_cfg->hw_constraints_rates =
+ &tsc2102_hw_constraints_rates;
+ codec_cfg->snd_imx_alsa_playback =
+ &tsc2102_snd_imx_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_imx_alsa_post_probe(pdev, codec_cfg);
+ } else
+ ret = -ENODEV;
+
+ return ret;
+}
+
+static int snd_imx_alsa_tsc2102_remove(struct platform_device *pdev)
+{
+ tsc2102_dac_power(0);
+
+ return snd_imx_alsa_remove(pdev);
+}
+
+static struct platform_driver imx_alsa_driver = {
+ .probe = snd_imx_alsa_tsc2102_probe,
+ .remove = snd_imx_alsa_tsc2102_remove,
+#ifdef CONFIG_PM
+ .suspend = snd_imx_alsa_tsc2102_suspend,
+ .resume = snd_imx_alsa_tsc2102_resume,
+#endif // CONFIG_PM
+ .driver = {
+ .name = "tsc2102-alsa",
+ },
+};
+
+static int __init imx_alsa_tsc2102_init(void)
+{
+ int err;
+
+ ADEBUG();
+ err = platform_driver_register(&imx_alsa_driver);
+
+ return err;
+}
+
+static void __exit imx_alsa_tsc2102_exit(void)
+{
+ ADEBUG();
+ platform_driver_unregister(&imx_alsa_driver);
+}
+
+module_init(imx_alsa_tsc2102_init);
+module_exit(imx_alsa_tsc2102_exit);
+
Added: trunk/target/linux/sound/arm/imx-alsa-tsc2102.h
===================================================================
--- trunk/target/linux/sound/arm/imx-alsa-tsc2102.h (rev 0)
+++ trunk/target/linux/sound/arm/imx-alsa-tsc2102.h 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,46 @@
+/*
+ * sound/arm/imx-alsa-tsc2102.h
+ *
+ * Alsa codec driver for TSC2102 chip for IMX1 platforms.
+ *
+ * Copyright (c) 2008 Jorasse <jo...@ar...>
+ * Code based on the TSC2101 ALSA driver for omap platforms.
+ * Copyright (c) 2006 Andrzej Zaborowski <ba...@za...>
+ * 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 IMX_ALSA_TSC2102_H_
+#define IMX_ALSA_TSC2102_H_
+
+#include <linux/types.h>
+
+/* Define to set the TSC as the master, otherwise slave */
+#define TSC_MASTER
+
+/*
+ * Audio related macros
+ */
+#ifndef DEFAULT_BITPERSAMPLE
+#define DEFAULT_BITPERSAMPLE 16
+#endif
+
+#define DEFAULT_SAMPLE_RATE 48000
+#define CODEC_CLOCK 16000000
+#define AUDIO_MCBSP OMAP_MCBSP1 /* to remove */
+
+/*
+ * 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 /* IMX_ALSA_TSC2102_H_ */
+
Added: trunk/target/linux/sound/arm/imx-alsa.c
===================================================================
--- trunk/target/linux/sound/arm/imx-alsa.c (rev 0)
+++ trunk/target/linux/sound/arm/imx-alsa.c 2008-07-21 17:56:15 UTC (rev 846)
@@ -0,0 +1,683 @@
+/*
+ * sound/arm/imx-alsa.c
+ *
+ * Alsa Driver for i.MXL / SSI
+ *
+ * Copyright (C) 2008 Armadeus Systems <nic...@ar...>
+ * <jul...@ar...>
+ * Based on omap-alsa.c
+ *
+ * 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/platform_device.h>
+#include <linux/spi/tsc2102.h>
+#ifdef CONFIG_PM
+#include <linux/pm.h>
+#endif
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+
+#include <asm/arch/imx-alsa.h>
+#include <linux/dma-mapping.h>
+#include <asm/arch/imx-dma.h>
+
+#define TSC_MASTER
+
+#define TRANSMIT_WM_LEVEL 8 // (in free places)
+#define SSI_DMA_BLR_TRANSMIT 16 // (3*2) // DMA Burst Length (in bytes)
+#define SSI_DMA_BLR 8
+
+MODULE_AUTHOR("Nicolas Colombain / Julien Boibessot - Armadeus Systems");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("i.MX1/L driver for ALSA");
+MODULE_ALIAS("iMX_alsa_ssi");
+
+static struct snd_card_imx_codec *alsa_codec = NULL;
+static struct imx_alsa_codec_config *alsa_codec_config = NULL;
+
+
+/*
+ * HW interface start and stop helper functions
+ */
+static int audio_ifc_start(void)
+{
+ printk("Starting HW\n");
+ SSI_SCSR |= SSI_TE; /* TE enable */
+ return 0;
+}
+
+static int audio_ifc_stop(void)
+{
+ printk("Stopping HW\n");
+ SSI_SCSR &= ~SSI_TE; /* TE disable */
+ return 0;
+}
+
+#ifdef DEBUG
+static void dump_ssi_registers(void)
+{
+ printk("SSI_STX: 0x%x\n", SSI_STX);
+ printk("SSI_SRX: 0x%x\n", SSI_SRX);
+ printk("SSI_SCSR: 0x%x\n", SSI_SCSR);
+ printk("SSI_STCR: 0x%x\n", SSI_STCR);
+ printk("SSI_SRCR: 0x%x\n", SSI_SRCR);
+ printk("SSI_STCCR: 0x%x\n", SSI_STCCR);
+ printk("SSI_SRCCR: 0x%x\n", SSI_SRCCR);
+ printk("SSI_STSR: 0x%x\n", SSI_STSR);
+ printk("SSI_SFCSR: 0x%x\n", SSI_SFCSR);
+ printk("SSI_STR: 0x%x\n", SSI_STR);
+ printk("SSI_SOR: 0x%x\n", SSI_SOR);
+}
+#endif
+
+static void imx_alsa_audio_init(struct snd_card_imx_codec *imx_alsa)
+{
+ /* Setup DMA stuff */
+ imx_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].id = "Alsa imx out";
+ imx_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].stream_id =
+ SNDRV_PCM_STREAM_PLAYBACK;
+ imx_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].dma_dev =
+ IMX_DMA_CHANNELS-1;
+ imx_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].hw_start =
+ audio_ifc_start;
+ imx_alsa->s[SNDRV_PCM_STREAM_PLAYBACK].hw_stop =
+ audio_ifc_stop;
+
+ imx_alsa->s[SNDRV_PCM_STREAM_CAPTURE].id = "Alsa imx in";
+ imx_alsa->s[SNDRV_PCM_STREAM_CAPTURE].stream_id =
+ SNDRV_PCM_STREAM_CAPTU...
[truncated message content] |