Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Support for configuration of IO Delay module found on Texas Instruments SoCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * such as DRA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2015-2017 Texas Instruments Incorporated - https://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * This file is licensed under the terms of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * License version 2. This program is licensed "as is" without any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * warranty of any kind, whether express or implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/pinctrl/pinconf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/pinctrl/pinconf-generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/pinctrl/pinctrl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include "../core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include "../devicetree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define DRIVER_NAME	"ti-iodelay"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * struct ti_iodelay_reg_data - Describes the registers for the iodelay instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * @signature_mask: CONFIG_REG mask for the signature bits (see TRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * @signature_value: CONFIG_REG signature value to be written (see TRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * @lock_mask: CONFIG_REG mask for the lock bits (see TRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * @lock_val: CONFIG_REG lock value for the lock bits (see TRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * @unlock_val:CONFIG_REG unlock value for the lock bits (see TRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * @binary_data_coarse_mask: CONFIG_REG coarse mask (see TRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * @binary_data_fine_mask: CONFIG_REG fine mask (see TRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * @reg_refclk_offset: Refclk register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * @refclk_period_mask: Refclk mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * @reg_coarse_offset: Coarse register configuration offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * @coarse_delay_count_mask: Coarse delay count mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * @coarse_ref_count_mask: Coarse ref count mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * @reg_fine_offset: Fine register configuration offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  * @fine_delay_count_mask: Fine delay count mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)  * @fine_ref_count_mask: Fine ref count mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46)  * @reg_global_lock_offset: Global iodelay module lock register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)  * @global_lock_mask: Lock mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)  * @global_unlock_val: Unlock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * @global_lock_val: Lock value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * @reg_start_offset: Offset to iodelay registers after the CONFIG_REG_0 to 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * @reg_nr_per_pin: Number of iodelay registers for each pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * @regmap_config: Regmap configuration for the IODelay region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) struct ti_iodelay_reg_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	u32 signature_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	u32 signature_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	u32 lock_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	u32 lock_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	u32 unlock_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	u32 binary_data_coarse_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	u32 binary_data_fine_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	u32 reg_refclk_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	u32 refclk_period_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	u32 reg_coarse_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	u32 coarse_delay_count_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	u32 coarse_ref_count_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	u32 reg_fine_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	u32 fine_delay_count_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	u32 fine_ref_count_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	u32 reg_global_lock_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	u32 global_lock_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	u32 global_unlock_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	u32 global_lock_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	u32 reg_start_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	u32 reg_nr_per_pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	struct regmap_config *regmap_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * struct ti_iodelay_reg_values - Computed io_reg configuration values (see TRM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * @coarse_ref_count: Coarse reference count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * @coarse_delay_count: Coarse delay count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  * @fine_ref_count: Fine reference count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * @fine_delay_count: Fine Delay count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * @ref_clk_period: Reference Clock period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * @cdpe: Coarse delay parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * @fdpe: Fine delay parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) struct ti_iodelay_reg_values {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	u16 coarse_ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	u16 coarse_delay_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	u16 fine_ref_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	u16 fine_delay_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	u16 ref_clk_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	u32 cdpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	u32 fdpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * struct ti_iodelay_cfg - Description of each configuration parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  * @offset: Configuration register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * @a_delay: Agnostic Delay (in ps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * @g_delay: Gnostic Delay (in ps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct ti_iodelay_cfg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	u16 offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	u16 a_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	u16 g_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * struct ti_iodelay_pingroup - Structure that describes one group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * @cfg: configuration array for the pin (from dt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  * @ncfg: number of configuration values allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * @config: pinconf "Config" - currently a dummy value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct ti_iodelay_pingroup {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	struct ti_iodelay_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	int ncfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	unsigned long config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * struct ti_iodelay_device - Represents information for a iodelay instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * @dev: Device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * @phys_base: Physical address base of the iodelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * @reg_base: Virtual address base of the iodelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * @regmap: Regmap for this iodelay instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * @pctl: Pinctrl device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * @desc: pinctrl descriptor for pctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * @pa: pinctrl pin wise description
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  * @reg_data: Register definition data for the IODelay instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * @reg_init_conf_values: Initial configuration values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct ti_iodelay_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	unsigned long phys_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	struct pinctrl_dev *pctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct pinctrl_desc desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct pinctrl_pin_desc *pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	const struct ti_iodelay_reg_data *reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	struct ti_iodelay_reg_values reg_init_conf_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  * ti_iodelay_extract() - extract bits for a field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  * @val: Register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  * @mask: Mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)  * Return: extracted value which is appropriately shifted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static inline u32 ti_iodelay_extract(u32 val, u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	return (val & mask) >> __ffs(mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)  * ti_iodelay_compute_dpe() - Compute equation for delay parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * @period: Period to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  * @ref: Reference Count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)  * @delay: Delay count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)  * @delay_m: Delay multiplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * Return: Computed delay parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static inline u32 ti_iodelay_compute_dpe(u16 period, u16 ref, u16 delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 					 u16 delay_m)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	u64 m, d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	/* Handle overflow conditions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	m = 10 * (u64)period * (u64)ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	d = 2 * (u64)delay * (u64)delay_m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	/* Truncate result back to 32 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	return div64_u64(m, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  * ti_iodelay_pinconf_set() - Configure the pin configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)  * @iod: iodelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)  * @cfg: Configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)  * Update the configuration register as per TRM and lockup once done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)  * *IMPORTANT NOTE* SoC TRM does recommend doing iodelay programmation only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)  * while in Isolation. But, then, isolation also implies that every pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)  * on the SoC (including DDR) will be isolated out. The only benefit being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)  * a glitchless configuration, However, the intent of this driver is purely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  * to support a "glitchy" configuration where applicable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  * Return: 0 in case of success, else appropriate error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static int ti_iodelay_pinconf_set(struct ti_iodelay_device *iod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				  struct ti_iodelay_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	const struct ti_iodelay_reg_data *reg = iod->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	struct ti_iodelay_reg_values *ival = &iod->reg_init_conf_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	struct device *dev = iod->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	u32 g_delay_coarse, g_delay_fine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	u32 a_delay_coarse, a_delay_fine;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	u32 c_elements, f_elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	u32 total_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	u32 reg_mask, reg_val, tmp_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	/* NOTE: Truncation is expected in all division below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	g_delay_coarse = cfg->g_delay / 920;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	g_delay_fine = ((cfg->g_delay % 920) * 10) / 60;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	a_delay_coarse = cfg->a_delay / ival->cdpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	a_delay_fine = ((cfg->a_delay % ival->cdpe) * 10) / ival->fdpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	c_elements = g_delay_coarse + a_delay_coarse;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	f_elements = (g_delay_fine + a_delay_fine) / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if (f_elements > 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		total_delay = c_elements * ival->cdpe + f_elements * ival->fdpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		c_elements = total_delay / ival->cdpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		f_elements = (total_delay % ival->cdpe) / ival->fdpe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	reg_mask = reg->signature_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	reg_val = reg->signature_value << __ffs(reg->signature_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	reg_mask |= reg->binary_data_coarse_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	tmp_val = c_elements << __ffs(reg->binary_data_coarse_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (tmp_val & ~reg->binary_data_coarse_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		dev_err(dev, "Masking overflow of coarse elements %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			tmp_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		tmp_val &= reg->binary_data_coarse_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	reg_val |= tmp_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	reg_mask |= reg->binary_data_fine_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	tmp_val = f_elements << __ffs(reg->binary_data_fine_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	if (tmp_val & ~reg->binary_data_fine_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		dev_err(dev, "Masking overflow of fine elements %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			tmp_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		tmp_val &= reg->binary_data_fine_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	reg_val |= tmp_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	 * NOTE: we leave the iodelay values unlocked - this is to work around
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	 * situations such as those found with mmc mode change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	 * However, this leaves open any unwarranted changes to padconf register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	 * impacting iodelay configuration. Use with care!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	reg_mask |= reg->lock_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	reg_val |= reg->unlock_val << __ffs(reg->lock_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	r = regmap_update_bits(iod->regmap, cfg->offset, reg_mask, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	dev_dbg(dev, "Set reg 0x%x Delay(a: %d g: %d), Elements(C=%d F=%d)0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		cfg->offset, cfg->a_delay, cfg->g_delay, c_elements,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		f_elements, reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  * ti_iodelay_pinconf_init_dev() - Initialize IODelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  * @iod: iodelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * Unlocks the iodelay region, computes the common parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  * Return: 0 in case of success, else appropriate error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static int ti_iodelay_pinconf_init_dev(struct ti_iodelay_device *iod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	const struct ti_iodelay_reg_data *reg = iod->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	struct device *dev = iod->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	struct ti_iodelay_reg_values *ival = &iod->reg_init_conf_values;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	/* unlock the iodelay region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	r = regmap_update_bits(iod->regmap, reg->reg_global_lock_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			       reg->global_lock_mask, reg->global_unlock_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	/* Read up Recalibration sequence done by bootloader */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	r = regmap_read(iod->regmap, reg->reg_refclk_offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	ival->ref_clk_period = ti_iodelay_extract(val, reg->refclk_period_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	dev_dbg(dev, "refclk_period=0x%04x\n", ival->ref_clk_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	r = regmap_read(iod->regmap, reg->reg_coarse_offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	ival->coarse_ref_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	    ti_iodelay_extract(val, reg->coarse_ref_count_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	ival->coarse_delay_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	    ti_iodelay_extract(val, reg->coarse_delay_count_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	if (!ival->coarse_delay_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		dev_err(dev, "Invalid Coarse delay count (0) (reg=0x%08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	ival->cdpe = ti_iodelay_compute_dpe(ival->ref_clk_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 					    ival->coarse_ref_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 					    ival->coarse_delay_count, 88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	if (!ival->cdpe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		dev_err(dev, "Invalid cdpe computed params = %d %d %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			ival->ref_clk_period, ival->coarse_ref_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			ival->coarse_delay_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	dev_dbg(iod->dev, "coarse: ref=0x%04x delay=0x%04x cdpe=0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		ival->coarse_ref_count, ival->coarse_delay_count, ival->cdpe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	r = regmap_read(iod->regmap, reg->reg_fine_offset, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	ival->fine_ref_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	    ti_iodelay_extract(val, reg->fine_ref_count_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	ival->fine_delay_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	    ti_iodelay_extract(val, reg->fine_delay_count_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	if (!ival->fine_delay_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		dev_err(dev, "Invalid Fine delay count (0) (reg=0x%08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 			val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	ival->fdpe = ti_iodelay_compute_dpe(ival->ref_clk_period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 					    ival->fine_ref_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 					    ival->fine_delay_count, 264);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	if (!ival->fdpe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		dev_err(dev, "Invalid fdpe(0) computed params = %d %d %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			ival->ref_clk_period, ival->fine_ref_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			ival->fine_delay_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	dev_dbg(iod->dev, "fine: ref=0x%04x delay=0x%04x fdpe=0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		ival->fine_ref_count, ival->fine_delay_count, ival->fdpe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)  * ti_iodelay_pinconf_deinit_dev() - deinit the iodelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)  * @iod:	IODelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)  * Deinitialize the IODelay device (basically just lock the region back up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static void ti_iodelay_pinconf_deinit_dev(struct ti_iodelay_device *iod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	const struct ti_iodelay_reg_data *reg = iod->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	/* lock the iodelay region back again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	regmap_update_bits(iod->regmap, reg->reg_global_lock_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			   reg->global_lock_mask, reg->global_lock_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  * ti_iodelay_get_pingroup() - Find the group mapped by a group selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)  * @iod: iodelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)  * @selector: Group Selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)  * Return: Corresponding group representing group selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static struct ti_iodelay_pingroup *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ti_iodelay_get_pingroup(struct ti_iodelay_device *iod, unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	struct group_desc *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	g = pinctrl_generic_get_group(iod->pctl, selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	if (!g) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		dev_err(iod->dev, "%s could not find pingroup %i\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 			selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	return g->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  * ti_iodelay_offset_to_pin() - get a pin index based on the register offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  * @iod: iodelay driver instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  * @offset: register offset from the base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int ti_iodelay_offset_to_pin(struct ti_iodelay_device *iod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 				    unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	const struct ti_iodelay_reg_data *r = iod->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	if (offset > r->regmap_config->max_register) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		dev_err(iod->dev, "mux offset out of range: 0x%x (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			offset, r->regmap_config->max_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	index = (offset - r->reg_start_offset) / r->regmap_config->reg_stride;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	index /= r->reg_nr_per_pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)  * ti_iodelay_node_iterator() - Iterate iodelay node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)  * @pctldev: Pin controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  * @np: Device node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  * @pinctrl_spec: Parsed arguments from device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)  * @pins: Array of pins in the pin group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)  * @pin_index: Pin index in the pin array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)  * @data: Pin controller driver specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static int ti_iodelay_node_iterator(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 				    struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 				    const struct of_phandle_args *pinctrl_spec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 				    int *pins, int pin_index, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	struct ti_iodelay_device *iod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	struct ti_iodelay_cfg *cfg = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	const struct ti_iodelay_reg_data *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	struct pinctrl_pin_desc *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	int pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	iod = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	if (!iod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	r = iod->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	if (pinctrl_spec->args_count < r->reg_nr_per_pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		dev_err(iod->dev, "invalid args_count for spec: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			pinctrl_spec->args_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	/* Index plus two value cells */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	cfg[pin_index].offset = pinctrl_spec->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	cfg[pin_index].a_delay = pinctrl_spec->args[1] & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	cfg[pin_index].g_delay = pinctrl_spec->args[2] & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	pin = ti_iodelay_offset_to_pin(iod, cfg[pin_index].offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	if (pin < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		dev_err(iod->dev, "could not add functions for %pOFn %ux\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 			np, cfg[pin_index].offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	pins[pin_index] = pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	pd = &iod->pa[pin];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	pd->drv_data = &cfg[pin_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	dev_dbg(iod->dev, "%pOFn offset=%x a_delay = %d g_delay = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		np, cfg[pin_index].offset, cfg[pin_index].a_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		cfg[pin_index].g_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)  * ti_iodelay_dt_node_to_map() - Map a device tree node to appropriate group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)  * @pctldev: pinctrl device representing IODelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)  * @np: Node Pointer (device tree)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)  * @map: Pinctrl Map returned back to pinctrl framework
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)  * @num_maps: Number of maps (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)  * Maps the device tree description into a group of configuration parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)  * for iodelay block entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)  * Return: 0 in case of success, else appropriate error value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static int ti_iodelay_dt_node_to_map(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 				     struct device_node *np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 				     struct pinctrl_map **map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 				     unsigned int *num_maps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	struct ti_iodelay_device *iod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	struct ti_iodelay_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	struct ti_iodelay_pingroup *g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	const char *name = "pinctrl-pin-array";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	int rows, *pins, error = -EINVAL, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	iod = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	if (!iod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	rows = pinctrl_count_index_with_args(np, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	if (rows < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		return rows;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	*map = devm_kzalloc(iod->dev, sizeof(**map), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	if (!*map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	*num_maps = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	g = devm_kzalloc(iod->dev, sizeof(*g), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	if (!g) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		goto free_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	pins = devm_kcalloc(iod->dev, rows, sizeof(*pins), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (!pins)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		goto free_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	cfg = devm_kcalloc(iod->dev, rows, sizeof(*cfg), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	if (!cfg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		goto free_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	for (i = 0; i < rows; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		struct of_phandle_args pinctrl_spec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		error = pinctrl_parse_index_with_args(np, name, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 						      &pinctrl_spec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 			goto free_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		error = ti_iodelay_node_iterator(pctldev, np, &pinctrl_spec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 						 pins, i, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			goto free_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	g->cfg = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	g->ncfg = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 	g->config = PIN_CONFIG_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	error = pinctrl_generic_add_group(iod->pctl, np->name, pins, i, g);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		goto free_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	(*map)->type = PIN_MAP_TYPE_CONFIGS_GROUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	(*map)->data.configs.group_or_pin = np->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	(*map)->data.configs.configs = &g->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	(*map)->data.configs.num_configs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	*num_maps = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) free_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	devm_kfree(iod->dev, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) free_pins:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	devm_kfree(iod->dev, pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) free_group:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	devm_kfree(iod->dev, g);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) free_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	devm_kfree(iod->dev, *map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)  * ti_iodelay_pinconf_group_get() - Get the group configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)  * @pctldev: pinctrl device representing IODelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)  * @selector: Group selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)  * @config: Configuration returned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)  * Return: The configuration if the group is valid, else returns -EINVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static int ti_iodelay_pinconf_group_get(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 					unsigned int selector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 					unsigned long *config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	struct ti_iodelay_device *iod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	struct ti_iodelay_pingroup *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	iod = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	group = ti_iodelay_get_pingroup(iod, selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (!group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	*config = group->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)  * ti_iodelay_pinconf_group_set() - Configure the groups of pins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)  * @pctldev: pinctrl device representing IODelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)  * @selector: Group selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)  * @configs: Configurations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)  * @num_configs: Number of configurations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)  * Return: 0 if all went fine, else appropriate error value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static int ti_iodelay_pinconf_group_set(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 					unsigned int selector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 					unsigned long *configs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 					unsigned int num_configs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	struct ti_iodelay_device *iod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	struct ti_iodelay_pingroup *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	iod = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	dev = iod->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	group = ti_iodelay_get_pingroup(iod, selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	if (num_configs != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 		dev_err(dev, "Unsupported number of configurations %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 			num_configs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	if (*configs != PIN_CONFIG_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		dev_err(dev, "Unsupported configuration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	for (i = 0; i < group->ncfg; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		if (ti_iodelay_pinconf_set(iod, &group->cfg[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 			return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)  * ti_iodelay_pin_to_offset() - get pin register offset based on the pin index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)  * @iod: iodelay driver instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)  * @selector: Pin index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static unsigned int ti_iodelay_pin_to_offset(struct ti_iodelay_device *iod,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 					     unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	const struct ti_iodelay_reg_data *r = iod->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	offset = selector * r->regmap_config->reg_stride;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	offset *= r->reg_nr_per_pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	offset += r->reg_start_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) static void ti_iodelay_pin_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 				    struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 				    unsigned int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	struct ti_iodelay_device *iod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	struct pinctrl_pin_desc *pd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	struct ti_iodelay_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	const struct ti_iodelay_reg_data *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	unsigned long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	u32 in, oen, out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	iod = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	r = iod->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	offset = ti_iodelay_pin_to_offset(iod, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	pd = &iod->pa[pin];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	cfg = pd->drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	regmap_read(iod->regmap, offset, &in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	regmap_read(iod->regmap, offset + r->regmap_config->reg_stride, &oen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	regmap_read(iod->regmap, offset + r->regmap_config->reg_stride * 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		    &out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	seq_printf(s, "%lx a: %i g: %i (%08x %08x %08x) %s ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		   iod->phys_base + offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		   cfg ? cfg->a_delay : -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		   cfg ? cfg->g_delay : -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		   in, oen, out, DRIVER_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)  * ti_iodelay_pinconf_group_dbg_show() - show the group information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)  * @pctldev: Show the group information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)  * @s: Sequence file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)  * @selector: Group selector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)  * Provide the configuration information of the selected group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static void ti_iodelay_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 					      struct seq_file *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 					      unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	struct ti_iodelay_device *iod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	struct ti_iodelay_pingroup *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	iod = pinctrl_dev_get_drvdata(pctldev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	group = ti_iodelay_get_pingroup(iod, selector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	if (!group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	for (i = 0; i < group->ncfg; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		struct ti_iodelay_cfg *cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		u32 reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 		cfg = &group->cfg[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 		regmap_read(iod->regmap, cfg->offset, &reg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 			seq_printf(s, "\n\t0x%08x = 0x%08x (%3d, %3d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 				   cfg->offset, reg, cfg->a_delay,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 				   cfg->g_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static const struct pinctrl_ops ti_iodelay_pinctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	.get_groups_count = pinctrl_generic_get_group_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	.get_group_name = pinctrl_generic_get_group_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	.get_group_pins = pinctrl_generic_get_group_pins,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	.pin_dbg_show = ti_iodelay_pin_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	.dt_node_to_map = ti_iodelay_dt_node_to_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static const struct pinconf_ops ti_iodelay_pinctrl_pinconf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	.pin_config_group_get = ti_iodelay_pinconf_group_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	.pin_config_group_set = ti_iodelay_pinconf_group_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) #ifdef CONFIG_DEBUG_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	.pin_config_group_dbg_show = ti_iodelay_pinconf_group_dbg_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)  * ti_iodelay_alloc_pins() - Allocate structures needed for pins for iodelay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)  * @dev: Device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)  * @iod: iodelay device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)  * @base_phy: Base Physical Address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)  * Return: 0 if all went fine, else appropriate error value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) static int ti_iodelay_alloc_pins(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 				 struct ti_iodelay_device *iod, u32 base_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	const struct ti_iodelay_reg_data *r = iod->reg_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 	struct pinctrl_pin_desc *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	u32 phy_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	int nr_pins, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	nr_pins = ti_iodelay_offset_to_pin(iod, r->regmap_config->max_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	dev_dbg(dev, "Allocating %i pins\n", nr_pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	iod->pa = devm_kcalloc(dev, nr_pins, sizeof(*iod->pa), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	if (!iod->pa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	iod->desc.pins = iod->pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	iod->desc.npins = nr_pins;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 	phy_reg = r->reg_start_offset + base_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	for (i = 0; i < nr_pins; i++, phy_reg += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 		pin = &iod->pa[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 		pin->number = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static struct regmap_config dra7_iodelay_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	.reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	.reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	.val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	.max_register = 0xd1c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static struct ti_iodelay_reg_data dra7_iodelay_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	.signature_mask = 0x0003f000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	.signature_value = 0x29,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	.lock_mask = 0x00000400,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	.lock_val = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	.unlock_val = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	.binary_data_coarse_mask = 0x000003e0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	.binary_data_fine_mask = 0x0000001f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	.reg_refclk_offset = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	.refclk_period_mask = 0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 	.reg_coarse_offset = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	.coarse_delay_count_mask = 0xffff0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	.coarse_ref_count_mask = 0x0000ffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	.reg_fine_offset = 0x1C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	.fine_delay_count_mask = 0xffff0000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	.fine_ref_count_mask = 0x0000ffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	.reg_global_lock_offset = 0x2c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	.global_lock_mask = 0x0000ffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	.global_unlock_val = 0x0000aaaa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	.global_lock_val = 0x0000aaab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	.reg_start_offset = 0x30,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	.reg_nr_per_pin = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	.regmap_config = &dra7_iodelay_regmap_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static const struct of_device_id ti_iodelay_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	{.compatible = "ti,dra7-iodelay", .data = &dra7_iodelay_data},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	{ /* Hopefully no more.. */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) MODULE_DEVICE_TABLE(of, ti_iodelay_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)  * ti_iodelay_probe() - Standard probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)  * @pdev: platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)  * Return: 0 if all went fine, else appropriate error value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) static int ti_iodelay_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	struct device_node *np = of_node_get(dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	struct ti_iodelay_device *iod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 		dev_err(dev, "No OF node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 		goto exit_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	match = of_match_device(ti_iodelay_of_match, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	if (!match) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 		dev_err(dev, "No DATA match\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 		goto exit_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	iod = devm_kzalloc(dev, sizeof(*iod), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	if (!iod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 		goto exit_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 	iod->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	iod->reg_data = match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	/* So far We can assume there is only 1 bank of registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 		dev_err(dev, "Missing MEM resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 		goto exit_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	iod->phys_base = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	iod->reg_base = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	if (IS_ERR(iod->reg_base)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 		ret = PTR_ERR(iod->reg_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 		goto exit_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) 	iod->regmap = devm_regmap_init_mmio(dev, iod->reg_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 					    iod->reg_data->regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 	if (IS_ERR(iod->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 		dev_err(dev, "Regmap MMIO init failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 		ret = PTR_ERR(iod->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 		goto exit_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	if (ti_iodelay_pinconf_init_dev(iod))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 		goto exit_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 	ret = ti_iodelay_alloc_pins(dev, iod, res->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 		goto exit_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 	iod->desc.pctlops = &ti_iodelay_pinctrl_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	/* no pinmux ops - we are pinconf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 	iod->desc.confops = &ti_iodelay_pinctrl_pinconf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	iod->desc.name = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	iod->desc.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 	ret = pinctrl_register_and_init(&iod->desc, dev, iod, &iod->pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 		dev_err(dev, "Failed to register pinctrl\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 		goto exit_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 	platform_set_drvdata(pdev, iod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	return pinctrl_enable(iod->pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) exit_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 	of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)  * ti_iodelay_remove() - standard remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)  * @pdev: platform device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)  * Return: 0 if all went fine, else appropriate error value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) static int ti_iodelay_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 	struct ti_iodelay_device *iod = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 	if (!iod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 	if (iod->pctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 		pinctrl_unregister(iod->pctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 	ti_iodelay_pinconf_deinit_dev(iod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	/* Expect other allocations to be freed by devm */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) static struct platform_driver ti_iodelay_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 	.probe = ti_iodelay_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 	.remove = ti_iodelay_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 		   .name = DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 		   .of_match_table = ti_iodelay_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) module_platform_driver(ti_iodelay_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) MODULE_AUTHOR("Texas Instruments, Inc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) MODULE_DESCRIPTION("Pinconf driver for TI's IO Delay module");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) MODULE_LICENSE("GPL v2");