2019-06-01 10:08:55 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2014-10-31 09:26:16 -07:00
/*
* Driver for Goodix Touchscreens
*
* Copyright ( c ) 2014 Red Hat Inc .
2015-12-17 17:02:53 -08:00
* Copyright ( c ) 2015 K . Merker < merker @ debian . org >
2014-10-31 09:26:16 -07:00
*
* This code is based on gt9xx . c authored by andrew @ goodix . com :
*
* 2010 - 2012 Goodix Technology .
*/
# include <linux/kernel.h>
2015-07-24 09:08:53 -07:00
# include <linux/dmi.h>
2015-12-17 16:05:42 -08:00
# include <linux/firmware.h>
2014-10-31 09:26:16 -07:00
# include <linux/module.h>
# include <linux/delay.h>
# include <linux/irq.h>
# include <linux/interrupt.h>
2022-02-28 22:52:31 -08:00
# include <linux/platform_data/x86/soc.h>
2014-10-31 09:26:16 -07:00
# include <linux/slab.h>
2015-03-06 16:43:38 -08:00
# include <linux/acpi.h>
# include <linux/of.h>
2014-10-31 09:26:16 -07:00
# include <asm/unaligned.h>
2021-09-20 21:08:18 -07:00
# include "goodix.h"
2014-10-31 09:26:16 -07:00
2020-03-24 11:29:10 -07:00
# define GOODIX_GPIO_INT_NAME "irq"
# define GOODIX_GPIO_RST_NAME "reset"
# define GOODIX_MAX_HEIGHT 4096
# define GOODIX_MAX_WIDTH 4096
# define GOODIX_INT_TRIGGER 1
# define GOODIX_CONTACT_SIZE 8
# define GOODIX_MAX_CONTACT_SIZE 9
# define GOODIX_MAX_CONTACTS 10
2020-03-24 11:33:16 -07:00
# define GOODIX_CONFIG_MIN_LENGTH 186
2020-03-24 11:29:10 -07:00
# define GOODIX_CONFIG_911_LENGTH 186
# define GOODIX_CONFIG_967_LENGTH 228
2020-03-24 11:33:16 -07:00
# define GOODIX_CONFIG_GT9X_LENGTH 240
2020-03-24 11:29:10 -07:00
# define GOODIX_BUFFER_STATUS_READY BIT(7)
2020-03-24 11:38:49 -07:00
# define GOODIX_HAVE_KEY BIT(4)
2020-03-24 11:29:10 -07:00
# define GOODIX_BUFFER_STATUS_TIMEOUT 20
# define RESOLUTION_LOC 1
# define MAX_CONTACTS_LOC 5
# define TRIGGER_LOC 6
2020-04-01 12:53:36 -07:00
/* Our special handling for GPIO accesses through ACPI is x86 specific */
# if defined CONFIG_X86 && defined CONFIG_ACPI
# define ACPI_GPIO_SUPPORT
# endif
2020-03-24 11:57:58 -07:00
struct goodix_chip_id {
const char * id ;
const struct goodix_chip_data * data ;
} ;
2017-10-24 11:06:41 -07:00
static int goodix_check_cfg_8 ( struct goodix_ts_data * ts ,
2020-03-24 11:33:50 -07:00
const u8 * cfg , int len ) ;
2017-10-24 11:06:41 -07:00
static int goodix_check_cfg_16 ( struct goodix_ts_data * ts ,
2020-03-24 11:33:50 -07:00
const u8 * cfg , int len ) ;
2020-03-24 11:29:26 -07:00
static void goodix_calc_cfg_checksum_8 ( struct goodix_ts_data * ts ) ;
static void goodix_calc_cfg_checksum_16 ( struct goodix_ts_data * ts ) ;
2017-10-24 11:06:41 -07:00
static const struct goodix_chip_data gt1x_chip_data = {
. config_addr = GOODIX_GT1X_REG_CONFIG_DATA ,
2020-03-24 11:33:16 -07:00
. config_len = GOODIX_CONFIG_GT9X_LENGTH ,
2017-10-24 11:06:41 -07:00
. check_config = goodix_check_cfg_16 ,
2020-03-24 11:29:26 -07:00
. calc_config_checksum = goodix_calc_cfg_checksum_16 ,
2017-10-24 11:06:41 -07:00
} ;
static const struct goodix_chip_data gt911_chip_data = {
. config_addr = GOODIX_GT9X_REG_CONFIG_DATA ,
. config_len = GOODIX_CONFIG_911_LENGTH ,
. check_config = goodix_check_cfg_8 ,
2020-03-24 11:29:26 -07:00
. calc_config_checksum = goodix_calc_cfg_checksum_8 ,
2017-10-24 11:06:41 -07:00
} ;
static const struct goodix_chip_data gt967_chip_data = {
. config_addr = GOODIX_GT9X_REG_CONFIG_DATA ,
. config_len = GOODIX_CONFIG_967_LENGTH ,
. check_config = goodix_check_cfg_8 ,
2020-03-24 11:29:26 -07:00
. calc_config_checksum = goodix_calc_cfg_checksum_8 ,
2017-10-24 11:06:41 -07:00
} ;
static const struct goodix_chip_data gt9x_chip_data = {
. config_addr = GOODIX_GT9X_REG_CONFIG_DATA ,
2020-03-24 11:33:16 -07:00
. config_len = GOODIX_CONFIG_GT9X_LENGTH ,
2017-10-24 11:06:41 -07:00
. check_config = goodix_check_cfg_8 ,
2020-03-24 11:29:26 -07:00
. calc_config_checksum = goodix_calc_cfg_checksum_8 ,
2017-10-24 11:06:41 -07:00
} ;
2020-03-24 11:57:58 -07:00
static const struct goodix_chip_id goodix_chip_ids [ ] = {
{ . id = " 1151 " , . data = & gt1x_chip_data } ,
2022-08-11 16:16:54 -07:00
{ . id = " 1158 " , . data = & gt1x_chip_data } ,
2020-03-24 11:57:58 -07:00
{ . id = " 5663 " , . data = & gt1x_chip_data } ,
{ . id = " 5688 " , . data = & gt1x_chip_data } ,
2020-03-24 12:25:58 -07:00
{ . id = " 917S " , . data = & gt1x_chip_data } ,
2021-01-09 22:14:39 -08:00
{ . id = " 9286 " , . data = & gt1x_chip_data } ,
2020-03-24 11:57:58 -07:00
{ . id = " 911 " , . data = & gt911_chip_data } ,
{ . id = " 9271 " , . data = & gt911_chip_data } ,
{ . id = " 9110 " , . data = & gt911_chip_data } ,
2021-12-06 23:29:27 -08:00
{ . id = " 9111 " , . data = & gt911_chip_data } ,
2020-03-24 11:57:58 -07:00
{ . id = " 927 " , . data = & gt911_chip_data } ,
{ . id = " 928 " , . data = & gt911_chip_data } ,
{ . id = " 912 " , . data = & gt967_chip_data } ,
2020-03-24 12:32:27 -07:00
{ . id = " 9147 " , . data = & gt967_chip_data } ,
2020-03-24 11:57:58 -07:00
{ . id = " 967 " , . data = & gt967_chip_data } ,
{ }
} ;
2014-10-31 09:26:16 -07:00
static const unsigned long goodix_irq_flags [ ] = {
IRQ_TYPE_EDGE_RISING ,
IRQ_TYPE_EDGE_FALLING ,
IRQ_TYPE_LEVEL_LOW ,
IRQ_TYPE_LEVEL_HIGH ,
} ;
2019-09-16 16:32:24 -07:00
static const struct dmi_system_id nine_bytes_report [ ] = {
# if defined(CONFIG_DMI) && defined(CONFIG_X86)
{
2023-03-17 03:13:12 -07:00
/* Lenovo Yoga Book X90F / X90L */
2019-09-16 16:32:24 -07:00
. matches = {
2023-03-17 03:13:12 -07:00
DMI_EXACT_MATCH ( DMI_SYS_VENDOR , " Intel Corporation " ) ,
DMI_EXACT_MATCH ( DMI_PRODUCT_NAME , " CHERRYVIEW D1 PLATFORM " ) ,
DMI_EXACT_MATCH ( DMI_PRODUCT_VERSION , " YETI-11 " ) ,
}
} ,
{
/* Lenovo Yoga Book X91F / X91L */
. matches = {
/* Non exact match to match F + L versions */
DMI_MATCH ( DMI_PRODUCT_NAME , " Lenovo YB1-X91 " ) ,
2019-09-16 16:32:24 -07:00
}
} ,
# endif
{ }
} ;
2020-03-05 19:53:06 -08:00
/*
* Those tablets have their x coordinate inverted
*/
static const struct dmi_system_id inverted_x_screen [ ] = {
# if defined(CONFIG_DMI) && defined(CONFIG_X86)
{
. ident = " Cube I15-TC " ,
. matches = {
DMI_MATCH ( DMI_SYS_VENDOR , " Cube " ) ,
DMI_MATCH ( DMI_PRODUCT_NAME , " I15-TC " )
} ,
} ,
# endif
{ }
} ;
2014-10-31 09:26:16 -07:00
/**
* goodix_i2c_read - read data from a register of the i2c slave device .
*
* @ client : i2c device .
* @ reg : the register to read from .
* @ buf : raw write data buffer .
* @ len : length of the buffer to write
*/
2021-09-20 21:08:18 -07:00
int goodix_i2c_read ( struct i2c_client * client , u16 reg , u8 * buf , int len )
2014-10-31 09:26:16 -07:00
{
struct i2c_msg msgs [ 2 ] ;
2018-01-26 11:08:59 -08:00
__be16 wbuf = cpu_to_be16 ( reg ) ;
2014-10-31 09:26:16 -07:00
int ret ;
msgs [ 0 ] . flags = 0 ;
msgs [ 0 ] . addr = client - > addr ;
msgs [ 0 ] . len = 2 ;
2015-06-09 11:01:38 -07:00
msgs [ 0 ] . buf = ( u8 * ) & wbuf ;
2014-10-31 09:26:16 -07:00
msgs [ 1 ] . flags = I2C_M_RD ;
msgs [ 1 ] . addr = client - > addr ;
msgs [ 1 ] . len = len ;
msgs [ 1 ] . buf = buf ;
ret = i2c_transfer ( client - > adapter , msgs , 2 ) ;
2021-09-20 21:08:35 -07:00
if ( ret > = 0 )
ret = ( ret = = ARRAY_SIZE ( msgs ) ? 0 : - EIO ) ;
if ( ret )
dev_err ( & client - > dev , " Error reading %d bytes from 0x%04x: %d \n " ,
len , reg , ret ) ;
return ret ;
2014-10-31 09:26:16 -07:00
}
2015-12-17 16:05:42 -08:00
/**
* goodix_i2c_write - write data to a register of the i2c slave device .
*
* @ client : i2c device .
* @ reg : the register to write to .
* @ buf : raw data buffer to write .
* @ len : length of the buffer to write
*/
2021-09-20 21:08:18 -07:00
int goodix_i2c_write ( struct i2c_client * client , u16 reg , const u8 * buf , int len )
2015-12-17 16:05:42 -08:00
{
u8 * addr_buf ;
struct i2c_msg msg ;
int ret ;
addr_buf = kmalloc ( len + 2 , GFP_KERNEL ) ;
if ( ! addr_buf )
return - ENOMEM ;
addr_buf [ 0 ] = reg > > 8 ;
addr_buf [ 1 ] = reg & 0xFF ;
memcpy ( & addr_buf [ 2 ] , buf , len ) ;
msg . flags = 0 ;
msg . addr = client - > addr ;
msg . buf = addr_buf ;
msg . len = len + 2 ;
ret = i2c_transfer ( client - > adapter , & msg , 1 ) ;
2021-09-20 21:08:35 -07:00
if ( ret > = 0 )
ret = ( ret = = 1 ? 0 : - EIO ) ;
2015-12-17 16:05:42 -08:00
kfree ( addr_buf ) ;
2021-09-20 21:08:35 -07:00
if ( ret )
dev_err ( & client - > dev , " Error writing %d bytes to 0x%04x: %d \n " ,
len , reg , ret ) ;
return ret ;
2015-12-17 16:05:42 -08:00
}
2021-09-20 21:08:18 -07:00
int goodix_i2c_write_u8 ( struct i2c_client * client , u16 reg , u8 value )
2015-12-17 16:43:39 -08:00
{
return goodix_i2c_write ( client , reg , & value , sizeof ( value ) ) ;
}
2020-03-24 11:57:58 -07:00
static const struct goodix_chip_data * goodix_get_chip_data ( const char * id )
2015-12-17 15:55:21 -08:00
{
2020-03-24 11:57:58 -07:00
unsigned int i ;
2015-12-17 15:55:21 -08:00
2020-03-24 11:57:58 -07:00
for ( i = 0 ; goodix_chip_ids [ i ] . id ; i + + ) {
if ( ! strcmp ( goodix_chip_ids [ i ] . id , id ) )
return goodix_chip_ids [ i ] . data ;
2015-12-17 15:55:21 -08:00
}
2020-03-24 11:57:58 -07:00
return & gt9x_chip_data ;
2015-12-17 15:55:21 -08:00
}
2014-10-31 09:26:16 -07:00
static int goodix_ts_read_input_report ( struct goodix_ts_data * ts , u8 * data )
{
Input: goodix - poll the 'buffer status' bit before reading data
The Goodix panel triggers an interrupt on touch events. However, its
registers will contain the valid values a short time after the
interrupt, and not when it's raised. At that moment, the 'buffer status'
bit is set.
Previously, if the 'buffer status' bit was not set when the registers
were read, the data was discarded and no input event was emitted,
causing "finger down" or "finger up" events to be missed sometimes.
This went unnoticed until v4.9, as the DesignWare I2C driver commonly
used with this driver had enough latency for that bug to never trigger
until commit 2702ea7dbec5 ("i2c: designware: wait for disable/enable only
if necessary").
Now, in the IRQ handler we will poll (with a timeout) the 'buffer status'
bit and process the data of the panel as soon as this bit gets set.
Note that the Goodix panel will send a few spurious interrupts after the
'finger up' event, in which the 'buffer status' bit will never be set.
Cc: Bastien Nocera <hadess@hadess.net>
Cc: russianneuromancer@ya.ru
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
[hdegoede@redhat.com: Change poll loop to use jiffies,
add comment about typical poll time]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[dtor: rearranged control flow a bit to avoid explicit goto and double
check]
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2017-10-13 11:04:48 -07:00
unsigned long max_timeout ;
2014-10-31 09:26:16 -07:00
int touch_num ;
int error ;
2020-03-24 11:38:49 -07:00
u16 addr = GOODIX_READ_COOR_ADDR ;
/*
* We are going to read 1 - byte header ,
* ts - > contact_size * max ( 1 , touch_num ) bytes of coordinates
* and 1 - byte footer which contains the touch - key code .
*/
const int header_contact_keycode_size = 1 + ts - > contact_size + 1 ;
2014-10-31 09:26:16 -07:00
Input: goodix - poll the 'buffer status' bit before reading data
The Goodix panel triggers an interrupt on touch events. However, its
registers will contain the valid values a short time after the
interrupt, and not when it's raised. At that moment, the 'buffer status'
bit is set.
Previously, if the 'buffer status' bit was not set when the registers
were read, the data was discarded and no input event was emitted,
causing "finger down" or "finger up" events to be missed sometimes.
This went unnoticed until v4.9, as the DesignWare I2C driver commonly
used with this driver had enough latency for that bug to never trigger
until commit 2702ea7dbec5 ("i2c: designware: wait for disable/enable only
if necessary").
Now, in the IRQ handler we will poll (with a timeout) the 'buffer status'
bit and process the data of the panel as soon as this bit gets set.
Note that the Goodix panel will send a few spurious interrupts after the
'finger up' event, in which the 'buffer status' bit will never be set.
Cc: Bastien Nocera <hadess@hadess.net>
Cc: russianneuromancer@ya.ru
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
[hdegoede@redhat.com: Change poll loop to use jiffies,
add comment about typical poll time]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[dtor: rearranged control flow a bit to avoid explicit goto and double
check]
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2017-10-13 11:04:48 -07:00
/*
* The ' buffer status ' bit , which indicates that the data is valid , is
* not set as soon as the interrupt is raised , but slightly after .
* This takes around 10 ms to happen , so we poll for 20 ms .
*/
max_timeout = jiffies + msecs_to_jiffies ( GOODIX_BUFFER_STATUS_TIMEOUT ) ;
do {
2020-03-24 11:38:49 -07:00
error = goodix_i2c_read ( ts - > client , addr , data ,
header_contact_keycode_size ) ;
2021-09-20 21:08:35 -07:00
if ( error )
2014-10-31 09:26:16 -07:00
return error ;
Input: goodix - poll the 'buffer status' bit before reading data
The Goodix panel triggers an interrupt on touch events. However, its
registers will contain the valid values a short time after the
interrupt, and not when it's raised. At that moment, the 'buffer status'
bit is set.
Previously, if the 'buffer status' bit was not set when the registers
were read, the data was discarded and no input event was emitted,
causing "finger down" or "finger up" events to be missed sometimes.
This went unnoticed until v4.9, as the DesignWare I2C driver commonly
used with this driver had enough latency for that bug to never trigger
until commit 2702ea7dbec5 ("i2c: designware: wait for disable/enable only
if necessary").
Now, in the IRQ handler we will poll (with a timeout) the 'buffer status'
bit and process the data of the panel as soon as this bit gets set.
Note that the Goodix panel will send a few spurious interrupts after the
'finger up' event, in which the 'buffer status' bit will never be set.
Cc: Bastien Nocera <hadess@hadess.net>
Cc: russianneuromancer@ya.ru
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
[hdegoede@redhat.com: Change poll loop to use jiffies,
add comment about typical poll time]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[dtor: rearranged control flow a bit to avoid explicit goto and double
check]
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2017-10-13 11:04:48 -07:00
if ( data [ 0 ] & GOODIX_BUFFER_STATUS_READY ) {
touch_num = data [ 0 ] & 0x0f ;
if ( touch_num > ts - > max_touch_num )
return - EPROTO ;
if ( touch_num > 1 ) {
2020-03-24 11:38:49 -07:00
addr + = header_contact_keycode_size ;
data + = header_contact_keycode_size ;
Input: goodix - poll the 'buffer status' bit before reading data
The Goodix panel triggers an interrupt on touch events. However, its
registers will contain the valid values a short time after the
interrupt, and not when it's raised. At that moment, the 'buffer status'
bit is set.
Previously, if the 'buffer status' bit was not set when the registers
were read, the data was discarded and no input event was emitted,
causing "finger down" or "finger up" events to be missed sometimes.
This went unnoticed until v4.9, as the DesignWare I2C driver commonly
used with this driver had enough latency for that bug to never trigger
until commit 2702ea7dbec5 ("i2c: designware: wait for disable/enable only
if necessary").
Now, in the IRQ handler we will poll (with a timeout) the 'buffer status'
bit and process the data of the panel as soon as this bit gets set.
Note that the Goodix panel will send a few spurious interrupts after the
'finger up' event, in which the 'buffer status' bit will never be set.
Cc: Bastien Nocera <hadess@hadess.net>
Cc: russianneuromancer@ya.ru
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
[hdegoede@redhat.com: Change poll loop to use jiffies,
add comment about typical poll time]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[dtor: rearranged control flow a bit to avoid explicit goto and double
check]
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2017-10-13 11:04:48 -07:00
error = goodix_i2c_read ( ts - > client ,
2020-03-24 11:38:49 -07:00
addr , data ,
2019-09-16 16:32:24 -07:00
ts - > contact_size *
Input: goodix - poll the 'buffer status' bit before reading data
The Goodix panel triggers an interrupt on touch events. However, its
registers will contain the valid values a short time after the
interrupt, and not when it's raised. At that moment, the 'buffer status'
bit is set.
Previously, if the 'buffer status' bit was not set when the registers
were read, the data was discarded and no input event was emitted,
causing "finger down" or "finger up" events to be missed sometimes.
This went unnoticed until v4.9, as the DesignWare I2C driver commonly
used with this driver had enough latency for that bug to never trigger
until commit 2702ea7dbec5 ("i2c: designware: wait for disable/enable only
if necessary").
Now, in the IRQ handler we will poll (with a timeout) the 'buffer status'
bit and process the data of the panel as soon as this bit gets set.
Note that the Goodix panel will send a few spurious interrupts after the
'finger up' event, in which the 'buffer status' bit will never be set.
Cc: Bastien Nocera <hadess@hadess.net>
Cc: russianneuromancer@ya.ru
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
[hdegoede@redhat.com: Change poll loop to use jiffies,
add comment about typical poll time]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[dtor: rearranged control flow a bit to avoid explicit goto and double
check]
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2017-10-13 11:04:48 -07:00
( touch_num - 1 ) ) ;
if ( error )
return error ;
}
return touch_num ;
}
2021-09-20 21:08:53 -07:00
if ( data [ 0 ] = = 0 & & ts - > firmware_name ) {
if ( goodix_handle_fw_request ( ts ) )
return 0 ;
}
Input: goodix - poll the 'buffer status' bit before reading data
The Goodix panel triggers an interrupt on touch events. However, its
registers will contain the valid values a short time after the
interrupt, and not when it's raised. At that moment, the 'buffer status'
bit is set.
Previously, if the 'buffer status' bit was not set when the registers
were read, the data was discarded and no input event was emitted,
causing "finger down" or "finger up" events to be missed sometimes.
This went unnoticed until v4.9, as the DesignWare I2C driver commonly
used with this driver had enough latency for that bug to never trigger
until commit 2702ea7dbec5 ("i2c: designware: wait for disable/enable only
if necessary").
Now, in the IRQ handler we will poll (with a timeout) the 'buffer status'
bit and process the data of the panel as soon as this bit gets set.
Note that the Goodix panel will send a few spurious interrupts after the
'finger up' event, in which the 'buffer status' bit will never be set.
Cc: Bastien Nocera <hadess@hadess.net>
Cc: russianneuromancer@ya.ru
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
[hdegoede@redhat.com: Change poll loop to use jiffies,
add comment about typical poll time]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[dtor: rearranged control flow a bit to avoid explicit goto and double
check]
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2017-10-13 11:04:48 -07:00
usleep_range ( 1000 , 2000 ) ; /* Poll every 1 - 2 ms */
} while ( time_before ( jiffies , max_timeout ) ) ;
2014-10-31 09:26:16 -07:00
Input: goodix - poll the 'buffer status' bit before reading data
The Goodix panel triggers an interrupt on touch events. However, its
registers will contain the valid values a short time after the
interrupt, and not when it's raised. At that moment, the 'buffer status'
bit is set.
Previously, if the 'buffer status' bit was not set when the registers
were read, the data was discarded and no input event was emitted,
causing "finger down" or "finger up" events to be missed sometimes.
This went unnoticed until v4.9, as the DesignWare I2C driver commonly
used with this driver had enough latency for that bug to never trigger
until commit 2702ea7dbec5 ("i2c: designware: wait for disable/enable only
if necessary").
Now, in the IRQ handler we will poll (with a timeout) the 'buffer status'
bit and process the data of the panel as soon as this bit gets set.
Note that the Goodix panel will send a few spurious interrupts after the
'finger up' event, in which the 'buffer status' bit will never be set.
Cc: Bastien Nocera <hadess@hadess.net>
Cc: russianneuromancer@ya.ru
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
[hdegoede@redhat.com: Change poll loop to use jiffies,
add comment about typical poll time]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
[dtor: rearranged control flow a bit to avoid explicit goto and double
check]
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2017-10-13 11:04:48 -07:00
/*
* The Goodix panel will send spurious interrupts after a
* ' finger up ' event , which will always cause a timeout .
*/
2020-03-24 11:38:28 -07:00
return - ENOMSG ;
2014-10-31 09:26:16 -07:00
}
2022-02-28 22:59:34 -08:00
static int goodix_create_pen_input ( struct goodix_ts_data * ts )
2021-12-08 09:33:35 -08:00
{
struct device * dev = & ts - > client - > dev ;
struct input_dev * input ;
input = devm_input_allocate_device ( dev ) ;
if ( ! input )
2022-02-28 22:59:34 -08:00
return - ENOMEM ;
2021-12-08 09:33:35 -08:00
2022-02-28 22:59:03 -08:00
input_copy_abs ( input , ABS_X , ts - > input_dev , ABS_MT_POSITION_X ) ;
input_copy_abs ( input , ABS_Y , ts - > input_dev , ABS_MT_POSITION_Y ) ;
2021-12-08 09:33:35 -08:00
/*
* The resolution of these touchscreens is about 10 units / mm , the actual
* resolution does not matter much since we set INPUT_PROP_DIRECT .
* Userspace wants something here though , so just set it to 10 units / mm .
*/
input_abs_set_res ( input , ABS_X , 10 ) ;
input_abs_set_res ( input , ABS_Y , 10 ) ;
2022-02-28 22:59:03 -08:00
input_set_abs_params ( input , ABS_PRESSURE , 0 , 255 , 0 , 0 ) ;
input_set_capability ( input , EV_KEY , BTN_TOUCH ) ;
input_set_capability ( input , EV_KEY , BTN_TOOL_PEN ) ;
input_set_capability ( input , EV_KEY , BTN_STYLUS ) ;
input_set_capability ( input , EV_KEY , BTN_STYLUS2 ) ;
__set_bit ( INPUT_PROP_DIRECT , input - > propbit ) ;
2021-12-08 09:33:35 -08:00
input - > name = " Goodix Active Pen " ;
input - > phys = " input/pen " ;
input - > id . bustype = BUS_I2C ;
2021-12-12 20:54:29 -08:00
input - > id . vendor = 0x0416 ;
2021-12-08 09:33:35 -08:00
if ( kstrtou16 ( ts - > id , 10 , & input - > id . product ) )
input - > id . product = 0x1001 ;
input - > id . version = ts - > version ;
2022-02-28 22:59:34 -08:00
ts - > input_pen = input ;
return 0 ;
2021-12-08 09:33:35 -08:00
}
static void goodix_ts_report_pen_down ( struct goodix_ts_data * ts , u8 * data )
{
2022-02-28 22:59:34 -08:00
int input_x , input_y , input_w , error ;
2021-12-08 09:33:35 -08:00
u8 key_value ;
2022-02-28 22:59:34 -08:00
if ( ! ts - > pen_input_registered ) {
error = input_register_device ( ts - > input_pen ) ;
ts - > pen_input_registered = ( error = = 0 ) ? 1 : error ;
2021-12-08 09:33:35 -08:00
}
2022-02-28 22:59:34 -08:00
if ( ts - > pen_input_registered < 0 )
return ;
2021-12-08 09:33:35 -08:00
if ( ts - > contact_size = = 9 ) {
input_x = get_unaligned_le16 ( & data [ 4 ] ) ;
input_y = get_unaligned_le16 ( & data [ 6 ] ) ;
input_w = get_unaligned_le16 ( & data [ 8 ] ) ;
} else {
input_x = get_unaligned_le16 ( & data [ 2 ] ) ;
input_y = get_unaligned_le16 ( & data [ 4 ] ) ;
input_w = get_unaligned_le16 ( & data [ 6 ] ) ;
}
touchscreen_report_pos ( ts - > input_pen , & ts - > prop , input_x , input_y , false ) ;
input_report_abs ( ts - > input_pen , ABS_PRESSURE , input_w ) ;
input_report_key ( ts - > input_pen , BTN_TOUCH , 1 ) ;
input_report_key ( ts - > input_pen , BTN_TOOL_PEN , 1 ) ;
if ( data [ 0 ] & GOODIX_HAVE_KEY ) {
key_value = data [ 1 + ts - > contact_size ] ;
input_report_key ( ts - > input_pen , BTN_STYLUS , key_value & 0x10 ) ;
input_report_key ( ts - > input_pen , BTN_STYLUS2 , key_value & 0x20 ) ;
} else {
input_report_key ( ts - > input_pen , BTN_STYLUS , 0 ) ;
input_report_key ( ts - > input_pen , BTN_STYLUS2 , 0 ) ;
}
input_sync ( ts - > input_pen ) ;
}
static void goodix_ts_report_pen_up ( struct goodix_ts_data * ts )
{
if ( ! ts - > input_pen )
return ;
input_report_key ( ts - > input_pen , BTN_TOUCH , 0 ) ;
input_report_key ( ts - > input_pen , BTN_TOOL_PEN , 0 ) ;
input_report_key ( ts - > input_pen , BTN_STYLUS , 0 ) ;
input_report_key ( ts - > input_pen , BTN_STYLUS2 , 0 ) ;
input_sync ( ts - > input_pen ) ;
}
2019-09-16 16:32:24 -07:00
static void goodix_ts_report_touch_8b ( struct goodix_ts_data * ts , u8 * coor_data )
2014-10-31 09:26:16 -07:00
{
int id = coor_data [ 0 ] & 0x0F ;
int input_x = get_unaligned_le16 ( & coor_data [ 1 ] ) ;
int input_y = get_unaligned_le16 ( & coor_data [ 3 ] ) ;
int input_w = get_unaligned_le16 ( & coor_data [ 5 ] ) ;
input_mt_slot ( ts - > input_dev , id ) ;
input_mt_report_slot_state ( ts - > input_dev , MT_TOOL_FINGER , true ) ;
2018-01-26 11:08:59 -08:00
touchscreen_report_pos ( ts - > input_dev , & ts - > prop ,
input_x , input_y , true ) ;
2014-10-31 09:26:16 -07:00
input_report_abs ( ts - > input_dev , ABS_MT_TOUCH_MAJOR , input_w ) ;
input_report_abs ( ts - > input_dev , ABS_MT_WIDTH_MAJOR , input_w ) ;
}
2019-09-16 16:32:24 -07:00
static void goodix_ts_report_touch_9b ( struct goodix_ts_data * ts , u8 * coor_data )
{
int id = coor_data [ 1 ] & 0x0F ;
int input_x = get_unaligned_le16 ( & coor_data [ 3 ] ) ;
int input_y = get_unaligned_le16 ( & coor_data [ 5 ] ) ;
int input_w = get_unaligned_le16 ( & coor_data [ 7 ] ) ;
input_mt_slot ( ts - > input_dev , id ) ;
input_mt_report_slot_state ( ts - > input_dev , MT_TOOL_FINGER , true ) ;
touchscreen_report_pos ( ts - > input_dev , & ts - > prop ,
input_x , input_y , true ) ;
input_report_abs ( ts - > input_dev , ABS_MT_TOUCH_MAJOR , input_w ) ;
input_report_abs ( ts - > input_dev , ABS_MT_WIDTH_MAJOR , input_w ) ;
}
2021-12-08 09:33:35 -08:00
static void goodix_ts_release_keys ( struct goodix_ts_data * ts )
{
int i ;
for ( i = 0 ; i < GOODIX_MAX_KEYS ; i + + )
input_report_key ( ts - > input_dev , ts - > keymap [ i ] , 0 ) ;
}
2020-03-24 11:38:49 -07:00
static void goodix_ts_report_key ( struct goodix_ts_data * ts , u8 * data )
{
int touch_num ;
u8 key_value ;
int i ;
if ( data [ 0 ] & GOODIX_HAVE_KEY ) {
touch_num = data [ 0 ] & 0x0f ;
key_value = data [ 1 + ts - > contact_size * touch_num ] ;
for ( i = 0 ; i < GOODIX_MAX_KEYS ; i + + )
if ( key_value & BIT ( i ) )
input_report_key ( ts - > input_dev ,
ts - > keymap [ i ] , 1 ) ;
} else {
2021-12-08 09:33:35 -08:00
goodix_ts_release_keys ( ts ) ;
2020-03-24 11:38:49 -07:00
}
}
2014-10-31 09:26:16 -07:00
/**
* goodix_process_events - Process incoming events
*
* @ ts : our goodix_ts_data pointer
*
* Called when the IRQ is triggered . Read the current device state , and push
* the input events to the user space .
*/
static void goodix_process_events ( struct goodix_ts_data * ts )
{
2020-03-24 11:38:49 -07:00
u8 point_data [ 2 + GOODIX_MAX_CONTACT_SIZE * GOODIX_MAX_CONTACTS ] ;
2014-10-31 09:26:16 -07:00
int touch_num ;
int i ;
touch_num = goodix_ts_read_input_report ( ts , point_data ) ;
if ( touch_num < 0 )
return ;
2021-12-08 09:33:35 -08:00
/* The pen being down is always reported as a single touch */
if ( touch_num = = 1 & & ( point_data [ 1 ] & 0x80 ) ) {
goodix_ts_report_pen_down ( ts , point_data ) ;
goodix_ts_release_keys ( ts ) ;
2021-12-12 20:54:29 -08:00
goto sync ; /* Release any previously registered touches */
2021-12-08 09:33:35 -08:00
} else {
goodix_ts_report_pen_up ( ts ) ;
}
2020-03-24 11:38:49 -07:00
goodix_ts_report_key ( ts , point_data ) ;
2017-09-06 17:29:24 -07:00
2014-10-31 09:26:16 -07:00
for ( i = 0 ; i < touch_num ; i + + )
2019-09-16 16:32:24 -07:00
if ( ts - > contact_size = = 9 )
goodix_ts_report_touch_9b ( ts ,
& point_data [ 1 + ts - > contact_size * i ] ) ;
else
goodix_ts_report_touch_8b ( ts ,
& point_data [ 1 + ts - > contact_size * i ] ) ;
2014-10-31 09:26:16 -07:00
2021-12-08 09:33:35 -08:00
sync :
2014-10-31 09:26:16 -07:00
input_mt_sync_frame ( ts - > input_dev ) ;
input_sync ( ts - > input_dev ) ;
}
/**
* goodix_ts_irq_handler - The IRQ handler
*
* @ irq : interrupt number .
* @ dev_id : private data pointer .
*/
static irqreturn_t goodix_ts_irq_handler ( int irq , void * dev_id )
{
struct goodix_ts_data * ts = dev_id ;
goodix_process_events ( ts ) ;
2021-09-20 21:08:35 -07:00
goodix_i2c_write_u8 ( ts - > client , GOODIX_READ_COOR_ADDR , 0 ) ;
2014-10-31 09:26:16 -07:00
return IRQ_HANDLED ;
}
2015-12-17 16:43:39 -08:00
static void goodix_free_irq ( struct goodix_ts_data * ts )
{
devm_free_irq ( & ts - > client - > dev , ts - > client - > irq , ts ) ;
}
static int goodix_request_irq ( struct goodix_ts_data * ts )
{
return devm_request_threaded_irq ( & ts - > client - > dev , ts - > client - > irq ,
NULL , goodix_ts_irq_handler ,
ts - > irq_flags , ts - > client - > name , ts ) ;
}
2020-03-24 11:33:50 -07:00
static int goodix_check_cfg_8 ( struct goodix_ts_data * ts , const u8 * cfg , int len )
2015-12-17 16:05:42 -08:00
{
2020-03-24 11:33:50 -07:00
int i , raw_cfg_len = len - 2 ;
2015-12-17 16:05:42 -08:00
u8 check_sum = 0 ;
for ( i = 0 ; i < raw_cfg_len ; i + + )
2020-03-24 11:33:50 -07:00
check_sum + = cfg [ i ] ;
2015-12-17 16:05:42 -08:00
check_sum = ( ~ check_sum ) + 1 ;
2020-03-24 11:33:50 -07:00
if ( check_sum ! = cfg [ raw_cfg_len ] ) {
2015-12-17 16:05:42 -08:00
dev_err ( & ts - > client - > dev ,
" The checksum of the config fw is not correct " ) ;
return - EINVAL ;
}
2020-03-24 11:33:50 -07:00
if ( cfg [ raw_cfg_len + 1 ] ! = 1 ) {
2015-12-17 16:05:42 -08:00
dev_err ( & ts - > client - > dev ,
" Config fw must have Config_Fresh register set " ) ;
return - EINVAL ;
}
return 0 ;
}
2020-03-24 11:29:26 -07:00
static void goodix_calc_cfg_checksum_8 ( struct goodix_ts_data * ts )
{
int i , raw_cfg_len = ts - > chip - > config_len - 2 ;
u8 check_sum = 0 ;
for ( i = 0 ; i < raw_cfg_len ; i + + )
check_sum + = ts - > config [ i ] ;
check_sum = ( ~ check_sum ) + 1 ;
ts - > config [ raw_cfg_len ] = check_sum ;
ts - > config [ raw_cfg_len + 1 ] = 1 ; /* Set "config_fresh" bit */
}
2020-03-24 11:33:50 -07:00
static int goodix_check_cfg_16 ( struct goodix_ts_data * ts , const u8 * cfg ,
int len )
2017-10-24 11:06:41 -07:00
{
2020-03-24 11:33:50 -07:00
int i , raw_cfg_len = len - 3 ;
2017-10-24 11:06:41 -07:00
u16 check_sum = 0 ;
for ( i = 0 ; i < raw_cfg_len ; i + = 2 )
2020-03-24 11:33:50 -07:00
check_sum + = get_unaligned_be16 ( & cfg [ i ] ) ;
2017-10-24 11:06:41 -07:00
check_sum = ( ~ check_sum ) + 1 ;
2020-03-24 11:33:50 -07:00
if ( check_sum ! = get_unaligned_be16 ( & cfg [ raw_cfg_len ] ) ) {
2017-10-24 11:06:41 -07:00
dev_err ( & ts - > client - > dev ,
" The checksum of the config fw is not correct " ) ;
return - EINVAL ;
}
2020-03-24 11:33:50 -07:00
if ( cfg [ raw_cfg_len + 2 ] ! = 1 ) {
2017-10-24 11:06:41 -07:00
dev_err ( & ts - > client - > dev ,
" Config fw must have Config_Fresh register set " ) ;
return - EINVAL ;
}
return 0 ;
}
2020-03-24 11:29:26 -07:00
static void goodix_calc_cfg_checksum_16 ( struct goodix_ts_data * ts )
{
int i , raw_cfg_len = ts - > chip - > config_len - 3 ;
u16 check_sum = 0 ;
for ( i = 0 ; i < raw_cfg_len ; i + = 2 )
check_sum + = get_unaligned_be16 ( & ts - > config [ i ] ) ;
check_sum = ( ~ check_sum ) + 1 ;
put_unaligned_be16 ( check_sum , & ts - > config [ raw_cfg_len ] ) ;
ts - > config [ raw_cfg_len + 2 ] = 1 ; /* Set "config_fresh" bit */
}
2017-10-24 11:06:41 -07:00
/**
* goodix_check_cfg - Checks if config fw is valid
*
* @ ts : goodix_ts_data pointer
* @ cfg : firmware config data
2020-11-19 19:12:42 -08:00
* @ len : config data length
2017-10-24 11:06:41 -07:00
*/
2020-03-24 11:33:50 -07:00
static int goodix_check_cfg ( struct goodix_ts_data * ts , const u8 * cfg , int len )
2017-10-24 11:06:41 -07:00
{
2020-03-24 11:33:50 -07:00
if ( len < GOODIX_CONFIG_MIN_LENGTH | |
len > GOODIX_CONFIG_MAX_LENGTH ) {
2017-10-24 11:06:41 -07:00
dev_err ( & ts - > client - > dev ,
" The length of the config fw is not correct " ) ;
return - EINVAL ;
}
2020-03-24 11:33:50 -07:00
return ts - > chip - > check_config ( ts , cfg , len ) ;
2017-10-24 11:06:41 -07:00
}
2015-12-17 16:05:42 -08:00
/**
* goodix_send_cfg - Write fw config to device
*
* @ ts : goodix_ts_data pointer
* @ cfg : config firmware to write to device
2020-11-19 19:12:42 -08:00
* @ len : config data length
2015-12-17 16:05:42 -08:00
*/
2021-09-20 21:08:18 -07:00
int goodix_send_cfg ( struct goodix_ts_data * ts , const u8 * cfg , int len )
2015-12-17 16:05:42 -08:00
{
int error ;
2020-03-24 11:33:50 -07:00
error = goodix_check_cfg ( ts , cfg , len ) ;
2015-12-17 16:05:42 -08:00
if ( error )
return error ;
2020-03-24 11:33:50 -07:00
error = goodix_i2c_write ( ts - > client , ts - > chip - > config_addr , cfg , len ) ;
2021-09-20 21:08:35 -07:00
if ( error )
2015-12-17 16:05:42 -08:00
return error ;
2021-09-20 21:08:35 -07:00
2015-12-17 16:05:42 -08:00
dev_dbg ( & ts - > client - > dev , " Config sent successfully. " ) ;
/* Let the firmware reconfigure itself, so sleep for 10ms */
usleep_range ( 10000 , 11000 ) ;
return 0 ;
}
2020-04-01 12:53:36 -07:00
# ifdef ACPI_GPIO_SUPPORT
static int goodix_pin_acpi_direction_input ( struct goodix_ts_data * ts )
2020-03-24 11:12:10 -07:00
{
2020-04-01 12:53:36 -07:00
acpi_handle handle = ACPI_HANDLE ( & ts - > client - > dev ) ;
2020-03-24 11:24:31 -07:00
acpi_status status ;
2020-04-01 12:53:36 -07:00
status = acpi_evaluate_object ( handle , " INTI " , NULL , NULL ) ;
return ACPI_SUCCESS ( status ) ? 0 : - EIO ;
}
static int goodix_pin_acpi_output_method ( struct goodix_ts_data * ts , int value )
{
acpi_handle handle = ACPI_HANDLE ( & ts - > client - > dev ) ;
acpi_status status ;
status = acpi_execute_simple_method ( handle , " INTO " , value ) ;
return ACPI_SUCCESS ( status ) ? 0 : - EIO ;
}
# else
static int goodix_pin_acpi_direction_input ( struct goodix_ts_data * ts )
{
dev_err ( & ts - > client - > dev ,
" %s called on device without ACPI support \n " , __func__ ) ;
return - EINVAL ;
}
static int goodix_pin_acpi_output_method ( struct goodix_ts_data * ts , int value )
{
dev_err ( & ts - > client - > dev ,
" %s called on device without ACPI support \n " , __func__ ) ;
return - EINVAL ;
}
# endif
static int goodix_irq_direction_output ( struct goodix_ts_data * ts , int value )
{
2020-03-24 11:12:10 -07:00
switch ( ts - > irq_pin_access_method ) {
case IRQ_PIN_ACCESS_NONE :
dev_err ( & ts - > client - > dev ,
" %s called without an irq_pin_access_method set \n " ,
__func__ ) ;
return - EINVAL ;
case IRQ_PIN_ACCESS_GPIO :
return gpiod_direction_output ( ts - > gpiod_int , value ) ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
case IRQ_PIN_ACCESS_ACPI_GPIO :
/*
* The IRQ pin triggers on a falling edge , so its gets marked
* as active - low , use output_raw to avoid the value inversion .
*/
return gpiod_direction_output_raw ( ts - > gpiod_int , value ) ;
2020-03-24 11:24:31 -07:00
case IRQ_PIN_ACCESS_ACPI_METHOD :
2020-04-01 12:53:36 -07:00
return goodix_pin_acpi_output_method ( ts , value ) ;
2020-03-24 11:12:10 -07:00
}
return - EINVAL ; /* Never reached */
}
static int goodix_irq_direction_input ( struct goodix_ts_data * ts )
{
switch ( ts - > irq_pin_access_method ) {
case IRQ_PIN_ACCESS_NONE :
dev_err ( & ts - > client - > dev ,
" %s called without an irq_pin_access_method set \n " ,
__func__ ) ;
return - EINVAL ;
case IRQ_PIN_ACCESS_GPIO :
2020-04-01 12:53:36 -07:00
return gpiod_direction_input ( ts - > gpiod_int ) ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
case IRQ_PIN_ACCESS_ACPI_GPIO :
2020-03-24 11:12:10 -07:00
return gpiod_direction_input ( ts - > gpiod_int ) ;
2020-03-24 11:24:31 -07:00
case IRQ_PIN_ACCESS_ACPI_METHOD :
2020-04-01 12:53:36 -07:00
return goodix_pin_acpi_direction_input ( ts ) ;
2020-03-24 11:12:10 -07:00
}
return - EINVAL ; /* Never reached */
}
2021-09-20 21:08:18 -07:00
int goodix_int_sync ( struct goodix_ts_data * ts )
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
{
int error ;
2020-03-24 11:12:10 -07:00
error = goodix_irq_direction_output ( ts , 0 ) ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
if ( error )
2021-09-20 21:08:26 -07:00
goto error ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
msleep ( 50 ) ; /* T5: 50ms */
2020-03-24 11:12:10 -07:00
error = goodix_irq_direction_input ( ts ) ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
if ( error )
2021-09-20 21:08:26 -07:00
goto error ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
return 0 ;
2021-09-20 21:08:26 -07:00
error :
dev_err ( & ts - > client - > dev , " Controller irq sync failed. \n " ) ;
return error ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
}
/**
2021-09-20 21:08:26 -07:00
* goodix_reset_no_int_sync - Reset device , leaving interrupt line in output mode
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
*
* @ ts : goodix_ts_data pointer
*/
2021-09-20 21:08:26 -07:00
int goodix_reset_no_int_sync ( struct goodix_ts_data * ts )
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
{
int error ;
/* begin select I2C slave addr */
error = gpiod_direction_output ( ts - > gpiod_rst , 0 ) ;
if ( error )
2021-09-20 21:08:26 -07:00
goto error ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
msleep ( 20 ) ; /* T2: > 10ms */
/* HIGH: 0x28/0x29, LOW: 0xBA/0xBB */
2020-03-24 11:12:10 -07:00
error = goodix_irq_direction_output ( ts , ts - > client - > addr = = 0x14 ) ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
if ( error )
2021-09-20 21:08:26 -07:00
goto error ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
usleep_range ( 100 , 2000 ) ; /* T3: > 100us */
error = gpiod_direction_output ( ts - > gpiod_rst , 1 ) ;
if ( error )
2021-09-20 21:08:26 -07:00
goto error ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
usleep_range ( 6000 , 10000 ) ; /* T4: > 5ms */
2021-12-06 23:15:09 -08:00
/*
* Put the reset pin back in to input / high - impedance mode to save
* power . Only do this in the non ACPI case since some ACPI boards
* don ' t have a pull - up , so there the reset pin must stay active - high .
*/
if ( ts - > irq_pin_access_method = = IRQ_PIN_ACCESS_GPIO ) {
error = gpiod_direction_input ( ts - > gpiod_rst ) ;
if ( error )
goto error ;
}
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
2021-09-20 21:08:26 -07:00
return 0 ;
error :
dev_err ( & ts - > client - > dev , " Controller reset failed. \n " ) ;
return error ;
}
/**
* goodix_reset - Reset device during power on
*
* @ ts : goodix_ts_data pointer
*/
static int goodix_reset ( struct goodix_ts_data * ts )
{
int error ;
error = goodix_reset_no_int_sync ( ts ) ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
if ( error )
return error ;
2021-09-20 21:08:26 -07:00
return goodix_int_sync ( ts ) ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
}
2020-04-01 12:53:36 -07:00
# ifdef ACPI_GPIO_SUPPORT
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
static const struct acpi_gpio_params first_gpio = { 0 , 0 , false } ;
static const struct acpi_gpio_params second_gpio = { 1 , 0 , false } ;
static const struct acpi_gpio_mapping acpi_goodix_int_first_gpios [ ] = {
{ GOODIX_GPIO_INT_NAME " -gpios " , & first_gpio , 1 } ,
{ GOODIX_GPIO_RST_NAME " -gpios " , & second_gpio , 1 } ,
{ } ,
} ;
static const struct acpi_gpio_mapping acpi_goodix_int_last_gpios [ ] = {
{ GOODIX_GPIO_RST_NAME " -gpios " , & first_gpio , 1 } ,
{ GOODIX_GPIO_INT_NAME " -gpios " , & second_gpio , 1 } ,
{ } ,
} ;
2020-03-24 11:24:31 -07:00
static const struct acpi_gpio_mapping acpi_goodix_reset_only_gpios [ ] = {
{ GOODIX_GPIO_RST_NAME " -gpios " , & first_gpio , 1 } ,
{ } ,
} ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
static int goodix_resource ( struct acpi_resource * ares , void * data )
{
struct goodix_ts_data * ts = data ;
struct device * dev = & ts - > client - > dev ;
struct acpi_resource_gpio * gpio ;
2022-07-06 16:29:11 -07:00
if ( acpi_gpio_get_irq_resource ( ares , & gpio ) ) {
if ( ts - > gpio_int_idx = = - 1 ) {
ts - > gpio_int_idx = ts - > gpio_count ;
} else {
dev_err ( dev , " More then one GpioInt resource, ignoring ACPI GPIO resources \n " ) ;
ts - > gpio_int_idx = - 2 ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
}
ts - > gpio_count + + ;
2022-07-06 16:29:11 -07:00
} else if ( acpi_gpio_get_io_resource ( ares , & gpio ) )
ts - > gpio_count + + ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
return 0 ;
}
/*
* This function gets called in case we fail to get the irq GPIO directly
* because the ACPI tables lack GPIO - name to APCI _CRS index mappings
* ( no _DSD UUID daffd814 - 6 eba - 4 d8c - 8 a91 - bc9bbf4aa301 data ) .
* In that case we add our own mapping and then goodix_get_gpio_config ( )
* retries to get the GPIOs based on the added mapping .
*/
static int goodix_add_acpi_gpio_mappings ( struct goodix_ts_data * ts )
{
const struct acpi_gpio_mapping * gpio_mapping = NULL ;
struct device * dev = & ts - > client - > dev ;
LIST_HEAD ( resources ) ;
2022-02-28 22:53:12 -08:00
int irq , ret ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
ts - > gpio_count = 0 ;
ts - > gpio_int_idx = - 1 ;
ret = acpi_dev_get_resources ( ACPI_COMPANION ( dev ) , & resources ,
goodix_resource , ts ) ;
if ( ret < 0 ) {
dev_err ( dev , " Error getting ACPI resources: %d \n " , ret ) ;
return ret ;
}
acpi_dev_free_resource_list ( & resources ) ;
2022-02-28 22:53:12 -08:00
/*
* CHT devices should have a GpioInt + a regular GPIO ACPI resource .
* Some CHT devices have a bug ( where the also is bogus Interrupt
* resource copied from a previous BYT based generation ) . i2c - core - acpi
* will use the non - working Interrupt resource , fix this up .
*/
if ( soc_intel_is_cht ( ) & & ts - > gpio_count = = 2 & & ts - > gpio_int_idx ! = - 1 ) {
irq = acpi_dev_gpio_irq_get ( ACPI_COMPANION ( dev ) , 0 ) ;
if ( irq > 0 & & irq ! = ts - > client - > irq ) {
dev_warn ( dev , " Overriding IRQ %d -> %d \n " , ts - > client - > irq , irq ) ;
ts - > client - > irq = irq ;
}
}
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
if ( ts - > gpio_count = = 2 & & ts - > gpio_int_idx = = 0 ) {
ts - > irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO ;
gpio_mapping = acpi_goodix_int_first_gpios ;
} else if ( ts - > gpio_count = = 2 & & ts - > gpio_int_idx = = 1 ) {
ts - > irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO ;
gpio_mapping = acpi_goodix_int_last_gpios ;
2020-03-24 11:24:31 -07:00
} else if ( ts - > gpio_count = = 1 & & ts - > gpio_int_idx = = - 1 & &
acpi_has_method ( ACPI_HANDLE ( dev ) , " INTI " ) & &
acpi_has_method ( ACPI_HANDLE ( dev ) , " INTO " ) ) {
dev_info ( dev , " Using ACPI INTI and INTO methods for IRQ pin access \n " ) ;
ts - > irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_METHOD ;
gpio_mapping = acpi_goodix_reset_only_gpios ;
2022-02-28 22:52:31 -08:00
} else if ( soc_intel_is_byt ( ) & & ts - > gpio_count = = 2 & & ts - > gpio_int_idx = = - 1 ) {
Input: goodix - add support for getting IRQ + reset GPIOs on Bay Trail devices
On most Bay Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 2 GpioIo resource in their _CRS table, on all 4 such
devices which I have access to, the order of the 2 GPIOs is reset, int.
Note that the GPIO to which the touchscreen controller irq pin is connected
is configured in direct-irq mode on these Bay Trail devices, the
pinctrl-baytrail.c driver still allows controlling the pin as a GPIO in
this case, but this is not necessarily the case on other X86 ACPI
platforms, nor do we have a guarantee that the GPIO order is the same
elsewhere, so we limit the use of a _CRS table with 2 GpioIo resources
to Bay Trail devices only.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20200307121505.3707-5-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:35 -07:00
dev_info ( dev , " No ACPI GpioInt resource, assuming that the GPIO order is reset, int \n " ) ;
ts - > irq_pin_access_method = IRQ_PIN_ACCESS_ACPI_GPIO ;
gpio_mapping = acpi_goodix_int_last_gpios ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
} else {
dev_warn ( dev , " Unexpected ACPI resources: gpio_count %d, gpio_int_idx %d \n " ,
ts - > gpio_count , ts - > gpio_int_idx ) ;
2022-07-08 21:42:12 -07:00
/*
* On some devices _PS0 does a reset for us and
* sometimes this is necessary for things to work .
*/
acpi_device_fix_up_power ( ACPI_COMPANION ( dev ) ) ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
return - EINVAL ;
}
2021-12-06 23:15:09 -08:00
/*
* Normally we put the reset pin in input / high - impedance mode to save
* power . But some x86 / ACPI boards don ' t have a pull - up , so for the ACPI
* case , leave the pin as is . This results in the pin not being touched
* at all on x86 / ACPI boards , except when needed for error - recover .
*/
ts - > gpiod_rst_flags = GPIOD_ASIS ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
return devm_acpi_dev_add_driver_gpios ( dev , gpio_mapping ) ;
}
# else
static int goodix_add_acpi_gpio_mappings ( struct goodix_ts_data * ts )
{
return - EINVAL ;
}
# endif /* CONFIG_X86 && CONFIG_ACPI */
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
/**
* goodix_get_gpio_config - Get GPIO config from ACPI / DT
*
* @ ts : goodix_ts_data pointer
*/
static int goodix_get_gpio_config ( struct goodix_ts_data * ts )
{
struct device * dev ;
struct gpio_desc * gpiod ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
bool added_acpi_mappings = false ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
if ( ! ts - > client )
return - EINVAL ;
dev = & ts - > client - > dev ;
2021-12-06 23:15:09 -08:00
/*
* By default we request the reset pin as input , leaving it in
* high - impedance when not resetting the controller to save power .
*/
ts - > gpiod_rst_flags = GPIOD_IN ;
2019-04-03 15:20:26 -07:00
ts - > avdd28 = devm_regulator_get ( dev , " AVDD28 " ) ;
2023-06-25 18:28:06 +02:00
if ( IS_ERR ( ts - > avdd28 ) )
return dev_err_probe ( dev , PTR_ERR ( ts - > avdd28 ) , " Failed to get AVDD28 regulator \n " ) ;
2019-04-03 15:20:26 -07:00
ts - > vddio = devm_regulator_get ( dev , " VDDIO " ) ;
2023-06-25 18:28:06 +02:00
if ( IS_ERR ( ts - > vddio ) )
return dev_err_probe ( dev , PTR_ERR ( ts - > vddio ) , " Failed to get VDDIO regulator \n " ) ;
2019-04-03 15:20:26 -07:00
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
retry_get_irq_gpio :
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
/* Get the interrupt GPIO pin number */
gpiod = devm_gpiod_get_optional ( dev , GOODIX_GPIO_INT_NAME , GPIOD_IN ) ;
2023-06-25 18:28:06 +02:00
if ( IS_ERR ( gpiod ) )
return dev_err_probe ( dev , PTR_ERR ( gpiod ) , " Failed to get %s GPIO \n " ,
GOODIX_GPIO_INT_NAME ) ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
if ( ! gpiod & & has_acpi_companion ( dev ) & & ! added_acpi_mappings ) {
added_acpi_mappings = true ;
if ( goodix_add_acpi_gpio_mappings ( ts ) = = 0 )
goto retry_get_irq_gpio ;
}
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
ts - > gpiod_int = gpiod ;
/* Get the reset line GPIO pin number */
2021-12-06 23:15:09 -08:00
gpiod = devm_gpiod_get_optional ( dev , GOODIX_GPIO_RST_NAME , ts - > gpiod_rst_flags ) ;
2023-06-25 18:28:06 +02:00
if ( IS_ERR ( gpiod ) )
return dev_err_probe ( dev , PTR_ERR ( gpiod ) , " Failed to get %s GPIO \n " ,
GOODIX_GPIO_RST_NAME ) ;
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
ts - > gpiod_rst = gpiod ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
switch ( ts - > irq_pin_access_method ) {
case IRQ_PIN_ACCESS_ACPI_GPIO :
/*
* We end up here if goodix_add_acpi_gpio_mappings ( ) has
* called devm_acpi_dev_add_driver_gpios ( ) because the ACPI
* tables did not contain name to index mappings .
* Check that we successfully got both GPIOs after we ' ve
* added our own acpi_gpio_mapping and if we did not get both
* GPIOs reset irq_pin_access_method to IRQ_PIN_ACCESS_NONE .
*/
if ( ! ts - > gpiod_int | | ! ts - > gpiod_rst )
ts - > irq_pin_access_method = IRQ_PIN_ACCESS_NONE ;
break ;
2020-03-24 11:24:31 -07:00
case IRQ_PIN_ACCESS_ACPI_METHOD :
if ( ! ts - > gpiod_rst )
ts - > irq_pin_access_method = IRQ_PIN_ACCESS_NONE ;
break ;
Input: goodix - add support for getting IRQ + reset GPIOs on Cherry Trail devices
On most Cherry Trail (x86, UEFI + ACPI) devices the ACPI tables do not have
a _DSD with a "daffd814-6eba-4d8c-8a91-bc9bbf4aa301" UUID, adding
"irq-gpios" and "reset-gpios" mappings, so we cannot get the GPIOS by name
without first manually adding mappings ourselves.
These devices contain 1 GpioInt and 1 GpioIo resource in their _CRS table:
Method (_CRS, 0, NotSerialized) // _CRS: Current Resource Settings
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBusV2 (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\_SB.PCI0.I2C2",
0x00, ResourceConsumer, , Exclusive,
)
GpioInt (Edge, ActiveLow, Shared, PullDefault, 0x0000,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0013
}
GpioIo (Shared, PullDefault, 0x0000, 0x0000,
IoRestrictionOutputOnly,
"\\_SB.GPO1", 0x00, ResourceConsumer, ,
)
{ // Pin list
0x0019
}
})
Return (RBUF) /* \_SB_.PCI0.I2C2.TCS1._CRS.RBUF */
}
There is no fixed order for these 2. This commit adds code to check that
there is 1 of each as expected and then registers a mapping matching their
order using devm_acpi_dev_add_driver_gpios().
This gives us access to both GPIOs allowing us to properly suspend the
controller during suspend, and making it possible to reset the controller
if necessary.
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1786317
BugLink: https://github.com/nexus511/gpd-ubuntu-packages/issues/10
BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=199207
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Bastien Nocera <hadess@hadess.net>
Link: https://lore.kernel.org/r/20200307121505.3707-4-hdegoede@redhat.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2020-03-24 11:23:21 -07:00
default :
if ( ts - > gpiod_int & & ts - > gpiod_rst ) {
ts - > reset_controller_at_probe = true ;
ts - > load_cfg_from_disk = true ;
ts - > irq_pin_access_method = IRQ_PIN_ACCESS_GPIO ;
}
2020-03-24 11:12:35 -07:00
}
2020-03-24 11:12:10 -07:00
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
return 0 ;
}
2014-10-31 09:26:16 -07:00
/**
* goodix_read_config - Read the embedded configuration of the panel
*
* @ ts : our goodix_ts_data pointer
*
* Must be called during probe
*/
static void goodix_read_config ( struct goodix_ts_data * ts )
{
2018-01-26 11:08:59 -08:00
int x_max , y_max ;
2014-10-31 09:26:16 -07:00
int error ;
2021-09-20 21:08:53 -07:00
/*
* On controllers where we need to upload the firmware
* ( controllers without flash ) ts - > config already has the config
* at this point and the controller itself does not have it yet !
*/
if ( ! ts - > firmware_name ) {
error = goodix_i2c_read ( ts - > client , ts - > chip - > config_addr ,
ts - > config , ts - > chip - > config_len ) ;
if ( error ) {
ts - > int_trigger_type = GOODIX_INT_TRIGGER ;
ts - > max_touch_num = GOODIX_MAX_CONTACTS ;
return ;
}
2014-10-31 09:26:16 -07:00
}
2020-03-24 11:29:26 -07:00
ts - > int_trigger_type = ts - > config [ TRIGGER_LOC ] & 0x03 ;
ts - > max_touch_num = ts - > config [ MAX_CONTACTS_LOC ] & 0x0f ;
2015-07-24 09:08:53 -07:00
2020-03-24 11:29:26 -07:00
x_max = get_unaligned_le16 ( & ts - > config [ RESOLUTION_LOC ] ) ;
y_max = get_unaligned_le16 ( & ts - > config [ RESOLUTION_LOC + 2 ] ) ;
2018-01-26 11:08:59 -08:00
if ( x_max & & y_max ) {
input_abs_set_max ( ts - > input_dev , ABS_MT_POSITION_X , x_max - 1 ) ;
input_abs_set_max ( ts - > input_dev , ABS_MT_POSITION_Y , y_max - 1 ) ;
2015-12-17 17:08:31 -08:00
}
2020-03-24 11:29:26 -07:00
ts - > chip - > calc_config_checksum ( ts ) ;
2014-10-31 09:26:16 -07:00
}
/**
* goodix_read_version - Read goodix touchscreen version
*
2015-12-17 16:05:42 -08:00
* @ ts : our goodix_ts_data pointer
2014-10-31 09:26:16 -07:00
*/
2015-12-17 16:05:42 -08:00
static int goodix_read_version ( struct goodix_ts_data * ts )
2014-10-31 09:26:16 -07:00
{
int error ;
u8 buf [ 6 ] ;
2020-03-24 11:57:58 -07:00
char id_str [ GOODIX_ID_MAX_LEN + 1 ] ;
2014-10-31 09:26:16 -07:00
2015-12-17 16:05:42 -08:00
error = goodix_i2c_read ( ts - > client , GOODIX_REG_ID , buf , sizeof ( buf ) ) ;
2021-09-20 21:08:35 -07:00
if ( error )
2014-10-31 09:26:16 -07:00
return error ;
2020-03-24 11:57:58 -07:00
memcpy ( id_str , buf , GOODIX_ID_MAX_LEN ) ;
id_str [ GOODIX_ID_MAX_LEN ] = 0 ;
strscpy ( ts - > id , id_str , GOODIX_ID_MAX_LEN + 1 ) ;
2014-10-31 09:26:16 -07:00
2015-12-17 16:05:42 -08:00
ts - > version = get_unaligned_le16 ( & buf [ 4 ] ) ;
2015-06-09 11:04:40 -07:00
2020-03-24 11:57:58 -07:00
dev_info ( & ts - > client - > dev , " ID %s, version: %04x \n " , ts - > id ,
2015-12-17 16:05:42 -08:00
ts - > version ) ;
2014-10-31 09:26:16 -07:00
return 0 ;
}
/**
* goodix_i2c_test - I2C test function to check if the device answers .
*
* @ client : the i2c client
*/
static int goodix_i2c_test ( struct i2c_client * client )
{
int retry = 0 ;
int error ;
u8 test ;
while ( retry + + < 2 ) {
2021-09-20 21:08:35 -07:00
error = goodix_i2c_read ( client , GOODIX_REG_ID , & test , 1 ) ;
2014-10-31 09:26:16 -07:00
if ( ! error )
return 0 ;
msleep ( 20 ) ;
}
return error ;
}
/**
2018-01-26 11:08:59 -08:00
* goodix_configure_dev - Finish device initialization
2014-10-31 09:26:16 -07:00
*
* @ ts : our goodix_ts_data pointer
*
2018-01-26 11:08:59 -08:00
* Must be called from probe to finish initialization of the device .
* Contains the common initialization code for both devices that
* declare gpio pins and devices that do not . It is either called
* directly from probe or from request_firmware_wait callback .
2014-10-31 09:26:16 -07:00
*/
2018-01-26 11:08:59 -08:00
static int goodix_configure_dev ( struct goodix_ts_data * ts )
2014-10-31 09:26:16 -07:00
{
int error ;
2020-03-24 11:38:49 -07:00
int i ;
2014-10-31 09:26:16 -07:00
2018-01-26 11:08:59 -08:00
ts - > int_trigger_type = GOODIX_INT_TRIGGER ;
ts - > max_touch_num = GOODIX_MAX_CONTACTS ;
2014-10-31 09:26:16 -07:00
ts - > input_dev = devm_input_allocate_device ( & ts - > client - > dev ) ;
if ( ! ts - > input_dev ) {
dev_err ( & ts - > client - > dev , " Failed to allocate input device. " ) ;
return - ENOMEM ;
}
ts - > input_dev - > name = " Goodix Capacitive TouchScreen " ;
ts - > input_dev - > phys = " input/ts " ;
ts - > input_dev - > id . bustype = BUS_I2C ;
ts - > input_dev - > id . vendor = 0x0416 ;
2020-03-24 11:57:58 -07:00
if ( kstrtou16 ( ts - > id , 10 , & ts - > input_dev - > id . product ) )
ts - > input_dev - > id . product = 0x1001 ;
2015-12-17 16:05:42 -08:00
ts - > input_dev - > id . version = ts - > version ;
2014-10-31 09:26:16 -07:00
2020-03-24 11:38:49 -07:00
ts - > input_dev - > keycode = ts - > keymap ;
ts - > input_dev - > keycodesize = sizeof ( ts - > keymap [ 0 ] ) ;
ts - > input_dev - > keycodemax = GOODIX_MAX_KEYS ;
2017-09-06 17:29:24 -07:00
/* Capacitive Windows/Home button on some devices */
2020-03-24 11:38:49 -07:00
for ( i = 0 ; i < GOODIX_MAX_KEYS ; + + i ) {
if ( i = = 0 )
ts - > keymap [ i ] = KEY_LEFTMETA ;
else
ts - > keymap [ i ] = KEY_F1 + ( i - 1 ) ;
input_set_capability ( ts - > input_dev , EV_KEY , ts - > keymap [ i ] ) ;
}
2017-09-06 17:29:24 -07:00
2018-01-26 11:08:59 -08:00
input_set_capability ( ts - > input_dev , EV_ABS , ABS_MT_POSITION_X ) ;
input_set_capability ( ts - > input_dev , EV_ABS , ABS_MT_POSITION_Y ) ;
input_set_abs_params ( ts - > input_dev , ABS_MT_WIDTH_MAJOR , 0 , 255 , 0 , 0 ) ;
input_set_abs_params ( ts - > input_dev , ABS_MT_TOUCH_MAJOR , 0 , 255 , 0 , 0 ) ;
2014-10-31 09:26:16 -07:00
2022-11-03 11:31:43 -07:00
retry_read_config :
2018-01-26 11:08:59 -08:00
/* Read configuration and apply touchscreen parameters */
goodix_read_config ( ts ) ;
2014-10-31 09:26:16 -07:00
2018-01-26 11:08:59 -08:00
/* Try overriding touchscreen parameters via device properties */
touchscreen_parse_properties ( ts - > input_dev , true , & ts - > prop ) ;
2015-12-17 16:05:42 -08:00
2018-01-26 11:08:59 -08:00
if ( ! ts - > prop . max_x | | ! ts - > prop . max_y | | ! ts - > max_touch_num ) {
2022-11-03 11:31:43 -07:00
if ( ! ts - > reset_controller_at_probe & &
ts - > irq_pin_access_method ! = IRQ_PIN_ACCESS_NONE ) {
dev_info ( & ts - > client - > dev , " Config not set, resetting controller \n " ) ;
/* Retry after a controller reset */
ts - > reset_controller_at_probe = true ;
error = goodix_reset ( ts ) ;
if ( error )
return error ;
goto retry_read_config ;
}
2019-02-16 23:04:43 -08:00
dev_err ( & ts - > client - > dev ,
" Invalid config (%d, %d, %d), using defaults \n " ,
ts - > prop . max_x , ts - > prop . max_y , ts - > max_touch_num ) ;
2018-01-26 11:08:59 -08:00
ts - > prop . max_x = GOODIX_MAX_WIDTH - 1 ;
ts - > prop . max_y = GOODIX_MAX_HEIGHT - 1 ;
ts - > max_touch_num = GOODIX_MAX_CONTACTS ;
input_abs_set_max ( ts - > input_dev ,
ABS_MT_POSITION_X , ts - > prop . max_x ) ;
input_abs_set_max ( ts - > input_dev ,
ABS_MT_POSITION_Y , ts - > prop . max_y ) ;
}
2015-12-17 17:02:53 -08:00
2019-09-16 16:32:24 -07:00
if ( dmi_check_system ( nine_bytes_report ) ) {
ts - > contact_size = 9 ;
dev_dbg ( & ts - > client - > dev ,
" Non-standard 9-bytes report format quirk \n " ) ;
}
2020-03-05 19:53:06 -08:00
if ( dmi_check_system ( inverted_x_screen ) ) {
ts - > prop . invert_x = true ;
dev_dbg ( & ts - > client - > dev ,
" Applying 'inverted x screen' quirk \n " ) ;
}
2018-01-26 11:08:59 -08:00
error = input_mt_init_slots ( ts - > input_dev , ts - > max_touch_num ,
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED ) ;
if ( error ) {
dev_err ( & ts - > client - > dev ,
" Failed to initialize MT slots: %d " , error ) ;
return error ;
}
error = input_register_device ( ts - > input_dev ) ;
if ( error ) {
dev_err ( & ts - > client - > dev ,
" Failed to register input device: %d " , error ) ;
2015-12-17 16:05:42 -08:00
return error ;
2018-01-26 11:08:59 -08:00
}
2015-12-17 16:05:42 -08:00
2022-02-28 22:59:34 -08:00
/*
* Create the input_pen device before goodix_request_irq ( ) calls
* devm_request_threaded_irq ( ) so that the devm framework frees
* it after disabling the irq .
* Unfortunately there is no way to detect if the touchscreen has pen
* support , so registering the dev is delayed till the first pen event .
*/
error = goodix_create_pen_input ( ts ) ;
if ( error )
return error ;
2015-12-17 16:43:39 -08:00
ts - > irq_flags = goodix_irq_flags [ ts - > int_trigger_type ] | IRQF_ONESHOT ;
error = goodix_request_irq ( ts ) ;
2015-12-17 16:05:42 -08:00
if ( error ) {
dev_err ( & ts - > client - > dev , " request IRQ failed: %d \n " , error ) ;
return error ;
}
return 0 ;
}
/**
* goodix_config_cb - Callback to finish device init
*
2020-11-19 19:12:42 -08:00
* @ cfg : firmware config
2020-11-19 19:19:38 -08:00
* @ ctx : our goodix_ts_data pointer
2015-12-17 16:05:42 -08:00
*
* request_firmware_wait callback that finishes
* initialization of the device .
*/
static void goodix_config_cb ( const struct firmware * cfg , void * ctx )
{
struct goodix_ts_data * ts = ctx ;
int error ;
2021-09-20 21:08:53 -07:00
if ( ts - > firmware_name ) {
if ( ! cfg )
goto err_release_cfg ;
error = goodix_check_cfg ( ts , cfg - > data , cfg - > size ) ;
if ( error )
goto err_release_cfg ;
memcpy ( ts - > config , cfg - > data , cfg - > size ) ;
} else if ( cfg ) {
2015-12-17 16:05:42 -08:00
/* send device configuration to the firmware */
2020-03-24 11:33:50 -07:00
error = goodix_send_cfg ( ts , cfg - > data , cfg - > size ) ;
2015-12-17 16:05:42 -08:00
if ( error )
goto err_release_cfg ;
}
goodix_configure_dev ( ts ) ;
err_release_cfg :
release_firmware ( cfg ) ;
complete_all ( & ts - > firmware_loading_complete ) ;
}
2019-04-03 15:20:26 -07:00
static void goodix_disable_regulators ( void * arg )
{
struct goodix_ts_data * ts = arg ;
regulator_disable ( ts - > vddio ) ;
regulator_disable ( ts - > avdd28 ) ;
}
2022-11-18 23:39:35 +01:00
static int goodix_ts_probe ( struct i2c_client * client )
2014-10-31 09:26:16 -07:00
{
struct goodix_ts_data * ts ;
2021-09-20 21:08:44 -07:00
const char * cfg_name ;
2014-10-31 09:26:16 -07:00
int error ;
dev_dbg ( & client - > dev , " I2C Address: 0x%02x \n " , client - > addr ) ;
if ( ! i2c_check_functionality ( client - > adapter , I2C_FUNC_I2C ) ) {
dev_err ( & client - > dev , " I2C check functionality failed. \n " ) ;
return - ENXIO ;
}
ts = devm_kzalloc ( & client - > dev , sizeof ( * ts ) , GFP_KERNEL ) ;
if ( ! ts )
return - ENOMEM ;
ts - > client = client ;
i2c_set_clientdata ( client , ts ) ;
2015-12-17 16:05:42 -08:00
init_completion ( & ts - > firmware_loading_complete ) ;
2019-09-16 16:32:24 -07:00
ts - > contact_size = GOODIX_CONTACT_SIZE ;
2014-10-31 09:26:16 -07:00
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
error = goodix_get_gpio_config ( ts ) ;
if ( error )
return error ;
2019-04-03 15:20:26 -07:00
/* power up the controller */
error = regulator_enable ( ts - > avdd28 ) ;
if ( error ) {
dev_err ( & client - > dev ,
" Failed to enable AVDD28 regulator: %d \n " ,
error ) ;
return error ;
}
error = regulator_enable ( ts - > vddio ) ;
if ( error ) {
dev_err ( & client - > dev ,
" Failed to enable VDDIO regulator: %d \n " ,
error ) ;
regulator_disable ( ts - > avdd28 ) ;
return error ;
}
error = devm_add_action_or_reset ( & client - > dev ,
goodix_disable_regulators , ts ) ;
if ( error )
return error ;
2020-03-24 11:37:23 -07:00
reset :
2020-03-24 11:23:04 -07:00
if ( ts - > reset_controller_at_probe ) {
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
/* reset the controller */
error = goodix_reset ( ts ) ;
2021-09-20 21:08:26 -07:00
if ( error )
Input: goodix - reset device at init
After power on, it is recommended that the driver resets the device.
The reset procedure timing is described in the datasheet and is used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This procedure
also includes setting the slave address to the one specified in the
ACPI/device tree.
This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
driver gt9xx.c for Android (publicly available in Android kernel
trees for various devices).
For reset the driver needs to control the interrupt and
reset gpio pins (configured through ACPI/device tree). For devices
that do not have the gpio pins properly declared, the functionality
depending on these pins will not be available, but the device can still
be used with basic functionality.
For both device tree and ACPI, the interrupt gpio pin configuration is
read from the "irq-gpios" property and the reset pin configuration is
read from the "reset-gpios" property. For ACPI 5.1, named properties
can be specified using the _DSD section. This functionality will not be
available for devices that use indexed gpio pins declared in the _CRS
section (we need to provide backward compatibility with devices
that do not support using the interrupt gpio pin as output).
For ACPI, the pins can be specified using ACPI 5.1:
Device (STAC)
{
Name (_HID, "GDIX1001")
...
Method (_CRS, 0, Serialized)
{
Name (RBUF, ResourceTemplate ()
{
I2cSerialBus (0x0014, ControllerInitiated, 0x00061A80,
AddressingMode7Bit, "\\I2C0",
0x00, ResourceConsumer, ,
)
GpioInt (Edge, ActiveHigh, Exclusive, PullNone, 0x0000,
"\\I2C0", 0x00, ResourceConsumer, ,
)
{ // Pin list
0
}
GpioIo (Exclusive, PullDown, 0x0000, 0x0000,
IoRestrictionOutputOnly, "\\I2C0", 0x00,
ResourceConsumer, ,
)
{
1
}
})
Return (RBUF)
}
Name (_DSD, Package ()
{
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package ()
{
Package (2) {"irq-gpios", Package() {^STAC, 0, 0, 0 }},
Package (2) {"reset-gpios", Package() {^STAC, 1, 0, 0 }},
...
}
}
Signed-off-by: Octavian Purdila <octavian.purdila@intel.com>
Signed-off-by: Irina Tirdea <irina.tirdea@intel.com>
Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Bastien Nocera <hadess@hadess.net>
Tested-by: Aleksei Mamlin <mamlinav@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
2015-12-17 15:57:34 -08:00
return error ;
}
2014-10-31 09:26:16 -07:00
error = goodix_i2c_test ( client ) ;
if ( error ) {
2020-03-24 11:37:23 -07:00
if ( ! ts - > reset_controller_at_probe & &
ts - > irq_pin_access_method ! = IRQ_PIN_ACCESS_NONE ) {
/* Retry after a controller reset */
ts - > reset_controller_at_probe = true ;
goto reset ;
}
2014-10-31 09:26:16 -07:00
dev_err ( & client - > dev , " I2C communication failure: %d \n " , error ) ;
return error ;
}
2021-09-20 21:08:53 -07:00
error = goodix_firmware_check ( ts ) ;
if ( error )
return error ;
2015-12-17 16:05:42 -08:00
error = goodix_read_version ( ts ) ;
2021-09-20 21:08:35 -07:00
if ( error )
2014-10-31 09:26:16 -07:00
return error ;
2017-10-24 11:06:41 -07:00
ts - > chip = goodix_get_chip_data ( ts - > id ) ;
2014-10-31 09:26:16 -07:00
2020-03-24 11:12:35 -07:00
if ( ts - > load_cfg_from_disk ) {
2015-12-17 16:05:42 -08:00
/* update device config */
2021-09-20 21:08:44 -07:00
error = device_property_read_string ( & client - > dev ,
" goodix,config-name " ,
& cfg_name ) ;
if ( ! error )
snprintf ( ts - > cfg_name , sizeof ( ts - > cfg_name ) ,
" goodix/%s " , cfg_name ) ;
else
snprintf ( ts - > cfg_name , sizeof ( ts - > cfg_name ) ,
" goodix_%s_cfg.bin " , ts - > id ) ;
2015-12-17 16:05:42 -08:00
error = request_firmware_nowait ( THIS_MODULE , true , ts - > cfg_name ,
& client - > dev , GFP_KERNEL , ts ,
goodix_config_cb ) ;
if ( error ) {
dev_err ( & client - > dev ,
" Failed to invoke firmware loader: %d \n " ,
error ) ;
return error ;
}
2014-10-31 09:26:16 -07:00
2015-12-17 16:05:42 -08:00
return 0 ;
} else {
error = goodix_configure_dev ( ts ) ;
if ( error )
return error ;
2014-10-31 09:26:16 -07:00
}
return 0 ;
}
2022-08-15 10:02:30 +02:00
static void goodix_ts_remove ( struct i2c_client * client )
2015-12-17 16:05:42 -08:00
{
struct goodix_ts_data * ts = i2c_get_clientdata ( client ) ;
2020-03-24 11:12:35 -07:00
if ( ts - > load_cfg_from_disk )
2015-12-17 16:05:42 -08:00
wait_for_completion ( & ts - > firmware_loading_complete ) ;
}
2023-01-02 18:18:19 +00:00
static int goodix_suspend ( struct device * dev )
2015-12-17 16:43:39 -08:00
{
struct i2c_client * client = to_i2c_client ( dev ) ;
struct goodix_ts_data * ts = i2c_get_clientdata ( client ) ;
int error ;
2020-03-24 11:12:35 -07:00
if ( ts - > load_cfg_from_disk )
wait_for_completion ( & ts - > firmware_loading_complete ) ;
2015-12-17 16:43:39 -08:00
/* We need gpio pins to suspend/resume */
2020-03-24 11:12:10 -07:00
if ( ts - > irq_pin_access_method = = IRQ_PIN_ACCESS_NONE ) {
2018-01-12 00:36:48 -08:00
disable_irq ( client - > irq ) ;
2015-12-17 16:43:39 -08:00
return 0 ;
2018-01-12 00:36:48 -08:00
}
2015-12-17 16:43:39 -08:00
/* Free IRQ as IRQ pin is used as output in the suspend sequence */
goodix_free_irq ( ts ) ;
2021-09-20 21:08:53 -07:00
/* Save reference (calibration) info if necessary */
goodix_save_bak_ref ( ts ) ;
2015-12-17 16:43:39 -08:00
/* Output LOW on the INT pin for 5 ms */
2020-03-24 11:12:10 -07:00
error = goodix_irq_direction_output ( ts , 0 ) ;
2015-12-17 16:43:39 -08:00
if ( error ) {
goodix_request_irq ( ts ) ;
return error ;
}
usleep_range ( 5000 , 6000 ) ;
error = goodix_i2c_write_u8 ( ts - > client , GOODIX_REG_COMMAND ,
GOODIX_CMD_SCREEN_OFF ) ;
if ( error ) {
2020-03-24 11:12:10 -07:00
goodix_irq_direction_input ( ts ) ;
2015-12-17 16:43:39 -08:00
goodix_request_irq ( ts ) ;
return - EAGAIN ;
}
/*
* The datasheet specifies that the interval between sending screen - off
* command and wake - up should be longer than 58 ms . To avoid waking up
* sooner , delay 58 ms here .
*/
msleep ( 58 ) ;
return 0 ;
}
2023-01-02 18:18:19 +00:00
static int goodix_resume ( struct device * dev )
2015-12-17 16:43:39 -08:00
{
struct i2c_client * client = to_i2c_client ( dev ) ;
struct goodix_ts_data * ts = i2c_get_clientdata ( client ) ;
2020-03-24 11:34:11 -07:00
u8 config_ver ;
2015-12-17 16:43:39 -08:00
int error ;
2020-03-24 11:12:10 -07:00
if ( ts - > irq_pin_access_method = = IRQ_PIN_ACCESS_NONE ) {
2018-01-12 00:36:48 -08:00
enable_irq ( client - > irq ) ;
2015-12-17 16:43:39 -08:00
return 0 ;
2018-01-12 00:36:48 -08:00
}
2015-12-17 16:43:39 -08:00
/*
* Exit sleep mode by outputting HIGH level to INT pin
* for 2 ms ~ 5 ms .
*/
2020-03-24 11:12:10 -07:00
error = goodix_irq_direction_output ( ts , 1 ) ;
2015-12-17 16:43:39 -08:00
if ( error )
return error ;
usleep_range ( 2000 , 5000 ) ;
error = goodix_int_sync ( ts ) ;
if ( error )
return error ;
2020-03-24 11:34:11 -07:00
error = goodix_i2c_read ( ts - > client , ts - > chip - > config_addr ,
& config_ver , 1 ) ;
2021-09-20 21:08:35 -07:00
if ( ! error & & config_ver ! = ts - > config [ 0 ] )
2020-03-24 11:34:11 -07:00
dev_info ( dev , " Config version mismatch %d != %d, resetting controller \n " ,
config_ver , ts - > config [ 0 ] ) ;
if ( error ! = 0 | | config_ver ! = ts - > config [ 0 ] ) {
error = goodix_reset ( ts ) ;
2021-09-20 21:08:26 -07:00
if ( error )
2020-03-24 11:34:11 -07:00
return error ;
error = goodix_send_cfg ( ts , ts - > config , ts - > chip - > config_len ) ;
if ( error )
return error ;
}
2015-12-17 16:43:39 -08:00
error = goodix_request_irq ( ts ) ;
if ( error )
return error ;
return 0 ;
}
2023-01-02 18:18:19 +00:00
static DEFINE_SIMPLE_DEV_PM_OPS ( goodix_pm_ops , goodix_suspend , goodix_resume ) ;
2015-12-17 16:43:39 -08:00
2014-10-31 09:26:16 -07:00
static const struct i2c_device_id goodix_ts_id [ ] = {
{ " GDIX1001:00 " , 0 } ,
{ }
} ;
2015-07-30 10:38:52 -07:00
MODULE_DEVICE_TABLE ( i2c , goodix_ts_id ) ;
2014-10-31 09:26:16 -07:00
2015-03-06 16:43:38 -08:00
# ifdef CONFIG_ACPI
2014-10-31 09:26:16 -07:00
static const struct acpi_device_id goodix_acpi_match [ ] = {
{ " GDIX1001 " , 0 } ,
2018-05-31 16:13:17 -07:00
{ " GDIX1002 " , 0 } ,
2014-10-31 09:26:16 -07:00
{ }
} ;
MODULE_DEVICE_TABLE ( acpi , goodix_acpi_match ) ;
2015-03-06 16:43:38 -08:00
# endif
# ifdef CONFIG_OF
static const struct of_device_id goodix_of_match [ ] = {
2017-10-24 11:06:41 -07:00
{ . compatible = " goodix,gt1151 " } ,
2022-08-23 10:00:37 -07:00
{ . compatible = " goodix,gt1158 " } ,
2019-04-03 16:05:34 -07:00
{ . compatible = " goodix,gt5663 " } ,
2019-02-16 23:03:13 -08:00
{ . compatible = " goodix,gt5688 " } ,
2015-03-06 16:43:38 -08:00
{ . compatible = " goodix,gt911 " } ,
{ . compatible = " goodix,gt9110 " } ,
{ . compatible = " goodix,gt912 " } ,
2020-03-24 12:32:27 -07:00
{ . compatible = " goodix,gt9147 " } ,
2020-03-24 12:25:58 -07:00
{ . compatible = " goodix,gt917s " } ,
2015-03-06 16:43:38 -08:00
{ . compatible = " goodix,gt927 " } ,
{ . compatible = " goodix,gt9271 " } ,
{ . compatible = " goodix,gt928 " } ,
2021-01-09 22:14:39 -08:00
{ . compatible = " goodix,gt9286 " } ,
2015-03-06 16:43:38 -08:00
{ . compatible = " goodix,gt967 " } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , goodix_of_match ) ;
# endif
2014-10-31 09:26:16 -07:00
static struct i2c_driver goodix_ts_driver = {
2023-05-17 09:55:42 -07:00
. probe = goodix_ts_probe ,
2015-12-17 16:05:42 -08:00
. remove = goodix_ts_remove ,
2014-10-31 09:26:16 -07:00
. id_table = goodix_ts_id ,
. driver = {
. name = " Goodix-TS " ,
2015-03-06 16:43:38 -08:00
. acpi_match_table = ACPI_PTR ( goodix_acpi_match ) ,
. of_match_table = of_match_ptr ( goodix_of_match ) ,
2023-01-02 18:18:19 +00:00
. pm = pm_sleep_ptr ( & goodix_pm_ops ) ,
2014-10-31 09:26:16 -07:00
} ,
} ;
module_i2c_driver ( goodix_ts_driver ) ;
MODULE_AUTHOR ( " Benjamin Tissoires <benjamin.tissoires@gmail.com> " ) ;
MODULE_AUTHOR ( " Bastien Nocera <hadess@hadess.net> " ) ;
MODULE_DESCRIPTION ( " Goodix touchscreen driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;