From 9cf2c9901df4c2647c9a80651ae2261078d83137 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 8 Dec 2008 16:12:36 -0800 Subject: [PATCH] REMOVE OMAP LEGACY CODE: Get rid of old tsc2101 and tsc2102 This code should use tsc210x. Patches welcome to re-enable H2 LCD. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-h2.c | 98 +-- drivers/spi/Kconfig | 15 - drivers/spi/Makefile | 2 - drivers/spi/tsc2101.c | 316 --------- drivers/spi/tsc2102.c | 1207 -------------------------------- drivers/video/omap/Makefile | 1 - drivers/video/omap/lcd_h2.c | 155 ---- include/linux/spi/tsc2101.h | 43 -- include/linux/spi/tsc2102.h | 175 ----- 9 files changed, 5 insertions(+), 2007 deletions(-) delete mode 100644 drivers/spi/tsc2101.c delete mode 100644 drivers/spi/tsc2102.c delete mode 100644 drivers/video/omap/lcd_h2.c delete mode 100644 include/linux/spi/tsc2101.h delete mode 100644 include/linux/spi/tsc2102.h diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 9b857f58fd8..97f26f9ee4d 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include @@ -296,97 +294,13 @@ static struct platform_device h2_lcd_device = { .id = -1, }; -struct { - struct clk *mclk; - int initialized; -} h2_tsc2101; - -#define TSC2101_MUX_MCLK_ON R10_1610_MCLK_ON -#define TSC2101_MUX_MCLK_OFF R10_1610_MCLK_OFF - -static void h2_lcd_dev_init(struct spi_device *tsc2101) -{ - /* The LCD is connected to the GPIO pins of the TSC2101, so - * we have to tie them here. We can also register the LCD driver - * first only here, where we know that the TSC driver is ready. - */ - - h2_lcd_device.dev.platform_data = tsc2101; - platform_device_register(&h2_lcd_device); -} - -static int h2_tsc2101_init(struct spi_device *spi) -{ - int r; - - if (h2_tsc2101.initialized) { - printk(KERN_ERR "tsc2101: already initialized\n"); - return -ENODEV; - } - - /* Get the MCLK */ - h2_tsc2101.mclk = clk_get(&spi->dev, "mclk"); - if (IS_ERR(h2_tsc2101.mclk)) { - dev_err(&spi->dev, "unable to get the clock MCLK\n"); - return PTR_ERR(h2_tsc2101.mclk); - } - if ((r = clk_set_rate(h2_tsc2101.mclk, 12000000)) < 0) { - dev_err(&spi->dev, "unable to set rate to the MCLK\n"); - goto err; - } - - omap_cfg_reg(TSC2101_MUX_MCLK_OFF); - omap_cfg_reg(N15_1610_UWIRE_CS1); - - h2_lcd_dev_init(spi); - - return 0; -err: - clk_put(h2_tsc2101.mclk); - return r; -} - -static void h2_tsc2101_cleanup(struct spi_device *spi) -{ - clk_put(h2_tsc2101.mclk); - omap_cfg_reg(TSC2101_MUX_MCLK_OFF); -} - -static void h2_tsc2101_enable_mclk(struct spi_device *spi) -{ - omap_cfg_reg(TSC2101_MUX_MCLK_ON); - clk_enable(h2_tsc2101.mclk); -} - -static void h2_tsc2101_disable_mclk(struct spi_device *spi) -{ - clk_disable(h2_tsc2101.mclk); - omap_cfg_reg(R10_1610_MCLK_OFF); -} - -static struct tsc2101_platform_data h2_tsc2101_platform_data = { - .init = h2_tsc2101_init, - .cleanup = h2_tsc2101_cleanup, - .enable_mclk = h2_tsc2101_enable_mclk, - .disable_mclk = h2_tsc2101_disable_mclk, -}; - -static struct spi_board_info h2_spi_board_info[] __initdata = { - [0] = { - .modalias = "tsc2101", - .bus_num = 2, - .chip_select = 1, - .max_speed_hz = 16000000, - .platform_data = &h2_tsc2101_platform_data, - }, -}; - static struct platform_device *h2_devices[] __initdata = { &h2_nor_device, &h2_nand_device, &h2_smc91x_device, &h2_irda_device, &h2_kp_device, + &h2_lcd_device, }; static void __init h2_init_smc91x(void) @@ -496,15 +410,13 @@ static void __init h2_init(void) /* Irda */ #if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE) omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A); - if (gpio_request(H2_IRDA_FIRSEL_GPIO_PIN, "IRDA mode") < 0) - BUG(); - gpio_direction_output(H2_IRDA_FIRSEL_GPIO_PIN, 0); - h2_irda_data.transceiver_mode = h2_transceiver_mode; + if (!(omap_request_gpio(H2_IRDA_FIRSEL_GPIO_PIN))) { + omap_set_gpio_direction(H2_IRDA_FIRSEL_GPIO_PIN, 0); + h2_irda_data.transceiver_mode = h2_transceiver_mode; + } #endif platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices)); - spi_register_board_info(h2_spi_board_info, - ARRAY_SIZE(h2_spi_board_info)); omap_board_config = h2_config; omap_board_config_size = ARRAY_SIZE(h2_config); omap_serial_init(); diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index c04029a8598..c891c1e1191 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -225,21 +225,6 @@ config SPI_AT25 This driver can also be built as a module. If so, the module will be called at25. -config SPI_TSC2101 - depends on SPI_MASTER - tristate "TSC2101 chip support" - ---help--- - Say Y here if you want support for the TSC2101 chip. - At the moment it provides basic register read / write interface - as well as a way to enable the MCLK clock. - -config SPI_TSC2102 - depends on SPI_MASTER - tristate "TSC2102 codec support" - ---help--- - Say Y here if you want support for the TSC2102 chip. It - will be needed for the touchscreen driver on some boards. - config SPI_TSC210X depends on SPI_MASTER && EXPERIMENTAL tristate "TI TSC210x (TSC2101/TSC2102) support" diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 7bfff235ffc..141c84eee6f 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -35,8 +35,6 @@ obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o obj-$(CONFIG_SPI_AT25) += at25.o obj-$(CONFIG_SPI_SPIDEV) += spidev.o obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o -obj-$(CONFIG_SPI_TSC2101) += tsc2101.o -obj-$(CONFIG_SPI_TSC2102) += tsc2102.o obj-$(CONFIG_SPI_TSC210X) += tsc210x.o obj-$(CONFIG_SPI_TSC2301) += tsc2301.o tsc2301-objs := tsc2301-core.o diff --git a/drivers/spi/tsc2101.c b/drivers/spi/tsc2101.c deleted file mode 100644 index 71702e2cb62..00000000000 --- a/drivers/spi/tsc2101.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * linux/drivers/spi/tsc2101.c - * - * TSC2101 codec interface driver for the OMAP platform - * - * Copyright (C) 2004 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * History: - * - * 2004/11/07 Nishanth Menon - Modified for common hooks for Audio and Touchscreen - */ - -#include -#include -#include -#include -#include - -struct tsc2101_device { - struct mutex mutex; - int mclk_enabled; - struct clock *mclk_ck; - struct spi_message message; - struct spi_transfer transfer[2]; - u16 command; - void (*enable_mclk)(struct spi_device *spi); - void (*disable_mclk)(struct spi_device *spi); -}; - -int tsc2101_enable_mclk(struct spi_device *spi) -{ - struct tsc2101_device *tsc2101; - - tsc2101 = spi_get_drvdata(spi); - - mutex_lock(&tsc2101->mutex); - - if (spi->dev.power.power_state.event != PM_EVENT_ON) { - mutex_unlock(&tsc2101->mutex); - return -ENODEV; - } - - if (tsc2101->mclk_enabled++ == 0) { - if (tsc2101->enable_mclk != NULL) - tsc2101->enable_mclk(spi); - } - - mutex_unlock(&tsc2101->mutex); - return 0; -} -EXPORT_SYMBOL(tsc2101_enable_mclk); - -void tsc2101_disable_mclk(struct spi_device *spi) -{ - struct tsc2101_device *tsc2101; - - tsc2101 = spi_get_drvdata(spi); - - mutex_lock(&tsc2101->mutex); - - if (--tsc2101->mclk_enabled == 0) { - if (tsc2101->disable_mclk != NULL && - spi->dev.power.power_state.event == PM_EVENT_ON) - tsc2101->disable_mclk(spi); - } - - mutex_lock(&tsc2101->mutex); -} -EXPORT_SYMBOL(tsc2101_disable_mclk); - -int tsc2101_write_sync(struct spi_device *spi, int page, u8 address, u16 data) -{ - struct tsc2101_device *tsc2101; - struct spi_message *m; - struct spi_transfer *t; - int ret; - - tsc2101 = spi_get_drvdata(spi); - - mutex_lock(&tsc2101->mutex); - if (spi->dev.power.power_state.event != PM_EVENT_ON) { - mutex_unlock(&tsc2101->mutex); - return -ENODEV; - } - - m = &tsc2101->message; - spi_message_init(m); - t = &tsc2101->transfer[0]; - memset(t, 0, sizeof(tsc2101->transfer)); - - /* Address */ - tsc2101->command = (page << 11) | (address << 5); - t->tx_buf = &tsc2101->command; - t->len = 2; - spi_message_add_tail(t, m); - - /* Data */ - t++; - t->tx_buf = &data; - t->len = 2; - spi_message_add_tail(t, m); - - ret = spi_sync(spi, m); - if (!ret) - ret = tsc2101->message.status; - mutex_unlock(&tsc2101->mutex); - - return ret; -} -EXPORT_SYMBOL(tsc2101_write_sync); - -int tsc2101_reads_sync(struct spi_device *spi, - int page, u8 startaddress, u16 *data, int numregs) -{ - struct tsc2101_device *tsc2101; - struct spi_message *m; - struct spi_transfer *t; - int ret; - - tsc2101 = spi_get_drvdata(spi); - - mutex_lock(&tsc2101->mutex); - if (spi->dev.power.power_state.event != PM_EVENT_ON) { - mutex_unlock(&tsc2101->mutex); - return -ENODEV; - } - - m = &tsc2101->message; - spi_message_init(m); - t = &tsc2101->transfer[0]; - memset(t, 0, sizeof(tsc2101->transfer)); - - /* Address */ - tsc2101->command = 0x8000 | (page << 11) | (startaddress << 5); - t->tx_buf = &tsc2101->command; - t->len = 2; - spi_message_add_tail(t, m); - - /* Data */ - t++; - t->rx_buf = data; - t->len = numregs << 1; - spi_message_add_tail(t, m); - - ret = spi_sync(spi, m); - if (!ret) - ret = tsc2101->message.status; - - mutex_unlock(&tsc2101->mutex); - - return ret; -} -EXPORT_SYMBOL(tsc2101_reads_sync); - -int tsc2101_read_sync(struct spi_device *spi, int page, u8 address) -{ - int err; - u16 val; - - err = tsc2101_reads_sync(spi, page, address, &val, 1); - if (err) - return err; - return val; -} -EXPORT_SYMBOL(tsc2101_read_sync); - -static int tsc2101_suspend(struct spi_device *spi, pm_message_t state) -{ - struct tsc2101_device *tsc2101; - - tsc2101 = spi_get_drvdata(spi); - - if (tsc2101 == NULL) - return 0; - - mutex_lock(&tsc2101->mutex); - - spi->dev.power.power_state = state; - if (tsc2101->mclk_enabled && tsc2101->disable_mclk != NULL) - tsc2101->disable_mclk(spi); - - mutex_unlock(&tsc2101->mutex); - - return 0; -} - -static int tsc2101_resume(struct spi_device *spi) -{ - struct tsc2101_device *tsc2101; - - tsc2101 = spi_get_drvdata(spi); - - if (tsc2101 == NULL) - return 0; - - mutex_lock(&tsc2101->mutex); - - spi->dev.power.power_state = PMSG_ON; - if (tsc2101->mclk_enabled && tsc2101->enable_mclk != NULL) - tsc2101->enable_mclk(spi); - - mutex_unlock(&tsc2101->mutex); - - return 0; -} - -static int tsc2101_probe(struct spi_device *spi) -{ - struct tsc2101_platform_data *pdata; - struct tsc2101_device *tsc2101; - u16 w; - int r; - - pdata = spi->dev.platform_data; - if (pdata == NULL) { - dev_err(&spi->dev, "no platform data\n"); - return -ENODEV; - } - - tsc2101 = kzalloc(sizeof(*tsc2101), GFP_KERNEL); - if (tsc2101 == NULL) { - dev_err(&spi->dev, "out of mem\n"); - return -ENOMEM; - } - - spi_set_drvdata(spi, tsc2101); - tsc2101->enable_mclk = pdata->enable_mclk; - tsc2101->disable_mclk = pdata->disable_mclk; - - mutex_init(&tsc2101->mutex); - - spi->mode = SPI_MODE_1; - spi->bits_per_word = 16; - if ((r = spi_setup(spi)) < 0) { - dev_err(&spi->dev, "SPI setup failed\n"); - goto err; - } - - w = tsc2101_read_sync(spi, 1, 0); - if (!(w & (1 << 14))) { - dev_err(&spi->dev, "invalid ADC register value %04x\n", w); - goto err; - } - - if (pdata->init != NULL) { - if ((r = pdata->init(spi)) < 0) { - dev_err(&spi->dev, "platform init failed\n"); - goto err; - } - } - - dev_info(&spi->dev, "initialized\n"); - - return 0; -err: - kfree(tsc2101); - return r; -} - -static int tsc2101_remove(struct spi_device *spi) -{ - struct tsc2101_platform_data *pdata; - struct tsc2101_device *tsc2101; - - pdata = spi->dev.platform_data; - tsc2101 = spi_get_drvdata(spi); - - /* We assume that this can't race with the rest of the driver. */ - if (tsc2101->mclk_enabled && tsc2101->disable_mclk != NULL) - tsc2101->disable_mclk(spi); - - if (pdata->cleanup != NULL) - pdata->cleanup(spi); - - spi_set_drvdata(spi, NULL); - kfree(tsc2101); - - return 0; -} - -static struct spi_driver tsc2101_driver = { - .probe = tsc2101_probe, - .remove = tsc2101_remove, - .suspend = tsc2101_suspend, - .resume = tsc2101_resume, - .driver = { - .name = "tsc2101", - .owner = THIS_MODULE, - }, -}; - -static int tsc2101_init(void) -{ - return spi_register_driver(&tsc2101_driver); -} - -static void tsc2101_exit(void) -{ - spi_unregister_driver(&tsc2101_driver); -} - -module_init(tsc2101_init); -module_exit(tsc2101_exit); - -MODULE_AUTHOR("Texas Instruments"); -MODULE_DESCRIPTION - ("Glue audio driver for the TI OMAP1610/OMAP1710 TSC2101 codec."); -MODULE_LICENSE("GPL"); diff --git a/drivers/spi/tsc2102.c b/drivers/spi/tsc2102.c deleted file mode 100644 index 59171cac73f..00000000000 --- a/drivers/spi/tsc2102.c +++ /dev/null @@ -1,1207 +0,0 @@ -/* - * drivers/spi/tsc2102.c - * - * TSC2102 interface driver. - * - * Copyright (c) 2005 Andrzej Zaborowski - * - * 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 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef CONFIG_APM -#include -#endif - -/* Bit field definitions for chip registers */ -#define TSC2102_ADC_TS_CONTROL 0x8bf4 -#define TSC2102_ADC_SCAN_CONTROL 0x2ff4 -#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_EXT_REF 0x0002 -#define TSC2102_CONFIG_TIMES 0x0008 -#define TSC2102_RESET 0xbb00 -#define TSC2102_ADC_PSTCM (1 << 15) -#define TSC2102_ADC_ADST (1 << 14) -#define TSC2102_TS_DAV 0x0780 -#define TSC2102_PS_DAV 0x0078 -#define TSC2102_T1_DAV 0x0004 -#define TSC2102_T2_DAV 0x0002 -#define TSC2102_DAC_ON 0x3ba0 -#define TSC2102_DAC_OFF 0xafa0 -#define TSC2102_FS44K (1 << 13) -#define TSC2102_PLL1_OFF 0x0000 -#define TSC2102_PLL1_44K 0x811c -#define TSC2102_PLL1_48K 0x8120 -#define TSC2102_PLL2_44K (5462 << 2) -#define TSC2102_PLL2_48K (1920 << 2) -#define TSC2102_SLVMS (1 << 11) -#define TSC2102_DEEMPF (1 << 0) -#define TSC2102_BASSBC (1 << 1) -#define TSC2102_KEYCLICK_OFF 0x0000 - -#define CS_CHANGE(val) 0 - -struct tsc2102_spi_req { - struct spi_device *dev; - uint16_t command; - uint16_t data; - struct spi_transfer *transfer; - struct spi_message message; -}; - -struct tsc2102_dev { - struct tsc2102_config *pdata; - spinlock_t lock, lock_sync; - struct clk *bclk_ck; - - int state; /* 0: TS, 1: Portscan, 2-3: Temps */ - 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; - 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; - tsc2102_temp_t temp2_cb; - unsigned int ts_msecs; /* Interval for .ts_timer */ - unsigned int mode_msecs; /* Interval for .mode_timer */ - - struct spi_device *spi; - struct spi_transfer *transfers; - struct tsc2102_spi_req req_adc; - struct tsc2102_spi_req req_status; - struct tsc2102_spi_req req_pressure; - struct tsc2102_spi_req req_stopadc; - struct tsc2102_spi_req req_mode; - - int bat[2], aux[1], temp[2]; - struct class_device *hwmondev; -}; - -static struct tsc2102_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"); - -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) -{ - static struct tsc2102_spi_req req; - static struct spi_transfer transfer[2]; - int ret; - - spi_message_init(&req.message); - req.transfer = transfer; - - /* Address */ - req.command = (page << 11) | (address << 5); - req.transfer[0].tx_buf = &req.command; - req.transfer[0].rx_buf = 0; - req.transfer[0].len = 2; - spi_message_add_tail(&req.transfer[0], &req.message); - - /* Data */ - req.transfer[1].tx_buf = &data; - req.transfer[1].rx_buf = 0; - req.transfer[1].len = 2; - req.transfer[1].cs_change = CS_CHANGE(1); - spi_message_add_tail(&req.transfer[1], &req.message); - - ret = spi_sync(tsc.spi, &req.message); - if (!ret && req.message.status) - ret = req.message.status; - - if (ret) - printk(KERN_ERR "%s: error %i in SPI request\n", - __FUNCTION__, ret); -} - -void tsc2102_reads_sync(int page, u8 startaddress, u16 *data, int numregs) -{ - static struct tsc2102_spi_req req; - static struct spi_transfer transfer[6]; - int ret, i, j; - - BUG_ON(numregs + 1 > ARRAY_SIZE(transfer)); - - spi_message_init(&req.message); - req.transfer = transfer; - i = 0; - j = 0; - - /* Address */ - req.command = 0x8000 | (page << 11) | (startaddress << 5); - req.transfer[i].tx_buf = &req.command; - req.transfer[i].rx_buf = 0; - req.transfer[i].len = 2; - spi_message_add_tail(&req.transfer[i ++], &req.message); - - /* Data */ - while (j < numregs) { - req.transfer[i].tx_buf = 0; - req.transfer[i].rx_buf = &data[j ++]; - req.transfer[i].len = 2; - req.transfer[i].cs_change = CS_CHANGE(j == numregs); - spi_message_add_tail(&req.transfer[i ++], &req.message); - } - - ret = spi_sync(tsc.spi, &req.message); - if (!ret && req.message.status) - ret = req.message.status; - - if (ret) - printk(KERN_ERR "%s: error %i in SPI request\n", - __FUNCTION__, ret); -} - -u16 tsc2102_read_sync(int page, u8 address) -{ - u16 ret; - tsc2102_reads_sync(page, address, &ret, 1); - return ret; -} - -static void tsc2102_write_async( - struct tsc2102_spi_req *spi, int page, u8 address, u16 data, - void (*complete)(struct tsc2102_dev *context)) -{ - int ret; - - spi_message_init(&spi->message); - spi->message.complete = (void (*)(void *)) complete; - spi->message.context = &tsc; - - /* Address */ - spi->command = (page << 11) | (address << 5); - spi->transfer[0].tx_buf = &spi->command; - spi->transfer[0].rx_buf = 0; - spi->transfer[0].len = 2; - spi_message_add_tail(&spi->transfer[0], &spi->message); - - /* Data */ - spi->data = data; - spi->transfer[1].tx_buf = &spi->data; - spi->transfer[1].rx_buf = 0; - spi->transfer[1].len = 2; - spi->transfer[1].cs_change = CS_CHANGE(1); - spi_message_add_tail(&spi->transfer[1], &spi->message); - - ret = spi_async(spi->dev, &spi->message); - if (ret) - printk(KERN_ERR "%s: error %i in SPI request\n", - __FUNCTION__, ret); -} - -static void tsc2102_reads_async(struct tsc2102_spi_req *spi, - int page, u8 startaddress, u16 *data, int numregs, - void (*complete)(struct tsc2102_dev *context)) -{ - int ret, i, j; - - spi_message_init(&spi->message); - spi->message.complete = (void (*)(void *)) complete; - spi->message.context = &tsc; - i = 0; - j = 0; - - /* Address */ - spi->command = 0x8000 | (page << 11) | (startaddress << 5); - spi->transfer[i].tx_buf = &spi->command; - spi->transfer[i].rx_buf = 0; - spi->transfer[i].len = 2; - spi_message_add_tail(&spi->transfer[i ++], &spi->message); - - /* Data */ - while (j < numregs) { - spi->transfer[i].tx_buf = 0; - spi->transfer[i].rx_buf = &data[j ++]; - spi->transfer[i].len = 2; - spi->transfer[i].cs_change = CS_CHANGE(j == numregs); - spi_message_add_tail(&spi->transfer[i ++], &spi->message); - } - - ret = spi_async(spi->dev, &spi->message); - if (ret) - printk(KERN_ERR "%s: error %i in SPI request\n", - __FUNCTION__, ret); -} - -static void tsc2102_read_async(struct tsc2102_spi_req *spi, - int page, u8 address, u16 *ret, - void (*complete)(struct tsc2102_dev *context)) -{ - tsc2102_reads_async(spi, page, address, ret, 1, complete); -} - -static void tsc2102_request_alloc(struct tsc2102_dev *dev, - struct tsc2102_spi_req *spi, int direction, int numregs, - struct spi_transfer **buffer) -{ - spi->dev = dev->spi; - - if (direction == 1) /* Write */ - numregs = 2; - else /* Read */ - numregs += 1; - - spi->transfer = *buffer; - *buffer += numregs; -} - -#define tsc2102_cb_register_func(cb, cb_t) \ -int tsc2102_ ## cb(cb_t handler) \ -{ \ - spin_lock(&tsc.lock); \ - \ - /* Lock the module */ \ - if (handler && !tsc.cb) \ - if (!try_module_get(THIS_MODULE)) { \ - printk(KERN_INFO "Failed to get TSC module\n"); \ - } \ - if (!handler && tsc.cb) \ - module_put(THIS_MODULE); \ - \ - tsc.cb = handler; \ - \ - spin_unlock(&tsc.lock); \ - return 0; \ -} - -tsc2102_cb_register_func(touch_cb, tsc2102_touch_t) -tsc2102_cb_register_func(coords_cb, tsc2102_coords_t) -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) - -#ifdef DEBUG -static void tsc2102_print_dav(void) -{ - u16 status = tsc2102_read_sync(TSC2102_TS_STATUS_CTRL); - if (status & 0x0fff) - printk("TSC2102: data in"); - if (status & 0x0400) - printk(" X"); - if (status & 0x0200) - printk(" Y"); - if (status & 0x0100) - printk(" Z1"); - if (status & 0x0080) - printk(" Z2"); - if (status & 0x0040) - printk(" BAT1"); - if (status & 0x0020) - printk(" BAT2"); - if (status & 0x0010) - printk(" AUX1"); - if (status & 0x0008) - printk(" AUX2"); - if (status & 0x0004) - printk(" TEMP1"); - if (status & 0x0002) - printk(" TEMP2"); - if (status & 0x0001) - printk(" KP"); - if (status & 0x0fff) - printk(".\n"); -} -#endif - -static void tsc2102_complete_dummy(struct tsc2102_dev *dev) -{ -} - -static inline void tsc2102_touchscreen_mode(struct tsc2102_dev *dev) -{ - /* 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); -} - -static inline void tsc2102_portscan_mode(struct tsc2102_dev *dev) -{ - /* 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) -{ - /* 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) -{ - /* 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); - break; - case 1: - tsc2102_portscan_mode(dev); - break; - case 2: - tsc2102_temp1_mode(dev); - break; - case 3: - tsc2102_temp2_mode(dev); - break; - default: - dev->state = 0; - tsc2102_touchscreen_mode(dev); - break; - } -} - -/* Lock is held when this is called. */ -static void tsc2102_new_mode(struct tsc2102_dev *dev) -{ - /* Abort current conversion if any */ - tsc2102_write_async(&dev->req_stopadc, - TSC2102_TS_ADC_CTRL, TSC2102_ADC_ADST, - tsc2102_complete_dummy); - - dev->state ++; - tsc2102_mode(dev); -} - -static void tsc2102_check_status(struct tsc2102_dev *dev); - -/* TSC has new data for us availiable. */ -static irqreturn_t tsc2102_handler(int irq, void *dev_id) -{ - struct tsc2102_dev *dev = (struct tsc2102_dev *) dev_id; - spin_lock_irq(&dev->lock); - - if (!dev->data_pending) - tsc2102_check_status(dev); - - dev->data_pending ++; - - spin_unlock_irq(&dev->lock); - return IRQ_HANDLED; -} - -static void tsc2102_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; - } - - spin_lock_irq(&dev->lock); - - 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); - - spin_unlock_irq(&dev->lock); -} - -static void tsc2102_status_report(struct tsc2102_dev *dev) -{ - /* - * 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); - - mod_timer(&dev->ts_timer, jiffies + - msecs_to_jiffies(dev->ts_msecs)); - } - } - - if (dev->status & TSC2102_PS_DAV) { - tsc2102_reads_async(&dev->req_adc, TSC2102_TS_BAT1, - dev->adc_data, 3, tsc2102_data_report); - } - - if (dev->status & TSC2102_T1_DAV) { - tsc2102_read_async(&dev->req_adc, TSC2102_TS_TEMP1, - dev->adc_data, tsc2102_data_report); - } - - 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); -} - -/* - * 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 defined(CONFIG_SND_OMAP_TSC2102) || defined(CONFIG_SND_OMAP_TSC2102_MODULE) - -/* - * 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) -{ - 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; - - spin_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); -} -EXPORT_SYMBOL_GPL(tsc2102_set_volume); - -void tsc2102_set_mute(int left_ch, int right_ch) -{ - u16 val; - spin_lock(&tsc.lock_sync); - - val = tsc2102_read_sync(TSC2102_DAC_GAIN_CTRL); - - val &= 0x7f7f; /* Preserve volume settings */ - val |= (left_ch << 15) | (right_ch << 7); - - tsc2102_write_sync(TSC2102_DAC_GAIN_CTRL, val); - - spin_unlock(&tsc.lock_sync); -} -EXPORT_SYMBOL_GPL(tsc2102_set_mute); - -void tsc2102_get_mute(int *left_ch, int *right_ch) -{ - u16 val; - spin_lock(&tsc.lock_sync); - - val = tsc2102_read_sync(TSC2102_DAC_GAIN_CTRL); - - spin_unlock(&tsc.lock_sync); - - *left_ch = !!(val & (1 << 15)); - *right_ch = !!(val & (1 << 7)); -} - -void tsc2102_set_deemphasis(int enable) -{ - u16 val; - spin_lock(&tsc.lock_sync); - val = tsc2102_read_sync(TSC2102_DAC_POWER_CTRL); - - if (enable) - val &= ~TSC2102_DEEMPF; - else - val |= TSC2102_DEEMPF; - - tsc2102_write_sync(TSC2102_DAC_POWER_CTRL, val); - spin_unlock(&tsc.lock_sync); -} -EXPORT_SYMBOL_GPL(tsc2102_set_deemphasis); - -void tsc2102_set_bassboost(int enable) -{ - u16 val; - spin_lock(&tsc.lock_sync); - val = tsc2102_read_sync(TSC2102_DAC_POWER_CTRL); - - if (enable) - val &= ~TSC2102_BASSBC; - else - val |= TSC2102_BASSBC; - - tsc2102_write_sync(TSC2102_DAC_POWER_CTRL, val); - spin_unlock(&tsc.lock_sync); -} -EXPORT_SYMBOL_GPL(tsc2102_set_bassboost); - -/* {rate, dsor, fsref} */ -static const struct tsc2102_rate_info_s tsc2102_rates[] = { - /* Fsref / 6.0 */ - {7350, 63, 1}, - {8000, 63, 0}, - /* Fsref / 6.0 */ - {7350, 54, 1}, - {8000, 54, 0}, - /* Fsref / 5.0 */ - {8820, 45, 1}, - {9600, 45, 0}, - /* Fsref / 4.0 */ - {11025, 36, 1}, - {12000, 36, 0}, - /* Fsref / 3.0 */ - {14700, 27, 1}, - {16000, 27, 0}, - /* Fsref / 2.0 */ - {22050, 18, 1}, - {24000, 18, 0}, - /* Fsref / 1.5 */ - {29400, 9, 1}, - {32000, 9, 0}, - /* Fsref */ - {44100, 0, 1}, - {48000, 0, 0}, - - {0, 0, 0}, -}; - -int tsc2102_set_rate(int rate) -{ - int i; - uint16_t val; - - for (i = 0; tsc2102_rates[i].sample_rate; i ++) - if (tsc2102_rates[i].sample_rate == rate) - break; - if (tsc2102_rates[i].sample_rate == 0) { - printk(KERN_ERR "Unknown sampling rate %i.0 Hz\n", rate); - return -EINVAL; - } - - spin_lock(&tsc.lock_sync); - - tsc2102_write_sync(TSC2102_AUDIO1_CTRL, tsc2102_rates[i].divisor); - - val = tsc2102_read_sync(TSC2102_AUDIO3_CTRL); - - 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); - } 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); - } - - spin_unlock(&tsc.lock_sync); - return 0; -} -EXPORT_SYMBOL(tsc2102_set_rate); - -/* - * Perform basic set-up with default values and power the DAC on. - */ -void tsc2102_dac_power(int state) -{ - spin_lock(&tsc.lock_sync); - - if (state) { - /* 16-bit words, DSP mode, sample at Fsref */ - tsc2102_write_sync(TSC2102_AUDIO1_CTRL, 0x0100); - /* Keyclicks off, soft-stepping at normal rate */ - tsc2102_write_sync(TSC2102_AUDIO2_CTRL, TSC2102_KEYCLICK_OFF); - /* 44.1 kHz Fsref, continuous transfer mode, master DAC */ - tsc2102_write_sync(TSC2102_AUDIO3_CTRL, 0x2800); - /* Soft-stepping enabled */ - tsc2102_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); - - /* Codec & DAC power up, virtual ground disabled */ - tsc2102_write_sync(TSC2102_DAC_POWER_CTRL, TSC2102_DAC_ON); - } else { - /* All off */ - tsc2102_write_sync(TSC2102_AUDIO4_CTRL, TSC2102_KEYCLICK_OFF); - tsc2102_write_sync(TSC2102_PLL1_CTRL, TSC2102_PLL1_OFF); - } - - spin_unlock(&tsc.lock_sync); -} -EXPORT_SYMBOL_GPL(tsc2102_dac_power); - -void tsc2102_set_i2s_master(int state) -{ - uint16_t val; - spin_lock(&tsc.lock_sync); - - val = tsc2102_read_sync(TSC2102_AUDIO3_CTRL); - - if (state) - tsc2102_write_sync(TSC2102_AUDIO3_CTRL, val | TSC2102_SLVMS); - else - tsc2102_write_sync(TSC2102_AUDIO3_CTRL, val & ~TSC2102_SLVMS); - - spin_unlock(&tsc.lock_sync); -} -EXPORT_SYMBOL_GPL(tsc2102_set_i2s_master); - -#endif /* CONFIG_SND_OMAP_TSC2101 */ - -static int tsc2102_configure(struct tsc2102_dev *dev) -{ - /* Reset the chip */ - tsc2102_write_sync(TSC2102_TS_RESET_CTRL, TSC2102_RESET); - - /* Reference mode, 100 usec delay, 1.25 V reference */ - if (dev->pdata->use_internal) - tsc2102_write_sync(TSC2102_TS_REF_CTRL, TSC2102_ADC_INT_REF); - else - tsc2102_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); - - /* PINT/DAV acts as DAV */ - tsc2102_write_sync(TSC2102_TS_STATUS_CTRL, TSC2102_ADC_DAV); - - tsc2102_mode(dev); - mod_timer(&dev->mode_timer, jiffies + - msecs_to_jiffies(dev->mode_msecs)); - return 0; -} - -/* - * Retrieves chip revision. Should be always 1. - */ -int tsc2102_get_revision(void) -{ - return tsc2102_read_sync(TSC2102_AUDIO3_CTRL) & 7; -} - -/* - * Emit a short keyclick typically in order to give feedback to - * user on specific events. - * - * amplitude must be between 0 (lowest) and 2 (highest). - * freq must be between 0 (corresponds to 62.5 Hz) and 7 (8 kHz). - * length should be between 2 and 32 periods. - * - * This function sleeps but doesn't sleep until the sound has - * finished. - */ -void tsc2102_keyclick(int amplitude, int freq, int length) -{ - u16 val; - spin_lock(&tsc.lock_sync); - val = tsc2102_read_sync(TSC2102_AUDIO2_CTRL); - val &= 0x800f; - - /* Set amplitude */ - switch (amplitude) { - case 1: - val |= 4 << 12; - break; - case 2: - val |= 7 << 12; - break; - default: - break; - } - - /* Frequency */ - val |= (freq & 0x7) << 8; - - /* Round to nearest supported length */ - if (length > 20) - val |= 4 << 4; - else if (length > 6) - val |= 3 << 4; - else if (length > 4) - val |= 2 << 4; - else if (length > 2) - val |= 1 << 4; - - /* Enable keyclick */ - val |= 0x8000; - - tsc2102_write_sync(TSC2102_AUDIO2_CTRL, val); - spin_unlock(&tsc.lock_sync); -} - -#ifdef CONFIG_HWMON -#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); \ -} \ -static DEVICE_ATTR(devname ## _input, S_IRUGO, show_ ## devname, NULL); - -TSC2102_INPUT(in0, bat[0]) -TSC2102_INPUT(in1, bat[1]) -TSC2102_INPUT(in2, aux[0]) -TSC2102_INPUT(in3, temp[0]) -TSC2102_INPUT(in4, temp[1]) - -static ssize_t show_temp1(struct device *dev, - struct device_attribute *devattr, char *buf) -{ - struct tsc2102_dev *devhwmon = dev_get_drvdata(dev); - int t1, t2; - int value, diff; - - 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. - */ - 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 */ - - t1 = value - 273150; /* Celcius millidegree */ - return sprintf(buf, "%i\n", t1); -} -static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL); -#endif /* CONFIG_HWMON */ - -#ifdef CONFIG_APM -static void tsc2102_get_power_status(struct apm_power_info *info) -{ - tsc.pdata->apm_report(info, tsc.bat); -} -#endif - -#ifdef CONFIG_PM -/* - * Suspend the chip. - */ -static int -tsc2102_suspend(struct spi_device *spi, pm_message_t state) -{ - struct tsc2102_dev *dev = dev_get_drvdata(&spi->dev); - - if (!dev) - return 0; - - spin_lock(&dev->lock_sync); - - del_timer(&dev->mode_timer); - del_timer(&dev->ts_timer); - - if (dev->pendown && 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; - - spin_unlock(&dev->lock_sync); - return 0; -} - -/* - * Resume chip operation. - */ -static int tsc2102_resume(struct spi_device *spi) -{ - struct tsc2102_dev *dev = dev_get_drvdata(&spi->dev); - int err; - - if (!dev) - return 0; - - spin_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); - return err; -} -#else -#define tsc2102_suspend NULL -#define tsc2102_resume NULL -#endif - -static struct platform_device tsc2102_ts_device = { - .name = "tsc2102-ts", - .id = -1, -}; - -static struct platform_device tsc2102_alsa_device = { - .name = "tsc2102-alsa", - .id = -1, -}; - -static int tsc2102_probe(struct spi_device *spi) -{ - struct tsc2102_config *pdata = spi->dev.platform_data; - struct spi_transfer *spi_buffer; - int err = 0; - - if (!pdata) { - printk(KERN_ERR "TSC2102: Platform data not supplied\n"); - return -ENOENT; - } - - if (!spi->irq) { - printk(KERN_ERR "TSC2102: Invalid irq value\n"); - return -ENOENT; - } - - tsc.pdata = pdata; - tsc.state = 0; - tsc.pendown = 0; - tsc.data_pending = 0; - tsc.ts_msecs = 20; - tsc.mode_msecs = 1000; - tsc.spi = spi; - - /* Allocate enough struct spi_transfer's for all requests */ - spi_buffer = kzalloc(sizeof(struct spi_transfer) * 16, GFP_KERNEL); - if (!spi_buffer) { - printk(KERN_ERR "TSC2102: No memory for SPI buffers\n"); - return -ENOMEM; - } - - tsc.transfers = spi_buffer; - tsc2102_request_alloc(&tsc, &tsc.req_adc, 0, 4, &spi_buffer); - tsc2102_request_alloc(&tsc, &tsc.req_status, 0, 1, &spi_buffer); - tsc2102_request_alloc(&tsc, &tsc.req_pressure, 0, 1, &spi_buffer); - tsc2102_request_alloc(&tsc, &tsc.req_stopadc, 1, 1, &spi_buffer); - tsc2102_request_alloc(&tsc, &tsc.req_mode, 1, 1, &spi_buffer); - - spin_lock_init(&tsc.lock); - spin_lock(&tsc.lock_sync); - - /* Get the BCLK - assuming the rate is at 12000000 */ - tsc.bclk_ck = clk_get(0, "bclk"); - if (!tsc.bclk_ck) { - printk(KERN_ERR "Unable to get the clock BCLK\n"); - err = -EPERM; - goto done; - } - - clk_enable(tsc.bclk_ck); - - if (request_irq(spi->irq, tsc2102_handler, IRQF_SAMPLE_RANDOM | - IRQF_TRIGGER_FALLING, "tsc2102", &tsc)) { - printk(KERN_ERR "Could not allocate touchscreen IRQ!\n"); - err = -EINVAL; - goto err_clk; - } - - setup_timer(&tsc.ts_timer, - tsc2102_pressure, (unsigned long) &tsc); - setup_timer(&tsc.mode_timer, - tsc2102_mode_timer, (unsigned long) &tsc); - - /* Set up the communication bus */ - dev_set_drvdata(&spi->dev, &tsc); - spi->dev.power.power_state = PMSG_ON; - spi->mode = SPI_MODE_1; - spi->bits_per_word = 16; - err = spi_setup(spi); - if (err) - 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!\n"); - goto err_timer; - } - - err = tsc2102_configure(&tsc); - 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); - 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); - if (err) - goto err_ts; - -#ifdef CONFIG_HWMON - tsc.hwmondev = hwmon_device_register(&spi->dev); - if (IS_ERR(tsc.hwmondev)) { - printk(KERN_ERR "tsc2102_hwmon: Device registration failed\n"); - err = PTR_ERR(tsc.hwmondev); - goto err_alsa; - } - - if (pdata->monitor & TSC_BAT1) - 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) - err |= device_create_file(&spi->dev, &dev_attr_in2_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) - printk(KERN_ERR "tsc2102_hwmon: Creating one or more " - "attribute files failed\n"); - err = 0; /* Not fatal */ -#endif - -#ifdef CONFIG_APM - if (pdata->apm_report) - apm_get_power_status = tsc2102_get_power_status; -#endif - - if (!err) - goto done; - -err_alsa: - platform_device_unregister(&tsc2102_alsa_device); -err_ts: - platform_device_unregister(&tsc2102_ts_device); -err_timer: - del_timer(&tsc.ts_timer); - del_timer(&tsc.mode_timer); - dev_set_drvdata(&spi->dev, NULL); -err_clk: - clk_disable(tsc.bclk_ck); - clk_put(tsc.bclk_ck); -done: - spin_unlock(&tsc.lock_sync); - return err; -} - -static int tsc2102_remove(struct spi_device *spi) -{ - struct tsc2102_dev *dev = dev_get_drvdata(&spi->dev); - - 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); - - del_timer(&tsc.mode_timer); - del_timer(&tsc.ts_timer); - - kfree(tsc.transfers); - -#ifdef CONFIG_HWMON - hwmon_device_unregister(dev->hwmondev); -#endif - -#ifdef CONFIG_APM - apm_get_power_status = 0; -#endif - - spin_unlock(&dev->lock_sync); - - return 0; -} - -static struct spi_driver tsc2102_driver = { - .probe = tsc2102_probe, - .remove = tsc2102_remove, - .suspend = tsc2102_suspend, - .resume = tsc2102_resume, - .driver = { - .name = "tsc2102", - .owner = THIS_MODULE, - .bus = &spi_bus_type, - }, -}; - -static char __initdata banner[] = KERN_INFO "TI TSC2102 driver initializing\n"; - -static int __init tsc2102_init(void) -{ - printk(banner); - return spi_register_driver(&tsc2102_driver); -} - -static void __exit tsc2102_exit(void) -{ - spi_unregister_driver(&tsc2102_driver); -} - -module_init(tsc2102_init); -module_exit(tsc2102_exit); - -EXPORT_SYMBOL(tsc2102_read_sync); -EXPORT_SYMBOL(tsc2102_reads_sync); -EXPORT_SYMBOL(tsc2102_write_sync); -EXPORT_SYMBOL(tsc2102_keyclick); - -MODULE_AUTHOR("Andrzej Zaborowski"); -MODULE_DESCRIPTION("Interface driver for TI TSC2102 chips."); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile index 25a47b006fa..b63b198d1f0 100644 --- a/drivers/video/omap/Makefile +++ b/drivers/video/omap/Makefile @@ -19,7 +19,6 @@ objs-y$(CONFIG_FB_OMAP_LCDC_BLIZZARD) += blizzard.o objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o objs-y$(CONFIG_MACH_OMAP_H4) += lcd_h4.o objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o -objs-y$(CONFIG_MACH_OMAP_H2) += lcd_h2.o objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o objs-y$(CONFIG_MACH_OMAP_PALMZ71) += lcd_palmz71.o diff --git a/drivers/video/omap/lcd_h2.c b/drivers/video/omap/lcd_h2.c deleted file mode 100644 index 96b4816f648..00000000000 --- a/drivers/video/omap/lcd_h2.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * LCD panel support for the TI OMAP H2 board - * - * Copyright (C) 2004 Nokia Corporation - * Author: Imre Deak - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#include -#include -#include - -#include -#include - -static struct { - struct platform_device *lcd_dev; - struct spi_device *tsc2101_dev; -} h2_panel_dev; - -static int h2_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) -{ - return 0; -} - -static void h2_panel_cleanup(struct lcd_panel *panel) -{ -} - -static int h2_panel_enable(struct lcd_panel *panel) -{ - int r; - - /* - * Assert LCD_EN, BKLIGHT_EN pins on LCD panel - * page2, GPIO config reg, GPIO(0,1) to out and asserted - */ - r = tsc2101_write_sync(h2_panel_dev.tsc2101_dev, 2, 0x23, 0xcc00); - if (r < 0) - dev_err(&h2_panel_dev.lcd_dev->dev, - "failed to enable LCD panel\n"); - - return r; -} - -static void h2_panel_disable(struct lcd_panel *panel) -{ - /* - * Deassert LCD_EN and BKLIGHT_EN pins on LCD panel - * page2, GPIO config reg, GPIO(0,1) to out and deasserted - */ - if (tsc2101_write_sync(h2_panel_dev.tsc2101_dev, 2, 0x23, 0x8800)) - dev_err(&h2_panel_dev.lcd_dev->dev, - "failed to disable LCD panel\n"); -} - -static unsigned long h2_panel_get_caps(struct lcd_panel *panel) -{ - return 0; -} - -struct lcd_panel h2_panel = { - .name = "h2", - .config = OMAP_LCDC_PANEL_TFT, - - .bpp = 16, - .data_lines = 16, - .x_res = 240, - .y_res = 320, - .pixel_clock = 5000, - .hsw = 12, - .hfp = 12, - .hbp = 46, - .vsw = 1, - .vfp = 1, - .vbp = 0, - - .init = h2_panel_init, - .cleanup = h2_panel_cleanup, - .enable = h2_panel_enable, - .disable = h2_panel_disable, - .get_caps = h2_panel_get_caps, -}; - -static int h2_panel_probe(struct platform_device *pdev) -{ - struct spi_device *tsc2101; - - tsc2101 = pdev->dev.platform_data; - if (tsc2101 == NULL) { - dev_err(&pdev->dev, "no platform data\n"); - return -ENODEV; - } - if (strncmp(tsc2101->modalias, "tsc2101", 8) != 0) { - dev_err(&pdev->dev, "tsc2101 not found\n"); - return -EINVAL; - } - h2_panel_dev.lcd_dev = pdev; - h2_panel_dev.tsc2101_dev = tsc2101; - omapfb_register_panel(&h2_panel); - return 0; -} - -static int h2_panel_remove(struct platform_device *pdev) -{ - return 0; -} - -static int h2_panel_suspend(struct platform_device *pdev, pm_message_t mesg) -{ - return 0; -} - -static int h2_panel_resume(struct platform_device *pdev) -{ - return 0; -} - -struct platform_driver h2_panel_driver = { - .probe = h2_panel_probe, - .remove = h2_panel_remove, - .suspend = h2_panel_suspend, - .resume = h2_panel_resume, - .driver = { - .name = "lcd_h2", - .owner = THIS_MODULE, - }, -}; - -static int h2_panel_drv_init(void) -{ - return platform_driver_register(&h2_panel_driver); -} - -static void h2_panel_drv_cleanup(void) -{ - platform_driver_unregister(&h2_panel_driver); -} - -module_init(h2_panel_drv_init); -module_exit(h2_panel_drv_cleanup); - diff --git a/include/linux/spi/tsc2101.h b/include/linux/spi/tsc2101.h deleted file mode 100644 index 01e6d231a3b..00000000000 --- a/include/linux/spi/tsc2101.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * include/linux/spi/tsc2101.h - * - * TSC2101 codec interface driver for the OMAP platform - * - * Copyright (C) 2004 Texas Instruments, Inc. - * - * This package is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * History: - * - * 2004/11/07 Nishanth Menon - Provided common hooks for Audio and Touchscreen - */ - -#ifndef __OMAP_TSC2101_H -#define __OMAP_TSC2101_H - -#include - -struct tsc2101_platform_data { - int (*init)(struct spi_device *spi); - void (*cleanup)(struct spi_device *spi); - void (*enable_mclk)(struct spi_device *spi); - void (*disable_mclk)(struct spi_device *spi); -}; - -extern int tsc2101_read_sync(struct spi_device *spi, int page, u8 address); -extern int tsc2101_reads_sync(struct spi_device *spi, int page, - u8 startaddress, u16 * data, int numregs); -extern int tsc2101_write_sync(struct spi_device *spi, int page, u8 address, - u16 data); - -extern int tsc2101_enable_mclk(struct spi_device *spi); -extern void tsc2101_disable_mclk(struct spi_device *spi); - -#endif - diff --git a/include/linux/spi/tsc2102.h b/include/linux/spi/tsc2102.h deleted file mode 100644 index be133008a6c..00000000000 --- a/include/linux/spi/tsc2102.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * include/linux/spi/tsc2102.h - * - * TI TSC2102 Touchscreen, Audio and Battery control register definitions - * - * Copyright (c) 2005 Andrzej Zaborowski - * - * 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); - -#if defined(CONFIG_SND_OMAP_TSC2102) || defined(CONFIG_SND_OMAP_TSC2102_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); -#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 */ -- 2.41.0