From 542664420cc0aeaa1851f019db335232c304130c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Jirman?= Date: Wed, 9 Feb 2022 23:32:07 +0100 Subject: [PATCH 335/389] iio: af8133j: Cleanup probe and power up/down This prepares the driver for runtime PM and sleep implementation. Signed-off-by: Ondrej Jirman --- drivers/iio/magnetometer/af8133j.c | 165 +++++++++++++---------------- 1 file changed, 73 insertions(+), 92 deletions(-) diff --git a/drivers/iio/magnetometer/af8133j.c b/drivers/iio/magnetometer/af8133j.c index 2aa7cb03148c..3ec4a405cc8e 100644 --- a/drivers/iio/magnetometer/af8133j.c +++ b/drivers/iio/magnetometer/af8133j.c @@ -4,8 +4,6 @@ * * Based on mmc35240.c, which is: * Copyright (c) 2015, Intel Corporation. - * - * TODO: */ #include @@ -19,7 +17,6 @@ #include #define AF8133J_DRV_NAME "af8133j" -#define AF8133J_REGMAP_NAME "af8133j_regmap" #define AF8133J_REG_OUT 0x03 /* Little endian */ @@ -42,15 +39,21 @@ #define AF8133J_REG_SWR 0x11 #define AF8133J_REG_SWR_PERFORM BIT(0) +static const char * const af8133j_supply_names[] = { + "avdd", + "dvdd", +}; + +#define AF8133J_NUM_SUPPLIES ARRAY_SIZE(af8133j_supply_names) + struct af8133j_data { struct i2c_client *client; struct regmap *regmap; struct mutex mutex; struct gpio_desc *reset_gpiod; - struct regulator *avdd; - struct regulator *dvdd; struct iio_mount_matrix orientation; + struct regulator_bulk_data supplies[AF8133J_NUM_SUPPLIES]; }; enum af8133j_axis { @@ -88,28 +91,42 @@ static const struct iio_chan_spec af8133j_channels[] = { AF8133J_CHANNEL(Z), }; -static int af8133j_init(struct af8133j_data *data) +static int af8133j_power_up(struct af8133j_data *data) { + struct device *dev = &data->client->dev; unsigned int val; int ret; + ret = regulator_bulk_enable(AF8133J_NUM_SUPPLIES, data->supplies); + if (ret) { + dev_err(dev, "Could not enable regulators\n"); + return ret; + } + + msleep(15); + + gpiod_set_value_cansleep(data->reset_gpiod, 0); + + msleep(1); + ret = regmap_read(data->regmap, AF8133J_REG_PCODE, &val); if (ret < 0) { - dev_err(&data->client->dev, "Error reading product code\n"); - return ret; + dev_err(dev, "Error reading product code\n"); + goto out_assert_reset; } if (val != AF8133J_REG_PCODE_VAL) { - dev_warn(&data->client->dev, - "Unknown AF8133J product code %x\n", val); + dev_err(dev, "Unknown AF8133J product code 0x%x\n", val); + ret = -EINVAL; + goto out_assert_reset; } /* Reset the chip */ ret = regmap_write(data->regmap, AF8133J_REG_SWR, AF8133J_REG_SWR_PERFORM); if (ret < 0) { - dev_err(&data->client->dev, "Failed to write regmap\n"); - return ret; + dev_err(dev, "Failed to reset the chip\n"); + goto out_assert_reset; } /* Wait for reset finish */ @@ -118,17 +135,27 @@ static int af8133j_init(struct af8133j_data *data) /* Check whether the reset bit is cleared */ ret = regmap_read(data->regmap, AF8133J_REG_SWR, &val); if (ret < 0) { - dev_err(&data->client->dev, "Failed to read regmap\n"); - return ret; + dev_err(dev, "Failed to read reset status\n"); + goto out_assert_reset; } if (val & AF8133J_REG_SWR_PERFORM) { - dev_err(&data->client->dev, "Device is not responding\n"); - return -EIO; + dev_err(dev, "Device is not responding to reset\n"); + ret = -EIO; + goto out_assert_reset; } - /* The reset value should satisfy us now. */ - return 0; + +out_assert_reset: + gpiod_set_value_cansleep(data->reset_gpiod, 1); + regulator_bulk_disable(AF8133J_NUM_SUPPLIES, data->supplies); + return ret; +} + +static void af8133j_power_down(struct af8133j_data *data) +{ + gpiod_set_value_cansleep(data->reset_gpiod, 1); + regulator_bulk_disable(AF8133J_NUM_SUPPLIES, data->supplies); } static int af8133j_take_measurement(struct af8133j_data *data) @@ -200,7 +227,7 @@ static const struct iio_info af8133j_info = { }; static const struct regmap_config af8133j_regmap_config = { - .name = AF8133J_REGMAP_NAME, + .name = "af8133j_regmap", .reg_bits = 8, .val_bits = 8, @@ -215,49 +242,43 @@ static int af8133j_probe(struct i2c_client *client, struct af8133j_data *data; struct iio_dev *indio_dev; struct regmap *regmap; - int ret; + int ret, i; indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; regmap = devm_regmap_init_i2c(client, &af8133j_regmap_config); - if (IS_ERR(regmap)) { - dev_err(&client->dev, "regmap initialization failed\n"); - return PTR_ERR(regmap); - } + if (IS_ERR(regmap)) + return dev_err_probe(&client->dev, PTR_ERR(regmap), + "regmap initialization failed\n"); data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); data->client = client; data->regmap = regmap; + mutex_init(&data->mutex); - data->reset_gpiod = devm_gpiod_get(&client->dev, "reset", - GPIOD_OUT_HIGH); - if (IS_ERR(data->reset_gpiod)) { - dev_err(&client->dev, "Got error while retrieving reset gpio\n"); - ret = PTR_ERR(data->reset_gpiod); - goto out_release_reset_gpio; - } - - data->avdd = devm_regulator_get(&client->dev, "avdd"); - if (IS_ERR(data->avdd)) { - dev_err(&client->dev, "Got error while retrieving avdd reg\n"); - ret = PTR_ERR(data->avdd); - goto out_release_reset_gpio; - } + data->reset_gpiod = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(data->reset_gpiod)) + return dev_err_probe(&client->dev, PTR_ERR(data->reset_gpiod), + "Failed to get reset gpio\n"); - data->dvdd = devm_regulator_get(&client->dev, "dvdd"); - if (IS_ERR(data->dvdd)) { - dev_err(&client->dev, "Got error while retrieving dvdd reg\n"); - ret = PTR_ERR(data->dvdd); - goto out_release_reset_gpio; - } + for (i = 0; i < AF8133J_NUM_SUPPLIES; i++) + data->supplies[i].supply = af8133j_supply_names[i]; + ret = devm_regulator_bulk_get(&client->dev, AF8133J_NUM_SUPPLIES, data->supplies); + if (ret) + return ret; - mutex_init(&data->mutex); + ret = iio_read_mount_matrix(&client->dev, &data->orientation); + if (ret) + return dev_err_probe(&client->dev, ret, + "Failed to read mount matrix\n"); - ret = iio_read_mount_matrix(&client->dev, "mount-matrix", - &data->orientation); + /* + * Check if the device is responding. + */ + ret = af8133j_power_up(data); if (ret) return ret; @@ -267,60 +288,20 @@ static int af8133j_probe(struct i2c_client *client, indio_dev->num_channels = ARRAY_SIZE(af8133j_channels); indio_dev->modes = INDIO_DIRECT_MODE; - /* Power sequence */ - ret = regulator_enable(data->avdd); - if (ret) { - dev_err(&client->dev, "Failed to enable avdd regulator"); - goto out_release_reset_gpio; - } - - ret = regulator_enable(data->dvdd); - if (ret) { - dev_err(&client->dev, "Failed to enable dvdd regulator"); - goto out_disable_avdd; - } - - msleep(15); - - gpiod_set_value_cansleep(data->reset_gpiod, 0); - - msleep(1); - - ret = af8133j_init(data); - if (ret) { - dev_err(&client->dev, "Failed to init af8133j"); - goto out_assert_reset; - } - ret = devm_iio_device_register(&client->dev, indio_dev); - if (ret) { - dev_err(&client->dev, "Failed to register iio device"); - goto out_assert_reset; - } + if (ret) + return dev_err_probe(&client->dev, ret, + "Failed to register iio device"); return 0; - -out_assert_reset: - gpiod_set_value_cansleep(data->reset_gpiod, 1); - regulator_disable(data->dvdd); -out_disable_avdd: - regulator_disable(data->avdd); -out_release_reset_gpio: - gpiod_direction_input(data->reset_gpiod); - - return ret; } -static int af8133j_remove(struct i2c_client *client) +static void af8133j_remove(struct i2c_client *client) { struct iio_dev *indio_dev = i2c_get_clientdata(client); struct af8133j_data *data = iio_priv(indio_dev); - gpiod_set_value_cansleep(data->reset_gpiod, 0); - regulator_disable(data->dvdd); - regulator_disable(data->avdd); - - return 0; + af8133j_power_down(data); } static const struct of_device_id af8133j_of_match[] = { -- 2.35.3