diff options
Diffstat (limited to 'drivers/iio/adc/ti-ads1015.c')
-rw-r--r-- | drivers/iio/adc/ti-ads1015.c | 398 |
1 files changed, 232 insertions, 166 deletions
diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c index 068efbce1710..5544da80b636 100644 --- a/drivers/iio/adc/ti-ads1015.c +++ b/drivers/iio/adc/ti-ads1015.c @@ -76,10 +76,15 @@ #define ADS1015_DEFAULT_DATA_RATE 4 #define ADS1015_DEFAULT_CHAN 0 -enum chip_ids { - ADSXXXX = 0, - ADS1015, - ADS1115, +struct ads1015_chip_data { + struct iio_chan_spec const *channels; + int num_channels; + const struct iio_info *info; + const int *data_rate; + const int data_rate_len; + const int *scale; + const int scale_len; + bool has_comparator; }; enum ads1015_channels { @@ -94,11 +99,11 @@ enum ads1015_channels { ADS1015_TIMESTAMP, }; -static const unsigned int ads1015_data_rate[] = { +static const int ads1015_data_rate[] = { 128, 250, 490, 920, 1600, 2400, 3300, 3300 }; -static const unsigned int ads1115_data_rate[] = { +static const int ads1115_data_rate[] = { 8, 16, 32, 64, 128, 250, 475, 860 }; @@ -106,10 +111,28 @@ static const unsigned int ads1115_data_rate[] = { * Translation from PGA bits to full-scale positive and negative input voltage * range in mV */ -static int ads1015_fullscale_range[] = { +static const int ads1015_fullscale_range[] = { 6144, 4096, 2048, 1024, 512, 256, 256, 256 }; +static const int ads1015_scale[] = { /* 12bit ADC */ + 256, 11, + 512, 11, + 1024, 11, + 2048, 11, + 4096, 11, + 6144, 11 +}; + +static const int ads1115_scale[] = { /* 16bit ADC */ + 256, 15, + 512, 15, + 1024, 15, + 2048, 15, + 4096, 15, + 6144, 15 +}; + /* * Translation from COMP_QUE field value to the number of successive readings * exceed the threshold values before an interrupt is generated @@ -134,71 +157,53 @@ static const struct iio_event_spec ads1015_events[] = { }, }; -#define ADS1015_V_CHAN(_chan, _addr) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .address = _addr, \ - .channel = _chan, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ - BIT(IIO_CHAN_INFO_SCALE) | \ - BIT(IIO_CHAN_INFO_SAMP_FREQ), \ - .scan_index = _addr, \ - .scan_type = { \ - .sign = 's', \ - .realbits = 12, \ - .storagebits = 16, \ - .shift = 4, \ - .endianness = IIO_CPU, \ - }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ - .datasheet_name = "AIN"#_chan, \ -} - -#define ADS1015_V_DIFF_CHAN(_chan, _chan2, _addr) { \ +/* + * Compile-time check whether _fitbits can accommodate up to _testbits + * bits. Returns _fitbits on success, fails to compile otherwise. + * + * The test works such that it multiplies constant _fitbits by constant + * double-negation of size of a non-empty structure, i.e. it multiplies + * constant _fitbits by constant 1 in each successful compilation case. + * The non-empty structure may contain C11 _Static_assert(), make use of + * this and place the kernel variant of static assert in there, so that + * it performs the compile-time check for _testbits <= _fitbits. Note + * that it is not possible to directly use static_assert in compound + * statements, hence this convoluted construct. + */ +#define FIT_CHECK(_testbits, _fitbits) \ + ( \ + (_fitbits) * \ + !!sizeof(struct { \ + static_assert((_testbits) <= (_fitbits)); \ + int pad; \ + }) \ + ) + +#define ADS1015_V_CHAN(_chan, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \ .type = IIO_VOLTAGE, \ - .differential = 1, \ .indexed = 1, \ .address = _addr, \ .channel = _chan, \ - .channel2 = _chan2, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ - .scan_index = _addr, \ - .scan_type = { \ - .sign = 's', \ - .realbits = 12, \ - .storagebits = 16, \ - .shift = 4, \ - .endianness = IIO_CPU, \ - }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ - .datasheet_name = "AIN"#_chan"-AIN"#_chan2, \ -} - -#define ADS1115_V_CHAN(_chan, _addr) { \ - .type = IIO_VOLTAGE, \ - .indexed = 1, \ - .address = _addr, \ - .channel = _chan, \ - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + .info_mask_shared_by_all_available = \ BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = _addr, \ .scan_type = { \ .sign = 's', \ - .realbits = 16, \ - .storagebits = 16, \ + .realbits = (_realbits), \ + .storagebits = FIT_CHECK((_realbits) + (_shift), 16), \ + .shift = (_shift), \ .endianness = IIO_CPU, \ }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ + .event_spec = (_event_spec), \ + .num_event_specs = (_num_event_specs), \ .datasheet_name = "AIN"#_chan, \ } -#define ADS1115_V_DIFF_CHAN(_chan, _chan2, _addr) { \ +#define ADS1015_V_DIFF_CHAN(_chan, _chan2, _addr, _realbits, _shift, _event_spec, _num_event_specs) { \ .type = IIO_VOLTAGE, \ .differential = 1, \ .indexed = 1, \ @@ -208,15 +213,19 @@ static const struct iio_event_spec ads1015_events[] = { .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = _addr, \ .scan_type = { \ .sign = 's', \ - .realbits = 16, \ - .storagebits = 16, \ + .realbits = (_realbits), \ + .storagebits = FIT_CHECK((_realbits) + (_shift), 16), \ + .shift = (_shift), \ .endianness = IIO_CPU, \ }, \ - .event_spec = ads1015_events, \ - .num_event_specs = ARRAY_SIZE(ads1015_events), \ + .event_spec = (_event_spec), \ + .num_event_specs = (_num_event_specs), \ .datasheet_name = "AIN"#_chan"-AIN"#_chan2, \ } @@ -245,7 +254,7 @@ struct ads1015_data { unsigned int comp_mode; struct ads1015_thresh_data thresh_data[ADS1015_CHANNELS]; - unsigned int *data_rate; + const struct ads1015_chip_data *chip; /* * Set to true when the ADC is switched to the continuous-conversion * mode and exits from a power-down state. This flag is used to avoid @@ -273,49 +282,91 @@ static void ads1015_event_channel_disable(struct ads1015_data *data, int chan) data->event_channel = ADS1015_CHANNELS; } -static bool ads1015_is_writeable_reg(struct device *dev, unsigned int reg) -{ - switch (reg) { - case ADS1015_CFG_REG: - case ADS1015_LO_THRESH_REG: - case ADS1015_HI_THRESH_REG: - return true; - default: - return false; - } -} +static const struct regmap_range ads1015_writeable_ranges[] = { + regmap_reg_range(ADS1015_CFG_REG, ADS1015_HI_THRESH_REG), +}; + +static const struct regmap_access_table ads1015_writeable_table = { + .yes_ranges = ads1015_writeable_ranges, + .n_yes_ranges = ARRAY_SIZE(ads1015_writeable_ranges), +}; static const struct regmap_config ads1015_regmap_config = { .reg_bits = 8, .val_bits = 16, .max_register = ADS1015_HI_THRESH_REG, - .writeable_reg = ads1015_is_writeable_reg, + .wr_table = &ads1015_writeable_table, +}; + +static const struct regmap_range tla2024_writeable_ranges[] = { + regmap_reg_range(ADS1015_CFG_REG, ADS1015_CFG_REG), +}; + +static const struct regmap_access_table tla2024_writeable_table = { + .yes_ranges = tla2024_writeable_ranges, + .n_yes_ranges = ARRAY_SIZE(tla2024_writeable_ranges), +}; + +static const struct regmap_config tla2024_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .max_register = ADS1015_CFG_REG, + .wr_table = &tla2024_writeable_table, }; static const struct iio_chan_spec ads1015_channels[] = { - ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1), - ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3), - ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3), - ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3), - ADS1015_V_CHAN(0, ADS1015_AIN0), - ADS1015_V_CHAN(1, ADS1015_AIN1), - ADS1015_V_CHAN(2, ADS1015_AIN2), - ADS1015_V_CHAN(3, ADS1015_AIN3), + ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(0, ADS1015_AIN0, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(1, ADS1015_AIN1, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(2, ADS1015_AIN2, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(3, ADS1015_AIN3, 12, 4, + ads1015_events, ARRAY_SIZE(ads1015_events)), IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP), }; static const struct iio_chan_spec ads1115_channels[] = { - ADS1115_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1), - ADS1115_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3), - ADS1115_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3), - ADS1115_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3), - ADS1115_V_CHAN(0, ADS1015_AIN0), - ADS1115_V_CHAN(1, ADS1015_AIN1), - ADS1115_V_CHAN(2, ADS1015_AIN2), - ADS1115_V_CHAN(3, ADS1015_AIN3), + ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(0, ADS1015_AIN0, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(1, ADS1015_AIN1, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(2, ADS1015_AIN2, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), + ADS1015_V_CHAN(3, ADS1015_AIN3, 16, 0, + ads1015_events, ARRAY_SIZE(ads1015_events)), IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP), }; +static const struct iio_chan_spec tla2024_channels[] = { + ADS1015_V_DIFF_CHAN(0, 1, ADS1015_AIN0_AIN1, 12, 4, NULL, 0), + ADS1015_V_DIFF_CHAN(0, 3, ADS1015_AIN0_AIN3, 12, 4, NULL, 0), + ADS1015_V_DIFF_CHAN(1, 3, ADS1015_AIN1_AIN3, 12, 4, NULL, 0), + ADS1015_V_DIFF_CHAN(2, 3, ADS1015_AIN2_AIN3, 12, 4, NULL, 0), + ADS1015_V_CHAN(0, ADS1015_AIN0, 12, 4, NULL, 0), + ADS1015_V_CHAN(1, ADS1015_AIN1, 12, 4, NULL, 0), + ADS1015_V_CHAN(2, ADS1015_AIN2, 12, 4, NULL, 0), + ADS1015_V_CHAN(3, ADS1015_AIN3, 12, 4, NULL, 0), + IIO_CHAN_SOFT_TIMESTAMP(ADS1015_TIMESTAMP), +}; + + #ifdef CONFIG_PM static int ads1015_set_power_state(struct ads1015_data *data, bool on) { @@ -344,6 +395,7 @@ static int ads1015_set_power_state(struct ads1015_data *data, bool on) static int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val) { + const int *data_rate = data->chip->data_rate; int ret, pga, dr, dr_old, conv_time; unsigned int old, mask, cfg; @@ -378,8 +430,8 @@ int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val) } if (data->conv_invalid) { dr_old = (old & ADS1015_CFG_DR_MASK) >> ADS1015_CFG_DR_SHIFT; - conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr_old]); - conv_time += DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]); + conv_time = DIV_ROUND_UP(USEC_PER_SEC, data_rate[dr_old]); + conv_time += DIV_ROUND_UP(USEC_PER_SEC, data_rate[dr]); conv_time += conv_time / 10; /* 10% internal clock inaccuracy */ usleep_range(conv_time, conv_time + 1); data->conv_invalid = false; @@ -445,8 +497,8 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate) { int i; - for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++) { - if (data->data_rate[i] == rate) { + for (i = 0; i < data->chip->data_rate_len; i++) { + if (data->chip->data_rate[i] == rate) { data->channel_data[chan].data_rate = i; return 0; } @@ -455,6 +507,32 @@ static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate) return -EINVAL; } +static int ads1015_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct ads1015_data *data = iio_priv(indio_dev); + + if (chan->type != IIO_VOLTAGE) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *type = IIO_VAL_FRACTIONAL_LOG2; + *vals = data->chip->scale; + *length = data->chip->scale_len; + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + *type = IIO_VAL_INT; + *vals = data->chip->data_rate; + *length = data->chip->data_rate_len; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + static int ads1015_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -504,7 +582,7 @@ release_direct: break; case IIO_CHAN_INFO_SAMP_FREQ: idx = data->channel_data[chan->address].data_rate; - *val = data->data_rate[idx]; + *val = data->chip->data_rate[idx]; ret = IIO_VAL_INT; break; default: @@ -564,7 +642,7 @@ static int ads1015_read_event(struct iio_dev *indio_dev, dr = data->channel_data[chan->address].data_rate; comp_queue = data->thresh_data[chan->address].comp_queue; period = ads1015_comp_queue[comp_queue] * - USEC_PER_SEC / data->data_rate[dr]; + USEC_PER_SEC / data->chip->data_rate[dr]; *val = period / USEC_PER_SEC; *val2 = period % USEC_PER_SEC; @@ -586,6 +664,7 @@ static int ads1015_write_event(struct iio_dev *indio_dev, int val2) { struct ads1015_data *data = iio_priv(indio_dev); + const int *data_rate = data->chip->data_rate; int realbits = chan->scan_type.realbits; int ret = 0; long long period; @@ -611,7 +690,7 @@ static int ads1015_write_event(struct iio_dev *indio_dev, for (i = 0; i < ARRAY_SIZE(ads1015_comp_queue) - 1; i++) { if (period <= ads1015_comp_queue[i] * - USEC_PER_SEC / data->data_rate[dr]) + USEC_PER_SEC / data_rate[dr]) break; } data->thresh_data[chan->address].comp_queue = i; @@ -802,54 +881,20 @@ static const struct iio_buffer_setup_ops ads1015_buffer_setup_ops = { .validate_scan_mask = &iio_validate_scan_mask_onehot, }; -static IIO_CONST_ATTR_NAMED(ads1015_scale_available, scale_available, - "3 2 1 0.5 0.25 0.125"); -static IIO_CONST_ATTR_NAMED(ads1115_scale_available, scale_available, - "0.1875 0.125 0.0625 0.03125 0.015625 0.007813"); - -static IIO_CONST_ATTR_NAMED(ads1015_sampling_frequency_available, - sampling_frequency_available, "128 250 490 920 1600 2400 3300"); -static IIO_CONST_ATTR_NAMED(ads1115_sampling_frequency_available, - sampling_frequency_available, "8 16 32 64 128 250 475 860"); - -static struct attribute *ads1015_attributes[] = { - &iio_const_attr_ads1015_scale_available.dev_attr.attr, - &iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ads1015_attribute_group = { - .attrs = ads1015_attributes, -}; - -static struct attribute *ads1115_attributes[] = { - &iio_const_attr_ads1115_scale_available.dev_attr.attr, - &iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ads1115_attribute_group = { - .attrs = ads1115_attributes, -}; - static const struct iio_info ads1015_info = { + .read_avail = ads1015_read_avail, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, .read_event_value = ads1015_read_event, .write_event_value = ads1015_write_event, .read_event_config = ads1015_read_event_config, .write_event_config = ads1015_write_event_config, - .attrs = &ads1015_attribute_group, }; -static const struct iio_info ads1115_info = { +static const struct iio_info tla2024_info = { + .read_avail = ads1015_read_avail, .read_raw = ads1015_read_raw, .write_raw = ads1015_write_raw, - .read_event_value = ads1015_read_event, - .write_event_value = ads1015_write_event, - .read_event_config = ads1015_read_event_config, - .write_event_config = ads1015_write_event_config, - .attrs = &ads1115_attribute_group, }; static int ads1015_client_get_channels_config(struct i2c_client *client) @@ -932,12 +977,18 @@ static int ads1015_set_conv_mode(struct ads1015_data *data, int mode) static int ads1015_probe(struct i2c_client *client, const struct i2c_device_id *id) { + const struct ads1015_chip_data *chip; struct iio_dev *indio_dev; struct ads1015_data *data; int ret; - enum chip_ids chip; int i; + chip = device_get_match_data(&client->dev); + if (!chip) + chip = (const struct ads1015_chip_data *)id->driver_data; + if (!chip) + return dev_err_probe(&client->dev, -EINVAL, "Unknown chip\n"); + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; @@ -950,28 +1001,12 @@ static int ads1015_probe(struct i2c_client *client, indio_dev->name = ADS1015_DRV_NAME; indio_dev->modes = INDIO_DIRECT_MODE; - chip = (uintptr_t)device_get_match_data(&client->dev); - if (chip == ADSXXXX) - chip = id->driver_data; - switch (chip) { - case ADS1015: - indio_dev->channels = ads1015_channels; - indio_dev->num_channels = ARRAY_SIZE(ads1015_channels); - indio_dev->info = &ads1015_info; - data->data_rate = (unsigned int *) &ads1015_data_rate; - break; - case ADS1115: - indio_dev->channels = ads1115_channels; - indio_dev->num_channels = ARRAY_SIZE(ads1115_channels); - indio_dev->info = &ads1115_info; - data->data_rate = (unsigned int *) &ads1115_data_rate; - break; - default: - dev_err(&client->dev, "Unknown chip %d\n", chip); - return -EINVAL; - } - + indio_dev->channels = chip->channels; + indio_dev->num_channels = chip->num_channels; + indio_dev->info = chip->info; + data->chip = chip; data->event_channel = ADS1015_CHANNELS; + /* * Set default lower and upper threshold to min and max value * respectively. @@ -986,7 +1021,9 @@ static int ads1015_probe(struct i2c_client *client, /* we need to keep this ABI the same as used by hwmon ADS1015 driver */ ads1015_get_channels_config(client); - data->regmap = devm_regmap_init_i2c(client, &ads1015_regmap_config); + data->regmap = devm_regmap_init_i2c(client, chip->has_comparator ? + &ads1015_regmap_config : + &tla2024_regmap_config); if (IS_ERR(data->regmap)) { dev_err(&client->dev, "Failed to allocate register map\n"); return PTR_ERR(data->regmap); @@ -1000,7 +1037,7 @@ static int ads1015_probe(struct i2c_client *client, return ret; } - if (client->irq) { + if (client->irq && chip->has_comparator) { unsigned long irq_trig = irqd_get_trigger_type(irq_get_irq_data(client->irq)); unsigned int cfg_comp_mask = ADS1015_CFG_COMP_QUE_MASK | @@ -1099,22 +1136,51 @@ static const struct dev_pm_ops ads1015_pm_ops = { ads1015_runtime_resume, NULL) }; +static const struct ads1015_chip_data ads1015_data = { + .channels = ads1015_channels, + .num_channels = ARRAY_SIZE(ads1015_channels), + .info = &ads1015_info, + .data_rate = ads1015_data_rate, + .data_rate_len = ARRAY_SIZE(ads1015_data_rate), + .scale = ads1015_scale, + .scale_len = ARRAY_SIZE(ads1015_scale), + .has_comparator = true, +}; + +static const struct ads1015_chip_data ads1115_data = { + .channels = ads1115_channels, + .num_channels = ARRAY_SIZE(ads1115_channels), + .info = &ads1015_info, + .data_rate = ads1115_data_rate, + .data_rate_len = ARRAY_SIZE(ads1115_data_rate), + .scale = ads1115_scale, + .scale_len = ARRAY_SIZE(ads1115_scale), + .has_comparator = true, +}; + +static const struct ads1015_chip_data tla2024_data = { + .channels = tla2024_channels, + .num_channels = ARRAY_SIZE(tla2024_channels), + .info = &tla2024_info, + .data_rate = ads1015_data_rate, + .data_rate_len = ARRAY_SIZE(ads1015_data_rate), + .scale = ads1015_scale, + .scale_len = ARRAY_SIZE(ads1015_scale), + .has_comparator = false, +}; + static const struct i2c_device_id ads1015_id[] = { - {"ads1015", ADS1015}, - {"ads1115", ADS1115}, + { "ads1015", (kernel_ulong_t)&ads1015_data }, + { "ads1115", (kernel_ulong_t)&ads1115_data }, + { "tla2024", (kernel_ulong_t)&tla2024_data }, {} }; MODULE_DEVICE_TABLE(i2c, ads1015_id); static const struct of_device_id ads1015_of_match[] = { - { - .compatible = "ti,ads1015", - .data = (void *)ADS1015 - }, - { - .compatible = "ti,ads1115", - .data = (void *)ADS1115 - }, + { .compatible = "ti,ads1015", .data = &ads1015_data }, + { .compatible = "ti,ads1115", .data = &ads1115_data }, + { .compatible = "ti,tla2024", .data = &tla2024_data }, {} }; MODULE_DEVICE_TABLE(of, ads1015_of_match); |