Skip to content

Commit 344c9c6

Browse files
RuibinChangcarlescufi
authored andcommitted
ITE drivers/pinctrl/it8xxx2: extend pinctrl driver for kscan pins
Extend pinctrl driver for kscan pins. Signed-off-by: Ruibin Chang <[email protected]>
1 parent d7f482a commit 344c9c6

File tree

6 files changed

+422
-96
lines changed

6 files changed

+422
-96
lines changed

drivers/pinctrl/pinctrl_ite_it8xxx2.c

Lines changed: 211 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ LOG_MODULE_REGISTER(pinctrl_ite_it8xxx2, LOG_LEVEL_ERR);
1717
((struct gpio_it8xxx2_regs *)DT_REG_ADDR(DT_NODELABEL(gpiogcr)))
1818
#define GPIO_GROUP_MEMBERS 8
1919

20-
struct pinctrl_it8xxx2_config {
20+
struct pinctrl_it8xxx2_gpio {
2121
/* gpio port control register (byte mapping to pin) */
2222
uint8_t *reg_gpcr;
2323
/* function 3 general control register */
@@ -34,13 +34,42 @@ struct pinctrl_it8xxx2_config {
3434
uint8_t volt_sel_mask[GPIO_GROUP_MEMBERS];
3535
};
3636

37+
struct pinctrl_it8xxx2_ksi_kso {
38+
/*
39+
* KSI[7:0]/KSO[15:8]/KSO[7:0] port gpio control register
40+
* (bit mapping to pin)
41+
*/
42+
uint8_t *reg_gctrl;
43+
/* KSI[7:0]/KSO[15:8]/KSO[7:0] port control register */
44+
uint8_t *reg_ctrl;
45+
/*
46+
* KSO push-pull/open-drain bit of KSO[15:0] control register
47+
* (this bit apply to all pins)
48+
*/
49+
int pp_od_mask;
50+
/*
51+
* KSI/KSO pullup bit of KSI[7:0]/KSO[15:0] control register
52+
* (this bit apply to all pins)
53+
*/
54+
int pullup_mask;
55+
};
56+
57+
struct pinctrl_it8xxx2_config {
58+
bool gpio_group;
59+
union {
60+
struct pinctrl_it8xxx2_gpio gpio;
61+
struct pinctrl_it8xxx2_ksi_kso ksi_kso;
62+
};
63+
};
64+
3765
static int pinctrl_it8xxx2_set(const pinctrl_soc_pin_t *pins)
3866
{
3967
const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
68+
const struct pinctrl_it8xxx2_gpio *gpio = &(pinctrl_config->gpio);
4069
uint32_t pincfg = pins->pincfg;
4170
uint8_t pin = pins->pin;
42-
volatile uint8_t *reg_gpcr = (uint8_t *)pinctrl_config->reg_gpcr + pin;
43-
volatile uint8_t *reg_volt_sel = (uint8_t *)(pinctrl_config->volt_sel[pin]);
71+
volatile uint8_t *reg_gpcr = (uint8_t *)gpio->reg_gpcr + pin;
72+
volatile uint8_t *reg_volt_sel = (uint8_t *)(gpio->volt_sel[pin]);
4473

4574
/* Setting pull-up or pull-down. */
4675
switch (IT8XXX2_DT_PINCFG_PUPDR(pincfg)) {
@@ -66,14 +95,14 @@ static int pinctrl_it8xxx2_set(const pinctrl_soc_pin_t *pins)
6695
switch (IT8XXX2_DT_PINCFG_VOLTAGE(pincfg)) {
6796
case IT8XXX2_VOLTAGE_3V3:
6897
/* Input voltage selection 3.3V. */
69-
*reg_volt_sel &= ~pinctrl_config->volt_sel_mask[pin];
98+
*reg_volt_sel &= ~gpio->volt_sel_mask[pin];
7099
break;
71100
case IT8XXX2_VOLTAGE_1V8:
72101
__ASSERT(!(IT8XXX2_DT_PINCFG_PUPDR(pincfg)
73102
== IT8XXX2_PULL_UP),
74103
"Don't enable internal pullup if 1.8V voltage is used");
75104
/* Input voltage selection 1.8V. */
76-
*reg_volt_sel |= pinctrl_config->volt_sel_mask[pin];
105+
*reg_volt_sel |= gpio->volt_sel_mask[pin];
77106
break;
78107
default:
79108
LOG_ERR("The voltage selection is not supported");
@@ -89,79 +118,164 @@ static int pinctrl_it8xxx2_set(const pinctrl_soc_pin_t *pins)
89118
return 0;
90119
}
91120

92-
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
93-
uintptr_t reg)
121+
static int pinctrl_gpio_it8xxx2_configure_pins(const pinctrl_soc_pin_t *pins)
94122
{
95-
ARG_UNUSED(reg);
123+
const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
124+
const struct pinctrl_it8xxx2_gpio *gpio = &(pinctrl_config->gpio);
125+
uint8_t pin = pins->pin;
126+
volatile uint8_t *reg_gpcr = (uint8_t *)gpio->reg_gpcr + pin;
127+
volatile uint8_t *reg_func3_gcr = (uint8_t *)(gpio->func3_gcr[pin]);
128+
volatile uint8_t *reg_func4_gcr = (uint8_t *)(gpio->func4_gcr[pin]);
96129

97-
const struct pinctrl_it8xxx2_config *pinctrl_config;
98-
volatile uint8_t *reg_gpcr;
99-
volatile uint8_t *reg_func3_gcr;
100-
volatile uint8_t *reg_func4_gcr;
101-
uint8_t pin;
130+
/* Handle PIN configuration. */
131+
if (pinctrl_it8xxx2_set(pins)) {
132+
LOG_ERR("Pin configuration is invalid.");
133+
return -EINVAL;
134+
}
102135

103-
for (uint8_t i = 0U; i < pin_cnt; i++) {
104-
pinctrl_config = pins[i].pinctrls->config;
105-
pin = pins[i].pin;
106-
reg_gpcr = (uint8_t *)pinctrl_config->reg_gpcr + pin;
107-
reg_func3_gcr = (uint8_t *)(pinctrl_config->func3_gcr[pin]);
108-
reg_func4_gcr = (uint8_t *)(pinctrl_config->func4_gcr[pin]);
109-
110-
/* Handle PIN configuration. */
111-
if (pinctrl_it8xxx2_set(&pins[i])) {
112-
LOG_ERR("Pin configuration is invalid.");
113-
return -EINVAL;
114-
}
136+
/*
137+
* If pincfg is input, we don't need to handle
138+
* alternate function.
139+
*/
140+
if (IT8XXX2_DT_PINCFG_INPUT(pins->pincfg)) {
141+
*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) &
142+
~GPCR_PORT_PIN_MODE_OUTPUT;
143+
return 0;
144+
}
115145

146+
/*
147+
* Handle alternate function.
148+
*/
149+
/* Common settings for alternate function. */
150+
*reg_gpcr &= ~(GPCR_PORT_PIN_MODE_INPUT |
151+
GPCR_PORT_PIN_MODE_OUTPUT);
152+
switch (pins->alt_func) {
153+
case IT8XXX2_ALT_FUNC_1:
154+
/* Func1: Alternate function has been set above. */
155+
break;
156+
case IT8XXX2_ALT_FUNC_2:
157+
/* Func2: WUI function: turn the pin into an input */
158+
*reg_gpcr |= GPCR_PORT_PIN_MODE_INPUT;
159+
break;
160+
case IT8XXX2_ALT_FUNC_3:
116161
/*
117-
* If pincfg is input, we don't need to handle
118-
* alternate function.
162+
* Func3: In addition to the alternate setting above,
163+
* Func3 also need to set the general control.
119164
*/
120-
if (IT8XXX2_DT_PINCFG_INPUT(pins[i].pincfg)) {
121-
*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) &
122-
~GPCR_PORT_PIN_MODE_OUTPUT;
123-
continue;
124-
}
125-
165+
*reg_func3_gcr |= gpio->func3_en_mask[pin];
166+
break;
167+
case IT8XXX2_ALT_FUNC_4:
126168
/*
127-
* Handle alternate function.
169+
* Func4: In addition to the alternate setting above,
170+
* Func4 also need to set the general control.
128171
*/
129-
/* Common settings for alternate function. */
130-
*reg_gpcr &= ~(GPCR_PORT_PIN_MODE_INPUT |
131-
GPCR_PORT_PIN_MODE_OUTPUT);
132-
switch (pins[i].alt_func) {
133-
case IT8XXX2_ALT_FUNC_1:
134-
/* Func1: Alternate function has been set above. */
135-
break;
136-
case IT8XXX2_ALT_FUNC_2:
137-
/* Func2: WUI function: turn the pin into an input */
138-
*reg_gpcr |= GPCR_PORT_PIN_MODE_INPUT;
139-
break;
140-
case IT8XXX2_ALT_FUNC_3:
141-
/*
142-
* Func3: In addition to the alternate setting above,
143-
* Func3 also need to set the general control.
144-
*/
145-
*reg_func3_gcr |= pinctrl_config->func3_en_mask[pin];
146-
break;
147-
case IT8XXX2_ALT_FUNC_4:
148-
/*
149-
* Func4: In addition to the alternate setting above,
150-
* Func4 also need to set the general control.
151-
*/
152-
*reg_func4_gcr |= pinctrl_config->func4_en_mask[pin];
172+
*reg_func4_gcr |= gpio->func4_en_mask[pin];
173+
break;
174+
case IT8XXX2_ALT_DEFAULT:
175+
*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) &
176+
~GPCR_PORT_PIN_MODE_OUTPUT;
177+
*reg_func3_gcr &= ~gpio->func3_en_mask[pin];
178+
*reg_func4_gcr &= ~gpio->func4_en_mask[pin];
179+
break;
180+
default:
181+
LOG_ERR("This function is not supported.");
182+
return -EINVAL;
183+
}
184+
185+
return 0;
186+
}
187+
188+
static int pinctrl_kscan_it8xxx2_set(const pinctrl_soc_pin_t *pins)
189+
{
190+
const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
191+
const struct pinctrl_it8xxx2_ksi_kso *ksi_kso = &(pinctrl_config->ksi_kso);
192+
volatile uint8_t *reg_ctrl = ksi_kso->reg_ctrl;
193+
uint8_t pullup_mask = ksi_kso->pullup_mask;
194+
uint8_t pp_od_mask = ksi_kso->pp_od_mask;
195+
uint32_t pincfg = pins->pincfg;
196+
197+
/*
198+
* Enable or disable internal pull-up (this bit apply to all pins):
199+
* If KSI[7:0]/KSO[15:0] is in KBS mode , setting 1 enables the internal
200+
* pull-up (KSO[17:16] setting internal pull-up by GPIO port GPCR register).
201+
* If KSI[7:0]/KSO[15:0] is in GPIO mode, then this bit is always disabled.
202+
*/
203+
switch (IT8XXX2_DT_PINCFG_PULLUP(pincfg)) {
204+
case IT8XXX2_PULL_PIN_DEFAULT:
205+
/* Disable internal pulll-up */
206+
*reg_ctrl &= ~pullup_mask;
207+
break;
208+
case IT8XXX2_PULL_UP:
209+
*reg_ctrl |= pullup_mask;
210+
break;
211+
default:
212+
LOG_ERR("This pull level is not supported.");
213+
return -EINVAL;
214+
}
215+
216+
/*
217+
* Set push-pull or open-drain mode (this bit apply to all pins):
218+
* KSI[7:0] doesn't support push-pull and open-drain settings in kbs mode.
219+
* If KSO[17:0] is in KBS mode, setting 1 selects open-drain mode,
220+
* setting 0 selects push-pull mode.
221+
* If KSO[15:0] is in GPIO mode, then this bit is always disabled.
222+
*/
223+
if (pp_od_mask != NO_FUNC) {
224+
switch (IT8XXX2_DT_PINCFG_PP_OD(pincfg)) {
225+
case IT8XXX2_PUSH_PULL:
226+
*reg_ctrl &= ~pp_od_mask;
153227
break;
154-
case IT8XXX2_ALT_DEFAULT:
155-
*reg_gpcr = (*reg_gpcr | GPCR_PORT_PIN_MODE_INPUT) &
156-
~GPCR_PORT_PIN_MODE_OUTPUT;
157-
*reg_func3_gcr &= ~pinctrl_config->func3_en_mask[pin];
158-
*reg_func4_gcr &= ~pinctrl_config->func4_en_mask[pin];
228+
case IT8XXX2_OPEN_DRAIN:
229+
*reg_ctrl |= pp_od_mask;
159230
break;
160231
default:
161-
LOG_ERR("This function is not supported.");
232+
LOG_ERR("This pull mode is not supported.");
162233
return -EINVAL;
163234
}
235+
}
164236

237+
return 0;
238+
}
239+
240+
static int pinctrl_kscan_it8xxx2_configure_pins(const pinctrl_soc_pin_t *pins)
241+
{
242+
const struct pinctrl_it8xxx2_config *pinctrl_config = pins->pinctrls->config;
243+
const struct pinctrl_it8xxx2_ksi_kso *ksi_kso = &(pinctrl_config->ksi_kso);
244+
volatile uint8_t *reg_gctrl = ksi_kso->reg_gctrl;
245+
uint8_t pin_mask = BIT(pins->pin);
246+
247+
/* Set a pin of KSI[7:0]/KSO[15:0] to pullup, push-pull/open-drain */
248+
if (pinctrl_kscan_it8xxx2_set(pins)) {
249+
return -EINVAL;
250+
}
251+
252+
/* Set a pin of KSI[7:0]/KSO[15:0] to kbs mode */
253+
*reg_gctrl &= ~pin_mask;
254+
255+
return 0;
256+
}
257+
258+
int pinctrl_configure_pins(const pinctrl_soc_pin_t *pins, uint8_t pin_cnt,
259+
uintptr_t reg)
260+
{
261+
ARG_UNUSED(reg);
262+
const struct pinctrl_it8xxx2_config *pinctrl_config;
263+
int status;
264+
265+
for (uint8_t i = 0U; i < pin_cnt; i++) {
266+
pinctrl_config = pins[i].pinctrls->config;
267+
268+
if (pinctrl_config->gpio_group) {
269+
status = pinctrl_gpio_it8xxx2_configure_pins(&pins[i]);
270+
} else {
271+
status = pinctrl_kscan_it8xxx2_configure_pins(&pins[i]);
272+
}
273+
274+
if (status < 0) {
275+
LOG_ERR("%s pin%d configuration is invalid.",
276+
pins[i].pinctrls->name, pins[i].pin);
277+
return status;
278+
}
165279
}
166280

167281
return 0;
@@ -186,23 +300,38 @@ static int pinctrl_it8xxx2_init(const struct device *dev)
186300
return 0;
187301
}
188302

189-
#define PINCTRL_ITE_INIT(inst) \
190-
static const struct pinctrl_it8xxx2_config pinctrl_it8xxx2_cfg_##inst = { \
191-
.reg_gpcr = (uint8_t *)DT_INST_REG_ADDR(inst), \
192-
.func3_gcr = DT_INST_PROP(inst, func3_gcr), \
193-
.func3_en_mask = DT_INST_PROP(inst, func3_en_mask), \
194-
.func4_gcr = DT_INST_PROP(inst, func4_gcr), \
195-
.func4_en_mask = DT_INST_PROP(inst, func4_en_mask), \
196-
.volt_sel = DT_INST_PROP(inst, volt_sel), \
197-
.volt_sel_mask = DT_INST_PROP(inst, volt_sel_mask), \
198-
}; \
199-
\
200-
DEVICE_DT_INST_DEFINE(inst, &pinctrl_it8xxx2_init, \
201-
NULL, \
202-
NULL, \
203-
&pinctrl_it8xxx2_cfg_##inst, \
204-
PRE_KERNEL_1, \
205-
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
206-
NULL);
303+
#define INIT_UNION_CONFIG(inst) \
304+
COND_CODE_1(DT_INST_PROP(inst, gpio_group), \
305+
(.gpio = { \
306+
.reg_gpcr = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0), \
307+
.func3_gcr = DT_INST_PROP(inst, func3_gcr), \
308+
.func3_en_mask = DT_INST_PROP(inst, func3_en_mask), \
309+
.func4_gcr = DT_INST_PROP(inst, func4_gcr), \
310+
.func4_en_mask = DT_INST_PROP(inst, func4_en_mask), \
311+
.volt_sel = DT_INST_PROP(inst, volt_sel), \
312+
.volt_sel_mask = DT_INST_PROP(inst, volt_sel_mask), \
313+
}), \
314+
(.ksi_kso = { \
315+
.reg_gctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 0), \
316+
.reg_ctrl = (uint8_t *)DT_INST_REG_ADDR_BY_IDX(inst, 1), \
317+
.pp_od_mask = (uint8_t)DT_INST_PROP(inst, pp_od_mask), \
318+
.pullup_mask = (uint8_t)DT_INST_PROP(inst, pullup_mask), \
319+
}) \
320+
)
207321

322+
#define PINCTRL_ITE_INIT(inst) \
323+
static const struct pinctrl_it8xxx2_config pinctrl_it8xxx2_cfg_##inst = { \
324+
.gpio_group = DT_INST_PROP(inst, gpio_group), \
325+
{ \
326+
INIT_UNION_CONFIG(inst) \
327+
} \
328+
}; \
329+
\
330+
DEVICE_DT_INST_DEFINE(inst, &pinctrl_it8xxx2_init, \
331+
NULL, \
332+
NULL, \
333+
&pinctrl_it8xxx2_cfg_##inst, \
334+
PRE_KERNEL_1, \
335+
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
336+
NULL);
208337
DT_INST_FOREACH_STATUS_OKAY(PINCTRL_ITE_INIT)

0 commit comments

Comments
 (0)