2021-01-15 09:06:40 -08:00
// SPDX-License-Identifier: GPL-2.0
/*
* Driver for Goodix touchscreens that use the i2c - hid protocol .
*
* Copyright 2020 Google LLC
*/
# include <linux/delay.h>
# include <linux/device.h>
# include <linux/gpio/consumer.h>
# include <linux/i2c.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/of.h>
# include <linux/pm.h>
# include <linux/regulator/consumer.h>
# include "i2c-hid.h"
struct goodix_i2c_hid_timing_data {
unsigned int post_gpio_reset_delay_ms ;
unsigned int post_power_delay_ms ;
} ;
struct i2c_hid_of_goodix {
struct i2chid_ops ops ;
struct regulator * vdd ;
2021-06-25 08:18:36 -07:00
struct notifier_block nb ;
2021-01-15 09:06:40 -08:00
struct gpio_desc * reset_gpio ;
const struct goodix_i2c_hid_timing_data * timings ;
} ;
2021-06-25 08:18:36 -07:00
static void goodix_i2c_hid_deassert_reset ( struct i2c_hid_of_goodix * ihid_goodix ,
bool regulator_just_turned_on )
2021-01-15 09:06:40 -08:00
{
2021-06-25 08:18:36 -07:00
if ( regulator_just_turned_on & & ihid_goodix - > timings - > post_power_delay_ms )
2021-01-15 09:06:40 -08:00
msleep ( ihid_goodix - > timings - > post_power_delay_ms ) ;
gpiod_set_value_cansleep ( ihid_goodix - > reset_gpio , 0 ) ;
if ( ihid_goodix - > timings - > post_gpio_reset_delay_ms )
msleep ( ihid_goodix - > timings - > post_gpio_reset_delay_ms ) ;
2021-06-25 08:18:36 -07:00
}
2021-01-15 09:06:40 -08:00
2021-06-25 08:18:36 -07:00
static int goodix_i2c_hid_power_up ( struct i2chid_ops * ops )
{
struct i2c_hid_of_goodix * ihid_goodix =
container_of ( ops , struct i2c_hid_of_goodix , ops ) ;
return regulator_enable ( ihid_goodix - > vdd ) ;
2021-01-15 09:06:40 -08:00
}
static void goodix_i2c_hid_power_down ( struct i2chid_ops * ops )
{
struct i2c_hid_of_goodix * ihid_goodix =
container_of ( ops , struct i2c_hid_of_goodix , ops ) ;
regulator_disable ( ihid_goodix - > vdd ) ;
}
2021-06-25 08:18:36 -07:00
static int ihid_goodix_vdd_notify ( struct notifier_block * nb ,
unsigned long event ,
void * ignored )
{
struct i2c_hid_of_goodix * ihid_goodix =
container_of ( nb , struct i2c_hid_of_goodix , nb ) ;
int ret = NOTIFY_OK ;
switch ( event ) {
case REGULATOR_EVENT_PRE_DISABLE :
gpiod_set_value_cansleep ( ihid_goodix - > reset_gpio , 1 ) ;
break ;
case REGULATOR_EVENT_ENABLE :
goodix_i2c_hid_deassert_reset ( ihid_goodix , true ) ;
break ;
case REGULATOR_EVENT_ABORT_DISABLE :
goodix_i2c_hid_deassert_reset ( ihid_goodix , false ) ;
break ;
default :
ret = NOTIFY_DONE ;
break ;
}
return ret ;
}
HID: i2c: use simple i2c probe
All these drivers have an i2c probe function which doesn't use the
"struct i2c_device_id *id" parameter, so they can trivially be
converted to the "probe_new" style of probe with a single argument.
This is part of an ongoing transition to single-argument i2c probe
functions. Old-style probe functions involve a call to i2c_match_id:
in drivers/i2c/i2c-core-base.c,
/*
* When there are no more users of probe(),
* rename probe_new to probe.
*/
if (driver->probe_new)
status = driver->probe_new(client);
else if (driver->probe)
status = driver->probe(client,
i2c_match_id(driver->id_table, client));
else
status = -EINVAL;
Drivers which don't need the second parameter can be declared using
probe_new instead, avoiding the call to i2c_match_id. Drivers which do
can still be converted to probe_new-style, calling i2c_match_id
themselves (as is done currently for of_match_id).
This change was done using the following Coccinelle script, and fixed
up for whitespace changes:
@ rule1 @
identifier fn;
identifier client, id;
@@
- static int fn(struct i2c_client *client, const struct i2c_device_id *id)
+ static int fn(struct i2c_client *client)
{
...when != id
}
@ rule2 depends on rule1 @
identifier rule1.fn;
identifier driver;
@@
struct i2c_driver driver = {
- .probe
+ .probe_new
=
(
fn
|
- &fn
+ fn
)
,
};
Signed-off-by: Stephen Kitt <steve@sk2.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-10-12 18:33:00 +02:00
static int i2c_hid_of_goodix_probe ( struct i2c_client * client )
2021-01-15 09:06:40 -08:00
{
struct i2c_hid_of_goodix * ihid_goodix ;
2021-06-25 08:18:36 -07:00
int ret ;
2021-01-15 09:06:40 -08:00
ihid_goodix = devm_kzalloc ( & client - > dev , sizeof ( * ihid_goodix ) ,
GFP_KERNEL ) ;
if ( ! ihid_goodix )
return - ENOMEM ;
ihid_goodix - > ops . power_up = goodix_i2c_hid_power_up ;
ihid_goodix - > ops . power_down = goodix_i2c_hid_power_down ;
/* Start out with reset asserted */
ihid_goodix - > reset_gpio =
devm_gpiod_get_optional ( & client - > dev , " reset " , GPIOD_OUT_HIGH ) ;
if ( IS_ERR ( ihid_goodix - > reset_gpio ) )
return PTR_ERR ( ihid_goodix - > reset_gpio ) ;
ihid_goodix - > vdd = devm_regulator_get ( & client - > dev , " vdd " ) ;
if ( IS_ERR ( ihid_goodix - > vdd ) )
return PTR_ERR ( ihid_goodix - > vdd ) ;
ihid_goodix - > timings = device_get_match_data ( & client - > dev ) ;
2021-06-25 08:18:36 -07:00
/*
* We need to control the " reset " line in lockstep with the regulator
* actually turning on an off instead of just when we make the request .
* This matters if the regulator is shared with another consumer .
* - If the regulator is off then we must assert reset . The reset
* line is active low and on some boards it could cause a current
* leak if left high .
* - If the regulator is on then we don ' t want reset asserted for very
* long . Holding the controller in reset apparently draws extra
* power .
*/
ihid_goodix - > nb . notifier_call = ihid_goodix_vdd_notify ;
2021-07-20 09:07:49 -07:00
ret = devm_regulator_register_notifier ( ihid_goodix - > vdd , & ihid_goodix - > nb ) ;
2022-01-28 17:46:25 +00:00
if ( ret )
2021-06-25 08:18:36 -07:00
return dev_err_probe ( & client - > dev , ret ,
" regulator notifier request failed \n " ) ;
/*
* If someone else is holding the regulator on ( or the regulator is
* an always - on one ) we might never be told to deassert reset . Do it
2022-01-28 17:46:25 +00:00
* now . . . and temporarily bump the regulator reference count just to
* make sure it is impossible for this to race with our own notifier !
* We also assume that someone else might have _just barely_ turned
* the regulator on so we ' ll do the full " post_power_delay " just in
* case .
2021-06-25 08:18:36 -07:00
*/
2022-01-28 17:46:25 +00:00
if ( ihid_goodix - > reset_gpio & & regulator_is_enabled ( ihid_goodix - > vdd ) ) {
ret = regulator_enable ( ihid_goodix - > vdd ) ;
if ( ret )
return ret ;
2021-06-25 08:18:36 -07:00
goodix_i2c_hid_deassert_reset ( ihid_goodix , true ) ;
2022-01-28 17:46:25 +00:00
regulator_disable ( ihid_goodix - > vdd ) ;
}
2021-06-25 08:18:36 -07:00
2021-12-08 22:40:44 +10:00
return i2c_hid_core_probe ( client , & ihid_goodix - > ops , 0x0001 , 0 ) ;
2021-01-15 09:06:40 -08:00
}
static const struct goodix_i2c_hid_timing_data goodix_gt7375p_timing_data = {
. post_power_delay_ms = 10 ,
. post_gpio_reset_delay_ms = 180 ,
} ;
static const struct of_device_id goodix_i2c_hid_of_match [ ] = {
{ . compatible = " goodix,gt7375p " , . data = & goodix_gt7375p_timing_data } ,
{ }
} ;
MODULE_DEVICE_TABLE ( of , goodix_i2c_hid_of_match ) ;
static struct i2c_driver goodix_i2c_hid_ts_driver = {
. driver = {
. name = " i2c_hid_of_goodix " ,
. pm = & i2c_hid_core_pm ,
. probe_type = PROBE_PREFER_ASYNCHRONOUS ,
. of_match_table = of_match_ptr ( goodix_i2c_hid_of_match ) ,
} ,
HID: i2c: use simple i2c probe
All these drivers have an i2c probe function which doesn't use the
"struct i2c_device_id *id" parameter, so they can trivially be
converted to the "probe_new" style of probe with a single argument.
This is part of an ongoing transition to single-argument i2c probe
functions. Old-style probe functions involve a call to i2c_match_id:
in drivers/i2c/i2c-core-base.c,
/*
* When there are no more users of probe(),
* rename probe_new to probe.
*/
if (driver->probe_new)
status = driver->probe_new(client);
else if (driver->probe)
status = driver->probe(client,
i2c_match_id(driver->id_table, client));
else
status = -EINVAL;
Drivers which don't need the second parameter can be declared using
probe_new instead, avoiding the call to i2c_match_id. Drivers which do
can still be converted to probe_new-style, calling i2c_match_id
themselves (as is done currently for of_match_id).
This change was done using the following Coccinelle script, and fixed
up for whitespace changes:
@ rule1 @
identifier fn;
identifier client, id;
@@
- static int fn(struct i2c_client *client, const struct i2c_device_id *id)
+ static int fn(struct i2c_client *client)
{
...when != id
}
@ rule2 depends on rule1 @
identifier rule1.fn;
identifier driver;
@@
struct i2c_driver driver = {
- .probe
+ .probe_new
=
(
fn
|
- &fn
+ fn
)
,
};
Signed-off-by: Stephen Kitt <steve@sk2.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2022-10-12 18:33:00 +02:00
. probe_new = i2c_hid_of_goodix_probe ,
2021-01-15 09:06:40 -08:00
. remove = i2c_hid_core_remove ,
. shutdown = i2c_hid_core_shutdown ,
} ;
module_i2c_driver ( goodix_i2c_hid_ts_driver ) ;
MODULE_AUTHOR ( " Douglas Anderson <dianders@chromium.org> " ) ;
MODULE_DESCRIPTION ( " Goodix i2c-hid touchscreen driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;