1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/platform_device.h>
#include "core.h"
#define SCU 0x1e6e2000
#define SCU80 (SCU + 0x80)
#define SCU84 (SCU + 0x84)
#define SCU88 (SCU + 0x88)
#define SCU90 (SCU + 0x90)
#define SCU94 (SCU + 0x94)
struct ast_pinctrl_desc {
uint32_t *c1_reg;
uint32_t c1_mask;
uint32_t *c2_reg;
uint32_t c2_mask;
};
#define DEF_AST_PIN(name, a, b, c, d) \
static struct ast_pinctrl_desc BALL_##name = {(u32 *) a, b, c, d}
DEF_AST_PIN(D6, SCU80, BIT_MASK(0), NULL, 0);
DEF_AST_PIN(B5, SCU80, BIT_MASK(1), NULL, 0);
DEF_AST_PIN(A4, SCU80, BIT_MASK(2), NULL, 0);
DEF_AST_PIN(E6, SCU80, BIT_MASK(3), NULL, 0);
DEF_AST_PIN(C5, SCU90, BIT_MASK(22), NULL, 0);
DEF_AST_PIN(B4, SCU90, BIT_MASK(22), NULL, 0);
DEF_AST_PIN(A3, SCU90, BIT_MASK(2), NULL, 0);
DEF_AST_PIN(D5, SCU90, BIT_MASK(2), NULL, 0);
#define AST_PIN_DESC(n, pinname) \
{ .number = n, .name = "pinname", .drv_data = &BALL_##pinname }
static const struct pinctrl_pin_desc ast2400_pins[] = {
AST_PIN_DESC(0, D6),
AST_PIN_DESC(1, B5),
AST_PIN_DESC(2, A4),
AST_PIN_DESC(3, E6),
AST_PIN_DESC(4, C5),
AST_PIN_DESC(5, B4),
AST_PIN_DESC(6, A3),
AST_PIN_DESC(7, D5),
};
static const unsigned int i2c9_pins[] = { 4, 5 };
struct ast_pin_group {
const char *name;
const unsigned int *pins;
const unsigned num_pins;
};
static const struct ast_pin_group ast_pin_groups[] = {
{
.name = "i2c9",
.pins = i2c9_pins,
.num_pins = ARRAY_SIZE(i2c9_pins),
},
};
static int ast_get_groups_count(struct pinctrl_dev *pctl)
{
return ARRAY_SIZE(ast_pin_groups);
}
static const char *ast_get_group_name(struct pinctrl_dev *pctl,
unsigned selector)
{
return ast_pin_groups[selector].name;
}
static int ast_get_group_pins(struct pinctrl_dev *pctl, unsigned selector,
const unsigned **pins, unsigned *num_pins)
{
*pins = (unsigned *)ast_pin_groups[selector].pins;
*num_pins = ast_pin_groups[selector].num_pins;
return 0;
}
static struct pinctrl_ops ast_pinctrl_ops = {
.get_groups_count = ast_get_groups_count,
.get_group_name = ast_get_group_name,
.get_group_pins = ast_get_group_pins,
};
static int ast_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long *config)
{
dev_err(pctldev->dev, "Unimplemented function %s\n", __func__);
return -ENOTSUPP;
}
static int ast_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *configs, unsigned num_configs)
{
struct ast_pinctrl_desc *desc;
if (pin >= pctldev->desc->npins) {
dev_err(pctldev->dev, "pin number %d is too damn high\n",
pin);
return -ERANGE;
}
desc = pctldev->desc->pins[pin].drv_data;
dev_err(pctldev->dev, "Unimplemented function %s\n", __func__);
return -ENOTSUPP;
}
static struct pinconf_ops ast_pconf_ops = {
.pin_config_get = ast_pinconf_get,
.pin_config_set = ast_pinconf_set,
};
struct ast_pinctrl {
struct device *dev;
struct pinctrl_dev *pctl;
};
struct pinctrl_desc ast_desc = {
.name = "Aspeed",
.pins = ast2400_pins,
.npins = ARRAY_SIZE(ast2400_pins),
.pctlops = &ast_pinctrl_ops,
.confops = &ast_pconf_ops,
.owner = THIS_MODULE,
};
struct aspeed_pinctrl {
struct device *dev;
void __iomem *base;
struct pinctrl_dev *pctl_dev;
};
int ast_pinctrl_probe(struct platform_device *pdev)
{
struct aspeed_pinctrl *pctl;
struct resource *res;
pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
if (!pctl)
return -ENOMEM;
platform_set_drvdata(pdev, pctl);
pctl->dev = &pdev->dev;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
pctl->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(pctl->base))
return PTR_ERR(pctl->base);
pctl->pctl_dev = pinctrl_register(&ast_desc, &pdev->dev, pctl);
if (!pctl->dev) {
pr_err("could not register apseed pin driver\n");
return -EIO;
}
return 0;
}
|