mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 07:38:10 +00:00
iio: temperature: ltc2983: support more parts
Add support for the following parts: * LTC2984 * LTC2986 * LTM2985 The LTC2984 is a variant of the LTC2983 with EEPROM. The LTC2986 is a variant of the LTC2983 with only 10 channels, EEPROM and support for active analog temperature sensors. The LTM2985 is software-compatible with the LTC2986. Signed-off-by: Cosmin Tanislav <cosmin.tanislav@analog.com> Link: https://lore.kernel.org/r/20221103130041.2153295-14-demonsingur@gmail.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
This commit is contained in:
parent
d240526950
commit
6f7cadcf66
1 changed files with 176 additions and 7 deletions
|
@ -25,9 +25,12 @@
|
||||||
#define LTC2983_STATUS_REG 0x0000
|
#define LTC2983_STATUS_REG 0x0000
|
||||||
#define LTC2983_TEMP_RES_START_REG 0x0010
|
#define LTC2983_TEMP_RES_START_REG 0x0010
|
||||||
#define LTC2983_TEMP_RES_END_REG 0x005F
|
#define LTC2983_TEMP_RES_END_REG 0x005F
|
||||||
|
#define LTC2983_EEPROM_KEY_REG 0x00B0
|
||||||
|
#define LTC2983_EEPROM_READ_STATUS_REG 0x00D0
|
||||||
#define LTC2983_GLOBAL_CONFIG_REG 0x00F0
|
#define LTC2983_GLOBAL_CONFIG_REG 0x00F0
|
||||||
#define LTC2983_MULT_CHANNEL_START_REG 0x00F4
|
#define LTC2983_MULT_CHANNEL_START_REG 0x00F4
|
||||||
#define LTC2983_MULT_CHANNEL_END_REG 0x00F7
|
#define LTC2983_MULT_CHANNEL_END_REG 0x00F7
|
||||||
|
#define LTC2986_EEPROM_STATUS_REG 0x00F9
|
||||||
#define LTC2983_MUX_CONFIG_REG 0x00FF
|
#define LTC2983_MUX_CONFIG_REG 0x00FF
|
||||||
#define LTC2983_CHAN_ASSIGN_START_REG 0x0200
|
#define LTC2983_CHAN_ASSIGN_START_REG 0x0200
|
||||||
#define LTC2983_CHAN_ASSIGN_END_REG 0x024F
|
#define LTC2983_CHAN_ASSIGN_END_REG 0x024F
|
||||||
|
@ -35,13 +38,21 @@
|
||||||
#define LTC2983_CUST_SENS_TBL_END_REG 0x03CF
|
#define LTC2983_CUST_SENS_TBL_END_REG 0x03CF
|
||||||
|
|
||||||
#define LTC2983_DIFFERENTIAL_CHAN_MIN 2
|
#define LTC2983_DIFFERENTIAL_CHAN_MIN 2
|
||||||
#define LTC2983_MAX_CHANNELS_NR 20
|
|
||||||
#define LTC2983_MIN_CHANNELS_NR 1
|
#define LTC2983_MIN_CHANNELS_NR 1
|
||||||
#define LTC2983_SLEEP 0x97
|
#define LTC2983_SLEEP 0x97
|
||||||
#define LTC2983_CUSTOM_STEINHART_SIZE 24
|
#define LTC2983_CUSTOM_STEINHART_SIZE 24
|
||||||
#define LTC2983_CUSTOM_SENSOR_ENTRY_SZ 6
|
#define LTC2983_CUSTOM_SENSOR_ENTRY_SZ 6
|
||||||
#define LTC2983_CUSTOM_STEINHART_ENTRY_SZ 4
|
#define LTC2983_CUSTOM_STEINHART_ENTRY_SZ 4
|
||||||
|
|
||||||
|
#define LTC2983_EEPROM_KEY 0xA53C0F5A
|
||||||
|
#define LTC2983_EEPROM_WRITE_CMD 0x15
|
||||||
|
#define LTC2983_EEPROM_READ_CMD 0x16
|
||||||
|
#define LTC2983_EEPROM_STATUS_FAILURE_MASK GENMASK(3, 1)
|
||||||
|
#define LTC2983_EEPROM_READ_FAILURE_MASK GENMASK(7, 0)
|
||||||
|
|
||||||
|
#define LTC2983_EEPROM_WRITE_TIME_MS 2600
|
||||||
|
#define LTC2983_EEPROM_READ_TIME_MS 20
|
||||||
|
|
||||||
#define LTC2983_CHAN_START_ADDR(chan) \
|
#define LTC2983_CHAN_START_ADDR(chan) \
|
||||||
(((chan - 1) * 4) + LTC2983_CHAN_ASSIGN_START_REG)
|
(((chan - 1) * 4) + LTC2983_CHAN_ASSIGN_START_REG)
|
||||||
#define LTC2983_CHAN_RES_ADDR(chan) \
|
#define LTC2983_CHAN_RES_ADDR(chan) \
|
||||||
|
@ -171,6 +182,7 @@ enum {
|
||||||
LTC2983_SENSOR_DIODE = 28,
|
LTC2983_SENSOR_DIODE = 28,
|
||||||
LTC2983_SENSOR_SENSE_RESISTOR = 29,
|
LTC2983_SENSOR_SENSE_RESISTOR = 29,
|
||||||
LTC2983_SENSOR_DIRECT_ADC = 30,
|
LTC2983_SENSOR_DIRECT_ADC = 30,
|
||||||
|
LTC2983_SENSOR_ACTIVE_TEMP = 31,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_thermocouple(_sensor) \
|
#define to_thermocouple(_sensor) \
|
||||||
|
@ -191,7 +203,17 @@ enum {
|
||||||
#define to_adc(_sensor) \
|
#define to_adc(_sensor) \
|
||||||
container_of(_sensor, struct ltc2983_adc, sensor)
|
container_of(_sensor, struct ltc2983_adc, sensor)
|
||||||
|
|
||||||
|
#define to_temp(_sensor) \
|
||||||
|
container_of(_sensor, struct ltc2983_temp, sensor)
|
||||||
|
|
||||||
|
struct ltc2983_chip_info {
|
||||||
|
unsigned int max_channels_nr;
|
||||||
|
bool has_temp;
|
||||||
|
bool has_eeprom;
|
||||||
|
};
|
||||||
|
|
||||||
struct ltc2983_data {
|
struct ltc2983_data {
|
||||||
|
const struct ltc2983_chip_info *info;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
struct spi_device *spi;
|
struct spi_device *spi;
|
||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
|
@ -210,6 +232,7 @@ struct ltc2983_data {
|
||||||
*/
|
*/
|
||||||
__be32 temp __aligned(IIO_DMA_MINALIGN);
|
__be32 temp __aligned(IIO_DMA_MINALIGN);
|
||||||
__be32 chan_val;
|
__be32 chan_val;
|
||||||
|
__be32 eeprom_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ltc2983_sensor {
|
struct ltc2983_sensor {
|
||||||
|
@ -272,6 +295,12 @@ struct ltc2983_adc {
|
||||||
bool single_ended;
|
bool single_ended;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ltc2983_temp {
|
||||||
|
struct ltc2983_sensor sensor;
|
||||||
|
struct ltc2983_custom_sensor *custom;
|
||||||
|
bool single_ended;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Convert to Q format numbers. These number's are integers where
|
* Convert to Q format numbers. These number's are integers where
|
||||||
* the number of integer and fractional bits are specified. The resolution
|
* the number of integer and fractional bits are specified. The resolution
|
||||||
|
@ -606,6 +635,22 @@ static int ltc2983_adc_assign_chan(struct ltc2983_data *st,
|
||||||
return __ltc2983_chan_assign_common(st, sensor, chan_val);
|
return __ltc2983_chan_assign_common(st, sensor, chan_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ltc2983_temp_assign_chan(struct ltc2983_data *st,
|
||||||
|
const struct ltc2983_sensor *sensor)
|
||||||
|
{
|
||||||
|
struct ltc2983_temp *temp = to_temp(sensor);
|
||||||
|
u32 chan_val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
chan_val = LTC2983_ADC_SINGLE_ENDED(temp->single_ended);
|
||||||
|
|
||||||
|
ret = __ltc2983_chan_custom_sensor_assign(st, temp->custom, &chan_val);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return __ltc2983_chan_assign_common(st, sensor, chan_val);
|
||||||
|
}
|
||||||
|
|
||||||
static struct ltc2983_sensor *
|
static struct ltc2983_sensor *
|
||||||
ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data *st,
|
ltc2983_thermocouple_new(const struct fwnode_handle *child, struct ltc2983_data *st,
|
||||||
const struct ltc2983_sensor *sensor)
|
const struct ltc2983_sensor *sensor)
|
||||||
|
@ -771,10 +816,10 @@ ltc2983_rtd_new(const struct fwnode_handle *child, struct ltc2983_data *st,
|
||||||
if (rtd->sensor_config & LTC2983_RTD_4_WIRE_MASK) {
|
if (rtd->sensor_config & LTC2983_RTD_4_WIRE_MASK) {
|
||||||
/* 4-wire */
|
/* 4-wire */
|
||||||
u8 min = LTC2983_DIFFERENTIAL_CHAN_MIN,
|
u8 min = LTC2983_DIFFERENTIAL_CHAN_MIN,
|
||||||
max = LTC2983_MAX_CHANNELS_NR;
|
max = st->info->max_channels_nr;
|
||||||
|
|
||||||
if (rtd->sensor_config & LTC2983_RTD_ROTATION_MASK)
|
if (rtd->sensor_config & LTC2983_RTD_ROTATION_MASK)
|
||||||
max = LTC2983_MAX_CHANNELS_NR - 1;
|
max = st->info->max_channels_nr - 1;
|
||||||
|
|
||||||
if (((rtd->sensor_config & LTC2983_RTD_KELVIN_R_SENSE_MASK)
|
if (((rtd->sensor_config & LTC2983_RTD_KELVIN_R_SENSE_MASK)
|
||||||
== LTC2983_RTD_KELVIN_R_SENSE_MASK) &&
|
== LTC2983_RTD_KELVIN_R_SENSE_MASK) &&
|
||||||
|
@ -1143,6 +1188,38 @@ static struct ltc2983_sensor *ltc2983_adc_new(struct fwnode_handle *child,
|
||||||
return &adc->sensor;
|
return &adc->sensor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct ltc2983_sensor *ltc2983_temp_new(struct fwnode_handle *child,
|
||||||
|
struct ltc2983_data *st,
|
||||||
|
const struct ltc2983_sensor *sensor)
|
||||||
|
{
|
||||||
|
struct ltc2983_temp *temp;
|
||||||
|
|
||||||
|
temp = devm_kzalloc(&st->spi->dev, sizeof(*temp), GFP_KERNEL);
|
||||||
|
if (!temp)
|
||||||
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
if (fwnode_property_read_bool(child, "adi,single-ended"))
|
||||||
|
temp->single_ended = true;
|
||||||
|
|
||||||
|
if (!temp->single_ended &&
|
||||||
|
sensor->chan < LTC2983_DIFFERENTIAL_CHAN_MIN) {
|
||||||
|
dev_err(&st->spi->dev, "Invalid chan:%d for differential temp\n",
|
||||||
|
sensor->chan);
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
temp->custom = __ltc2983_custom_sensor_new(st, child, "adi,custom-temp",
|
||||||
|
false, 4096, true);
|
||||||
|
if (IS_ERR(temp->custom))
|
||||||
|
return ERR_CAST(temp->custom);
|
||||||
|
|
||||||
|
/* set common parameters */
|
||||||
|
temp->sensor.assign_chan = ltc2983_temp_assign_chan;
|
||||||
|
temp->sensor.fault_handler = ltc2983_common_fault_handler;
|
||||||
|
|
||||||
|
return &temp->sensor;
|
||||||
|
}
|
||||||
|
|
||||||
static int ltc2983_chan_read(struct ltc2983_data *st,
|
static int ltc2983_chan_read(struct ltc2983_data *st,
|
||||||
const struct ltc2983_sensor *sensor, int *val)
|
const struct ltc2983_sensor *sensor, int *val)
|
||||||
{
|
{
|
||||||
|
@ -1302,10 +1379,10 @@ static int ltc2983_parse_dt(struct ltc2983_data *st)
|
||||||
|
|
||||||
/* check if we have a valid channel */
|
/* check if we have a valid channel */
|
||||||
if (sensor.chan < LTC2983_MIN_CHANNELS_NR ||
|
if (sensor.chan < LTC2983_MIN_CHANNELS_NR ||
|
||||||
sensor.chan > LTC2983_MAX_CHANNELS_NR) {
|
sensor.chan > st->info->max_channels_nr) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
dev_err(dev, "chan:%d must be from %u to %u\n", sensor.chan,
|
dev_err(dev, "chan:%d must be from %u to %u\n", sensor.chan,
|
||||||
LTC2983_MIN_CHANNELS_NR, LTC2983_MAX_CHANNELS_NR);
|
LTC2983_MIN_CHANNELS_NR, st->info->max_channels_nr);
|
||||||
goto put_child;
|
goto put_child;
|
||||||
} else if (channel_avail_mask & BIT(sensor.chan)) {
|
} else if (channel_avail_mask & BIT(sensor.chan)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -1345,6 +1422,9 @@ static int ltc2983_parse_dt(struct ltc2983_data *st)
|
||||||
st->iio_channels--;
|
st->iio_channels--;
|
||||||
} else if (sensor.type == LTC2983_SENSOR_DIRECT_ADC) {
|
} else if (sensor.type == LTC2983_SENSOR_DIRECT_ADC) {
|
||||||
st->sensors[chan] = ltc2983_adc_new(child, st, &sensor);
|
st->sensors[chan] = ltc2983_adc_new(child, st, &sensor);
|
||||||
|
} else if (st->info->has_temp &&
|
||||||
|
sensor.type == LTC2983_SENSOR_ACTIVE_TEMP) {
|
||||||
|
st->sensors[chan] = ltc2983_temp_new(child, st, &sensor);
|
||||||
} else {
|
} else {
|
||||||
dev_err(dev, "Unknown sensor type %d\n", sensor.type);
|
dev_err(dev, "Unknown sensor type %d\n", sensor.type);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -1371,6 +1451,45 @@ static int ltc2983_parse_dt(struct ltc2983_data *st)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ltc2983_eeprom_cmd(struct ltc2983_data *st, unsigned int cmd,
|
||||||
|
unsigned int wait_time, unsigned int status_reg,
|
||||||
|
unsigned long status_fail_mask)
|
||||||
|
{
|
||||||
|
unsigned long time;
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = regmap_bulk_write(st->regmap, LTC2983_EEPROM_KEY_REG,
|
||||||
|
&st->eeprom_key, sizeof(st->eeprom_key));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
reinit_completion(&st->completion);
|
||||||
|
|
||||||
|
ret = regmap_write(st->regmap, LTC2983_STATUS_REG,
|
||||||
|
LTC2983_STATUS_START(true) | cmd);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
time = wait_for_completion_timeout(&st->completion,
|
||||||
|
msecs_to_jiffies(wait_time));
|
||||||
|
if (!time) {
|
||||||
|
dev_err(&st->spi->dev, "EEPROM command timed out\n");
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = regmap_read(st->regmap, status_reg, &val);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (val & status_fail_mask) {
|
||||||
|
dev_err(&st->spi->dev, "EEPROM command failed: 0x%02X\n", val);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
|
static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
|
||||||
{
|
{
|
||||||
u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0, status;
|
u32 iio_chan_t = 0, iio_chan_v = 0, chan, iio_idx = 0, status;
|
||||||
|
@ -1396,6 +1515,15 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (st->info->has_eeprom && !assign_iio) {
|
||||||
|
ret = ltc2983_eeprom_cmd(st, LTC2983_EEPROM_READ_CMD,
|
||||||
|
LTC2983_EEPROM_READ_TIME_MS,
|
||||||
|
LTC2983_EEPROM_READ_STATUS_REG,
|
||||||
|
LTC2983_EEPROM_READ_FAILURE_MASK);
|
||||||
|
if (!ret)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (chan = 0; chan < st->num_channels; chan++) {
|
for (chan = 0; chan < st->num_channels; chan++) {
|
||||||
u32 chan_type = 0, *iio_chan;
|
u32 chan_type = 0, *iio_chan;
|
||||||
|
|
||||||
|
@ -1435,9 +1563,13 @@ static int ltc2983_setup(struct ltc2983_data *st, bool assign_iio)
|
||||||
static const struct regmap_range ltc2983_reg_ranges[] = {
|
static const struct regmap_range ltc2983_reg_ranges[] = {
|
||||||
regmap_reg_range(LTC2983_STATUS_REG, LTC2983_STATUS_REG),
|
regmap_reg_range(LTC2983_STATUS_REG, LTC2983_STATUS_REG),
|
||||||
regmap_reg_range(LTC2983_TEMP_RES_START_REG, LTC2983_TEMP_RES_END_REG),
|
regmap_reg_range(LTC2983_TEMP_RES_START_REG, LTC2983_TEMP_RES_END_REG),
|
||||||
|
regmap_reg_range(LTC2983_EEPROM_KEY_REG, LTC2983_EEPROM_KEY_REG),
|
||||||
|
regmap_reg_range(LTC2983_EEPROM_READ_STATUS_REG,
|
||||||
|
LTC2983_EEPROM_READ_STATUS_REG),
|
||||||
regmap_reg_range(LTC2983_GLOBAL_CONFIG_REG, LTC2983_GLOBAL_CONFIG_REG),
|
regmap_reg_range(LTC2983_GLOBAL_CONFIG_REG, LTC2983_GLOBAL_CONFIG_REG),
|
||||||
regmap_reg_range(LTC2983_MULT_CHANNEL_START_REG,
|
regmap_reg_range(LTC2983_MULT_CHANNEL_START_REG,
|
||||||
LTC2983_MULT_CHANNEL_END_REG),
|
LTC2983_MULT_CHANNEL_END_REG),
|
||||||
|
regmap_reg_range(LTC2986_EEPROM_STATUS_REG, LTC2986_EEPROM_STATUS_REG),
|
||||||
regmap_reg_range(LTC2983_MUX_CONFIG_REG, LTC2983_MUX_CONFIG_REG),
|
regmap_reg_range(LTC2983_MUX_CONFIG_REG, LTC2983_MUX_CONFIG_REG),
|
||||||
regmap_reg_range(LTC2983_CHAN_ASSIGN_START_REG,
|
regmap_reg_range(LTC2983_CHAN_ASSIGN_START_REG,
|
||||||
LTC2983_CHAN_ASSIGN_END_REG),
|
LTC2983_CHAN_ASSIGN_END_REG),
|
||||||
|
@ -1482,6 +1614,12 @@ static int ltc2983_probe(struct spi_device *spi)
|
||||||
|
|
||||||
st = iio_priv(indio_dev);
|
st = iio_priv(indio_dev);
|
||||||
|
|
||||||
|
st->info = device_get_match_data(&spi->dev);
|
||||||
|
if (!st->info)
|
||||||
|
st->info = (void *)spi_get_device_id(spi)->driver_data;
|
||||||
|
if (!st->info)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
st->regmap = devm_regmap_init_spi(spi, <c2983_regmap_config);
|
st->regmap = devm_regmap_init_spi(spi, <c2983_regmap_config);
|
||||||
if (IS_ERR(st->regmap)) {
|
if (IS_ERR(st->regmap)) {
|
||||||
dev_err(&spi->dev, "Failed to initialize regmap\n");
|
dev_err(&spi->dev, "Failed to initialize regmap\n");
|
||||||
|
@ -1491,6 +1629,7 @@ static int ltc2983_probe(struct spi_device *spi)
|
||||||
mutex_init(&st->lock);
|
mutex_init(&st->lock);
|
||||||
init_completion(&st->completion);
|
init_completion(&st->completion);
|
||||||
st->spi = spi;
|
st->spi = spi;
|
||||||
|
st->eeprom_key = cpu_to_be32(LTC2983_EEPROM_KEY);
|
||||||
spi_set_drvdata(spi, st);
|
spi_set_drvdata(spi, st);
|
||||||
|
|
||||||
ret = ltc2983_parse_dt(st);
|
ret = ltc2983_parse_dt(st);
|
||||||
|
@ -1524,6 +1663,15 @@ static int ltc2983_probe(struct spi_device *spi)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (st->info->has_eeprom) {
|
||||||
|
ret = ltc2983_eeprom_cmd(st, LTC2983_EEPROM_WRITE_CMD,
|
||||||
|
LTC2983_EEPROM_WRITE_TIME_MS,
|
||||||
|
LTC2986_EEPROM_STATUS_REG,
|
||||||
|
LTC2983_EEPROM_STATUS_FAILURE_MASK);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
indio_dev->name = name;
|
indio_dev->name = name;
|
||||||
indio_dev->num_channels = st->iio_channels;
|
indio_dev->num_channels = st->iio_channels;
|
||||||
indio_dev->channels = st->iio_chan;
|
indio_dev->channels = st->iio_chan;
|
||||||
|
@ -1554,14 +1702,35 @@ static int ltc2983_suspend(struct device *dev)
|
||||||
static DEFINE_SIMPLE_DEV_PM_OPS(ltc2983_pm_ops, ltc2983_suspend,
|
static DEFINE_SIMPLE_DEV_PM_OPS(ltc2983_pm_ops, ltc2983_suspend,
|
||||||
ltc2983_resume);
|
ltc2983_resume);
|
||||||
|
|
||||||
|
static const struct ltc2983_chip_info ltc2983_chip_info_data = {
|
||||||
|
.max_channels_nr = 20,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ltc2983_chip_info ltc2984_chip_info_data = {
|
||||||
|
.max_channels_nr = 20,
|
||||||
|
.has_eeprom = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ltc2983_chip_info ltc2986_chip_info_data = {
|
||||||
|
.max_channels_nr = 10,
|
||||||
|
.has_temp = true,
|
||||||
|
.has_eeprom = true,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct spi_device_id ltc2983_id_table[] = {
|
static const struct spi_device_id ltc2983_id_table[] = {
|
||||||
{ "ltc2983" },
|
{ "ltc2983", (kernel_ulong_t)<c2983_chip_info_data },
|
||||||
|
{ "ltc2984", (kernel_ulong_t)<c2984_chip_info_data },
|
||||||
|
{ "ltc2986", (kernel_ulong_t)<c2986_chip_info_data },
|
||||||
|
{ "ltm2985", (kernel_ulong_t)<c2986_chip_info_data },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(spi, ltc2983_id_table);
|
MODULE_DEVICE_TABLE(spi, ltc2983_id_table);
|
||||||
|
|
||||||
static const struct of_device_id ltc2983_of_match[] = {
|
static const struct of_device_id ltc2983_of_match[] = {
|
||||||
{ .compatible = "adi,ltc2983" },
|
{ .compatible = "adi,ltc2983", .data = <c2983_chip_info_data },
|
||||||
|
{ .compatible = "adi,ltc2984", .data = <c2984_chip_info_data },
|
||||||
|
{ .compatible = "adi,ltc2986", .data = <c2986_chip_info_data },
|
||||||
|
{ .compatible = "adi,ltm2985", .data = <c2986_chip_info_data },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, ltc2983_of_match);
|
MODULE_DEVICE_TABLE(of, ltc2983_of_match);
|
||||||
|
|
Loading…
Reference in a new issue