Add pinctrl support for broadcom bcm6838 SoC. Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>lime2-spi
parent
9dc8d155d4
commit
b3f8e88f3c
@ -0,0 +1,35 @@ |
|||||||
|
* broadcom bcm6838 pinctrl |
||||||
|
|
||||||
|
Required properties for the pinctrl driver: |
||||||
|
- compatible: "brcm,bcm6838-pinctrl" |
||||||
|
- regmap: specify the gpio test port syscon |
||||||
|
- brcm,pins-count: the number of pin |
||||||
|
- brcm,functions-count: the number of function |
||||||
|
|
||||||
|
Please refer to pinctrl-bindings.txt in this directory for details of the |
||||||
|
common pinctrl bindings used by client devices. |
||||||
|
|
||||||
|
Example: |
||||||
|
|
||||||
|
gpio_test_port: syscon@14e00294 { |
||||||
|
compatible = "syscon"; |
||||||
|
reg = <0x14e00294 0x1c>; |
||||||
|
}; |
||||||
|
|
||||||
|
pinctrl: pinctrl { |
||||||
|
compatible = "brcm,bcm6838-pinctrl"; |
||||||
|
regmap = <&gpio_test_port>; |
||||||
|
brcm,pins-count = <74>; |
||||||
|
brcm,functions-count = <8>; |
||||||
|
|
||||||
|
usb0: usb0 { |
||||||
|
usb0_pwrflt { |
||||||
|
pins = "69"; |
||||||
|
function = "1"; |
||||||
|
}; |
||||||
|
usb0_pwron { |
||||||
|
pins = "70"; |
||||||
|
function = "1"; |
||||||
|
}; |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,161 @@ |
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
|
||||||
|
#include <common.h> |
||||||
|
#include <dm.h> |
||||||
|
#include <regmap.h> |
||||||
|
#include <syscon.h> |
||||||
|
#include <dm/pinctrl.h> |
||||||
|
|
||||||
|
#define BCM6838_CMD_LOAD_MUX 0x21 |
||||||
|
|
||||||
|
#define BCM6838_FUNC_OFFS 12 |
||||||
|
#define BCM6838_FUNC_MASK (0x37 << BCM6838_FUNC_OFFS) |
||||||
|
#define BCM6838_PIN_OFFS 0 |
||||||
|
#define BCM6838_PIN_MASK (0xfff << BCM6838_PIN_OFFS) |
||||||
|
|
||||||
|
#define BCM6838_MAX_PIN_NAME_LEN 8 |
||||||
|
static char bcm6838_pin_name[BCM6838_MAX_PIN_NAME_LEN]; |
||||||
|
|
||||||
|
#define BCM6838_MAX_FUNC_NAME_LEN 8 |
||||||
|
static char bcm6838_func_name[BCM6838_MAX_FUNC_NAME_LEN]; |
||||||
|
|
||||||
|
struct bcm6838_test_port_hw { |
||||||
|
unsigned long port_blk_data1; |
||||||
|
unsigned long port_blk_data2; |
||||||
|
unsigned long port_command; |
||||||
|
}; |
||||||
|
|
||||||
|
static const struct bcm6838_test_port_hw bcm6838_hw = { |
||||||
|
.port_blk_data1 = 0x10, |
||||||
|
.port_blk_data2 = 0x14, |
||||||
|
.port_command = 0x18 |
||||||
|
}; |
||||||
|
|
||||||
|
struct bcm6838_pinctrl_priv { |
||||||
|
const struct bcm6838_test_port_hw *hw; |
||||||
|
struct regmap *regmap; |
||||||
|
u32 pins_count; |
||||||
|
u32 functions_count; |
||||||
|
}; |
||||||
|
|
||||||
|
int bcm6838_pinctrl_get_pins_count(struct udevice *dev) |
||||||
|
{ |
||||||
|
struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev); |
||||||
|
|
||||||
|
return priv->pins_count; |
||||||
|
} |
||||||
|
|
||||||
|
const char *bcm6838_pinctrl_get_pin_name(struct udevice *dev, |
||||||
|
unsigned int selector) |
||||||
|
{ |
||||||
|
snprintf(bcm6838_pin_name, BCM6838_MAX_PIN_NAME_LEN, "%u", selector); |
||||||
|
return bcm6838_pin_name; |
||||||
|
} |
||||||
|
|
||||||
|
int bcm6838_pinctrl_get_functions_count(struct udevice *dev) |
||||||
|
{ |
||||||
|
struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev); |
||||||
|
|
||||||
|
return priv->functions_count; |
||||||
|
} |
||||||
|
|
||||||
|
const char *bcm6838_pinctrl_get_function_name(struct udevice *dev, |
||||||
|
unsigned int selector) |
||||||
|
{ |
||||||
|
snprintf(bcm6838_func_name, BCM6838_MAX_FUNC_NAME_LEN, "%u", selector); |
||||||
|
return bcm6838_func_name; |
||||||
|
} |
||||||
|
|
||||||
|
int bcm6838_pinctrl_pinmux_set(struct udevice *dev, |
||||||
|
unsigned int pin_selector, |
||||||
|
unsigned int func_selector) |
||||||
|
{ |
||||||
|
struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev); |
||||||
|
const struct bcm6838_test_port_hw *hw = priv->hw; |
||||||
|
unsigned int data; |
||||||
|
|
||||||
|
regmap_write(priv->regmap, hw->port_blk_data1, 0); |
||||||
|
data = (func_selector << BCM6838_FUNC_OFFS) & BCM6838_FUNC_MASK; |
||||||
|
data |= (pin_selector << BCM6838_PIN_OFFS) & BCM6838_PIN_MASK; |
||||||
|
regmap_write(priv->regmap, hw->port_blk_data2, data); |
||||||
|
regmap_write(priv->regmap, hw->port_command, BCM6838_CMD_LOAD_MUX); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
int bcm6838_pinctrl_probe(struct udevice *dev) |
||||||
|
{ |
||||||
|
struct bcm6838_pinctrl_priv *priv = dev_get_priv(dev); |
||||||
|
const struct bcm6838_test_port_hw *hw = |
||||||
|
(const struct bcm6838_test_port_hw *)dev_get_driver_data(dev); |
||||||
|
int err; |
||||||
|
u32 phandle; |
||||||
|
ofnode node; |
||||||
|
|
||||||
|
err = ofnode_read_u32(dev_ofnode(dev), "regmap", &phandle); |
||||||
|
if (err) { |
||||||
|
dev_err(dev, "%s: unable to read regmap\n", __func__); |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
node = ofnode_get_by_phandle(phandle); |
||||||
|
if (!ofnode_valid(node)) { |
||||||
|
dev_err(dev, "%s: unable to find node\n", __func__); |
||||||
|
err = -EINVAL; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
priv->regmap = syscon_node_to_regmap(node); |
||||||
|
if (!priv->regmap) { |
||||||
|
dev_err(dev, "%s: unable to find regmap\n", __func__); |
||||||
|
err = -ENODEV; |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
err = ofnode_read_u32(dev_ofnode(dev), "brcm,pins-count", |
||||||
|
&priv->pins_count); |
||||||
|
if (err) { |
||||||
|
dev_err(dev, "%s: unable to read brcm,pins-count\n", |
||||||
|
__func__); |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
err = ofnode_read_u32(dev_ofnode(dev), "brcm,functions-count", |
||||||
|
&priv->functions_count); |
||||||
|
if (err) { |
||||||
|
dev_err(dev, "%s: unable to read brcm,functions-count\n", |
||||||
|
__func__); |
||||||
|
goto out; |
||||||
|
} |
||||||
|
|
||||||
|
priv->hw = hw; |
||||||
|
|
||||||
|
out: |
||||||
|
return err; |
||||||
|
} |
||||||
|
|
||||||
|
const struct pinctrl_ops bcm6838_pinctrl_ops = { |
||||||
|
.set_state = pinctrl_generic_set_state, |
||||||
|
.get_pins_count = bcm6838_pinctrl_get_pins_count, |
||||||
|
.get_pin_name = bcm6838_pinctrl_get_pin_name, |
||||||
|
.get_functions_count = bcm6838_pinctrl_get_functions_count, |
||||||
|
.get_function_name = bcm6838_pinctrl_get_function_name, |
||||||
|
.pinmux_set = bcm6838_pinctrl_pinmux_set, |
||||||
|
}; |
||||||
|
|
||||||
|
static const struct udevice_id bcm6838_pinctrl_match[] = { |
||||||
|
{ |
||||||
|
.compatible = "brcm,bcm6838-pinctrl", |
||||||
|
.data = (ulong)&bcm6838_hw, |
||||||
|
}, |
||||||
|
{ /* sentinel */ } |
||||||
|
}; |
||||||
|
|
||||||
|
U_BOOT_DRIVER(bcm6838_pinctrl) = { |
||||||
|
.name = "bcm6838_pinctrl", |
||||||
|
.id = UCLASS_PINCTRL, |
||||||
|
.of_match = bcm6838_pinctrl_match, |
||||||
|
.ops = &bcm6838_pinctrl_ops, |
||||||
|
.priv_auto_alloc_size = sizeof(struct bcm6838_pinctrl_priv), |
||||||
|
.probe = bcm6838_pinctrl_probe, |
||||||
|
}; |
Loading…
Reference in new issue