1fda8d26eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2217494e5SDenis CIOCCA /* 3217494e5SDenis CIOCCA * STMicroelectronics pressures driver 4217494e5SDenis CIOCCA * 5217494e5SDenis CIOCCA * Copyright 2013 STMicroelectronics Inc. 6217494e5SDenis CIOCCA * 7217494e5SDenis CIOCCA * Denis Ciocca <denis.ciocca@st.com> 8217494e5SDenis CIOCCA */ 9217494e5SDenis CIOCCA 10217494e5SDenis CIOCCA #include <linux/kernel.h> 11217494e5SDenis CIOCCA #include <linux/module.h> 12217494e5SDenis CIOCCA #include <linux/slab.h> 139d317724SShrirang Bagul #include <linux/acpi.h> 14217494e5SDenis CIOCCA #include <linux/i2c.h> 15217494e5SDenis CIOCCA #include <linux/iio/iio.h> 16217494e5SDenis CIOCCA 17217494e5SDenis CIOCCA #include <linux/iio/common/st_sensors.h> 18217494e5SDenis CIOCCA #include <linux/iio/common/st_sensors_i2c.h> 19217494e5SDenis CIOCCA #include "st_pressure.h" 20217494e5SDenis CIOCCA 212d7768a8SLinus Walleij #ifdef CONFIG_OF 222d7768a8SLinus Walleij static const struct of_device_id st_press_of_match[] = { 232d7768a8SLinus Walleij { 242d7768a8SLinus Walleij .compatible = "st,lps001wp-press", 252d7768a8SLinus Walleij .data = LPS001WP_PRESS_DEV_NAME, 262d7768a8SLinus Walleij }, 272d7768a8SLinus Walleij { 282d7768a8SLinus Walleij .compatible = "st,lps25h-press", 292d7768a8SLinus Walleij .data = LPS25H_PRESS_DEV_NAME, 302d7768a8SLinus Walleij }, 312d7768a8SLinus Walleij { 322d7768a8SLinus Walleij .compatible = "st,lps331ap-press", 332d7768a8SLinus Walleij .data = LPS331AP_PRESS_DEV_NAME, 342d7768a8SLinus Walleij }, 35e039e2f5SGregor Boirie { 36e039e2f5SGregor Boirie .compatible = "st,lps22hb-press", 37e039e2f5SGregor Boirie .data = LPS22HB_PRESS_DEV_NAME, 38e039e2f5SGregor Boirie }, 39b954d77aSLorenzo Bianconi { 40b954d77aSLorenzo Bianconi .compatible = "st,lps33hw", 41b954d77aSLorenzo Bianconi .data = LPS33HW_PRESS_DEV_NAME, 42b954d77aSLorenzo Bianconi }, 43b954d77aSLorenzo Bianconi { 44b954d77aSLorenzo Bianconi .compatible = "st,lps35hw", 45b954d77aSLorenzo Bianconi .data = LPS35HW_PRESS_DEV_NAME, 46b954d77aSLorenzo Bianconi }, 47e5aab7b0Smario tesi { 48e5aab7b0Smario tesi .compatible = "st,lps22hh", 49e5aab7b0Smario tesi .data = LPS22HH_PRESS_DEV_NAME, 50e5aab7b0Smario tesi }, 512d7768a8SLinus Walleij {}, 522d7768a8SLinus Walleij }; 532d7768a8SLinus Walleij MODULE_DEVICE_TABLE(of, st_press_of_match); 542d7768a8SLinus Walleij #else 552d7768a8SLinus Walleij #define st_press_of_match NULL 562d7768a8SLinus Walleij #endif 572d7768a8SLinus Walleij 589d317724SShrirang Bagul #ifdef CONFIG_ACPI 599d317724SShrirang Bagul static const struct acpi_device_id st_press_acpi_match[] = { 609d317724SShrirang Bagul {"SNO9210", LPS22HB}, 619d317724SShrirang Bagul { }, 629d317724SShrirang Bagul }; 639d317724SShrirang Bagul MODULE_DEVICE_TABLE(acpi, st_press_acpi_match); 649d317724SShrirang Bagul #else 659d317724SShrirang Bagul #define st_press_acpi_match NULL 669d317724SShrirang Bagul #endif 679d317724SShrirang Bagul 689d317724SShrirang Bagul static const struct i2c_device_id st_press_id_table[] = { 699d317724SShrirang Bagul { LPS001WP_PRESS_DEV_NAME, LPS001WP }, 709d317724SShrirang Bagul { LPS25H_PRESS_DEV_NAME, LPS25H }, 719d317724SShrirang Bagul { LPS331AP_PRESS_DEV_NAME, LPS331AP }, 729d317724SShrirang Bagul { LPS22HB_PRESS_DEV_NAME, LPS22HB }, 73b954d77aSLorenzo Bianconi { LPS33HW_PRESS_DEV_NAME, LPS33HW }, 74b954d77aSLorenzo Bianconi { LPS35HW_PRESS_DEV_NAME, LPS35HW }, 75e5aab7b0Smario tesi { LPS22HH_PRESS_DEV_NAME, LPS22HH }, 769d317724SShrirang Bagul {}, 779d317724SShrirang Bagul }; 789d317724SShrirang Bagul MODULE_DEVICE_TABLE(i2c, st_press_id_table); 799d317724SShrirang Bagul 80217494e5SDenis CIOCCA static int st_press_i2c_probe(struct i2c_client *client, 81217494e5SDenis CIOCCA const struct i2c_device_id *id) 82217494e5SDenis CIOCCA { 83*570c2c55SDenis Ciocca const struct st_sensor_settings *settings; 84a1dcf429SDenis CIOCCA struct st_sensor_data *press_data; 85*570c2c55SDenis Ciocca struct iio_dev *indio_dev; 869d317724SShrirang Bagul int ret; 87217494e5SDenis CIOCCA 889d317724SShrirang Bagul if (client->dev.of_node) { 89250bbbdbSLorenzo Bianconi st_sensors_of_name_probe(&client->dev, st_press_of_match, 90250bbbdbSLorenzo Bianconi client->name, sizeof(client->name)); 919d317724SShrirang Bagul } else if (ACPI_HANDLE(&client->dev)) { 929d317724SShrirang Bagul ret = st_sensors_match_acpi_device(&client->dev); 939d317724SShrirang Bagul if ((ret < 0) || (ret >= ST_PRESS_MAX)) 949d317724SShrirang Bagul return -ENODEV; 959d317724SShrirang Bagul 96cd570e6fSDominique Martinet strlcpy(client->name, st_press_id_table[ret].name, 979d317724SShrirang Bagul sizeof(client->name)); 989d317724SShrirang Bagul } else if (!id) 999d317724SShrirang Bagul return -ENODEV; 100217494e5SDenis CIOCCA 101*570c2c55SDenis Ciocca settings = st_press_get_settings(client->name); 102*570c2c55SDenis Ciocca if (!settings) { 103*570c2c55SDenis Ciocca dev_err(&client->dev, "device name %s not recognized.\n", 104*570c2c55SDenis Ciocca client->name); 105*570c2c55SDenis Ciocca return -ENODEV; 106*570c2c55SDenis Ciocca } 107*570c2c55SDenis Ciocca 108*570c2c55SDenis Ciocca indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*press_data)); 109*570c2c55SDenis Ciocca if (!indio_dev) 110*570c2c55SDenis Ciocca return -ENOMEM; 111*570c2c55SDenis Ciocca 112*570c2c55SDenis Ciocca press_data = iio_priv(indio_dev); 113*570c2c55SDenis Ciocca press_data->sensor_settings = (struct st_sensor_settings *)settings; 114*570c2c55SDenis Ciocca 115a1dcf429SDenis CIOCCA st_sensors_i2c_configure(indio_dev, client, press_data); 116217494e5SDenis CIOCCA 1179d317724SShrirang Bagul ret = st_press_common_probe(indio_dev); 1189d317724SShrirang Bagul if (ret < 0) 1199d317724SShrirang Bagul return ret; 120217494e5SDenis CIOCCA 121217494e5SDenis CIOCCA return 0; 122217494e5SDenis CIOCCA } 123217494e5SDenis CIOCCA 124217494e5SDenis CIOCCA static int st_press_i2c_remove(struct i2c_client *client) 125217494e5SDenis CIOCCA { 126217494e5SDenis CIOCCA st_press_common_remove(i2c_get_clientdata(client)); 127217494e5SDenis CIOCCA 128217494e5SDenis CIOCCA return 0; 129217494e5SDenis CIOCCA } 130217494e5SDenis CIOCCA 131217494e5SDenis CIOCCA static struct i2c_driver st_press_driver = { 132217494e5SDenis CIOCCA .driver = { 133217494e5SDenis CIOCCA .name = "st-press-i2c", 1342d7768a8SLinus Walleij .of_match_table = of_match_ptr(st_press_of_match), 1359d317724SShrirang Bagul .acpi_match_table = ACPI_PTR(st_press_acpi_match), 136217494e5SDenis CIOCCA }, 137217494e5SDenis CIOCCA .probe = st_press_i2c_probe, 138217494e5SDenis CIOCCA .remove = st_press_i2c_remove, 139217494e5SDenis CIOCCA .id_table = st_press_id_table, 140217494e5SDenis CIOCCA }; 141217494e5SDenis CIOCCA module_i2c_driver(st_press_driver); 142217494e5SDenis CIOCCA 143217494e5SDenis CIOCCA MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 144217494e5SDenis CIOCCA MODULE_DESCRIPTION("STMicroelectronics pressures i2c driver"); 145217494e5SDenis CIOCCA MODULE_LICENSE("GPL v2"); 146