1 // SPDX-License-Identifier: GPL-2.0
3 * System Control and Power Interface (SCMI) Protocol based i.MX pinctrl driver
8 #include <linux/device.h>
10 #include <linux/errno.h>
11 #include <linux/module.h>
12 #include <linux/mod_devicetable.h>
14 #include <linux/scmi_protocol.h>
15 #include <linux/seq_file.h>
16 #include <linux/slab.h>
17 #include <linux/types.h>
19 #include <linux/pinctrl/machine.h>
20 #include <linux/pinctrl/pinconf.h>
21 #include <linux/pinctrl/pinconf-generic.h>
22 #include <linux/pinctrl/pinctrl.h>
23 #include <linux/pinctrl/pinmux.h>
25 #include "../pinctrl-utils.h"
27 #include "../pinconf.h"
28 #include "../pinmux.h"
30 #define DRV_NAME "scmi-pinctrl-imx"
32 struct scmi_pinctrl_imx
{
34 struct scmi_protocol_handle
*ph
;
35 struct pinctrl_dev
*pctldev
;
36 struct pinctrl_desc pctl_desc
;
37 const struct scmi_pinctrl_proto_ops
*ops
;
40 /* SCMI pin control types, aligned with SCMI firmware */
41 #define IMX_SCMI_NUM_CFG 4
42 #define IMX_SCMI_PIN_MUX 192
43 #define IMX_SCMI_PIN_CONFIG 193
44 #define IMX_SCMI_PIN_DAISY_ID 194
45 #define IMX_SCMI_PIN_DAISY_CFG 195
47 #define IMX_SCMI_NO_PAD_CTL BIT(31)
48 #define IMX_SCMI_PAD_SION BIT(30)
49 #define IMX_SCMI_IOMUXC_CONFIG_SION BIT(4)
51 #define IMX_SCMI_PIN_SIZE 24
53 #define IMX95_DAISY_OFF 0x408
55 static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev
*pctldev
,
56 struct device_node
*np
,
57 struct pinctrl_map
**map
,
58 unsigned int *num_maps
)
60 struct pinctrl_map
*new_map
;
62 unsigned long *configs
= NULL
;
63 unsigned long cfg
[IMX_SCMI_NUM_CFG
];
64 int map_num
, size
, pin_size
, pin_id
, num_pins
;
65 int mux_reg
, conf_reg
, input_reg
, mux_val
, conf_val
, input_val
;
68 static uint32_t daisy_off
;
71 if (of_machine_is_compatible("fsl,imx95")) {
72 daisy_off
= IMX95_DAISY_OFF
;
74 dev_err(pctldev
->dev
, "platform not support scmi pinctrl\n");
79 list
= of_get_property(np
, "fsl,pins", &size
);
81 dev_err(pctldev
->dev
, "no fsl,pins property in node %pOF\n", np
);
85 pin_size
= IMX_SCMI_PIN_SIZE
;
87 if (!size
|| size
% pin_size
) {
88 dev_err(pctldev
->dev
, "Invalid fsl,pins or pins property in node %pOF\n", np
);
92 num_pins
= size
/ pin_size
;
95 new_map
= kmalloc_array(map_num
, sizeof(struct pinctrl_map
),
103 /* create config map */
104 for (i
= 0; i
< num_pins
; i
++) {
106 ncfg
= IMX_SCMI_NUM_CFG
;
107 mux_reg
= be32_to_cpu(*list
++);
108 conf_reg
= be32_to_cpu(*list
++);
109 input_reg
= be32_to_cpu(*list
++);
110 mux_val
= be32_to_cpu(*list
++);
111 input_val
= be32_to_cpu(*list
++);
112 conf_val
= be32_to_cpu(*list
++);
113 if (conf_val
& IMX_SCMI_PAD_SION
)
114 mux_val
|= IMX_SCMI_IOMUXC_CONFIG_SION
;
116 pin_id
= mux_reg
/ 4;
118 cfg
[j
++] = pinconf_to_config_packed(IMX_SCMI_PIN_MUX
, mux_val
);
120 if (!conf_reg
|| (conf_val
& IMX_SCMI_NO_PAD_CTL
))
123 cfg
[j
++] = pinconf_to_config_packed(IMX_SCMI_PIN_CONFIG
, conf_val
);
128 cfg
[j
++] = pinconf_to_config_packed(IMX_SCMI_PIN_DAISY_ID
,
129 (input_reg
- daisy_off
) / 4);
130 cfg
[j
++] = pinconf_to_config_packed(IMX_SCMI_PIN_DAISY_CFG
, input_val
);
133 configs
= kmemdup_array(cfg
, ncfg
, sizeof(unsigned long), GFP_KERNEL
);
135 new_map
[i
].type
= PIN_MAP_TYPE_CONFIGS_PIN
;
136 new_map
[i
].data
.configs
.group_or_pin
= pin_get_name(pctldev
, pin_id
);
137 new_map
[i
].data
.configs
.configs
= configs
;
138 new_map
[i
].data
.configs
.num_configs
= ncfg
;
144 static void pinctrl_scmi_imx_dt_free_map(struct pinctrl_dev
*pctldev
,
145 struct pinctrl_map
*map
, unsigned int num_maps
)
150 static const struct pinctrl_ops pinctrl_scmi_imx_pinctrl_ops
= {
151 .get_groups_count
= pinctrl_generic_get_group_count
,
152 .get_group_name
= pinctrl_generic_get_group_name
,
153 .get_group_pins
= pinctrl_generic_get_group_pins
,
154 .dt_node_to_map
= pinctrl_scmi_imx_dt_node_to_map
,
155 .dt_free_map
= pinctrl_scmi_imx_dt_free_map
,
158 static int pinctrl_scmi_imx_func_set_mux(struct pinctrl_dev
*pctldev
,
159 unsigned int selector
, unsigned int group
)
162 * For i.MX SCMI PINCTRL , postpone the mux setting
163 * until config is set as they can be set together
169 static const struct pinmux_ops pinctrl_scmi_imx_pinmux_ops
= {
170 .get_functions_count
= pinmux_generic_get_function_count
,
171 .get_function_name
= pinmux_generic_get_function_name
,
172 .get_function_groups
= pinmux_generic_get_function_groups
,
173 .set_mux
= pinctrl_scmi_imx_func_set_mux
,
176 static int pinctrl_scmi_imx_pinconf_get(struct pinctrl_dev
*pctldev
,
177 unsigned int pin
, unsigned long *config
)
180 struct scmi_pinctrl_imx
*pmx
= pinctrl_dev_get_drvdata(pctldev
);
181 u32 config_type
, val
;
186 config_type
= pinconf_to_config_param(*config
);
188 ret
= pmx
->ops
->settings_get_one(pmx
->ph
, pin
, PIN_TYPE
, config_type
, &val
);
189 /* Convert SCMI error code to PINCTRL expected error code */
190 if (ret
== -EOPNOTSUPP
)
195 *config
= pinconf_to_config_packed(config_type
, val
);
197 dev_dbg(pmx
->dev
, "pin:%s, conf:0x%x", pin_get_name(pctldev
, pin
), val
);
202 static int pinctrl_scmi_imx_pinconf_set(struct pinctrl_dev
*pctldev
,
204 unsigned long *configs
,
205 unsigned int num_configs
)
207 struct scmi_pinctrl_imx
*pmx
= pinctrl_dev_get_drvdata(pctldev
);
208 enum scmi_pinctrl_conf_type config_type
[IMX_SCMI_NUM_CFG
];
209 u32 config_value
[IMX_SCMI_NUM_CFG
];
210 enum scmi_pinctrl_conf_type
*p_config_type
= config_type
;
211 u32
*p_config_value
= config_value
;
215 if (!configs
|| !num_configs
)
218 if (num_configs
> IMX_SCMI_NUM_CFG
) {
219 dev_err(pmx
->dev
, "num_configs(%d) too large\n", num_configs
);
223 for (i
= 0; i
< num_configs
; i
++) {
224 /* cast to avoid build warning */
226 (enum scmi_pinctrl_conf_type
)pinconf_to_config_param(configs
[i
]);
227 p_config_value
[i
] = pinconf_to_config_argument(configs
[i
]);
229 dev_dbg(pmx
->dev
, "pin: %u, type: %u, val: 0x%x\n",
230 pin
, p_config_type
[i
], p_config_value
[i
]);
233 ret
= pmx
->ops
->settings_conf(pmx
->ph
, pin
, PIN_TYPE
, num_configs
,
234 p_config_type
, p_config_value
);
236 dev_err(pmx
->dev
, "Error set config %d\n", ret
);
241 static void pinctrl_scmi_imx_pinconf_dbg_show(struct pinctrl_dev
*pctldev
,
242 struct seq_file
*s
, unsigned int pin_id
)
244 unsigned long config
= pinconf_to_config_packed(IMX_SCMI_PIN_CONFIG
, 0);
247 ret
= pinctrl_scmi_imx_pinconf_get(pctldev
, pin_id
, &config
);
251 config
= pinconf_to_config_argument(config
);
253 seq_printf(s
, "0x%lx", config
);
256 static const struct pinconf_ops pinctrl_scmi_imx_pinconf_ops
= {
257 .pin_config_get
= pinctrl_scmi_imx_pinconf_get
,
258 .pin_config_set
= pinctrl_scmi_imx_pinconf_set
,
259 .pin_config_dbg_show
= pinctrl_scmi_imx_pinconf_dbg_show
,
263 scmi_pinctrl_imx_get_pins(struct scmi_pinctrl_imx
*pmx
, struct pinctrl_desc
*desc
)
265 struct pinctrl_pin_desc
*pins
;
269 npins
= pmx
->ops
->count_get(pmx
->ph
, PIN_TYPE
);
270 pins
= devm_kmalloc_array(pmx
->dev
, npins
, sizeof(*pins
), GFP_KERNEL
);
274 for (i
= 0; i
< npins
; i
++) {
276 /* no need free name, firmware driver handles it */
277 ret
= pmx
->ops
->name_get(pmx
->ph
, i
, PIN_TYPE
, &pins
[i
].name
);
279 return dev_err_probe(pmx
->dev
, ret
,
280 "Can't get name for pin %d", i
);
285 dev_dbg(pmx
->dev
, "got pins %u", npins
);
290 static const char * const scmi_pinctrl_imx_allowlist
[] = {
295 static int scmi_pinctrl_imx_probe(struct scmi_device
*sdev
)
297 struct device
*dev
= &sdev
->dev
;
298 const struct scmi_handle
*handle
= sdev
->handle
;
299 struct scmi_pinctrl_imx
*pmx
;
300 struct scmi_protocol_handle
*ph
;
301 const struct scmi_pinctrl_proto_ops
*pinctrl_ops
;
307 if (!of_machine_compatible_match(scmi_pinctrl_imx_allowlist
))
310 pinctrl_ops
= handle
->devm_protocol_get(sdev
, SCMI_PROTOCOL_PINCTRL
, &ph
);
311 if (IS_ERR(pinctrl_ops
))
312 return PTR_ERR(pinctrl_ops
);
314 pmx
= devm_kzalloc(dev
, sizeof(*pmx
), GFP_KERNEL
);
319 pmx
->ops
= pinctrl_ops
;
322 pmx
->pctl_desc
.name
= DRV_NAME
;
323 pmx
->pctl_desc
.owner
= THIS_MODULE
;
324 pmx
->pctl_desc
.pctlops
= &pinctrl_scmi_imx_pinctrl_ops
;
325 pmx
->pctl_desc
.pmxops
= &pinctrl_scmi_imx_pinmux_ops
;
326 pmx
->pctl_desc
.confops
= &pinctrl_scmi_imx_pinconf_ops
;
328 ret
= scmi_pinctrl_imx_get_pins(pmx
, &pmx
->pctl_desc
);
332 pmx
->dev
= &sdev
->dev
;
334 ret
= devm_pinctrl_register_and_init(dev
, &pmx
->pctl_desc
, pmx
,
337 return dev_err_probe(dev
, ret
, "Failed to register pinctrl\n");
339 return pinctrl_enable(pmx
->pctldev
);
342 static const struct scmi_device_id scmi_id_table
[] = {
343 { SCMI_PROTOCOL_PINCTRL
, "pinctrl-imx" },
346 MODULE_DEVICE_TABLE(scmi
, scmi_id_table
);
348 static struct scmi_driver scmi_pinctrl_imx_driver
= {
350 .probe
= scmi_pinctrl_imx_probe
,
351 .id_table
= scmi_id_table
,
353 module_scmi_driver(scmi_pinctrl_imx_driver
);
355 MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
356 MODULE_DESCRIPTION("i.MX SCMI pin controller driver");
357 MODULE_LICENSE("GPL");