Commit fa6a8adf authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-4.11c' of...

Merge tag 'iio-for-4.11c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:

Third set of new device support, features and cleanups for IIO in the 4.11 cycle

This also involves a merge of the ib-mid-iio-pwm-4.11 branch from mfd to
bring in support for the stm32 timer triggers needed for the buffered
features in the stm32 adc driver.

New device support:
* Amligic Meson SAR ADC
  - new driver and bindings
* cros_ec barometer
  - new driver
* max5481 digital potentiometers
  - new driver for 5481, 5482, 5483 and 5484
* Renesas GyroADC - a very specific spi offload engine for ADCs
  - new driver and bindings.
* srf08 ultrasonic ranger
  - new driver, bindings and ABI docs,

New features
* Qualcomm PM8xxx ADC bindings.
  - due to a trivial build issues the driver will be following shortly.
* stm32 ADC
  - Triggered buffer mode
  - Allow use of stm32 timer triggers
  - Add trigger polarity control
  - Optional DMA support with bindings update
* stx104
  - add support for gpio names
  - support set_multiple callback
* tmp007
  - optional interrupt support

Cleanups
* ad7150
  - alignment fix.
* ad7816
  - octal rather than symbolic permissions.
* lsm6dsx
  - allow selection of data ready pin via device tree bindings.
* ssp_sensors
  - use devm_iio_device_register to handle unregister automatically.
* stx104
  - use devm functions in probe allowing removal or the remove function.
  - drop unneeded struct stx104_dev
* tmp007
  - fix the name attribute to be a meaninful description of the part.
parents 20380430 bfe7288e
What: /sys/bus/iio/devices/triggerX/trigger_polarity
KernelVersion: 4.11
Contact: fabrice.gasnier@st.com
Description:
The STM32 ADC can be configured to use external trigger sources
(e.g. timers, pwm or exti gpio). Then, it can be tuned to start
conversions on external trigger by either:
- "rising-edge"
- "falling-edge"
- "both-edges".
Reading returns current trigger polarity.
Writing value before enabling conversions sets trigger polarity.
What: /sys/bus/iio/devices/triggerX/trigger_polarity_available
KernelVersion: 4.11
Contact: fabrice.gasnier@st.com
Description:
List all available trigger_polarity settings.
What /sys/bus/iio/devices/iio:deviceX/sensor_sensitivity
Date: January 2017
KernelVersion: 4.11
Contact: linux-iio@vger.kernel.org
Description:
Show or set the gain boost of the amp, from 0-31 range.
default 31
What /sys/bus/iio/devices/iio:deviceX/sensor_max_range
Date: January 2017
KernelVersion: 4.11
Contact: linux-iio@vger.kernel.org
Description:
Show or set the maximum range between the sensor and the
first object echoed in meters. Default value is 6.020.
This setting limits the time the driver is waiting for a
echo.
Showing the range of available values is represented as the
minimum value, the step and the maximum value, all enclosed
in square brackets.
Example:
[0.043 0.043 11.008]
What: /sys/bus/iio/devices/triggerX/master_mode_available
KernelVersion: 4.11
Contact: benjamin.gaignard@st.com
Description:
Reading returns the list possible master modes which are:
- "reset" : The UG bit from the TIMx_EGR register is used as trigger output (TRGO).
- "enable" : The Counter Enable signal CNT_EN is used as trigger output.
- "update" : The update event is selected as trigger output.
For instance a master timer can then be used as a prescaler for a slave timer.
- "compare_pulse" : The trigger output send a positive pulse when the CC1IF flag is to be set.
- "OC1REF" : OC1REF signal is used as trigger output.
- "OC2REF" : OC2REF signal is used as trigger output.
- "OC3REF" : OC3REF signal is used as trigger output.
- "OC4REF" : OC4REF signal is used as trigger output.
What: /sys/bus/iio/devices/triggerX/master_mode
KernelVersion: 4.11
Contact: benjamin.gaignard@st.com
Description:
Reading returns the current master modes.
Writing set the master mode
What: /sys/bus/iio/devices/triggerX/sampling_frequency
KernelVersion: 4.11
Contact: benjamin.gaignard@st.com
Description:
Reading returns the current sampling frequency.
Writing an value different of 0 set and start sampling.
Writing 0 stop sampling.
......@@ -36,6 +36,7 @@ dallas,ds1775 Tiny Digital Thermometer and Thermostat
dallas,ds3232 Extremely Accurate I²C RTC with Integrated Crystal and SRAM
dallas,ds4510 CPU Supervisor with Nonvolatile Memory and Programmable I/O
dallas,ds75 Digital Thermometer and Thermostat
devantech,srf08 Devantech SRF08 ultrasonic ranger
dlg,da9053 DA9053: flexible system level PMIC with multicore support
dlg,da9063 DA9063: system PMIC for quad-core application processors
domintech,dmard09 DMARD09: 3-axis Accelerometer
......
* Amlogic Meson SAR (Successive Approximation Register) A/D converter
Required properties:
- compatible: depending on the SoC this should be one of:
- "amlogic,meson-gxbb-saradc" for GXBB
- "amlogic,meson-gxl-saradc" for GXL
- "amlogic,meson-gxm-saradc" for GXM
along with the generic "amlogic,meson-saradc"
- reg: the physical base address and length of the registers
- clocks: phandle and clock identifier (see clock-names)
- clock-names: mandatory clocks:
- "clkin" for the reference clock (typically XTAL)
- "core" for the SAR ADC core clock
optional clocks:
- "sana" for the analog clock
- "adc_clk" for the ADC (sampling) clock
- "adc_sel" for the ADC (sampling) clock mux
- vref-supply: the regulator supply for the ADC reference voltage
- #io-channel-cells: must be 1, see ../iio-bindings.txt
Example:
saradc: adc@8680 {
compatible = "amlogic,meson-gxl-saradc", "amlogic,meson-saradc";
#io-channel-cells = <1>;
reg = <0x0 0x8680 0x0 0x34>;
clocks = <&xtal>,
<&clkc CLKID_SAR_ADC>,
<&clkc CLKID_SANA>,
<&clkc CLKID_SAR_ADC_CLK>,
<&clkc CLKID_SAR_ADC_SEL>;
clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel";
};
Qualcomm's PM8xxx voltage XOADC
The Qualcomm PM8xxx PMICs contain a HK/XO ADC (Housekeeping/Crystal
oscillator ADC) encompassing PM8018, PM8038, PM8058 and PM8921.
Required properties:
- compatible: should be one of:
"qcom,pm8018-adc"
"qcom,pm8038-adc"
"qcom,pm8058-adc"
"qcom,pm8921-adc"
- reg: should contain the ADC base address in the PMIC, typically
0x197.
- xoadc-ref-supply: should reference a regulator that can supply
a reference voltage on demand. The reference voltage may vary
with PMIC variant but is typically something like 2.2 or 1.8V.
The following required properties are standard for IO channels, see
iio-bindings.txt for more details:
- #address-cells: should be set to <1>
- #size-cells: should be set to <0>
- #io-channel-cells: should be set to <1>
- interrupts: should refer to the parent PMIC interrupt controller
and reference the proper ADC interrupt.
Required subnodes:
The ADC channels are configured as subnodes of the ADC. Since some of
them are used for calibrating the ADC, these nodes are compulsory:
adc-channel@c {
reg = <0x0c>;
};
adc-channel@d {
reg = <0x0d>;
};
adc-channel@f {
reg = <0x0f>;
};
These three nodes are used for absolute and ratiometric calibration
and only need to have these reg values: they are by hardware definition
1:1 ratio converters that sample 625, 1250 and 0 milliV and create
an interpolation calibration for all other ADCs.
Optional subnodes: any channels other than channel 0x0c, 0x0d and
0x0f are optional.
Required channel node properties:
- reg: should contain the hardware channel number in the range
0 .. 0x0f (4 bits). The hardware only supports 16 channels.
Optional channel node properties:
- qcom,decimation:
Value type: <u32>
Definition: This parameter is used to decrease the ADC sampling rate.
Quicker measurements can be made by reducing the decimation ratio.
Valid values are 512, 1024, 2048, 4096.
If the property is not found, a default value of 512 will be used.
- qcom,ratiometric:
Value type: <u32>
Definition: Channel calibration type. If this property is specified
VADC will use a special voltage references for channel
calibration. The available references are specified in the
as a u32 value setting (see below) and it is compulsory
to also specify this reference if ratiometric calibration
is selected.
If the property is not found, the channel will be
calibrated with the 0.625V and 1.25V reference channels, also
known as an absolute calibration.
The reference voltage pairs when using ratiometric calibration:
0 = XO_IN/XOADC_GND
1 = PMIC_IN/XOADC_GND
2 = PMIC_IN/BMS_CSP
3 (invalid)
4 = XOADC_GND/XOADC_GND
5 = XOADC_VREF/XOADC_GND
Example:
xoadc: xoadc@197 {
compatible = "qcom,pm8058-adc";
reg = <0x197>;
interrupt-parent = <&pm8058>;
interrupts = <76 1>;
#address-cells = <1>;
#size-cells = <0>;
#io-channel-cells = <1>;
vcoin: adc-channel@0 {
reg = <0x00>;
};
vbat: adc-channel@1 {
reg = <0x01>;
};
dcin: adc-channel@2 {
reg = <0x02>;
};
ichg: adc-channel@3 {
reg = <0x03>;
};
vph_pwr: adc-channel@4 {
reg = <0x04>;
};
usb_vbus: adc-channel@a {
reg = <0x0a>;
};
die_temp: adc-channel@b {
reg = <0x0b>;
};
ref_625mv: adc-channel@c {
reg = <0x0c>;
};
ref_1250mv: adc-channel@d {
reg = <0x0d>;
};
ref_325mv: adc-channel@e {
reg = <0x0e>;
};
ref_muxoff: adc-channel@f {
reg = <0x0f>;
};
};
/* IIO client node */
iio-hwmon {
compatible = "iio-hwmon";
io-channels = <&xoadc 0x01>, /* Battery */
<&xoadc 0x02>, /* DC in (charger) */
<&xoadc 0x04>, /* VPH the main system voltage */
<&xoadc 0x0b>, /* Die temperature */
<&xoadc 0x0c>, /* Reference voltage 1.25V */
<&xoadc 0x0d>, /* Reference voltage 0.625V */
<&xoadc 0x0e>; /* Reference voltage 0.325V */
};
* Renesas RCar GyroADC device driver
The GyroADC block is a reduced SPI block with up to 8 chipselect lines,
which supports the SPI protocol of a selected few SPI ADCs. The SPI ADCs
are sampled by the GyroADC block in a round-robin fashion and the result
presented in the GyroADC registers.
Required properties:
- compatible: Should be "<soc-specific>", "renesas,rcar-gyroadc".
The <soc-specific> should be one of:
renesas,r8a7791-gyroadc - for the GyroADC block present
in r8a7791 SoC
renesas,r8a7792-gyroadc - for the GyroADC with interrupt
block present in r8a7792 SoC
- reg: Address and length of the register set for the device
- clocks: References to all the clocks specified in the clock-names
property as specified in
Documentation/devicetree/bindings/clock/clock-bindings.txt.
- clock-names: Shall contain "fck" and "if". The "fck" is the GyroADC block
clock, the "if" is the interface clock.
- power-domains: Must contain a reference to the PM domain, if available.
- #address-cells: Should be <1> (setting for the subnodes) for all ADCs
except for "fujitsu,mb88101a". Should be <0> (setting for
only subnode) for "fujitsu,mb88101a".
- #size-cells: Should be <0> (setting for the subnodes)
Sub-nodes:
You must define subnode(s) which select the connected ADC type and reference
voltage for the GyroADC channels.
Required properties for subnodes:
- compatible: Should be either of:
"fujitsu,mb88101a"
- Fujitsu MB88101A compatible mode,
12bit sampling, up to 4 channels can be sampled in
round-robin fashion. One Fujitsu chip supplies four
GyroADC channels with data as it contains four ADCs
on the chip and thus for 4-channel operation, single
MB88101A is required. The Cx chipselect lines of the
MB88101A connect directly to two CHS lines of the
GyroADC, no demuxer is required. The data out line
of each MB88101A connects to a shared input pin of
the GyroADC.
"ti,adcs7476" or "ti,adc121" or "adi,ad7476"
- TI ADCS7476 / TI ADC121 / ADI AD7476 compatible mode,
15bit sampling, up to 8 channels can be sampled in
round-robin fashion. One TI/ADI chip supplies single
ADC channel with data, thus for 8-channel operation,
8 chips are required. A 3:8 chipselect demuxer is
required to connect the nCS line of the TI/ADI chips
to the GyroADC, while MISO line of each TI/ADI ADC
connects to a shared input pin of the GyroADC.
"maxim,max1162" or "maxim,max11100"
- Maxim MAX1162 / Maxim MAX11100 compatible mode,
16bit sampling, up to 8 channels can be sampled in
round-robin fashion. One Maxim chip supplies single
ADC channel with data, thus for 8-channel operation,
8 chips are required. A 3:8 chipselect demuxer is
required to connect the nCS line of the MAX chips
to the GyroADC, while MISO line of each Maxim ADC
connects to a shared input pin of the GyroADC.
- reg: Should be the number of the analog input. Should be present
for all ADCs except "fujitsu,mb88101a".
- vref-supply: Reference to the channel reference voltage regulator.
Example:
vref_max1162: regulator-vref-max1162 {
compatible = "regulator-fixed";
regulator-name = "MAX1162 Vref";
regulator-min-microvolt = <4096000>;
regulator-max-microvolt = <4096000>;
};
adc@e6e54000 {
compatible = "renesas,r8a7791-gyroadc", "renesas,rcar-gyroadc";
reg = <0 0xe6e54000 0 64>;
clocks = <&mstp9_clks R8A7791_CLK_GYROADC>, <&clk_65m>;
clock-names = "fck", "if";
power-domains = <&sysc R8A7791_PD_ALWAYS_ON>;
pinctrl-0 = <&adc_pins>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
reg = <0>;
compatible = "maxim,max1162";
vref-supply = <&vref_max1162>;
};
adc@1 {
reg = <1>;
compatible = "maxim,max1162";
vref-supply = <&vref_max1162>;
};
};
......@@ -53,6 +53,11 @@ Required properties:
- #io-channel-cells = <1>: See the IIO bindings section "IIO consumers" in
Documentation/devicetree/bindings/iio/iio-bindings.txt
Optional properties:
- dmas: Phandle to dma channel for this ADC instance.
See ../../dma/dma.txt for details.
- dma-names: Must be "rx" when dmas property is being used.
Example:
adc: adc@40012000 {
compatible = "st,stm32f4-adc-core";
......@@ -77,6 +82,8 @@ Example:
interrupt-parent = <&adc>;
interrupts = <0>;
st,adc-channels = <8>;
dmas = <&dma2 0 0 0x400 0x0>;
dma-names = "rx";
};
...
other adc child nodes follow...
......
......@@ -7,6 +7,8 @@ Required properties:
- reg: i2c address of the sensor / spi cs line
Optional properties:
- st,drdy-int-pin: the pin on the package that will be used to signal
"data ready" (valid values: 1 or 2).
- interrupt-parent: should be the phandle for the interrupt controller
- interrupts: interrupt mapping for IRQ. It should be configured with
flags IRQ_TYPE_LEVEL_HIGH or IRQ_TYPE_EDGE_RISING.
......
* Maxim Linear-Taper Digital Potentiometer MAX5481-MAX5484
The node for this driver must be a child node of a SPI controller, hence
all mandatory properties described in
Documentation/devicetree/bindings/spi/spi-bus.txt
must be specified.
Required properties:
- compatible: Must be one of the following, depending on the
model:
"maxim,max5481"
"maxim,max5482"
"maxim,max5483"
"maxim,max5484"
Example:
max548x: max548x@0 {
compatible = "maxim,max5482";
spi-max-frequency = <7000000>;
reg = <0>; /* chip-select */
};
......@@ -18,10 +18,18 @@ Required properties:
1 SDA 0x46
1 SCL 0x47
Optional properties:
- interrupt-parent: should be the phandle for the interrupt controller
- interrupts: interrupt mapping for GPIO IRQ (level active low)
Example:
tmp007@40 {
compatible = "ti,tmp007";
reg = <0x40>;
interrupt-parent = <&gpio0>;
interrupts = <5 0x08>;
};
STMicroelectronics STM32 Timers IIO timer bindings
Must be a sub-node of an STM32 Timers device tree node.
See ../mfd/stm32-timers.txt for details about the parent node.
Required parameters:
- compatible: Must be "st,stm32-timer-trigger".
- reg: Identify trigger hardware block.
Example:
timers@40010000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "st,stm32-timers";
reg = <0x40010000 0x400>;
clocks = <&rcc 0 160>;
clock-names = "clk_int";
timer@0 {
compatible = "st,stm32-timer-trigger";
reg = <0>;
};
};
STM32 Timers driver bindings
This IP provides 3 types of timer along with PWM functionality:
- advanced-control timers consist of a 16-bit auto-reload counter driven by a programmable
prescaler, break input feature, PWM outputs and complementary PWM ouputs channels.
- general-purpose timers consist of a 16-bit or 32-bit auto-reload counter driven by a
programmable prescaler and PWM outputs.
- basic timers consist of a 16-bit auto-reload counter driven by a programmable prescaler.
Required parameters:
- compatible: must be "st,stm32-timers"
- reg: Physical base address and length of the controller's
registers.
- clock-names: Set to "int".
- clocks: Phandle to the clock used by the timer module.
For Clk properties, please refer to ../clock/clock-bindings.txt
Optional parameters:
- resets: Phandle to the parent reset controller.
See ../reset/st,stm32-rcc.txt
Optional subnodes:
- pwm: See ../pwm/pwm-stm32.txt
- timer: See ../iio/timer/stm32-timer-trigger.txt
Example:
timers@40010000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "st,stm32-timers";
reg = <0x40010000 0x400>;
clocks = <&rcc 0 160>;
clock-names = "clk_int";
pwm {
compatible = "st,stm32-pwm";
pinctrl-0 = <&pwm1_pins>;
pinctrl-names = "default";
};
timer@0 {
compatible = "st,stm32-timer-trigger";
reg = <0>;
};
};
STMicroelectronics STM32 Timers PWM bindings
Must be a sub-node of an STM32 Timers device tree node.
See ../mfd/stm32-timers.txt for details about the parent node.
Required parameters:
- compatible: Must be "st,stm32-pwm".
- pinctrl-names: Set to "default".
- pinctrl-0: List of phandles pointing to pin configuration nodes for PWM module.
For Pinctrl properties see ../pinctrl/pinctrl-bindings.txt
Optional parameters:
- st,breakinput: One or two <index level filter> to describe break input configurations.
"index" indicates on which break input (0 or 1) the configuration
should be applied.
"level" gives the active level (0=low or 1=high) of the input signal
for this configuration.
"filter" gives the filtering value to be applied.
Example:
timers@40010000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "st,stm32-timers";
reg = <0x40010000 0x400>;
clocks = <&rcc 0 160>;
clock-names = "clk_int";
pwm {
compatible = "st,stm32-pwm";
pinctrl-0 = <&pwm1_pins>;
pinctrl-names = "default";
st,breakinput = <0 1 5>;
};
};
......@@ -76,6 +76,7 @@ dallas Maxim Integrated Products (formerly Dallas Semiconductor)
davicom DAVICOM Semiconductor, Inc.
delta Delta Electronics, Inc.
denx Denx Software Engineering
devantech Devantech, Ltd.
digi Digi International Inc.
digilent Diglent, Inc.
dlg Dialog Semiconductor
......
......@@ -10439,6 +10439,12 @@ L: linux-renesas-soc@vger.kernel.org
F: drivers/net/ethernet/renesas/
F: include/linux/sh_eth.h
RENESAS R-CAR GYROADC DRIVER
M: Marek Vasut <marek.vasut@gmail.com>
L: linux-iio@vger.kernel.org
S: Supported
F: drivers/iio/adc/rcar_gyro_adc.c
RENESAS USB2 PHY DRIVER
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
L: linux-renesas-soc@vger.kernel.org
......
......@@ -136,7 +136,7 @@ static int ssp_accel_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev);
ret = iio_device_register(indio_dev);
ret = devm_iio_device_register(&pdev->dev, indio_dev);
if (ret < 0)
return ret;
......@@ -146,21 +146,11 @@ static int ssp_accel_probe(struct platform_device *pdev)
return 0;
}
static int ssp_accel_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
iio_device_unregister(indio_dev);
return 0;
}
static struct platform_driver ssp_accel_driver = {
.driver = {
.name = SSP_ACCEL_NAME,
},
.probe = ssp_accel_probe,
.remove = ssp_accel_remove,
};
module_platform_driver(ssp_accel_driver);
......
......@@ -399,6 +399,18 @@ config MEN_Z188_ADC
This driver can also be built as a module. If so, the module will be
called men_z188_adc.
config MESON_SARADC
tristate "Amlogic Meson SAR ADC driver"
default ARCH_MESON
depends on OF && COMMON_CLK && (ARCH_MESON || COMPILE_TEST)
select REGMAP_MMIO
help
Say yes here to build support for the SAR ADC found in Amlogic Meson
SoCs.
To compile this driver as a module, choose M here: the
module will be called meson_saradc.
config MXS_LRADC
tristate "Freescale i.MX23/i.MX28 LRADC"
depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM
......@@ -458,6 +470,19 @@ config QCOM_SPMI_VADC
To compile this driver as a module, choose M here: the module will
be called qcom-spmi-vadc.
config RCAR_GYRO_ADC
tristate "Renesas R-Car GyroADC driver"
depends on ARCH_RCAR_GEN2 || (ARM && COMPILE_TEST)
help
Say yes here to build support for the GyroADC found in Renesas
R-Car Gen2 SoCs. This block is a simple SPI offload engine for
reading data out of attached compatible ADCs in a round-robin
fashion. Up to 4 or 8 ADC channels are supported by this block,
depending on which ADCs are attached.
To compile this driver as a module, choose M here: the
module will be called rcar-gyroadc.
config ROCKCHIP_SARADC
tristate "Rockchip SARADC driver"
depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST)
......@@ -472,8 +497,13 @@ config ROCKCHIP_SARADC
config STM32_ADC_CORE
tristate "STMicroelectronics STM32 adc core"
depends on ARCH_STM32 || COMPILE_TEST
depends on HAS_DMA
depends on OF
depends on REGULATOR
select IIO_BUFFER
select MFD_STM32_TIMERS
select IIO_STM32_TIMER_TRIGGER
select IIO_TRIGGERED_BUFFER
help
Select this option to enable the core driver for STMicroelectronics
STM32 analog-to-digital converter (ADC).
......
......@@ -38,11 +38,13 @@ obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_MCP3422) += mcp3422.o
obj-$(CONFIG_MEDIATEK_MT6577_AUXADC) += mt6577_auxadc.o
obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o
obj-$(CONFIG_MESON_SARADC) += meson_saradc.o
obj-$(CONFIG_MXS_LRADC) += mxs-lradc.o
obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
obj-$(CONFIG_QCOM_SPMI_VADC) += qcom-spmi-vadc.o
obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o
obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
obj-$(CONFIG_STX104) += stx104.o
obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
......
/*
* Amlogic Meson Successive Approximation Register (SAR) A/D Converter
*
* Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/iio/iio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#define MESON_SAR_ADC_REG0 0x00
#define MESON_SAR_ADC_REG0_PANEL_DETECT BIT(31)
#define MESON_SAR_ADC_REG0_BUSY_MASK GENMASK(30, 28)
#define MESON_SAR_ADC_REG0_DELTA_BUSY BIT(30)
#define MESON_SAR_ADC_REG0_AVG_BUSY BIT(29)
#define MESON_SAR_ADC_REG0_SAMPLE_BUSY BIT(28)
#define MESON_SAR_ADC_REG0_FIFO_FULL BIT(27)
#define MESON_SAR_ADC_REG0_FIFO_EMPTY BIT(26)
#define MESON_SAR_ADC_REG0_FIFO_COUNT_MASK GENMASK(25, 21)
#define MESON_SAR_ADC_REG0_ADC_BIAS_CTRL_MASK GENMASK(20, 19)
#define MESON_SAR_ADC_REG0_CURR_CHAN_ID_MASK GENMASK(18, 16)
#define MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL BIT(15)
#define MESON_SAR_ADC_REG0_SAMPLING_STOP BIT(14)
#define MESON_SAR_ADC_REG0_CHAN_DELTA_EN_MASK GENMASK(13, 12)
#define MESON_SAR_ADC_REG0_DETECT_IRQ_POL BIT(10)
#define MESON_SAR_ADC_REG0_DETECT_IRQ_EN BIT(9)
#define MESON_SAR_ADC_REG0_FIFO_CNT_IRQ_MASK GENMASK(8, 4)
#define MESON_SAR_ADC_REG0_FIFO_IRQ_EN BIT(3)
#define MESON_SAR_ADC_REG0_SAMPLING_START BIT(2)
#define MESON_SAR_ADC_REG0_CONTINUOUS_EN BIT(1)
#define MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE BIT(0)
#define MESON_SAR_ADC_CHAN_LIST 0x04
#define MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK GENMASK(26, 24)
#define MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(_chan) \
(GENMASK(2, 0) << ((_chan) * 3))
#define MESON_SAR_ADC_AVG_CNTL 0x08
#define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(_chan) \
(16 + ((_chan) * 2))
#define MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(_chan) \
(GENMASK(17, 16) << ((_chan) * 2))
#define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(_chan) \
(0 + ((_chan) * 2))
#define MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(_chan) \
(GENMASK(1, 0) << ((_chan) * 2))
#define MESON_SAR_ADC_REG3 0x0c
#define MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY BIT(31)
#define MESON_SAR_ADC_REG3_CLK_EN BIT(30)
#define MESON_SAR_ADC_REG3_BL30_INITIALIZED BIT(28)
#define MESON_SAR_ADC_REG3_CTRL_CONT_RING_COUNTER_EN BIT(27)
#define MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE BIT(26)
#define MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK GENMASK(25, 23)
#define MESON_SAR_ADC_REG3_DETECT_EN BIT(22)
#define MESON_SAR_ADC_REG3_ADC_EN BIT(21)
#define MESON_SAR_ADC_REG3_PANEL_DETECT_COUNT_MASK GENMASK(20, 18)
#define MESON_SAR_ADC_REG3_PANEL_DETECT_FILTER_TB_MASK GENMASK(17, 16)
#define MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT 10
#define MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH 5
#define MESON_SAR_ADC_REG3_BLOCK_DLY_SEL_MASK GENMASK(9, 8)
#define MESON_SAR_ADC_REG3_BLOCK_DLY_MASK GENMASK(7, 0)
#define MESON_SAR_ADC_DELAY 0x10
#define MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK GENMASK(25, 24)
#define MESON_SAR_ADC_DELAY_BL30_BUSY BIT(15)
#define MESON_SAR_ADC_DELAY_KERNEL_BUSY BIT(14)
#define MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK GENMASK(23, 16)
#define MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK GENMASK(9, 8)
#define MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK GENMASK(7, 0)
#define MESON_SAR_ADC_LAST_RD 0x14
#define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL1_MASK GENMASK(23, 16)
#define MESON_SAR_ADC_LAST_RD_LAST_CHANNEL0_MASK GENMASK(9, 0)
#define MESON_SAR_ADC_FIFO_RD 0x18
#define MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK GENMASK(14, 12)
#define MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK GENMASK(11, 0)
#define MESON_SAR_ADC_AUX_SW 0x1c
#define MESON_SAR_ADC_AUX_SW_MUX_SEL_CHAN_MASK(_chan) \
(GENMASK(10, 8) << (((_chan) - 2) * 2))
#define MESON_SAR_ADC_AUX_SW_VREF_P_MUX BIT(6)
#define MESON_SAR_ADC_AUX_SW_VREF_N_MUX BIT(5)
#define MESON_SAR_ADC_AUX_SW_MODE_SEL BIT(4)
#define MESON_SAR_ADC_AUX_SW_YP_DRIVE_SW BIT(3)
#define MESON_SAR_ADC_AUX_SW_XP_DRIVE_SW BIT(2)
#define MESON_SAR_ADC_AUX_SW_YM_DRIVE_SW BIT(1)
#define MESON_SAR_ADC_AUX_SW_XM_DRIVE_SW BIT(0)
#define MESON_SAR_ADC_CHAN_10_SW 0x20
#define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MUX_SEL_MASK GENMASK(25, 23)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_P_MUX BIT(22)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN1_VREF_N_MUX BIT(21)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN1_MODE_SEL BIT(20)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YP_DRIVE_SW BIT(19)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XP_DRIVE_SW BIT(18)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN1_YM_DRIVE_SW BIT(17)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN1_XM_DRIVE_SW BIT(16)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MUX_SEL_MASK GENMASK(9, 7)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_P_MUX BIT(6)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN0_VREF_N_MUX BIT(5)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN0_MODE_SEL BIT(4)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YP_DRIVE_SW BIT(3)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XP_DRIVE_SW BIT(2)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN0_YM_DRIVE_SW BIT(1)
#define MESON_SAR_ADC_CHAN_10_SW_CHAN0_XM_DRIVE_SW BIT(0)
#define MESON_SAR_ADC_DETECT_IDLE_SW 0x24
#define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_SW_EN BIT(26)
#define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK GENMASK(25, 23)
#define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_P_MUX BIT(22)
#define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_VREF_N_MUX BIT(21)
#define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MODE_SEL BIT(20)
#define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YP_DRIVE_SW BIT(19)
#define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XP_DRIVE_SW BIT(18)
#define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_YM_DRIVE_SW BIT(17)
#define MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_XM_DRIVE_SW BIT(16)
#define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK GENMASK(9, 7)
#define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_P_MUX BIT(6)
#define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_VREF_N_MUX BIT(5)
#define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MODE_SEL BIT(4)
#define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YP_DRIVE_SW BIT(3)
#define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XP_DRIVE_SW BIT(2)
#define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_YM_DRIVE_SW BIT(1)
#define MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_XM_DRIVE_SW BIT(0)
#define MESON_SAR_ADC_DELTA_10 0x28
#define MESON_SAR_ADC_DELTA_10_TEMP_SEL BIT(27)
#define MESON_SAR_ADC_DELTA_10_TS_REVE1 BIT(26)
#define MESON_SAR_ADC_DELTA_10_CHAN1_DELTA_VALUE_MASK GENMASK(25, 16)
#define MESON_SAR_ADC_DELTA_10_TS_REVE0 BIT(15)
#define MESON_SAR_ADC_DELTA_10_TS_C_SHIFT 11
#define MESON_SAR_ADC_DELTA_10_TS_C_MASK GENMASK(14, 11)
#define MESON_SAR_ADC_DELTA_10_TS_VBG_EN BIT(10)
#define MESON_SAR_ADC_DELTA_10_CHAN0_DELTA_VALUE_MASK GENMASK(9, 0)
/*
* NOTE: registers from here are undocumented (the vendor Linux kernel driver
* and u-boot source served as reference). These only seem to be relevant on
* GXBB and newer.
*/
#define MESON_SAR_ADC_REG11 0x2c
#define MESON_SAR_ADC_REG11_BANDGAP_EN BIT(13)
#define MESON_SAR_ADC_REG13 0x34
#define MESON_SAR_ADC_REG13_12BIT_CALIBRATION_MASK GENMASK(13, 8)
#define MESON_SAR_ADC_MAX_FIFO_SIZE 32
#define MESON_SAR_ADC_CHAN(_chan) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = _chan, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_AVERAGE_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.datasheet_name = "SAR_ADC_CH"#_chan, \
}
/*
* TODO: the hardware supports IIO_TEMP for channel 6 as well which is
* currently not supported by this driver.
*/
static const struct iio_chan_spec meson_sar_adc_iio_channels[] = {
MESON_SAR_ADC_CHAN(0),
MESON_SAR_ADC_CHAN(1),
MESON_SAR_ADC_CHAN(2),
MESON_SAR_ADC_CHAN(3),
MESON_SAR_ADC_CHAN(4),
MESON_SAR_ADC_CHAN(5),
MESON_SAR_ADC_CHAN(6),
MESON_SAR_ADC_CHAN(7),
IIO_CHAN_SOFT_TIMESTAMP(8),
};
enum meson_sar_adc_avg_mode {
NO_AVERAGING = 0x0,
MEAN_AVERAGING = 0x1,
MEDIAN_AVERAGING = 0x2,
};
enum meson_sar_adc_num_samples {
ONE_SAMPLE = 0x0,
TWO_SAMPLES = 0x1,
FOUR_SAMPLES = 0x2,
EIGHT_SAMPLES = 0x3,
};
enum meson_sar_adc_chan7_mux_sel {
CHAN7_MUX_VSS = 0x0,
CHAN7_MUX_VDD_DIV4 = 0x1,
CHAN7_MUX_VDD_DIV2 = 0x2,
CHAN7_MUX_VDD_MUL3_DIV4 = 0x3,
CHAN7_MUX_VDD = 0x4,
CHAN7_MUX_CH7_INPUT = 0x7,
};
struct meson_sar_adc_data {
unsigned int resolution;
const char *name;
};
struct meson_sar_adc_priv {
struct regmap *regmap;
struct regulator *vref;
const struct meson_sar_adc_data *data;
struct clk *clkin;
struct clk *core_clk;
struct clk *sana_clk;
struct clk *adc_sel_clk;
struct clk *adc_clk;
struct clk_gate clk_gate;
struct clk *adc_div_clk;
struct clk_divider clk_div;
};
static const struct regmap_config meson_sar_adc_regmap_config = {
.reg_bits = 8,
.val_bits = 32,
.reg_stride = 4,
.max_register = MESON_SAR_ADC_REG13,
};
static unsigned int meson_sar_adc_get_fifo_count(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
u32 regval;
regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval);
return FIELD_GET(MESON_SAR_ADC_REG0_FIFO_COUNT_MASK, regval);
}
static int meson_sar_adc_wait_busy_clear(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int regval, timeout = 10000;
/*
* NOTE: we need a small delay before reading the status, otherwise
* the sample engine may not have started internally (which would
* seem to us that sampling is already finished).
*/
do {
udelay(1);
regmap_read(priv->regmap, MESON_SAR_ADC_REG0, &regval);
} while (FIELD_GET(MESON_SAR_ADC_REG0_BUSY_MASK, regval) && timeout--);
if (timeout < 0)
return -ETIMEDOUT;
return 0;
}
static int meson_sar_adc_read_raw_sample(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
int *val)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int ret, regval, fifo_chan, fifo_val, sum = 0, count = 0;
ret = meson_sar_adc_wait_busy_clear(indio_dev);
if (ret)
return ret;
while (meson_sar_adc_get_fifo_count(indio_dev) > 0 &&
count < MESON_SAR_ADC_MAX_FIFO_SIZE) {
regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, &regval);
fifo_chan = FIELD_GET(MESON_SAR_ADC_FIFO_RD_CHAN_ID_MASK,
regval);
if (fifo_chan != chan->channel)
continue;
fifo_val = FIELD_GET(MESON_SAR_ADC_FIFO_RD_SAMPLE_VALUE_MASK,
regval);
fifo_val &= (BIT(priv->data->resolution) - 1);
sum += fifo_val;
count++;
}
if (!count)
return -ENOENT;
*val = sum / count;
return 0;
}
static void meson_sar_adc_set_averaging(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum meson_sar_adc_avg_mode mode,
enum meson_sar_adc_num_samples samples)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int val, channel = chan->channel;
val = samples << MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_SHIFT(channel);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
MESON_SAR_ADC_AVG_CNTL_NUM_SAMPLES_MASK(channel),
val);
val = mode << MESON_SAR_ADC_AVG_CNTL_AVG_MODE_SHIFT(channel);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_AVG_CNTL,
MESON_SAR_ADC_AVG_CNTL_AVG_MODE_MASK(channel), val);
}
static void meson_sar_adc_enable_channel(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
u32 regval;
/*
* the SAR ADC engine allows sampling multiple channels at the same
* time. to keep it simple we're only working with one *internal*
* channel, which starts counting at index 0 (which means: count = 1).
*/
regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, 0);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
MESON_SAR_ADC_CHAN_LIST_MAX_INDEX_MASK, regval);
/* map channel index 0 to the channel which we want to read */
regval = FIELD_PREP(MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0),
chan->channel);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_CHAN_LIST,
MESON_SAR_ADC_CHAN_LIST_ENTRY_MASK(0), regval);
regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
chan->channel);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
MESON_SAR_ADC_DETECT_IDLE_SW_DETECT_MUX_MASK,
regval);
regval = FIELD_PREP(MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
chan->channel);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DETECT_IDLE_SW,
MESON_SAR_ADC_DETECT_IDLE_SW_IDLE_MUX_SEL_MASK,
regval);
if (chan->channel == 6)
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELTA_10,
MESON_SAR_ADC_DELTA_10_TEMP_SEL, 0);
}
static void meson_sar_adc_set_chan7_mux(struct iio_dev *indio_dev,
enum meson_sar_adc_chan7_mux_sel sel)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
u32 regval;
regval = FIELD_PREP(MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, sel);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
MESON_SAR_ADC_REG3_CTRL_CHAN7_MUX_SEL_MASK, regval);
usleep_range(10, 20);
}
static void meson_sar_adc_start_sample_engine(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE,
MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
MESON_SAR_ADC_REG0_SAMPLING_START,
MESON_SAR_ADC_REG0_SAMPLING_START);
}
static void meson_sar_adc_stop_sample_engine(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
MESON_SAR_ADC_REG0_SAMPLING_STOP,
MESON_SAR_ADC_REG0_SAMPLING_STOP);
/* wait until all modules are stopped */
meson_sar_adc_wait_busy_clear(indio_dev);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
MESON_SAR_ADC_REG0_SAMPLE_ENGINE_ENABLE, 0);
}
static int meson_sar_adc_lock(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int val, timeout = 10000;
mutex_lock(&indio_dev->mlock);
/* prevent BL30 from using the SAR ADC while we are using it */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY);
/* wait until BL30 releases it's lock (so we can use the SAR ADC) */
do {
udelay(1);
regmap_read(priv->regmap, MESON_SAR_ADC_DELAY, &val);
} while (val & MESON_SAR_ADC_DELAY_BL30_BUSY && timeout--);
if (timeout < 0)
return -ETIMEDOUT;
return 0;
}
static void meson_sar_adc_unlock(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
/* allow BL30 to use the SAR ADC again */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_KERNEL_BUSY, 0);
mutex_unlock(&indio_dev->mlock);
}
static void meson_sar_adc_clear_fifo(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int count;
for (count = 0; count < MESON_SAR_ADC_MAX_FIFO_SIZE; count++) {
if (!meson_sar_adc_get_fifo_count(indio_dev))
break;
regmap_read(priv->regmap, MESON_SAR_ADC_FIFO_RD, 0);
}
}
static int meson_sar_adc_get_sample(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum meson_sar_adc_avg_mode avg_mode,
enum meson_sar_adc_num_samples avg_samples,
int *val)
{
int ret;
ret = meson_sar_adc_lock(indio_dev);
if (ret)
return ret;
/* clear the FIFO to make sure we're not reading old values */
meson_sar_adc_clear_fifo(indio_dev);
meson_sar_adc_set_averaging(indio_dev, chan, avg_mode, avg_samples);
meson_sar_adc_enable_channel(indio_dev, chan);
meson_sar_adc_start_sample_engine(indio_dev);
ret = meson_sar_adc_read_raw_sample(indio_dev, chan, val);
meson_sar_adc_stop_sample_engine(indio_dev);
meson_sar_adc_unlock(indio_dev);
if (ret) {
dev_warn(indio_dev->dev.parent,
"failed to read sample for channel %d: %d\n",
chan->channel, ret);
return ret;
}
return IIO_VAL_INT;
}
static int meson_sar_adc_iio_info_read_raw(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
int *val, int *val2, long mask)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
return meson_sar_adc_get_sample(indio_dev, chan, NO_AVERAGING,
ONE_SAMPLE, val);
break;
case IIO_CHAN_INFO_AVERAGE_RAW:
return meson_sar_adc_get_sample(indio_dev, chan,
MEAN_AVERAGING, EIGHT_SAMPLES,
val);
break;
case IIO_CHAN_INFO_SCALE:
ret = regulator_get_voltage(priv->vref);
if (ret < 0) {
dev_err(indio_dev->dev.parent,
"failed to get vref voltage: %d\n", ret);
return ret;
}
*val = ret / 1000;
*val2 = priv->data->resolution;
return IIO_VAL_FRACTIONAL_LOG2;
default:
return -EINVAL;
}
}
static int meson_sar_adc_clk_init(struct iio_dev *indio_dev,
void __iomem *base)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
struct clk_init_data init;
const char *clk_parents[1];
init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_div",
of_node_full_name(indio_dev->dev.of_node));
init.flags = 0;
init.ops = &clk_divider_ops;
clk_parents[0] = __clk_get_name(priv->clkin);
init.parent_names = clk_parents;
init.num_parents = 1;
priv->clk_div.reg = base + MESON_SAR_ADC_REG3;
priv->clk_div.shift = MESON_SAR_ADC_REG3_ADC_CLK_DIV_SHIFT;
priv->clk_div.width = MESON_SAR_ADC_REG3_ADC_CLK_DIV_WIDTH;
priv->clk_div.hw.init = &init;
priv->clk_div.flags = 0;
priv->adc_div_clk = devm_clk_register(&indio_dev->dev,
&priv->clk_div.hw);
if (WARN_ON(IS_ERR(priv->adc_div_clk)))
return PTR_ERR(priv->adc_div_clk);
init.name = devm_kasprintf(&indio_dev->dev, GFP_KERNEL, "%s#adc_en",
of_node_full_name(indio_dev->dev.of_node));
init.flags = CLK_SET_RATE_PARENT;
init.ops = &clk_gate_ops;
clk_parents[0] = __clk_get_name(priv->adc_div_clk);
init.parent_names = clk_parents;
init.num_parents = 1;
priv->clk_gate.reg = base + MESON_SAR_ADC_REG3;
priv->clk_gate.bit_idx = fls(MESON_SAR_ADC_REG3_CLK_EN);
priv->clk_gate.hw.init = &init;
priv->adc_clk = devm_clk_register(&indio_dev->dev, &priv->clk_gate.hw);
if (WARN_ON(IS_ERR(priv->adc_clk)))
return PTR_ERR(priv->adc_clk);
return 0;
}
static int meson_sar_adc_init(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int regval, ret;
/*
* make sure we start at CH7 input since the other muxes are only used
* for internal calibration.
*/
meson_sar_adc_set_chan7_mux(indio_dev, CHAN7_MUX_CH7_INPUT);
/*
* leave sampling delay and the input clocks as configured by BL30 to
* make sure BL30 gets the values it expects when reading the
* temperature sensor.
*/
regmap_read(priv->regmap, MESON_SAR_ADC_REG3, &regval);
if (regval & MESON_SAR_ADC_REG3_BL30_INITIALIZED)
return 0;
meson_sar_adc_stop_sample_engine(indio_dev);
/* update the channel 6 MUX to select the temperature sensor */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG0,
MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL,
MESON_SAR_ADC_REG0_ADC_TEMP_SEN_SEL);
/* disable all channels by default */
regmap_write(priv->regmap, MESON_SAR_ADC_CHAN_LIST, 0x0);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
MESON_SAR_ADC_REG3_CTRL_SAMPLING_CLOCK_PHASE, 0);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY,
MESON_SAR_ADC_REG3_CNTL_USE_SC_DLY);
/* delay between two samples = (10+1) * 1uS */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_CNT_MASK,
10));
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
FIELD_PREP(MESON_SAR_ADC_DELAY_SAMPLE_DLY_SEL_MASK,
0));
/* delay between two samples = (10+1) * 1uS */
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_CNT_MASK,
10));
regmap_update_bits(priv->regmap, MESON_SAR_ADC_DELAY,
MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
FIELD_PREP(MESON_SAR_ADC_DELAY_INPUT_DLY_SEL_MASK,
1));
ret = clk_set_parent(priv->adc_sel_clk, priv->clkin);
if (ret) {
dev_err(indio_dev->dev.parent,
"failed to set adc parent to clkin\n");
return ret;
}
ret = clk_set_rate(priv->adc_clk, 1200000);
if (ret) {
dev_err(indio_dev->dev.parent,
"failed to set adc clock rate\n");
return ret;
}
return 0;
}
static int meson_sar_adc_hw_enable(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int ret;
ret = meson_sar_adc_lock(indio_dev);
if (ret)
goto err_lock;
ret = regulator_enable(priv->vref);
if (ret < 0) {
dev_err(indio_dev->dev.parent,
"failed to enable vref regulator\n");
goto err_vref;
}
ret = clk_prepare_enable(priv->core_clk);
if (ret) {
dev_err(indio_dev->dev.parent, "failed to enable core clk\n");
goto err_core_clk;
}
ret = clk_prepare_enable(priv->sana_clk);
if (ret) {
dev_err(indio_dev->dev.parent, "failed to enable sana clk\n");
goto err_sana_clk;
}
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
MESON_SAR_ADC_REG11_BANDGAP_EN,
MESON_SAR_ADC_REG11_BANDGAP_EN);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
MESON_SAR_ADC_REG3_ADC_EN,
MESON_SAR_ADC_REG3_ADC_EN);
udelay(5);
ret = clk_prepare_enable(priv->adc_clk);
if (ret) {
dev_err(indio_dev->dev.parent, "failed to enable adc clk\n");
goto err_adc_clk;
}
meson_sar_adc_unlock(indio_dev);
return 0;
err_adc_clk:
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
MESON_SAR_ADC_REG3_ADC_EN, 0);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
MESON_SAR_ADC_REG11_BANDGAP_EN, 0);
clk_disable_unprepare(priv->sana_clk);
err_sana_clk:
clk_disable_unprepare(priv->core_clk);
err_core_clk:
regulator_disable(priv->vref);
err_vref:
meson_sar_adc_unlock(indio_dev);
err_lock:
return ret;
}
static int meson_sar_adc_hw_disable(struct iio_dev *indio_dev)
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
int ret;
ret = meson_sar_adc_lock(indio_dev);
if (ret)
return ret;
clk_disable_unprepare(priv->adc_clk);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG3,
MESON_SAR_ADC_REG3_ADC_EN, 0);
regmap_update_bits(priv->regmap, MESON_SAR_ADC_REG11,
MESON_SAR_ADC_REG11_BANDGAP_EN, 0);
clk_disable_unprepare(priv->sana_clk);
clk_disable_unprepare(priv->core_clk);
regulator_disable(priv->vref);
meson_sar_adc_unlock(indio_dev);
return 0;
}
static const struct iio_info meson_sar_adc_iio_info = {
.read_raw = meson_sar_adc_iio_info_read_raw,
.driver_module = THIS_MODULE,
};
struct meson_sar_adc_data meson_sar_adc_gxbb_data = {
.resolution = 10,
.name = "meson-gxbb-saradc",
};
struct meson_sar_adc_data meson_sar_adc_gxl_data = {
.resolution = 12,
.name = "meson-gxl-saradc",
};
struct meson_sar_adc_data meson_sar_adc_gxm_data = {
.resolution = 12,
.name = "meson-gxm-saradc",
};
static const struct of_device_id meson_sar_adc_of_match[] = {
{
.compatible = "amlogic,meson-gxbb-saradc",
.data = &meson_sar_adc_gxbb_data,
}, {
.compatible = "amlogic,meson-gxl-saradc",
.data = &meson_sar_adc_gxl_data,
}, {
.compatible = "amlogic,meson-gxm-saradc",
.data = &meson_sar_adc_gxm_data,
},
{},
};
MODULE_DEVICE_TABLE(of, meson_sar_adc_of_match);
static int meson_sar_adc_probe(struct platform_device *pdev)
{
struct meson_sar_adc_priv *priv;
struct iio_dev *indio_dev;
struct resource *res;
void __iomem *base;
const struct of_device_id *match;
int ret;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
if (!indio_dev) {
dev_err(&pdev->dev, "failed allocating iio device\n");
return -ENOMEM;
}
priv = iio_priv(indio_dev);
match = of_match_device(meson_sar_adc_of_match, &pdev->dev);
priv->data = match->data;
indio_dev->name = priv->data->name;
indio_dev->dev.parent = &pdev->dev;
indio_dev->dev.of_node = pdev->dev.of_node;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &meson_sar_adc_iio_info;
indio_dev->channels = meson_sar_adc_iio_channels;
indio_dev->num_channels = ARRAY_SIZE(meson_sar_adc_iio_channels);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
&meson_sar_adc_regmap_config);
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
priv->clkin = devm_clk_get(&pdev->dev, "clkin");
if (IS_ERR(priv->clkin)) {
dev_err(&pdev->dev, "failed to get clkin\n");
return PTR_ERR(priv->clkin);
}
priv->core_clk = devm_clk_get(&pdev->dev, "core");
if (IS_ERR(priv->core_clk)) {
dev_err(&pdev->dev, "failed to get core clk\n");
return PTR_ERR(priv->core_clk);
}
priv->sana_clk = devm_clk_get(&pdev->dev, "sana");
if (IS_ERR(priv->sana_clk)) {
if (PTR_ERR(priv->sana_clk) == -ENOENT) {
priv->sana_clk = NULL;
} else {
dev_err(&pdev->dev, "failed to get sana clk\n");
return PTR_ERR(priv->sana_clk);
}
}
priv->adc_clk = devm_clk_get(&pdev->dev, "adc_clk");
if (IS_ERR(priv->adc_clk)) {
if (PTR_ERR(priv->adc_clk) == -ENOENT) {
priv->adc_clk = NULL;
} else {
dev_err(&pdev->dev, "failed to get adc clk\n");
return PTR_ERR(priv->adc_clk);
}
}
priv->adc_sel_clk = devm_clk_get(&pdev->dev, "adc_sel");
if (IS_ERR(priv->adc_sel_clk)) {
if (PTR_ERR(priv->adc_sel_clk) == -ENOENT) {
priv->adc_sel_clk = NULL;
} else {
dev_err(&pdev->dev, "failed to get adc_sel clk\n");
return PTR_ERR(priv->adc_sel_clk);
}
}
/* on pre-GXBB SoCs the SAR ADC itself provides the ADC clock: */
if (!priv->adc_clk) {
ret = meson_sar_adc_clk_init(indio_dev, base);
if (ret)
return ret;
}
priv->vref = devm_regulator_get(&pdev->dev, "vref");
if (IS_ERR(priv->vref)) {
dev_err(&pdev->dev, "failed to get vref regulator\n");
return PTR_ERR(priv->vref);
}
ret = meson_sar_adc_init(indio_dev);
if (ret)
goto err;
ret = meson_sar_adc_hw_enable(indio_dev);
if (ret)
goto err;
platform_set_drvdata(pdev, indio_dev);
ret = iio_device_register(indio_dev);
if (ret)
goto err_hw;
return 0;
err_hw:
meson_sar_adc_hw_disable(indio_dev);
err:
return ret;
}
static int meson_sar_adc_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
iio_device_unregister(indio_dev);
return meson_sar_adc_hw_disable(indio_dev);
}
static int __maybe_unused meson_sar_adc_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
return meson_sar_adc_hw_disable(indio_dev);
}
static int __maybe_unused meson_sar_adc_resume(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
return meson_sar_adc_hw_enable(indio_dev);
}
static SIMPLE_DEV_PM_OPS(meson_sar_adc_pm_ops,
meson_sar_adc_suspend, meson_sar_adc_resume);
static struct platform_driver meson_sar_adc_driver = {
.probe = meson_sar_adc_probe,
.remove = meson_sar_adc_remove,
.driver = {
.name = "meson-saradc",
.of_match_table = meson_sar_adc_of_match,
.pm = &meson_sar_adc_pm_ops,
},
};
module_platform_driver(meson_sar_adc_driver);
MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
MODULE_DESCRIPTION("Amlogic Meson SAR ADC driver");
MODULE_LICENSE("GPL v2");
/*
* Renesas R-Car GyroADC driver
*
* Copyright 2016 Marek Vasut <marek.vasut@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/regulator/consumer.h>
#include <linux/of_platform.h>
#include <linux/err.h>
#include <linux/pm_runtime.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#define DRIVER_NAME "rcar-gyroadc"
/* GyroADC registers. */
#define RCAR_GYROADC_MODE_SELECT 0x00
#define RCAR_GYROADC_MODE_SELECT_1_MB88101A 0x0
#define RCAR_GYROADC_MODE_SELECT_2_ADCS7476 0x1
#define RCAR_GYROADC_MODE_SELECT_3_MAX1162 0x3
#define RCAR_GYROADC_START_STOP 0x04
#define RCAR_GYROADC_START_STOP_START BIT(0)
#define RCAR_GYROADC_CLOCK_LENGTH 0x08
#define RCAR_GYROADC_1_25MS_LENGTH 0x0c
#define RCAR_GYROADC_REALTIME_DATA(ch) (0x10 + ((ch) * 4))
#define RCAR_GYROADC_100MS_ADDED_DATA(ch) (0x30 + ((ch) * 4))
#define RCAR_GYROADC_10MS_AVG_DATA(ch) (0x50 + ((ch) * 4))
#define RCAR_GYROADC_FIFO_STATUS 0x70
#define RCAR_GYROADC_FIFO_STATUS_EMPTY(ch) BIT(0 + (4 * (ch)))
#define RCAR_GYROADC_FIFO_STATUS_FULL(ch) BIT(1 + (4 * (ch)))
#define RCAR_GYROADC_FIFO_STATUS_ERROR(ch) BIT(2 + (4 * (ch)))
#define RCAR_GYROADC_INTR 0x74
#define RCAR_GYROADC_INTR_INT BIT(0)
#define RCAR_GYROADC_INTENR 0x78
#define RCAR_GYROADC_INTENR_INTEN BIT(0)
#define RCAR_GYROADC_SAMPLE_RATE 800 /* Hz */
#define RCAR_GYROADC_RUNTIME_PM_DELAY_MS 2000
enum rcar_gyroadc_model {
RCAR_GYROADC_MODEL_DEFAULT,
RCAR_GYROADC_MODEL_R8A7792,
};
struct rcar_gyroadc {
struct device *dev;
void __iomem *regs;
struct clk *iclk;
struct regulator *vref[8];
unsigned int num_channels;
enum rcar_gyroadc_model model;
unsigned int mode;
unsigned int sample_width;
};
static void rcar_gyroadc_hw_init(struct rcar_gyroadc *priv)
{
const unsigned long clk_mhz = clk_get_rate(priv->iclk) / 1000000;
const unsigned long clk_mul =
(priv->mode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) ? 10 : 5;
unsigned long clk_len = clk_mhz * clk_mul;
/*
* According to the R-Car Gen2 datasheet Rev. 1.01, Sept 08 2014,
* page 77-7, clock length must be even number. If it's odd number,
* add one.
*/
if (clk_len & 1)
clk_len++;
/* Stop the GyroADC. */
writel(0, priv->regs + RCAR_GYROADC_START_STOP);
/* Disable IRQ on V2H. */
if (priv->model == RCAR_GYROADC_MODEL_R8A7792)
writel(0, priv->regs + RCAR_GYROADC_INTENR);
/* Set mode and timing. */
writel(priv->mode, priv->regs + RCAR_GYROADC_MODE_SELECT);
writel(clk_len, priv->regs + RCAR_GYROADC_CLOCK_LENGTH);
writel(clk_mhz * 1250, priv->regs + RCAR_GYROADC_1_25MS_LENGTH);
}
static void rcar_gyroadc_hw_start(struct rcar_gyroadc *priv)
{
/* Start sampling. */
writel(RCAR_GYROADC_START_STOP_START,
priv->regs + RCAR_GYROADC_START_STOP);
/*
* Wait for the first conversion to complete. This is longer than
* the 1.25 mS in the datasheet because 1.25 mS is not enough for
* the hardware to deliver the first sample and the hardware does
* then return zeroes instead of valid data.
*/
mdelay(3);
}
static void rcar_gyroadc_hw_stop(struct rcar_gyroadc *priv)
{
/* Stop the GyroADC. */
writel(0, priv->regs + RCAR_GYROADC_START_STOP);
}
#define RCAR_GYROADC_CHAN(_idx) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (_idx), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
}
static const struct iio_chan_spec rcar_gyroadc_iio_channels_1[] = {
RCAR_GYROADC_CHAN(0),
RCAR_GYROADC_CHAN(1),
RCAR_GYROADC_CHAN(2),
RCAR_GYROADC_CHAN(3),
};
static const struct iio_chan_spec rcar_gyroadc_iio_channels_2[] = {
RCAR_GYROADC_CHAN(0),
RCAR_GYROADC_CHAN(1),
RCAR_GYROADC_CHAN(2),
RCAR_GYROADC_CHAN(3),
RCAR_GYROADC_CHAN(4),
RCAR_GYROADC_CHAN(5),
RCAR_GYROADC_CHAN(6),
RCAR_GYROADC_CHAN(7),
};
static const struct iio_chan_spec rcar_gyroadc_iio_channels_3[] = {
RCAR_GYROADC_CHAN(0),
RCAR_GYROADC_CHAN(1),
RCAR_GYROADC_CHAN(2),
RCAR_GYROADC_CHAN(3),
RCAR_GYROADC_CHAN(4),
RCAR_GYROADC_CHAN(5),
RCAR_GYROADC_CHAN(6),
RCAR_GYROADC_CHAN(7),
};
static int rcar_gyroadc_set_power(struct rcar_gyroadc *priv, bool on)
{
struct device *dev = priv->dev;
int ret;
if (on) {
ret = pm_runtime_get_sync(dev);
if (ret < 0)
pm_runtime_put_noidle(dev);
} else {
pm_runtime_mark_last_busy(dev);
ret = pm_runtime_put_autosuspend(dev);
}
return ret;
}
static int rcar_gyroadc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct rcar_gyroadc *priv = iio_priv(indio_dev);
struct regulator *consumer;
unsigned int datareg = RCAR_GYROADC_REALTIME_DATA(chan->channel);
unsigned int vref;
int ret;
/*
* MB88101 is special in that it has only single regulator for
* all four channels.
*/
if (priv->mode == RCAR_GYROADC_MODE_SELECT_1_MB88101A)
consumer = priv->vref[0];
else
consumer = priv->vref[chan->channel];
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (chan->type != IIO_VOLTAGE)
return -EINVAL;
/* Channel not connected. */
if (!consumer)
return -EINVAL;
ret = iio_device_claim_direct_mode(indio_dev);
if (ret)
return ret;
ret = rcar_gyroadc_set_power(priv, true);
if (ret < 0) {
iio_device_release_direct_mode(indio_dev);
return ret;
}
*val = readl(priv->regs + datareg);
*val &= BIT(priv->sample_width) - 1;
ret = rcar_gyroadc_set_power(priv, false);
iio_device_release_direct_mode(indio_dev);
if (ret < 0)
return ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
/* Channel not connected. */
if (!consumer)
return -EINVAL;
vref = regulator_get_voltage(consumer);
*val = vref / 1000;
*val2 = 1 << priv->sample_width;
return IIO_VAL_FRACTIONAL;
case IIO_CHAN_INFO_SAMP_FREQ:
*val = RCAR_GYROADC_SAMPLE_RATE;
return IIO_VAL_INT;
default:
return -EINVAL;
}
}
static int rcar_gyroadc_reg_access(struct iio_dev *indio_dev,
unsigned int reg, unsigned int writeval,
unsigned int *readval)
{
struct rcar_gyroadc *priv = iio_priv(indio_dev);
unsigned int maxreg = RCAR_GYROADC_FIFO_STATUS;
if (readval == NULL)
return -EINVAL;
if (reg % 4)
return -EINVAL;
/* Handle the V2H case with extra interrupt block. */
if (priv->model == RCAR_GYROADC_MODEL_R8A7792)
maxreg = RCAR_GYROADC_INTENR;
if (reg > maxreg)
return -EINVAL;
*readval = readl(priv->regs + reg);
return 0;
}
static const struct iio_info rcar_gyroadc_iio_info = {
.driver_module = THIS_MODULE,
.read_raw = rcar_gyroadc_read_raw,
.debugfs_reg_access = rcar_gyroadc_reg_access,
};
static const struct of_device_id rcar_gyroadc_match[] = {
{
/* R-Car compatible GyroADC */
.compatible = "renesas,rcar-gyroadc",
.data = (void *)RCAR_GYROADC_MODEL_DEFAULT,
}, {
/* R-Car V2H specialty with interrupt registers. */
.compatible = "renesas,r8a7792-gyroadc",
.data = (void *)RCAR_GYROADC_MODEL_R8A7792,
}, {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(of, rcar_gyroadc_match);
static const struct of_device_id rcar_gyroadc_child_match[] = {
/* Mode 1 ADCs */
{
.compatible = "fujitsu,mb88101a",
.data = (void *)RCAR_GYROADC_MODE_SELECT_1_MB88101A,
},
/* Mode 2 ADCs */
{
.compatible = "ti,adcs7476",
.data = (void *)RCAR_GYROADC_MODE_SELECT_2_ADCS7476,
}, {
.compatible = "ti,adc121",
.data = (void *)RCAR_GYROADC_MODE_SELECT_2_ADCS7476,
}, {
.compatible = "adi,ad7476",
.data = (void *)RCAR_GYROADC_MODE_SELECT_2_ADCS7476,
},
/* Mode 3 ADCs */
{
.compatible = "maxim,max1162",
.data = (void *)RCAR_GYROADC_MODE_SELECT_3_MAX1162,
}, {
.compatible = "maxim,max11100",
.data = (void *)RCAR_GYROADC_MODE_SELECT_3_MAX1162,
},
{ /* sentinel */ }
};
static int rcar_gyroadc_parse_subdevs(struct iio_dev *indio_dev)
{
const struct of_device_id *of_id;
const struct iio_chan_spec *channels;
struct rcar_gyroadc *priv = iio_priv(indio_dev);
struct device *dev = priv->dev;
struct device_node *np = dev->of_node;
struct device_node *child;
struct regulator *vref;
unsigned int reg;
unsigned int adcmode, childmode;
unsigned int sample_width;
unsigned int num_channels;
int ret, first = 1;
for_each_child_of_node(np, child) {
of_id = of_match_node(rcar_gyroadc_child_match, child);
if (!of_id) {
dev_err(dev, "Ignoring unsupported ADC \"%s\".",
child->name);
continue;
}
childmode = (unsigned int)of_id->data;
switch (childmode) {
case RCAR_GYROADC_MODE_SELECT_1_MB88101A:
sample_width = 12;
channels = rcar_gyroadc_iio_channels_1;
num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_1);
break;
case RCAR_GYROADC_MODE_SELECT_2_ADCS7476:
sample_width = 15;
channels = rcar_gyroadc_iio_channels_2;
num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_2);
break;
case RCAR_GYROADC_MODE_SELECT_3_MAX1162:
sample_width = 16;
channels = rcar_gyroadc_iio_channels_3;
num_channels = ARRAY_SIZE(rcar_gyroadc_iio_channels_3);
break;
}
/*
* MB88101 is special in that it's only a single chip taking
* up all the CHS lines. Thus, the DT binding is also special
* and has no reg property. If we run into such ADC, handle
* it here.
*/
if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A) {
reg = 0;
} else {
ret = of_property_read_u32(child, "reg", &reg);
if (ret) {
dev_err(dev,
"Failed to get child reg property of ADC \"%s\".\n",
child->name);
return ret;
}
/* Channel number is too high. */
if (reg >= num_channels) {
dev_err(dev,
"Only %i channels supported with %s, but reg = <%i>.\n",
num_channels, child->name, reg);
return ret;
}
}
/* Child node selected different mode than the rest. */
if (!first && (adcmode != childmode)) {
dev_err(dev,
"Channel %i uses different ADC mode than the rest.\n",
reg);
return ret;
}
/* Channel is valid, grab the regulator. */
dev->of_node = child;
vref = devm_regulator_get(dev, "vref");
dev->of_node = np;
if (IS_ERR(vref)) {
dev_dbg(dev, "Channel %i 'vref' supply not connected.\n",
reg);
return PTR_ERR(vref);
}
priv->vref[reg] = vref;
if (!first)
continue;
/* First child node which passed sanity tests. */
adcmode = childmode;
first = 0;
priv->num_channels = num_channels;
priv->mode = childmode;
priv->sample_width = sample_width;
indio_dev->channels = channels;
indio_dev->num_channels = num_channels;
/*
* MB88101 is special and we only have one such device
* attached to the GyroADC at a time, so if we found it,
* we can stop parsing here.
*/
if (childmode == RCAR_GYROADC_MODE_SELECT_1_MB88101A)
break;
}
if (first) {
dev_err(dev, "No valid ADC channels found, aborting.\n");
return -EINVAL;
}
return 0;
}
static void rcar_gyroadc_deinit_supplies(struct iio_dev *indio_dev)
{
struct rcar_gyroadc *priv = iio_priv(indio_dev);
unsigned int i;
for (i = 0; i < priv->num_channels; i++) {
if (!priv->vref[i])
continue;
regulator_disable(priv->vref[i]);
}
}
static int rcar_gyroadc_init_supplies(struct iio_dev *indio_dev)
{
struct rcar_gyroadc *priv = iio_priv(indio_dev);
struct device *dev = priv->dev;
unsigned int i;
int ret;
for (i = 0; i < priv->num_channels; i++) {
if (!priv->vref[i])
continue;
ret = regulator_enable(priv->vref[i]);
if (ret) {
dev_err(dev, "Failed to enable regulator %i (ret=%i)\n",
i, ret);
goto err;
}
}
return 0;
err:
rcar_gyroadc_deinit_supplies(indio_dev);
return ret;
}
static int rcar_gyroadc_probe(struct platform_device *pdev)
{
const struct of_device_id *of_id =
of_match_device(rcar_gyroadc_match, &pdev->dev);
struct device *dev = &pdev->dev;
struct rcar_gyroadc *priv;
struct iio_dev *indio_dev;
struct resource *mem;
int ret;
indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
if (!indio_dev) {
dev_err(dev, "Failed to allocate IIO device.\n");
return -ENOMEM;
}
priv = iio_priv(indio_dev);
priv->dev = dev;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
priv->regs = devm_ioremap_resource(dev, mem);
if (IS_ERR(priv->regs))
return PTR_ERR(priv->regs);
priv->iclk = devm_clk_get(dev, "if");
if (IS_ERR(priv->iclk)) {
ret = PTR_ERR(priv->iclk);
if (ret != -EPROBE_DEFER)
dev_err(dev, "Failed to get IF clock (ret=%i)\n", ret);
return ret;
}
ret = rcar_gyroadc_parse_subdevs(indio_dev);
if (ret)
return ret;
ret = rcar_gyroadc_init_supplies(indio_dev);
if (ret)
return ret;
priv->model = (enum rcar_gyroadc_model)of_id->data;
platform_set_drvdata(pdev, indio_dev);
indio_dev->name = DRIVER_NAME;
indio_dev->dev.parent = dev;
indio_dev->dev.of_node = pdev->dev.of_node;
indio_dev->info = &rcar_gyroadc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = clk_prepare_enable(priv->iclk);
if (ret) {
dev_err(dev, "Could not prepare or enable the IF clock.\n");
goto err_clk_if_enable;
}
pm_runtime_set_autosuspend_delay(dev, RCAR_GYROADC_RUNTIME_PM_DELAY_MS);
pm_runtime_use_autosuspend(dev);
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
rcar_gyroadc_hw_init(priv);
rcar_gyroadc_hw_start(priv);
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(dev, "Couldn't register IIO device.\n");
goto err_iio_device_register;
}
pm_runtime_put_sync(dev);
return 0;
err_iio_device_register:
rcar_gyroadc_hw_stop(priv);
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
clk_disable_unprepare(priv->iclk);
err_clk_if_enable:
rcar_gyroadc_deinit_supplies(indio_dev);
return ret;
}
static int rcar_gyroadc_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct rcar_gyroadc *priv = iio_priv(indio_dev);
struct device *dev = priv->dev;
iio_device_unregister(indio_dev);
pm_runtime_get_sync(dev);
rcar_gyroadc_hw_stop(priv);
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
clk_disable_unprepare(priv->iclk);
rcar_gyroadc_deinit_supplies(indio_dev);
return 0;
}
#if defined(CONFIG_PM)
static int rcar_gyroadc_suspend(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct rcar_gyroadc *priv = iio_priv(indio_dev);
rcar_gyroadc_hw_stop(priv);
return 0;
}
static int rcar_gyroadc_resume(struct device *dev)
{
struct iio_dev *indio_dev = dev_get_drvdata(dev);
struct rcar_gyroadc *priv = iio_priv(indio_dev);
rcar_gyroadc_hw_start(priv);
return 0;
}
#endif
static const struct dev_pm_ops rcar_gyroadc_pm_ops = {
SET_RUNTIME_PM_OPS(rcar_gyroadc_suspend, rcar_gyroadc_resume, NULL)
};
static struct platform_driver rcar_gyroadc_driver = {
.probe = rcar_gyroadc_probe,
.remove = rcar_gyroadc_remove,
.driver = {
.name = DRIVER_NAME,
.of_match_table = rcar_gyroadc_match,
.pm = &rcar_gyroadc_pm_ops,
},
};
module_platform_driver(rcar_gyroadc_driver);
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("Renesas R-Car GyroADC driver");
MODULE_LICENSE("GPL");
......@@ -201,6 +201,7 @@ static int stm32_adc_probe(struct platform_device *pdev)
priv->common.base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(priv->common.base))
return PTR_ERR(priv->common.base);
priv->common.phys_base = res->start;
priv->vref = devm_regulator_get(&pdev->dev, "vref");
if (IS_ERR(priv->vref)) {
......
......@@ -42,10 +42,12 @@
/**
* struct stm32_adc_common - stm32 ADC driver common data (for all instances)
* @base: control registers base cpu addr
* @phys_base: control registers base physical addr
* @vref_mv: vref voltage (mv)
*/
struct stm32_adc_common {
void __iomem *base;
phys_addr_t phys_base;
int vref_mv;
};
......
......@@ -21,7 +21,14 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/timer/stm32-timer-trigger.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
......@@ -58,21 +65,71 @@
/* STM32F4_ADC_CR2 - bit fields */
#define STM32F4_SWSTART BIT(30)
#define STM32F4_EXTEN_SHIFT 28
#define STM32F4_EXTEN_MASK GENMASK(29, 28)
#define STM32F4_EXTSEL_SHIFT 24
#define STM32F4_EXTSEL_MASK GENMASK(27, 24)
#define STM32F4_EOCS BIT(10)
#define STM32F4_DDS BIT(9)
#define STM32F4_DMA BIT(8)
#define STM32F4_ADON BIT(0)
/* STM32F4_ADC_SQR1 - bit fields */
#define STM32F4_L_SHIFT 20
#define STM32F4_L_MASK GENMASK(23, 20)
/* STM32F4_ADC_SQR3 - bit fields */
#define STM32F4_SQ1_SHIFT 0
#define STM32F4_SQ1_MASK GENMASK(4, 0)
#define STM32_ADC_MAX_SQ 16 /* SQ1..SQ16 */
#define STM32_ADC_TIMEOUT_US 100000
#define STM32_ADC_TIMEOUT (msecs_to_jiffies(STM32_ADC_TIMEOUT_US / 1000))
#define STM32_DMA_BUFFER_SIZE PAGE_SIZE
/* External trigger enable */
enum stm32_adc_exten {
STM32_EXTEN_SWTRIG,
STM32_EXTEN_HWTRIG_RISING_EDGE,
STM32_EXTEN_HWTRIG_FALLING_EDGE,
STM32_EXTEN_HWTRIG_BOTH_EDGES,
};
/* extsel - trigger mux selection value */
enum stm32_adc_extsel {
STM32_EXT0,
STM32_EXT1,
STM32_EXT2,
STM32_EXT3,
STM32_EXT4,
STM32_EXT5,
STM32_EXT6,
STM32_EXT7,
STM32_EXT8,
STM32_EXT9,
STM32_EXT10,
STM32_EXT11,
STM32_EXT12,
STM32_EXT13,
STM32_EXT14,
STM32_EXT15,
};
/**
* struct stm32_adc_trig_info - ADC trigger info
* @name: name of the trigger, corresponding to its source
* @extsel: trigger selection
*/
struct stm32_adc_trig_info {
const char *name;
enum stm32_adc_extsel extsel;
};
/**
* stm32_adc_regs - stm32 ADC misc registers & bitfield desc
* @reg: register offset
* @mask: bitfield mask
* @shift: left shift
*/
struct stm32_adc_regs {
int reg;
int mask;
int shift;
};
/**
* struct stm32_adc - private data of each ADC IIO instance
* @common: reference to ADC block common data
......@@ -82,15 +139,29 @@
* @clk: clock for this adc instance
* @irq: interrupt for this adc instance
* @lock: spinlock
* @bufi: data buffer index
* @num_conv: expected number of scan conversions
* @trigger_polarity: external trigger polarity (e.g. exten)
* @dma_chan: dma channel
* @rx_buf: dma rx buffer cpu address
* @rx_dma_buf: dma rx buffer bus address
* @rx_buf_sz: dma rx buffer size
*/
struct stm32_adc {
struct stm32_adc_common *common;
u32 offset;
struct completion completion;
u16 *buffer;
u16 buffer[STM32_ADC_MAX_SQ];
struct clk *clk;
int irq;
spinlock_t lock; /* interrupt lock */
unsigned int bufi;
unsigned int num_conv;
u32 trigger_polarity;
struct dma_chan *dma_chan;
u8 *rx_buf;
dma_addr_t rx_dma_buf;
unsigned int rx_buf_sz;
};
/**
......@@ -125,6 +196,53 @@ static const struct stm32_adc_chan_spec stm32f4_adc123_channels[] = {
{ IIO_VOLTAGE, 15, "in15" },
};
/**
* stm32f4_sq - describe regular sequence registers
* - L: sequence len (register & bit field)
* - SQ1..SQ16: sequence entries (register & bit field)
*/
static const struct stm32_adc_regs stm32f4_sq[STM32_ADC_MAX_SQ + 1] = {
/* L: len bit field description to be kept as first element */
{ STM32F4_ADC_SQR1, GENMASK(23, 20), 20 },
/* SQ1..SQ16 registers & bit fields (reg, mask, shift) */
{ STM32F4_ADC_SQR3, GENMASK(4, 0), 0 },
{ STM32F4_ADC_SQR3, GENMASK(9, 5), 5 },
{ STM32F4_ADC_SQR3, GENMASK(14, 10), 10 },
{ STM32F4_ADC_SQR3, GENMASK(19, 15), 15 },
{ STM32F4_ADC_SQR3, GENMASK(24, 20), 20 },
{ STM32F4_ADC_SQR3, GENMASK(29, 25), 25 },
{ STM32F4_ADC_SQR2, GENMASK(4, 0), 0 },
{ STM32F4_ADC_SQR2, GENMASK(9, 5), 5 },
{ STM32F4_ADC_SQR2, GENMASK(14, 10), 10 },
{ STM32F4_ADC_SQR2, GENMASK(19, 15), 15 },
{ STM32F4_ADC_SQR2, GENMASK(24, 20), 20 },
{ STM32F4_ADC_SQR2, GENMASK(29, 25), 25 },
{ STM32F4_ADC_SQR1, GENMASK(4, 0), 0 },
{ STM32F4_ADC_SQR1, GENMASK(9, 5), 5 },
{ STM32F4_ADC_SQR1, GENMASK(14, 10), 10 },
{ STM32F4_ADC_SQR1, GENMASK(19, 15), 15 },
};
/* STM32F4 external trigger sources for all instances */
static struct stm32_adc_trig_info stm32f4_adc_trigs[] = {
{ TIM1_CH1, STM32_EXT0 },
{ TIM1_CH2, STM32_EXT1 },
{ TIM1_CH3, STM32_EXT2 },
{ TIM2_CH2, STM32_EXT3 },
{ TIM2_CH3, STM32_EXT4 },
{ TIM2_CH4, STM32_EXT5 },
{ TIM2_TRGO, STM32_EXT6 },
{ TIM3_CH1, STM32_EXT7 },
{ TIM3_TRGO, STM32_EXT8 },
{ TIM4_CH4, STM32_EXT9 },
{ TIM5_CH1, STM32_EXT10 },
{ TIM5_CH2, STM32_EXT11 },
{ TIM5_CH3, STM32_EXT12 },
{ TIM8_CH1, STM32_EXT13 },
{ TIM8_TRGO, STM32_EXT14 },
{}, /* sentinel */
};
/**
* STM32 ADC registers access routines
* @adc: stm32 adc instance
......@@ -187,10 +305,21 @@ static void stm32_adc_conv_irq_disable(struct stm32_adc *adc)
/**
* stm32_adc_start_conv() - Start conversions for regular channels.
* @adc: stm32 adc instance
* @dma: use dma to transfer conversion result
*
* Start conversions for regular channels.
* Also take care of normal or DMA mode. Circular DMA may be used for regular
* conversions, in IIO buffer modes. Otherwise, use ADC interrupt with direct
* DR read instead (e.g. read_raw, or triggered buffer mode without DMA).
*/
static void stm32_adc_start_conv(struct stm32_adc *adc)
static void stm32_adc_start_conv(struct stm32_adc *adc, bool dma)
{
stm32_adc_set_bits(adc, STM32F4_ADC_CR1, STM32F4_SCAN);
if (dma)
stm32_adc_set_bits(adc, STM32F4_ADC_CR2,
STM32F4_DMA | STM32F4_DDS);
stm32_adc_set_bits(adc, STM32F4_ADC_CR2, STM32F4_EOCS | STM32F4_ADON);
/* Wait for Power-up time (tSTAB from datasheet) */
......@@ -207,9 +336,152 @@ static void stm32_adc_stop_conv(struct stm32_adc *adc)
stm32_adc_clr_bits(adc, STM32F4_ADC_SR, STM32F4_STRT);
stm32_adc_clr_bits(adc, STM32F4_ADC_CR1, STM32F4_SCAN);
stm32_adc_clr_bits(adc, STM32F4_ADC_CR2, STM32F4_ADON);
stm32_adc_clr_bits(adc, STM32F4_ADC_CR2,
STM32F4_ADON | STM32F4_DMA | STM32F4_DDS);
}
/**
* stm32_adc_conf_scan_seq() - Build regular channels scan sequence
* @indio_dev: IIO device
* @scan_mask: channels to be converted
*
* Conversion sequence :
* Configure ADC scan sequence based on selected channels in scan_mask.
* Add channels to SQR registers, from scan_mask LSB to MSB, then
* program sequence len.
*/
static int stm32_adc_conf_scan_seq(struct iio_dev *indio_dev,
const unsigned long *scan_mask)
{
struct stm32_adc *adc = iio_priv(indio_dev);
const struct iio_chan_spec *chan;
u32 val, bit;
int i = 0;
for_each_set_bit(bit, scan_mask, indio_dev->masklength) {
chan = indio_dev->channels + bit;
/*
* Assign one channel per SQ entry in regular
* sequence, starting with SQ1.
*/
i++;
if (i > STM32_ADC_MAX_SQ)
return -EINVAL;
dev_dbg(&indio_dev->dev, "%s chan %d to SQ%d\n",
__func__, chan->channel, i);
val = stm32_adc_readl(adc, stm32f4_sq[i].reg);
val &= ~stm32f4_sq[i].mask;
val |= chan->channel << stm32f4_sq[i].shift;
stm32_adc_writel(adc, stm32f4_sq[i].reg, val);
}
if (!i)
return -EINVAL;
/* Sequence len */
val = stm32_adc_readl(adc, stm32f4_sq[0].reg);
val &= ~stm32f4_sq[0].mask;
val |= ((i - 1) << stm32f4_sq[0].shift);
stm32_adc_writel(adc, stm32f4_sq[0].reg, val);
return 0;
}
/**
* stm32_adc_get_trig_extsel() - Get external trigger selection
* @trig: trigger
*
* Returns trigger extsel value, if trig matches, -EINVAL otherwise.
*/
static int stm32_adc_get_trig_extsel(struct iio_trigger *trig)
{
int i;
/* lookup triggers registered by stm32 timer trigger driver */
for (i = 0; stm32f4_adc_trigs[i].name; i++) {
/**
* Checking both stm32 timer trigger type and trig name
* should be safe against arbitrary trigger names.
*/
if (is_stm32_timer_trigger(trig) &&
!strcmp(stm32f4_adc_trigs[i].name, trig->name)) {
return stm32f4_adc_trigs[i].extsel;
}
}
return -EINVAL;
}
/**
* stm32_adc_set_trig() - Set a regular trigger
* @indio_dev: IIO device
* @trig: IIO trigger
*
* Set trigger source/polarity (e.g. SW, or HW with polarity) :
* - if HW trigger disabled (e.g. trig == NULL, conversion launched by sw)
* - if HW trigger enabled, set source & polarity
*/
static int stm32_adc_set_trig(struct iio_dev *indio_dev,
struct iio_trigger *trig)
{
struct stm32_adc *adc = iio_priv(indio_dev);
u32 val, extsel = 0, exten = STM32_EXTEN_SWTRIG;
unsigned long flags;
int ret;
if (trig) {
ret = stm32_adc_get_trig_extsel(trig);
if (ret < 0)
return ret;
/* set trigger source and polarity (default to rising edge) */
extsel = ret;
exten = adc->trigger_polarity + STM32_EXTEN_HWTRIG_RISING_EDGE;
}
spin_lock_irqsave(&adc->lock, flags);
val = stm32_adc_readl(adc, STM32F4_ADC_CR2);
val &= ~(STM32F4_EXTEN_MASK | STM32F4_EXTSEL_MASK);
val |= exten << STM32F4_EXTEN_SHIFT;
val |= extsel << STM32F4_EXTSEL_SHIFT;
stm32_adc_writel(adc, STM32F4_ADC_CR2, val);
spin_unlock_irqrestore(&adc->lock, flags);
return 0;
}
static int stm32_adc_set_trig_pol(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
unsigned int type)
{
struct stm32_adc *adc = iio_priv(indio_dev);
adc->trigger_polarity = type;
return 0;
}
static int stm32_adc_get_trig_pol(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
struct stm32_adc *adc = iio_priv(indio_dev);
return adc->trigger_polarity;
}
static const char * const stm32_trig_pol_items[] = {
"rising-edge", "falling-edge", "both-edges",
};
static const struct iio_enum stm32_adc_trig_pol = {
.items = stm32_trig_pol_items,
.num_items = ARRAY_SIZE(stm32_trig_pol_items),
.get = stm32_adc_get_trig_pol,
.set = stm32_adc_set_trig_pol,
};
/**
* stm32_adc_single_conv() - Performs a single conversion
* @indio_dev: IIO device
......@@ -228,28 +500,27 @@ static int stm32_adc_single_conv(struct iio_dev *indio_dev,
struct stm32_adc *adc = iio_priv(indio_dev);
long timeout;
u32 val;
u16 result;
int ret;
reinit_completion(&adc->completion);
adc->buffer = &result;
adc->bufi = 0;
/* Program chan number in regular sequence */
val = stm32_adc_readl(adc, STM32F4_ADC_SQR3);
val &= ~STM32F4_SQ1_MASK;
val |= chan->channel << STM32F4_SQ1_SHIFT;
stm32_adc_writel(adc, STM32F4_ADC_SQR3, val);
/* Program chan number in regular sequence (SQ1) */
val = stm32_adc_readl(adc, stm32f4_sq[1].reg);
val &= ~stm32f4_sq[1].mask;
val |= chan->channel << stm32f4_sq[1].shift;
stm32_adc_writel(adc, stm32f4_sq[1].reg, val);
/* Set regular sequence len (0 for 1 conversion) */
stm32_adc_clr_bits(adc, STM32F4_ADC_SQR1, STM32F4_L_MASK);
stm32_adc_clr_bits(adc, stm32f4_sq[0].reg, stm32f4_sq[0].mask);
/* Trigger detection disabled (conversion can be launched in SW) */
stm32_adc_clr_bits(adc, STM32F4_ADC_CR2, STM32F4_EXTEN_MASK);
stm32_adc_conv_irq_enable(adc);
stm32_adc_start_conv(adc);
stm32_adc_start_conv(adc, false);
timeout = wait_for_completion_interruptible_timeout(
&adc->completion, STM32_ADC_TIMEOUT);
......@@ -258,7 +529,7 @@ static int stm32_adc_single_conv(struct iio_dev *indio_dev,
} else if (timeout < 0) {
ret = timeout;
} else {
*res = result;
*res = adc->buffer[0];
ret = IIO_VAL_INT;
}
......@@ -301,17 +572,73 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev,
static irqreturn_t stm32_adc_isr(int irq, void *data)
{
struct stm32_adc *adc = data;
struct iio_dev *indio_dev = iio_priv_to_dev(adc);
u32 status = stm32_adc_readl(adc, STM32F4_ADC_SR);
if (status & STM32F4_EOC) {
*adc->buffer = stm32_adc_readw(adc, STM32F4_ADC_DR);
complete(&adc->completion);
/* Reading DR also clears EOC status flag */
adc->buffer[adc->bufi] = stm32_adc_readw(adc, STM32F4_ADC_DR);
if (iio_buffer_enabled(indio_dev)) {
adc->bufi++;
if (adc->bufi >= adc->num_conv) {
stm32_adc_conv_irq_disable(adc);
iio_trigger_poll(indio_dev->trig);
}
} else {
complete(&adc->completion);
}
return IRQ_HANDLED;
}
return IRQ_NONE;
}
/**
* stm32_adc_validate_trigger() - validate trigger for stm32 adc
* @indio_dev: IIO device
* @trig: new trigger
*
* Returns: 0 if trig matches one of the triggers registered by stm32 adc
* driver, -EINVAL otherwise.
*/
static int stm32_adc_validate_trigger(struct iio_dev *indio_dev,
struct iio_trigger *trig)
{
return stm32_adc_get_trig_extsel(trig) < 0 ? -EINVAL : 0;
}
static int stm32_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val)
{
struct stm32_adc *adc = iio_priv(indio_dev);
unsigned int watermark = STM32_DMA_BUFFER_SIZE / 2;
/*
* dma cyclic transfers are used, buffer is split into two periods.
* There should be :
* - always one buffer (period) dma is working on
* - one buffer (period) driver can push with iio_trigger_poll().
*/
watermark = min(watermark, val * (unsigned)(sizeof(u16)));
adc->rx_buf_sz = watermark * 2;
return 0;
}
static int stm32_adc_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask)
{
struct stm32_adc *adc = iio_priv(indio_dev);
int ret;
adc->num_conv = bitmap_weight(scan_mask, indio_dev->masklength);
ret = stm32_adc_conf_scan_seq(indio_dev, scan_mask);
if (ret)
return ret;
return 0;
}
static int stm32_adc_of_xlate(struct iio_dev *indio_dev,
const struct of_phandle_args *iiospec)
{
......@@ -350,11 +677,199 @@ static int stm32_adc_debugfs_reg_access(struct iio_dev *indio_dev,
static const struct iio_info stm32_adc_iio_info = {
.read_raw = stm32_adc_read_raw,
.validate_trigger = stm32_adc_validate_trigger,
.hwfifo_set_watermark = stm32_adc_set_watermark,
.update_scan_mode = stm32_adc_update_scan_mode,
.debugfs_reg_access = stm32_adc_debugfs_reg_access,
.of_xlate = stm32_adc_of_xlate,
.driver_module = THIS_MODULE,
};
static unsigned int stm32_adc_dma_residue(struct stm32_adc *adc)
{
struct dma_tx_state state;
enum dma_status status;
status = dmaengine_tx_status(adc->dma_chan,
adc->dma_chan->cookie,
&state);
if (status == DMA_IN_PROGRESS) {
/* Residue is size in bytes from end of buffer */
unsigned int i = adc->rx_buf_sz - state.residue;
unsigned int size;
/* Return available bytes */
if (i >= adc->bufi)
size = i - adc->bufi;
else
size = adc->rx_buf_sz + i - adc->bufi;
return size;
}
return 0;
}
static void stm32_adc_dma_buffer_done(void *data)
{
struct iio_dev *indio_dev = data;
iio_trigger_poll_chained(indio_dev->trig);
}
static int stm32_adc_dma_start(struct iio_dev *indio_dev)
{
struct stm32_adc *adc = iio_priv(indio_dev);
struct dma_async_tx_descriptor *desc;
dma_cookie_t cookie;
int ret;
if (!adc->dma_chan)
return 0;
dev_dbg(&indio_dev->dev, "%s size=%d watermark=%d\n", __func__,
adc->rx_buf_sz, adc->rx_buf_sz / 2);
/* Prepare a DMA cyclic transaction */
desc = dmaengine_prep_dma_cyclic(adc->dma_chan,
adc->rx_dma_buf,
adc->rx_buf_sz, adc->rx_buf_sz / 2,
DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT);
if (!desc)
return -EBUSY;
desc->callback = stm32_adc_dma_buffer_done;
desc->callback_param = indio_dev;
cookie = dmaengine_submit(desc);
ret = dma_submit_error(cookie);
if (ret) {
dmaengine_terminate_all(adc->dma_chan);
return ret;
}
/* Issue pending DMA requests */
dma_async_issue_pending(adc->dma_chan);
return 0;
}
static int stm32_adc_buffer_postenable(struct iio_dev *indio_dev)
{
struct stm32_adc *adc = iio_priv(indio_dev);
int ret;
ret = stm32_adc_set_trig(indio_dev, indio_dev->trig);
if (ret) {
dev_err(&indio_dev->dev, "Can't set trigger\n");
return ret;
}
ret = stm32_adc_dma_start(indio_dev);
if (ret) {
dev_err(&indio_dev->dev, "Can't start dma\n");
goto err_clr_trig;
}
ret = iio_triggered_buffer_postenable(indio_dev);
if (ret < 0)
goto err_stop_dma;
/* Reset adc buffer index */
adc->bufi = 0;
if (!adc->dma_chan)
stm32_adc_conv_irq_enable(adc);
stm32_adc_start_conv(adc, !!adc->dma_chan);
return 0;
err_stop_dma:
if (adc->dma_chan)
dmaengine_terminate_all(adc->dma_chan);
err_clr_trig:
stm32_adc_set_trig(indio_dev, NULL);
return ret;
}
static int stm32_adc_buffer_predisable(struct iio_dev *indio_dev)
{
struct stm32_adc *adc = iio_priv(indio_dev);
int ret;
stm32_adc_stop_conv(adc);
if (!adc->dma_chan)
stm32_adc_conv_irq_disable(adc);
ret = iio_triggered_buffer_predisable(indio_dev);
if (ret < 0)
dev_err(&indio_dev->dev, "predisable failed\n");
if (adc->dma_chan)
dmaengine_terminate_all(adc->dma_chan);
if (stm32_adc_set_trig(indio_dev, NULL))
dev_err(&indio_dev->dev, "Can't clear trigger\n");
return ret;
}
static const struct iio_buffer_setup_ops stm32_adc_buffer_setup_ops = {
.postenable = &stm32_adc_buffer_postenable,
.predisable = &stm32_adc_buffer_predisable,
};
static irqreturn_t stm32_adc_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct stm32_adc *adc = iio_priv(indio_dev);
dev_dbg(&indio_dev->dev, "%s bufi=%d\n", __func__, adc->bufi);
if (!adc->dma_chan) {
/* reset buffer index */
adc->bufi = 0;
iio_push_to_buffers_with_timestamp(indio_dev, adc->buffer,
pf->timestamp);
} else {
int residue = stm32_adc_dma_residue(adc);
while (residue >= indio_dev->scan_bytes) {
u16 *buffer = (u16 *)&adc->rx_buf[adc->bufi];
iio_push_to_buffers_with_timestamp(indio_dev, buffer,
pf->timestamp);
residue -= indio_dev->scan_bytes;
adc->bufi += indio_dev->scan_bytes;
if (adc->bufi >= adc->rx_buf_sz)
adc->bufi = 0;
}
}
iio_trigger_notify_done(indio_dev->trig);
/* re-enable eoc irq */
if (!adc->dma_chan)
stm32_adc_conv_irq_enable(adc);
return IRQ_HANDLED;
}
static const struct iio_chan_spec_ext_info stm32_adc_ext_info[] = {
IIO_ENUM("trigger_polarity", IIO_SHARED_BY_ALL, &stm32_adc_trig_pol),
{
.name = "trigger_polarity_available",
.shared = IIO_SHARED_BY_ALL,
.read = iio_enum_available_read,
.private = (uintptr_t)&stm32_adc_trig_pol,
},
{},
};
static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
struct iio_chan_spec *chan,
const struct stm32_adc_chan_spec *channel,
......@@ -370,6 +885,7 @@ static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
chan->scan_type.sign = 'u';
chan->scan_type.realbits = 12;
chan->scan_type.storagebits = 16;
chan->ext_info = stm32_adc_ext_info;
}
static int stm32_adc_chan_of_init(struct iio_dev *indio_dev)
......@@ -410,6 +926,45 @@ static int stm32_adc_chan_of_init(struct iio_dev *indio_dev)
return 0;
}
static int stm32_adc_dma_request(struct iio_dev *indio_dev)
{
struct stm32_adc *adc = iio_priv(indio_dev);
struct dma_slave_config config;
int ret;
adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx");
if (!adc->dma_chan)
return 0;
adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev,
STM32_DMA_BUFFER_SIZE,
&adc->rx_dma_buf, GFP_KERNEL);
if (!adc->rx_buf) {
ret = -ENOMEM;
goto err_release;
}
/* Configure DMA channel to read data register */
memset(&config, 0, sizeof(config));
config.src_addr = (dma_addr_t)adc->common->phys_base;
config.src_addr += adc->offset + STM32F4_ADC_DR;
config.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
ret = dmaengine_slave_config(adc->dma_chan, &config);
if (ret)
goto err_free;
return 0;
err_free:
dma_free_coherent(adc->dma_chan->device->dev, STM32_DMA_BUFFER_SIZE,
adc->rx_buf, adc->rx_dma_buf);
err_release:
dma_release_channel(adc->dma_chan);
return ret;
}
static int stm32_adc_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
......@@ -471,14 +1026,37 @@ static int stm32_adc_probe(struct platform_device *pdev)
if (ret < 0)
goto err_clk_disable;
ret = stm32_adc_dma_request(indio_dev);
if (ret < 0)
goto err_clk_disable;
ret = iio_triggered_buffer_setup(indio_dev,
&iio_pollfunc_store_time,
&stm32_adc_trigger_handler,
&stm32_adc_buffer_setup_ops);
if (ret) {
dev_err(&pdev->dev, "buffer setup failed\n");
goto err_dma_disable;
}
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&pdev->dev, "iio dev register failed\n");
goto err_clk_disable;
goto err_buffer_cleanup;
}
return 0;
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
err_dma_disable:
if (adc->dma_chan) {
dma_free_coherent(adc->dma_chan->device->dev,
STM32_DMA_BUFFER_SIZE,
adc->rx_buf, adc->rx_dma_buf);
dma_release_channel(adc->dma_chan);
}
err_clk_disable:
clk_disable_unprepare(adc->clk);
......@@ -491,6 +1069,13 @@ static int stm32_adc_remove(struct platform_device *pdev)
struct iio_dev *indio_dev = iio_priv_to_dev(adc);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
if (adc->dma_chan) {
dma_free_coherent(adc->dma_chan->device->dev,
STM32_DMA_BUFFER_SIZE,
adc->rx_buf, adc->rx_dma_buf);
dma_release_channel(adc->dma_chan);
}
clk_disable_unprepare(adc->clk);
return 0;
......
......@@ -76,16 +76,6 @@ struct stx104_gpio {
unsigned int out_state;
};
/**
* struct stx104_dev - STX104 device private data structure
* @indio_dev: IIO device
* @chip: instance of the gpio_chip
*/
struct stx104_dev {
struct iio_dev *indio_dev;
struct gpio_chip *chip;
};
static int stx104_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val, int *val2, long mask)
{
......@@ -266,12 +256,38 @@ static void stx104_gpio_set(struct gpio_chip *chip, unsigned int offset,
spin_unlock_irqrestore(&stx104gpio->lock, flags);
}
#define STX104_NGPIO 8
static const char *stx104_names[STX104_NGPIO] = {
"DIN0", "DIN1", "DIN2", "DIN3", "DOUT0", "DOUT1", "DOUT2", "DOUT3"
};
static void stx104_gpio_set_multiple(struct gpio_chip *chip,
unsigned long *mask, unsigned long *bits)
{
struct stx104_gpio *const stx104gpio = gpiochip_get_data(chip);
unsigned long flags;
/* verify masked GPIO are output */
if (!(*mask & 0xF0))
return;
*mask >>= 4;
*bits >>= 4;
spin_lock_irqsave(&stx104gpio->lock, flags);
stx104gpio->out_state &= ~*mask;
stx104gpio->out_state |= *mask & *bits;
outb(stx104gpio->out_state, stx104gpio->base);
spin_unlock_irqrestore(&stx104gpio->lock, flags);
}
static int stx104_probe(struct device *dev, unsigned int id)
{
struct iio_dev *indio_dev;
struct stx104_iio *priv;
struct stx104_gpio *stx104gpio;
struct stx104_dev *stx104dev;
int err;
indio_dev = devm_iio_device_alloc(dev, sizeof(*priv));
......@@ -282,10 +298,6 @@ static int stx104_probe(struct device *dev, unsigned int id)
if (!stx104gpio)
return -ENOMEM;
stx104dev = devm_kzalloc(dev, sizeof(*stx104dev), GFP_KERNEL);
if (!stx104dev)
return -ENOMEM;
if (!devm_request_region(dev, base[id], STX104_EXTENT,
dev_name(dev))) {
dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
......@@ -324,45 +336,26 @@ static int stx104_probe(struct device *dev, unsigned int id)
stx104gpio->chip.parent = dev;
stx104gpio->chip.owner = THIS_MODULE;
stx104gpio->chip.base = -1;
stx104gpio->chip.ngpio = 8;
stx104gpio->chip.ngpio = STX104_NGPIO;
stx104gpio->chip.names = stx104_names;
stx104gpio->chip.get_direction = stx104_gpio_get_direction;
stx104gpio->chip.direction_input = stx104_gpio_direction_input;
stx104gpio->chip.direction_output = stx104_gpio_direction_output;
stx104gpio->chip.get = stx104_gpio_get;
stx104gpio->chip.set = stx104_gpio_set;
stx104gpio->chip.set_multiple = stx104_gpio_set_multiple;
stx104gpio->base = base[id] + 3;
stx104gpio->out_state = 0x0;
spin_lock_init(&stx104gpio->lock);
stx104dev->indio_dev = indio_dev;
stx104dev->chip = &stx104gpio->chip;
dev_set_drvdata(dev, stx104dev);
err = gpiochip_add_data(&stx104gpio->chip, stx104gpio);
err = devm_gpiochip_add_data(dev, &stx104gpio->chip, stx104gpio);
if (err) {
dev_err(dev, "GPIO registering failed (%d)\n", err);
return err;
}
err = iio_device_register(indio_dev);
if (err) {
dev_err(dev, "IIO device registering failed (%d)\n", err);
gpiochip_remove(&stx104gpio->chip);
return err;
}
return 0;
}
static int stx104_remove(struct device *dev, unsigned int id)
{
struct stx104_dev *const stx104dev = dev_get_drvdata(dev);
iio_device_unregister(stx104dev->indio_dev);
gpiochip_remove(stx104dev->chip);
return 0;
return devm_iio_device_register(dev, indio_dev);
}
static struct isa_driver stx104_driver = {
......@@ -370,7 +363,6 @@ static struct isa_driver stx104_driver = {
.driver = {
.name = "stx104"
},
.remove = stx104_remove
};
module_isa_driver(stx104_driver, num_stx104);
......
......@@ -135,7 +135,7 @@ static int ssp_gyro_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, indio_dev);
ret = iio_device_register(indio_dev);
ret = devm_iio_device_register(&pdev->dev, indio_dev);
if (ret < 0)
return ret;
......@@ -145,21 +145,11 @@ static int ssp_gyro_probe(struct platform_device *pdev)
return 0;
}
static int ssp_gyro_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
iio_device_unregister(indio_dev);
return 0;
}
static struct platform_driver ssp_gyro_driver = {
.driver = {
.name = SSP_GYROSCOPE_NAME,
},
.probe = ssp_gyro_probe,
.remove = ssp_gyro_remove,
};
module_platform_driver(ssp_gyro_driver);
......
......@@ -37,11 +37,14 @@
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/platform_data/st_sensors_pdata.h>
#include "st_lsm6dsx.h"
#define ST_LSM6DSX_REG_ACC_DEC_MASK GENMASK(2, 0)
#define ST_LSM6DSX_REG_GYRO_DEC_MASK GENMASK(5, 3)
#define ST_LSM6DSX_REG_INT1_ADDR 0x0d
#define ST_LSM6DSX_REG_INT2_ADDR 0x0e
#define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK BIT(3)
#define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f
#define ST_LSM6DSX_REG_RESET_ADDR 0x12
......@@ -532,10 +535,56 @@ static const struct iio_info st_lsm6dsx_gyro_info = {
static const unsigned long st_lsm6dsx_available_scan_masks[] = {0x7, 0x0};
static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
{
struct device_node *np = hw->dev->of_node;
int err;
if (!np)
return -EINVAL;
err = of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
if (err == -ENODATA) {
/* if the property has not been specified use default value */
*drdy_pin = 1;
err = 0;
}
return err;
}
static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
{
int err = 0, drdy_pin;
if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) {
struct st_sensors_platform_data *pdata;
struct device *dev = hw->dev;
pdata = (struct st_sensors_platform_data *)dev->platform_data;
drdy_pin = pdata ? pdata->drdy_int_pin : 1;
}
switch (drdy_pin) {
case 1:
*drdy_reg = ST_LSM6DSX_REG_INT1_ADDR;
break;
case 2:
*drdy_reg = ST_LSM6DSX_REG_INT2_ADDR;
break;
default:
dev_err(hw->dev, "unsupported data ready pin\n");
err = -EINVAL;
break;
}
return err;
}
static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
{
u8 data, drdy_int_reg;
int err;
u8 data;
data = ST_LSM6DSX_REG_RESET_MASK;
err = hw->tf->write(hw->dev, ST_LSM6DSX_REG_RESET_ADDR, sizeof(data),
......@@ -563,14 +612,12 @@ static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
return err;
/* enable FIFO watermak interrupt */
err = st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_INT1_ADDR,
ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 1);
err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg);
if (err < 0)
return err;
/* redirect INT2 on INT1 */
return st_lsm6dsx_write_with_mask(hw, ST_LSM6DSX_REG_INT2_ON_INT1_ADDR,
ST_LSM6DSX_REG_INT2_ON_INT1_MASK, 1);
return st_lsm6dsx_write_with_mask(hw, drdy_int_reg,
ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 1);
}
static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
......
......@@ -15,6 +15,17 @@ config DS1803
To compile this driver as a module, choose M here: the
module will be called ds1803.
config MAX5481
tristate "Maxim MAX5481-MAX5484 Digital Potentiometer driver"
depends on SPI
help
Say yes here to build support for the Maxim
MAX5481, MAX5482, MAX5483, MAX5484 digital potentiometer
chips.
To compile this driver as a module, choose M here: the
module will be called max5481.
config MAX5487
tristate "Maxim MAX5487/MAX5488/MAX5489 Digital Potentiometer driver"
depends on SPI
......
......@@ -4,6 +4,7 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_DS1803) += ds1803.o
obj-$(CONFIG_MAX5481) += max5481.o
obj-$(CONFIG_MAX5487) += max5487.o
obj-$(CONFIG_MCP4131) += mcp4131.o
obj-$(CONFIG_MCP4531) += mcp4531.o
......
/*
* Maxim Integrated MAX5481-MAX5484 digital potentiometer driver
* Copyright 2016 Rockwell Collins
*
* Datasheet:
* http://datasheets.maximintegrated.com/en/ds/MAX5481-MAX5484.pdf
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the gnu general public license version 2 as
* published by the free software foundation.
*
*/
#include <linux/acpi.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/spi/spi.h>
/* write wiper reg */
#define MAX5481_WRITE_WIPER (0 << 4)
/* copy wiper reg to NV reg */
#define MAX5481_COPY_AB_TO_NV (2 << 4)
/* copy NV reg to wiper reg */
#define MAX5481_COPY_NV_TO_AB (3 << 4)
#define MAX5481_MAX_POS 1023
enum max5481_variant {
max5481,
max5482,
max5483,
max5484,
};
struct max5481_cfg {
int kohms;
};
static const struct max5481_cfg max5481_cfg[] = {
[max5481] = { .kohms = 10, },
[max5482] = { .kohms = 50, },
[max5483] = { .kohms = 10, },
[max5484] = { .kohms = 50, },
};
struct max5481_data {
struct spi_device *spi;
const struct max5481_cfg *cfg;
u8 msg[3] ____cacheline_aligned;
};
#define MAX5481_CHANNEL { \
.type = IIO_RESISTANCE, \
.indexed = 1, \
.output = 1, \
.channel = 0, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
}
static const struct iio_chan_spec max5481_channels[] = {
MAX5481_CHANNEL,
};
static int max5481_write_cmd(struct max5481_data *data, u8 cmd, u16 val)
{
struct spi_device *spi = data->spi;
data->msg[0] = cmd;
switch (cmd) {
case MAX5481_WRITE_WIPER:
data->msg[1] = val >> 2;
data->msg[2] = (val & 0x3) << 6;
return spi_write(spi, data->msg, 3);
case MAX5481_COPY_AB_TO_NV:
case MAX5481_COPY_NV_TO_AB:
return spi_write(spi, data->msg, 1);
default:
return -EIO;
}
}
static int max5481_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct max5481_data *data = iio_priv(indio_dev);
if (mask != IIO_CHAN_INFO_SCALE)
return -EINVAL;
*val = 1000 * data->cfg->kohms;
*val2 = MAX5481_MAX_POS;
return IIO_VAL_FRACTIONAL;
}
static int max5481_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct max5481_data *data = iio_priv(indio_dev);
if (mask != IIO_CHAN_INFO_RAW)
return -EINVAL;
if (val < 0 || val > MAX5481_MAX_POS)
return -EINVAL;
return max5481_write_cmd(data, MAX5481_WRITE_WIPER, val);
}
static const struct iio_info max5481_info = {
.read_raw = max5481_read_raw,
.write_raw = max5481_write_raw,
.driver_module = THIS_MODULE,
};
#if defined(CONFIG_OF)
static const struct of_device_id max5481_match[] = {
{ .compatible = "maxim,max5481", .data = &max5481_cfg[max5481] },
{ .compatible = "maxim,max5482", .data = &max5481_cfg[max5482] },
{ .compatible = "maxim,max5483", .data = &max5481_cfg[max5483] },
{ .compatible = "maxim,max5484", .data = &max5481_cfg[max5484] },
{ }
};
MODULE_DEVICE_TABLE(of, max5481_match);
#endif
static int max5481_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct max5481_data *data;
const struct spi_device_id *id = spi_get_device_id(spi);
const struct of_device_id *match;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
dev_set_drvdata(&spi->dev, indio_dev);
data = iio_priv(indio_dev);
data->spi = spi;
match = of_match_device(of_match_ptr(max5481_match), &spi->dev);
if (match)
data->cfg = of_device_get_match_data(&spi->dev);
else
data->cfg = &max5481_cfg[id->driver_data];
indio_dev->name = id->name;
indio_dev->dev.parent = &spi->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
/* variant specific configuration */
indio_dev->info = &max5481_info;
indio_dev->channels = max5481_channels;
indio_dev->num_channels = ARRAY_SIZE(max5481_channels);
/* restore wiper from NV */
ret = max5481_write_cmd(data, MAX5481_COPY_NV_TO_AB, 0);
if (ret < 0)
return ret;
return iio_device_register(indio_dev);
}
static int max5481_remove(struct spi_device *spi)
{
struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
struct max5481_data *data = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
/* save wiper reg to NV reg */
return max5481_write_cmd(data, MAX5481_COPY_AB_TO_NV, 0);
}
static const struct spi_device_id max5481_id_table[] = {
{ "max5481", max5481 },
{ "max5482", max5482 },
{ "max5483", max5483 },
{ "max5484", max5484 },
{ }
};
MODULE_DEVICE_TABLE(spi, max5481_id_table);
#if defined(CONFIG_ACPI)
static const struct acpi_device_id max5481_acpi_match[] = {
{ "max5481", max5481 },
{ "max5482", max5482 },
{ "max5483", max5483 },
{ "max5484", max5484 },
{ }
};
MODULE_DEVICE_TABLE(acpi, max5481_acpi_match);
#endif
static struct spi_driver max5481_driver = {
.driver = {
.name = "max5481",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(max5481_match),
.acpi_match_table = ACPI_PTR(max5481_acpi_match),
},
.probe = max5481_probe,
.remove = max5481_remove,
.id_table = max5481_id_table,
};
module_spi_driver(max5481_driver);
MODULE_AUTHOR("Maury Anderson <maury.anderson@rockwellcollins.com>");
MODULE_DESCRIPTION("max5481 SPI driver");
MODULE_LICENSE("GPL v2");
......@@ -42,6 +42,16 @@ config BMP280_SPI
depends on SPI_MASTER
select REGMAP
config IIO_CROS_EC_BARO
tristate "ChromeOS EC Barometer Sensor"
depends on IIO_CROS_EC_SENSORS_CORE
help
Say yes here to build support for the Barometer sensor when
presented by the ChromeOS EC Sensor hub.
To compile this driver as a module, choose M here: the module
will be called cros_ec_baro.
config HID_SENSOR_PRESS
depends on HID_SENSOR_HUB
select IIO_BUFFER
......
......@@ -8,6 +8,7 @@ obj-$(CONFIG_BMP280) += bmp280.o
bmp280-objs := bmp280-core.o bmp280-regmap.o
obj-$(CONFIG_BMP280_I2C) += bmp280-i2c.o
obj-$(CONFIG_BMP280_SPI) += bmp280-spi.o
obj-$(CONFIG_IIO_CROS_EC_BARO) += cros_ec_baro.o
obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o
obj-$(CONFIG_HP03) += hp03.o
obj-$(CONFIG_MPL115) += mpl115.o
......
/*
* cros_ec_baro - Driver for barometer sensor behind CrosEC.
*
* Copyright (C) 2017 Google, Inc
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/kernel.h>
#include <linux/mfd/cros_ec.h>
#include <linux/mfd/cros_ec_commands.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include "../common/cros_ec_sensors/cros_ec_sensors_core.h"
/*
* One channel for pressure, the other for timestamp.
*/
#define CROS_EC_BARO_MAX_CHANNELS (1 + 1)
/* State data for ec_sensors iio driver. */
struct cros_ec_baro_state {
/* Shared by all sensors */
struct cros_ec_sensors_core_state core;
struct iio_chan_spec channels[CROS_EC_BARO_MAX_CHANNELS];
};
static int cros_ec_baro_read(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct cros_ec_baro_state *st = iio_priv(indio_dev);
u16 data = 0;
int ret = IIO_VAL_INT;
int idx = chan->scan_index;
mutex_lock(&st->core.cmd_lock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (cros_ec_sensors_read_cmd(indio_dev, 1 << idx,
(s16 *)&data) < 0)
ret = -EIO;
*val = data;
break;
case IIO_CHAN_INFO_SCALE:
st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
st->core.param.sensor_range.data = EC_MOTION_SENSE_NO_VALUE;
if (cros_ec_motion_send_host_cmd(&st->core, 0)) {
ret = -EIO;
break;
}
*val = st->core.resp->sensor_range.ret;
/* scale * in_pressure_raw --> kPa */
*val2 = 10 << CROS_EC_SENSOR_BITS;
ret = IIO_VAL_FRACTIONAL;
break;
default:
ret = cros_ec_sensors_core_read(&st->core, chan, val, val2,
mask);
break;
}
mutex_unlock(&st->core.cmd_lock);
return ret;
}
static int cros_ec_baro_write(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct cros_ec_baro_state *st = iio_priv(indio_dev);
int ret = 0;
mutex_lock(&st->core.cmd_lock);
switch (mask) {
case IIO_CHAN_INFO_SCALE:
st->core.param.cmd = MOTIONSENSE_CMD_SENSOR_RANGE;
st->core.param.sensor_range.data = val;
/* Always roundup, so caller gets at least what it asks for. */
st->core.param.sensor_range.roundup = 1;
if (cros_ec_motion_send_host_cmd(&st->core, 0))
ret = -EIO;
break;
default:
ret = cros_ec_sensors_core_write(&st->core, chan, val, val2,
mask);
break;
}
mutex_unlock(&st->core.cmd_lock);
return ret;
}
static const struct iio_info cros_ec_baro_info = {
.read_raw = &cros_ec_baro_read,
.write_raw = &cros_ec_baro_write,
.driver_module = THIS_MODULE,
};
static int cros_ec_baro_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct cros_ec_dev *ec_dev = dev_get_drvdata(dev->parent);
struct cros_ec_device *ec_device;
struct iio_dev *indio_dev;
struct cros_ec_baro_state *state;
struct iio_chan_spec *channel;
int ret;
if (!ec_dev || !ec_dev->ec_dev) {
dev_warn(dev, "No CROS EC device found.\n");
return -EINVAL;
}
ec_device = ec_dev->ec_dev;
indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
if (!indio_dev)
return -ENOMEM;
ret = cros_ec_sensors_core_init(pdev, indio_dev, true);
if (ret)
return ret;
indio_dev->info = &cros_ec_baro_info;
state = iio_priv(indio_dev);
state->core.type = state->core.resp->info.type;
state->core.loc = state->core.resp->info.location;
channel = state->channels;
/* Common part */
channel->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
channel->info_mask_shared_by_all =
BIT(IIO_CHAN_INFO_SCALE) |
BIT(IIO_CHAN_INFO_SAMP_FREQ) |
BIT(IIO_CHAN_INFO_FREQUENCY);
channel->scan_type.realbits = CROS_EC_SENSOR_BITS;
channel->scan_type.storagebits = CROS_EC_SENSOR_BITS;
channel->scan_type.shift = 0;
channel->scan_index = 0;
channel->ext_info = cros_ec_sensors_ext_info;
channel->scan_type.sign = 'u';
state->core.calib[0] = 0;
/* Sensor specific */
switch (state->core.type) {
case MOTIONSENSE_TYPE_BARO:
channel->type = IIO_PRESSURE;
break;
default:
dev_warn(dev, "Unknown motion sensor\n");
return -EINVAL;
}
/* Timestamp */
channel++;
channel->type = IIO_TIMESTAMP;
channel->channel = -1;
channel->scan_index = 1;
channel->scan_type.sign = 's';
channel->scan_type.realbits = 64;
channel->scan_type.storagebits = 64;
indio_dev->channels = state->channels;
indio_dev->num_channels = CROS_EC_BARO_MAX_CHANNELS;
state->core.read_ec_sensors_data = cros_ec_sensors_read_cmd;
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
cros_ec_sensors_capture, NULL);
if (ret)
return ret;
return devm_iio_device_register(dev, indio_dev);
}
static const struct platform_device_id cros_ec_baro_ids[] = {
{
.name = "cros-ec-baro",
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, cros_ec_baro_ids);
static struct platform_driver cros_ec_baro_platform_driver = {
.driver = {
.name = "cros-ec-baro",
},
.probe = cros_ec_baro_probe,
.id_table = cros_ec_baro_ids,
};
module_platform_driver(cros_ec_baro_platform_driver);
MODULE_DESCRIPTION("ChromeOS EC barometer sensor driver");
MODULE_LICENSE("GPL v2");
......@@ -18,7 +18,7 @@ config AS3935
endmenu
menu "Proximity sensors"
menu "Proximity and distance sensors"
config LIDAR_LITE_V2
tristate "PulsedLight LIDAR sensor"
......@@ -45,4 +45,15 @@ config SX9500
To compile this driver as a module, choose M here: the
module will be called sx9500.
config SRF08
tristate "Devantech SRF08 ultrasonic ranger sensor"
depends on I2C
help
Say Y here to build a driver for Devantech SRF08 ultrasonic
ranger sensor. This driver can be used to measure the distance
of objects.
To compile this driver as a module, choose M here: the
module will be called srf08.
endmenu
......@@ -5,4 +5,5 @@
# When adding new entries keep the list in alphabetical order
obj-$(CONFIG_AS3935) += as3935.o
obj-$(CONFIG_LIDAR_LITE_V2) += pulsedlight-lidar-lite-v2.o
obj-$(CONFIG_SRF08) += srf08.o
obj-$(CONFIG_SX9500) += sx9500.o
/*
* srf08.c - Support for Devantech SRF08 ultrasonic ranger
*
* Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de>
*
* This file is subject to the terms and conditions of version 2 of
* the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
*
* For details about the device see:
* http://www.robot-electronics.co.uk/htm/srf08tech.html
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
/* registers of SRF08 device */
#define SRF08_WRITE_COMMAND 0x00 /* Command Register */
#define SRF08_WRITE_MAX_GAIN 0x01 /* Max Gain Register: 0 .. 31 */
#define SRF08_WRITE_RANGE 0x02 /* Range Register: 0 .. 255 */
#define SRF08_READ_SW_REVISION 0x00 /* Software Revision */
#define SRF08_READ_LIGHT 0x01 /* Light Sensor during last echo */
#define SRF08_READ_ECHO_1_HIGH 0x02 /* Range of first echo received */
#define SRF08_READ_ECHO_1_LOW 0x03 /* Range of first echo received */
#define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */
#define SRF08_DEFAULT_GAIN 1025 /* default analogue value of Gain */
#define SRF08_DEFAULT_RANGE 6020 /* default value of Range in mm */
struct srf08_data {
struct i2c_client *client;
int sensitivity; /* Gain */
int range_mm; /* max. Range in mm */
struct mutex lock;
};
/*
* in the documentation one can read about the "Gain" of the device
* which is used here for amplifying the signal and filtering out unwanted
* ones.
* But with ADC's this term is already used differently and that's why it
* is called "Sensitivity" here.
*/
static const int srf08_sensitivity[] = {
94, 97, 100, 103, 107, 110, 114, 118,
123, 128, 133, 139, 145, 152, 159, 168,
177, 187, 199, 212, 227, 245, 265, 288,
317, 352, 395, 450, 524, 626, 777, 1025 };
static int srf08_read_ranging(struct srf08_data *data)
{
struct i2c_client *client = data->client;
int ret, i;
int waittime;
mutex_lock(&data->lock);
ret = i2c_smbus_write_byte_data(data->client,
SRF08_WRITE_COMMAND, SRF08_CMD_RANGING_CM);
if (ret < 0) {
dev_err(&client->dev, "write command - err: %d\n", ret);
mutex_unlock(&data->lock);
return ret;
}
/*
* we read here until a correct version number shows up as
* suggested by the documentation
*
* with an ultrasonic speed of 343 m/s and a roundtrip of it
* sleep the expected duration and try to read from the device
* if nothing useful is read try it in a shorter grid
*
* polling for not more than 20 ms should be enough
*/
waittime = 1 + data->range_mm / 172;
msleep(waittime);
for (i = 0; i < 4; i++) {
ret = i2c_smbus_read_byte_data(data->client,
SRF08_READ_SW_REVISION);
/* check if a valid version number is read */
if (ret < 255 && ret > 0)
break;
msleep(5);
}
if (ret >= 255 || ret <= 0) {
dev_err(&client->dev, "device not ready\n");
mutex_unlock(&data->lock);
return -EIO;
}
ret = i2c_smbus_read_word_swapped(data->client,
SRF08_READ_ECHO_1_HIGH);
if (ret < 0) {
dev_err(&client->dev, "cannot read distance: ret=%d\n", ret);
mutex_unlock(&data->lock);
return ret;
}
mutex_unlock(&data->lock);
return ret;
}
static int srf08_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *channel, int *val,
int *val2, long mask)
{
struct srf08_data *data = iio_priv(indio_dev);
int ret;
if (channel->type != IIO_DISTANCE)
return -EINVAL;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = srf08_read_ranging(data);
if (ret < 0)
return ret;
*val = ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
/* 1 LSB is 1 cm */
*val = 0;
*val2 = 10000;
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
}
static ssize_t srf08_show_range_mm_available(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "[0.043 0.043 11.008]\n");
}
static IIO_DEVICE_ATTR(sensor_max_range_available, S_IRUGO,
srf08_show_range_mm_available, NULL, 0);
static ssize_t srf08_show_range_mm(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct srf08_data *data = iio_priv(indio_dev);
return sprintf(buf, "%d.%03d\n", data->range_mm / 1000,
data->range_mm % 1000);
}
/*
* set the range of the sensor to an even multiple of 43 mm
* which corresponds to 1 LSB in the register
*
* register value corresponding range
* 0x00 43 mm
* 0x01 86 mm
* 0x02 129 mm
* ...
* 0xFF 11008 mm
*/
static ssize_t srf08_write_range_mm(struct srf08_data *data, unsigned int val)
{
int ret;
struct i2c_client *client = data->client;
unsigned int mod;
u8 regval;
ret = val / 43 - 1;
mod = val % 43;
if (mod || (ret < 0) || (ret > 255))
return -EINVAL;
regval = ret;
mutex_lock(&data->lock);
ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_RANGE, regval);
if (ret < 0) {
dev_err(&client->dev, "write_range - err: %d\n", ret);
mutex_unlock(&data->lock);
return ret;
}
data->range_mm = val;
mutex_unlock(&data->lock);
return 0;
}
static ssize_t srf08_store_range_mm(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct srf08_data *data = iio_priv(indio_dev);
int ret;
int integer, fract;
ret = iio_str_to_fixpoint(buf, 100, &integer, &fract);
if (ret)
return ret;
ret = srf08_write_range_mm(data, integer * 1000 + fract);
if (ret < 0)
return ret;
return len;
}
static IIO_DEVICE_ATTR(sensor_max_range, S_IRUGO | S_IWUSR,
srf08_show_range_mm, srf08_store_range_mm, 0);
static ssize_t srf08_show_sensitivity_available(struct device *dev,
struct device_attribute *attr, char *buf)
{
int i, len = 0;
for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++)
len += sprintf(buf + len, "%d ", srf08_sensitivity[i]);
len += sprintf(buf + len, "\n");
return len;
}
static IIO_DEVICE_ATTR(sensor_sensitivity_available, S_IRUGO,
srf08_show_sensitivity_available, NULL, 0);
static ssize_t srf08_show_sensitivity(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct srf08_data *data = iio_priv(indio_dev);
int len;
len = sprintf(buf, "%d\n", data->sensitivity);
return len;
}
static ssize_t srf08_write_sensitivity(struct srf08_data *data,
unsigned int val)
{
struct i2c_client *client = data->client;
int ret, i;
u8 regval;
for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++)
if (val == srf08_sensitivity[i]) {
regval = i;
break;
}
if (i >= ARRAY_SIZE(srf08_sensitivity))
return -EINVAL;
mutex_lock(&data->lock);
ret = i2c_smbus_write_byte_data(client,
SRF08_WRITE_MAX_GAIN, regval);
if (ret < 0) {
dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
mutex_unlock(&data->lock);
return ret;
}
data->sensitivity = val;
mutex_unlock(&data->lock);
return 0;
}
static ssize_t srf08_store_sensitivity(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct srf08_data *data = iio_priv(indio_dev);
int ret;
unsigned int val;
ret = kstrtouint(buf, 10, &val);
if (ret)
return ret;
ret = srf08_write_sensitivity(data, val);
if (ret < 0)
return ret;
return len;
}
static IIO_DEVICE_ATTR(sensor_sensitivity, S_IRUGO | S_IWUSR,
srf08_show_sensitivity, srf08_store_sensitivity, 0);
static struct attribute *srf08_attributes[] = {
&iio_dev_attr_sensor_max_range.dev_attr.attr,
&iio_dev_attr_sensor_max_range_available.dev_attr.attr,
&iio_dev_attr_sensor_sensitivity.dev_attr.attr,
&iio_dev_attr_sensor_sensitivity_available.dev_attr.attr,
NULL,
};
static const struct attribute_group srf08_attribute_group = {
.attrs = srf08_attributes,
};
static const struct iio_chan_spec srf08_channels[] = {
{
.type = IIO_DISTANCE,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
},
};
static const struct iio_info srf08_info = {
.read_raw = srf08_read_raw,
.attrs = &srf08_attribute_group,
.driver_module = THIS_MODULE,
};
static int srf08_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct srf08_data *data;
int ret;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_BYTE_DATA |
I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
I2C_FUNC_SMBUS_READ_WORD_DATA))
return -ENODEV;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
indio_dev->name = "srf08";
indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &srf08_info;
indio_dev->channels = srf08_channels;
indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
mutex_init(&data->lock);
/*
* set default values of device here
* these register values cannot be read from the hardware
* therefore set driver specific default values
*/
ret = srf08_write_range_mm(data, SRF08_DEFAULT_RANGE);
if (ret < 0)
return ret;
ret = srf08_write_sensitivity(data, SRF08_DEFAULT_GAIN);
if (ret < 0)
return ret;
return devm_iio_device_register(&client->dev, indio_dev);
}
static const struct i2c_device_id srf08_id[] = {
{ "srf08", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, srf08_id);
static struct i2c_driver srf08_driver = {
.driver = {
.name = "srf08",
},
.probe = srf08_probe,
.id_table = srf08_id,
};
module_i2c_driver(srf08_driver);
MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
MODULE_DESCRIPTION("Devantech SRF08 ultrasonic ranger driver");
MODULE_LICENSE("GPL");
......@@ -233,7 +233,7 @@ static int tmp007_probe(struct i2c_client *client,
data->client = client;
indio_dev->dev.parent = &client->dev;
indio_dev->name = dev_name(&client->dev);
indio_dev->name = "tmp007";
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &tmp007_info;
......
......@@ -24,6 +24,15 @@ config IIO_INTERRUPT_TRIGGER
To compile this driver as a module, choose M here: the
module will be called iio-trig-interrupt.
config IIO_STM32_TIMER_TRIGGER
tristate "STM32 Timer Trigger"
depends on (ARCH_STM32 && OF && MFD_STM32_TIMERS) || COMPILE_TEST
help
Select this option to enable STM32 Timer Trigger
To compile this driver as a module, choose M here: the
module will be called stm32-timer-trigger.
config IIO_TIGHTLOOP_TRIGGER
tristate "A kthread based hammering loop trigger"
depends on IIO_SW_TRIGGER
......
......@@ -6,5 +6,6 @@
obj-$(CONFIG_IIO_HRTIMER_TRIGGER) += iio-trig-hrtimer.o
obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o
obj-$(CONFIG_IIO_STM32_TIMER_TRIGGER) += stm32-timer-trigger.o
obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o
obj-$(CONFIG_IIO_TIGHTLOOP_TRIGGER) += iio-trig-loop.o
/*
* Copyright (C) STMicroelectronics 2016
*
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
*
* License terms: GNU General Public License (GPL), version 2
*/
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/timer/stm32-timer-trigger.h>
#include <linux/iio/trigger.h>
#include <linux/mfd/stm32-timers.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#define MAX_TRIGGERS 6
/* List the triggers created by each timer */
static const void *triggers_table[][MAX_TRIGGERS] = {
{ TIM1_TRGO, TIM1_CH1, TIM1_CH2, TIM1_CH3, TIM1_CH4,},
{ TIM2_TRGO, TIM2_CH1, TIM2_CH2, TIM2_CH3, TIM2_CH4,},
{ TIM3_TRGO, TIM3_CH1, TIM3_CH2, TIM3_CH3, TIM3_CH4,},
{ TIM4_TRGO, TIM4_CH1, TIM4_CH2, TIM4_CH3, TIM4_CH4,},
{ TIM5_TRGO, TIM5_CH1, TIM5_CH2, TIM5_CH3, TIM5_CH4,},
{ TIM6_TRGO,},
{ TIM7_TRGO,},
{ TIM8_TRGO, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,},
{ TIM9_TRGO, TIM9_CH1, TIM9_CH2,},
{ }, /* timer 10 */
{ }, /* timer 11 */
{ TIM12_TRGO, TIM12_CH1, TIM12_CH2,},
};
struct stm32_timer_trigger {
struct device *dev;
struct regmap *regmap;
struct clk *clk;
u32 max_arr;
const void *triggers;
};
static int stm32_timer_start(struct stm32_timer_trigger *priv,
unsigned int frequency)
{
unsigned long long prd, div;
int prescaler = 0;
u32 ccer, cr1;
/* Period and prescaler values depends of clock rate */
div = (unsigned long long)clk_get_rate(priv->clk);
do_div(div, frequency);
prd = div;
/*
* Increase prescaler value until we get a result that fit
* with auto reload register maximum value.
*/
while (div > priv->max_arr) {
prescaler++;
div = prd;
do_div(div, (prescaler + 1));
}
prd = div;
if (prescaler > MAX_TIM_PSC) {
dev_err(priv->dev, "prescaler exceeds the maximum value\n");
return -EINVAL;
}
/* Check if nobody else use the timer */
regmap_read(priv->regmap, TIM_CCER, &ccer);
if (ccer & TIM_CCER_CCXE)
return -EBUSY;
regmap_read(priv->regmap, TIM_CR1, &cr1);
if (!(cr1 & TIM_CR1_CEN))
clk_enable(priv->clk);
regmap_write(priv->regmap, TIM_PSC, prescaler);
regmap_write(priv->regmap, TIM_ARR, prd - 1);
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
/* Force master mode to update mode */
regmap_update_bits(priv->regmap, TIM_CR2, TIM_CR2_MMS, 0x20);
/* Make sure that registers are updated */
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
/* Enable controller */
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
return 0;
}
static void stm32_timer_stop(struct stm32_timer_trigger *priv)
{
u32 ccer, cr1;
regmap_read(priv->regmap, TIM_CCER, &ccer);
if (ccer & TIM_CCER_CCXE)
return;
regmap_read(priv->regmap, TIM_CR1, &cr1);
if (cr1 & TIM_CR1_CEN)
clk_disable(priv->clk);
/* Stop timer */
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
regmap_write(priv->regmap, TIM_PSC, 0);
regmap_write(priv->regmap, TIM_ARR, 0);
/* Make sure that registers are updated */
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
}
static ssize_t stm32_tt_store_frequency(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct iio_trigger *trig = to_iio_trigger(dev);
struct stm32_timer_trigger *priv = iio_trigger_get_drvdata(trig);
unsigned int freq;
int ret;
ret = kstrtouint(buf, 10, &freq);
if (ret)
return ret;
if (freq == 0) {
stm32_timer_stop(priv);
} else {
ret = stm32_timer_start(priv, freq);
if (ret)
return ret;
}
return len;
}
static ssize_t stm32_tt_read_frequency(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct iio_trigger *trig = to_iio_trigger(dev);
struct stm32_timer_trigger *priv = iio_trigger_get_drvdata(trig);
u32 psc, arr, cr1;
unsigned long long freq = 0;
regmap_read(priv->regmap, TIM_CR1, &cr1);
regmap_read(priv->regmap, TIM_PSC, &psc);
regmap_read(priv->regmap, TIM_ARR, &arr);
if (psc && arr && (cr1 & TIM_CR1_CEN)) {
freq = (unsigned long long)clk_get_rate(priv->clk);
do_div(freq, psc);
do_div(freq, arr);
}
return sprintf(buf, "%d\n", (unsigned int)freq);
}
static IIO_DEV_ATTR_SAMP_FREQ(0660,
stm32_tt_read_frequency,
stm32_tt_store_frequency);
static char *master_mode_table[] = {
"reset",
"enable",
"update",
"compare_pulse",
"OC1REF",
"OC2REF",
"OC3REF",
"OC4REF"
};
static ssize_t stm32_tt_show_master_mode(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct stm32_timer_trigger *priv = iio_priv(indio_dev);
u32 cr2;
regmap_read(priv->regmap, TIM_CR2, &cr2);
cr2 = (cr2 & TIM_CR2_MMS) >> TIM_CR2_MMS_SHIFT;
return snprintf(buf, PAGE_SIZE, "%s\n", master_mode_table[cr2]);
}
static ssize_t stm32_tt_store_master_mode(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct stm32_timer_trigger *priv = iio_priv(indio_dev);
int i;
for (i = 0; i < ARRAY_SIZE(master_mode_table); i++) {
if (!strncmp(master_mode_table[i], buf,
strlen(master_mode_table[i]))) {
regmap_update_bits(priv->regmap, TIM_CR2,
TIM_CR2_MMS, i << TIM_CR2_MMS_SHIFT);
/* Make sure that registers are updated */
regmap_update_bits(priv->regmap, TIM_EGR,
TIM_EGR_UG, TIM_EGR_UG);
return len;
}
}
return -EINVAL;
}
static IIO_CONST_ATTR(master_mode_available,
"reset enable update compare_pulse OC1REF OC2REF OC3REF OC4REF");
static IIO_DEVICE_ATTR(master_mode, 0660,
stm32_tt_show_master_mode,
stm32_tt_store_master_mode,
0);
static struct attribute *stm32_trigger_attrs[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_dev_attr_master_mode.dev_attr.attr,
&iio_const_attr_master_mode_available.dev_attr.attr,
NULL,
};
static const struct attribute_group stm32_trigger_attr_group = {
.attrs = stm32_trigger_attrs,
};
static const struct attribute_group *stm32_trigger_attr_groups[] = {
&stm32_trigger_attr_group,
NULL,
};
static const struct iio_trigger_ops timer_trigger_ops = {
.owner = THIS_MODULE,
};
static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
{
int ret;
const char * const *cur = priv->triggers;
while (cur && *cur) {
struct iio_trigger *trig;
trig = devm_iio_trigger_alloc(priv->dev, "%s", *cur);
if (!trig)
return -ENOMEM;
trig->dev.parent = priv->dev->parent;
trig->ops = &timer_trigger_ops;
/*
* sampling frequency and master mode attributes
* should only be available on trgo trigger which
* is always the first in the list.
*/
if (cur == priv->triggers)
trig->dev.groups = stm32_trigger_attr_groups;
iio_trigger_set_drvdata(trig, priv);
ret = devm_iio_trigger_register(priv->dev, trig);
if (ret)
return ret;
cur++;
}
return 0;
}
/**
* is_stm32_timer_trigger
* @trig: trigger to be checked
*
* return true if the trigger is a valid stm32 iio timer trigger
* either return false
*/
bool is_stm32_timer_trigger(struct iio_trigger *trig)
{
return (trig->ops == &timer_trigger_ops);
}
EXPORT_SYMBOL(is_stm32_timer_trigger);
static int stm32_timer_trigger_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct stm32_timer_trigger *priv;
struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
unsigned int index;
int ret;
if (of_property_read_u32(dev->of_node, "reg", &index))
return -EINVAL;
if (index >= ARRAY_SIZE(triggers_table))
return -EINVAL;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->dev = dev;
priv->regmap = ddata->regmap;
priv->clk = ddata->clk;
priv->max_arr = ddata->max_arr;
priv->triggers = triggers_table[index];
ret = stm32_setup_iio_triggers(priv);
if (ret)
return ret;
platform_set_drvdata(pdev, priv);
return 0;
}
static const struct of_device_id stm32_trig_of_match[] = {
{ .compatible = "st,stm32-timer-trigger", },
{ /* end node */ },
};
MODULE_DEVICE_TABLE(of, stm32_trig_of_match);
static struct platform_driver stm32_timer_trigger_driver = {
.probe = stm32_timer_trigger_probe,
.driver = {
.name = "stm32-timer-trigger",
.of_match_table = stm32_trig_of_match,
},
};
module_platform_driver(stm32_timer_trigger_driver);
MODULE_ALIAS("platform: stm32-timer-trigger");
MODULE_DESCRIPTION("STMicroelectronics STM32 Timer Trigger driver");
MODULE_LICENSE("GPL v2");
......@@ -1621,6 +1621,17 @@ config MFD_STW481X
in various ST Microelectronics and ST-Ericsson embedded
Nomadik series.
config MFD_STM32_TIMERS
tristate "Support for STM32 Timers"
depends on (ARCH_STM32 && OF) || COMPILE_TEST
select MFD_CORE
select REGMAP
select REGMAP_MMIO
help
Select this option to enable STM32 timers driver used
for PWM and IIO Timer. This driver allow to share the
registers between the others drivers.
menu "Multimedia Capabilities Port drivers"
depends on ARCH_SA1100
......
......@@ -212,3 +212,5 @@ obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
/*
* Copyright (C) STMicroelectronics 2016
*
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
*
* License terms: GNU General Public License (GPL), version 2
*/
#include <linux/mfd/stm32-timers.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/reset.h>
static const struct regmap_config stm32_timers_regmap_cfg = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = sizeof(u32),
.max_register = 0x400,
};
static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
{
/*
* Only the available bits will be written so when readback
* we get the maximum value of auto reload register
*/
regmap_write(ddata->regmap, TIM_ARR, ~0L);
regmap_read(ddata->regmap, TIM_ARR, &ddata->max_arr);
regmap_write(ddata->regmap, TIM_ARR, 0x0);
}
static int stm32_timers_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct stm32_timers *ddata;
struct resource *res;
void __iomem *mmio;
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
if (!ddata)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mmio = devm_ioremap_resource(dev, res);
if (IS_ERR(mmio))
return PTR_ERR(mmio);
ddata->regmap = devm_regmap_init_mmio_clk(dev, "int", mmio,
&stm32_timers_regmap_cfg);
if (IS_ERR(ddata->regmap))
return PTR_ERR(ddata->regmap);
ddata->clk = devm_clk_get(dev, NULL);
if (IS_ERR(ddata->clk))
return PTR_ERR(ddata->clk);
stm32_timers_get_arr_size(ddata);
platform_set_drvdata(pdev, ddata);
return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
}
static const struct of_device_id stm32_timers_of_match[] = {
{ .compatible = "st,stm32-timers", },
{ /* end node */ },
};
MODULE_DEVICE_TABLE(of, stm32_timers_of_match);
static struct platform_driver stm32_timers_driver = {
.probe = stm32_timers_probe,
.driver = {
.name = "stm32-timers",
.of_match_table = stm32_timers_of_match,
},
};
module_platform_driver(stm32_timers_driver);
MODULE_DESCRIPTION("STMicroelectronics STM32 Timers");
MODULE_LICENSE("GPL v2");
......@@ -328,6 +328,9 @@ static void cros_ec_sensors_register(struct cros_ec_dev *ec)
case MOTIONSENSE_TYPE_ACCEL:
sensor_cells[id].name = "cros-ec-accel";
break;
case MOTIONSENSE_TYPE_BARO:
sensor_cells[id].name = "cros-ec-baro";
break;
case MOTIONSENSE_TYPE_GYRO:
sensor_cells[id].name = "cros-ec-gyro";
break;
......
......@@ -397,6 +397,15 @@ config PWM_STI
To compile this driver as a module, choose M here: the module
will be called pwm-sti.
config PWM_STM32
tristate "STMicroelectronics STM32 PWM"
depends on MFD_STM32_TIMERS || COMPILE_TEST
help
Generic PWM framework driver for STM32 SoCs.
To compile this driver as a module, choose M here: the module
will be called pwm-stm32.
config PWM_STMPE
bool "STMPE expander PWM export"
depends on MFD_STMPE
......
......@@ -38,6 +38,7 @@ obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
obj-$(CONFIG_PWM_STI) += pwm-sti.o
obj-$(CONFIG_PWM_STM32) += pwm-stm32.o
obj-$(CONFIG_PWM_STMPE) += pwm-stmpe.o
obj-$(CONFIG_PWM_SUN4I) += pwm-sun4i.o
obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
......
/*
* Copyright (C) STMicroelectronics 2016
*
* Author: Gerald Baeza <gerald.baeza@st.com>
*
* License terms: GNU General Public License (GPL), version 2
*
* Inspired by timer-stm32.c from Maxime Coquelin
* pwm-atmel.c from Bo Shen
*/
#include <linux/mfd/stm32-timers.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pwm.h>
#define CCMR_CHANNEL_SHIFT 8
#define CCMR_CHANNEL_MASK 0xFF
#define MAX_BREAKINPUT 2
struct stm32_pwm {
struct pwm_chip chip;
struct device *dev;
struct clk *clk;
struct regmap *regmap;
u32 max_arr;
bool have_complementary_output;
};
struct stm32_breakinput {
u32 index;
u32 level;
u32 filter;
};
static inline struct stm32_pwm *to_stm32_pwm_dev(struct pwm_chip *chip)
{
return container_of(chip, struct stm32_pwm, chip);
}
static u32 active_channels(struct stm32_pwm *dev)
{
u32 ccer;
regmap_read(dev->regmap, TIM_CCER, &ccer);
return ccer & TIM_CCER_CCXE;
}
static int write_ccrx(struct stm32_pwm *dev, int ch, u32 value)
{
switch (ch) {
case 0:
return regmap_write(dev->regmap, TIM_CCR1, value);
case 1:
return regmap_write(dev->regmap, TIM_CCR2, value);
case 2:
return regmap_write(dev->regmap, TIM_CCR3, value);
case 3:
return regmap_write(dev->regmap, TIM_CCR4, value);
}
return -EINVAL;
}
static int stm32_pwm_config(struct stm32_pwm *priv, int ch,
int duty_ns, int period_ns)
{
unsigned long long prd, div, dty;
unsigned int prescaler = 0;
u32 ccmr, mask, shift;
/* Period and prescaler values depends on clock rate */
div = (unsigned long long)clk_get_rate(priv->clk) * period_ns;
do_div(div, NSEC_PER_SEC);
prd = div;
while (div > priv->max_arr) {
prescaler++;
div = prd;
do_div(div, prescaler + 1);
}
prd = div;
if (prescaler > MAX_TIM_PSC)
return -EINVAL;
/*
* All channels share the same prescaler and counter so when two
* channels are active at the same time we can't change them
*/
if (active_channels(priv) & ~(1 << ch * 4)) {
u32 psc, arr;
regmap_read(priv->regmap, TIM_PSC, &psc);
regmap_read(priv->regmap, TIM_ARR, &arr);
if ((psc != prescaler) || (arr != prd - 1))
return -EBUSY;
}
regmap_write(priv->regmap, TIM_PSC, prescaler);
regmap_write(priv->regmap, TIM_ARR, prd - 1);
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE);
/* Calculate the duty cycles */
dty = prd * duty_ns;
do_div(dty, period_ns);
write_ccrx(priv, ch, dty);
/* Configure output mode */
shift = (ch & 0x1) * CCMR_CHANNEL_SHIFT;
ccmr = (TIM_CCMR_PE | TIM_CCMR_M1) << shift;
mask = CCMR_CHANNEL_MASK << shift;
if (ch < 2)
regmap_update_bits(priv->regmap, TIM_CCMR1, mask, ccmr);
else
regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr);
regmap_update_bits(priv->regmap, TIM_BDTR,
TIM_BDTR_MOE | TIM_BDTR_AOE,
TIM_BDTR_MOE | TIM_BDTR_AOE);
return 0;
}
static int stm32_pwm_set_polarity(struct stm32_pwm *priv, int ch,
enum pwm_polarity polarity)
{
u32 mask;
mask = TIM_CCER_CC1P << (ch * 4);
if (priv->have_complementary_output)
mask |= TIM_CCER_CC1NP << (ch * 4);
regmap_update_bits(priv->regmap, TIM_CCER, mask,
polarity == PWM_POLARITY_NORMAL ? 0 : mask);
return 0;
}
static int stm32_pwm_enable(struct stm32_pwm *priv, int ch)
{
u32 mask;
int ret;
ret = clk_enable(priv->clk);
if (ret)
return ret;
/* Enable channel */
mask = TIM_CCER_CC1E << (ch * 4);
if (priv->have_complementary_output)
mask |= TIM_CCER_CC1NE << (ch * 4);
regmap_update_bits(priv->regmap, TIM_CCER, mask, mask);
/* Make sure that registers are updated */
regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG);
/* Enable controller */
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN);
return 0;
}
static void stm32_pwm_disable(struct stm32_pwm *priv, int ch)
{
u32 mask;
/* Disable channel */
mask = TIM_CCER_CC1E << (ch * 4);
if (priv->have_complementary_output)
mask |= TIM_CCER_CC1NE << (ch * 4);
regmap_update_bits(priv->regmap, TIM_CCER, mask, 0);
/* When all channels are disabled, we can disable the controller */
if (!active_channels(priv))
regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0);
clk_disable(priv->clk);
}
static int stm32_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
struct pwm_state *state)
{
bool enabled;
struct stm32_pwm *priv = to_stm32_pwm_dev(chip);
int ret;
enabled = pwm->state.enabled;
if (enabled && !state->enabled) {
stm32_pwm_disable(priv, pwm->hwpwm);
return 0;
}
if (state->polarity != pwm->state.polarity)
stm32_pwm_set_polarity(priv, pwm->hwpwm, state->polarity);
ret = stm32_pwm_config(priv, pwm->hwpwm,
state->duty_cycle, state->period);
if (ret)
return ret;
if (!enabled && state->enabled)
ret = stm32_pwm_enable(priv, pwm->hwpwm);
return ret;
}
static const struct pwm_ops stm32pwm_ops = {
.owner = THIS_MODULE,
.apply = stm32_pwm_apply,
};
static int stm32_pwm_set_breakinput(struct stm32_pwm *priv,
int index, int level, int filter)
{
u32 bke = (index == 0) ? TIM_BDTR_BKE : TIM_BDTR_BK2E;
int shift = (index == 0) ? TIM_BDTR_BKF_SHIFT : TIM_BDTR_BK2F_SHIFT;
u32 mask = (index == 0) ? TIM_BDTR_BKE | TIM_BDTR_BKP | TIM_BDTR_BKF
: TIM_BDTR_BK2E | TIM_BDTR_BK2P | TIM_BDTR_BK2F;
u32 bdtr = bke;
/*
* The both bits could be set since only one will be wrote
* due to mask value.
*/
if (level)
bdtr |= TIM_BDTR_BKP | TIM_BDTR_BK2P;
bdtr |= (filter & TIM_BDTR_BKF_MASK) << shift;
regmap_update_bits(priv->regmap, TIM_BDTR, mask, bdtr);
regmap_read(priv->regmap, TIM_BDTR, &bdtr);
return (bdtr & bke) ? 0 : -EINVAL;
}
static int stm32_pwm_apply_breakinputs(struct stm32_pwm *priv,
struct device_node *np)
{
struct stm32_breakinput breakinput[MAX_BREAKINPUT];
int nb, ret, i, array_size;
nb = of_property_count_elems_of_size(np, "st,breakinput",
sizeof(struct stm32_breakinput));
/*
* Because "st,breakinput" parameter is optional do not make probe
* failed if it doesn't exist.
*/
if (nb <= 0)
return 0;
if (nb > MAX_BREAKINPUT)
return -EINVAL;
array_size = nb * sizeof(struct stm32_breakinput) / sizeof(u32);
ret = of_property_read_u32_array(np, "st,breakinput",
(u32 *)breakinput, array_size);
if (ret)
return ret;
for (i = 0; i < nb && !ret; i++) {
ret = stm32_pwm_set_breakinput(priv,
breakinput[i].index,
breakinput[i].level,
breakinput[i].filter);
}
return ret;
}
static void stm32_pwm_detect_complementary(struct stm32_pwm *priv)
{
u32 ccer;
/*
* If complementary bit doesn't exist writing 1 will have no
* effect so we can detect it.
*/
regmap_update_bits(priv->regmap,
TIM_CCER, TIM_CCER_CC1NE, TIM_CCER_CC1NE);
regmap_read(priv->regmap, TIM_CCER, &ccer);
regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CC1NE, 0);
priv->have_complementary_output = (ccer != 0);
}
static int stm32_pwm_detect_channels(struct stm32_pwm *priv)
{
u32 ccer;
int npwm = 0;
/*
* If channels enable bits don't exist writing 1 will have no
* effect so we can detect and count them.
*/
regmap_update_bits(priv->regmap,
TIM_CCER, TIM_CCER_CCXE, TIM_CCER_CCXE);
regmap_read(priv->regmap, TIM_CCER, &ccer);
regmap_update_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE, 0);
if (ccer & TIM_CCER_CC1E)
npwm++;
if (ccer & TIM_CCER_CC2E)
npwm++;
if (ccer & TIM_CCER_CC3E)
npwm++;
if (ccer & TIM_CCER_CC4E)
npwm++;
return npwm;
}
static int stm32_pwm_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
struct stm32_pwm *priv;
int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->regmap = ddata->regmap;
priv->clk = ddata->clk;
priv->max_arr = ddata->max_arr;
if (!priv->regmap || !priv->clk)
return -EINVAL;
ret = stm32_pwm_apply_breakinputs(priv, np);
if (ret)
return ret;
stm32_pwm_detect_complementary(priv);
priv->chip.base = -1;
priv->chip.dev = dev;
priv->chip.ops = &stm32pwm_ops;
priv->chip.npwm = stm32_pwm_detect_channels(priv);
ret = pwmchip_add(&priv->chip);
if (ret < 0)
return ret;
platform_set_drvdata(pdev, priv);
return 0;
}
static int stm32_pwm_remove(struct platform_device *pdev)
{
struct stm32_pwm *priv = platform_get_drvdata(pdev);
unsigned int i;
for (i = 0; i < priv->chip.npwm; i++)
pwm_disable(&priv->chip.pwms[i]);
pwmchip_remove(&priv->chip);
return 0;
}
static const struct of_device_id stm32_pwm_of_match[] = {
{ .compatible = "st,stm32-pwm", },
{ /* end node */ },
};
MODULE_DEVICE_TABLE(of, stm32_pwm_of_match);
static struct platform_driver stm32_pwm_driver = {
.probe = stm32_pwm_probe,
.remove = stm32_pwm_remove,
.driver = {
.name = "stm32-pwm",
.of_match_table = stm32_pwm_of_match,
},
};
module_platform_driver(stm32_pwm_driver);
MODULE_ALIAS("platform:stm32-pwm");
MODULE_DESCRIPTION("STMicroelectronics STM32 PWM driver");
MODULE_LICENSE("GPL v2");
......@@ -139,7 +139,7 @@ static ssize_t ad7816_store_mode(struct device *dev,
return len;
}
static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
static IIO_DEVICE_ATTR(mode, 0644,
ad7816_show_mode,
ad7816_store_mode,
0);
......@@ -151,7 +151,7 @@ static ssize_t ad7816_show_available_modes(struct device *dev,
return sprintf(buf, "full\npower-save\n");
}
static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes,
static IIO_DEVICE_ATTR(available_modes, 0444, ad7816_show_available_modes,
NULL, 0);
static ssize_t ad7816_show_channel(struct device *dev,
......@@ -197,7 +197,7 @@ static ssize_t ad7816_store_channel(struct device *dev,
return len;
}
static IIO_DEVICE_ATTR(channel, S_IRUGO | S_IWUSR,
static IIO_DEVICE_ATTR(channel, 0644,
ad7816_show_channel,
ad7816_store_channel,
0);
......@@ -228,7 +228,7 @@ static ssize_t ad7816_show_value(struct device *dev,
return sprintf(buf, "%u\n", data);
}
static IIO_DEVICE_ATTR(value, S_IRUGO, ad7816_show_value, NULL, 0);
static IIO_DEVICE_ATTR(value, 0444, ad7816_show_value, NULL, 0);
static struct attribute *ad7816_attributes[] = {
&iio_dev_attr_available_modes.dev_attr.attr,
......@@ -319,7 +319,7 @@ static inline ssize_t ad7816_set_oti(struct device *dev,
return len;
}
static IIO_DEVICE_ATTR(oti, S_IRUGO | S_IWUSR,
static IIO_DEVICE_ATTR(oti, 0644,
ad7816_show_oti, ad7816_set_oti, 0);
static struct attribute *ad7816_event_attributes[] = {
......
......@@ -610,27 +610,27 @@ static int ad7150_probe(struct i2c_client *client,
if (client->irq) {
ret = devm_request_threaded_irq(&client->dev, client->irq,
NULL,
&ad7150_event_handler,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING |
IRQF_ONESHOT,
"ad7150_irq1",
indio_dev);
NULL,
&ad7150_event_handler,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING |
IRQF_ONESHOT,
"ad7150_irq1",
indio_dev);
if (ret)
return ret;
}
if (client->dev.platform_data) {
ret = devm_request_threaded_irq(&client->dev, *(unsigned int *)
client->dev.platform_data,
NULL,
&ad7150_event_handler,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING |
IRQF_ONESHOT,
"ad7150_irq2",
indio_dev);
client->dev.platform_data,
NULL,
&ad7150_event_handler,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING |
IRQF_ONESHOT,
"ad7150_irq2",
indio_dev);
if (ret)
return ret;
}
......
/*
* Copyright (C) STMicroelectronics 2016
*
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
*
* License terms: GNU General Public License (GPL), version 2
*/
#ifndef _STM32_TIMER_TRIGGER_H_
#define _STM32_TIMER_TRIGGER_H_
#define TIM1_TRGO "tim1_trgo"
#define TIM1_CH1 "tim1_ch1"
#define TIM1_CH2 "tim1_ch2"
#define TIM1_CH3 "tim1_ch3"
#define TIM1_CH4 "tim1_ch4"
#define TIM2_TRGO "tim2_trgo"
#define TIM2_CH1 "tim2_ch1"
#define TIM2_CH2 "tim2_ch2"
#define TIM2_CH3 "tim2_ch3"
#define TIM2_CH4 "tim2_ch4"
#define TIM3_TRGO "tim3_trgo"
#define TIM3_CH1 "tim3_ch1"
#define TIM3_CH2 "tim3_ch2"
#define TIM3_CH3 "tim3_ch3"
#define TIM3_CH4 "tim3_ch4"
#define TIM4_TRGO "tim4_trgo"
#define TIM4_CH1 "tim4_ch1"
#define TIM4_CH2 "tim4_ch2"
#define TIM4_CH3 "tim4_ch3"
#define TIM4_CH4 "tim4_ch4"
#define TIM5_TRGO "tim5_trgo"
#define TIM5_CH1 "tim5_ch1"
#define TIM5_CH2 "tim5_ch2"
#define TIM5_CH3 "tim5_ch3"
#define TIM5_CH4 "tim5_ch4"
#define TIM6_TRGO "tim6_trgo"
#define TIM7_TRGO "tim7_trgo"
#define TIM8_TRGO "tim8_trgo"
#define TIM8_CH1 "tim8_ch1"
#define TIM8_CH2 "tim8_ch2"
#define TIM8_CH3 "tim8_ch3"
#define TIM8_CH4 "tim8_ch4"
#define TIM9_TRGO "tim9_trgo"
#define TIM9_CH1 "tim9_ch1"
#define TIM9_CH2 "tim9_ch2"
#define TIM12_TRGO "tim12_trgo"
#define TIM12_CH1 "tim12_ch1"
#define TIM12_CH2 "tim12_ch2"
bool is_stm32_timer_trigger(struct iio_trigger *trig);
#endif
......@@ -1441,7 +1441,8 @@ enum motionsensor_type {
MOTIONSENSE_TYPE_PROX = 3,
MOTIONSENSE_TYPE_LIGHT = 4,
MOTIONSENSE_TYPE_ACTIVITY = 5,
MOTIONSENSE_TYPE_MAX
MOTIONSENSE_TYPE_BARO = 6,
MOTIONSENSE_TYPE_MAX,
};
/* List of motion sensor locations. */
......
/*
* Copyright (C) STMicroelectronics 2016
*
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
*
* License terms: GNU General Public License (GPL), version 2
*/
#ifndef _LINUX_STM32_GPTIMER_H_
#define _LINUX_STM32_GPTIMER_H_
#include <linux/clk.h>
#include <linux/regmap.h>
#define TIM_CR1 0x00 /* Control Register 1 */
#define TIM_CR2 0x04 /* Control Register 2 */
#define TIM_SMCR 0x08 /* Slave mode control reg */
#define TIM_DIER 0x0C /* DMA/interrupt register */
#define TIM_SR 0x10 /* Status register */
#define TIM_EGR 0x14 /* Event Generation Reg */
#define TIM_CCMR1 0x18 /* Capt/Comp 1 Mode Reg */
#define TIM_CCMR2 0x1C /* Capt/Comp 2 Mode Reg */
#define TIM_CCER 0x20 /* Capt/Comp Enable Reg */
#define TIM_PSC 0x28 /* Prescaler */
#define TIM_ARR 0x2c /* Auto-Reload Register */
#define TIM_CCR1 0x34 /* Capt/Comp Register 1 */
#define TIM_CCR2 0x38 /* Capt/Comp Register 2 */
#define TIM_CCR3 0x3C /* Capt/Comp Register 3 */
#define TIM_CCR4 0x40 /* Capt/Comp Register 4 */
#define TIM_BDTR 0x44 /* Break and Dead-Time Reg */
#define TIM_CR1_CEN BIT(0) /* Counter Enable */
#define TIM_CR1_ARPE BIT(7) /* Auto-reload Preload Ena */
#define TIM_CR2_MMS (BIT(4) | BIT(5) | BIT(6)) /* Master mode selection */
#define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
#define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
#define TIM_DIER_UIE BIT(0) /* Update interrupt */
#define TIM_SR_UIF BIT(0) /* Update interrupt flag */
#define TIM_EGR_UG BIT(0) /* Update Generation */
#define TIM_CCMR_PE BIT(3) /* Channel Preload Enable */
#define TIM_CCMR_M1 (BIT(6) | BIT(5)) /* Channel PWM Mode 1 */
#define TIM_CCER_CC1E BIT(0) /* Capt/Comp 1 out Ena */
#define TIM_CCER_CC1P BIT(1) /* Capt/Comp 1 Polarity */
#define TIM_CCER_CC1NE BIT(2) /* Capt/Comp 1N out Ena */
#define TIM_CCER_CC1NP BIT(3) /* Capt/Comp 1N Polarity */
#define TIM_CCER_CC2E BIT(4) /* Capt/Comp 2 out Ena */
#define TIM_CCER_CC3E BIT(8) /* Capt/Comp 3 out Ena */
#define TIM_CCER_CC4E BIT(12) /* Capt/Comp 4 out Ena */
#define TIM_CCER_CCXE (BIT(0) | BIT(4) | BIT(8) | BIT(12))
#define TIM_BDTR_BKE BIT(12) /* Break input enable */
#define TIM_BDTR_BKP BIT(13) /* Break input polarity */
#define TIM_BDTR_AOE BIT(14) /* Automatic Output Enable */
#define TIM_BDTR_MOE BIT(15) /* Main Output Enable */
#define TIM_BDTR_BKF (BIT(16) | BIT(17) | BIT(18) | BIT(19))
#define TIM_BDTR_BK2F (BIT(20) | BIT(21) | BIT(22) | BIT(23))
#define TIM_BDTR_BK2E BIT(24) /* Break 2 input enable */
#define TIM_BDTR_BK2P BIT(25) /* Break 2 input polarity */
#define MAX_TIM_PSC 0xFFFF
#define TIM_CR2_MMS_SHIFT 4
#define TIM_SMCR_TS_SHIFT 4
#define TIM_BDTR_BKF_MASK 0xF
#define TIM_BDTR_BKF_SHIFT 16
#define TIM_BDTR_BK2F_SHIFT 20
struct stm32_timers {
struct clk *clk;
struct regmap *regmap;
u32 max_arr;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment