| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * STMicroelectronics pressures driver |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright 2013 STMicroelectronics Inc. |
|---|
| 5 | 6 | * |
|---|
| 6 | 7 | * Denis Ciocca <denis.ciocca@st.com> |
|---|
| 7 | | - * |
|---|
| 8 | | - * Licensed under the GPL-2. |
|---|
| 9 | 8 | */ |
|---|
| 10 | 9 | |
|---|
| 11 | 10 | #include <linux/kernel.h> |
|---|
| 12 | 11 | #include <linux/module.h> |
|---|
| 13 | 12 | #include <linux/slab.h> |
|---|
| 14 | | -#include <linux/acpi.h> |
|---|
| 15 | 13 | #include <linux/i2c.h> |
|---|
| 16 | 14 | #include <linux/iio/iio.h> |
|---|
| 17 | 15 | |
|---|
| .. | .. |
|---|
| 19 | 17 | #include <linux/iio/common/st_sensors_i2c.h> |
|---|
| 20 | 18 | #include "st_pressure.h" |
|---|
| 21 | 19 | |
|---|
| 22 | | -#ifdef CONFIG_OF |
|---|
| 23 | 20 | static const struct of_device_id st_press_of_match[] = { |
|---|
| 24 | 21 | { |
|---|
| 25 | 22 | .compatible = "st,lps001wp-press", |
|---|
| .. | .. |
|---|
| 45 | 42 | .compatible = "st,lps35hw", |
|---|
| 46 | 43 | .data = LPS35HW_PRESS_DEV_NAME, |
|---|
| 47 | 44 | }, |
|---|
| 45 | + { |
|---|
| 46 | + .compatible = "st,lps22hh", |
|---|
| 47 | + .data = LPS22HH_PRESS_DEV_NAME, |
|---|
| 48 | + }, |
|---|
| 48 | 49 | {}, |
|---|
| 49 | 50 | }; |
|---|
| 50 | 51 | MODULE_DEVICE_TABLE(of, st_press_of_match); |
|---|
| 51 | | -#else |
|---|
| 52 | | -#define st_press_of_match NULL |
|---|
| 53 | | -#endif |
|---|
| 54 | 52 | |
|---|
| 55 | 53 | #ifdef CONFIG_ACPI |
|---|
| 56 | 54 | static const struct acpi_device_id st_press_acpi_match[] = { |
|---|
| .. | .. |
|---|
| 58 | 56 | { }, |
|---|
| 59 | 57 | }; |
|---|
| 60 | 58 | MODULE_DEVICE_TABLE(acpi, st_press_acpi_match); |
|---|
| 61 | | -#else |
|---|
| 62 | | -#define st_press_acpi_match NULL |
|---|
| 63 | 59 | #endif |
|---|
| 64 | 60 | |
|---|
| 65 | 61 | static const struct i2c_device_id st_press_id_table[] = { |
|---|
| .. | .. |
|---|
| 69 | 65 | { LPS22HB_PRESS_DEV_NAME, LPS22HB }, |
|---|
| 70 | 66 | { LPS33HW_PRESS_DEV_NAME, LPS33HW }, |
|---|
| 71 | 67 | { LPS35HW_PRESS_DEV_NAME, LPS35HW }, |
|---|
| 68 | + { LPS22HH_PRESS_DEV_NAME, LPS22HH }, |
|---|
| 72 | 69 | {}, |
|---|
| 73 | 70 | }; |
|---|
| 74 | 71 | MODULE_DEVICE_TABLE(i2c, st_press_id_table); |
|---|
| 75 | 72 | |
|---|
| 76 | 73 | static int st_press_i2c_probe(struct i2c_client *client, |
|---|
| 77 | | - const struct i2c_device_id *id) |
|---|
| 74 | + const struct i2c_device_id *id) |
|---|
| 78 | 75 | { |
|---|
| 79 | | - struct iio_dev *indio_dev; |
|---|
| 76 | + const struct st_sensor_settings *settings; |
|---|
| 80 | 77 | struct st_sensor_data *press_data; |
|---|
| 78 | + struct iio_dev *indio_dev; |
|---|
| 81 | 79 | int ret; |
|---|
| 80 | + |
|---|
| 81 | + st_sensors_dev_name_probe(&client->dev, client->name, sizeof(client->name)); |
|---|
| 82 | + |
|---|
| 83 | + settings = st_press_get_settings(client->name); |
|---|
| 84 | + if (!settings) { |
|---|
| 85 | + dev_err(&client->dev, "device name %s not recognized.\n", |
|---|
| 86 | + client->name); |
|---|
| 87 | + return -ENODEV; |
|---|
| 88 | + } |
|---|
| 82 | 89 | |
|---|
| 83 | 90 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*press_data)); |
|---|
| 84 | 91 | if (!indio_dev) |
|---|
| 85 | 92 | return -ENOMEM; |
|---|
| 86 | 93 | |
|---|
| 87 | 94 | press_data = iio_priv(indio_dev); |
|---|
| 95 | + press_data->sensor_settings = (struct st_sensor_settings *)settings; |
|---|
| 88 | 96 | |
|---|
| 89 | | - if (client->dev.of_node) { |
|---|
| 90 | | - st_sensors_of_name_probe(&client->dev, st_press_of_match, |
|---|
| 91 | | - client->name, sizeof(client->name)); |
|---|
| 92 | | - } else if (ACPI_HANDLE(&client->dev)) { |
|---|
| 93 | | - ret = st_sensors_match_acpi_device(&client->dev); |
|---|
| 94 | | - if ((ret < 0) || (ret >= ST_PRESS_MAX)) |
|---|
| 95 | | - return -ENODEV; |
|---|
| 96 | | - |
|---|
| 97 | | - strlcpy(client->name, st_press_id_table[ret].name, |
|---|
| 98 | | - sizeof(client->name)); |
|---|
| 99 | | - } else if (!id) |
|---|
| 100 | | - return -ENODEV; |
|---|
| 101 | | - |
|---|
| 102 | | - st_sensors_i2c_configure(indio_dev, client, press_data); |
|---|
| 103 | | - |
|---|
| 104 | | - ret = st_press_common_probe(indio_dev); |
|---|
| 97 | + ret = st_sensors_i2c_configure(indio_dev, client); |
|---|
| 105 | 98 | if (ret < 0) |
|---|
| 106 | 99 | return ret; |
|---|
| 107 | 100 | |
|---|
| 101 | + ret = st_sensors_power_enable(indio_dev); |
|---|
| 102 | + if (ret) |
|---|
| 103 | + return ret; |
|---|
| 104 | + |
|---|
| 105 | + ret = st_press_common_probe(indio_dev); |
|---|
| 106 | + if (ret < 0) |
|---|
| 107 | + goto st_press_power_off; |
|---|
| 108 | + |
|---|
| 108 | 109 | return 0; |
|---|
| 110 | + |
|---|
| 111 | +st_press_power_off: |
|---|
| 112 | + st_sensors_power_disable(indio_dev); |
|---|
| 113 | + |
|---|
| 114 | + return ret; |
|---|
| 109 | 115 | } |
|---|
| 110 | 116 | |
|---|
| 111 | 117 | static int st_press_i2c_remove(struct i2c_client *client) |
|---|
| 112 | 118 | { |
|---|
| 113 | | - st_press_common_remove(i2c_get_clientdata(client)); |
|---|
| 119 | + struct iio_dev *indio_dev = i2c_get_clientdata(client); |
|---|
| 120 | + |
|---|
| 121 | + st_press_common_remove(indio_dev); |
|---|
| 122 | + |
|---|
| 123 | + st_sensors_power_disable(indio_dev); |
|---|
| 114 | 124 | |
|---|
| 115 | 125 | return 0; |
|---|
| 116 | 126 | } |
|---|
| .. | .. |
|---|
| 118 | 128 | static struct i2c_driver st_press_driver = { |
|---|
| 119 | 129 | .driver = { |
|---|
| 120 | 130 | .name = "st-press-i2c", |
|---|
| 121 | | - .of_match_table = of_match_ptr(st_press_of_match), |
|---|
| 131 | + .of_match_table = st_press_of_match, |
|---|
| 122 | 132 | .acpi_match_table = ACPI_PTR(st_press_acpi_match), |
|---|
| 123 | 133 | }, |
|---|
| 124 | 134 | .probe = st_press_i2c_probe, |
|---|