[Armadeus-commitlog] SF.net SVN: armadeus: [649] trunk/buildroot/target/device/armadeus/linux/ ker
Brought to you by:
sszy
|
From: <th...@us...> - 2007-09-27 20:07:38
|
Revision: 649
http://armadeus.svn.sourceforge.net/armadeus/?rev=649&view=rev
Author: thom25
Date: 2007-09-27 13:07:35 -0700 (Thu, 27 Sep 2007)
Log Message:
-----------
new armadeus TS driver
Modified Paths:
--------------
trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.18.1/073-linux-2.6.18-tsc2102.diff
Modified: trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.18.1/073-linux-2.6.18-tsc2102.diff
===================================================================
--- trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.18.1/073-linux-2.6.18-tsc2102.diff 2007-09-27 18:32:23 UTC (rev 648)
+++ trunk/buildroot/target/device/armadeus/linux/kernel-patches/2.6.18.1/073-linux-2.6.18-tsc2102.diff 2007-09-27 20:07:35 UTC (rev 649)
@@ -1,26 +1,192 @@
-From: Andrzej Zaborowski <ba...@za...>
-Date: Mon, 2 Apr 2007 17:15:00 +0000 (-0400)
-Subject: SPI: Add TSC2102 main SPI driver
-X-Git-Url: http://source.mvista.com/git/gitweb.cgi?p=linux-davinci-2.6.git;a=commitdiff;h=05f24ed7f2264675cd4c01bba62374d14db37fe9
-
-SPI: Add TSC2102 main SPI driver
-
-This adds a driver for the TSC2102 chip by Texas Instruments. This
-driver is responsible for all communication with the chip and doesn't
-export anything for user-space, but for other drivers controlling
-devices connected to the chip.
-
-Signed-off-by: Andrzej Zaborowski <ba...@za...>
----
-
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -131,6 +131,12 @@
+diff -pNur ref/linux-2.6.18.1/include/linux/spi/tsc2102.h linux-2.6.18.1/include/linux/spi/tsc2102.h
+--- ref/linux-2.6.18.1/include/linux/spi/tsc2102.h 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18.1/include/linux/spi/tsc2102.h 2007-09-22 01:42:29.000000000 +0200
+@@ -0,0 +1,175 @@
++/*
++ * include/linux/spi/tsc2102.h
++ *
++ * TI TSC2102 Touchscreen, Audio and Battery control register definitions
++ *
++ * Copyright (c) 2005 Andrzej Zaborowski <ba...@za...>
++ *
++ * This package 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 package 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 package; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++#ifndef __LINUX_SPI_TSC2102_H
++#define __LINUX_SPI_TSC2102_H
++
++struct apm_power_info;
++struct tsc2102_config {
++ int use_internal; /* Use internal reference voltage */
++ uint32_t monitor; /* What inputs are relevant */
++ int temp_at25c; /* Thermometer calibration data */
++ void (*apm_report)(struct apm_power_info *info, int *battery);
++ /* Report status to APM based on battery[] */
++ void *alsa_config; /* .platform_data for the ALSA device */
++};
++
++#define TSC_BAT1 (1 << 0)
++#define TSC_BAT2 (1 << 1)
++#define TSC_AUX (1 << 2)
++#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,
++ int numregs);
++extern void tsc2102_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);
++extern int tsc2102_temp2_cb(tsc2102_temp_t handler);
++
++#ifdef CONFIG_SOUND
++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);
++#endif
++
++extern void tsc2102_keyclick(int amplitude, int freq, int length);
++
++#define TSC2102_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)
++
++/* 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)
++
++/* 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)
++
++/* Field masks for Audio Control 1 */
++#define AC1_WLEN(ARG) (((ARG) & 0x03) << 10)
++#define AC1_DATFM(ARG) (((ARG) & 0x03) << 8)
++#define AC1_DACFS(ARG) ((ARG) & 0x3f)
++
++/* 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 formats for TSC2102_AUDIO2_CTRL */
++#define AC2_KCLEN (1 << 15)
++#define AC2_KCLAC(ARG) (((ARG) & 0x07) << 12)
++#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)
++
++/* Field masks for TSC2102_DAC_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)
++
++/* Field masks for TSC2101_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_DALOVF (1 << 7)
++#define AC3_DAROVF (1 << 6)
++#define AC3_REVID(ARG) (((ARG) & 0x07))
++
++/* Field masks for TSC2102_PLL1_CTRL */
++#define PLL1_PLLEN (1 << 15)
++#define PLL1_Q_VAL(ARG) (((ARG) & 0x0f) << 11)
++#define PLL1_P_VAL(ARG) (((ARG) & 0x07) << 8)
++#define PLL1_I_VAL(ARG) (((ARG) & 0x3f) << 2)
++
++/* Field masks for TSC2102_PLL2_CTRL */
++#define PLL2_D_VAL(ARG) (((ARG) & 0x3fff) << 2)
++
++/* Field masks for TSC2101_AUDIO_CTRL_4 */
++#define AC4_DASTPD (1 << 14)
++
++struct tsc2102_rate_info_s {
++ u16 sample_rate;
++ u8 divisor;
++ u8 fs_44k; /* 44.1 kHz Fsref if 1, 48 kHz if 0 */
++};
++
++#endif /* __LINUX_SPI_TSC2102_H */
+diff -pNur test/buildroot/build_arm_nofpu/linux-2.6.18.1/drivers/spi/Kconfig armadeus/buildroot/build_arm_nofpu/linux-2.6.18.1/drivers/spi/Kconfig
+--- ref/linux-2.6.18.1/drivers/spi/Kconfig 2007-09-22 02:39:35.000000000 +0200
++++ linux-2.6.18.1/drivers/spi/Kconfig 2007-09-16 11:08:17.000000000 +0200
+@@ -131,6 +131,13 @@ comment "SPI Protocol Masters"
#
# Add new SPI protocol masters in alphabetical order above this line
#
+config SPI_TSC2102
+ depends on SPI_MASTER
++ depends on HWMON = n || HWMON
+ tristate "TSC2102 codec support"
+ ---help---
+ Say Y here if you want support for the TSC2102 chip. It
@@ -28,9 +194,10 @@
# (slave support would go here)
---- a/drivers/spi/Makefile
-+++ a/drivers/spi/Makefile
-@@ -21,6 +21,7 @@
+diff -pNur ref/linux-2.6.18.1/drivers/spi/Makefile linux-2.6.18.1/drivers/spi/Makefile
+--- ref/linux-2.6.18.1/drivers/spi/Makefile 2007-09-22 02:39:35.000000000 +0200
++++ linux-2.6.18.1/drivers/spi/Makefile 2007-09-16 11:08:16.000000000 +0200
+@@ -21,6 +21,7 @@ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24x
# ... add above this line ...
# SPI protocol drivers (device/link on bus)
@@ -38,16 +205,19 @@
# ... add above this line ...
# SPI slave controller drivers (upstream link)
---- /dev/null
-+++ b/drivers/spi/tsc2102.c
-@@ -0,0 +1,1198 @@
+diff -pNur ref/linux-2.6.18.1/drivers/spi/tsc2102.c linux-2.6.18.1/drivers/spi/tsc2102.c
+--- ref/linux-2.6.18.1/drivers/spi/tsc2102.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18.1/drivers/spi/tsc2102.c 2007-09-22 01:42:55.000000000 +0200
+@@ -0,0 +1,1103 @@
+/*
+ * drivers/spi/tsc2102.c
+ *
+ * TSC2102 interface driver.
++ * Copyright (C) 2007 Armadeus systems (nc)
++ * -> fix dead locks, reorganize state machine
++ * -> fix scheduling while atomic and hwmon support
++ * Copyright (c) 2005 Andrzej Zaborowski <ba...@za...>
+ *
-+ * Copyright (c) 2005 Andrzej Zaborowski <ba...@za...>
-+ *
+ * This package 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
@@ -94,7 +264,10 @@
+#define TSC2102_ADC_T1_CONTROL 0x2bf4
+#define TSC2102_ADC_T2_CONTROL 0x33f4
+#define TSC2102_ADC_DAV 0x4000
-+#define TSC2102_ADC_INT_REF 0x0016
++#define TSC2102_ADC_PEN 0x0000
++#define TSC2102_ADC_INT_REF_125 0x0016
++#define TSC2102_ADC_INT_REF_250 0x0017
++#define TSC2102_ADC_REF TSC2102_ADC_INT_REF_250 /*2.5V*/
+#define TSC2102_ADC_EXT_REF 0x0002
+#define TSC2102_CONFIG_TIMES 0x0008
+#define TSC2102_RESET 0xbb00
@@ -129,14 +302,14 @@
+
+struct tsc2102_dev {
+ struct tsc2102_config *pdata;
-+ spinlock_t lock, lock_sync;
-+ struct clk *bclk_ck;
++ spinlock_t lock;
++ struct mutex lock_sync;
++// struct clk *bclk_ck; TODO add clock mechanism to i.MX ???
+
-+ int state; /* 0: TS, 1: Portscan, 2-3: Temps */
++ int state; /* Scan modes */
+ struct timer_list ts_timer; /* Busy-wait for PEN UP */
+ struct timer_list mode_timer; /* Change .state every some time */
-+ int pendown;
-+ int data_pending;
++ int touch_in_progress;
+ uint16_t status, adc_status, adc_data[4];
+ tsc2102_touch_t touch_cb;
+ tsc2102_coords_t coords_cb;
@@ -350,7 +523,9 @@
+}
+
+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)
+tsc2102_cb_register_func(temp2_cb, tsc2102_temp_t)
@@ -388,242 +563,153 @@
+}
+#endif
+
-+static void tsc2102_complete_dummy(struct tsc2102_dev *dev)
-+{
-+}
++static void tsc2102_complete_dummy(struct tsc2102_dev *dev){}
+
+static inline void tsc2102_touchscreen_mode(struct tsc2102_dev *dev)
+{
++ spin_lock_irq(&dev->lock);
++ dev->touch_in_progress = 1;
++
+ /* Scan X, Y, Z1, Z2, chip controlled, 12-bit, 16 samples, 500 usec */
+ tsc2102_write_async(&dev->req_mode,
+ TSC2102_TS_ADC_CTRL, TSC2102_ADC_TS_CONTROL,
+ tsc2102_complete_dummy);
++ spin_unlock_irq(&dev->lock);
+}
+
-+static inline void tsc2102_portscan_mode(struct tsc2102_dev *dev)
++static void tsc2102_end_current_conversion(struct tsc2102_dev *dev)
+{
++ spin_lock_irq(&dev->lock);
++ dev->touch_in_progress = 0;
++ dev->state++;
++ switch (dev->state) {
+ /* Scan BAT1, BAT2, AUX, 12-bit, 16 samples, 500 usec */
-+ tsc2102_write_async(&dev->req_mode,
-+ TSC2102_TS_ADC_CTRL, TSC2102_ADC_SCAN_CONTROL,
-+ tsc2102_complete_dummy);
-+}
-+
-+static inline void tsc2102_temp1_mode(struct tsc2102_dev *dev)
-+{
++ case 0: tsc2102_write_async(&dev->req_mode, TSC2102_TS_ADC_CTRL,
++ TSC2102_ADC_SCAN_CONTROL, tsc2102_complete_dummy);
++ break;
+ /* Scan TEMP1, 12-bit, 16 samples, 500 usec */
-+ tsc2102_write_async(&dev->req_mode,
-+ TSC2102_TS_ADC_CTRL, TSC2102_ADC_T1_CONTROL,
-+ tsc2102_complete_dummy);
-+}
-+
-+static inline void tsc2102_temp2_mode(struct tsc2102_dev *dev)
-+{
++ case 1: tsc2102_write_async(&dev->req_mode, TSC2102_TS_ADC_CTRL,
++ TSC2102_ADC_T1_CONTROL, tsc2102_complete_dummy);
++ break;
+ /* Scan TEMP2, 12-bit, 16 samples, 500 usec */
-+ tsc2102_write_async(&dev->req_mode,
-+ TSC2102_TS_ADC_CTRL, TSC2102_ADC_T2_CONTROL,
-+ tsc2102_complete_dummy);
-+}
-+
-+static void tsc2102_mode(struct tsc2102_dev *dev)
-+{
-+ switch (dev->state) {
-+ case 0:
-+ tsc2102_touchscreen_mode(dev);
++ case 2: tsc2102_write_async(&dev->req_mode, TSC2102_TS_ADC_CTRL,
++ TSC2102_ADC_T2_CONTROL, tsc2102_complete_dummy);
+ break;
-+ case 1:
-+ tsc2102_portscan_mode(dev);
-+ break;
-+ case 2:
-+ tsc2102_temp1_mode(dev);
-+ break;
-+ case 3:
-+ tsc2102_temp2_mode(dev);
-+ break;
-+ default:
++ default:
++ tsc2102_write_async(&dev->req_mode, TSC2102_TS_ADC_CTRL,
++ TSC2102_ADC_SCAN_CONTROL, tsc2102_complete_dummy);
+ dev->state = 0;
-+ tsc2102_touchscreen_mode(dev);
+ break;
+ }
++ spin_unlock_irq(&dev->lock);
++ mod_timer(&dev->mode_timer, jiffies +
++ msecs_to_jiffies(dev->mode_msecs));
+}
+
-+/* Lock is held when this is called. */
-+static void tsc2102_new_mode(struct tsc2102_dev *dev)
++static void tsc2102_mode(unsigned long data)
+{
-+ /* Abort current conversion if any */
++ struct tsc2102_dev *dev = (struct tsc2102_dev *) data;
++ spin_lock_irq(&dev->lock);
++
+ tsc2102_write_async(&dev->req_stopadc,
+ TSC2102_TS_ADC_CTRL, TSC2102_ADC_ADST,
-+ tsc2102_complete_dummy);
++ tsc2102_end_current_conversion);
+
-+ dev->state ++;
-+ tsc2102_mode(dev);
++ spin_unlock_irq(&dev->lock);
+}
+
-+static void tsc2102_check_status(struct tsc2102_dev *dev);
++/* Read touch screen data */
++static void tsc2102_TS_data_report(struct tsc2102_dev *dev)
++{
++ if (dev->coords_cb)
++ dev->coords_cb(
++ dev->adc_data[0], dev->adc_data[1],
++ dev->adc_data[2], dev->adc_data[3]);
++}
+
-+/* TSC has new data for us availiable. */
-+static irqreturn_t tsc2102_handler(int irq, void *dev_id)
++static void tsc2102_pressure_report(struct tsc2102_dev *dev)
+{
-+ struct tsc2102_dev *dev = (struct tsc2102_dev *) dev_id;
+ spin_lock_irq(&dev->lock);
++ mod_timer(&dev->mode_timer, jiffies +
++ msecs_to_jiffies(dev->mode_msecs));
+
-+ if (!dev->data_pending)
-+ tsc2102_check_status(dev);
++ tsc2102_reads_async(&dev->req_adc, TSC2102_TS_X,
++ dev->adc_data, 4, tsc2102_TS_data_report);
+
-+ dev->data_pending ++;
-+
++ if ( dev->adc_status & TSC2102_ADC_PSTCM) {
++ mod_timer(&dev->ts_timer, jiffies +
++ msecs_to_jiffies(dev->ts_msecs));
++ }
+ spin_unlock_irq(&dev->lock);
-+ return IRQ_HANDLED;
+}
+
-+static void tsc2102_data_report(struct tsc2102_dev *dev)
++static void tsc2102_scan_data_report(struct tsc2102_dev *dev)
+{
-+ if (dev->status & TSC2102_TS_DAV) {
-+ if (dev->coords_cb)
-+ dev->coords_cb(
-+ dev->adc_data[0], dev->adc_data[1],
-+ dev->adc_data[2], dev->adc_data[3]);
-+ }
-+
-+ if (dev->status & TSC2102_PS_DAV) {
-+ if (dev->ports_cb)
-+ dev->ports_cb(dev->adc_data[0],
-+ dev->adc_data[1], dev->adc_data[2]);
-+ dev->bat[0] = dev->adc_data[0];
-+ dev->bat[1] = dev->adc_data[1];
-+ dev->aux[0] = dev->adc_data[2];
-+ }
-+
-+ if (dev->status & TSC2102_T1_DAV) {
-+ if (dev->temp1_cb)
-+ dev->temp1_cb(*dev->adc_data);
-+ dev->temp[0] = *dev->adc_data;
-+ }
-+
-+ if (dev->status & TSC2102_T2_DAV) {
-+ if (dev->temp2_cb)
-+ dev->temp2_cb(*dev->adc_data);
-+ dev->temp[1] = *dev->adc_data;
-+ }
-+
++ mod_timer(&dev->mode_timer, jiffies +
++ msecs_to_jiffies(dev->mode_msecs));
+ spin_lock_irq(&dev->lock);
++ switch (dev->state)
++ {
++ case 0: if (dev->ports_cb)
++ dev->ports_cb(dev->adc_data[0],
++ dev->adc_data[1], dev->adc_data[2]);
++ dev->bat[0] = dev->adc_data[0];
++ dev->bat[1] = dev->adc_data[1];
++ dev->aux[0] = dev->adc_data[2];
++ break;
++
++ case 1: if (dev->temp1_cb)
++ dev->temp1_cb(*dev->adc_data);
++ dev->temp[0] = *dev->adc_data;
++ break;
+
-+ dev->data_pending --;
-+
-+ /*
-+ * This may happen if the registers were successfully read and a
-+ * new conversion was started and completed by the TSC before the
-+ * completion for SPI read was called.
-+ */
-+ if (dev->data_pending)
-+ tsc2102_check_status(dev);
-+
-+ if (dev->status & (TSC2102_PS_DAV | TSC2102_T1_DAV | TSC2102_T2_DAV))
-+ tsc2102_new_mode(dev);
-+
++ case 2: if (dev->temp2_cb)
++ dev->temp2_cb(*dev->adc_data);
++ dev->temp[1] = *dev->adc_data;
++ break;
++ default: break;
++ }
++ tsc2102_touchscreen_mode(dev);
+ spin_unlock_irq(&dev->lock);
+}
+
-+static void tsc2102_status_report(struct tsc2102_dev *dev)
++/* TSC has new data for us available. */
++static irqreturn_t tsc2102_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
-+ /*
-+ * Read all converted data from corresponding registers
-+ * so that the ADC can move on to a new conversion.
-+ */
-+ if (dev->status & TSC2102_TS_DAV) {
-+ tsc2102_reads_async(&dev->req_adc, TSC2102_TS_X,
-+ dev->adc_data, 4, tsc2102_data_report);
-+ if (!dev->pendown) {
-+ dev->pendown = 1;
-+ if (dev->touch_cb)
-+ dev->touch_cb(1);
++ struct tsc2102_dev *dev = (struct tsc2102_dev *) dev_id;
+
-+ mod_timer(&dev->ts_timer, jiffies +
-+ msecs_to_jiffies(dev->ts_msecs));
-+ }
-+ }
++ mod_timer(&dev->mode_timer, jiffies +
++ msecs_to_jiffies(dev->mode_msecs));
+
-+ if (dev->status & TSC2102_PS_DAV) {
-+ tsc2102_reads_async(&dev->req_adc, TSC2102_TS_BAT1,
-+ dev->adc_data, 3, tsc2102_data_report);
++ spin_lock_irq(&dev->lock);
++ if( dev->touch_in_progress ){
++ tsc2102_read_async(&dev->req_pressure, TSC2102_TS_ADC_CTRL,
++ &dev->adc_status, tsc2102_pressure_report);
+ }
-+
-+ if (dev->status & TSC2102_T1_DAV) {
-+ tsc2102_read_async(&dev->req_adc, TSC2102_TS_TEMP1,
-+ dev->adc_data, tsc2102_data_report);
++ else{
++ switch(dev->state){
++ case 0: tsc2102_reads_async(&dev->req_adc, TSC2102_TS_BAT1,
++ dev->adc_data, 3, tsc2102_scan_data_report);
++ break;
++ case 1: tsc2102_read_async(&dev->req_adc, TSC2102_TS_TEMP1,
++ dev->adc_data, tsc2102_scan_data_report);
++ break;
++ case 2: tsc2102_read_async(&dev->req_adc, TSC2102_TS_TEMP2,
++ dev->adc_data, tsc2102_scan_data_report);
++ break;
++ default: break;
++ }
+ }
-+
-+ if (dev->status & TSC2102_T2_DAV) {
-+ tsc2102_read_async(&dev->req_adc, TSC2102_TS_TEMP2,
-+ dev->adc_data, tsc2102_data_report);
-+ }
-+
-+ if (!(dev->status & (TSC2102_TS_DAV | TSC2102_PS_DAV |
-+ TSC2102_T1_DAV | TSC2102_T2_DAV))) {
-+ spin_lock_irq(&dev->lock);
-+ dev->data_pending --;
-+ spin_unlock_irq(&dev->lock);
-+
-+ WARN_ON(!dev->state);
-+ }
-+}
-+
-+static void tsc2102_check_status(struct tsc2102_dev *dev)
-+{
-+ tsc2102_read_async(&dev->req_status, TSC2102_TS_STATUS_CTRL,
-+ &dev->status, tsc2102_status_report);
-+}
-+
-+static void tsc2102_mode_timer(unsigned long data)
-+{
-+ struct tsc2102_dev *dev = (struct tsc2102_dev *) data;
-+ spin_lock_irq(&dev->lock);
-+
-+ BUG_ON(dev->state);
-+
-+ tsc2102_new_mode(dev);
-+
-+ mod_timer(&dev->mode_timer, jiffies +
-+ msecs_to_jiffies(dev->mode_msecs));
+ spin_unlock_irq(&dev->lock);
++ return IRQ_HANDLED;
+}
+
-+/*
-+ * There are at least three ways to check for pen-up:
-+ * - the PINT/DAV pin state,
-+ * - reading PSTCM bit in ADC Control register (D15, offset 0x00),
-+ * - reading ADST bit in ADC Control register (D14, offset 0x00),
-+ * ADC idle would indicate no screen touch.
-+ * Unfortunately none of them seems to be 100% accurate and you will
-+ * find they are totally inconsistent, i.e. you get to see any arbitrary
-+ * combination of values in these three bits. So we will busy-wait
-+ * for a moment when all three indicate a pen-up, using a timer, before
-+ * we report a pen-up.
-+ */
-+static void tsc2102_pressure_report(struct tsc2102_dev *dev)
-+{
-+ if (!dev->pendown)
-+ return;
-+
-+ if (dev->state ||
-+ (dev->adc_status & TSC2102_ADC_PSTCM) ||
-+ !(dev->adc_status & TSC2102_ADC_ADST)) {
-+ mod_timer(&dev->ts_timer, jiffies +
-+ msecs_to_jiffies(dev->ts_msecs));
-+ } else {
-+ dev->pendown = 0;
-+ if (dev->touch_cb)
-+ dev->touch_cb(0);
-+ }
-+}
-+
+static void tsc2102_pressure(unsigned long data)
+{
+ struct tsc2102_dev *dev = (struct tsc2102_dev *) data;
-+
-+ BUG_ON(!dev->pendown);
-+
-+ tsc2102_read_async(&dev->req_pressure, TSC2102_TS_ADC_CTRL,
-+ &dev->adc_status, tsc2102_pressure_report);
++ if (dev->touch_cb){
++ dev->touch_cb(0);
++ }
+}
+
+#ifdef CONFIG_SOUND
@@ -639,22 +725,20 @@
+ if (right_ch == 0x00 || right_ch == 0x7f)
+ right_ch ^= 0x7f;
+
-+ spin_lock(&tsc.lock_sync);
-+
++ mutex_lock(&tsc.lock_sync);
+ val = tsc2102_read_sync(TSC2102_DAC_GAIN_CTRL);
+
+ val &= 0x8080; /* Preserve mute-bits */
+ val |= (left_ch << 8) | right_ch;
+
+ tsc2102_write_sync(TSC2102_DAC_GAIN_CTRL, val);
-+
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
+}
+
+void tsc2102_set_mute(int left_ch, int right_ch)
+{
+ u16 val;
-+ spin_lock(&tsc.lock_sync);
++ mutex_lock(&tsc.lock_sync);
+
+ val = tsc2102_read_sync(TSC2102_DAC_GAIN_CTRL);
+
@@ -663,17 +747,17 @@
+
+ tsc2102_write_sync(TSC2102_DAC_GAIN_CTRL, val);
+
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
+}
+
+void tsc2102_get_mute(int *left_ch, int *right_ch)
+{
+ u16 val;
-+ spin_lock(&tsc.lock_sync);
++ mutex_lock(&tsc.lock_sync);
+
+ val = tsc2102_read_sync(TSC2102_DAC_GAIN_CTRL);
+
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
+
+ *left_ch = !!(val & (1 << 15));
+ *right_ch = !!(val & (1 << 7));
@@ -682,7 +766,7 @@
+void tsc2102_set_deemphasis(int enable)
+{
+ u16 val;
-+ spin_lock(&tsc.lock_sync);
++ mutex_lock(&tsc.lock_sync);
+ val = tsc2102_read_sync(TSC2102_DAC_POWER_CTRL);
+
+ if (enable)
@@ -691,13 +775,13 @@
+ val |= TSC2102_DEEMPF;
+
+ tsc2102_write_sync(TSC2102_DAC_POWER_CTRL, val);
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
+}
+
+void tsc2102_set_bassboost(int enable)
+{
+ u16 val;
-+ spin_lock(&tsc.lock_sync);
++ mutex_lock(&tsc.lock_sync);
+ val = tsc2102_read_sync(TSC2102_DAC_POWER_CTRL);
+
+ if (enable)
@@ -706,7 +790,7 @@
+ val |= TSC2102_BASSBC;
+
+ tsc2102_write_sync(TSC2102_DAC_POWER_CTRL, val);
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
+}
+
+/* {rate, dsor, fsref} */
@@ -752,7 +836,7 @@
+ return -EINVAL;
+ }
+
-+ spin_lock(&tsc.lock_sync);
++ mutex_lock(&tsc.lock_sync);
+
+ tsc2102_write_sync(TSC2102_AUDIO1_CTRL, tsc2102_rates[i].divisor);
+
@@ -770,7 +854,7 @@
+ tsc2102_write_sync(TSC2102_PLL2_CTRL, TSC2102_PLL2_48K);
+ }
+
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
+ return 0;
+}
+
@@ -779,7 +863,7 @@
+ */
+void tsc2102_dac_power(int state)
+{
-+ spin_lock(&tsc.lock_sync);
++ mutex_lock(&tsc.lock_sync);
+
+ if (state) {
+ /* 16-bit words, DSP mode, sample at Fsref */
@@ -803,13 +887,13 @@
+ tsc2102_write_sync(TSC2102_PLL1_CTRL, TSC2102_PLL1_OFF);
+ }
+
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
+}
+
+void tsc2102_set_i2s_master(int state)
+{
+ uint16_t val;
-+ spin_lock(&tsc.lock_sync);
++ mutex_lock(&tsc.lock_sync);
+
+ val = tsc2102_read_sync(TSC2102_AUDIO3_CTRL);
+
@@ -818,7 +902,7 @@
+ else
+ tsc2102_write_sync(TSC2102_AUDIO3_CTRL, val & ~TSC2102_SLVMS);
+
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
+}
+#endif /* CONFIG_SOUND */
+
@@ -827,9 +911,9 @@
+ /* Reset the chip */
+ tsc2102_write_sync(TSC2102_TS_RESET_CTRL, TSC2102_RESET);
+
-+ /* Reference mode, 100 usec delay, 1.25 V reference */
++ /* Reference mode, 100 usec delay, 2.5V reference */
+ if (dev->pdata->use_internal)
-+ tsc2102_write_sync(TSC2102_TS_REF_CTRL, TSC2102_ADC_INT_REF);
++ tsc2102_write_sync(TSC2102_TS_REF_CTRL, TSC2102_ADC_REF);
+ else
+ tsc2102_write_sync(TSC2102_TS_REF_CTRL, TSC2102_ADC_EXT_REF);
+
@@ -839,7 +923,10 @@
+ /* PINT/DAV acts as DAV */
+ tsc2102_write_sync(TSC2102_TS_STATUS_CTRL, TSC2102_ADC_DAV);
+
-+ tsc2102_mode(dev);
++ /* Init mode state machine */
++ dev->state = 0;
++ dev->touch_in_progress = 0;
++ /* Start mode timer */
+ mod_timer(&dev->mode_timer, jiffies +
+ msecs_to_jiffies(dev->mode_msecs));
+ return 0;
@@ -867,7 +954,7 @@
+void tsc2102_keyclick(int amplitude, int freq, int length)
+{
+ u16 val;
-+ spin_lock(&tsc.lock_sync);
++ mutex_lock(&tsc.lock_sync);
+ val = tsc2102_read_sync(TSC2102_AUDIO2_CTRL);
+ val &= 0x800f;
+
@@ -900,17 +987,17 @@
+ val |= 0x8000;
+
+ tsc2102_write_sync(TSC2102_AUDIO2_CTRL, val);
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
+}
+
-+#ifdef CONFIG_HWMON
++#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
+#define TSC2102_INPUT(devname, field) \
+static ssize_t show_ ## devname(struct device *dev, \
+ struct device_attribute *devattr, char *buf) \
+{ \
+ struct tsc2102_dev *devhwmon = dev_get_drvdata(dev); \
+ int value = devhwmon->field; \
-+ return sprintf(buf, "%i\n", value); \
++ return sprintf(buf, "%i\n", value); \
+} \
+static DEVICE_ATTR(devname ## _input, S_IRUGO, show_ ## devname, NULL);
+
@@ -924,29 +1011,19 @@
+ struct device_attribute *devattr, char *buf)
+{
+ struct tsc2102_dev *devhwmon = dev_get_drvdata(dev);
-+ int t1, t2;
-+ int value, diff;
++ int value;
+
-+ t1 = devhwmon->temp[0];
-+ t2 = devhwmon->temp[1];
-+
+ /*
+ * Use method #2 (differential) to calculate current temperature.
-+ * The difference between TEMP2 and TEMP1 input values is
-+ * multiplied by a constant to obtain current temperature.
-+ * To find this constant we use the values measured at 25 C as
-+ * thermometer calibration data.
-+ *
-+ * 298150 is 25 degrees Celcius represented in Kelvins and
-+ * multiplied by 1000 for fixed point precision (273.15 + 25).
-+ * 273150 is zero degrees Celcius.
++ * The approximation curve is: y = ax + b
++ * where b = 185 and a = 0.61 (taken from TSC datasheet page 15)
++ * the result (x) is in degree Celcius
++ * As it is the silicium temperature, a compensation factor can specified to
++ * estimate the ambient temperature.
+ */
-+ diff = devhwmon->pdata->temp_at25c[1] - devhwmon->pdata->temp_at25c[0];
-+ BUG_ON(diff == 0);
-+ value = (t2 - t1) * 298150 / diff; /* This is in Kelvins now */
++ value = (devhwmon->temp[1] - devhwmon->temp[0] - 185)*1639 ; /* Celcius millidegree */
+
-+ t1 = value - 273150; /* Celcius millidegree */
-+ return sprintf(buf, "%i\n", t1);
++ return sprintf(buf, "%i\n", value - devhwmon->pdata->temp_at25c);
+}
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL);
+#endif /* CONFIG_HWMON */
@@ -970,20 +1047,20 @@
+ if (!dev)
+ return 0;
+
-+ spin_lock(&dev->lock_sync);
++ mutex_lock(&dev->lock_sync);
+
+ del_timer(&dev->mode_timer);
+ del_timer(&dev->ts_timer);
+
-+ if (dev->pendown && dev->touch_cb)
++ if (dev->touch_cb)
+ dev->touch_cb(0);
+
+ /* Abort current conversion and power down the ADC */
+ tsc2102_write_sync(TSC2102_TS_ADC_CTRL, TSC2102_ADC_ADST);
+
+ dev->spi->dev.power.power_state = state;
++ mutex_unlock(&dev->lock_sync);
+
-+ spin_unlock(&dev->lock_sync);
+ return 0;
+}
+
@@ -998,16 +1075,13 @@
+ if (!dev)
+ return 0;
+
-+ spin_lock(&dev->lock_sync);
++ mutex_lock(&dev->lock_sync);
+
+ dev->spi->dev.power.power_state = PMSG_ON;
+
-+ dev->state = 0;
-+ dev->pendown = 0;
-+
+ err = tsc2102_configure(dev);
+
-+ spin_unlock(&dev->lock_sync);
++ mutex_unlock(&dev->lock_sync);
+ return err;
+}
+#else
@@ -1029,7 +1103,7 @@
+{
+ struct tsc2102_config *pdata = spi->dev.platform_data;
+ struct spi_transfer *spi_buffer;
-+ int err = 0;
++ int err = -EINVAL;
+
+ if (!pdata) {
+ printk(KERN_ERR "TSC2102: Platform data not supplied\n");
@@ -1042,11 +1116,8 @@
+ }
+
+ tsc.pdata = pdata;
-+ tsc.state = 0;
-+ tsc.pendown = 0;
-+ tsc.data_pending = 0;
-+ tsc.ts_msecs = 20;
-+ tsc.mode_msecs = 1000;
++ tsc.ts_msecs = 30;
++ tsc.mode_msecs = 500;
+ tsc.spi = spi;
+
+ /* Allocate enough struct spi_transfer's for all requests */
@@ -1064,21 +1135,23 @@
+ tsc2102_request_alloc(&tsc, &tsc.req_mode, 1, 1, &spi_buffer);
+
+ spin_lock_init(&tsc.lock);
-+ spin_lock(&tsc.lock_sync);
++ mutex_init(&tsc.lock_sync);
++ mutex_lock(&tsc.lock_sync);
+
+ /* Get the BCLK - assuming the rate is at 12000000 */
-+ tsc.bclk_ck = clk_get(0, "bclk");
++#ifdef IMX_CLOCK_CONFIG
++ 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");
+ err = -EPERM;
+ goto done;
+ }
-+
++
+ clk_enable(tsc.bclk_ck);
++#endif //IMX_CLOCK_CONFIG
+
-+ if (request_irq(spi->irq, tsc2102_handler, IRQF_SAMPLE_RANDOM |
-+ IRQF_TRIGGER_FALLING, "tsc2102", &tsc)) {
-+ printk(KERN_ERR "Could not allocate touchscreen IRQ!\n");
++ if (request_irq(spi->irq, tsc2102_handler, IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING, "tsc2102", &tsc)) {
++ printk(KERN_ERR "Could not allocate touchscreen IRQ (n %d)\n", spi->irq);
+ err = -EINVAL;
+ goto err_clk;
+ }
@@ -1086,7 +1159,7 @@
+ setup_timer(&tsc.ts_timer,
+ tsc2102_pressure, (unsigned long) &tsc);
+ setup_timer(&tsc.mode_timer,
-+ tsc2102_mode_timer, (unsigned long) &tsc);
++ tsc2102_mode, (unsigned long) &tsc);
+
+ /* Set up the communication bus */
+ dev_set_drvdata(&spi->dev, &tsc);
@@ -1099,7 +1172,7 @@
+
+ /* Now try to detect the chip, make first contact */
+ if (tsc2102_get_revision() != 0x1) {
-+ printk(KERN_ERR "No TI TSC2102 chip found!\n");
++ printk(KERN_ERR "No TI TSC2102 chip found! Bad revision: %x\n", tsc2102_get_revision());
+ goto err_timer;
+ }
+
@@ -1120,7 +1193,7 @@
+ if (err)
+ goto err_ts;
+
-+#ifdef CONFIG_HWMON
++#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
+ tsc.hwmondev = hwmon_device_register(&spi->dev);
+ if (IS_ERR(tsc.hwmondev)) {
+ printk(KERN_ERR "tsc2102_hwmon: Device registration failed\n");
@@ -1163,34 +1236,34 @@
+ del_timer(&tsc.mode_timer);
+ dev_set_drvdata(&spi->dev, NULL);
+err_clk:
-+ clk_disable(tsc.bclk_ck);
-+ clk_put(tsc.bclk_ck);
++/* clk_disable(tsc.bclk_ck); TODO add clock mechanism to i.MX ???
++ clk_put(tsc.bclk_ck);*/
+done:
-+ spin_unlock(&tsc.lock_sync);
++ mutex_unlock(&tsc.lock_sync);
++
+ return err;
+}
+
+static int tsc2102_remove(struct spi_device *spi)
+{
+ struct tsc2102_dev *dev = dev_get_drvdata(&spi->dev);
++ mutex_lock(&dev->lock_sync);
+
-+ spin_lock(&dev->lock_sync);
-+
+ platform_device_unregister(&tsc2102_ts_device);
+ platform_device_unregister(&tsc2102_alsa_device);
+
+ dev_set_drvdata(&spi->dev, NULL);
+
+ /* Release the BCLK */
-+ clk_disable(dev->bclk_ck);
-+ clk_put(dev->bclk_ck);
++/* clk_disable(dev->bclk_ck); TODO add clock mechanism to i.MX ???
++ clk_put(dev->bclk_ck); */
+
+ del_timer(&tsc.mode_timer);
+ del_timer(&tsc.ts_timer);
+
+ kfree(tsc.transfers);
+
-+#ifdef CONFIG_HWMON
++#if defined(CONFIG_HWMON) || defined(CONFIG_HWMON_MODULE)
+ hwmon_device_unregister(dev->hwmondev);
+#endif
+
@@ -1198,7 +1271,7 @@
+ apm_get_power_status = 0;
+#endif
+
-+ spin_unlock(&dev->lock_sync);
++ mutex_unlock(&dev->lock_sync);
+
+ return 0;
+}
@@ -1239,181 +1312,4 @@
+MODULE_AUTHOR("Andrzej Zaborowski");
+MODULE_DESCRIPTION("Interface driver for TI TSC2102 chips.");
+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/include/linux/spi/tsc2102.h
-@@ -0,0 +1,175 @@
-+/*
-+ * include/linux/spi/tsc2102.h
-+ *
-+ * TI TSC2102 Touchscreen, Audio and Battery control register definitions
-+ *
-+ * Copyright (c) 2005 Andrzej Zaborowski <ba...@za...>
-+ *
-+ * This package 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 package 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 package; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ */
-+
-+#ifndef __LINUX_SPI_TSC2102_H
-+#define __LINUX_SPI_TSC2102_H
-+
-+struct apm_power_info;
-+struct tsc2102_config {
-+ int use_internal; /* Use internal reference voltage */
-+ uint32_t monitor; /* What inputs are relevant */
-+ int temp_at25c[2]; /* Thermometer calibration data */
-+ void (*apm_report)(struct apm_power_info *info, int *battery);
-+ /* Report status to APM based on battery[] */
-+ void *alsa_config; /* .platform_data for the ALSA device */
-+};
-+
-+#define TSC_BAT1 (1 << 0)
-+#define TSC_BAT2 (1 << 1)
-+#define TSC_AUX (1 << 2)
-+#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,
-+ int numregs);
-+extern void tsc2102_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);
-+extern int tsc2102_temp2_cb(tsc2102_temp_t handler);
-+
-+#ifdef CONFIG_SOUND
-+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);
-+#endif
-+
-+extern void tsc2102_keyclick(int amplitude, int freq, int length);
-+
-+#define TSC2102_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)
-+
-+/* 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)
-+
-+/* 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)
-+
-+/* Field masks for Audio Control 1 */
-+#define AC1_WLEN(ARG) (((ARG) & 0x03) << 10)
-+#define AC1_DATFM(ARG) (((ARG) & 0x03) << 8)
-+#define AC1_DACFS(ARG) ((ARG) & 0x3f)
-+
-+/* 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 formats for TSC2102_AUDIO2_CTRL */
-+#define AC2_KCLEN (1 << 15)
-+#define AC2_KCLAC(ARG) (((ARG) & 0x07) << 12)
-+#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)
-+
-+/* Field masks for TSC2102_DAC_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)
-+
-+/* Field masks for TSC2101_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_DALOVF (1 << 7)
-+#define AC3_DAROVF (1 << 6)
-+#define AC3_REVID(ARG) (((ARG) & 0x07))
-+
-+/* Field masks for TSC2102_PLL1_CTRL */
-+#define PLL1_PLLEN (1 << 15)
-+#define PLL1_Q_VAL(ARG) (((ARG) & 0x0f) << 11)
-+#define PLL1_P_VAL(ARG) (((ARG) & 0x07) << 8)
-+#define PLL1_I_VAL(ARG) (((ARG) & 0x3f) << 2)
-+
-+/* Field masks for TSC2102_PLL2_CTRL */
-+#define PLL2_D_VAL(ARG) (((ARG) & 0x3fff) << 2)
-+
-+/* Field masks for TSC2101_AUDIO_CTRL_4 */
-+#define AC4_DASTPD (1 << 14)
-+
-+struct tsc2102_rate_info_s {
-+ u16 sample_rate;
-+ u8 divisor;
-+ u8 fs_44k; /* 44.1 kHz Fsref if 1, 48 kHz if 0 */
-+};
-+
-+#endif /* __LINUX_SPI_TSC2102_H */
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|