2019-06-04 11:10:57 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2011-11-17 09:32:20 +04:00
/*
* ST Microelectronics MFD : stmpe ' s i2c client specific driver
*
* Copyright ( C ) ST - Ericsson SA 2010
* Copyright ( C ) ST Microelectronics SA 2011
*
* Author : Rabin Vincent < rabin . vincent @ stericsson . com > for ST - Ericsson
2015-07-18 02:23:50 +03:00
* Author : Viresh Kumar < vireshk @ kernel . org > for ST Microelectronics
2011-11-17 09:32:20 +04:00
*/
# include <linux/i2c.h>
# include <linux/interrupt.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/types.h>
2014-04-24 01:35:58 +04:00
# include <linux/of_device.h>
2011-11-17 09:32:20 +04:00
# include "stmpe.h"
static int i2c_reg_read ( struct stmpe * stmpe , u8 reg )
{
struct i2c_client * i2c = stmpe - > client ;
return i2c_smbus_read_byte_data ( i2c , reg ) ;
}
static int i2c_reg_write ( struct stmpe * stmpe , u8 reg , u8 val )
{
struct i2c_client * i2c = stmpe - > client ;
return i2c_smbus_write_byte_data ( i2c , reg , val ) ;
}
static int i2c_block_read ( struct stmpe * stmpe , u8 reg , u8 length , u8 * values )
{
struct i2c_client * i2c = stmpe - > client ;
return i2c_smbus_read_i2c_block_data ( i2c , reg , length , values ) ;
}
static int i2c_block_write ( struct stmpe * stmpe , u8 reg , u8 length ,
const u8 * values )
{
struct i2c_client * i2c = stmpe - > client ;
return i2c_smbus_write_i2c_block_data ( i2c , reg , length , values ) ;
}
static struct stmpe_client_info i2c_ci = {
. read_byte = i2c_reg_read ,
. write_byte = i2c_reg_write ,
. read_block = i2c_block_read ,
. write_block = i2c_block_write ,
} ;
2014-04-24 01:35:58 +04:00
static const struct of_device_id stmpe_of_match [ ] = {
{ . compatible = " st,stmpe610 " , . data = ( void * ) STMPE610 , } ,
{ . compatible = " st,stmpe801 " , . data = ( void * ) STMPE801 , } ,
{ . compatible = " st,stmpe811 " , . data = ( void * ) STMPE811 , } ,
2016-08-10 10:39:14 +03:00
{ . compatible = " st,stmpe1600 " , . data = ( void * ) STMPE1600 , } ,
2014-04-24 01:35:58 +04:00
{ . compatible = " st,stmpe1601 " , . data = ( void * ) STMPE1601 , } ,
{ . compatible = " st,stmpe1801 " , . data = ( void * ) STMPE1801 , } ,
{ . compatible = " st,stmpe2401 " , . data = ( void * ) STMPE2401 , } ,
{ . compatible = " st,stmpe2403 " , . data = ( void * ) STMPE2403 , } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , stmpe_of_match ) ;
2012-11-19 22:23:04 +04:00
static int
2022-11-19 01:43:15 +03:00
stmpe_i2c_probe ( struct i2c_client * i2c )
2011-11-17 09:32:20 +04:00
{
2022-11-19 01:43:15 +03:00
const struct i2c_device_id * id = i2c_client_get_device_id ( i2c ) ;
2014-07-02 14:54:32 +04:00
enum stmpe_partnum partnum ;
2014-04-24 01:35:58 +04:00
const struct of_device_id * of_id ;
2011-11-17 09:32:20 +04:00
i2c_ci . data = ( void * ) id ;
i2c_ci . irq = i2c - > irq ;
i2c_ci . client = i2c ;
i2c_ci . dev = & i2c - > dev ;
2014-04-24 01:35:58 +04:00
of_id = of_match_device ( stmpe_of_match , & i2c - > dev ) ;
if ( ! of_id ) {
/*
* This happens when the I2C ID matches the node name
* but no real compatible string has been given .
*/
dev_info ( & i2c - > dev , " matching on node name, compatible is preferred \n " ) ;
partnum = id - > driver_data ;
} else
2014-07-02 14:54:32 +04:00
partnum = ( enum stmpe_partnum ) of_id - > data ;
2014-04-24 01:35:58 +04:00
return stmpe_probe ( & i2c_ci , partnum ) ;
2011-11-17 09:32:20 +04:00
}
2022-08-15 11:02:30 +03:00
static void stmpe_i2c_remove ( struct i2c_client * i2c )
2011-11-17 09:32:20 +04:00
{
struct stmpe * stmpe = dev_get_drvdata ( & i2c - > dev ) ;
2021-10-12 18:39:34 +03:00
stmpe_remove ( stmpe ) ;
2011-11-17 09:32:20 +04:00
}
static const struct i2c_device_id stmpe_i2c_id [ ] = {
2011-11-17 09:32:22 +04:00
{ " stmpe610 " , STMPE610 } ,
2011-11-17 09:32:23 +04:00
{ " stmpe801 " , STMPE801 } ,
2011-11-17 09:32:20 +04:00
{ " stmpe811 " , STMPE811 } ,
2016-08-10 10:39:14 +03:00
{ " stmpe1600 " , STMPE1600 } ,
2011-11-17 09:32:20 +04:00
{ " stmpe1601 " , STMPE1601 } ,
2013-04-09 12:35:19 +04:00
{ " stmpe1801 " , STMPE1801 } ,
2011-11-17 09:32:20 +04:00
{ " stmpe2401 " , STMPE2401 } ,
{ " stmpe2403 " , STMPE2403 } ,
{ }
} ;
2021-05-12 09:33:46 +03:00
MODULE_DEVICE_TABLE ( i2c , stmpe_i2c_id ) ;
2011-11-17 09:32:20 +04:00
static struct i2c_driver stmpe_i2c_driver = {
2012-11-22 22:56:19 +04:00
. driver = {
. name = " stmpe-i2c " ,
2011-11-17 09:32:20 +04:00
# ifdef CONFIG_PM
2012-11-22 22:56:19 +04:00
. pm = & stmpe_dev_pm_ops ,
2011-11-17 09:32:20 +04:00
# endif
2014-04-24 01:35:58 +04:00
. of_match_table = stmpe_of_match ,
2012-11-22 22:56:19 +04:00
} ,
2022-11-19 01:43:15 +03:00
. probe_new = stmpe_i2c_probe ,
2012-11-19 22:20:24 +04:00
. remove = stmpe_i2c_remove ,
2011-11-17 09:32:20 +04:00
. id_table = stmpe_i2c_id ,
} ;
static int __init stmpe_init ( void )
{
return i2c_add_driver ( & stmpe_i2c_driver ) ;
}
subsys_initcall ( stmpe_init ) ;
static void __exit stmpe_exit ( void )
{
i2c_del_driver ( & stmpe_i2c_driver ) ;
}
module_exit ( stmpe_exit ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_DESCRIPTION ( " STMPE MFD I2C Interface Driver " ) ;
MODULE_AUTHOR ( " Rabin Vincent <rabin.vincent@stericsson.com> " ) ;