-
Notifications
You must be signed in to change notification settings - Fork 863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ad5791 offload #2616
ad5791 offload #2616
Conversation
802e9b1
to
3976d47
Compare
03d271e
to
65e5a18
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here it goes my review. Note that I'm expecting some stuff to be sent upstream (like gpio reset)... Also it seems this driver could use a proper refactor if you are willing to do that 😄
drivers/iio/dac/ad5791.c
Outdated
st->gpio_ldac = devm_gpiod_get_optional(&spi->dev, "ldac", | ||
GPIOD_OUT_LOW); | ||
if (IS_ERR(st->gpio_ldac)) | ||
return PTR_ERR(st->gpio_ldac); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the intent of the above two gpio's? I would say, if we're not using them now, don't bother in adding them. Still ok to leave them in the bindings though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
they are actually on the eval board and if i dont drive them they are set as input. we need to make sure they are on the right state: CLR high and LDAC low (datasheet table9 p21) for the output to be set according to the register value when we write on spi xfer. I think we need to keep them.
drivers/iio/dac/ad5791.c
Outdated
st->gpio_reset = devm_gpiod_get_optional(&spi->dev, "reset", | ||
GPIOD_OUT_LOW); | ||
if (IS_ERR(st->gpio_reset)) | ||
return PTR_ERR(st->gpio_reset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above makes sense to have already. But do a reset in case we have it. Typical pattern is:
gpio_reset = devm_gpiod_get_optional(&spi->dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(gpio_reset))
return PTR_ERR(gpio_reset);
if (gpio_reset) {
// typically there's some time we need to wait for the reset to happen
fseep(x);
// get it out of reset
gpiod_set_value_cansleep(gpio_reset, 0);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
drivers/iio/dac/ad5791.c
Outdated
st->pwr_down = pwr_down; | ||
|
||
ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl); | ||
ret = __ad5791_dac_powerdown(indio_dev, pwr_down); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated change. Not disagreeing with it but should be in a separate patch. If you want to take it one step further, it even seems that some proper locking is missing... Moreover, we should set st->pwr_down
after we actually do ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i will drop this change and only check the power status in pre-enable. as you suggested below.
drivers/iio/dac/ad5791.c
Outdated
|
||
if (spi_engine_ex_offload_supported(spi)) { | ||
indio_dev->channels = | ||
&ad5791_channels[spi_get_device_id(spi)->driver_data]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The above could also be an opportunity for a nice cleanup. Adding a chip_info structure and actual OF support. Thus getting rid of the id enum
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
drivers/iio/dac/ad5791.c
Outdated
struct ad5791_state *st = iio_priv(indio_dev); | ||
int ret; | ||
|
||
ret = __ad5791_dac_powerdown(indio_dev, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see now it's related but see below...
drivers/iio/dac/ad5791.c
Outdated
pwm_disable(st->cnv_trigger); | ||
spi_bus_unlock(st->spi->master); | ||
|
||
return __ad5791_dac_powerdown(indio_dev, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to assume we want to powerdown the DAC? Since it's a user control I would rather check it and return error or something in ad5791_buffer_preenable() in case it's in a powerdown state. This would also mean that we can't power it down while in buffer mode. Thus, using iio_device_claim_direct_mode()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok.
drivers/iio/dac/ad5791.c
Outdated
int ret; | ||
|
||
if (!st->cnv_trigger) | ||
return -ENODEV; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICT, this is only available for offload support and cnv_trigger is mandatory (otherwise we fail to probe). So, seems like a redundant check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple more suggestions for upstream "cleanup":
- Use
devm_regulator_get_enable_read_voltage()
to simplify the regulator code. - Drop the driver
remove
callback by using moredevm_
.
65e5a18
to
5be52c8
Compare
changes in V2: implement new suggested driver simplifications:
Fixes related to comments:
|
drivers/iio/dac/ad5791.c
Outdated
@@ -430,30 +412,9 @@ static int ad5791_probe(struct spi_device *spi) | |||
indio_dev->name = st->chip_info->name; | |||
ret = iio_device_register(indio_dev); | |||
if (ret) | |||
goto error_disable_reg_neg; | |||
return dev_err_probe(&spi->dev, ret, "unable to register iio device\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most drivers will just return devm_iio_device_register()
directly, so don't usually have the dev_err_probe()
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
0c0d193
to
9c53b59
Compare
changes in V3:
|
drivers/iio/dac/ad5791.c
Outdated
static int ad5791_get_sampling_freq(struct ad5791_state *st) | ||
{ | ||
return DIV_ROUND_CLOSEST_ULL(NSEC_PER_SEC, | ||
pwm_get_period(st->cnv_trigger)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still want DIV_ROUND_CLOSEST_ULL()
? @ukleinek seemed to have doubts about it...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i missed to address that. in fact is the same on the 400x driver. i guess we need to change both.
|
||
st->spi_transfer.len = 4; | ||
st->spi_transfer.bits_per_word = 24; | ||
st->spi_transfer.tx_buf = (void *)-1; /* steaming tx */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: we could have a better comment for why we have to do this (ugly) hack
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
drivers/iio/dac/ad5791.c
Outdated
if (st->pwr_down) | ||
return -EINVAL; | ||
|
||
ret = pwm_enable(st->cnv_trigger); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we have an extra space?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. will remove.
drivers/iio/dac/ad5791.c
Outdated
return devm_add_action_or_reset(&spi->dev, ad5791_pwm_disable, | ||
st->cnv_trigger); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also wondering about the devm action. AFAICT, you're not enabling the PWM in __ad5791_set_sampling_freq() so this looks unbalanced... I guess this is not really a problem but also looks unnecessary.
the device tree is actually: arch/arm/boot/dts/socfpga_cyclone5_de10_nano_ad57xx.dts |
drivers/iio/dac/ad5791.c
Outdated
if (ret) { | ||
ad5791_pwm_disable(st->cnv_trigger); | ||
return ret; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Somehow this did not went in my review... Looks like a leftover
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes... i saw that! im remove the devm_action.
bb84d25
to
64fd6bb
Compare
Changes V6:
|
|
||
dmas = <&tx_dma 0>; | ||
dma-names = "tx"; | ||
pwms = <&adc_trigger 0 1000 0>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pwms = <&adc_trigger 0 1000 0>; | |
pwms = <&dac_trigger 0 1000 0>; |
Looks like a copy-paste from an ADC, but this is a DAC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
64fd6bb
to
3f44a10
Compare
Changes v7
|
return PTR_ERR(st->gpio_clear); | ||
|
||
st->gpio_ldac = devm_gpiod_get_optional(&spi->dev, "ldac", | ||
GPIOD_OUT_HIGH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this also need to be changed to GPIOD_OUT_LOW
since we changed the devcietree to active low?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be for legacy reasons but i think the gpio wording is quite confusing
think that "HIGH" actually means "active" ? perhaps why we see several "resets" being
handled in opposite way when i think they are all "active low" ?
for the output to be set according to the DAC register value the actual state of the physical gpio needs to be low
(table 9 p 21 of datasheet) (reset=1 clr=1 ldac=0)
so by setting to out_high the gpio is actually going to low state if is "active low" in dts
at least that is what i measure and see on debugfs:
gpiochip0: GPIOs 2016-2047, parent: platform/ff210080.gpio_bd, /soc/axi_h2f_lw_bridge@0xff200000/gpio_bd@0x00010080:
gpio-2032 ( |reset ) out hi ACTIVE LOW
gpio-2033 ( |clear ) out hi ACTIVE LOW
gpio-2034 ( |ldac ) out lo ACTIVE LOW
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
think that "HIGH" actually means "active" ?
yes, or "asserted"
Depending on board layout, the ad57xx may need control of reset, clear, and ldac pins by the host driver. Add optional bindings for these gpios. Reviewed-by: David Lechner <[email protected]> Reviewed-by: Krzysztof Kozlowski <[email protected]> Signed-off-by: Axel Haslam <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jonathan Cameron <[email protected]>
Vcc, iovcc, vrefp, and vrefn are needed for the DAC to work. Add them as required bindings for ad5791. Reviewed-by: David Lechner <[email protected]> Reviewed-by: Krzysztof Kozlowski <[email protected]> Signed-off-by: Axel Haslam <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jonathan Cameron <[email protected]>
On the example, the ldac gpio is flagged as active high, when in reality its an active low gpio. Fix the example by using the active low flag for the ldac gpio. Signed-off-by: Axel Haslam <[email protected]>
Include a chip info struct in device SPI and device OF match tables to provide channel definitions for each particular ADC model and drop device enum. Suggested-by: Nuno Sa <[email protected]> Reviewed-by: David Lechner <[email protected]> Signed-off-by: Axel Haslam <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jonathan Cameron <[email protected]>
The ad7591 has reset, clr and ldac gpios. For the DAC to output data continuously written to the data register the state of these gpios needs to be set by the driver. Add these gpios to the driver making them optional in case they are fixed on the pcb. Reviewed-by: David Lechner <[email protected]> Signed-off-by: Axel Haslam <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jonathan Cameron <[email protected]>
Simplify probe by using of the devm_regulator_get_enable_read_voltage. Suggested-by: David Lechner <[email protected]> Reviewed-by: David Lechner <[email protected]> Signed-off-by: Axel Haslam <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jonathan Cameron <[email protected]>
Use devm_iio_device_register to automatically free the iio device. since this is the last remaining resource that was not automatically freed, we can drop the ".remove" callback. Suggested-by: David Lechner <[email protected]> Reviewed-by: David Lechner <[email protected]> Signed-off-by: Axel Haslam <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jonathan Cameron <[email protected]>
This property is not defined on the binidngs, and is not used by the driver. Remove it Suggested-by: David Lechner <[email protected]> Signed-off-by: Axel Haslam <[email protected]>
This adds the bi-directional gpio block to the d10 nano Signed-off-by: Axel Haslam <[email protected]>
Add devicetree for ad57xx on de10nano. Signed-off-by: Axel Haslam <[email protected]>
To allow offload to stream a "tx" type of xfer we need the write flag set but no messages on the SDO memory of the offload engine. but the current code relies on the tx_buf pointer for both of these operations, so there is no way to separate the two. The offload patches currently on development for upstream add flags on core spi structures to flag an offload xfer as a streaming xfer. While those patches get review and are ready to backport to the adi tree, Workaround this limitation by checking if the tx_buf address is -1 to flag it as "streaming type". Signed-off-by: Axel Haslam <[email protected]>
Add spi offload support to stream tx buffers using dma. This allows loading samples to the dac with a rate of 1 MSPS. Signed-off-by: Axel Haslam <[email protected]>
3f44a10
to
de61469
Compare
Changes re-based/tested on new kernel in main v6.6. requires #2666 i remove the fixes tag, so CI would be happy. |
spi offload support for ad57xx dac
This adds offload support for the ad57xx dac to be able to send samples up to 1MSPS.
PR Type
PR Checklist