2018-11-12 11:30:06 -08:00
// SPDX-License-Identifier: GPL-2.0
2010-12-15 23:39:25 -08: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 08:53:13 -08:00
# include <linux/gpio/consumer.h>
2010-12-15 23:39:25 -08:00
# include <linux/i2c.h>
# include <linux/input.h>
2019-10-22 10:31:16 -07:00
# include <linux/input/mt.h>
# include <linux/input/touchscreen.h>
2010-12-15 23:39:25 -08:00
# include <linux/interrupt.h>
# include <linux/module.h>
2013-10-06 00:56:40 -07:00
# include <linux/of.h>
2011-12-23 01:24:25 +01:00
# include <linux/pm_qos.h>
2010-12-15 23:39:25 -08:00
# include <linux/slab.h>
# include <linux/types.h>
# define ST1232_TS_NAME "st1232-ts"
2019-01-28 10:38:10 -08:00
# define ST1633_TS_NAME "st1633-ts"
2010-12-15 23:39:25 -08:00
2019-10-22 10:31:16 -07:00
# define ST_TS_MAX_FINGERS 10
2010-12-15 23:39:25 -08:00
2019-01-28 10:38:10 -08:00
struct st_chip_info {
bool have_z ;
u16 max_x ;
u16 max_y ;
u16 max_area ;
u16 max_fingers ;
u8 start_reg ;
} ;
2010-12-15 23:39:25 -08:00
struct st1232_ts_data {
struct i2c_client * client ;
struct input_dev * input_dev ;
2019-02-11 00:30:26 -08:00
struct touchscreen_properties prop ;
2011-12-23 01:24:25 +01:00
struct dev_pm_qos_request low_latency_req ;
2019-02-09 08:53:13 -08:00
struct gpio_desc * reset_gpio ;
2019-01-28 10:38:10 -08:00
const struct st_chip_info * chip_info ;
int read_buf_len ;
u8 * read_buf ;
2010-12-15 23:39:25 -08:00
} ;
static int st1232_ts_read_data ( struct st1232_ts_data * ts )
{
struct i2c_client * client = ts - > client ;
2019-01-28 10:38:10 -08:00
u8 start_reg = ts - > chip_info - > start_reg ;
2019-10-21 10:11:23 -07:00
struct i2c_msg msg [ ] = {
{
. addr = client - > addr ,
. len = sizeof ( start_reg ) ,
. buf = & start_reg ,
} ,
{
. addr = client - > addr ,
2019-10-22 09:34:59 -07:00
. flags = I2C_M_RD | I2C_M_DMA_SAFE ,
2019-10-21 10:11:23 -07:00
. len = ts - > read_buf_len ,
. buf = ts - > read_buf ,
}
} ;
int ret ;
2010-12-15 23:39:25 -08:00
2019-10-21 10:11:23 -07:00
ret = i2c_transfer ( client - > adapter , msg , ARRAY_SIZE ( msg ) ) ;
if ( ret ! = ARRAY_SIZE ( msg ) )
return ret < 0 ? ret : - EIO ;
2010-12-15 23:39:25 -08:00
2019-10-22 10:31:16 -07:00
return 0 ;
}
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 10:11:23 -07:00
for ( i = 0 ; i < ts - > chip_info - > max_fingers ; i + + ) {
2019-10-22 10:31:16 -07: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-15 23:39:25 -08:00
2019-01-28 10:38:10 -08:00
/* st1232 includes a z-axis / touch strength */
if ( ts - > chip_info - > have_z )
2019-10-22 10:31:16 -07:00
z [ n_contacts ] = ts - > read_buf [ i + 6 ] ;
n_contacts + + ;
2019-01-28 10:38:10 -08:00
}
2010-12-15 23:39:25 -08:00
}
2019-10-22 10:31:16 -07: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-15 23:39:25 -08:00
}
static irqreturn_t st1232_ts_irq_handler ( int irq , void * dev_id )
{
struct st1232_ts_data * ts = dev_id ;
2019-10-22 10:31:16 -07:00
int count ;
int error ;
2010-12-15 23:39:25 -08:00
2019-10-22 10:31:16 -07:00
error = st1232_ts_read_data ( ts ) ;
if ( error )
goto out ;
2019-01-28 10:38:10 -08:00
2019-10-22 10:31:16 -07:00
count = st1232_ts_parse_and_report ( ts ) ;
2011-12-23 01:24:25 +01: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 00:36:00 +01:00
& ts - > low_latency_req ,
DEV_PM_QOS_RESUME_LATENCY , 100 ) ;
2011-12-23 01:24:25 +01:00
}
2010-12-15 23:39:25 -08:00
2019-10-22 10:31:16 -07:00
out :
2010-12-15 23:39:25 -08:00
return IRQ_HANDLED ;
}
2013-04-15 09:31:00 -07:00
static void st1232_ts_power ( struct st1232_ts_data * ts , bool poweron )
{
2019-02-09 08:53:13 -08:00
if ( ts - > reset_gpio )
gpiod_set_value_cansleep ( ts - > reset_gpio , ! poweron ) ;
2013-04-15 09:31:00 -07:00
}
2019-10-21 11:02:33 -07:00
static void st1232_ts_power_off ( void * data )
{
st1232_ts_power ( data , false ) ;
}
2019-01-28 10:38:10 -08:00
static const struct st_chip_info st1232_chip_info = {
. have_z = true ,
. max_x = 0x31f , /* 800 - 1 */
. max_y = 0x1df , /* 480 -1 */
. max_area = 0xff ,
. max_fingers = 2 ,
. start_reg = 0x12 ,
} ;
static const struct st_chip_info st1633_chip_info = {
. have_z = false ,
. max_x = 0x13f , /* 320 - 1 */
. max_y = 0x1df , /* 480 -1 */
. max_area = 0x00 ,
. max_fingers = 5 ,
. start_reg = 0x12 ,
} ;
2012-11-23 21:38:25 -08:00
static int st1232_ts_probe ( struct i2c_client * client ,
2017-10-31 09:47:28 -07:00
const struct i2c_device_id * id )
2010-12-15 23:39:25 -08:00
{
2019-01-28 10:38:10 -08:00
const struct st_chip_info * match ;
2010-12-15 23:39:25 -08:00
struct st1232_ts_data * ts ;
struct input_dev * input_dev ;
int error ;
2019-01-28 10:38:10 -08: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-15 23:39:25 -08: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 10:31:16 -07:00
ts = devm_kzalloc ( & client - > dev , sizeof ( * ts ) , GFP_KERNEL ) ;
2013-04-15 09:23:00 -07:00
if ( ! ts )
return - ENOMEM ;
2010-12-15 23:39:25 -08:00
2019-01-28 10:38:10 -08: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 09:23:00 -07:00
input_dev = devm_input_allocate_device ( & client - > dev ) ;
if ( ! input_dev )
return - ENOMEM ;
2010-12-15 23:39:25 -08:00
ts - > client = client ;
ts - > input_dev = input_dev ;
2019-02-09 08:53:13 -08: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 09:31:00 -07:00
}
st1232_ts_power ( ts , true ) ;
2019-10-21 11:02:33 -07: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-15 23:39:25 -08:00
input_dev - > name = " st1232-touchscreen " ;
input_dev - > id . bustype = BUS_I2C ;
2019-01-28 10:38:10 -08: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 ,
0 , ts - > chip_info - > max_x , 0 , 0 ) ;
input_set_abs_params ( input_dev , ABS_MT_POSITION_Y ,
0 , ts - > chip_info - > max_y , 0 , 0 ) ;
2010-12-15 23:39:25 -08:00
2019-02-11 00:30:26 -08:00
touchscreen_parse_properties ( input_dev , true , & ts - > prop ) ;
2019-10-22 10:31:16 -07: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 09:23:00 -07:00
error = devm_request_threaded_irq ( & client - > dev , client - > irq ,
NULL , st1232_ts_irq_handler ,
IRQF_ONESHOT ,
client - > name , ts ) ;
2010-12-15 23:39:25 -08:00
if ( error ) {
dev_err ( & client - > dev , " Failed to register interrupt \n " ) ;
2013-04-15 09:23:00 -07:00
return error ;
2010-12-15 23:39:25 -08: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 09:23:00 -07:00
return error ;
2010-12-15 23:39:25 -08:00
}
i2c_set_clientdata ( client , ts ) ;
return 0 ;
}
2014-11-02 00:04:14 -07:00
static int __maybe_unused st1232_ts_suspend ( struct device * dev )
2010-12-15 23:39:25 -08:00
{
struct i2c_client * client = to_i2c_client ( dev ) ;
2013-04-15 09:31:00 -07:00
struct st1232_ts_data * ts = i2c_get_clientdata ( client ) ;
2010-12-15 23:39:25 -08:00
2019-10-21 11:00:21 -07:00
disable_irq ( client - > irq ) ;
if ( ! device_may_wakeup ( & client - > dev ) )
2013-04-15 09:31:00 -07:00
st1232_ts_power ( ts , false ) ;
2010-12-15 23:39:25 -08:00
return 0 ;
}
2014-11-02 00:04:14 -07:00
static int __maybe_unused st1232_ts_resume ( struct device * dev )
2010-12-15 23:39:25 -08:00
{
struct i2c_client * client = to_i2c_client ( dev ) ;
2013-04-15 09:31:00 -07:00
struct st1232_ts_data * ts = i2c_get_clientdata ( client ) ;
2010-12-15 23:39:25 -08:00
2019-10-21 11:00:21 -07:00
if ( ! device_may_wakeup ( & client - > dev ) )
2013-04-15 09:31:00 -07:00
st1232_ts_power ( ts , true ) ;
2019-10-21 11:00:21 -07:00
enable_irq ( client - > irq ) ;
2010-12-15 23:39:25 -08:00
return 0 ;
}
2012-04-03 11:30:28 -07:00
static SIMPLE_DEV_PM_OPS ( st1232_ts_pm_ops ,
st1232_ts_suspend , st1232_ts_resume ) ;
2010-12-15 23:39:25 -08:00
static const struct i2c_device_id st1232_ts_id [ ] = {
2019-01-28 10:38:10 -08:00
{ ST1232_TS_NAME , ( unsigned long ) & st1232_chip_info } ,
{ ST1633_TS_NAME , ( unsigned long ) & st1633_chip_info } ,
2010-12-15 23:39:25 -08:00
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , st1232_ts_id ) ;
2012-11-23 21:31:00 -08:00
static const struct of_device_id st1232_ts_dt_ids [ ] = {
2019-01-28 10:38:10 -08:00
{ . compatible = " sitronix,st1232 " , . data = & st1232_chip_info } ,
{ . compatible = " sitronix,st1633 " , . data = & st1633_chip_info } ,
2012-04-03 11:30:28 -07:00
{ }
} ;
MODULE_DEVICE_TABLE ( of , st1232_ts_dt_ids ) ;
2010-12-15 23:39:25 -08:00
static struct i2c_driver st1232_ts_driver = {
. probe = st1232_ts_probe ,
. id_table = st1232_ts_id ,
. driver = {
. name = ST1232_TS_NAME ,
2017-10-31 09:47:28 -07:00
. of_match_table = st1232_ts_dt_ids ,
2010-12-15 23:39:25 -08:00
. pm = & st1232_ts_pm_ops ,
} ,
} ;
2012-03-16 23:05:41 -07:00
module_i2c_driver ( st1232_ts_driver ) ;
2010-12-15 23:39:25 -08:00
MODULE_AUTHOR ( " Tony SIM <chinyeow.sim.xt@renesas.com> " ) ;
2019-01-28 11:04:08 -08:00
MODULE_AUTHOR ( " Martin Kepplinger <martin.kepplinger@ginzinger.com> " ) ;
2010-12-15 23:39:25 -08:00
MODULE_DESCRIPTION ( " SITRONIX ST1232 Touchscreen Controller Driver " ) ;
2018-11-12 11:30:06 -08:00
MODULE_LICENSE ( " GPL v2 " ) ;