2018-11-12 22:30:06 +03:00
// SPDX-License-Identifier: GPL-2.0
2010-12-16 10:39:25 +03:00
/*
* ST1232 Touchscreen Controller Driver
*
* Copyright ( C ) 2010 Renesas Solutions Corp .
* Tony SIM < chinyeow . sim . xt @ renesas . com >
*
* Using code from :
* - android . git . kernel . org : projects / kernel / common . git : synaptics_i2c_rmi . c
* Copyright ( C ) 2007 Google , Inc .
*/
# include <linux/delay.h>
2019-02-09 19:53:13 +03:00
# include <linux/gpio/consumer.h>
2010-12-16 10:39:25 +03:00
# include <linux/i2c.h>
# include <linux/input.h>
2019-10-22 20:31:16 +03:00
# include <linux/input/mt.h>
# include <linux/input/touchscreen.h>
2010-12-16 10:39:25 +03:00
# include <linux/interrupt.h>
# include <linux/module.h>
2013-10-06 11:56:40 +04:00
# include <linux/of.h>
2011-12-23 04:24:25 +04:00
# include <linux/pm_qos.h>
2010-12-16 10:39:25 +03:00
# include <linux/slab.h>
# include <linux/types.h>
# define ST1232_TS_NAME "st1232-ts"
2019-01-28 21:38:10 +03:00
# define ST1633_TS_NAME "st1633-ts"
2010-12-16 10:39:25 +03:00
2021-01-02 09:15:15 +03:00
# define REG_STATUS 0x01 /* Device Status | Error Code */
# define STATUS_NORMAL 0x00
# define STATUS_INIT 0x01
# define STATUS_ERROR 0x02
# define STATUS_AUTO_TUNING 0x03
# define STATUS_IDLE 0x04
# define STATUS_POWER_DOWN 0x05
# define ERROR_NONE 0x00
# define ERROR_INVALID_ADDRESS 0x10
# define ERROR_INVALID_VALUE 0x20
# define ERROR_INVALID_PLATFORM 0x30
2020-11-12 04:52:50 +03:00
# define REG_XY_RESOLUTION 0x04
# define REG_XY_COORDINATES 0x12
2019-10-22 20:31:16 +03:00
# define ST_TS_MAX_FINGERS 10
2010-12-16 10:39:25 +03:00
2019-01-28 21:38:10 +03:00
struct st_chip_info {
bool have_z ;
u16 max_area ;
u16 max_fingers ;
} ;
2010-12-16 10:39:25 +03:00
struct st1232_ts_data {
struct i2c_client * client ;
struct input_dev * input_dev ;
2019-02-11 11:30:26 +03:00
struct touchscreen_properties prop ;
2011-12-23 04:24:25 +04:00
struct dev_pm_qos_request low_latency_req ;
2019-02-09 19:53:13 +03:00
struct gpio_desc * reset_gpio ;
2019-01-28 21:38:10 +03:00
const struct st_chip_info * chip_info ;
int read_buf_len ;
u8 * read_buf ;
2010-12-16 10:39:25 +03:00
} ;
2021-01-02 09:13:13 +03:00
static int st1232_ts_read_data ( struct st1232_ts_data * ts , u8 reg ,
unsigned int n )
2010-12-16 10:39:25 +03:00
{
struct i2c_client * client = ts - > client ;
2019-10-21 20:11:23 +03:00
struct i2c_msg msg [ ] = {
{
. addr = client - > addr ,
2020-11-12 04:52:50 +03:00
. len = sizeof ( reg ) ,
. buf = & reg ,
2019-10-21 20:11:23 +03:00
} ,
{
. addr = client - > addr ,
2019-10-22 19:34:59 +03:00
. flags = I2C_M_RD | I2C_M_DMA_SAFE ,
2021-01-02 09:13:13 +03:00
. len = n ,
2019-10-21 20:11:23 +03:00
. buf = ts - > read_buf ,
}
} ;
int ret ;
2010-12-16 10:39:25 +03:00
2019-10-21 20:11:23 +03:00
ret = i2c_transfer ( client - > adapter , msg , ARRAY_SIZE ( msg ) ) ;
if ( ret ! = ARRAY_SIZE ( msg ) )
return ret < 0 ? ret : - EIO ;
2010-12-16 10:39:25 +03:00
2019-10-22 20:31:16 +03:00
return 0 ;
}
2021-01-02 09:15:15 +03:00
static int st1232_ts_wait_ready ( struct st1232_ts_data * ts )
{
unsigned int retries ;
int error ;
2021-10-06 21:06:03 +03:00
for ( retries = 100 ; retries ; retries - - ) {
2021-01-02 09:15:15 +03:00
error = st1232_ts_read_data ( ts , REG_STATUS , 1 ) ;
2021-02-23 20:30:09 +03:00
if ( ! error ) {
switch ( ts - > read_buf [ 0 ] ) {
case STATUS_NORMAL | ERROR_NONE :
case STATUS_IDLE | ERROR_NONE :
return 0 ;
}
}
2021-01-02 09:15:15 +03:00
usleep_range ( 1000 , 2000 ) ;
}
return - ENXIO ;
}
2020-11-12 04:52:50 +03:00
static int st1232_ts_read_resolution ( struct st1232_ts_data * ts , u16 * max_x ,
u16 * max_y )
{
u8 * buf ;
int error ;
/* select resolution register */
2021-01-02 09:13:13 +03:00
error = st1232_ts_read_data ( ts , REG_XY_RESOLUTION , 3 ) ;
2020-11-12 04:52:50 +03:00
if ( error )
return error ;
buf = ts - > read_buf ;
2021-01-02 09:12:27 +03:00
* max_x = ( ( ( buf [ 0 ] & 0x0070 ) < < 4 ) | buf [ 1 ] ) - 1 ;
* max_y = ( ( ( buf [ 0 ] & 0x0007 ) < < 8 ) | buf [ 2 ] ) - 1 ;
2020-11-12 04:52:50 +03:00
return 0 ;
}
2019-10-22 20:31:16 +03:00
static int st1232_ts_parse_and_report ( struct st1232_ts_data * ts )
{
struct input_dev * input = ts - > input_dev ;
struct input_mt_pos pos [ ST_TS_MAX_FINGERS ] ;
u8 z [ ST_TS_MAX_FINGERS ] ;
int slots [ ST_TS_MAX_FINGERS ] ;
int n_contacts = 0 ;
int i ;
2019-10-21 20:11:23 +03:00
for ( i = 0 ; i < ts - > chip_info - > max_fingers ; i + + ) {
2019-10-22 20:31:16 +03:00
u8 * buf = & ts - > read_buf [ i * 4 ] ;
if ( buf [ 0 ] & BIT ( 7 ) ) {
unsigned int x = ( ( buf [ 0 ] & 0x70 ) < < 4 ) | buf [ 1 ] ;
unsigned int y = ( ( buf [ 0 ] & 0x07 ) < < 8 ) | buf [ 2 ] ;
touchscreen_set_mt_pos ( & pos [ n_contacts ] ,
& ts - > prop , x , y ) ;
2010-12-16 10:39:25 +03:00
2019-01-28 21:38:10 +03:00
/* st1232 includes a z-axis / touch strength */
if ( ts - > chip_info - > have_z )
2019-10-22 20:31:16 +03:00
z [ n_contacts ] = ts - > read_buf [ i + 6 ] ;
n_contacts + + ;
2019-01-28 21:38:10 +03:00
}
2010-12-16 10:39:25 +03:00
}
2019-10-22 20:31:16 +03:00
input_mt_assign_slots ( input , slots , pos , n_contacts , 0 ) ;
for ( i = 0 ; i < n_contacts ; i + + ) {
input_mt_slot ( input , slots [ i ] ) ;
input_mt_report_slot_state ( input , MT_TOOL_FINGER , true ) ;
input_report_abs ( input , ABS_MT_POSITION_X , pos [ i ] . x ) ;
input_report_abs ( input , ABS_MT_POSITION_Y , pos [ i ] . y ) ;
if ( ts - > chip_info - > have_z )
input_report_abs ( input , ABS_MT_TOUCH_MAJOR , z [ i ] ) ;
}
input_mt_sync_frame ( input ) ;
input_sync ( input ) ;
return n_contacts ;
2010-12-16 10:39:25 +03:00
}
static irqreturn_t st1232_ts_irq_handler ( int irq , void * dev_id )
{
struct st1232_ts_data * ts = dev_id ;
2019-10-22 20:31:16 +03:00
int count ;
int error ;
2010-12-16 10:39:25 +03:00
2021-01-02 09:13:13 +03:00
error = st1232_ts_read_data ( ts , REG_XY_COORDINATES , ts - > read_buf_len ) ;
2019-10-22 20:31:16 +03:00
if ( error )
goto out ;
2019-01-28 21:38:10 +03:00
2019-10-22 20:31:16 +03:00
count = st1232_ts_parse_and_report ( ts ) ;
2011-12-23 04:24:25 +04:00
if ( ! count ) {
if ( ts - > low_latency_req . dev ) {
dev_pm_qos_remove_request ( & ts - > low_latency_req ) ;
ts - > low_latency_req . dev = NULL ;
}
} else if ( ! ts - > low_latency_req . dev ) {
/* First contact, request 100 us latency. */
dev_pm_qos_add_ancestor_request ( & ts - > client - > dev ,
2014-02-11 03:36:00 +04:00
& ts - > low_latency_req ,
DEV_PM_QOS_RESUME_LATENCY , 100 ) ;
2011-12-23 04:24:25 +04:00
}
2010-12-16 10:39:25 +03:00
2019-10-22 20:31:16 +03:00
out :
2010-12-16 10:39:25 +03:00
return IRQ_HANDLED ;
}
2013-04-15 20:31:00 +04:00
static void st1232_ts_power ( struct st1232_ts_data * ts , bool poweron )
{
2019-02-09 19:53:13 +03:00
if ( ts - > reset_gpio )
gpiod_set_value_cansleep ( ts - > reset_gpio , ! poweron ) ;
2013-04-15 20:31:00 +04:00
}
2019-10-21 21:02:33 +03:00
static void st1232_ts_power_off ( void * data )
{
st1232_ts_power ( data , false ) ;
}
2019-01-28 21:38:10 +03:00
static const struct st_chip_info st1232_chip_info = {
. have_z = true ,
. max_area = 0xff ,
. max_fingers = 2 ,
} ;
static const struct st_chip_info st1633_chip_info = {
. have_z = false ,
. max_area = 0x00 ,
. max_fingers = 5 ,
} ;
2022-11-19 01:39:53 +03:00
static int st1232_ts_probe ( struct i2c_client * client )
2010-12-16 10:39:25 +03:00
{
2022-11-19 01:39:53 +03:00
const struct i2c_device_id * id = i2c_client_get_device_id ( client ) ;
2019-01-28 21:38:10 +03:00
const struct st_chip_info * match ;
2010-12-16 10:39:25 +03:00
struct st1232_ts_data * ts ;
struct input_dev * input_dev ;
2020-11-12 04:52:50 +03:00
u16 max_x , max_y ;
2010-12-16 10:39:25 +03:00
int error ;
2019-01-28 21:38:10 +03:00
match = device_get_match_data ( & client - > dev ) ;
if ( ! match & & id )
match = ( const void * ) id - > driver_data ;
if ( ! match ) {
dev_err ( & client - > dev , " unknown device model \n " ) ;
return - ENODEV ;
}
2010-12-16 10:39:25 +03:00
if ( ! i2c_check_functionality ( client - > adapter , I2C_FUNC_I2C ) ) {
dev_err ( & client - > dev , " need I2C_FUNC_I2C \n " ) ;
return - EIO ;
}
if ( ! client - > irq ) {
dev_err ( & client - > dev , " no IRQ? \n " ) ;
return - EINVAL ;
}
2019-10-22 20:31:16 +03:00
ts = devm_kzalloc ( & client - > dev , sizeof ( * ts ) , GFP_KERNEL ) ;
2013-04-15 20:23:00 +04:00
if ( ! ts )
return - ENOMEM ;
2010-12-16 10:39:25 +03:00
2019-01-28 21:38:10 +03:00
ts - > chip_info = match ;
/* allocate a buffer according to the number of registers to read */
ts - > read_buf_len = ts - > chip_info - > max_fingers * 4 ;
ts - > read_buf = devm_kzalloc ( & client - > dev , ts - > read_buf_len , GFP_KERNEL ) ;
if ( ! ts - > read_buf )
return - ENOMEM ;
2013-04-15 20:23:00 +04:00
input_dev = devm_input_allocate_device ( & client - > dev ) ;
if ( ! input_dev )
return - ENOMEM ;
2010-12-16 10:39:25 +03:00
ts - > client = client ;
ts - > input_dev = input_dev ;
2019-02-09 19:53:13 +03:00
ts - > reset_gpio = devm_gpiod_get_optional ( & client - > dev , NULL ,
GPIOD_OUT_HIGH ) ;
if ( IS_ERR ( ts - > reset_gpio ) ) {
error = PTR_ERR ( ts - > reset_gpio ) ;
dev_err ( & client - > dev , " Unable to request GPIO pin: %d. \n " ,
error ) ;
return error ;
2013-04-15 20:31:00 +04:00
}
st1232_ts_power ( ts , true ) ;
2019-10-21 21:02:33 +03:00
error = devm_add_action_or_reset ( & client - > dev , st1232_ts_power_off , ts ) ;
if ( error ) {
dev_err ( & client - > dev ,
" Failed to install power off action: %d \n " , error ) ;
return error ;
}
2010-12-16 10:39:25 +03:00
input_dev - > name = " st1232-touchscreen " ;
input_dev - > id . bustype = BUS_I2C ;
2021-01-02 09:15:15 +03:00
/* Wait until device is ready */
error = st1232_ts_wait_ready ( ts ) ;
if ( error )
return error ;
2020-11-12 04:52:50 +03:00
/* Read resolution from the chip */
error = st1232_ts_read_resolution ( ts , & max_x , & max_y ) ;
if ( error ) {
dev_err ( & client - > dev ,
" Failed to read resolution: %d \n " , error ) ;
return error ;
}
2019-01-28 21:38:10 +03:00
if ( ts - > chip_info - > have_z )
input_set_abs_params ( input_dev , ABS_MT_TOUCH_MAJOR , 0 ,
ts - > chip_info - > max_area , 0 , 0 ) ;
input_set_abs_params ( input_dev , ABS_MT_POSITION_X ,
2020-11-12 04:52:50 +03:00
0 , max_x , 0 , 0 ) ;
2019-01-28 21:38:10 +03:00
input_set_abs_params ( input_dev , ABS_MT_POSITION_Y ,
2020-11-12 04:52:50 +03:00
0 , max_y , 0 , 0 ) ;
2010-12-16 10:39:25 +03:00
2019-02-11 11:30:26 +03:00
touchscreen_parse_properties ( input_dev , true , & ts - > prop ) ;
2019-10-22 20:31:16 +03:00
error = input_mt_init_slots ( input_dev , ts - > chip_info - > max_fingers ,
INPUT_MT_DIRECT | INPUT_MT_TRACK |
INPUT_MT_DROP_UNUSED ) ;
if ( error ) {
dev_err ( & client - > dev , " failed to initialize MT slots \n " ) ;
return error ;
}
2013-04-15 20:23:00 +04:00
error = devm_request_threaded_irq ( & client - > dev , client - > irq ,
NULL , st1232_ts_irq_handler ,
IRQF_ONESHOT ,
client - > name , ts ) ;
2010-12-16 10:39:25 +03:00
if ( error ) {
dev_err ( & client - > dev , " Failed to register interrupt \n " ) ;
2013-04-15 20:23:00 +04:00
return error ;
2010-12-16 10:39:25 +03:00
}
error = input_register_device ( ts - > input_dev ) ;
if ( error ) {
dev_err ( & client - > dev , " Unable to register %s input device \n " ,
input_dev - > name ) ;
2013-04-15 20:23:00 +04:00
return error ;
2010-12-16 10:39:25 +03:00
}
i2c_set_clientdata ( client , ts ) ;
return 0 ;
}
2023-01-02 21:18:33 +03:00
static int st1232_ts_suspend ( struct device * dev )
2010-12-16 10:39:25 +03:00
{
struct i2c_client * client = to_i2c_client ( dev ) ;
2013-04-15 20:31:00 +04:00
struct st1232_ts_data * ts = i2c_get_clientdata ( client ) ;
2010-12-16 10:39:25 +03:00
2019-10-21 21:00:21 +03:00
disable_irq ( client - > irq ) ;
if ( ! device_may_wakeup ( & client - > dev ) )
2013-04-15 20:31:00 +04:00
st1232_ts_power ( ts , false ) ;
2010-12-16 10:39:25 +03:00
return 0 ;
}
2023-01-02 21:18:33 +03:00
static int st1232_ts_resume ( struct device * dev )
2010-12-16 10:39:25 +03:00
{
struct i2c_client * client = to_i2c_client ( dev ) ;
2013-04-15 20:31:00 +04:00
struct st1232_ts_data * ts = i2c_get_clientdata ( client ) ;
2010-12-16 10:39:25 +03:00
2019-10-21 21:00:21 +03:00
if ( ! device_may_wakeup ( & client - > dev ) )
2013-04-15 20:31:00 +04:00
st1232_ts_power ( ts , true ) ;
2019-10-21 21:00:21 +03:00
enable_irq ( client - > irq ) ;
2010-12-16 10:39:25 +03:00
return 0 ;
}
2023-01-02 21:18:33 +03:00
static DEFINE_SIMPLE_DEV_PM_OPS ( st1232_ts_pm_ops ,
st1232_ts_suspend , st1232_ts_resume ) ;
2012-04-03 22:30:28 +04:00
2010-12-16 10:39:25 +03:00
static const struct i2c_device_id st1232_ts_id [ ] = {
2019-01-28 21:38:10 +03:00
{ ST1232_TS_NAME , ( unsigned long ) & st1232_chip_info } ,
{ ST1633_TS_NAME , ( unsigned long ) & st1633_chip_info } ,
2010-12-16 10:39:25 +03:00
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , st1232_ts_id ) ;
2012-11-24 09:31:00 +04:00
static const struct of_device_id st1232_ts_dt_ids [ ] = {
2019-01-28 21:38:10 +03:00
{ . compatible = " sitronix,st1232 " , . data = & st1232_chip_info } ,
{ . compatible = " sitronix,st1633 " , . data = & st1633_chip_info } ,
2012-04-03 22:30:28 +04:00
{ }
} ;
MODULE_DEVICE_TABLE ( of , st1232_ts_dt_ids ) ;
2010-12-16 10:39:25 +03:00
static struct i2c_driver st1232_ts_driver = {
2023-05-17 19:55:42 +03:00
. probe = st1232_ts_probe ,
2010-12-16 10:39:25 +03:00
. id_table = st1232_ts_id ,
. driver = {
. name = ST1232_TS_NAME ,
2017-10-31 19:47:28 +03:00
. of_match_table = st1232_ts_dt_ids ,
2021-10-12 04:31:40 +03:00
. probe_type = PROBE_PREFER_ASYNCHRONOUS ,
2023-01-02 21:18:33 +03:00
. pm = pm_sleep_ptr ( & st1232_ts_pm_ops ) ,
2010-12-16 10:39:25 +03:00
} ,
} ;
2012-03-17 10:05:41 +04:00
module_i2c_driver ( st1232_ts_driver ) ;
2010-12-16 10:39:25 +03:00
MODULE_AUTHOR ( " Tony SIM <chinyeow.sim.xt@renesas.com> " ) ;
2019-01-28 22:04:08 +03:00
MODULE_AUTHOR ( " Martin Kepplinger <martin.kepplinger@ginzinger.com> " ) ;
2010-12-16 10:39:25 +03:00
MODULE_DESCRIPTION ( " SITRONIX ST1232 Touchscreen Controller Driver " ) ;
2018-11-12 22:30:06 +03:00
MODULE_LICENSE ( " GPL v2 " ) ;