2019-05-29 07:18:02 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2015-09-21 12:55:15 +02:00
/*
* 3 - axis accelerometer driver supporting following I2C Bosch - Sensortec chips :
* - BMC150
* - BMI055
* - BMA255
* - BMA250E
2020-11-15 21:57:44 +01:00
* - BMA222
2015-09-21 12:55:15 +02:00
* - BMA222E
* - BMA280
*
* Copyright ( c ) 2014 , Intel Corporation .
*/
# include <linux/device.h>
# include <linux/mod_devicetable.h>
# include <linux/i2c.h>
# include <linux/module.h>
# include <linux/acpi.h>
# include <linux/regmap.h>
# include "bmc150-accel.h"
static int bmc150_accel_probe ( struct i2c_client * client ,
const struct i2c_device_id * id )
{
struct regmap * regmap ;
const char * name = NULL ;
bool block_supported =
i2c_check_functionality ( client - > adapter , I2C_FUNC_I2C ) | |
i2c_check_functionality ( client - > adapter ,
I2C_FUNC_SMBUS_READ_I2C_BLOCK ) ;
2020-11-30 15:19:53 +01:00
struct acpi_device __maybe_unused * adev ;
int ret ;
2015-09-21 12:55:15 +02:00
2016-03-29 15:21:21 +03:00
regmap = devm_regmap_init_i2c ( client , & bmc150_regmap_conf ) ;
2015-09-21 12:55:15 +02:00
if ( IS_ERR ( regmap ) ) {
dev_err ( & client - > dev , " Failed to initialize i2c regmap \n " ) ;
return PTR_ERR ( regmap ) ;
}
if ( id )
name = id - > name ;
2020-11-30 15:19:53 +01:00
ret = bmc150_accel_core_probe ( & client - > dev , regmap , client - > irq , name , block_supported ) ;
if ( ret )
return ret ;
/*
* Some BOSC0200 acpi_devices describe 2 accelerometers in a single ACPI
* device , try instantiating a second i2c_client for an I2cSerialBusV2
* ACPI resource with index 1. The ! id check avoids recursion when
* bmc150_accel_probe ( ) gets called for the second client .
*/
# ifdef CONFIG_ACPI
adev = ACPI_COMPANION ( & client - > dev ) ;
if ( ! id & & adev & & strcmp ( acpi_device_hid ( adev ) , " BOSC0200 " ) = = 0 ) {
struct i2c_board_info board_info = {
. type = " bmc150_accel " ,
/*
* The 2 nd accel sits in the base of 2 - in - 1 s . Note this
* name is static , as there should never be more then 1
* BOSC0200 ACPI node with 2 accelerometers in it .
*/
. dev_name = " BOSC0200:base " ,
. fwnode = client - > dev . fwnode ,
. irq = - ENOENT ,
} ;
struct i2c_client * second_dev ;
second_dev = i2c_acpi_new_device ( & client - > dev , 1 , & board_info ) ;
if ( ! IS_ERR ( second_dev ) )
bmc150_set_second_device ( second_dev ) ;
}
# endif
return 0 ;
2015-09-21 12:55:15 +02:00
}
static int bmc150_accel_remove ( struct i2c_client * client )
{
2020-11-30 15:19:53 +01:00
struct i2c_client * second_dev = bmc150_get_second_device ( client ) ;
i2c_unregister_device ( second_dev ) ;
2015-09-21 12:55:15 +02:00
return bmc150_accel_core_remove ( & client - > dev ) ;
}
static const struct acpi_device_id bmc150_accel_acpi_match [ ] = {
{ " BSBA0150 " , bmc150 } ,
{ " BMC150A " , bmc150 } ,
{ " BMI055A " , bmi055 } ,
{ " BMA0255 " , bma255 } ,
{ " BMA250E " , bma250e } ,
2020-11-15 21:57:44 +01:00
{ " BMA222 " , bma222 } ,
2015-09-21 12:55:15 +02:00
{ " BMA222E " , bma222e } ,
{ " BMA0280 " , bma280 } ,
2017-06-19 08:22:25 +02:00
{ " BOSC0200 " } ,
2015-09-21 12:55:15 +02:00
{ } ,
} ;
MODULE_DEVICE_TABLE ( acpi , bmc150_accel_acpi_match ) ;
static const struct i2c_device_id bmc150_accel_id [ ] = {
{ " bmc150_accel " , bmc150 } ,
{ " bmi055_accel " , bmi055 } ,
{ " bma255 " , bma255 } ,
{ " bma250e " , bma250e } ,
2020-11-15 21:57:44 +01:00
{ " bma222 " , bma222 } ,
2015-09-21 12:55:15 +02:00
{ " bma222e " , bma222e } ,
{ " bma280 " , bma280 } ,
{ }
} ;
MODULE_DEVICE_TABLE ( i2c , bmc150_accel_id ) ;
2017-12-01 12:10:58 +01:00
static const struct of_device_id bmc150_accel_of_match [ ] = {
{ . compatible = " bosch,bmc150_accel " } ,
{ . compatible = " bosch,bmi055_accel " } ,
{ . compatible = " bosch,bma255 " } ,
{ . compatible = " bosch,bma250e " } ,
2020-11-15 21:57:44 +01:00
{ . compatible = " bosch,bma222 " } ,
2017-12-01 12:10:58 +01:00
{ . compatible = " bosch,bma222e " } ,
{ . compatible = " bosch,bma280 " } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , bmc150_accel_of_match ) ;
2015-09-21 12:55:15 +02:00
static struct i2c_driver bmc150_accel_driver = {
. driver = {
. name = " bmc150_accel_i2c " ,
2017-12-01 12:10:58 +01:00
. of_match_table = bmc150_accel_of_match ,
2015-09-21 12:55:15 +02:00
. acpi_match_table = ACPI_PTR ( bmc150_accel_acpi_match ) ,
. pm = & bmc150_accel_pm_ops ,
} ,
. probe = bmc150_accel_probe ,
. remove = bmc150_accel_remove ,
. id_table = bmc150_accel_id ,
} ;
module_i2c_driver ( bmc150_accel_driver ) ;
MODULE_AUTHOR ( " Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
MODULE_DESCRIPTION ( " BMC150 I2C accelerometer driver " ) ;