Hi On Mon, Aug 29, 2022 at 8:20 AM Balamanikandan Gunasundar <balamanikandan.gunasun...@microchip.com> wrote: > > Add driver for atmel Static Memory Controller. Add helper functions to > configure SMC. This file is inherited from the work done by Boris > Brezillon for Linux >
This does not look like a driver.Those are helper functions. Now I have no objections to put it here but it will be the first one under mfd. I think linux commit message subject give more an idea on what exactly it is mfd: syscon: atmel-smc: Add new helpers to ease SMC regs manipulation Michael > Signed-off-by: Balamanikandan Gunasundar > <balamanikandan.gunasun...@microchip.com> > --- > drivers/Kconfig | 2 + > drivers/Makefile | 1 + > drivers/mfd/Kconfig | 4 + > drivers/mfd/Makefile | 1 + > drivers/mfd/atmel-smc.c | 364 +++++++++++++++++++++++++++ > include/linux/mfd/syscon/atmel-smc.h | 119 +++++++++ > 6 files changed, 491 insertions(+) > create mode 100644 drivers/mfd/Kconfig > create mode 100644 drivers/mfd/Makefile > create mode 100644 drivers/mfd/atmel-smc.c > create mode 100644 include/linux/mfd/syscon/atmel-smc.h > > diff --git a/drivers/Kconfig b/drivers/Kconfig > index 8b6fead351..ffc06ed65e 100644 > --- a/drivers/Kconfig > +++ b/drivers/Kconfig > @@ -60,6 +60,8 @@ source "drivers/mailbox/Kconfig" > > source "drivers/memory/Kconfig" > > +source "drivers/mfd/Kconfig" > + > source "drivers/misc/Kconfig" > > source "drivers/mmc/Kconfig" > diff --git a/drivers/Makefile b/drivers/Makefile > index eba9940231..5a8e80d4fe 100644 > --- a/drivers/Makefile > +++ b/drivers/Makefile > @@ -101,6 +101,7 @@ obj-$(CONFIG_QE) += qe/ > obj-$(CONFIG_U_QE) += qe/ > obj-y += mailbox/ > obj-y += memory/ > +obj-y += mfd/ > obj-y += mtd/ > obj-y += pwm/ > obj-y += reset/ > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > new file mode 100644 > index 0000000000..ae53b02f27 > --- /dev/null > +++ b/drivers/mfd/Kconfig > @@ -0,0 +1,4 @@ > +config MFD_ATMEL_SMC > + bool "Atmel Static Memory Controller driver" > + help > + Say yes here to support Atmel Static Memory Controller driver. > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > new file mode 100644 > index 0000000000..4454815a98 > --- /dev/null > +++ b/drivers/mfd/Makefile > @@ -0,0 +1 @@ > +obj-$(CONFIG_MFD_ATMEL_SMC) += atmel-smc.o > diff --git a/drivers/mfd/atmel-smc.c b/drivers/mfd/atmel-smc.c > new file mode 100644 > index 0000000000..15296f71a1 > --- /dev/null > +++ b/drivers/mfd/atmel-smc.c > @@ -0,0 +1,364 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* > + * Atmel SMC (Static Memory Controller) helper functions. > + * > + * Copyright (C) 2022 Microchip Technology Inc. > + * Copyright (C) 2017 Free Electrons > + * > + * Author: Boris Brezillon <boris.brezil...@free-electrons.com> > + */ > + > +#include <clk.h> > +#include <dm/device.h> > +#include <linux/err.h> > +#include <linux/errno.h> > +#include <linux/mfd/syscon/atmel-smc.h> > +#include <linux/string.h> > + > +/** > + * atmel_smc_cs_conf_init - initialize a SMC CS conf > + * @conf: the SMC CS conf to initialize > + * > + * Set all fields to 0 so that one can start defining a new config. > + */ > +void atmel_smc_cs_conf_init(struct atmel_smc_cs_conf *conf) > +{ > + memset(conf, 0, sizeof(*conf)); > +} > +EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_init); > + > +/** > + * atmel_smc_cs_encode_ncycles - encode a number of MCK clk cycles in the > + * format expected by the SMC engine > + * @ncycles: number of MCK clk cycles > + * @msbpos: position of the MSB part of the timing field > + * @msbwidth: width of the MSB part of the timing field > + * @msbfactor: factor applied to the MSB > + * @encodedval: param used to store the encoding result > + * > + * This function encodes the @ncycles value as described in the datasheet > + * (section "SMC Setup/Pulse/Cycle/Timings Register"). This is a generic > + * helper which called with different parameter depending on the encoding > + * scheme. > + * > + * If the @ncycles value is too big to be encoded, -ERANGE is returned and > + * the encodedval is contains the maximum val. Otherwise, 0 is returned. > + */ > +static int atmel_smc_cs_encode_ncycles(unsigned int ncycles, > + unsigned int msbpos, > + unsigned int msbwidth, > + unsigned int msbfactor, > + unsigned int *encodedval) > +{ > + unsigned int lsbmask = GENMASK(msbpos - 1, 0); > + unsigned int msbmask = GENMASK(msbwidth - 1, 0); > + unsigned int msb, lsb; > + int ret = 0; > + > + msb = ncycles / msbfactor; > + lsb = ncycles % msbfactor; > + > + if (lsb > lsbmask) { > + lsb = 0; > + msb++; > + } > + > + /* > + * Let's just put the maximum we can if the requested setting does > + * not fit in the register field. > + * We still return -ERANGE in case the caller cares. > + */ > + if (msb > msbmask) { > + msb = msbmask; > + lsb = lsbmask; > + ret = -ERANGE; > + } > + > + *encodedval = (msb << msbpos) | lsb; > + > + return ret; > +} > + > +/** > + * atmel_smc_cs_conf_set_timing - set the SMC CS conf Txx parameter to a > + * specific value > + * @conf: SMC CS conf descriptor > + * @shift: the position of the Txx field in the TIMINGS register > + * @ncycles: value (expressed in MCK clk cycles) to assign to this Txx > + * parameter > + * > + * This function encodes the @ncycles value as described in the datasheet > + * (section "SMC Timings Register"), and then stores the result in the > + * @conf->timings field at @shift position. > + * > + * Returns -EINVAL if shift is invalid, -ERANGE if ncycles does not fit in > + * the field, and 0 otherwise. > + */ > +int atmel_smc_cs_conf_set_timing(struct atmel_smc_cs_conf *conf, > + unsigned int shift, unsigned int ncycles) > +{ > + unsigned int val; > + int ret; > + > + if (shift != ATMEL_HSMC_TIMINGS_TCLR_SHIFT && > + shift != ATMEL_HSMC_TIMINGS_TADL_SHIFT && > + shift != ATMEL_HSMC_TIMINGS_TAR_SHIFT && > + shift != ATMEL_HSMC_TIMINGS_TRR_SHIFT && > + shift != ATMEL_HSMC_TIMINGS_TWB_SHIFT) > + return -EINVAL; > + > + /* > + * The formula described in atmel datasheets (section "HSMC Timings > + * Register"): > + * > + * ncycles = (Txx[3] * 64) + Txx[2:0] > + */ > + ret = atmel_smc_cs_encode_ncycles(ncycles, 3, 1, 64, &val); > + conf->timings &= ~GENMASK(shift + 3, shift); > + conf->timings |= val << shift; > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_set_timing); > + > +/** > + * atmel_smc_cs_conf_set_setup - set the SMC CS conf xx_SETUP parameter to a > + * specific value > + * @conf: SMC CS conf descriptor > + * @shift: the position of the xx_SETUP field in the SETUP register > + * @ncycles: value (expressed in MCK clk cycles) to assign to this xx_SETUP > + * parameter > + * > + * This function encodes the @ncycles value as described in the datasheet > + * (section "SMC Setup Register"), and then stores the result in the > + * @conf->setup field at @shift position. > + * > + * Returns -EINVAL if @shift is invalid, -ERANGE if @ncycles does not fit in > + * the field, and 0 otherwise. > + */ > +int atmel_smc_cs_conf_set_setup(struct atmel_smc_cs_conf *conf, > + unsigned int shift, unsigned int ncycles) > +{ > + unsigned int val; > + int ret; > + > + if (shift != ATMEL_SMC_NWE_SHIFT && shift != ATMEL_SMC_NCS_WR_SHIFT && > + shift != ATMEL_SMC_NRD_SHIFT && shift != ATMEL_SMC_NCS_RD_SHIFT) > + return -EINVAL; > + > + /* > + * The formula described in atmel datasheets (section "SMC Setup > + * Register"): > + * > + * ncycles = (128 * xx_SETUP[5]) + xx_SETUP[4:0] > + */ > + ret = atmel_smc_cs_encode_ncycles(ncycles, 5, 1, 128, &val); > + conf->setup &= ~GENMASK(shift + 7, shift); > + conf->setup |= val << shift; > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_set_setup); > + > +/** > + * atmel_smc_cs_conf_set_pulse - set the SMC CS conf xx_PULSE parameter to a > + * specific value > + * @conf: SMC CS conf descriptor > + * @shift: the position of the xx_PULSE field in the PULSE register > + * @ncycles: value (expressed in MCK clk cycles) to assign to this xx_PULSE > + * parameter > + * > + * This function encodes the @ncycles value as described in the datasheet > + * (section "SMC Pulse Register"), and then stores the result in the > + * @conf->setup field at @shift position. > + * > + * Returns -EINVAL if @shift is invalid, -ERANGE if @ncycles does not fit in > + * the field, and 0 otherwise. > + */ > +int atmel_smc_cs_conf_set_pulse(struct atmel_smc_cs_conf *conf, > + unsigned int shift, unsigned int ncycles) > +{ > + unsigned int val; > + int ret; > + > + if (shift != ATMEL_SMC_NWE_SHIFT && shift != ATMEL_SMC_NCS_WR_SHIFT && > + shift != ATMEL_SMC_NRD_SHIFT && shift != ATMEL_SMC_NCS_RD_SHIFT) > + return -EINVAL; > + > + /* > + * The formula described in atmel datasheets (section "SMC Pulse > + * Register"): > + * > + * ncycles = (256 * xx_PULSE[6]) + xx_PULSE[5:0] > + */ > + ret = atmel_smc_cs_encode_ncycles(ncycles, 6, 1, 256, &val); > + conf->pulse &= ~GENMASK(shift + 7, shift); > + conf->pulse |= val << shift; > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_set_pulse); > + > +/** > + * atmel_smc_cs_conf_set_cycle - set the SMC CS conf xx_CYCLE parameter to a > + * specific value > + * @conf: SMC CS conf descriptor > + * @shift: the position of the xx_CYCLE field in the CYCLE register > + * @ncycles: value (expressed in MCK clk cycles) to assign to this xx_CYCLE > + * parameter > + * > + * This function encodes the @ncycles value as described in the datasheet > + * (section "SMC Cycle Register"), and then stores the result in the > + * @conf->setup field at @shift position. > + * > + * Returns -EINVAL if @shift is invalid, -ERANGE if @ncycles does not fit in > + * the field, and 0 otherwise. > + */ > +int atmel_smc_cs_conf_set_cycle(struct atmel_smc_cs_conf *conf, > + unsigned int shift, unsigned int ncycles) > +{ > + unsigned int val; > + int ret; > + > + if (shift != ATMEL_SMC_NWE_SHIFT && shift != ATMEL_SMC_NRD_SHIFT) > + return -EINVAL; > + > + /* > + * The formula described in atmel datasheets (section "SMC Cycle > + * Register"): > + * > + * ncycles = (xx_CYCLE[8:7] * 256) + xx_CYCLE[6:0] > + */ > + ret = atmel_smc_cs_encode_ncycles(ncycles, 7, 2, 256, &val); > + conf->cycle &= ~GENMASK(shift + 15, shift); > + conf->cycle |= val << shift; > + > + return ret; > +} > +EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_set_cycle); > + > +/** > + * atmel_smc_cs_conf_apply - apply an SMC CS conf > + * @regmap: the SMC regmap > + * @cs: the CS id > + * @conf: the SMC CS conf to apply > + * > + * Applies an SMC CS configuration. > + * Only valid on at91sam9/avr32 SoCs. > + */ > +void atmel_smc_cs_conf_apply(struct regmap *regmap, int cs, > + const struct atmel_smc_cs_conf *conf) > +{ > + regmap_write(regmap, ATMEL_SMC_SETUP(cs), conf->setup); > + regmap_write(regmap, ATMEL_SMC_PULSE(cs), conf->pulse); > + regmap_write(regmap, ATMEL_SMC_CYCLE(cs), conf->cycle); > + regmap_write(regmap, ATMEL_SMC_MODE(cs), conf->mode); > +} > +EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_apply); > + > +/** > + * atmel_hsmc_cs_conf_apply - apply an SMC CS conf > + * @regmap: the HSMC regmap > + * @cs: the CS id > + * @layout: the layout of registers > + * @conf: the SMC CS conf to apply > + * > + * Applies an SMC CS configuration. > + * Only valid on post-sama5 SoCs. > + */ > +void atmel_hsmc_cs_conf_apply(struct regmap *regmap, > + const struct atmel_hsmc_reg_layout *layout, > + int cs, const struct atmel_smc_cs_conf *conf) > +{ > + regmap_write(regmap, ATMEL_HSMC_SETUP(layout, cs), conf->setup); > + regmap_write(regmap, ATMEL_HSMC_PULSE(layout, cs), conf->pulse); > + regmap_write(regmap, ATMEL_HSMC_CYCLE(layout, cs), conf->cycle); > + regmap_write(regmap, ATMEL_HSMC_TIMINGS(layout, cs), conf->timings); > + regmap_write(regmap, ATMEL_HSMC_MODE(layout, cs), conf->mode); > +} > +EXPORT_SYMBOL_GPL(atmel_hsmc_cs_conf_apply); > + > +/** > + * atmel_smc_cs_conf_get - retrieve the current SMC CS conf > + * @regmap: the SMC regmap > + * @cs: the CS id > + * @conf: the SMC CS conf object to store the current conf > + * > + * Retrieve the SMC CS configuration. > + * Only valid on at91sam9/avr32 SoCs. > + */ > +void atmel_smc_cs_conf_get(struct regmap *regmap, int cs, > + struct atmel_smc_cs_conf *conf) > +{ > + regmap_read(regmap, ATMEL_SMC_SETUP(cs), &conf->setup); > + regmap_read(regmap, ATMEL_SMC_PULSE(cs), &conf->pulse); > + regmap_read(regmap, ATMEL_SMC_CYCLE(cs), &conf->cycle); > + regmap_read(regmap, ATMEL_SMC_MODE(cs), &conf->mode); > +} > +EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_get); > + > +/** > + * atmel_hsmc_cs_conf_get - retrieve the current SMC CS conf > + * @regmap: the HSMC regmap > + * @cs: the CS id > + * @layout: the layout of registers > + * @conf: the SMC CS conf object to store the current conf > + * > + * Retrieve the SMC CS configuration. > + * Only valid on post-sama5 SoCs. > + */ > +void atmel_hsmc_cs_conf_get(struct regmap *regmap, > + const struct atmel_hsmc_reg_layout *layout, > + int cs, struct atmel_smc_cs_conf *conf) > +{ > + regmap_read(regmap, ATMEL_HSMC_SETUP(layout, cs), &conf->setup); > + regmap_read(regmap, ATMEL_HSMC_PULSE(layout, cs), &conf->pulse); > + regmap_read(regmap, ATMEL_HSMC_CYCLE(layout, cs), &conf->cycle); > + regmap_read(regmap, ATMEL_HSMC_TIMINGS(layout, cs), &conf->timings); > + regmap_read(regmap, ATMEL_HSMC_MODE(layout, cs), &conf->mode); > +} > +EXPORT_SYMBOL_GPL(atmel_hsmc_cs_conf_get); > + > +static const struct atmel_hsmc_reg_layout sama5d3_reg_layout = { > + .timing_regs_offset = 0x600, > +}; > + > +static const struct atmel_hsmc_reg_layout sama5d2_reg_layout = { > + .timing_regs_offset = 0x700, > +}; > + > +static const struct udevice_id atmel_smc_ids[] = { > + { .compatible = "atmel,at91sam9260-smc", .data = (ulong)0 }, > + { .compatible = "atmel,sama5d3-smc", .data = > (ulong)&sama5d3_reg_layout }, > + { .compatible = "atmel,sama5d2-smc", .data = > (ulong)&sama5d2_reg_layout }, > + { /* sentinel */ }, > +}; > + > +/** > + * atmel_hsmc_get_reg_layout - retrieve the layout of HSMC registers > + * @np: the HSMC regmap > + * > + * Retrieve the layout of HSMC registers. > + * > + * Returns NULL in case of SMC, a struct atmel_hsmc_reg_layout pointer > + * in HSMC case, otherwise ERR_PTR(-EINVAL). > + */ > +const struct atmel_hsmc_reg_layout * > +atmel_hsmc_get_reg_layout(ofnode np) > +{ > + int i; > + const struct udevice_id *match; > + const char *name; > + int len; > + > + name = ofnode_get_property(np, "compatible", &len); > + > + for (i = 0; i < ARRAY_SIZE(atmel_smc_ids); i++) { > + if (!strcmp(name, atmel_smc_ids[i].compatible)) { > + match = &atmel_smc_ids[i]; > + break; > + } > + } > + > + return match ? (struct atmel_hsmc_reg_layout *)match->data : > ERR_PTR(-EINVAL); > +} > diff --git a/include/linux/mfd/syscon/atmel-smc.h > b/include/linux/mfd/syscon/atmel-smc.h > new file mode 100644 > index 0000000000..74be5a199f > --- /dev/null > +++ b/include/linux/mfd/syscon/atmel-smc.h > @@ -0,0 +1,119 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Atmel SMC (Static Memory Controller) register offsets and bit definitions. > + * > + * Copyright (C) 2014 Atmel > + * Copyright (C) 2014 Free Electrons > + * > + * Author: Boris Brezillon <boris.brezil...@free-electrons.com> > + */ > + > +#ifndef _LINUX_MFD_SYSCON_ATMEL_SMC_H_ > +#define _LINUX_MFD_SYSCON_ATMEL_SMC_H_ > + > +#include <linux/kernel.h> > +#include <dm/ofnode.h> > +#include <regmap.h> > + > +#define ATMEL_SMC_SETUP(cs) (((cs) * 0x10)) > +#define ATMEL_HSMC_SETUP(layout, cs) \ > + ((layout)->timing_regs_offset + ((cs) * 0x14)) > +#define ATMEL_SMC_PULSE(cs) (((cs) * 0x10) + 0x4) > +#define ATMEL_HSMC_PULSE(layout, cs) \ > + ((layout)->timing_regs_offset + ((cs) * 0x14) + 0x4) > +#define ATMEL_SMC_CYCLE(cs) (((cs) * 0x10) + 0x8) > +#define ATMEL_HSMC_CYCLE(layout, cs) \ > + ((layout)->timing_regs_offset + ((cs) * 0x14) + 0x8) > +#define ATMEL_SMC_NWE_SHIFT 0 > +#define ATMEL_SMC_NCS_WR_SHIFT 8 > +#define ATMEL_SMC_NRD_SHIFT 16 > +#define ATMEL_SMC_NCS_RD_SHIFT 24 > + > +#define ATMEL_SMC_MODE(cs) (((cs) * 0x10) + 0xc) > +#define ATMEL_HSMC_MODE(layout, cs) \ > + ((layout)->timing_regs_offset + ((cs) * 0x14) + 0x10) > +#define ATMEL_SMC_MODE_READMODE_MASK BIT(0) > +#define ATMEL_SMC_MODE_READMODE_NCS (0 << 0) > +#define ATMEL_SMC_MODE_READMODE_NRD (1 << 0) > +#define ATMEL_SMC_MODE_WRITEMODE_MASK BIT(1) > +#define ATMEL_SMC_MODE_WRITEMODE_NCS (0 << 1) > +#define ATMEL_SMC_MODE_WRITEMODE_NWE (1 << 1) > +#define ATMEL_SMC_MODE_EXNWMODE_MASK GENMASK(5, 4) > +#define ATMEL_SMC_MODE_EXNWMODE_DISABLE (0 << 4) > +#define ATMEL_SMC_MODE_EXNWMODE_FROZEN (2 << 4) > +#define ATMEL_SMC_MODE_EXNWMODE_READY (3 << 4) > +#define ATMEL_SMC_MODE_BAT_MASK BIT(8) > +#define ATMEL_SMC_MODE_BAT_SELECT (0 << 8) > +#define ATMEL_SMC_MODE_BAT_WRITE (1 << 8) > +#define ATMEL_SMC_MODE_DBW_MASK GENMASK(13, 12) > +#define ATMEL_SMC_MODE_DBW_8 (0 << 12) > +#define ATMEL_SMC_MODE_DBW_16 (1 << 12) > +#define ATMEL_SMC_MODE_DBW_32 (2 << 12) > +#define ATMEL_SMC_MODE_TDF_MASK GENMASK(19, 16) > +#define ATMEL_SMC_MODE_TDF(x) (((x) - 1) << 16) > +#define ATMEL_SMC_MODE_TDF_MAX 16 > +#define ATMEL_SMC_MODE_TDF_MIN 1 > +#define ATMEL_SMC_MODE_TDFMODE_OPTIMIZED BIT(20) > +#define ATMEL_SMC_MODE_PMEN BIT(24) > +#define ATMEL_SMC_MODE_PS_MASK GENMASK(29, 28) > +#define ATMEL_SMC_MODE_PS_4 (0 << 28) > +#define ATMEL_SMC_MODE_PS_8 (1 << 28) > +#define ATMEL_SMC_MODE_PS_16 (2 << 28) > +#define ATMEL_SMC_MODE_PS_32 (3 << 28) > + > +#define ATMEL_HSMC_TIMINGS(layout, cs) \ > + ((layout)->timing_regs_offset + ((cs) * 0x14) + 0xc) > +#define ATMEL_HSMC_TIMINGS_OCMS BIT(12) > +#define ATMEL_HSMC_TIMINGS_RBNSEL(x) ((x) << 28) > +#define ATMEL_HSMC_TIMINGS_NFSEL BIT(31) > +#define ATMEL_HSMC_TIMINGS_TCLR_SHIFT 0 > +#define ATMEL_HSMC_TIMINGS_TADL_SHIFT 4 > +#define ATMEL_HSMC_TIMINGS_TAR_SHIFT 8 > +#define ATMEL_HSMC_TIMINGS_TRR_SHIFT 16 > +#define ATMEL_HSMC_TIMINGS_TWB_SHIFT 24 > + > +struct atmel_hsmc_reg_layout { > + unsigned int timing_regs_offset; > +}; > + > +/** > + * struct atmel_smc_cs_conf - SMC CS config as described in the datasheet. > + * @setup: NCS/NWE/NRD setup timings (not applicable to at91rm9200) > + * @pulse: NCS/NWE/NRD pulse timings (not applicable to at91rm9200) > + * @cycle: NWE/NRD cycle timings (not applicable to at91rm9200) > + * @timings: advanced NAND related timings (only applicable to HSMC) > + * @mode: all kind of config parameters (see the fields definition above). > + * The mode fields are different on at91rm9200 > + */ > +struct atmel_smc_cs_conf { > + u32 setup; > + u32 pulse; > + u32 cycle; > + u32 timings; > + u32 mode; > +}; > + > +void atmel_smc_cs_conf_init(struct atmel_smc_cs_conf *conf); > +int atmel_smc_cs_conf_set_timing(struct atmel_smc_cs_conf *conf, > + unsigned int shift, > + unsigned int ncycles); > +int atmel_smc_cs_conf_set_setup(struct atmel_smc_cs_conf *conf, > + unsigned int shift, unsigned int ncycles); > +int atmel_smc_cs_conf_set_pulse(struct atmel_smc_cs_conf *conf, > + unsigned int shift, unsigned int ncycles); > +int atmel_smc_cs_conf_set_cycle(struct atmel_smc_cs_conf *conf, > + unsigned int shift, unsigned int ncycles); > +void atmel_smc_cs_conf_apply(struct regmap *regmap, int cs, > + const struct atmel_smc_cs_conf *conf); > +void atmel_hsmc_cs_conf_apply(struct regmap *regmap, > + const struct atmel_hsmc_reg_layout *reglayout, > + int cs, const struct atmel_smc_cs_conf *conf); > +void atmel_smc_cs_conf_get(struct regmap *regmap, int cs, > + struct atmel_smc_cs_conf *conf); > +void atmel_hsmc_cs_conf_get(struct regmap *regmap, > + const struct atmel_hsmc_reg_layout *reglayout, > + int cs, struct atmel_smc_cs_conf *conf); > +const struct atmel_hsmc_reg_layout * > +atmel_hsmc_get_reg_layout(ofnode np); > + > +#endif /* _LINUX_MFD_SYSCON_ATMEL_SMC_H_ */ > -- > 2.34.1 > -- Michael Nazzareno Trimarchi Co-Founder & Chief Executive Officer M. +39 347 913 2170 mich...@amarulasolutions.com __________________________________ Amarula Solutions BV Joop Geesinkweg 125, 1114 AB, Amsterdam, NL T. +31 (0)85 111 9172 i...@amarulasolutions.com www.amarulasolutions.com