F: drivers/acpi/
F: drivers/pnp/pnpacpi/
F: include/linux/acpi.h
+F: include/linux/fwnode.h
F: include/acpi/
F: Documentation/acpi/
F: Documentation/ABI/testing/sysfs-bus-acpi
F: drivers/pci/*/*/*acpi*
F: tools/power/acpi/
+ACPI APEI
+F: drivers/acpi/apei/
+
ACPI COMPONENT ARCHITECTURE (ACPICA)
S: Supported
F: drivers/media/i2c/adv7180.c
+ANALOG DEVICES INC ADV748X DRIVER
+S: Maintained
+F: drivers/media/i2c/adv748x/*
+
ANALOG DEVICES INC ADV7511 DRIVER
F: arch/arm/mach-artpec
F: arch/arm/boot/dts/artpec6*
F: drivers/clk/axis
+F: drivers/crypto/axis
F: drivers/pinctrl/pinctrl-artpec*
F: Documentation/devicetree/bindings/pinctrl/axis,artpec6-pinctrl.txt
ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE
T: git git://github.com/ulli-kroll/linux.git
S: Maintained
+F: Documentation/devicetree/bindings/arm/gemini.txt
+F: Documentation/devicetree/bindings/pinctrl/cortina,gemini-pinctrl.txt
+F: Documentation/devicetree/bindings/rtc/faraday,ftrtc010.txt
F: arch/arm/mach-gemini/
+F: drivers/pinctrl/pinctrl-gemini.c
F: drivers/rtc/rtc-ftrtc010.c
ARM/CSR SIRFPRIMA2 MACHINE SUPPORT
S: Maintained
-F: drivers/phy/phy-mt65xx-usb3.c
+F: drivers/phy/mediatek/phy-mtk-tphy.c
ARM/MICREL KS8695 ARCHITECTURE
F: drivers/bus/uniphier-system-bus.c
F: drivers/clk/uniphier/
F: drivers/i2c/busses/i2c-uniphier*
+F: drivers/irqchip/irq-uniphier-aidet.c
F: drivers/pinctrl/uniphier/
F: drivers/reset/reset-uniphier.c
F: drivers/tty/serial/8250/8250_uniphier.c
F: arch/arm64/
F: Documentation/arm64/
+AS3645A LED FLASH CONTROLLER DRIVER
+S: Maintained
+F: drivers/leds/leds-as3645a.c
+
AS3645A LED FLASH CONTROLLER DRIVER
S: Maintained
F: Documentation/ABI/testing/sysfs-class-net-batman-adv
F: Documentation/ABI/testing/sysfs-class-net-mesh
-F: Documentation/networking/batman-adv.txt
+F: Documentation/networking/batman-adv.rst
F: include/uapi/linux/batman_adv.h
F: net/batman-adv/
F: drivers/gpu/drm/qxl/
F: include/uapi/drm/qxl_drm.h
+DRM DRIVER FOR PERVASIVE DISPLAYS REPAPER PANELS
+S: Maintained
+F: drivers/gpu/drm/tinydrm/repaper.c
+F: Documentation/devicetree/bindings/display/repaper.txt
+
DRM DRIVER FOR RAGE 128 VIDEO CARDS
S: Orphan / Obsolete
F: drivers/gpu/drm/r128/
F: drivers/gpu/drm/sis/
F: include/uapi/drm/sis_drm.h
+DRM DRIVER FOR SITRONIX ST7586 PANELS
+S: Maintained
+F: drivers/gpu/drm/tinydrm/st7586.c
+F: Documentation/devicetree/bindings/display/st7586.txt
+
DRM DRIVER FOR TDFX VIDEO CARDS
S: Orphan / Obsolete
F: drivers/gpu/drm/tdfx/
F: include/drm/drm_panel.h
F: Documentation/devicetree/bindings/display/panel/
+DRM TINYDRM DRIVERS
+W: https://github.com/notro/tinydrm/wiki/Development
+T: git git://anongit.freedesktop.org/drm/drm-misc
+S: Maintained
+F: drivers/gpu/drm/tinydrm/
+F: include/drm/tinydrm/
+
DSBR100 USB FM RADIO DRIVER
F: include/linux/phy.h
F: include/linux/phy_fixed.h
F: include/linux/platform_data/mdio-gpio.h
+F: include/linux/platform_data/mdio-bcm-unimac.h
F: include/trace/events/mdio.h
F: include/uapi/linux/mdio.h
F: include/uapi/linux/mii.h
FPGA MANAGER FRAMEWORK
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
+Q: http://patchwork.kernel.org/project/linux-fpga/list/
F: Documentation/fpga/
F: Documentation/devicetree/bindings/fpga/
F: drivers/fpga/
F: Documentation/acpi/gpio-properties.txt
F: drivers/gpio/gpiolib-acpi.c
+GPIO IR Transmitter
+S: Maintained
+F: drivers/media/rc/gpio-ir-tx.c
+
GPIO MOCKUP DRIVER
F: drivers/net/ethernet/hisilicon/
F: Documentation/devicetree/bindings/net/hisilicon*.txt
+HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3)
+W: http://www.hisilicon.com
+S: Maintained
+F: drivers/net/ethernet/hisilicon/hns3/
+
HISILICON ROCE DRIVER
S: Maintained
F: drivers/input/touchscreen/htcpen.c
+HUAWEI ETHERNET DRIVER
+S: Supported
+F: Documentation/networking/hinic.txt
+F: drivers/net/ethernet/huawei/hinic/
+
HUGETLB FILESYSTEM
S: Maintained
S: Maintained
+F: Documentation/networking/netvsc.txt
F: arch/x86/include/asm/mshyperv.h
+F: arch/x86/include/asm/trace/hyperv.h
F: arch/x86/include/uapi/asm/hyperv.h
F: arch/x86/kernel/cpu/mshyperv.c
F: arch/x86/hyperv
F: drivers/scsi/storvsc_drv.c
F: drivers/uio/uio_hv_generic.c
F: drivers/video/fbdev/hyperv_fb.c
+F: net/vmw_vsock/hyperv_transport.c
F: include/linux/hyperv.h
+F: include/uapi/linux/hyperv.h
F: tools/hv/
F: Documentation/ABI/stable/sysfs-bus-vmbus
S: Supported
F: drivers/net/ethernet/ibm/ibmvnic.*
+IBM Power Virtual Accelerator Switchboard
+M: Sukadev Bhattiprolu
+S: Supported
+F: arch/powerpc/platforms/powernv/vas*
+F: arch/powerpc/platforms/powernv/copy-paste.h
+F: arch/powerpc/include/asm/vas.h
+F: arch/powerpc/include/uapi/asm/vas.h
+
IBM Power Virtual Ethernet Device Driver
F: drivers/scsi/isci/
INTEL DRM DRIVERS (excluding Poulsbo, Moorestown and derivative chipsets)
W: https://01.org/linuxgraphics/
B: https://01.org/linuxgraphics/documentation/how-report-bugs
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git
F: Documentation/networking/irda.txt
-F: drivers/net/irda/
-F: include/net/irda/
-F: net/irda/
+F: drivers/staging/irda/
IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
S: Maintained
F: drivers/media/dvb-frontends/lgdt3305.*
-LGUEST
-W: http://lguest.ozlabs.org/
-S: Odd Fixes
-F: arch/x86/include/asm/lguest*.h
-F: arch/x86/lguest/
-F: drivers/lguest/
-F: include/linux/lguest*.h
-F: tools/lguest/
-
LIBATA PATA ARASAN COMPACT FLASH CONTROLLER
F: drivers/rtc/rtc-opal.c
F: drivers/scsi/ibmvscsi/
F: drivers/tty/hvc/hvc_opal.c
+F: drivers/watchdog/wdrtas.c
F: tools/testing/selftests/powerpc
N: /pmac
N: powermac
S: Supported
F: drivers/media/dvb-frontends/lnbh25*
+MEDIA DRIVERS FOR MXL5XX TUNER DEMODULATORS
+W: https://linuxtv.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/mxl5xx*
+
MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices
F: Documentation/devicetree/bindings/media/renesas,vsp1.txt
F: drivers/media/platform/vsp1/
+MEDIA DRIVERS FOR ST STV0910 DEMODULATOR ICs
+W: https://linuxtv.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/stv0910*
+
+MEDIA DRIVERS FOR ST STV6111 TUNER ICs
+W: https://linuxtv.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/dvb-frontends/stv6111*
+
+MEDIA DRIVERS FOR DIGITAL DEVICES PCIE DEVICES
+W: https://linuxtv.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: drivers/media/pci/ddbridge/*
+
MEDIA INPUT INFRASTRUCTURE (V4L/DVB)
MEDIATEK ETHERNET DRIVER
S: Maintained
F: drivers/net/ethernet/mediatek/
S: Maintained
F: drivers/net/wireless/mediatek/mt7601u/
+MEDIATEK CIR DRIVER
+S: Maintained
+F: drivers/media/rc/mtk-cir.c
+
MEDIATEK RANDOM NUMBER GENERATOR SUPPORT
S: Maintained
F: drivers/char/hw_random/mtk-rng.c
+MEDIATEK USB3 DRD IP DRIVER
+S: Maintained
+F: drivers/usb/mtu3/
+
MEGACHIPS STDPXXXX-GE-B850V3-FW LVDS/DP++ BRIDGES
S: Supported
-F: kernel/membarrier.c
+F: kernel/sched/membarrier.c
F: include/uapi/linux/membarrier.h
MEMORY MANAGEMENT
F: drivers/hwmon/menf21bmc_hwmon.c
F: Documentation/hwmon/menf21bmc
+MESON AO CEC DRIVER FOR AMLOGIC SOCS
+W: http://linux-meson.com/
+S: Supported
+F: drivers/media/platform/meson/ao-cec.c
+F: Documentation/devicetree/bindings/media/meson-ao-cec.txt
+T: git git://linuxtv.org/media_tree.git
+
METAG ARCHITECTURE
F: drivers/dma/at_hdmac_regs.h
F: include/linux/platform_data/dma-atmel.h
+MICROCHIP / ATMEL ECC DRIVER
+S: Maintained
+F: drivers/crypto/atmel-ecc.*
+
MICROCHIP / ATMEL ISC DRIVER
S: Maintained
F: drivers/nvmem/
F: Documentation/devicetree/bindings/nvmem/
+F: Documentation/ABI/stable/sysfs-bus-nvmem
F: include/linux/nvmem-consumer.h
F: include/linux/nvmem-provider.h
F: drivers/media/i2c/ov5640.c
OMNIVISION OV5647 SENSOR DRIVER
-M: Ramiro Oliveira <roliveir@synopsys.com>
+M: Luis Oliveira <lolivei@synopsys.com>
T: git git://linuxtv.org/media_tree.git
S: Maintained
T: git git://linuxtv.org/media_tree.git
S: Maintained
F: drivers/media/usb/pulse8-cec/*
+F: Documentation/media/cec-drivers/pulse8-cec.rst
PVRUSB2 VIDEO4LINUX DRIVER
F: Documentation/hwmon/pwm-fan
F: drivers/hwmon/pwm-fan.c
+PWM IR Transmitter
+S: Maintained
+F: drivers/media/rc/pwm-ir-tx.c
+
PWM SUBSYSTEM
S: Supported
F: drivers/net/wireless/ath/ath9k/
+QUALCOMM CAMERA SUBSYSTEM DRIVER
+S: Maintained
+F: Documentation/devicetree/bindings/media/qcom,camss.txt
+F: Documentation/media/v4l-drivers/qcom_camss.rst
+F: drivers/media/platform/qcom/camss-8x16/
+
QUALCOMM EMAC GIGABIT ETHERNET DRIVER
S: Supported
F: arch/x86/kernel/cpu/intel_rdt*
-F: arch/x86/include/asm/intel_rdt*
+F: arch/x86/include/asm/intel_rdt_sched.h
F: Documentation/x86/intel_rdt*
READ-COPY UPDATE (RCU)
S: Odd Fixes
F: drivers/tty/serial/rp2.*
+ ROHM MULTIFUNCTION BD9571MWV-M PMIC DEVICE DRIVERS
+ S: Supported
+ F: drivers/mfd/bd9571mwv.c
+ F: drivers/regulator/bd9571mwv-regulator.c
+ F: drivers/gpio/gpio-bd9571mwv.c
+ F: include/linux/mfd/bd9571mwv.h
+ F: Documentation/devicetree/bindings/mfd/bd9571mwv.txt
+
ROSE NETWORK LAYER
S: Odd Fixes
F: drivers/net/ethernet/adaptec/starfire*
+STEC S1220 SKD DRIVER
+S: Maintained
+F: drivers/block/skd*[ch]
+
STI CEC DRIVER
S: Maintained
S: Maintained
F: drivers/thunderbolt/
+THUNDERX GPIO DRIVER
+S: Maintained
+F: drivers/gpio/gpio-thunderx.c
+
TI AM437X VPFE DRIVER
#include <linux/dmaengine.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
+ #include <linux/iio/timer/stm32-lptim-trigger.h>
#include <linux/iio/timer/stm32-timer-trigger.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#define STM32H7_ADC_IER 0x04
#define STM32H7_ADC_CR 0x08
#define STM32H7_ADC_CFGR 0x0C
+#define STM32H7_ADC_SMPR1 0x14
+#define STM32H7_ADC_SMPR2 0x18
#define STM32H7_ADC_PCSEL 0x1C
#define STM32H7_ADC_SQR1 0x30
#define STM32H7_ADC_SQR2 0x34
#define STM32H7_BOOST_CLKRATE 20000000UL
#define STM32_ADC_MAX_SQ 16 /* SQ1..SQ16 */
+#define STM32_ADC_MAX_SMP 7 /* SMPx range is [0..7] */
#define STM32_ADC_TIMEOUT_US 100000
#define STM32_ADC_TIMEOUT (msecs_to_jiffies(STM32_ADC_TIMEOUT_US / 1000))
STM32_EXT13,
STM32_EXT14,
STM32_EXT15,
+ STM32_EXT16,
+ STM32_EXT17,
+ STM32_EXT18,
+ STM32_EXT19,
+ STM32_EXT20,
};
/**
* @exten: trigger control register & bitfield
* @extsel: trigger selection register & bitfield
* @res: resolution selection register & bitfield
+ * @smpr: smpr1 & smpr2 registers offset array
+ * @smp_bits: smpr1 & smpr2 index and bitfields
*/
struct stm32_adc_regspec {
const u32 dr;
const struct stm32_adc_regs exten;
const struct stm32_adc_regs extsel;
const struct stm32_adc_regs res;
+ const u32 smpr[2];
+ const struct stm32_adc_regs *smp_bits;
};
struct stm32_adc;
* @start_conv: routine to start conversions
* @stop_conv: routine to stop conversions
* @unprepare: optional unprepare routine (disable, power-down)
+ * @smp_cycles: programmable sampling time (ADC clock cycles)
*/
struct stm32_adc_cfg {
const struct stm32_adc_regspec *regs;
void (*start_conv)(struct stm32_adc *, bool dma);
void (*stop_conv)(struct stm32_adc *);
void (*unprepare)(struct stm32_adc *);
+ const unsigned int *smp_cycles;
};
/**
* @rx_dma_buf: dma rx buffer bus address
* @rx_buf_sz: dma rx buffer size
* @pcsel bitmask to preselect channels on some devices
+ * @smpr_val: sampling time settings (e.g. smpr1 / smpr2)
* @cal: optional calibration data on some devices
*/
struct stm32_adc {
dma_addr_t rx_dma_buf;
unsigned int rx_buf_sz;
u32 pcsel;
+ u32 smpr_val[2];
struct stm32_adc_calib cal;
};
{}, /* sentinel */
};
+/**
+ * stm32f4_smp_bits[] - describe sampling time register index & bit fields
+ * Sorted so it can be indexed by channel number.
+ */
+static const struct stm32_adc_regs stm32f4_smp_bits[] = {
+ /* STM32F4_ADC_SMPR2: smpr[] index, mask, shift for SMP0 to SMP9 */
+ { 1, GENMASK(2, 0), 0 },
+ { 1, GENMASK(5, 3), 3 },
+ { 1, GENMASK(8, 6), 6 },
+ { 1, GENMASK(11, 9), 9 },
+ { 1, GENMASK(14, 12), 12 },
+ { 1, GENMASK(17, 15), 15 },
+ { 1, GENMASK(20, 18), 18 },
+ { 1, GENMASK(23, 21), 21 },
+ { 1, GENMASK(26, 24), 24 },
+ { 1, GENMASK(29, 27), 27 },
+ /* STM32F4_ADC_SMPR1, smpr[] index, mask, shift for SMP10 to SMP18 */
+ { 0, GENMASK(2, 0), 0 },
+ { 0, GENMASK(5, 3), 3 },
+ { 0, GENMASK(8, 6), 6 },
+ { 0, GENMASK(11, 9), 9 },
+ { 0, GENMASK(14, 12), 12 },
+ { 0, GENMASK(17, 15), 15 },
+ { 0, GENMASK(20, 18), 18 },
+ { 0, GENMASK(23, 21), 21 },
+ { 0, GENMASK(26, 24), 24 },
+};
+
+/* STM32F4 programmable sampling time (ADC clock cycles) */
+static const unsigned int stm32f4_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = {
+ 3, 15, 28, 56, 84, 112, 144, 480,
+};
+
static const struct stm32_adc_regspec stm32f4_adc_regspec = {
.dr = STM32F4_ADC_DR,
.ier_eoc = { STM32F4_ADC_CR1, STM32F4_EOCIE },
.extsel = { STM32F4_ADC_CR2, STM32F4_EXTSEL_MASK,
STM32F4_EXTSEL_SHIFT },
.res = { STM32F4_ADC_CR1, STM32F4_RES_MASK, STM32F4_RES_SHIFT },
+ .smpr = { STM32F4_ADC_SMPR1, STM32F4_ADC_SMPR2 },
+ .smp_bits = stm32f4_smp_bits,
};
static const struct stm32_adc_regs stm32h7_sq[STM32_ADC_MAX_SQ + 1] = {
{ TIM4_TRGO, STM32_EXT12 },
{ TIM6_TRGO, STM32_EXT13 },
{ TIM3_CH4, STM32_EXT15 },
+ { LPTIM1_OUT, STM32_EXT18 },
+ { LPTIM2_OUT, STM32_EXT19 },
+ { LPTIM3_OUT, STM32_EXT20 },
{},
};
+/**
+ * stm32h7_smp_bits - describe sampling time register index & bit fields
+ * Sorted so it can be indexed by channel number.
+ */
+static const struct stm32_adc_regs stm32h7_smp_bits[] = {
+ /* STM32H7_ADC_SMPR1, smpr[] index, mask, shift for SMP0 to SMP9 */
+ { 0, GENMASK(2, 0), 0 },
+ { 0, GENMASK(5, 3), 3 },
+ { 0, GENMASK(8, 6), 6 },
+ { 0, GENMASK(11, 9), 9 },
+ { 0, GENMASK(14, 12), 12 },
+ { 0, GENMASK(17, 15), 15 },
+ { 0, GENMASK(20, 18), 18 },
+ { 0, GENMASK(23, 21), 21 },
+ { 0, GENMASK(26, 24), 24 },
+ { 0, GENMASK(29, 27), 27 },
+ /* STM32H7_ADC_SMPR2, smpr[] index, mask, shift for SMP10 to SMP19 */
+ { 1, GENMASK(2, 0), 0 },
+ { 1, GENMASK(5, 3), 3 },
+ { 1, GENMASK(8, 6), 6 },
+ { 1, GENMASK(11, 9), 9 },
+ { 1, GENMASK(14, 12), 12 },
+ { 1, GENMASK(17, 15), 15 },
+ { 1, GENMASK(20, 18), 18 },
+ { 1, GENMASK(23, 21), 21 },
+ { 1, GENMASK(26, 24), 24 },
+ { 1, GENMASK(29, 27), 27 },
+};
+
+/* STM32H7 programmable sampling time (ADC clock cycles, rounded down) */
+static const unsigned int stm32h7_adc_smp_cycles[STM32_ADC_MAX_SMP + 1] = {
+ 1, 2, 8, 16, 32, 64, 387, 810,
+};
+
static const struct stm32_adc_regspec stm32h7_adc_regspec = {
.dr = STM32H7_ADC_DR,
.ier_eoc = { STM32H7_ADC_IER, STM32H7_EOCIE },
.extsel = { STM32H7_ADC_CFGR, STM32H7_EXTSEL_MASK,
STM32H7_EXTSEL_SHIFT },
.res = { STM32H7_ADC_CFGR, STM32H7_RES_MASK, STM32H7_RES_SHIFT },
+ .smpr = { STM32H7_ADC_SMPR1, STM32H7_ADC_SMPR2 },
+ .smp_bits = stm32h7_smp_bits,
};
/**
* @scan_mask: channels to be converted
*
* Conversion sequence :
+ * Apply sampling time settings for all channels.
* 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.
u32 val, bit;
int i = 0;
+ /* Apply sampling time settings */
+ stm32_adc_writel(adc, adc->cfg->regs->smpr[0], adc->smpr_val[0]);
+ stm32_adc_writel(adc, adc->cfg->regs->smpr[1], adc->smpr_val[1]);
+
for_each_set_bit(bit, scan_mask, indio_dev->masklength) {
chan = indio_dev->channels + bit;
/*
* Checking both stm32 timer trigger type and trig name
* should be safe against arbitrary trigger names.
*/
- if (is_stm32_timer_trigger(trig) &&
+ if ((is_stm32_timer_trigger(trig) ||
+ is_stm32_lptim_trigger(trig)) &&
!strcmp(adc->cfg->trigs[i].name, trig->name)) {
return adc->cfg->trigs[i].extsel;
}
* @res: conversion result
*
* The function performs a single conversion on a given channel:
+ * - Apply sampling time settings
* - Program sequencer with one channel (e.g. in SQ1 with len = 1)
* - Use SW trigger
* - Start conversion, then wait for interrupt completion.
return ret;
}
+ /* Apply sampling time settings */
+ stm32_adc_writel(adc, regs->smpr[0], adc->smpr_val[0]);
+ stm32_adc_writel(adc, regs->smpr[1], adc->smpr_val[1]);
+
/* Program chan number in regular sequence (SQ1) */
val = stm32_adc_readl(adc, regs->sqr[1].reg);
val &= ~regs->sqr[1].mask;
return 0;
}
+static void stm32_adc_smpr_init(struct stm32_adc *adc, int channel, u32 smp_ns)
+{
+ const struct stm32_adc_regs *smpr = &adc->cfg->regs->smp_bits[channel];
+ u32 period_ns, shift = smpr->shift, mask = smpr->mask;
+ unsigned int smp, r = smpr->reg;
+
+ /* Determine sampling time (ADC clock cycles) */
+ period_ns = NSEC_PER_SEC / adc->common->rate;
+ for (smp = 0; smp <= STM32_ADC_MAX_SMP; smp++)
+ if ((period_ns * adc->cfg->smp_cycles[smp]) >= smp_ns)
+ break;
+ if (smp > STM32_ADC_MAX_SMP)
+ smp = STM32_ADC_MAX_SMP;
+
+ /* pre-build sampling time registers (e.g. smpr1, smpr2) */
+ adc->smpr_val[r] = (adc->smpr_val[r] & ~mask) | (smp << shift);
+}
+
static void stm32_adc_chan_init_one(struct iio_dev *indio_dev,
struct iio_chan_spec *chan,
const struct stm32_adc_chan_spec *channel,
- int scan_index)
+ int scan_index, u32 smp)
{
struct stm32_adc *adc = iio_priv(indio_dev);
chan->scan_type.storagebits = 16;
chan->ext_info = stm32_adc_ext_info;
+ /* Prepare sampling time settings */
+ stm32_adc_smpr_init(adc, chan->channel, smp);
+
/* pre-build selected channels mask */
adc->pcsel |= BIT(chan->channel);
}
struct property *prop;
const __be32 *cur;
struct iio_chan_spec *channels;
- int scan_index = 0, num_channels;
- u32 val;
+ int scan_index = 0, num_channels, ret;
+ u32 val, smp = 0;
num_channels = of_property_count_u32_elems(node, "st,adc-channels");
if (num_channels < 0 ||
return num_channels < 0 ? num_channels : -EINVAL;
}
+ /* Optional sample time is provided either for each, or all channels */
+ ret = of_property_count_u32_elems(node, "st,min-sample-time-nsecs");
+ if (ret > 1 && ret != num_channels) {
+ dev_err(&indio_dev->dev, "Invalid st,min-sample-time-nsecs\n");
+ return -EINVAL;
+ }
+
channels = devm_kcalloc(&indio_dev->dev, num_channels,
sizeof(struct iio_chan_spec), GFP_KERNEL);
if (!channels)
dev_err(&indio_dev->dev, "Invalid channel %d\n", val);
return -EINVAL;
}
+
+ /*
+ * Using of_property_read_u32_index(), smp value will only be
+ * modified if valid u32 value can be decoded. This allows to
+ * get either no value, 1 shared value for all indexes, or one
+ * value per channel.
+ */
+ of_property_read_u32_index(node, "st,min-sample-time-nsecs",
+ scan_index, &smp);
+
stm32_adc_chan_init_one(indio_dev, &channels[scan_index],
&adc_info->channels[val],
- scan_index);
+ scan_index, smp);
scan_index++;
}
indio_dev->dev.parent = &pdev->dev;
indio_dev->dev.of_node = pdev->dev.of_node;
indio_dev->info = &stm32_adc_iio_info;
- indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->modes = INDIO_DIRECT_MODE | INDIO_HARDWARE_TRIGGERED;
platform_set_drvdata(pdev, adc);
.clk_required = true,
.start_conv = stm32f4_adc_start_conv,
.stop_conv = stm32f4_adc_stop_conv,
+ .smp_cycles = stm32f4_adc_smp_cycles,
};
static const struct stm32_adc_cfg stm32h7_adc_cfg = {
.stop_conv = stm32h7_adc_stop_conv,
.prepare = stm32h7_adc_prepare,
.unprepare = stm32h7_adc_unprepare,
+ .smp_cycles = stm32h7_adc_smp_cycles,
};
static const struct of_device_id stm32_adc_of_match[] = {