Home | History | Annotate | Download | only in aspeed
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Copyright 2017 Google, Inc
      4  */
      5 
      6 #include <common.h>
      7 #include <dm.h>
      8 #include <errno.h>
      9 #include <asm/io.h>
     10 #include <asm/arch/pinctrl.h>
     11 #include <asm/arch/scu_ast2500.h>
     12 #include <dm/pinctrl.h>
     13 
     14 /*
     15  * This driver works with very simple configuration that has the same name
     16  * for group and function. This way it is compatible with the Linux Kernel
     17  * driver.
     18  */
     19 
     20 struct ast2500_pinctrl_priv {
     21 	struct ast2500_scu *scu;
     22 };
     23 
     24 static int ast2500_pinctrl_probe(struct udevice *dev)
     25 {
     26 	struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
     27 
     28 	priv->scu = ast_get_scu();
     29 
     30 	return 0;
     31 }
     32 
     33 struct ast2500_group_config {
     34 	char *group_name;
     35 	/* Control register number (1-10) */
     36 	unsigned reg_num;
     37 	/* The mask of control bits in the register */
     38 	u32 ctrl_bit_mask;
     39 };
     40 
     41 static const struct ast2500_group_config ast2500_groups[] = {
     42 	{ "I2C1", 8, (1 << 13) | (1 << 12) },
     43 	{ "I2C2", 8, (1 << 15) | (1 << 14) },
     44 	{ "I2C3", 8, (1 << 16) },
     45 	{ "I2C4", 5, (1 << 17) },
     46 	{ "I2C4", 5, (1 << 17) },
     47 	{ "I2C5", 5, (1 << 18) },
     48 	{ "I2C6", 5, (1 << 19) },
     49 	{ "I2C7", 5, (1 << 20) },
     50 	{ "I2C8", 5, (1 << 21) },
     51 	{ "I2C9", 5, (1 << 22) },
     52 	{ "I2C10", 5, (1 << 23) },
     53 	{ "I2C11", 5, (1 << 24) },
     54 	{ "I2C12", 5, (1 << 25) },
     55 	{ "I2C13", 5, (1 << 26) },
     56 	{ "I2C14", 5, (1 << 27) },
     57 	{ "MAC1LINK", 1, (1 << 0) },
     58 	{ "MDIO1", 3, (1 << 31) | (1 << 30) },
     59 	{ "MAC2LINK", 1, (1 << 1) },
     60 	{ "MDIO2", 5, (1 << 2) },
     61 };
     62 
     63 static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
     64 {
     65 	debug("PINCTRL: get_(functions/groups)_count\n");
     66 
     67 	return ARRAY_SIZE(ast2500_groups);
     68 }
     69 
     70 static const char *ast2500_pinctrl_get_group_name(struct udevice *dev,
     71 						  unsigned selector)
     72 {
     73 	debug("PINCTRL: get_(function/group)_name %u\n", selector);
     74 
     75 	return ast2500_groups[selector].group_name;
     76 }
     77 
     78 static int ast2500_pinctrl_group_set(struct udevice *dev, unsigned selector,
     79 				     unsigned func_selector)
     80 {
     81 	struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
     82 	const struct ast2500_group_config *config;
     83 	u32 *ctrl_reg;
     84 
     85 	debug("PINCTRL: group_set <%u, %u>\n", selector, func_selector);
     86 	if (selector >= ARRAY_SIZE(ast2500_groups))
     87 		return -EINVAL;
     88 
     89 	config = &ast2500_groups[selector];
     90 	if (config->reg_num > 6)
     91 		ctrl_reg = &priv->scu->pinmux_ctrl1[config->reg_num - 7];
     92 	else
     93 		ctrl_reg = &priv->scu->pinmux_ctrl[config->reg_num - 1];
     94 
     95 	ast_scu_unlock(priv->scu);
     96 	setbits_le32(ctrl_reg, config->ctrl_bit_mask);
     97 	ast_scu_lock(priv->scu);
     98 
     99 	return 0;
    100 }
    101 
    102 static struct pinctrl_ops ast2500_pinctrl_ops = {
    103 	.set_state = pinctrl_generic_set_state,
    104 	.get_groups_count = ast2500_pinctrl_get_groups_count,
    105 	.get_group_name = ast2500_pinctrl_get_group_name,
    106 	.get_functions_count = ast2500_pinctrl_get_groups_count,
    107 	.get_function_name = ast2500_pinctrl_get_group_name,
    108 	.pinmux_group_set = ast2500_pinctrl_group_set,
    109 };
    110 
    111 static const struct udevice_id ast2500_pinctrl_ids[] = {
    112 	{ .compatible = "aspeed,ast2500-pinctrl" },
    113 	{ .compatible = "aspeed,g5-pinctrl" },
    114 	{ }
    115 };
    116 
    117 U_BOOT_DRIVER(pinctrl_ast2500) = {
    118 	.name = "aspeed_ast2500_pinctrl",
    119 	.id = UCLASS_PINCTRL,
    120 	.of_match = ast2500_pinctrl_ids,
    121 	.priv_auto_alloc_size = sizeof(struct ast2500_pinctrl_priv),
    122 	.ops = &ast2500_pinctrl_ops,
    123 	.probe = ast2500_pinctrl_probe,
    124 };
    125