Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: ti-adc128s052: Support ROHM BD79104

The ROHM BD79104 ADC has identical SPI communication logic as the
ti-adc128s052. Eg, SPI transfer should be 16 clk cycles, conversion is
started when the CS is pulled low, and channel selection is done by
writing the channel ID after two zero bits. Data is contained in
big-endian format in the last 12 bits.

The BD79104 has two input voltage pins. Data sheet uses terms "vdd" and
"iovdd". The "vdd" is used also as an analog reference voltage. Hence
the driver expects finding these from the device-tree, instead of having
the "vref" only as TI's driver.

NOTE: The TI's data sheet[1] does show that the TI's IC does actually
have two voltage inputs as well. Pins are called Va (analog reference)
and Vd (digital supply pin) - but I keep the existing driver behaviour
for the TI's IC "as is", because I have no HW to test changes, and
because I have no real need to touch it.

NOTE II: The BD79104 requires SPI MODE 3.

NOTE III: I used evaluation board "BD79104FV-EVK-001" made by ROHM. With
this board I had to drop the SPI speed below the 20M which is mentioned
in the data-sheet [2]. This, however, may be a limitation of the EVK
board, not the component itself.

Signed-off-by: Matti Vaittinen <mazziesaccount@gmail.com>
Datasheet: https://www.ti.com/lit/ds/symlink/adc128s052.pdf # [1]
Datasheet: https://fscdn.rohm.com/en/products/databook/datasheet/ic/data_converter/dac/bd79104fv-la-e.pdf # [2]
Link: https://patch.msgid.link/36ffa72cbdf8dbbdf1e612040db82ebcdf73fa24.1744022065.git.mazziesaccount@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Matti Vaittinen and committed by
Jonathan Cameron
fbc18f27 944de7fc

+37 -5
+1 -1
drivers/iio/adc/Kconfig
··· 1493 1493 depends on SPI 1494 1494 help 1495 1495 If you say yes here you get support for Texas Instruments ADC128S052, 1496 - ADC122S021 and ADC124S021 chips. 1496 + ADC122S021, ADC124S021 and ROHM Semiconductor BD79104 chips. 1497 1497 1498 1498 This driver can also be built as a module. If so, the module will be 1499 1499 called ti-adc128s052.
+36 -4
drivers/iio/adc/ti-adc128s052.c
··· 21 21 struct adc128_configuration { 22 22 const struct iio_chan_spec *channels; 23 23 u8 num_channels; 24 + const char *refname; 25 + int num_other_regulators; 26 + const char * const (*other_regulators)[]; 24 27 }; 25 28 26 29 struct adc128 { ··· 127 124 ADC128_VOLTAGE_CHANNEL(3), 128 125 }; 129 126 127 + static const char * const bd79104_regulators[] = { "iovdd" }; 128 + 130 129 static const struct adc128_configuration adc128_config[] = { 131 - { adc128s052_channels, ARRAY_SIZE(adc128s052_channels) }, 132 - { adc122s021_channels, ARRAY_SIZE(adc122s021_channels) }, 133 - { adc124s021_channels, ARRAY_SIZE(adc124s021_channels) }, 130 + { 131 + .channels = adc128s052_channels, 132 + .num_channels = ARRAY_SIZE(adc128s052_channels), 133 + .refname = "vref", 134 + }, { 135 + .channels = adc122s021_channels, 136 + .num_channels = ARRAY_SIZE(adc122s021_channels), 137 + .refname = "vref", 138 + }, { 139 + .channels = adc124s021_channels, 140 + .num_channels = ARRAY_SIZE(adc124s021_channels), 141 + .refname = "vref", 142 + }, { 143 + .channels = adc128s052_channels, 144 + .num_channels = ARRAY_SIZE(adc128s052_channels), 145 + .refname = "vdd", 146 + .other_regulators = &bd79104_regulators, 147 + .num_other_regulators = 1, 148 + }, 134 149 }; 135 150 136 151 static const struct iio_info adc128_info = { ··· 183 162 indio_dev->channels = config->channels; 184 163 indio_dev->num_channels = config->num_channels; 185 164 186 - adc->reg = devm_regulator_get(&spi->dev, "vref"); 165 + adc->reg = devm_regulator_get(&spi->dev, config->refname); 187 166 if (IS_ERR(adc->reg)) 188 167 return PTR_ERR(adc->reg); 189 168 ··· 194 173 adc->reg); 195 174 if (ret) 196 175 return ret; 176 + 177 + if (config->num_other_regulators) { 178 + ret = devm_regulator_bulk_get_enable(&spi->dev, 179 + config->num_other_regulators, 180 + *config->other_regulators); 181 + if (ret) 182 + return dev_err_probe(&spi->dev, ret, 183 + "Failed to enable regulators\n"); 184 + } 197 185 198 186 ret = devm_mutex_init(&spi->dev, &adc->lock); 199 187 if (ret) ··· 219 189 { .compatible = "ti,adc124s021", .data = &adc128_config[2] }, 220 190 { .compatible = "ti,adc124s051", .data = &adc128_config[2] }, 221 191 { .compatible = "ti,adc124s101", .data = &adc128_config[2] }, 192 + { .compatible = "rohm,bd79104", .data = &adc128_config[3] }, 222 193 { } 223 194 }; 224 195 MODULE_DEVICE_TABLE(of, adc128_of_match); ··· 232 201 { "adc124s021", (kernel_ulong_t)&adc128_config[2] }, 233 202 { "adc124s051", (kernel_ulong_t)&adc128_config[2] }, 234 203 { "adc124s101", (kernel_ulong_t)&adc128_config[2] }, 204 + { "bd79104", (kernel_ulong_t)&adc128_config[3] }, 235 205 { } 236 206 }; 237 207 MODULE_DEVICE_TABLE(spi, adc128_id);