Commit aa6a0f45 authored by Andrzej Zaborowski's avatar Andrzej Zaborowski Committed by Tony Lindgren

TSC210x driver using the SPI framework.

This is a rework of the TSC2102 driver from linux-omap-2.6 taking TSC2101
into account with the goal of using only a single driver.
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
parent 1f77fbae
...@@ -684,6 +684,18 @@ config SENSORS_APPLESMC ...@@ -684,6 +684,18 @@ config SENSORS_APPLESMC
Say Y here if you have an applicable laptop and want to experience Say Y here if you have an applicable laptop and want to experience
the awesome power of applesmc. the awesome power of applesmc.
config SENSORS_TSC210X
tristate "TI TSC2101/2102 battery & temperature sensors"
depends on HWMON && SPI_MASTER
select SPI_TSC210X
help
Say Y if your board has a TSC210X chip and you want to
have its battery state, auxiliary input and/or temperature
sensors exported through hwmon.
This driver can also be built as a module. In this case
the module will be called tsc210x_sensors.
config HWMON_DEBUG_CHIP config HWMON_DEBUG_CHIP
bool "Hardware Monitoring Chip debugging messages" bool "Hardware Monitoring Chip debugging messages"
default n default n
......
...@@ -62,6 +62,7 @@ obj-$(CONFIG_SENSORS_VT1211) += vt1211.o ...@@ -62,6 +62,7 @@ obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
obj-$(CONFIG_SENSORS_VT8231) += vt8231.o obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o
obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
obj-$(CONFIG_SENSORS_TSC210X) += tsc210x_sensors.o
ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y)
EXTRA_CFLAGS += -DDEBUG EXTRA_CFLAGS += -DDEBUG
......
/*
* drivers/hwmon/tsc210x_sensors.c
*
* hwmon interface for TSC210X sensors
*
* Copyright (c) 2005-2007 Andrzej Zaborowski <balrog@zabor.org>
*
* 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 <linux/init.h>
#include <linux/err.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#include <linux/autoconf.h>
#ifdef CONFIG_APM
# include <linux/apm-emulation.h>
#endif
#include <linux/spi/tsc210x.h>
struct tsc210x_hwmon {
int bat[2], aux[2], temp[2];
struct class_device *dev;
struct tsc210x_config *pdata;
#ifdef CONFIG_APM
spinlock_t apm_lock;
#endif
};
#ifdef CONFIG_APM
# define apm_lock() spin_lock(&hwmon->apm_lock)
# define apm_unlock() spin_unlock(&hwmon->apm_lock)
#else
# define apm_lock()
# define apm_unlock()
#endif
static void tsc210x_ports(struct tsc210x_hwmon *hwmon, int bat[], int aux[])
{
apm_lock();
hwmon->bat[0] = bat[0];
hwmon->bat[1] = bat[1];
hwmon->aux[0] = aux[0];
hwmon->aux[1] = aux[1];
apm_unlock();
}
static void tsc210x_temp1(struct tsc210x_hwmon *hwmon, int temp)
{
apm_lock();
hwmon->temp[0] = temp;
apm_unlock();
}
static void tsc210x_temp2(struct tsc210x_hwmon *hwmon, int temp)
{
apm_lock();
hwmon->temp[1] = temp;
apm_unlock();
}
#define TSC210X_INPUT(devname, field) \
static ssize_t tsc_show_ ## devname(struct device *dev, \
struct device_attribute *devattr, char *buf) \
{ \
struct tsc210x_hwmon *hwmon = (struct tsc210x_hwmon *) \
platform_get_drvdata(to_platform_device(dev)); \
return sprintf(buf, "%i\n", hwmon->field); \
} \
static DEVICE_ATTR(devname ## _input, S_IRUGO, tsc_show_ ## devname, NULL);
TSC210X_INPUT(in0, bat[0])
TSC210X_INPUT(in1, bat[1])
TSC210X_INPUT(in2, aux[0])
TSC210X_INPUT(in3, aux[1])
TSC210X_INPUT(in4, temp[0])
TSC210X_INPUT(in5, temp[1])
static ssize_t tsc_show_temp1(struct device *dev,
struct device_attribute *devattr, char *buf)
{
struct tsc210x_hwmon *hwmon = (struct tsc210x_hwmon *)
platform_get_drvdata(to_platform_device(dev));
int t1, t2;
int diff, value;
t1 = hwmon->temp[0];
t2 = hwmon->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 = hwmon->pdata->temp_at25c[1] - hwmon->pdata->temp_at25c[0];
BUG_ON(diff == 0);
value = (t2 - t1) * 298150 / diff; /* This is in Kelvins now */
value -= 273150; /* Celcius millidegree */
return sprintf(buf, "%i\n", value);
}
static DEVICE_ATTR(temp1_input, S_IRUGO, tsc_show_temp1, NULL);
#ifdef CONFIG_APM
static struct tsc210x_hwmon *apm_hwmon;
static void tsc210x_get_power_status(struct apm_power_info *info)
{
struct tsc210x_hwmon *hwmon = apm_hwmon;
apm_lock();
hwmon->pdata->apm_report(info, hwmon->bat);
apm_unlock();
}
#endif
static int tsc210x_hwmon_probe(struct platform_device *pdev)
{
struct tsc210x_hwmon *hwmon;
struct tsc210x_config *pdata = pdev->dev.platform_data;
int status = 0;
hwmon = (struct tsc210x_hwmon *)
kzalloc(sizeof(struct tsc210x_hwmon), GFP_KERNEL);
if (!hwmon) {
printk(KERN_ERR "%s: allocation failed\n", __FUNCTION__);
return -ENOMEM;
}
hwmon->dev = hwmon_device_register(&pdev->dev);
if (IS_ERR(hwmon->dev)) {
kfree(hwmon);
printk(KERN_ERR "%s: Class registration failed\n",
__FUNCTION__);
return PTR_ERR(hwmon->dev);
}
hwmon->pdata = pdata;
#ifdef CONFIG_APM
spin_lock_init(&hwmon->apm_lock);
if (pdata->apm_report) {
apm_hwmon = hwmon;
apm_get_power_status = tsc210x_get_power_status;
}
#endif
platform_set_drvdata(pdev, hwmon);
if (pdata->monitor & (TSC_BAT1 | TSC_BAT2 | TSC_AUX1 | TSC_AUX2))
status |= tsc210x_ports_cb(pdev->dev.parent,
(tsc210x_ports_t) tsc210x_ports, hwmon);
if (pdata->monitor & TSC_TEMP) {
status |= tsc210x_temp1_cb(pdev->dev.parent,
(tsc210x_temp_t) tsc210x_temp1, hwmon);
status |= tsc210x_temp2_cb(pdev->dev.parent,
(tsc210x_temp_t) tsc210x_temp2, hwmon);
}
if (status) {
tsc210x_ports_cb(pdev->dev.parent, 0, 0);
tsc210x_temp1_cb(pdev->dev.parent, 0, 0);
tsc210x_temp2_cb(pdev->dev.parent, 0, 0);
platform_set_drvdata(pdev, 0);
#ifdef CONFIG_APM
if (pdata->apm_report)
apm_get_power_status = 0;
#endif
hwmon_device_unregister(hwmon->dev);
kfree(hwmon);
return status;
}
if (pdata->monitor & TSC_BAT1)
status |= device_create_file(&pdev->dev, &dev_attr_in0_input);
if (pdata->monitor & TSC_BAT2)
status |= device_create_file(&pdev->dev, &dev_attr_in1_input);
if (pdata->monitor & TSC_AUX1)
status |= device_create_file(&pdev->dev, &dev_attr_in2_input);
if (pdata->monitor & TSC_AUX2)
status |= device_create_file(&pdev->dev, &dev_attr_in3_input);
if (pdata->monitor & TSC_TEMP) {
status |= device_create_file(&pdev->dev, &dev_attr_in4_input);
status |= device_create_file(&pdev->dev, &dev_attr_in5_input);
status |= device_create_file(&pdev->dev, &dev_attr_temp1_input);
}
if (status) /* Not fatal */
printk(KERN_ERR "%s: Creating one or more "
"attribute files failed\n", __FUNCTION__);
return 0;
}
static int tsc210x_hwmon_remove(struct platform_device *pdev)
{
struct tsc210x_hwmon *dev = platform_get_drvdata(pdev);
tsc210x_ports_cb(pdev->dev.parent, 0, 0);
tsc210x_temp1_cb(pdev->dev.parent, 0, 0);
tsc210x_temp2_cb(pdev->dev.parent, 0, 0);
platform_set_drvdata(pdev, 0);
#ifdef CONFIG_APM
if (dev->pdata->apm_report)
apm_get_power_status = 0;
#endif
hwmon_device_unregister(dev->dev);
kfree(dev);
return 0;
}
static struct platform_driver tsc210x_hwmon_driver = {
.probe = tsc210x_hwmon_probe,
.remove = tsc210x_hwmon_remove,
/* Nothing to do on suspend/resume */
.driver = {
.name = "tsc210x-hwmon",
},
};
static int __init tsc210x_hwmon_init(void)
{
return platform_driver_register(&tsc210x_hwmon_driver);
}
static void __exit tsc210x_hwmon_exit(void)
{
platform_driver_unregister(&tsc210x_hwmon_driver);
}
module_init(tsc210x_hwmon_init);
module_exit(tsc210x_hwmon_exit);
MODULE_AUTHOR("Andrzej Zaborowski");
MODULE_DESCRIPTION("hwmon driver for TI TSC210x-connected sensors.");
MODULE_LICENSE("GPL");
...@@ -192,6 +192,20 @@ config TOUCHSCREEN_TSC2102 ...@@ -192,6 +192,20 @@ config TOUCHSCREEN_TSC2102
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called tsc2102_ts. module will be called tsc2102_ts.
config TOUCHSCREEN_TSC210X
tristate "TSC 2101/2102 based touchscreens"
depends on SPI_MASTER
select SPI_TSC210X
help
Say Y here if you have a touchscreen interface using a
TI TSC 210x controller, and your board-specific initialisation
code includes that in its table of SPI devices.
If unsure, say N (but it's safe to say "Y").
To compile this driver as a module, choose M here: the
module will be called tsc210x_ts.
config TOUCHSCREEN_TSC2301 config TOUCHSCREEN_TSC2301
tristate "TSC2301 touchscreen support" tristate "TSC2301 touchscreen support"
depends on SPI_TSC2301 depends on SPI_TSC2301
......
...@@ -20,4 +20,5 @@ obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o ...@@ -20,4 +20,5 @@ obj-$(CONFIG_TOUCHSCREEN_TOUCHWIN) += touchwin.o
obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o obj-$(CONFIG_TOUCHSCREEN_UCB1400) += ucb1400_ts.o
obj-$(CONFIG_TOUCHSCREEN_TSC2102) += tsc2102_ts.o obj-$(CONFIG_TOUCHSCREEN_TSC2102) += tsc2102_ts.o
obj-$(CONFIG_TOUCHSCREEN_OMAP) += omap/ obj-$(CONFIG_TOUCHSCREEN_OMAP) += omap/
obj-$(CONFIG_TOUCHSCREEN_TSC210X) += tsc210x_ts.o
obj-$(CONFIG_TOUCHSCREEN_TSC2301) += tsc2301_ts.o obj-$(CONFIG_TOUCHSCREEN_TSC2301) += tsc2301_ts.o
/*
* input/touchscreen/tsc210x_ts.c
*
* Touchscreen input device driver for the TSC 2101/2102 chips.
*
* Copyright (c) 2006-2007 Andrzej Zaborowski <balrog@zabor.org>
*
* 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 <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/spi/tsc210x.h>
static void tsc210x_touch(struct input_dev *dev, int touching)
{
if (!touching) {
input_report_abs(dev, ABS_X, 0);
input_report_abs(dev, ABS_Y, 0);
input_report_abs(dev, ABS_PRESSURE, 0);
input_sync(dev);
}
input_report_key(dev, BTN_TOUCH, touching);
}
static void tsc210x_coords(struct input_dev *dev, int x, int y, int z1, int z2)
{
int p;
/* Calculate the touch resistance a la equation #1 */
if (z1 != 0)
p = x * (z2 - z1) / (z1 << 4);
else
p = 1;
input_report_abs(dev, ABS_X, x);
input_report_abs(dev, ABS_Y, y);
input_report_abs(dev, ABS_PRESSURE, p);
input_sync(dev);
}
static int tsc210x_ts_probe(struct platform_device *pdev)
{
int status;
struct input_dev *dev;
dev = input_allocate_device();
if (!dev)
return -ENOMEM;
status = tsc210x_touch_cb(pdev->dev.parent,
(tsc210x_touch_t) tsc210x_touch, dev);
if (status) {
input_free_device(dev);
return status;
}
status = tsc210x_coords_cb(pdev->dev.parent,
(tsc210x_coords_t) tsc210x_coords, dev);
if (status) {
tsc210x_touch_cb(pdev->dev.parent, 0, 0);
input_free_device(dev);
return status;
}
dev->name = "TSC210x Touchscreen";
dev->cdev.dev = &pdev->dev;
dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
dev->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
dev->phys = "tsc210x/input0";
dev->id.bustype = BUS_HOST;
dev->id.vendor = 0x0001;
dev->id.product = 0x2100;
dev->id.version = 0x0001;
status = input_register_device(dev);
if (status) {
tsc210x_coords_cb(pdev->dev.parent, 0, 0);
tsc210x_touch_cb(pdev->dev.parent, 0, 0);
input_free_device(dev);
return status;
}
platform_set_drvdata(pdev, dev);
printk(KERN_INFO "TSC210x touchscreen initialised\n");
return 0;
}
static int tsc210x_ts_remove(struct platform_device *pdev)
{
struct input_dev *dev = (struct input_dev *)
platform_get_drvdata(pdev);
tsc210x_touch_cb(pdev->dev.parent, 0, 0);
tsc210x_coords_cb(pdev->dev.parent, 0, 0);
platform_set_drvdata(pdev, 0);
input_unregister_device(dev);
input_free_device(dev);
return 0;
}
static struct platform_driver tsc210x_ts_driver = {
.probe = tsc210x_ts_probe,
.remove = tsc210x_ts_remove,
/* Nothing to do on suspend/resume */
.driver = {
.name = "tsc210x-ts",
.owner = THIS_MODULE,
},
};
static int __init tsc210x_ts_init(void)
{
int ret;
ret = platform_driver_register(&tsc210x_ts_driver);
if (ret)
return -ENODEV;
return 0;
}
static void __exit tsc210x_ts_exit(void)
{
platform_driver_unregister(&tsc210x_ts_driver);
}
module_init(tsc210x_ts_init);
module_exit(tsc210x_ts_exit);
MODULE_AUTHOR("Andrzej Zaborowski");
MODULE_DESCRIPTION("Touchscreen input driver for TI TSC2101/2102.");
MODULE_LICENSE("GPL");
...@@ -227,6 +227,18 @@ config SPI_TSC2102 ...@@ -227,6 +227,18 @@ config SPI_TSC2102
Say Y here if you want support for the TSC2102 chip. It Say Y here if you want support for the TSC2102 chip. It
will be needed for the touchscreen driver on some boards. will be needed for the touchscreen driver on some boards.
config SPI_TSC210X
depends on SPI_MASTER && EXPERIMENTAL
tristate "TSC2101/TSC2102 chips support"
help
Say Y here if you want support for the TSC210x chips. It
will be needed for the touchscreen driver on some boards.
Note that the device has to be present in the board's SPI
devices table for this driver to load. This driver doesn't
automatically enable touchscreen, sensors or audio
functionality - enable these in their respective menus.
config SPI_TSC2301 config SPI_TSC2301
tristate "TSC2301 driver" tristate "TSC2301 driver"
depends on SPI_MASTER depends on SPI_MASTER
......
...@@ -35,6 +35,7 @@ obj-$(CONFIG_SPI_SPIDEV) += spidev.o ...@@ -35,6 +35,7 @@ obj-$(CONFIG_SPI_SPIDEV) += spidev.o
obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o obj-$(CONFIG_SPI_TLE62X0) += tle62x0.o
obj-$(CONFIG_SPI_TSC2101) += tsc2101.o obj-$(CONFIG_SPI_TSC2101) += tsc2101.o
obj-$(CONFIG_SPI_TSC2102) += tsc2102.o obj-$(CONFIG_SPI_TSC2102) += tsc2102.o
obj-$(CONFIG_SPI_TSC210X) += tsc210x.o
obj-$(CONFIG_SPI_TSC2301) += tsc2301.o obj-$(CONFIG_SPI_TSC2301) += tsc2301.o
tsc2301-objs := tsc2301-core.o tsc2301-objs := tsc2301-core.o
tsc2301-$(CONFIG_SPI_TSC2301_AUDIO) += tsc2301-mixer.o tsc2301-$(CONFIG_SPI_TSC2301_AUDIO) += tsc2301-mixer.o
......
This diff is collapsed.
/*
* include/linux/spi/tsc2102.h
*
* TI TSC2101/2102 control register definitions.
*
* Copyright (c) 2005-2007 Andrzej Zaborowski <balrog@zabor.org>
*
* 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_TSC210X_H
#define __LINUX_SPI_TSC210X_H
struct apm_power_info;
struct tsc210x_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 */
const char *mclk; /* Optional: bclk name */
const char *bclk; /* Optional: mclk name */
};
#define TSC_BAT1 (1 << 0)
#define TSC_BAT2 (1 << 1)
#define TSC_AUX1 (1 << 2)
#define TSC_AUX2 (1 << 3)
#define TSC_TEMP (1 << 4)
#define TSC_AUX TSC_AUX1
#define TSC_VBAT TSC_BAT1
struct tsc210x_dev;
extern u16 tsc210x_read_sync(struct tsc210x_dev *dev, int page, u8 address);
extern void tsc210x_reads_sync(struct tsc210x_dev *dev, int page,
u8 startaddress, u16 *data, int numregs);
extern void tsc210x_write_sync(struct tsc210x_dev *dev, int page,
u8 address, u16 data);
typedef void (*tsc210x_touch_t)(void *context, int touching);
typedef void (*tsc210x_coords_t)(void *context, int x, int y, int z1, int z2);
typedef void (*tsc210x_ports_t)(void *context, int bat[], int aux[]);
typedef void (*tsc210x_temp_t)(void *context, int temp);
extern int tsc210x_touch_cb(struct device *dev,
tsc210x_touch_t handler, void *context);
extern int tsc210x_coords_cb(struct device *dev,
tsc210x_coords_t handler, void *context);
extern int tsc210x_ports_cb(struct device *dev,
tsc210x_ports_t handler, void *context);
extern int tsc210x_temp1_cb(struct device *dev,
tsc210x_temp_t handler, void *context);
extern int tsc210x_temp2_cb(struct device *dev,
tsc210x_temp_t handler, void *context);
#ifdef CONFIG_SOUND
extern void tsc210x_set_dac_volume(struct device *dev,
uint8_t left_ch, uint8_t right_ch);
extern void tsc210x_set_dac_mute(struct device *dev,
int left_ch, int right_ch);
extern void tsc210x_get_dac_mute(struct device *dev,
int *left_ch, int *right_ch);
extern void tsc210x_dac_power(struct device *dev, int on);
extern int tsc210x_set_rate(struct device *dev, int rate);
extern void tsc210x_set_i2s_master(struct device *dev, int state);
extern void tsc210x_set_deemphasis(struct device *dev, int enable);
extern void tsc2102_set_bassboost(struct device *dev, int enable);
#endif
/*
* 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 for a period unrelated to the length of
* the sound, i.e. returning doesn't indicate that the sound has
* finished.
*/
extern void tsc210x_keyclick(struct tsc210x_dev *dev,
int amplitude, int freq, int length);
/* Page 0, Touch Screen & Keypad Data registers */
#define TSC210X_TS_X 0, 0x00
#define TSC210X_TS_Y 0, 0x01
#define TSC210X_TS_Z1 0, 0x02
#define TSC210X_TS_Z2 0, 0x03
#define TSC210X_TS_BAT1 0, 0x05
#define TSC2102_TS_BAT2 0, 0x06
#define TSC210X_TS_AUX1 0, 0x07
#define TSC2101_TS_AUX2 0, 0x08
#define TSC210X_TS_TEMP1 0, 0x09
#define TSC210X_TS_TEMP2 0, 0x0a
/* Page 1, Touch Screen & Keypad Control registers */
#define TSC210X_TS_ADC_CTRL 1, 0x00
#define TSC210X_TS_STATUS_CTRL 1, 0x01
#define TSC2101_TS_BUFFER_CTRL 1, 0x02
#define TSC210X_TS_REF_CTRL 1, 0x03
#define TSC210X_TS_RESET_CTRL 1, 0x04
#define TSC210X_TS_CONFIG_CTRL 1, 0x05
#define TSC2101_TS_TEMPMAX_CTRL 1, 0x06
#define TSC2101_TS_TEMPMIN_CTRL 1, 0x07
#define TSC2101_TS_AUX1MAX_CTRL 1, 0x08
#define TSC2101_TS_AUX1MIN_CTRL 1, 0x09
#define TSC2101_TS_AUX2MAX_CTRL 1, 0x0a
#define TSC2101_TS_AUX2MIN_CTRL 1, 0x0b
#define TSC2101_TS_MCONFIG_CTRL 1, 0x0c
#define TSC2101_TS_DELAY_CTRL 1, 0x0d
/* Page 2, Audio Control registers */
#define TSC210X_AUDIO1_CTRL 2, 0x00
#define TSC2101_HEADSET_GAIN_CTRL 2, 0x01
#define TSC210X_DAC_GAIN_CTRL 2, 0x02
#define TSC2101_MIXER_GAIN_CTRL 2, 0x03
#define TSC210X_AUDIO2_CTRL 2, 0x04
#define TSC210X_POWER_CTRL 2, 0x05
#define TSC210X_AUDIO3_CTRL 2, 0x06
#define TSC210X_LCH_BASS_BOOST_N0 2, 0x07
#define TSC210X_LCH_BASS_BOOST_N1 2, 0x08
#define TSC210X_LCH_BASS_BOOST_N2 2, 0x09
#define TSC210X_LCH_BASS_BOOST_N3 2, 0x0a
#define TSC210X_LCH_BASS_BOOST_N4 2, 0x0b
#define TSC210X_LCH_BASS_BOOST_N5 2, 0x0c
#define TSC210X_LCH_BASS_BOOST_D1 2, 0x0d
#define TSC210X_LCH_BASS_BOOST_D2 2, 0x0e
#define TSC210X_LCH_BASS_BOOST_D4 2, 0x0f
#define TSC210X_LCH_BASS_BOOST_D5 2, 0x10
#define TSC210X_RCH_BASS_BOOST_N0 2, 0x11
#define TSC210X_RCH_BASS_BOOST_N1 2, 0x12
#define TSC210X_RCH_BASS_BOOST_N2 2, 0x13
#define TSC210X_RCH_BASS_BOOST_N3 2, 0x14
#define TSC210X_RCH_BASS_BOOST_N4 2, 0x15
#define TSC210X_RCH_BASS_BOOST_N5 2, 0x16
#define TSC210X_RCH_BASS_BOOST_D1 2, 0x17
#define TSC210X_RCH_BASS_BOOST_D2 2, 0x18
#define TSC210X_RCH_BASS_BOOST_D4 2, 0x19
#define TSC210X_RCH_BASS_BOOST_D5 2, 0x1a
#define TSC210X_PLL1_CTRL 2, 0x1b
#define TSC210X_PLL2_CTRL 2, 0x1c
#define TSC210X_AUDIO4_CTRL 2, 0x1d
#define TSC2101_HANDSET_GAIN_CTRL 2, 0x1e
#define TSC2101_CELL_GAIN_CTRL 2, 0x1f
#define TSC2101_AUIDO5_CTRL 2, 0x20
#define TSC2101_AUDIO6_CTRL 2, 0x21
#define TSC2101_AUDIO7_CTRL 2, 0x22
#define TSC2101_GPIO_CTRL 2, 0x23
#define TSC2101_IN_AGC_CTRL 2, 0x24
#define TSC2101_POWER_STATUS 2, 0x25
#define TSC2101_MIX_AGC_CTRL 2, 0x26
#define TSC2101_CELL_AGC_CTRL 2, 0x27
/* 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 TSC210X_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 TSC210X_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 TSC210X_AUDIO3_CTRL */
#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 TSC210X_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 TSC210X_PLL2_CTRL */
#define PLL2_D_VAL(ARG) (((ARG) & 0x3fff) << 2)
/* Field masks for TSC210X_AUDIO4_CTRL */
#define AC4_DASTPD (1 << 14)
struct tsc210x_rate_info_s {
u16 sample_rate;
u8 divisor;
u8 fs_44k; /* 44.1 kHz Fsref if 1, 48 kHz if 0 */
};
#endif /* __LINUX_SPI_TSC210X_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment