Loading drivers/iio/dac/ad5755.c +187 −1 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/delay.h> #include <linux/of.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/platform_data/ad5755.h> Loading Loading @@ -109,6 +110,51 @@ enum ad5755_type { 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, unsigned int reg, unsigned int val) { Loading Loading @@ -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) { enum ad5755_type type = spi_get_device_id(spi)->driver_data; Loading Loading @@ -583,8 +752,15 @@ static int ad5755_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; 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; } ret = ad5755_init_channels(indio_dev, pdata); if (ret) Loading @@ -607,6 +783,16 @@ static const struct spi_device_id 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 = { .driver = { .name = "ad5755", Loading Loading
drivers/iio/dac/ad5755.c +187 −1 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/delay.h> #include <linux/of.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/platform_data/ad5755.h> Loading Loading @@ -109,6 +110,51 @@ enum ad5755_type { 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, unsigned int reg, unsigned int val) { Loading Loading @@ -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) { enum ad5755_type type = spi_get_device_id(spi)->driver_data; Loading Loading @@ -583,8 +752,15 @@ static int ad5755_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; 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; } ret = ad5755_init_channels(indio_dev, pdata); if (ret) Loading @@ -607,6 +783,16 @@ static const struct spi_device_id 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 = { .driver = { .name = "ad5755", Loading