[Armadeus-commitlog] SF.net SVN: armadeus:[1026] trunk
Brought to you by:
sszy
|
From: <ar...@us...> - 2009-01-20 15:55:11
|
Revision: 1026
http://armadeus.svn.sourceforge.net/armadeus/?rev=1026&view=rev
Author: artemys
Date: 2009-01-20 15:55:03 +0000 (Tue, 20 Jan 2009)
Log Message:
-----------
[MERGE] Merge of tsc210x branch (APF27's TSC2101 integration)
Modified Paths:
--------------
trunk/buildroot/target/device/armadeus/apf9328/apf9328-linux-2.6.27.2.config
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-021-armadeus-apf9328.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-030-armadeus-add_USB_registers.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-073-armadeus-tsc2102.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-074-armadeus-tsc2102-touchscreen.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-090-armadeus-alsa-create_imx-alsa_h.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-091-armadeus-alsa-add_imx_ssi_tsc2102_driver.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-093-armadeus-add_ssi_registers_definition.patch
trunk/software/uboot_recover/bootloader.py
trunk/target/linux/Makefile
trunk/target/linux/debug/imxregs/imx27regs.h
trunk/target/linux/debug/imxssi/imxssi.c
Added Paths:
-----------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-095-armadeus-imx-ssi-add_driver.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-096-armadeus-clock-add_ssi_clk.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-097-armadeus-imx-dma-improvements.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-098-armadeus-imx-dma-announce_imx_is_supporting_scatter_gather.patch
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-305-apf27-armadeus-separates_imx_and_mx2_alsa_build.patch
trunk/target/linux/arch/arm/mach-imx/include/
trunk/target/linux/arch/arm/mach-imx/include/mach/
Removed Paths:
-------------
trunk/target/linux/arch/arm/mach-imx/include/mach/
Modified: trunk/buildroot/target/device/armadeus/apf9328/apf9328-linux-2.6.27.2.config
===================================================================
--- trunk/buildroot/target/device/armadeus/apf9328/apf9328-linux-2.6.27.2.config 2009-01-20 14:59:10 UTC (rev 1025)
+++ trunk/buildroot/target/device/armadeus/apf9328/apf9328-linux-2.6.27.2.config 2009-01-20 15:55:03 UTC (rev 1026)
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.27.2
-# Sun Dec 28 01:31:05 2008
+# Fri Jan 16 18:34:47 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -919,6 +919,7 @@
# CONFIG_SND_DEBUG is not set
# CONFIG_SND_DRIVERS is not set
CONFIG_SND_ARM=y
+CONFIG_SND_IMX_PCM=m
CONFIG_SND_IMX_TSC2102=m
# CONFIG_SND_SPI is not set
# CONFIG_SND_USB is not set
Modified: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-021-armadeus-apf9328.patch
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-021-armadeus-apf9328.patch 2009-01-20 14:59:10 UTC (rev 1025)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-021-armadeus-apf9328.patch 2009-01-20 15:55:03 UTC (rev 1026)
@@ -3,11 +3,11 @@
(Take a look at armadeus/target/linux/ directory to know how to generate it)
--- linux-2.6.27.2.original/arch/arm/mach-imx/apf9328.c
+++ linux-2.6.27.2.mod/arch/arm/mach-imx/apf9328.c
-@@ -0,0 +1,677 @@
+@@ -0,0 +1,731 @@
+/*
+ * linux/arch/arm/mach-imx/apf9328.c
+ *
-+ * Copyright (c) 2005 Armadeus
++ * Copyright (c) 2005-2009 Armadeus systems
+ * This work is based on scb9328.c from Sascha Hauer
+ *
+ * This program is free software; you can redistribute it and/or modify
@@ -45,14 +45,15 @@
+#include <mach/imx-uart.h>
+#include <mach/mmc.h>
+#include <mach/spi_imx.h>
-+#include <mach/imx-regs.h> // imx_gpio_mode()
++#include <mach/imx-regs.h> /* imx_gpio_mode() */
+#include <mach/imx-alsa.h>
+#include <linux/spi/max1027.h>
+#include <linux/usb/isp116x.h>
++#include <mach/imx_ssi.h>
+
+#ifdef CONFIG_DM9000
+#include <linux/dm9000.h>
-+#endif // CONFIG_DM9000
++#endif
+
+#include "generic.h"
+
@@ -188,26 +189,89 @@
+};
+
+#if defined(CONFIG_SND_IMX_TSC2102) || defined(CONFIG_SND_IMX_TSC2102_MODULE)
-+static struct imx_alsa_codec_config tsc2102_alsa_pdata;
++int apf9328_ssi_gpio_init(struct platform_device *pdev)
++{
++ /* 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("SSI pins configured\n");
++ return 0;
++}
+
++static struct imx_ssi_platform_data apf9328_ssi_pdata = {
++ .init = apf9328_ssi_gpio_init,
++};
++
+static struct resource ssi_resources[] = {
-+ [0] = {
-+ .start = (IMX_SSI_BASE),
-+ .end = (IMX_SSI_BASE + 0x28),
-+ .flags = IORESOURCE_MEM,
-+ },
++ [0] = {
++ .start = (0x00218000),
++ .end = (0x00218000 + 0x28),
++ .flags = IORESOURCE_MEM,
++ },
++ [1] = {
++ .start = SSI_TX_INT,
++ .end = SSI_TX_INT,
++ .flags = IORESOURCE_IRQ
++ },
++ [2] = {
++ .start = SSI_TX_ERR_INT,
++ .end = SSI_TX_ERR_INT,
++ .flags = IORESOURCE_IRQ
++ },
++ [3] = {
++ .start = SSI_RX_INT,
++ .end = SSI_RX_INT,
++ .flags = IORESOURCE_IRQ
++ },
++ [4] = {
++ .start = SSI_RX_ERR_INT,
++ .end = SSI_RX_ERR_INT,
++ .flags = IORESOURCE_IRQ
++ },
++ [5] = {
++ .name = "tx0",
++ .start = DMA_REQ_SSI_T,
++ .end = DMA_REQ_SSI_T,
++ .flags = IORESOURCE_DMA
++ },
++ [6] = {
++ .name = "rx0",
++ .start = DMA_REQ_SSI_R,
++ .end = DMA_REQ_SSI_R,
++ .flags = IORESOURCE_DMA
++ },
+};
+
++static struct platform_device apf9328_ssi_device = {
++ .name = "imx-ssi",
++ .id = 0,
++ .num_resources = ARRAY_SIZE(ssi_resources),
++ .resource = ssi_resources,
++ .dev = {
++ .platform_data = &apf9328_ssi_pdata,
++ }
++};
++
++static struct imx_sound_platform_data apf9328_alsa_pdata;
++
+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,
-+ }
++ .name = "tsc210x-alsa",
++ .id = 0,
++ .dev = {
++ .platform_data = &apf9328_alsa_pdata,
++ }
+};
-+#endif // defined(CONFIG_SND_IMX_TSC2102) || defined(CONFIG_SND_IMX_TSC2102_MODULE)
++#endif /* defined(CONFIG_SND_IMX_TSC2102) || defined(CONFIG_SND_IMX_TSC2102_MODULE) */
+
+
+// --- SERIAL RESSOURCE ---
@@ -417,19 +481,6 @@
+ 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");
+ return 0;
+}
@@ -448,12 +499,14 @@
+ .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,
-+ .init = tsc2102_init_gpio
-+/* .apm_report = palmte_get_power_status,
-+ .alsa_config = &palmte_alsa_config,*/
++static struct tsc210x_config apf9328_tsc2102_config = {
++ .use_internal = 1, // -> use internal voltage reference
++ .monitor = TSC_BAT1 | TSC_AUX | TSC_TEMP,
++ .init = tsc2102_init_gpio,
++/* .apm_report = palmte_get_power_status,*/
++/*#if defined(CONFIG_SND_IMX_TSC2102) || defined(CONFIG_SND_IMX_TSC2102_MODULE)
++ .alsa_config = &apf9328_alsa_pdata,
++#endif*/
+};
+
+#endif // CONFIG_SPI_TSC2102
@@ -518,7 +571,7 @@
+#endif // CONFIG_SENSORS_MAX1027
+#ifdef CONFIG_SPI_TSC2102
+{
-+ .modalias = "tsc2102",
++ .modalias = "tsc210x",
+ .controller_data = &tsc2102_hw,
+ .max_speed_hz = 8000000,
+ .bus_num = 2, // SPI2
@@ -570,23 +623,24 @@
+static struct platform_device *devices[] __initdata = {
+ &imx_uart1_device,
+ &imx_uart2_device,
-+#ifdef CONFIG_DM9000
++#ifdef CONFIG_DM9000
+ &dm9000x_device,
-+#endif // CONFIG_DM9000
++#endif
+#ifdef CONFIG_SPI_IMX
+ &imx_spi1,
+ &imx_spi2,
-+#endif //CONFIG_SPI_IMX
++#endif
+ &imx_pwm_device,
+#ifdef CONFIG_IMX_BACKLIGHT
+ &imxbl_device,
-+#endif // CONFIG_IMX_BACKLIGHT
++#endif
+#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
++ &apf9328_ssi_device,
++#endif
+#ifdef CONFIG_ARMADEUS_ISP1761
+ &devfull_isp1761_device,
-+#endif // CONFIG_ARMADEUS_ISP1761
++#endif
+};
+
+static void __init apf9328_init(void)
@@ -891,7 +945,7 @@
DON'T EDIT IT OR YOUR MODIFICATIONS WILL BE LOST
(Take a look at armadeus/target/linux/ directory to know how to generate it)
--- linux-2.6.27.2.original/arch/arm/mach-imx/include/mach/apf9328.h
-+++ linux-2.6.27.2.mod/arch/arm/mach-imx/include/mach/apf9328.h
++++ linux-2.6.27.2.mod/arch/arm/mach-imx/include/mach/apf9328.h
@@ -0,0 +1,63 @@
+/*
+ * linux/include/asm-arm/arch-imx/apf9328.h
Modified: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-030-armadeus-add_USB_registers.patch
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-030-armadeus-add_USB_registers.patch 2009-01-20 14:59:10 UTC (rev 1025)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-030-armadeus-add_USB_registers.patch 2009-01-20 15:55:03 UTC (rev 1026)
@@ -20,7 +20,7 @@
#define PB23_PF_USBD_SUSPND ( GPIO_PORTB | GPIO_PF | 23 )
#define PB24_PF_USBD_VP ( GPIO_PORTB | GPIO_PF | 24 )
#define PB25_PF_USBD_VM ( GPIO_PORTB | GPIO_PF | 25 )
-@@ -591,4 +591,146 @@
+@@ -591,4 +591,132 @@
#define UTS_RXFULL (1<<3) /* RxFIFO full */
#define UTS_SOFTRST (1<<0) /* Software reset */
@@ -142,20 +142,6 @@
+#define USB_ENDIAN (1<<28) /* Endian of USB modules */
+#define USB_POWER (1<<0) /* Power mode of USB modules */
+
-+/*
-+ * SSI register
-+ */
-+#define SSI_STX __REG(IMX_SSI_BASE)
-+#define SSI_SRX __REG(IMX_SSI_BASE + 0x4)
-+#define SSI_SCSR __REG(IMX_SSI_BASE + 0x8)
-+#define SSI_STCR __REG(IMX_SSI_BASE + 0xC)
-+#define SSI_SRCR __REG(IMX_SSI_BASE + 0x10)
-+#define SSI_STCCR __REG(IMX_SSI_BASE + 0x14)
-+#define SSI_SRCCR __REG(IMX_SSI_BASE + 0x18)
-+#define SSI_STSR __REG(IMX_SSI_BASE + 0x1C)
-+#define SSI_SFCSR __REG(IMX_SSI_BASE + 0x20)
-+#define SSI_STR __REG(IMX_SSI_BASE + 0x24)
-+#define SSI_SOR __REG(IMX_SSI_BASE + 0x28)
+
+#define SPI1_RXDATA __REG(IMX_SPI1_BASE + 0x0)
+#define SPI1_TXDATA __REG(IMX_SPI1_BASE + 0x4)
Modified: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-073-armadeus-tsc2102.patch
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-073-armadeus-tsc2102.patch 2009-01-20 14:59:10 UTC (rev 1025)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.27.2/linux-2.6.27.2-073-armadeus-tsc2102.patch 2009-01-20 15:55:03 UTC (rev 1026)
@@ -3,7 +3,7 @@
(Take a look at armadeus/target/linux/ directory to know how to generate it)
--- linux-2.6.27.2.original/include/linux/spi/tsc2102.h
+++ linux-2.6.27.2.mod/include/linux/spi/tsc2102.h
-@@ -0,0 +1,177 @@
+@@ -0,0 +1,299 @@
+/*
+ * include/linux/spi/tsc2102.h
+ *
@@ -31,7 +31,8 @@
+
+struct apm_power_info;
+
-+struct tsc2102_config {
++struct tsc210x_config {
++ unsigned int mclk; /* Main clock, fixed if TSC is master */
+ int use_internal; /* Use internal reference voltage */
+ uint32_t monitor; /* What inputs are relevant */
+ void (*apm_report)(struct apm_power_info *info, int *battery);
@@ -43,123 +44,174 @@
+
+#define TSC_BAT1 (1 << 0)
+#define TSC_BAT2 (1 << 1)
-+#define TSC_AUX (1 << 2)
++#define TSC_AUX (1 << 2)
++#define TSC_AUX1 (1 << 2) /* TSC2101 has 2 Aux inputs */
++#define TSC_AUX2 (1 << 3)
+#define TSC_TEMP (1 << 4)
+
-+extern u16 tsc2102_read_sync(int page, u8 address);
-+extern void tsc2102_reads_sync(int page, u8 startaddress, u16 *data,
++extern u16 tsc210x_read_sync(int page, u8 address);
++extern void tsc210x_reads_sync(int page, u8 startaddress, u16 *data,
+ int numregs);
-+extern void tsc2102_write_sync(int page, u8 address, u16 data);
++extern void tsc210x_write_sync(int page, u8 address, u16 data);
+
-+typedef void (*tsc2102_touch_t)(int touching);
-+typedef void (*tsc2102_coords_t)(int x, int y, int z1, int z2);
-+typedef void (*tsc2102_ports_t)(int bat1, int bat2, int aux);
-+typedef void (*tsc2102_temp_t)(int temp);
-+extern int tsc2102_touch_cb(tsc2102_touch_t handler);
-+extern int tsc2102_coords_cb(tsc2102_coords_t handler);
-+extern int tsc2102_ports_cb(tsc2102_ports_t handler);
-+extern int tsc2102_temp1_cb(tsc2102_temp_t handler);
++typedef void (*tsc210x_touch_t)(int touching);
++typedef void (*tsc210x_coords_t)(int x, int y, int z1, int z2);
++typedef void (*tsc210x_ports_t)(int bat1, int bat2, int aux);
++typedef void (*tsc210x_temp_t)(int temp);
++extern int tsc210x_touch_cb(tsc210x_touch_t handler);
++extern int tsc210x_coords_cb(tsc210x_coords_t handler);
++extern int tsc210x_ports_cb(tsc210x_ports_t handler);
++extern int tsc210x_temp1_cb(tsc210x_temp_t handler);
+
+#if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
-+extern void tsc2102_set_volume(uint8_t left_ch, uint8_t right_ch);
-+extern void tsc2102_set_mute(int left_ch, int right_ch);
-+extern void tsc2102_get_mute(int *left_ch, int *right_ch);
-+extern void tsc2102_dac_power(int state);
-+extern int tsc2102_set_rate(int rate);
-+extern void tsc2102_set_i2s_master(int state);
-+extern void tsc2102_set_deemphasis(int enable);
-+extern void tsc2102_set_bassboost(int enable);
++extern void tsc210x_set_dac_volume(uint8_t left_ch, uint8_t right_ch);
++extern void tsc210x_set_dac_mute(int left_ch, int right_ch);
++extern void tsc210x_get_dac_mute(int *left_ch, int *right_ch);
++extern void tsc210x_dac_power(int state);
++extern int tsc210x_set_rate(int rate);
++extern void tsc210x_set_i2s_master(int state);
++extern void tsc210x_set_deemphasis(int enable);
++extern void tsc210x_set_bassboost(int enable);
+#endif // CONFIG_SOUND || CONFIG_SOUND_MODULE
+
-+extern void tsc2102_keyclick(int amplitude, int freq, int length);
++extern void tsc210x_keyclick(int amplitude, int freq, int length);
+
-+#define TSC2102_REG(pg, addr) pg, addr
++#define TSC210X_REG(pg, addr) pg, addr
+
+/* Page 0, Touch Screen & Keypad Data registers */
-+#define TSC2102_TS_X TSC2102_REG(0, 0x00)
-+#define TSC2102_TS_Y TSC2102_REG(0, 0x01)
-+#define TSC2102_TS_Z1 TSC2102_REG(0, 0x02)
-+#define TSC2102_TS_Z2 TSC2102_REG(0, 0x03)
-+#define TSC2102_TS_BAT1 TSC2102_REG(0, 0x05)
-+#define TSC2102_TS_BAT2 TSC2102_REG(0, 0x06)
-+#define TSC2102_TS_AUX TSC2102_REG(0, 0x07)
-+#define TSC2102_TS_TEMP1 TSC2102_REG(0, 0x09)
-+#define TSC2102_TS_TEMP2 TSC2102_REG(0, 0x0a)
++#define TSC2102_TS_X TSC210X_REG(0, 0x00)
++#define TSC2102_TS_Y TSC210X_REG(0, 0x01)
++#define TSC2102_TS_Z1 TSC210X_REG(0, 0x02)
++#define TSC2102_TS_Z2 TSC210X_REG(0, 0x03)
++#define TSC2102_TS_BAT1 TSC210X_REG(0, 0x05)
++#define TSC2102_TS_BAT2 TSC210X_REG(0, 0x06)
++#define TSC2102_TS_AUX TSC210X_REG(0, 0x07)
++#define TSC2102_TS_TEMP1 TSC210X_REG(0, 0x09)
++#define TSC2102_TS_TEMP2 TSC210X_REG(0, 0x0a)
+
+/* Page 1, Touch Screen & Keypad Control registers */
-+#define TSC2102_TS_ADC_CTRL TSC2102_REG(1, 0x00)
-+#define TSC2102_TS_STATUS_CTRL TSC2102_REG(1, 0x01)
-+#define TSC2102_TS_REF_CTRL TSC2102_REG(1, 0x03)
-+#define TSC2102_TS_RESET_CTRL TSC2102_REG(1, 0x04)
-+#define TSC2102_TS_CONFIG_CTRL TSC2102_REG(1, 0x05)
++#define TSC2102_TS_ADC_CTRL TSC210X_REG(1, 0x00)
++#define TSC2102_TS_STATUS_CTRL TSC210X_REG(1, 0x01)
++#define TSC2102_TS_REF_CTRL TSC210X_REG(1, 0x03)
++#define TSC2102_TS_RESET_CTRL TSC210X_REG(1, 0x04)
++#define TSC2102_TS_CONFIG_CTRL TSC210X_REG(1, 0x05)
+
+/* Page 2, Audio Control registers */
-+#define TSC2102_AUDIO1_CTRL TSC2102_REG(2, 0x00)
-+#define TSC2102_DAC_GAIN_CTRL TSC2102_REG(2, 0x02)
-+#define TSC2102_AUDIO2_CTRL TSC2102_REG(2, 0x04)
-+#define TSC2102_DAC_POWER_CTRL TSC2102_REG(2, 0x05)
-+#define TSC2102_AUDIO3_CTRL TSC2102_REG(2, 0x06)
-+#define TSC2102_LCH_BASS_BOOST_N0 TSC2102_REG(2, 0x07)
-+#define TSC2102_LCH_BASS_BOOST_N1 TSC2102_REG(2, 0x08)
-+#define TSC2102_LCH_BASS_BOOST_N2 TSC2102_REG(2, 0x09)
-+#define TSC2102_LCH_BASS_BOOST_N3 TSC2102_REG(2, 0x0a)
-+#define TSC2102_LCH_BASS_BOOST_N4 TSC2102_REG(2, 0x0b)
-+#define TSC2102_LCH_BASS_BOOST_N5 TSC2102_REG(2, 0x0c)
-+#define TSC2102_LCH_BASS_BOOST_D1 TSC2102_REG(2, 0x0d)
-+#define TSC2102_LCH_BASS_BOOST_D2 TSC2102_REG(2, 0x0e)
-+#define TSC2102_LCH_BASS_BOOST_D4 TSC2102_REG(2, 0x0f)
-+#define TSC2102_LCH_BASS_BOOST_D5 TSC2102_REG(2, 0x10)
-+#define TSC2102_RCH_BASS_BOOST_N0 TSC2102_REG(2, 0x11)
-+#define TSC2102_RCH_BASS_BOOST_N1 TSC2102_REG(2, 0x12)
-+#define TSC2102_RCH_BASS_BOOST_N2 TSC2102_REG(2, 0x13)
-+#define TSC2102_RCH_BASS_BOOST_N3 TSC2102_REG(2, 0x14)
-+#define TSC2102_RCH_BASS_BOOST_N4 TSC2102_REG(2, 0x15)
-+#define TSC2102_RCH_BASS_BOOST_N5 TSC2102_REG(2, 0x16)
-+#define TSC2102_RCH_BASS_BOOST_D1 TSC2102_REG(2, 0x17)
-+#define TSC2102_RCH_BASS_BOOST_D2 TSC2102_REG(2, 0x18)
-+#define TSC2102_RCH_BASS_BOOST_D4 TSC2102_REG(2, 0x19)
-+#define TSC2102_RCH_BASS_BOOST_D5 TSC2102_REG(2, 0x1a)
-+#define TSC2102_PLL1_CTRL TSC2102_REG(2, 0x1b)
-+#define TSC2102_PLL2_CTRL TSC2102_REG(2, 0x1c)
-+#define TSC2102_AUDIO4_CTRL TSC2102_REG(2, 0x1d)
++#define TSC2102_AUDIO1_CTRL TSC210X_REG(2, 0x00)
++#define TSC210X_DAC_GAIN_CTRL TSC210X_REG(2, 0x02)
++#define TSC2101_HEADSET_GAIN_CTRL TSC210X_REG(2, 0x01) /* TSC2101 only */
++#define TSC2101_MIXER_PGA_CTRL TSC210X_REG(2, 0x03) /* TSC2101 only */
++#define TSC2102_AUDIO2_CTRL TSC210X_REG(2, 0x04)
++#define TSC210X_CODEC_POWER_CTRL TSC210X_REG(2, 0x05)
++#define TSC2102_AUDIO3_CTRL TSC210X_REG(2, 0x06)
++#define TSC2102_LCH_BASS_BOOST_N0 TSC210X_REG(2, 0x07)
++#define TSC2102_LCH_BASS_BOOST_N1 TSC210X_REG(2, 0x08)
++#define TSC2102_LCH_BASS_BOOST_N2 TSC210X_REG(2, 0x09)
++#define TSC2102_LCH_BASS_BOOST_N3 TSC210X_REG(2, 0x0a)
++#define TSC2102_LCH_BASS_BOOST_N4 TSC210X_REG(2, 0x0b)
++#define TSC2102_LCH_BASS_BOOST_N5 TSC210X_REG(2, 0x0c)
++#define TSC2102_LCH_BASS_BOOST_D1 TSC210X_REG(2, 0x0d)
++#define TSC2102_LCH_BASS_BOOST_D2 TSC210X_REG(2, 0x0e)
++#define TSC2102_LCH_BASS_BOOST_D4 TSC210X_REG(2, 0x0f)
++#define TSC2102_LCH_BASS_BOOST_D5 TSC210X_REG(2, 0x10)
++#define TSC2102_RCH_BASS_BOOST_N0 TSC210X_REG(2, 0x11)
++#define TSC2102_RCH_BASS_BOOST_N1 TSC210X_REG(2, 0x12)
++#define TSC2102_RCH_BASS_BOOST_N2 TSC210X_REG(2, 0x13)
++#define TSC2102_RCH_BASS_BOOST_N3 TSC210X_REG(2, 0x14)
++#define TSC2102_RCH_BASS_BOOST_N4 TSC210X_REG(2, 0x15)
++#define TSC2102_RCH_BASS_BOOST_N5 TSC210X_REG(2, 0x16)
++#define TSC2102_RCH_BASS_BOOST_D1 TSC210X_REG(2, 0x17)
++#define TSC2102_RCH_BASS_BOOST_D2 TSC210X_REG(2, 0x18)
++#define TSC2102_RCH_BASS_BOOST_D4 TSC210X_REG(2, 0x19)
++#define TSC2102_RCH_BASS_BOOST_D5 TSC210X_REG(2, 0x1a)
++#define TSC210X_PLL1_CTRL TSC210X_REG(2, 0x1b)
++#define TSC210X_PLL2_CTRL TSC210X_REG(2, 0x1c)
++#define TSC2102_AUDIO4_CTRL TSC210X_REG(2, 0x1d)
++#define TSC2101_HANDSET_PGA_CTRL TSC210X_REG(2, 0x1e)
++#define TSC2101_CELL_BUZZER_PGA_CTRL TSC210X_REG(2, 0x1f)
++#define TSC2101_AUDIO5_CTRL TSC210X_REG(2, 0x20)
++#define TSC2101_AUDIO6_CTRL TSC210X_REG(2, 0x21)
++#define TSC2101_AUDIO7_CTRL TSC210X_REG(2, 0x22)
++#define TSC2101_GPIO_CTRL TSC210X_REG(2, 0x23)
++#define TSC2101_AGP_CPIN_CTRL TSC210X_REG(2, 0x24)
++#define TSC2101_POWERDOWN_STATUS TSC210X_REG(2, 0x25)
++#define TSC2101_MIC_AGC_CTRL TSC210X_REG(2, 0x26)
++#define TSC2101_CELL_PHONE_AGC_CTRL TSC210X_REG(2, 0x27)
+
+/* Field masks for Audio Control 1 */
++#define AC1_ADCHPF(ARG) (((ARG) & 0x03) << 14) /* TSC2101 only */
+#define AC1_WLEN(ARG) (((ARG) & 0x03) << 10)
+#define AC1_DATFM(ARG) (((ARG) & 0x03) << 8)
-+#define AC1_DACFS_MASK (0x3f)
-+#define AC1_DACFS(ARG) ((ARG) & AC1_DACFS_MASK)
++#define AC1_DACFS(ARG) (((ARG) & 0x07) << 3)
++#define AC1_ADCFS(ARG) (((ARG) & 0x07) << 0)
++/* on TSC2102 always set ADCFS = DACFS */
+
++/* Field masks for Gain Control for Headset/Aux Input */
++/* TSC2101 only */
++#define HGC_ADMUT_HED(ARG) (1 << 15)
++#define HGC_ADPGA_HED(ARG) (((ARG) & 0x7f) << 8)
++#define HGC_AGCTG_HED(ARG) (((ARG) & 0x07) << 5)
++#define HGC_AGCTC_HED(ARG) (((ARG) & 0x0f) << 1)
++#define HGC_AGCEN_HED(ARG) (1 << 0)
++
+/* Field masks for TSC2102_DAC_GAIN_CTRL */
+#define DGC_DALMU (1 << 15)
+#define DGC_DALVL(ARG) (((ARG) & 0x7f) << 8)
+#define DGC_DARMU (1 << 7)
+#define DGC_DARVL(ARG) (((ARG) & 0x7f))
+
++/* Field masks for Mixer PGA Control */
++/* TSC2101 only: */
++#define MPC_ASTMU (1 << 15)
++#define MPC_ASTG(ARG) (((ARG) & 0x7f) << 8)
++#define MPC_MICSEL(ARG) (((ARG) & 0x07) << 5)
++#define MPC_MICADC (1 << 4)
++#define MPC_CPADC (1 << 3)
++#define MPC_ASTGF (1 << 0)
++
+/* Field formats for TSC2102_AUDIO2_CTRL */
+#define AC2_KCLEN (1 << 15)
+#define AC2_KCLAC(ARG) (((ARG) & 0x07) << 12)
++#define AC2_APGASS (1 << 11) /* TSC2101 only */
+#define AC2_KCLFRQ(ARG) (((ARG) & 0x07) << 8)
+#define AC2_KCLLN(ARG) (((ARG) & 0x0f) << 4)
+#define AC2_DLGAF (1 << 3)
+#define AC2_DRGAF (1 << 2)
+#define AC2_DASTC (1 << 1)
++#define AC2_ADGAF (1 << 0) /* TSC2101 only */
+
-+/* Field masks for TSC2102_DAC_POWER_CTRL */
++/* Field masks for TSC2102_CODEC_POWER_CTRL */
+#define CPC_PWDNC (1 << 15)
+#define CPC_DAODRC (1 << 12)
+#define CPC_DAPWDN (1 << 10)
+#define CPC_VGPWDN (1 << 8)
+#define CPC_DAPWDF (1 << 6)
+#define CPC_BASSBC (1 << 1)
-+#define CPC_DEEMPF (0x01)
++#define CPC_DEEMPF (1 << 0)
++/* TSC2101 specific bits */
++#define CPC_MBIAS_HND (1 << 15)
++#define CPC_MBIAS_HED (1 << 14)
++#define CPC_ASTPWD (1 << 13)
++#define CPC_SP1PWDN (1 << 12)
++#define CPC_SP2PWDN (1 << 11)
++#define CPC_ADPWDN (1 << 9)
++#define CPC_COPWDN (1 << 7)
++#define CPC_LSPWDN (1 << 6)
++#define CPC_ADPWDF (1 << 5)
++#define CPC_LDAPWDF (1 << 4)
++#define CPC_RDAPWDF (1 << 3)
++#define CPC_ASTPWF (1 << 2)
++#define CPC_EFFCTL (1 << 1)
+
-+/* Field masks for TSC2101_AUDIO_CTRL_3 */
++/* Field masks for TSC210x_AUDIO_CTRL_3 */
+#define AC3_DMSVOL(ARG) (((ARG) & 0x03) << 14)
+#define AC3_REFFS (1 << 13)
+#define AC3_DAXFM (1 << 12)
+#define AC3_SLVMS (1 << 11)
++#define AC3_ADCOVF (1 << 8) /* TSC2101 only */
+#define AC3_DALOVF (1 << 7)
+#define AC3_DAROVF (1 << 6)
++#define AC3_CLPST (1 << 3) /* TSC2101 only */
+#define AC3_REVID(ARG) (((ARG) & 0x07))
+
+/* Field masks for TSC2102_PLL1_CTRL */
@@ -171,10 +223,80 @@
+/* Field masks for TSC2102_PLL2_CTRL */
+#define PLL2_D_VAL(ARG) (((ARG) & 0x3fff) << 2)
+
-+/* Field masks for TSC2101_AUDIO_CTRL_4 */
++/* Field masks for TSC210x_AUDIO_CTRL_4 */
+#define AC4_DASTPD (1 << 14)
++/* TSC2101 only: */
++#define AC4_ADSTPD (1 << 15)
++#define AC4_ASSTPD (1 << 13)
++#define AC4_CISTPD (1 << 12)
++#define AC4_BISTPD (1 << 11)
++#define AC4_AGCHYS(ARG) (((ARG) & 0x03) << 9)
++#define AC4_MB_HED(ARG) (((ARG) & 0x03) << 7)
++#define AC4_MB_HND (1 << 6)
++#define AC4_SCPFL (1 << 1)
+
-+struct tsc2102_rate_info_s {
++/* !! FOLLOWING REGISTERS ARE ONLY AVAILABLE ON TSC2101 !! */
++
++/* Field masks for TSC2101_HANDSET_PGA_CTRL */
++#define HIGC_ADMUT_HND (1 << 15)
++#define HIGC_ADPGA_HND(ARG) (((ARG) & 0x7f) << 8)
++#define HIGC_AGCTG_HND(ARG) (((ARG) & 0x07) << 5)
++#define HIGC_AGCTC_HND(ARG) (((ARG) & 0x0f) << 1)
++#define HIGC_AGCEN_HND(ARG) (1 << 0)
++
++/* Field masks for TSC2101_CELL_BUZZER_PGA_CTRL */
++#define CPBGC_MUT_CP (1 << 15)
++#define CPBGC_CPGA(ARG) (((ARG) & 0x7f) << 8)
++#define CPBGC_CPGF (1 << 7)
++#define CPBGC_MUT_BU (1 << 6)
++#define CPBGC_BPGA(ARG) (((ARG) & 0x0f) << 2)
++#define CPBGC_BUGF (1 << 1)
++
++/* Field masks for TSC2101_AUDIO_CTRL_5 */
++#define AC5_DIFFIN (1 << 15)
++#define AC5_DAC2SPK1(ARG) (((ARG) & 0x03) << 13)
++#define AC5_AST2SPK1 (1 << 12)
++#define AC5_BUZ2SPK1 (1 << 11)
++#define AC5_KCL2SPK1 (1 << 10)
++#define AC5_CPI2SPK1 (1 << 9)
++#define AC5_DAC2SPK2(ARG) (((ARG) & 0x03) << 7)
++#define AC5_AST2SPK2 (1 << 6)
++#define AC5_BUZ2SPK2 (1 << 5)
++#define AC5_KCL2SPK2 (1 << 4)
++#define AC5_CPI2SPK2 (1 << 3)
++#define AC5_MUTSPK1 (1 << 2)
++#define AC5_MUTSPK2 (1 << 1)
++#define AC5_HDSCPTC (1 << 0)
++
++/* Field masks for TSC2101_AUDIO_CTRL_6 */
++#define AC6_SPL2LSK (1 << 15)
++#define AC6_AST2LSK (1 << 14)
++#define AC6_BUZ2LSK (1 << 13)
++#define AC6_KCL2LSK (1 << 12)
++#define AC6_CPI2LSK (1 << 11)
++#define AC6_MIC2CPO (1 << 10)
++#define AC6_SPL2CPO (1 << 9)
++#define AC6_SPR2CPO (1 << 8)
++#define AC6_MUTLSPK (1 << 7)
++#define AC6_MUTSPK2 (1 << 6)
++#define AC6_LDSCPTC (1 << 5)
++#define AC6_VGNDSCPTC (1 << 4)
++#define AC6_CAPINTF (1 << 3)
++
++/* Field masks for TSC2101_AUDIO_CTRL_7 */
++#define AC7_DETECT (1 << 15)
++#define AC7_HESTYPE(ARG) (((ARG) & 0x03) << 13)
++#define AC7_HDDETFL (1 << 12)
++#define AC7_BDETFL (1 << 11)
++#define AC7_HDDEBNPG(ARG) (((ARG) & 0x03) << 9)
++#define AC7_BDEBNPG(ARG) (((ARG) & 0x03) << 6)
++#define AC7_DGPIO2 (1 << 4)
++#define AC7_DGPIO1 (1 << 3)
++#define AC7_CLKGPIO2 (1 << 2)
++#define AC7_ADWSF(ARG) ((ARG) & 0x03)
++
++
++struct tsc210x_rate_info_s {
+ u16 sample_rate;
+ u8 divisor;
+ u8 fs_44k; /* 44.1 kHz Fsref if 1, 48 kHz if 0 */
@@ -186,7 +308,7 @@
(Take a look at armadeus/target/linux/ directory to know how to generate it)
--- linux-2.6.27.2.original/drivers/spi/tsc2102.c
+++ linux-2.6.27.2.mod/drivers/spi/tsc2102.c
-@@ -0,0 +1,1000 @@
+@@ -0,0 +1,1114 @@
+/*
+ * drivers/spi/tsc2102.c
+ *
@@ -229,17 +351,11 @@
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/io.h>
-+/*#include <asm/mach-types.h>
-+#include <asm/hardware.h>*/
+
+#ifdef CONFIG_APM
+#include <asm/apm.h>
+#endif
+
-+#ifdef CONFIG_MACH_APF9328 // TODO: Put MCLK choice in Kconfig ??
-+#define MCLK_16M 1
-+#endif // CONFIG_MACH_APF9328
-+
+/* #define DEBUG */
+#define DEBUG_AUDIO
+
@@ -263,32 +379,20 @@
+#define TSC2102_PS_DAV 0x0078
+#define TSC2102_T1_DAV 0x0004
+#define TSC2102_T2_DAV 0x0002
++#define TSC2101_DAC_ON 0x0000
++#define TSC2101_DAC_OFF 0xe7fc
+#define TSC2102_DAC_ON 0x3ba0
+#define TSC2102_DAC_OFF 0xafa0
-+#define TSC2102_FS44K (1 << 13)
-+#define TSC2102_PLL1_OFF 0x0000
-+#ifdef MCLK_16M /* 16Mhz master clock */
-+#define TSC2102_PLL1_44K (PLL1_PLLEN | PLL1_Q_VAL(0) | PLL1_P_VAL(1) | PLL1_J_VAL(5))
-+#define TSC2102_PLL1_48K (PLL1_PLLEN | PLL1_Q_VAL(0) | PLL1_P_VAL(1) | PLL1_J_VAL(6))
-+#define TSC2102_PLL2_44K (PLL2_D_VAL(6448))
-+#define TSC2102_PLL2_48K (PLL2_D_VAL(1440))
-+#else
-+#define TSC2102_PLL1_44K 0x811c
-+#define TSC2102_PLL1_48K 0x8120
-+#define TSC2102_PLL2_44K (5462 << 2)
-+#define TSC2102_PLL2_48K (1920 << 2)
-+#endif // MCLK_16M
-+#define TSC2102_SLVMS (1 << 11)
-+#define TSC2102_DEEMPF (1 << 0)
-+#define TSC2102_BASSBC (1 << 1)
-+#define TSC2102_KEYCLICK_OFF 0x0000
++#define TSC210X_PLL1_OFF 0x0000
++#define TSC210x_AUDIO1_INIT_VAL (AC1_WLEN(0) | AC1_DATFM(0) | AC1_DACFS(0) | AC1_ADCFS(0))
++#define TSC210X_KEYCLICK_OFF 0x0000
+
+#define CS_CHANGE(val) 0
+
+#define SM_BAT_AUX 0
+#define SM_TEMP1 1
+
-+struct tsc2102_spi_req {
++struct tsc210x_spi_req {
+ struct spi_device *dev;
+ uint16_t command;
+ uint16_t data;
@@ -296,27 +400,32 @@
+ struct spi_message message;
+};
+
-+struct tsc2102_dev {
-+ struct tsc2102_config *pdata;
++struct tsc210x_dev {
++ enum tsc_type {
++ tsc2101,
++ tsc2102,
++ } kind;
++ struct tsc210x_config *pdata;
+ spinlock_t lock;
+ struct mutex lock_sync;
-+// struct clk *bclk_ck; TODO add clock mechanism to i.MX ???
++ struct clk *mclk_ck;
++ unsigned int mclk;
+
+ int state; /* Scan modes */
+ struct timer_list ts_timer; /* Busy-wait for PEN UP */
+ struct timer_list mode_timer; /* Change .state every some time */
+
+ uint16_t status, adc_status, adc_data[4];
-+ tsc2102_touch_t touch_cb;
-+ tsc2102_coords_t coords_cb;
-+ tsc2102_ports_t ports_cb;
-+ tsc2102_temp_t temp1_cb;
++ tsc210x_touch_t touch_cb;
++ tsc210x_coords_t coords_cb;
++ tsc210x_ports_t ports_cb;
++ tsc210x_temp_t temp1_cb;
+ unsigned int ts_msecs; /* Interval for .ts_timer */
+ unsigned int mode_msecs; /* Interval for .mode_timer */
+
+ struct spi_device *spi;
+
-+ int bat[2], aux[1], temp;
++ int bat[2], aux[2], temp;
+ struct device *hwmondev;
+ struct work_struct work;
+ unsigned long todo;
@@ -324,7 +433,7 @@
+
+};
+
-+static struct tsc2102_dev tsc;
++static struct tsc210x_dev tsc;
+
+module_param_named(touch_check_msecs, tsc.ts_msecs, uint, 0);
+MODULE_PARM_DESC(touch_check_msecs, "Pen-up polling interval in msecs");
@@ -332,9 +441,9 @@
+module_param_named(sensor_scan_msecs, tsc.mode_msecs, uint, 0);
+MODULE_PARM_DESC(sensor_scan_msecs, "Temperature & battery scan interval");
+
-+void tsc2102_write_sync(int page, u8 address, u16 data)
++void tsc210x_write_sync(int page, u8 address, u16 data)
+{
-+ static struct tsc2102_spi_req req;
++ static struct tsc210x_spi_req req;
+ static struct spi_transfer transfer[2];
+ int ret;
+
@@ -364,9 +473,9 @@
+ __FUNCTION__, ret);
+}
+
-+void tsc2102_reads_sync(int page, u8 startaddress, u16 *data, int numregs)
++void tsc210x_reads_sync(int page, u8 startaddress, u16 *data, int numregs)
+{
-+ static struct tsc2102_spi_req req;
++ static struct tsc210x_spi_req req;
+ static struct spi_transfer transfer[6];
+ int ret, i, j;
+
@@ -402,47 +511,53 @@
+ __FUNCTION__, ret);
+}
+
-+u16 tsc2102_read_sync(int page, u8 address)
++u16 tsc210x_read_sync(int page, u8 address)
+{
+ u16 ret;
-+ tsc2102_reads_sync(page, address, &ret, 1);
++ tsc210x_reads_sync(page, address, &ret, 1);
+ return ret;
+}
+
+static void tsc_work(struct work_struct *work)
+{
+#define Z2STAT (1<<7)
-+#define AXSTAT (1<<4)
++#define AXSTAT (3<<3)
+#define T1STAT (1<<2)
+
+ int status;
+
+ mutex_lock(&tsc.lock_sync);
++
+ /* state of SM has to be changed ? */
+ if( test_and_clear_bit( WORK_CHANGE_MODE,&tsc.todo) ){
++ tsc210x_write_sync(TSC2102_TS_ADC_CTRL, TSC2102_ADC_ADST);
+ /* change state of SM */
+ if( tsc.state == SM_TEMP1 ){
+ tsc.state = SM_BAT_AUX;
-+ tsc2102_write_sync(TSC2102_TS_STATUS_CTRL,
++ tsc210x_write_sync(TSC2102_TS_STATUS_CTRL,
+ TSC2102_ADC_DAV);
-+ tsc2102_write_sync(TSC2102_TS_ADC_CTRL,
++ tsc210x_write_sync(TSC2102_TS_ADC_CTRL,
+ TSC2102_ADC_SCAN_CONTROL);
+ }
+ else{
+ tsc.state = SM_TEMP1;
-+ tsc2102_write_sync(TSC2102_TS_STATUS_CTRL,
++ tsc210x_write_sync(TSC2102_TS_STATUS_CTRL,
+ TSC2102_ADC_DAV);
-+ tsc2102_write_sync(TSC2102_TS_ADC_CTRL,
++ tsc210x_write_sync(TSC2102_TS_ADC_CTRL,
+ TSC2102_ADC_T1_CONTROL);
+ }
++ /* restart mode timer */
++ mod_timer(&tsc.mode_timer, jiffies +
++ msecs_to_jiffies(tsc.mode_msecs));
+ }
-+
-+ status = tsc2102_read_sync(TSC2102_TS_STATUS_CTRL);
++ status = tsc210x_read_sync(TSC2102_TS_STATUS_CTRL);
+
-+ if( status & Z2STAT){
-+ int pendown;
-+ tsc2102_reads_sync( TSC2102_TS_X, tsc.adc_data, 4);
-+ pendown = tsc2102_read_sync(TSC2102_TS_ADC_CTRL) & TSC2102_ADC_PSTCM;
++ if (status & Z2STAT) {
++ /* get pendown status */
++ int pendown = tsc210x_read_sync(TSC2102_TS_ADC_CTRL) & TSC2102_ADC_PSTCM;
++ /* postponed next interrupt to avoid processor overload */
++ msleep(3);
++ tsc210x_reads_sync( TSC2102_TS_X, tsc.adc_data, 4);
+ /* avoid sending data if pen is up*/
+ if (tsc.coords_cb && pendown){
+ tsc.coords_cb(tsc.adc_data[0], tsc.adc_data[1],
@@ -450,34 +565,35 @@
+ }
+ }
+
-+ if( status & AXSTAT ){
-+ tsc2102_reads_sync( TSC2102_TS_BAT1, tsc.adc_data, 3);
++ if (status & AXSTAT) {
++ tsc210x_reads_sync(TSC2102_TS_BAT1, tsc.adc_data, 4);
+ if (tsc.ports_cb)
+ tsc.ports_cb(tsc.adc_data[0], tsc.adc_data[1],
+ tsc.adc_data[2]);
+ tsc.bat[0] = tsc.adc_data[0];
+ tsc.bat[1] = tsc.adc_data[1];
+ tsc.aux[0] = tsc.adc_data[2];
++ tsc.aux[1] = tsc.adc_data[3];
+ /* switch to pintdav and TS control */
-+ tsc2102_write_sync( TSC2102_TS_ADC_CTRL,
++ tsc210x_write_sync(TSC2102_TS_ADC_CTRL,
+ TSC2102_ADC_TS_CONTROL);
-+ tsc2102_write_sync(TSC2102_TS_STATUS_CTRL, TSC2102_ADC_PINTDAV);
++ tsc210x_write_sync(TSC2102_TS_STATUS_CTRL, TSC2102_ADC_PINTDAV);
+ }
-+ else if( status & T1STAT) {
-+ tsc.temp = tsc2102_read_sync(TSC2102_TS_TEMP1);
++ else if (status & T1STAT) {
++ tsc.temp = tsc210x_read_sync(TSC2102_TS_TEMP1);
+ if (tsc.temp1_cb)
+ tsc.temp1_cb(tsc.temp);
+ /* switch to pintdav and TS control */
-+ tsc2102_write_sync( TSC2102_TS_ADC_CTRL,
++ tsc210x_write_sync( TSC2102_TS_ADC_CTRL,
+ TSC2102_ADC_TS_CONTROL);
-+ tsc2102_write_sync(TSC2102_TS_STATUS_CTRL, TSC2102_ADC_PINTDAV);
++ tsc210x_write_sync(TSC2102_TS_STATUS_CTRL, TSC2102_ADC_PINTDAV);
+ }
+
+ mutex_unlock(&tsc.lock_sync);
+}
+
-+#define tsc2102_cb_register_func(cb, cb_t) \
-+int tsc2102_ ## cb(cb_t handler) \
++#define tsc210x_cb_register_func(cb, cb_t) \
++int tsc210x_ ## cb(cb_t handler) \
+{ \
+ spin_lock(&tsc.lock); \
+ \
@@ -496,17 +612,17 @@
+}
+
+
-+tsc2102_cb_register_func(touch_cb, tsc2102_touch_t)
-+EXPORT_SYMBOL(tsc2102_touch_cb);
-+tsc2102_cb_register_func(coords_cb, tsc2102_coords_t)
-+EXPORT_SYMBOL(tsc2102_coords_cb);
-+tsc2102_cb_register_func(ports_cb, tsc2102_ports_t)
-+tsc2102_cb_register_func(temp1_cb, tsc2102_temp_t)
++tsc210x_cb_register_func(touch_cb, tsc210x_touch_t)
++EXPORT_SYMBOL(tsc210x_touch_cb);
++tsc210x_cb_register_func(coords_cb, tsc210x_coords_t)
++EXPORT_SYMBOL(tsc210x_coords_cb);
++tsc210x_cb_register_func(ports_cb, tsc210x_ports_t)
++tsc210x_cb_register_func(temp1_cb, tsc210x_temp_t)
+
+#ifdef DEBUG
+static void tsc2102_print_dav(void)
+{
-+ u16 status = tsc2102_read_sync(TSC2102_TS_STATUS_CTRL);
++ u16 status = tsc210x_read_sync(TSC2102_TS_STATUS_CTRL);
+ if (status & 0x0fff)
+ printk("TSC2102: data in");
+ if (status & 0x0400)
@@ -538,19 +654,18 @@
+
+static void tsc2102_mode(unsigned long data)
+{
-+ struct tsc2102_dev *dev = (struct tsc2102_dev *) data;
-+ /* request change of SM state */
-+ set_bit(WORK_CHANGE_MODE, &dev->todo);
-+ schedule_work(&dev->work);
-+ /* restart mode timer */
-+ mod_timer(&dev->mode_timer, jiffies +
-+ msecs_to_jiffies(dev->mode_msecs));
++ struct tsc210x_dev *dev = (struct tsc210x_dev *) data;
++// if(!test_bit( PENDOWN,&dev->todo)){
++ /* request change of SM state */
++ set_bit(WORK_CHANGE_MODE, &dev->todo);
++ schedule_work(&dev->work);
++// }
+}
+
+/* TSC has new data for us available. */
+static irqreturn_t tsc2102_handler(int irq, void *dev_id)
+{
-+ struct tsc2102_dev *dev = (struct tsc2102_dev *) dev_id;
++ struct tsc210x_dev *dev = (struct tsc210x_dev *) dev_id;
+ /* restart pen up timer */
+ mod_timer(&tsc.ts_timer, jiffies +
+ msecs_to_jiffies(tsc.ts_msecs));
@@ -561,7 +676,9 @@
+
+static void tsc2102_pressure(unsigned long data)
+{
-+ struct tsc2102_dev *dev = (struct tsc2102_dev *) data;
++ struct tsc210x_dev *dev = (struct tsc210x_dev *) data;
++ //printk("pen up\n");
++ //clear_bit(PENDOWN, &dev->todo);
+ if (dev->touch_cb)
+ dev->touch_cb(0);
+}
@@ -572,238 +689,323 @@
+ * Volume level values should be in the range [0, 127].
+ * Higher values mean lower volume.
+ */
-+void tsc2102_set_volume(uint8_t left_ch, uint8_t right_ch)
++void tsc210x_set_dac_volume(uint8_t left_ch, uint8_t right_ch)
+{
+ u16 val;
-+ if (left_ch == 0x00 || left_ch == 0x7f) /* All 0's or all 1's */
-+ left_ch ^= 0x7f;
-+ if (right_ch == 0x00 || right_ch == 0x7f)
-+ right_ch ^= 0x7f;
+
++ if (tsc.kind == tsc2102) {
++ /* On TSC2102, 127 means 0dB and 0 -63,5 dB */
++ if (left_ch == 0x00 || left_ch == 0x7f)
++ left_ch ^= 0x7f;
++ if (right_ch == 0x00 || right_ch == 0x7f)
++ right_ch ^= 0x7f;
++ }
+ mutex_lock(&tsc.lock_sync);
-+ val = tsc2102_read_sync(TSC2102_DAC_GAIN_CTRL);
++ val = tsc210x_read_sync(TSC210X_DAC_GAIN_CTRL);
++ /* ?? No check ?? */
+
-+ val &= 0x8080; /* Preserve mute-bits */
-+ val |= (left_ch << 8) | right_ch;
++ val &= (DGC_DALMU | DGC_DARMU); /* Preserve mute-bits */
++ val |= DGC_DALVL(left_ch) | DGC_DARVL(right_ch);
+
-+ tsc2102_write_sync(TSC2102_DAC_GAIN_CTRL, val);
++ tsc210x_write_sync(TSC210X_DAC_GAIN_CTRL, val);
+ mutex_unlock(&tsc.lock_sync);
+}
-+EXPORT_SYMBOL(tsc2102_set_volume);
++EXPORT_SYMBOL(tsc210x_set_dac_volume);
+
-+void tsc2102_set_mute(int left_ch, int right_ch)
++void tsc210x_set_dac_mute(int left_ch, int right_ch)
+{
+ u16 val;
+ mutex_lock(&tsc.lock_sync);
+
-+ val = tsc2102_read_sync(TSC2102_DAC_GAIN_CTRL);
++ val = tsc210x_read_sync(TSC210X_DAC_GAIN_CTRL);
++ /* ?? No check ?? */
+
-+ val &= 0x7f7f; /* Preserve volume settings */
-+ val |= (left_ch << 15) | (right_ch << 7);
++ val &= DGC_DALVL(0x7f) | DGC_DARVL(0x7f); /* Preserve volume settings */
++ if (left_ch)
++ val |= DGC_DALMU;
++ if (right_ch)
++ val |= DGC_DARMU;
+
-+ tsc2102_write_sync(TSC2102_DAC_GAIN_CTRL, val);
++ tsc210x_write_sync(TSC210X_DAC_GAIN_CTRL, val);
+
+ mutex_unlock(&tsc.lock_sync);
+}
-+EXPORT_SYMBOL(tsc2102_set_mute);
++EXPORT_SYMBOL(tsc210x_set_dac_mute);
+
-+void tsc2102_get_mute(int *left_ch, int *right_ch)
++void tsc210x_get_dac_mute(int *left_ch, int *right_ch)
+{
+ u16 val;
+ mutex_lock(&tsc.lock_sync);
+
-+ val = tsc2102_read_sync(TSC2102_DAC_GAIN_CTRL);
++ val = tsc210x_read_sync(TSC210X_DAC_GAIN_CTRL);
+
+ mutex_unlock(&tsc.lock_sync);
+
-+ *left_ch = !!(val & (1 << 15));
-+ *right_ch = !!(val & (1 << 7));
++ *left_ch = !!(val & DGC_DALMU);
++ *right_ch = !!(val & DGC_DARMU);
+}
-+EXPORT_SYMBOL(tsc2102_get_mute);
++EXPORT_SYMBOL(tsc210x_get_dac_mute);
+
-+void tsc2102_set_deemphasis(int enable)
++void tsc210x_set_deemphasis(int enable)
+{
+ u16 val;
+ mutex_lock(&tsc.lock_sync);
-+ val = tsc2102_read_sync(TSC2102_DAC_POWER_CTRL);
++ val = tsc210x_read_sync(TSC210X_CODEC_POWER_CTRL);
+
+ if (enable)
-+ val &= ~TSC2102_DEEMPF;
++ val &= ~CPC_DEEMPF;
+ else
-+ val |= TSC2102_DEEMPF;
++ val |= CPC_DEEMPF;
+
-+ tsc2102_write_sync(TSC2102_DAC_POWER_CTRL, val);
++ tsc210x_write_sync(TSC210X_CODEC_POWER_CTRL, val);
+ mutex_unlock(&tsc.lock_sync);
+}
-+EXPORT_SYMBOL(tsc2102_set_deemphasis);
++EXPORT_SYMBOL(tsc210x_set_deemphasis);
+
-+void tsc2102_set_bassboost(int enable)
++void tsc210x_set_bassboost(int enable)
+{
+ u16 val;
++
+ mutex_lock(&tsc.lock_sync);
-+ val = tsc2102_read_sync(TSC2102_DAC_POWER_CTRL);
++ val = tsc210x_read_sync(TSC210X_CODEC_POWER_CTRL);
+
+ if (enable)
-+ val &= ~TSC2102_BASSBC;
++ val &= ~CPC_BASSBC;
+ else
-+ val |= TSC2102_BASSBC;
++ val |= CPC_BASSBC;
+
-+ tsc2102_write_sync(TSC2102_DAC_POWER_CTRL, val);
++ tsc210x_write_sync(TSC210X_CODEC_POWER_CTRL, val);
+ mutex_unlock(&tsc.lock_sync);
+}
-+EXPORT_SYMBOL(tsc2102_set_bassboost);
++EXPORT_SYMBOL(tsc210x_set_bassboost);
+
-+/* {rate, divisor, fsref?=44,1k} */
-+static const struct tsc2102_rate_info_s tsc2102_rates[] = {
++/* {rate, divisor (for AC1), fsref} */
++static const struct tsc210x_rate_info_s tsc210x_rates[] = {
+ /* Fsref / 6.0 */
-+ {7350, 63, 1},
-+ {8000, 63, 0},
-+ /* Fsref / 6.0 */
-+ {7350, 54, 1},
-+ {8000, 54, 0},
++ {7350, 7, 1},
++ {8000, 7, 0},
++ /* Fsref / 5.5 */
++ {7350, 6, 1},
++ {8000, 6, 0},
+ /* Fsref / 5.0 */
-+ {8820, 45, 1},
-+ {9600, 45, 0},
++ {8820, 5, 1},
++ {9600, 5, 0},
+ /* Fsref / 4.0 */
-+ {11025, 36, 1},
-+ {12000, 36, 0},
++ {11025, 4, 1},
++ {12000, 4, 0},
+ /* Fsref / 3.0 */
-+ {14700, 27, 1},
-+ {16000, 27, 0},
++ {14700, 3, 1},
++ {16000, 3, 0},
+ /* Fsref / 2.0 */
-+ {22050, 18, 1},
-+ {24000, 18, 0},
++ {22050, 2, 1},
++ {24000, 2, 0},
+ /* Fsref / 1.5 */
-+ {29400, 9, 1},
-+ {32000, 9, 0},
++ {29400, 1, 1},
++ {32000, 1, 0},
+ /* Fsref */
+ {44100, 0, 1},
+ {48000, 0, 0},
-+
+ /* end of struct */
+ {0, 0, 0},
+};
+
-+int tsc2102_set_rate(int rate)
++struct pll_values {
++ u16 pll1;
++ u16 pll2;
++};
++
++static void tsc210x_calculate_pll(struct pll_values* pll, unsigned int mclk, unsigned int fsref)
+{
++ if (fsref == 44100) {
++ switch(mclk)
++ {
++ case 12288000:
++ pll->pll1 = (PLL1_PLLEN | PLL1_Q_VAL(0) | PLL1_P_VAL(1) | PLL1_J_VAL(7));
++ pll->pll2 = (PLL2_D_VAL(3500));
++ break;
++
++ case 16000000:
++ pll->pll1 = (PLL1_PLLEN | PLL1_Q_VAL(0) | PLL1_P_VAL(1) | PLL1_J_VAL(5));
++ pll->pll2 = (PLL2_D_VAL(6448));
++ break;
++
++ default:
++ pll->pll1 = 0x811c;
++ pll->pll2 = (PLL2_D_VAL(5462));
++ break;
++ }
++ } else { /* 48000 */
++ switch(mclk)
++ {
++ case 12288000:
++ /*pll->pll1 = (PLL1_Q_VAL(2)) -> doesn't work without enabling PLL */
++ pll->pll1 = (PLL1_PLLEN | PLL1_Q_VAL(0) | PLL1_P_VAL(1) | PLL1_J_VAL(8));
++ pll->pll2 = (PLL2_D_VAL(0));
++ break;
++
++ case 16000000:
++ pll->pll1 = (PLL1_PLLEN | PLL1_Q_VAL(0) | PLL1_P_VAL(1) | PLL1_J_VAL(6));
++ pll->pll2 = (PLL2_D_VAL(1440));
++ break;
++
++ default:
++ pll->pll1 = 0x8120;
++ pll->pll2 = (PLL2_D_VAL(1920));
++ break;
++ }
++ }
++}
++
++static void tsc210x_set_fsref(unsigned int fsref)
++{
++ struct pll_values pll;
++
++ tsc210x_calculate_pll(&pll, tsc.mclk, fsref);
++ /* Enable Phase-locked-loop & set up clock dividers */
++ tsc210x_write_sync(TSC210X_PLL1_CTRL, pll.pll1);
++ tsc210x_write_sync(TSC210X_PLL2_CTRL, pll.pll2);
++}
++
++int tsc210x_set_rate(int rate)
++{
+ int i;
-+ uint16_t val;
++ int val;
++ const struct tsc210x_rate_info_s *rates;
+
-+ for (i = 0; tsc2102_rates[i].sample_rate; i ++)
-+ if (tsc2102_rates[i].sample_rate == rate)
++ rates = tsc210x_rates;
++
++ for (i = 0; rates[i].sample_rate; i ++)
++ if (rates[i].sample_rate == rate)
+ break;
-+ if (tsc2102_rates[i].sample_rate == 0) {
++ if (rates[i].sample_rate == 0) {
+ printk(KERN_ERR "Unknown sampling rate %i.0 Hz\n", rate);
+ return -EINVAL;
+ }
+
+ mutex_lock(&tsc.lock_sync);
+
-+ val = tsc2102_read_sync(TSC2102_AUDIO1_CTRL) & ~AC1_DACFS_MASK;
-+ tsc2102_write_sync(TSC2102_AUDIO1_CTRL, val | AC1_DACFS(tsc2102_rates[i].divisor) );
++ val = tsc210x_read_sync(TSC2102_AUDIO1_CTRL);
++ if (val < 0) {
++ printk(KERN_ERR "%s, err %d\n", __FUNCTION__, val);
++ return val;
++ }
+
-+ val = tsc2102_read_sync(TSC2102_AUDIO3_CTRL);
++ val &= ~AC1_DACFS(0xff) & ~AC1_ADCFS(0xff);
++ val |= AC1_DACFS(rates[i].divisor);
++ val |= AC1_ADCFS(rates[i].divisor);
++ tsc210x_write_sync(TSC2102_AUDIO1_CTRL, val );
+
-+ if (tsc2102_rates[i].fs_44k) {
-+ tsc2102_write_sync(TSC2102_AUDIO3_CTRL, val | TSC2102_FS44K);
-+ /* Enable Phase-locked-loop, set up clock dividers */
-+ tsc2102_write_sync(TSC2102_PLL1_CTRL, TSC2102_PLL1_44K);
-+ tsc2102_write_sync(TSC2102_PLL2_CTRL, TSC2102_PLL2_44K);
++ val = tsc210x_read_sync(TSC2102_AUDIO3_CTRL);
++
++ if (rates[i].fs_44k) {
++ tsc210x_write_sync(TSC2102_AUDIO3_CTRL, val | AC3_REFFS);
++ tsc210x_set_fsref(44100);
+ } else {
-+ tsc2102_write_sync(TSC2102_AUDIO3_CTRL, val & ~TSC2102_FS44K);
-+ /* Enable Phase-locked-loop, set up clock dividers */
-+ tsc2102_write_sync(TSC2102_PLL1_CTRL, TSC2102_PLL1_48K);
-+ tsc2102_write_sync(TSC2102_PLL2_CTRL, TSC2102_PLL2_48K);
++ tsc210x_write_sync(TSC2102_AUDIO3_CTRL, val & ~AC3_REFFS);
++ tsc210x_set_fsref(48000);
+ }
+
+ mutex_unlock(&tsc.lock_sync);
+ return 0;
+}
-+EXPORT_SYMBOL(tsc2102_set_rate);
++EXPORT_SYMBOL(tsc210x_set_rate);
+
+/*
+ * Perform basic set-up with default values and power the DAC on.
+ */
-+void tsc2102_dac_power(int state)
++void tsc210x_dac_power(int state)
+{
+ mutex_lock(&tsc.lock_sync);
+
+ if (state) {
+ /* 16-bit words, I2S mode, sample at Fsref */
-+ tsc2102_write_sync(TSC2102_AUDIO1_CTRL, AC1_WLEN(0) | AC1_DATFM(0) | AC1_DACFS(0) );
++ tsc210x_write_sync(TSC2102_AUDIO1_CTRL, AC1_WLEN(0) | AC1_DATFM(0) | AC1_DACFS(0) );
+ /* Keyclicks off, soft-stepping at normal rate */
-+ tsc2102_write_sync(TSC2102_AUDIO2_CTRL, TSC2102_KEYCLICK_OFF);
++ tsc210x_write_sync(TSC2102_AUDIO2_CTRL, TSC210X_KEYCLICK_OFF);
+ /* 44.1 kHz Fsref, continuous transfer mode, master DAC */
-+ tsc2102_write_sync(TSC2102_AUDIO3_CTRL, 0x2800);
++ tsc210x_write_sync(TSC2102_AUDIO3_CTRL, 0x2800);
+ /* Soft-stepping enabled */
-+ tsc2102_write_sync(TSC2102_AUDIO4_CTRL, 0x0000);
-+
++ tsc210x_write_sync(TSC2102_AUDIO4_CTRL, 0x0000);
+ /* PLL generates 44.1 kHz */
-+ tsc2102_write_sync(TSC2102_PLL1_CTRL, TSC2102_PLL1_44K);
-+ tsc2102_write_sync(TSC2102_PLL2_CTRL, TSC2102_PLL2_44K);
-+
++ tsc210x_set_fsref(44100);
+ /* Codec & DAC power up, virtual ground disabled */
-+ tsc2102_write_sync(TSC2102_DAC_POWER_CTRL, TSC2102_DAC_ON);
++ tsc210x_write_sync(TSC210X_CODEC_POWER_CTRL,
++ (tsc.kind == tsc2101) ? TSC2101_DAC_ON : TSC2102_DAC_ON);
+ } else {
+ /* All off */
-+ tsc2102_write_sync(TSC2102_AUDIO4_CTRL, TSC2102_KEYCLICK_OFF);
-+ tsc2102_write_sync(TSC2102_PLL1_CTRL, TSC2102_PLL1_OFF);
++ tsc210x_write_sync(TSC2102_AUDIO2_CTRL, TSC210X_KEYCLICK_OFF);
++ tsc210x_write_sync(TSC210X_PLL1_CTRL, TSC210X_PLL1_OFF);
+ }
+
+ mutex_unlock(&tsc.lock_sync);
+}
-+EXPORT_SYMBOL(tsc2102_dac_power);
++EXPORT_SYMBOL(tsc210x_dac_power);
+
-+void tsc2102_set_i2s_master(int state)
++void tsc210x_set_i2s_master(int state)
+{
+ uint16_t val;
+ mutex_lock(&tsc.lock_sync);
+
-+ val = tsc2102_read_sync(TSC2102_AUDIO3_CTRL);
++ val = tsc210x_read_sync(TSC2102_AUDIO3_CTRL);
++ /* if (val < 0) { ?? no check ??
++ printk(KERN_ERR "%s, err %d\n", __FUNCTION__, val);
++ return;
++ }*/
+
+ if (state)
-+ tsc2102_write_sync(TSC2102_AUDIO3_CTRL, val | TSC2102_SLVMS);
++ tsc210x_write_sync(TSC2102_AUDIO3_CTRL, val | AC3_SLVMS);
+ else
-+ tsc2102_write_sync(TSC2102_AUDIO3_CTRL, val & ~TSC2102_SLVMS);
++ tsc210x_write_sync(TSC2102_AUDIO3_CTRL, val & ~AC3_SLVMS);
+
+ mutex_unlock(&tsc.lock_sync);
+}
-+EXPORT_SYMBOL(tsc2102_set_i2s_master);
++EXPORT_SYMBOL(tsc210x_set_i2s_master);
+#endif /* CONFIG_SOUND || CONFIG_SOUND_MODULE */
+
-+static int tsc2102_configure(struct tsc2102_dev *dev)
++static int tsc2102_configure(struct tsc210x_dev *dev)
+{
+ /* Reset the chip */
-+ tsc2102_write_sync(TSC2102_TS_RESET_CTRL, TSC2102_RESET);
++ tsc210x_write_sync(TSC2102_TS_RESET_CTRL, TSC2102_RESET);
+
+ /* Reference mode, 100 usec delay, 2.5V reference */
+ if (dev->pdata->use_internal)
-+ tsc2102_write_sync(TSC2102_TS_REF_CTRL, TSC2102_ADC_REF);
++ tsc210x_write_sync(TSC2102_TS_REF_CTRL, TSC2102_ADC_REF);
+ else
-+ tsc2102_write_sync(TSC2102_TS_REF_CTRL, TSC2102_ADC_EXT_REF);
++ tsc210x_write_sync(TSC2102_TS_REF_CTRL, TSC2102_ADC_EXT_REF);
+
+ /* 84 usec precharge time, 32 usec sense time */
-+ tsc2102_write_sync(TSC2102_TS_CONFIG_CTRL, TSC2102_CONFIG_TIMES);
++ tsc210x_write_sync(TSC2102_TS_CONFIG_CTRL, TSC2102_CONFIG_TIMES);
+
+ /* PINT/DAV acts as PINT */
-+ tsc2102_write_sync(TSC2102_TS_STATUS_CTRL, TSC2102_ADC_DAV);
++ tsc210x_write_sync(TSC2102_TS_STATUS_CTRL, TSC2102_ADC_DAV);
+
-+#if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
++#if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
+ /* 16-bit words, I2S mode, sample at Fsref */
-+ tsc2102_write_sync(TSC2102_AUDIO1_CTRL, AC1_WLEN(0) | AC1_DATFM(0) | AC1_DACFS(0) );
++ tsc210x_write_sync(TSC2102_AUDIO1_CTRL, TSC210x_AUDIO1_INIT_VAL );
+ /* Keyclicks off, soft-stepping at normal rate */
-+ tsc2102_write_sync(TSC2102_AUDIO2_CTRL, TSC2102_KEYCLICK_OFF);
++ tsc210x_write_sync(TSC2102_AUDIO2_CTRL, TSC210X_KEYCLICK_OFF);
+ /* 48 kHz Fsref, continuous transfer mode, master DAC */
-+ tsc2102_write_sync(TSC2102_AUDIO3_CTRL, 0x0800);
++ tsc210x_write_sync(TSC2102_AUDIO3_CTRL, 0x0800);
+ /* Soft-stepping enabled */
-+ tsc2102_write_sync(TSC2102_AUDIO4_CTRL, 0x0000);
++ tsc210x_write_sync(TSC2102_AUDIO4_CTRL, 0x0000);
+ /* FSRef = 44,1k */
-+ tsc2102_write_sync(TSC2102_PLL1_CTRL, TSC2102_PLL1_44K);
-+ tsc2102_write_sync(TSC2102_PLL2_CTRL, TSC2102_PLL2_44K);
++ tsc210x_set_fsref(44100);
+
-+ tsc2102_write_sync(TSC2102_DAC_GAIN_CTRL, 0xA0A0);
-+ tsc2102_write_sync(TSC2102_DAC_POWER_CTRL, 0x3BA0);
-+ tsc2102_write_sync(TSC2102_DAC_GAIN_CTRL, 0x7F7F);
++ if (tsc.kind == tsc2101) {
++ tsc210x_write_sync(TSC2101_AUDIO5_CTRL, /*AC5_AST2SPK1 |*/ AC5_DAC2SPK1(1) | AC5_DAC2SPK2(2));
++ tsc210x_write_sync(TSC2101_MIXER_PGA_CTRL, /*0x7f00*/ 0xc500 /* reset value */ | MPC_MICSEL(1) | MPC_MICADC);
++ tsc210x_write_sync(TSC2101_HEADSET_GAIN_CTRL, HGC_ADPGA_HED(0));
++ tsc210x_write_sync(TSC2101_HANDSET_PGA_CTRL, 0x0000);
++// tsc210x_write_sync(TSC210X_CODEC_POWER_CTRL, 0x00fc);
++ tsc210x_write_sync(TSC210X_CODEC_POWER_CTRL, 0xe2fc);
++ }
++ else
++ tsc210x_write_sync(TSC210X_CODEC_POWER_CTRL, TSC2102_DAC_ON);
++ /* Un-mute + volume max */
++ if (tsc.kind == tsc2101)
++ tsc210x_write_sync(TSC210X_DAC_GAIN_CTRL, 0x0000);
++ else
++ tsc210x_write_sync(TSC210X_DAC_GAIN_CTRL, 0x7F7F);
+#endif /* CONFIG_SOUND || CONFIG_SOUND_MODULE */
+
+ /* Init mode state machine */
@@ -816,11 +1018,11 @@
+}
+
+/*
-+ * Retrieves chip revision. Should be always 1.
++ * Retrieves chip revision. Should be 1 for TSC2102 and 4 for TSC2101
+ */
+int tsc2102_get_revision(void)
+{
-+ return tsc2102_read_sync(TSC2102_AUDIO3_CTRL) & 7;
++ return AC3_REVID(tsc210x_read_sync(TSC2102_AUDIO3_CTRL));
+}
+
+/*
@@ -834,42 +1036,44 @@
+ * This function sleeps but doesn't sleep until the sound has
+ * finished.
+ */
-+void tsc2102_keyclick(int amplitude, int freq, int length)
++void tsc210x_keyclick(int amplitude, int freq, int length)
+{
+ u16 val;
++
+ mutex_lock(&tsc.lock_sync);
-+ val = tsc2102_read_sync(TSC2102_AUDIO2_CTRL);
-+ val &= 0x800f;
++ val = tsc210x_read_sync(TSC2102_AUDIO2_CTRL);
++ /* Keeps current control values: */
++ val &= AC2_KCLEN | AC2_APGASS | AC2_DLGAF | AC2_DRGAF | AC2_DASTC | AC2_ADGAF;
+
+ /* Set amplitude */
+ switch (amplitude) {
+ case 1:
-+ val |= 4 << 12;
++ val |= AC2_KCLAC(4);
+ break;
+ case 2:
-+ val |= 7 << 12;
++ val |= AC2_KCLAC(7);
+ break;
+ default:
+ break;
+ }
+
+ /* Frequency */
-+ val |= (freq & 0x7) << 8;
++ val |= AC2_KCLFRQ(0x7);
+
+ /* Round to nearest supported length */
-+ if (length > 20)
-+ val |= 4 << 4;
++ if (length > 8)
++ val |= AC2_KCLLN(4);
+ else if (length > 6)
-+ val |= 3 << 4;
++ val |= AC2_KCLLN(3);
+ else if (length > 4)
-+ val |= 2 << 4;
++ val |= AC2_KCLLN(2);
+ else if (length > 2)
-+ val |= 1 << 4;
++ val |= AC2_KCLLN(1);
+
+ /* Enable keyclick */
-+ val |= 0x8000;
++ val |= AC2_KCLEN;
+
-+ tsc2102_write_sync(TSC2102_AUDIO2_CTRL, val);
++ tsc210x_write_sync(TSC2102_AUDIO2_CTRL, val);
+ mutex_unlock(&tsc.lock_sync);
+}
+
@@ -878,7 +1082,7 @@
+static ssize_t show_ ## devname(struct device *dev, \
+ struct device_attribute *devattr, char *buf) \
+{ \
-+ struct tsc2102_dev *devhwmon = dev_get_drvdata(dev); \
++ struct tsc210x_dev *devhwmon = dev_get_drvdata(dev); \
+ int value = devhwmon->field; \
+ return sprintf(buf, "%i\n", value); \
+} \
@@ -887,12 +1091,13 @@
+TSC2102_INPUT(in0, bat[0])
+TSC2102_INPUT(in1, bat[1])
+TSC2102_INPUT(in2, aux[0])
-+TSC2102_INPUT(in3, temp)
++TSC2102_INPUT(in3, aux[1])
++TSC2102_INPUT(in4, temp)
+
+static ssize_t show_temp1(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
-+ struct tsc2102_dev *devhwmon = dev_get_drvdata(dev);
++ struct tsc210x_dev *devhwmon = dev_get_drvdata(dev);
+ int value;
+
+ value = (-devhwmon->temp*7 + 8400)*50 ; /* Celcius millidegree */
@@ -914,9 +1119,9 @@
+ * Suspend the chip.
+ */
+static int
-+tsc2102_suspend(struct spi_device *spi, pm_message_t state)
++tsc210x_suspend(struct spi_device *spi, pm_message_t state)
+{
-+ struct tsc2102_dev *dev = dev_get_drvdata(&spi->dev);
++ struct tsc210x_dev *dev = dev_get_drvdata(&spi->dev);
+
+ if (!dev)
+ return 0;
@@ -931,7 +1136,7 @@
+ dev->touch_cb(0);
+
+ /* Abort current conversion and power down the ADC */
-+ tsc2102_write_sync(TSC2102_TS_ADC_CTRL, TSC2102_ADC_ADST);
++ tsc210x_write_sync(TSC2102_TS_ADC_CTRL, TSC2102_ADC_ADST);
+
+ dev->spi->dev.power.power_state = state;
+ mutex_unlock(&dev->lock_sync);
@@ -942,9 +1147,9 @@
+/*
+ * Resume chip operation.
+ */
-+static int tsc2102_resume(struct spi_device *spi)
++static int tsc210x_resume(struct spi_device *spi)
+{
-+ struct tsc2102_dev *dev = dev_get_drvdata(&spi->dev);
++ struct tsc210x_dev *dev = dev_get_drvdata(&spi->dev);
+ int err;
+
+ if (!dev)
@@ -960,39 +1165,49 @@
+ return err;
+}
+#else
-+#define tsc2102_suspend NULL
-+#define tsc2102_resume NULL
++#define tsc210x_suspend NULL
++#define tsc210x_resume NULL
+#endif
+
-+static struct platform_device tsc2102_ts_device = {
-+ .name = "tsc2102-ts",
++/* REVISIT don't make these static */
++static struct platform_device tsc210x_ts_device = {
++ .name = "tsc210x-ts",
+ .id = -1,
+};
+
-+static struct platform_device tsc2102_alsa_device = {
-+ .name = "tsc2102-alsa",
++/* TODO
++static struct platform_device tsc210x_hwmon_device = {
++ .name = "tsc210x-hwmon",
++ .id = -1,
++};
++*/
++
++static struct platform_device tsc210x_alsa_device = {
++ .name = "tsc210x-alsa",
+ .id = -1,
+};
+
-+static int tsc2102_probe(struct spi_device *spi)
++static int tsc210x_probe(struct spi_device *spi)
+{
-+ struct tsc2102_config *pdata = spi->dev.platform_data;
++ struct tsc210x_config *pdata = spi->dev.platform_data;
+ struct spi_transfer *spi_buffer;
+ int err = -EINVAL;
++ u16 rev_id = 0;
+
+ if (!pdata) {
-+ printk(KERN_ERR "TSC2102: Platform data not supplied\n");
++ printk(KERN_ERR "TSC210x: Platform data not supplied\n");
+ return -ENOENT;
+ }
+
+ if (!spi->irq) {
-+ printk(KERN_ERR "TSC2102: Invalid irq value\n");
++ printk(KERN_ERR "TSC210x: Invalid irq value\n");
+ return -ENOENT;
+ }
+
+ tsc.pdata = pdata;
+ tsc.ts_msecs = 30;
+ tsc.mode_msecs = 500;
++ tsc.todo = 0;
+ tsc.spi = spi;
+ INIT_WORK(&tsc.work, tsc_work);
+
@@ -1011,7 +1226,7 @@
+ if (pdata->init)
+ pdata->init();
+
-+#ifdef IMX_CLOCK_CONFIG
++#ifdef CONFIG_TSC_SLAVE
+ tsc.bclk_ck = clk_get(0, "bclk"); TODO add clock mechanism to i.MX ???
+ if (!tsc.bclk_ck) {
+ printk(KERN_ERR "Unable to get the clock BCLK\n");
@@ -1020,7 +1235,13 @@
+ }
+
+ clk_enable(tsc.bclk_ck);
-+#endif //IMX_CLOCK_CONFIG
++#else
++ /* Retrieve Master Clock from platform data */
++ if (pdata->mclk)
++ tsc.mclk = pdata->mclk;
++ else
++ tsc.mclk = 16000000; /* 16 MHz by default */
++#endif /* CONFIG_TSC_SLAVE */
+
+ if (request_irq(spi->irq, tsc2102_handler, IRQF_DISABLED | IRQF_SHARED | IRQF_TRIGGER_FALLING, "tsc2102", &tsc)) {
+ printk(KERN_ERR "Could not allocate touchscreen IRQ (n %d)\n", spi->irq);
@@ -1043,8 +1264,15 @@
+ goto err_timer;
+
+ /* Now try to detect the chip, make first contact */
-+ if (tsc2102_get_revision() != 0x1) {
-+ printk(KERN_ERR "No TI TSC2102 chip found! Bad revision: %x\n", tsc2102_get_revision());
++ rev_id = tsc2102_get_revision();
++ if (rev_id == 0x01) {
++ printk("TSC2102 detected\n");
++ tsc.kind = tsc2102;
++ } else if (rev_id == 0x04) {
++ printk("TSC2101 detected\n");
++ tsc.kind = tsc2101;
++ } else {
++ printk(KERN_ERR "No TI TSC210x chip found! Bad revision: %x\n", rev_id);
+ goto err_timer;
+ }
+
@@ -1052,16 +1280,16 @@
+ if (err)
+ goto err_timer;
+
-+ /* Register devices controlled by TSC 2102 */
-+ tsc2102_ts_device.dev.platform_data = pdata;
-+ tsc2102_ts_device.dev.parent = &spi->dev;
-+ err = platform_device_register(&tsc2102_ts_device);
++ /* Register devices controlled by TSC2101 / TSC2102 */
++ tsc210x_ts_device.dev.platform_data = pdata;
++ tsc210x_ts_device.dev.parent = &spi->dev;
++ err = platform_device_register(&tsc210x_ts_device);
+ if (err)
+ goto err_timer;
+
-+ tsc2102_alsa_device.dev.platform_data = pdata->alsa_config;
-+ tsc2102_alsa_device.dev.parent = &spi->dev;
-+ err = platform_device_register(&tsc2102_alsa_device);
++ tsc210x_alsa_device.dev.platform_data = pdata->alsa_config;
++ tsc210x_alsa_device.dev.parent = &spi->dev;
++ err = platform_device_register(&tsc210x_alsa_device);
+ if (err)
+ goto err_ts;
+
@@ -1077,11 +1305,13 @@
+ err |= device_create_file(&spi->dev, &dev_attr_in0_input);
+ if (pdata->monitor & TSC_BAT2)
+ err |= device_create_file(&spi->dev, &dev_attr_in1_input);
-+ if (pdata->monitor & TSC_AUX)
++ if (pdata->monitor & TSC_AUX1)
+ err |= device_create_file(&spi->dev, &dev_attr_in2_input);
++ if (pdata->monitor & TSC_AUX2)
++ err |= device_create_file(&spi->dev, &dev_attr_in3_input);
+ if (pdata->monitor & TSC_TEMP) {
+ err |= device_create_file(&spi->dev, &dev_attr_temp1_input);
-+ err |= device_create_file(&spi->dev, &dev_attr_in3_input);
++ err |= device_create_file(&spi->dev, &dev_attr_in4_input);
+ }
+
+ if (err)
@@ -1099,9 +1329,9 @@
+ goto done;
+
+err_alsa:
-+ platform_device_unregister(&tsc2102_alsa_device);
++ platform_device_unregister(&tsc210x_alsa_device);
+err_ts:
-+ platform_device_unregister(&tsc2102_ts_device);
++ platform_device_unregister(&tsc210x_ts_device);
+err_timer:
+ del_timer(&tsc.ts_timer);
+ del_timer(&tsc.mode_timer);
@@ -1116,13 +1346,13 @@
+ return err;
+}
+
-+static int tsc2102_remove(struct spi_device *spi)
++static int tsc210x_remove(struct spi_device *spi)
+{
-+ struct tsc2102_dev *dev = dev_get_drvdata(&spi->dev);
++ struct tsc210x_dev *dev = dev_get_drvdata(&spi->dev);
+ mutex_lock(&dev->lock_sync);
+
-+ platform_device_unregister(&tsc2102_ts_device);
-+ platform_device_unregister(&tsc2102_alsa_device);
++ platform_device_unregister(&tsc210x_ts_device);
++ platform_device_unregister(&tsc210x_alsa_device);
+
+ dev_set_drvdata(&spi->dev, NULL);
+
@@ -1130,9 +1360,11 @@
+ if (dev->pdata->exit)
+ dev->pdata->exit();
+
++#ifdef CONFIG_TSC_SLAVE
+ /* Release the BCLK */
-+/* clk_disable(dev->bclk_ck); TODO add clock mechanism to i.MX ???
-+ clk_put(dev->bclk_ck); */
++ clk_disable(dev->bclk_ck);
++ clk_put(dev->bclk_ck);
++#endif
+
+ del_timer(&tsc.mode_timer);
+ del_timer(&tsc.ts_timer);
@@ -1151,39 +1383,43 @@
+ return 0;
+}
+
-+static struct spi_driver tsc2102_driver = {
-+ .probe = tsc2102_probe,
-+ .remove = tsc2102_remove,
-+ .suspend = tsc2102_suspend,
-+ .resume = tsc2102_resume,
++static struct spi_driver tsc210x_driver = {
++ .probe = tsc210x_probe,
++ .remove = tsc210x_remove,
++ .suspend = tsc210x_suspend,
++ .resume = tsc210x_resume,
+ .driver = {
-+ .name = "tsc2102",
++ .name = "tsc210x",
+ .owner = THIS_MODULE,
+ .bus = &spi_bus_type,
+ },
+};
+
-+static char __initdata banner[] = KERN_INFO "TI TSC2102 driver initializing\n";
++static char __initdata banner[] = KERN_INFO "TI TSC210x driver initializing\n";
+
-+static int __init tsc2102_init(void)
++static int __init tsc210x_init(void)
+{
++ int err;
+ printk(banner);
-+ return spi_register_driver(&tsc2102_driver);
++
++ err = spi_register_driver(&tsc210x_driver);
++
++ return err;
+}
+
-+static void __exit tsc2102_exit(void)
++static void __exit tsc210x_exit(void)
+{
-+ spi_unregister_driver(&tsc2102_driver);
++ spi_unregist...
[truncated message content] |