iio: ad5755: add support for dt bindings
Devicetree can provide platform data Signed-off-by: Sean Nyekjaer <sean.nyekjaer@prevas.dk> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
This commit is contained in:
parent
29e3e06d89
commit
c947459979
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/sysfs.h>
|
#include <linux/sysfs.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/of.h>
|
||||||
#include <linux/iio/iio.h>
|
#include <linux/iio/iio.h>
|
||||||
#include <linux/iio/sysfs.h>
|
#include <linux/iio/sysfs.h>
|
||||||
#include <linux/platform_data/ad5755.h>
|
#include <linux/platform_data/ad5755.h>
|
||||||
|
@ -109,6 +110,51 @@ enum ad5755_type {
|
||||||
ID_AD5737,
|
ID_AD5737,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static const int ad5755_dcdc_freq_table[][2] = {
|
||||||
|
{ 250000, AD5755_DC_DC_FREQ_250kHZ },
|
||||||
|
{ 410000, AD5755_DC_DC_FREQ_410kHZ },
|
||||||
|
{ 650000, AD5755_DC_DC_FREQ_650kHZ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int ad5755_dcdc_maxv_table[][2] = {
|
||||||
|
{ 23000000, AD5755_DC_DC_MAXV_23V },
|
||||||
|
{ 24500000, AD5755_DC_DC_MAXV_24V5 },
|
||||||
|
{ 27000000, AD5755_DC_DC_MAXV_27V },
|
||||||
|
{ 29500000, AD5755_DC_DC_MAXV_29V5 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int ad5755_slew_rate_table[][2] = {
|
||||||
|
{ 64000, AD5755_SLEW_RATE_64k },
|
||||||
|
{ 32000, AD5755_SLEW_RATE_32k },
|
||||||
|
{ 16000, AD5755_SLEW_RATE_16k },
|
||||||
|
{ 8000, AD5755_SLEW_RATE_8k },
|
||||||
|
{ 4000, AD5755_SLEW_RATE_4k },
|
||||||
|
{ 2000, AD5755_SLEW_RATE_2k },
|
||||||
|
{ 1000, AD5755_SLEW_RATE_1k },
|
||||||
|
{ 500, AD5755_SLEW_RATE_500 },
|
||||||
|
{ 250, AD5755_SLEW_RATE_250 },
|
||||||
|
{ 125, AD5755_SLEW_RATE_125 },
|
||||||
|
{ 64, AD5755_SLEW_RATE_64 },
|
||||||
|
{ 32, AD5755_SLEW_RATE_32 },
|
||||||
|
{ 16, AD5755_SLEW_RATE_16 },
|
||||||
|
{ 8, AD5755_SLEW_RATE_8 },
|
||||||
|
{ 4, AD5755_SLEW_RATE_4 },
|
||||||
|
{ 0, AD5755_SLEW_RATE_0_5 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int ad5755_slew_step_table[][2] = {
|
||||||
|
{ 256, AD5755_SLEW_STEP_SIZE_256 },
|
||||||
|
{ 128, AD5755_SLEW_STEP_SIZE_128 },
|
||||||
|
{ 64, AD5755_SLEW_STEP_SIZE_64 },
|
||||||
|
{ 32, AD5755_SLEW_STEP_SIZE_32 },
|
||||||
|
{ 16, AD5755_SLEW_STEP_SIZE_16 },
|
||||||
|
{ 4, AD5755_SLEW_STEP_SIZE_4 },
|
||||||
|
{ 2, AD5755_SLEW_STEP_SIZE_2 },
|
||||||
|
{ 1, AD5755_SLEW_STEP_SIZE_1 },
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
static int ad5755_write_unlocked(struct iio_dev *indio_dev,
|
static int ad5755_write_unlocked(struct iio_dev *indio_dev,
|
||||||
unsigned int reg, unsigned int val)
|
unsigned int reg, unsigned int val)
|
||||||
{
|
{
|
||||||
|
@ -556,6 +602,129 @@ static const struct ad5755_platform_data ad5755_default_pdata = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static struct ad5755_platform_data *ad5755_parse_dt(struct device *dev)
|
||||||
|
{
|
||||||
|
struct device_node *np = dev->of_node;
|
||||||
|
struct device_node *pp;
|
||||||
|
struct ad5755_platform_data *pdata;
|
||||||
|
unsigned int tmp;
|
||||||
|
unsigned int tmparray[3];
|
||||||
|
int devnr, i;
|
||||||
|
|
||||||
|
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
|
||||||
|
if (!pdata)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pdata->ext_dc_dc_compenstation_resistor =
|
||||||
|
of_property_read_bool(np, "adi,ext-dc-dc-compenstation-resistor");
|
||||||
|
|
||||||
|
if (!of_property_read_u32(np, "adi,dc-dc-phase", &tmp))
|
||||||
|
pdata->dc_dc_phase = tmp;
|
||||||
|
else
|
||||||
|
pdata->dc_dc_phase = AD5755_DC_DC_PHASE_ALL_SAME_EDGE;
|
||||||
|
|
||||||
|
pdata->dc_dc_freq = AD5755_DC_DC_FREQ_410kHZ;
|
||||||
|
if (!of_property_read_u32(np, "adi,dc-dc-freq-hz", &tmp)) {
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ad5755_dcdc_freq_table); i++) {
|
||||||
|
if (tmp == ad5755_dcdc_freq_table[i][0]) {
|
||||||
|
pdata->dc_dc_freq = ad5755_dcdc_freq_table[i][1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == ARRAY_SIZE(ad5755_dcdc_freq_table)) {
|
||||||
|
dev_err(dev,
|
||||||
|
"adi,dc-dc-freq out of range selecting 410kHz");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pdata->dc_dc_maxv = AD5755_DC_DC_MAXV_23V;
|
||||||
|
if (!of_property_read_u32(np, "adi,dc-dc-max-microvolt", &tmp)) {
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ad5755_dcdc_maxv_table); i++) {
|
||||||
|
if (tmp == ad5755_dcdc_maxv_table[i][0]) {
|
||||||
|
pdata->dc_dc_maxv = ad5755_dcdc_maxv_table[i][1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == ARRAY_SIZE(ad5755_dcdc_maxv_table)) {
|
||||||
|
dev_err(dev,
|
||||||
|
"adi,dc-dc-maxv out of range selecting 23V");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
devnr = 0;
|
||||||
|
for_each_child_of_node(np, pp) {
|
||||||
|
if (devnr > AD5755_NUM_CHANNELS) {
|
||||||
|
dev_err(dev,
|
||||||
|
"There is to many channels defined in DT\n");
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!of_property_read_u32(pp, "adi,mode", &tmp))
|
||||||
|
pdata->dac[devnr].mode = tmp;
|
||||||
|
else
|
||||||
|
pdata->dac[devnr].mode = AD5755_MODE_CURRENT_4mA_20mA;
|
||||||
|
|
||||||
|
pdata->dac[devnr].ext_current_sense_resistor =
|
||||||
|
of_property_read_bool(pp, "adi,ext-current-sense-resistor");
|
||||||
|
|
||||||
|
pdata->dac[devnr].enable_voltage_overrange =
|
||||||
|
of_property_read_bool(pp, "adi,enable-voltage-overrange");
|
||||||
|
|
||||||
|
if (!of_property_read_u32_array(pp, "adi,slew", tmparray, 3)) {
|
||||||
|
pdata->dac[devnr].slew.enable = tmparray[0];
|
||||||
|
|
||||||
|
pdata->dac[devnr].slew.rate = AD5755_SLEW_RATE_64k;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ad5755_slew_rate_table); i++) {
|
||||||
|
if (tmparray[1] == ad5755_slew_rate_table[i][0]) {
|
||||||
|
pdata->dac[devnr].slew.rate =
|
||||||
|
ad5755_slew_rate_table[i][1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == ARRAY_SIZE(ad5755_slew_rate_table)) {
|
||||||
|
dev_err(dev,
|
||||||
|
"channel %d slew rate out of range selecting 64kHz",
|
||||||
|
devnr);
|
||||||
|
}
|
||||||
|
|
||||||
|
pdata->dac[devnr].slew.step_size = AD5755_SLEW_STEP_SIZE_1;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(ad5755_slew_step_table); i++) {
|
||||||
|
if (tmparray[2] == ad5755_slew_step_table[i][0]) {
|
||||||
|
pdata->dac[devnr].slew.step_size =
|
||||||
|
ad5755_slew_step_table[i][1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == ARRAY_SIZE(ad5755_slew_step_table)) {
|
||||||
|
dev_err(dev,
|
||||||
|
"channel %d slew step size out of range selecting 1 LSB",
|
||||||
|
devnr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pdata->dac[devnr].slew.enable = false;
|
||||||
|
pdata->dac[devnr].slew.rate = AD5755_SLEW_RATE_64k;
|
||||||
|
pdata->dac[devnr].slew.step_size =
|
||||||
|
AD5755_SLEW_STEP_SIZE_1;
|
||||||
|
}
|
||||||
|
devnr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pdata;
|
||||||
|
|
||||||
|
error_out:
|
||||||
|
devm_kfree(dev, pdata);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static
|
||||||
|
struct ad5755_platform_data *ad5755_parse_dt(struct device *dev)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int ad5755_probe(struct spi_device *spi)
|
static int ad5755_probe(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
enum ad5755_type type = spi_get_device_id(spi)->driver_data;
|
enum ad5755_type type = spi_get_device_id(spi)->driver_data;
|
||||||
|
@ -583,8 +752,15 @@ static int ad5755_probe(struct spi_device *spi)
|
||||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
indio_dev->num_channels = AD5755_NUM_CHANNELS;
|
indio_dev->num_channels = AD5755_NUM_CHANNELS;
|
||||||
|
|
||||||
if (!pdata)
|
if (spi->dev.of_node)
|
||||||
|
pdata = ad5755_parse_dt(&spi->dev);
|
||||||
|
else
|
||||||
|
pdata = spi->dev.platform_data;
|
||||||
|
|
||||||
|
if (!pdata) {
|
||||||
|
dev_warn(&spi->dev, "no platform data? using default\n");
|
||||||
pdata = &ad5755_default_pdata;
|
pdata = &ad5755_default_pdata;
|
||||||
|
}
|
||||||
|
|
||||||
ret = ad5755_init_channels(indio_dev, pdata);
|
ret = ad5755_init_channels(indio_dev, pdata);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -607,6 +783,16 @@ static const struct spi_device_id ad5755_id[] = {
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(spi, ad5755_id);
|
MODULE_DEVICE_TABLE(spi, ad5755_id);
|
||||||
|
|
||||||
|
static const struct of_device_id ad5755_of_match[] = {
|
||||||
|
{ .compatible = "adi,ad5755" },
|
||||||
|
{ .compatible = "adi,ad5755-1" },
|
||||||
|
{ .compatible = "adi,ad5757" },
|
||||||
|
{ .compatible = "adi,ad5735" },
|
||||||
|
{ .compatible = "adi,ad5737" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, ad5755_of_match);
|
||||||
|
|
||||||
static struct spi_driver ad5755_driver = {
|
static struct spi_driver ad5755_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "ad5755",
|
.name = "ad5755",
|
||||||
|
|
Loading…
Reference in New Issue