diff options
author | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2019-12-18 22:52:20 +0100 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2019-12-18 22:52:20 +0100 |
commit | 1ddf624b0b268fdc0b80b1de618b98f8d117afea (patch) | |
tree | 3d3218332bcb34cb0afa01d6ad996058a3dbcb77 /drivers/iio/adc/hx711.c | |
parent | 6b774eec1f9d3064e9b33634dfa99d5666d0a73a (diff) | |
parent | bfb9e5c03076a446b1f4f6a523ddc8d723c907a6 (diff) |
Merge tag 'v4.14.159' into 4.14-2.0.x-imx
This is the 4.14.159 stable release
Conflicts:
arch/arm/Kconfig.debug
arch/arm/boot/dts/imx7s.dtsi
arch/arm/mach-imx/cpuidle-imx6sx.c
drivers/crypto/caam/caamalg.c
drivers/crypto/mxs-dcp.c
drivers/dma/imx-sdma.c
drivers/input/keyboard/imx_keypad.c
drivers/net/can/flexcan.c
drivers/net/can/rx-offload.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/pci/dwc/pci-imx6.c
drivers/spi/spi-fsl-lpspi.c
drivers/usb/dwc3/gadget.c
Diffstat (limited to 'drivers/iio/adc/hx711.c')
-rw-r--r-- | drivers/iio/adc/hx711.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/drivers/iio/adc/hx711.c b/drivers/iio/adc/hx711.c index 27005d84ed73..0dec733471d5 100644 --- a/drivers/iio/adc/hx711.c +++ b/drivers/iio/adc/hx711.c @@ -89,20 +89,35 @@ struct hx711_data { int gain_set; /* gain set on device */ int gain_chan_a; /* gain for channel A */ struct mutex lock; + /* + * delay after a rising edge on SCK until the data is ready DOUT + * this is dependent on the hx711 where the datasheet tells a + * maximum value of 100 ns + * but also on potential parasitic capacities on the wiring + */ + u32 data_ready_delay_ns; + u32 clock_frequency; }; static int hx711_cycle(struct hx711_data *hx711_data) { - int val; + unsigned long flags; /* * if preempted for more then 60us while PD_SCK is high: * hx711 is going in reset * ==> measuring is false */ - preempt_disable(); + local_irq_save(flags); gpiod_set_value(hx711_data->gpiod_pd_sck, 1); - val = gpiod_get_value(hx711_data->gpiod_dout); + + /* + * wait until DOUT is ready + * it turned out that parasitic capacities are extending the time + * until DOUT has reached it's value + */ + ndelay(hx711_data->data_ready_delay_ns); + /* * here we are not waiting for 0.2 us as suggested by the datasheet, * because the oscilloscope showed in a test scenario @@ -110,9 +125,16 @@ static int hx711_cycle(struct hx711_data *hx711_data) * and 0.56 us for PD_SCK low on TI Sitara with 800 MHz */ gpiod_set_value(hx711_data->gpiod_pd_sck, 0); - preempt_enable(); + local_irq_restore(flags); - return val; + /* + * make it a square wave for addressing cases with capacitance on + * PC_SCK + */ + ndelay(hx711_data->data_ready_delay_ns); + + /* sample as late as possible */ + return gpiod_get_value(hx711_data->gpiod_dout); } static int hx711_read(struct hx711_data *hx711_data) @@ -401,6 +423,7 @@ static const struct iio_chan_spec hx711_chan_spec[] = { static int hx711_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; struct hx711_data *hx711_data; struct iio_dev *indio_dev; int ret; @@ -474,6 +497,22 @@ static int hx711_probe(struct platform_device *pdev) hx711_data->gain_set = 128; hx711_data->gain_chan_a = 128; + hx711_data->clock_frequency = 400000; + ret = of_property_read_u32(np, "clock-frequency", + &hx711_data->clock_frequency); + + /* + * datasheet says the high level of PD_SCK has a maximum duration + * of 50 microseconds + */ + if (hx711_data->clock_frequency < 20000) { + dev_warn(dev, "clock-frequency too low - assuming 400 kHz\n"); + hx711_data->clock_frequency = 400000; + } + + hx711_data->data_ready_delay_ns = + 1000000000 / hx711_data->clock_frequency; + platform_set_drvdata(pdev, indio_dev); indio_dev->name = "hx711"; |