From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/staging/iio/impedance-analyzer/ad5933.c | 187 ++++++++++++++++++++++++----------------------
1 files changed, 96 insertions(+), 91 deletions(-)
diff --git a/kernel/drivers/staging/iio/impedance-analyzer/ad5933.c b/kernel/drivers/staging/iio/impedance-analyzer/ad5933.c
index 14df895..dba7889 100644
--- a/kernel/drivers/staging/iio/impedance-analyzer/ad5933.c
+++ b/kernel/drivers/staging/iio/impedance-analyzer/ad5933.c
@@ -1,26 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* AD5933 AD5934 Impedance Converter, Network Analyzer
*
* Copyright 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2.
*/
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/sysfs.h>
-#include <linux/i2c.h>
-#include <linux/regulator/consumer.h>
-#include <linux/types.h>
-#include <linux/err.h>
+#include <linux/clk.h>
#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
#include <linux/iio/kfifo_buf.h>
+#include <linux/iio/sysfs.h>
/* AD5933/AD5934 Registers */
#define AD5933_REG_CONTROL_HB 0x80 /* R/W, 1 byte */
@@ -82,21 +82,10 @@
#define AD5933_POLL_TIME_ms 10
#define AD5933_INIT_EXCITATION_TIME_ms 100
-/**
- * struct ad5933_platform_data - platform specific data
- * @ext_clk_Hz: the external clock frequency in Hz, if not set
- * the driver uses the internal clock (16.776 MHz)
- * @vref_mv: the external reference voltage in millivolt
- */
-
-struct ad5933_platform_data {
- unsigned long ext_clk_Hz;
- unsigned short vref_mv;
-};
-
struct ad5933_state {
struct i2c_client *client;
struct regulator *reg;
+ struct clk *mclk;
struct delayed_work work;
struct mutex lock; /* Protect sensor state */
unsigned long mclk_hz;
@@ -110,10 +99,6 @@
unsigned int freq_inc;
unsigned int state;
unsigned int poll_time_jiffies;
-};
-
-static struct ad5933_platform_data ad5933_default_pdata = {
- .vref_mv = 3300,
};
#define AD5933_CHANNEL(_type, _extend_name, _info_mask_separate, _address, \
@@ -210,7 +195,7 @@
u8 d8[4];
} dat;
- freqreg = (u64) freq * (u64) (1 << 27);
+ freqreg = (u64)freq * (u64)(1 << 27);
do_div(freqreg, st->mclk_hz / 4);
switch (reg) {
@@ -267,7 +252,6 @@
for (i = 0; i < 4; i++)
st->range_avail[i] = normalized_3v3[i] * st->vref_mv / 3300;
-
}
/*
@@ -299,7 +283,7 @@
freqreg = be32_to_cpu(dat.d32) & 0xFFFFFF;
freqreg = (u64)freqreg * (u64)(st->mclk_hz / 4);
- do_div(freqreg, 1 << 27);
+ do_div(freqreg, BIT(27));
return sprintf(buf, "%d\n", (int)freqreg);
}
@@ -331,12 +315,12 @@
return ret ? ret : len;
}
-static IIO_DEVICE_ATTR(out_voltage0_freq_start, 0644,
+static IIO_DEVICE_ATTR(out_altvoltage0_frequency_start, 0644,
ad5933_show_frequency,
ad5933_store_frequency,
AD5933_REG_FREQ_START);
-static IIO_DEVICE_ATTR(out_voltage0_freq_increment, 0644,
+static IIO_DEVICE_ATTR(out_altvoltage0_frequency_increment, 0644,
ad5933_show_frequency,
ad5933_store_frequency,
AD5933_REG_FREQ_INC);
@@ -435,7 +419,7 @@
if (val > 1022)
val = (val >> 2) | (3 << 9);
else if (val > 511)
- val = (val >> 1) | (1 << 9);
+ val = (val >> 1) | BIT(9);
dat = cpu_to_be16(val);
ret = ad5933_i2c_write(st->client,
@@ -459,12 +443,12 @@
return ret ? ret : len;
}
-static IIO_DEVICE_ATTR(out_voltage0_scale, 0644,
+static IIO_DEVICE_ATTR(out_altvoltage0_raw, 0644,
ad5933_show,
ad5933_store,
AD5933_OUT_RANGE);
-static IIO_DEVICE_ATTR(out_voltage0_scale_available, 0444,
+static IIO_DEVICE_ATTR(out_altvoltage0_scale_available, 0444,
ad5933_show,
NULL,
AD5933_OUT_RANGE_AVAIL);
@@ -479,28 +463,29 @@
NULL,
AD5933_IN_PGA_GAIN_AVAIL);
-static IIO_DEVICE_ATTR(out_voltage0_freq_points, 0644,
+static IIO_DEVICE_ATTR(out_altvoltage0_frequency_points, 0644,
ad5933_show,
ad5933_store,
AD5933_FREQ_POINTS);
-static IIO_DEVICE_ATTR(out_voltage0_settling_cycles, 0644,
+static IIO_DEVICE_ATTR(out_altvoltage0_settling_cycles, 0644,
ad5933_show,
ad5933_store,
AD5933_OUT_SETTLING_CYCLES);
-/* note:
+/*
+ * note:
* ideally we would handle the scale attributes via the iio_info
* (read|write)_raw methods, however this part is a untypical since we
* don't create dedicated sysfs channel attributes for out0 and in0.
*/
static struct attribute *ad5933_attributes[] = {
- &iio_dev_attr_out_voltage0_scale.dev_attr.attr,
- &iio_dev_attr_out_voltage0_scale_available.dev_attr.attr,
- &iio_dev_attr_out_voltage0_freq_start.dev_attr.attr,
- &iio_dev_attr_out_voltage0_freq_increment.dev_attr.attr,
- &iio_dev_attr_out_voltage0_freq_points.dev_attr.attr,
- &iio_dev_attr_out_voltage0_settling_cycles.dev_attr.attr,
+ &iio_dev_attr_out_altvoltage0_raw.dev_attr.attr,
+ &iio_dev_attr_out_altvoltage0_scale_available.dev_attr.attr,
+ &iio_dev_attr_out_altvoltage0_frequency_start.dev_attr.attr,
+ &iio_dev_attr_out_altvoltage0_frequency_increment.dev_attr.attr,
+ &iio_dev_attr_out_altvoltage0_frequency_points.dev_attr.attr,
+ &iio_dev_attr_out_altvoltage0_settling_cycles.dev_attr.attr,
&iio_dev_attr_in_voltage0_scale.dev_attr.attr,
&iio_dev_attr_in_voltage0_scale_available.dev_attr.attr,
NULL
@@ -587,7 +572,8 @@
{
struct ad5933_state *st = iio_priv(indio_dev);
- /* AD5933_CTRL_INIT_START_FREQ:
+ /*
+ * AD5933_CTRL_INIT_START_FREQ:
* High Q complex circuits require a long time to reach steady state.
* To facilitate the measurement of such impedances, this mode allows
* the user full control of the settling time requirement before
@@ -616,11 +602,12 @@
.postdisable = ad5933_ring_postdisable,
};
-static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev)
+static int ad5933_register_ring_funcs_and_init(struct device *dev,
+ struct iio_dev *indio_dev)
{
struct iio_buffer *buffer;
- buffer = iio_kfifo_allocate();
+ buffer = devm_iio_kfifo_allocate(dev);
if (!buffer)
return -ENOMEM;
@@ -678,7 +665,8 @@
}
if (status & AD5933_STAT_SWEEP_DONE) {
- /* last sample received - power down do
+ /*
+ * last sample received - power down do
* nothing until the ring enable is toggled
*/
ad5933_cmd(st, AD5933_CTRL_POWER_DOWN);
@@ -689,13 +677,27 @@
}
}
+static void ad5933_reg_disable(void *data)
+{
+ struct ad5933_state *st = data;
+
+ regulator_disable(st->reg);
+}
+
+static void ad5933_clk_disable(void *data)
+{
+ struct ad5933_state *st = data;
+
+ clk_disable_unprepare(st->mclk);
+}
+
static int ad5933_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- int ret, voltage_uv = 0;
- struct ad5933_platform_data *pdata = dev_get_platdata(&client->dev);
+ int ret;
struct ad5933_state *st;
struct iio_dev *indio_dev;
+ unsigned long ext_clk_hz = 0;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (!indio_dev)
@@ -707,9 +709,6 @@
mutex_init(&st->lock);
- if (!pdata)
- pdata = &ad5933_default_pdata;
-
st->reg = devm_regulator_get(&client->dev, "vdd");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
@@ -719,15 +718,37 @@
dev_err(&client->dev, "Failed to enable specified VDD supply\n");
return ret;
}
- voltage_uv = regulator_get_voltage(st->reg);
- if (voltage_uv)
- st->vref_mv = voltage_uv / 1000;
- else
- st->vref_mv = pdata->vref_mv;
+ ret = devm_add_action_or_reset(&client->dev, ad5933_reg_disable, st);
+ if (ret)
+ return ret;
- if (pdata->ext_clk_Hz) {
- st->mclk_hz = pdata->ext_clk_Hz;
+ ret = regulator_get_voltage(st->reg);
+ if (ret < 0)
+ return ret;
+
+ st->vref_mv = ret / 1000;
+
+ st->mclk = devm_clk_get(&client->dev, "mclk");
+ if (IS_ERR(st->mclk) && PTR_ERR(st->mclk) != -ENOENT)
+ return PTR_ERR(st->mclk);
+
+ if (!IS_ERR(st->mclk)) {
+ ret = clk_prepare_enable(st->mclk);
+ if (ret < 0)
+ return ret;
+
+ ret = devm_add_action_or_reset(&client->dev,
+ ad5933_clk_disable,
+ st);
+ if (ret)
+ return ret;
+
+ ext_clk_hz = clk_get_rate(st->mclk);
+ }
+
+ if (ext_clk_hz) {
+ st->mclk_hz = ext_clk_hz;
st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK;
} else {
st->mclk_hz = AD5933_INT_OSC_FREQ_Hz;
@@ -738,45 +759,21 @@
INIT_DELAYED_WORK(&st->work, ad5933_work);
st->poll_time_jiffies = msecs_to_jiffies(AD5933_POLL_TIME_ms);
- indio_dev->dev.parent = &client->dev;
indio_dev->info = &ad5933_info;
indio_dev->name = id->name;
indio_dev->modes = (INDIO_BUFFER_SOFTWARE | INDIO_DIRECT_MODE);
indio_dev->channels = ad5933_channels;
indio_dev->num_channels = ARRAY_SIZE(ad5933_channels);
- ret = ad5933_register_ring_funcs_and_init(indio_dev);
+ ret = ad5933_register_ring_funcs_and_init(&client->dev, indio_dev);
if (ret)
- goto error_disable_reg;
+ return ret;
ret = ad5933_setup(st);
if (ret)
- goto error_unreg_ring;
+ return ret;
- ret = iio_device_register(indio_dev);
- if (ret)
- goto error_unreg_ring;
-
- return 0;
-
-error_unreg_ring:
- iio_kfifo_free(indio_dev->buffer);
-error_disable_reg:
- regulator_disable(st->reg);
-
- return ret;
-}
-
-static int ad5933_remove(struct i2c_client *client)
-{
- struct iio_dev *indio_dev = i2c_get_clientdata(client);
- struct ad5933_state *st = iio_priv(indio_dev);
-
- iio_device_unregister(indio_dev);
- iio_kfifo_free(indio_dev->buffer);
- regulator_disable(st->reg);
-
- return 0;
+ return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id ad5933_id[] = {
@@ -787,16 +784,24 @@
MODULE_DEVICE_TABLE(i2c, ad5933_id);
+static const struct of_device_id ad5933_of_match[] = {
+ { .compatible = "adi,ad5933" },
+ { .compatible = "adi,ad5934" },
+ { },
+};
+
+MODULE_DEVICE_TABLE(of, ad5933_of_match);
+
static struct i2c_driver ad5933_driver = {
.driver = {
.name = "ad5933",
+ .of_match_table = ad5933_of_match,
},
.probe = ad5933_probe,
- .remove = ad5933_remove,
.id_table = ad5933_id,
};
module_i2c_driver(ad5933_driver);
-MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD5933 Impedance Conv. Network Analyzer");
MODULE_LICENSE("GPL v2");
--
Gitblit v1.6.2