Skip to content

Commit ad320ee

Browse files
JasonLin-RealTekjhedberg
authored andcommitted
driver: input: implement input PM function
Add the pm device for rts5912 input driver Signed-off-by: Lin Yu-Cheng <[email protected]>
1 parent ffdf184 commit ad320ee

File tree

3 files changed

+241
-39
lines changed

3 files changed

+241
-39
lines changed

boards/realtek/rts5912_evb/rts5912_evb.dts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,19 @@
5959
&ksi2_gpio066 &ksi3_gpio067
6060
&ksi4_gpio068 &ksi5_gpio069
6161
&ksi6_gpio070 &ksi7_gpio071>;
62-
pinctrl-names = "default";
62+
pinctrl-1 = <&kso0_sleep_gpio041 &kso1_sleep_gpio042
63+
&kso2_sleep_gpio043 &kso3_sleep_gpio044
64+
&kso4_sleep_gpio045 &kso5_sleep_gpio046
65+
&kso6_sleep_gpio047 &kso7_sleep_gpio048
66+
&kso8_sleep_gpio049 &kso9_sleep_gpio050
67+
&kso10_sleep_gpio051 &kso11_sleep_gpio055
68+
&kso12_sleep_gpio056 &kso13_sleep_gpio057
69+
&kso14_sleep_gpio058 &kso15_sleep_gpio059
70+
&ksi0_gpio064 &ksi1_gpio065
71+
&ksi2_gpio066 &ksi3_gpio067
72+
&ksi4_gpio068 &ksi5_gpio069
73+
&ksi6_gpio070 &ksi7_gpio071>;
74+
pinctrl-names = "default", "sleep";
6375
row-size = <8>;
6476
col-size = <16>;
6577
};

drivers/input/input_realtek_rts5912_kbd.c

Lines changed: 122 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,11 @@ LOG_MODULE_REGISTER(input_realtek_rts5912_kbd, CONFIG_INPUT_LOG_LEVEL);
2020

2121
struct rts5912_kbd_config {
2222
struct input_kbd_matrix_common_config common;
23-
/* Keyboard scan controller base address */
2423
volatile struct kbm_regs *base;
25-
/* Keyboard scan input (KSI) wake-up irq */
2624
uint32_t irq;
27-
/* KSI/KSO keyboard scan alternate configuration */
2825
const struct pinctrl_dev_config *pcfg;
2926
const struct device *clk_dev;
3027
struct rts5912_sccon_subsys sccon_cfg;
31-
/* For user ignore specific pin of kso*/
3228
uint32_t kso_ignore_mask;
3329
};
3430

@@ -47,18 +43,14 @@ static void rts5912_kbd_drive_column(const struct device *dev, int col)
4743
uint32_t kso_val;
4844
uint32_t key;
4945

50-
/* Tri-state all outputs */
5146
if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_NONE) {
5247
kso_val = kso_mask;
53-
/* Assert all outputs */
5448
} else if (col == INPUT_KBD_MATRIX_COLUMN_DRIVE_ALL) {
5549
kso_val = 0;
56-
/* Assert a single output */
5750
} else {
5851
kso_val = kso_mask ^ BIT(col);
5952
}
6053

61-
/* Set KSO output data */
6254
key = irq_lock();
6355
inst->scan_out = kso_val;
6456
irq_unlock(key);
@@ -71,7 +63,6 @@ static kbd_row_t rts5912_kbd_read_row(const struct device *dev)
7163
const struct input_kbd_matrix_common_config *common = &config->common;
7264
const uint32_t ksi_mask = BIT_MASK(common->row_size);
7365

74-
/* Bits are active-low, so toggle it (return 1 means key pressed) */
7566
return (inst->scan_in ^ ksi_mask);
7667
}
7768

@@ -85,7 +76,6 @@ static void rts5912_intc_isr_clear(const struct device *dev)
8576

8677
static void rts5912_kbd_isr(const struct device *dev)
8778
{
88-
/* W/C interrupt status of KSI pins */
8979
rts5912_intc_isr_clear(dev);
9080
input_kbd_matrix_poll_start(dev);
9181
}
@@ -95,7 +85,6 @@ static void rts5912_kbd_set_detect_mode(const struct device *dev, bool enable)
9585
const struct rts5912_kbd_config *config = dev->config;
9686

9787
if (enable) {
98-
/* W/C interrupt status of KSI pins */
9988
rts5912_intc_isr_clear(dev);
10089

10190
irq_enable(config->irq);
@@ -114,74 +103,169 @@ static int rts5912_kbd_init(const struct device *dev)
114103
const uint32_t kso_mask = BIT_MASK(common->col_size) & ~config->kso_ignore_mask;
115104
const uint32_t ksi_mask = BIT_MASK(common->row_size);
116105

117-
uint32_t status;
106+
int ret;
118107

119-
/* Disable wakeup and interrupt of KSI pins before configuring */
120108
rts5912_kbd_set_detect_mode(dev, false);
121109

122-
/*
123-
* Enable the internal pull-up and kbs mode of the KSI pins.
124-
* Enable the internal pull-up and kbs mode of the KSO pins.
125-
* Enable the open-drain mode of the KSO pins.
126-
*/
127-
status = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
128-
if (status < 0) {
129-
LOG_ERR("Failed to configure KSI and KSO pins");
130-
return status;
110+
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
111+
if (ret < 0) {
112+
LOG_ERR("Failed to configure KSI and KSO pins: %d", ret);
113+
return ret;
131114
}
132115

133116
if (!device_is_ready(config->clk_dev)) {
134117
LOG_ERR("clock kbd device not ready");
135118
return -ENODEV;
136119
}
137120

138-
status = clock_control_on(config->clk_dev, (clock_control_subsys_t)&config->sccon_cfg);
139-
if (status != 0) {
140-
LOG_ERR("kbd clock power on fail");
141-
return status;
121+
ret = clock_control_on(config->clk_dev, (clock_control_subsys_t)&config->sccon_cfg);
122+
if (ret != 0) {
123+
LOG_ERR("kbd clock power on fail: %d", ret);
124+
return ret;
142125
}
143126

144-
/* KSO pins output low */
145127
inst->scan_out = 0x00;
146128

147-
/* Enable KSI 8 if RAW Size more than 8*/
148129
if (ksi_mask & BIT(8)) {
149130
inst->ctrl |= KBM_CTRL_KSI8EN_Msk;
150131
}
151132

152-
/* Enable KSI 9 if RAW Size more than 9*/
153133
if (ksi_mask & BIT(9)) {
154134
inst->ctrl |= KBM_CTRL_KSI9EN_Msk;
155135
}
156136

157-
/* Enable KSO 18 if COL Size more than 18*/
158137
if (kso_mask & BIT(18)) {
159138
inst->ctrl |= KBM_CTRL_KSO18EN_Msk;
160139
}
161140

162-
/* Enable KSO 19 if COL Size more than 19*/
163141
if (kso_mask & BIT(19)) {
164142
inst->ctrl |= KBM_CTRL_KSO19EN_Msk;
165143
}
166144

167-
/* Enable KSO OpenDrain Output Type */
168145
inst->ctrl |= KBM_CTRL_KSOTYPE_Msk;
169146

170-
/* Enable Scan Interrupt*/
171147
inst->int_en |= ksi_mask;
172148

173-
/* W/C interrupt status of KSI pins */
174149
rts5912_intc_isr_clear(dev);
175150

176151
NVIC_ClearPendingIRQ(DT_INST_IRQN(0));
177152

178-
/* Interrupts are enabled in the thread function */
179-
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
180-
rts5912_kbd_isr, DEVICE_DT_INST_GET(0), 0);
153+
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), rts5912_kbd_isr,
154+
DEVICE_DT_INST_GET(0), 0);
181155

182156
return input_kbd_matrix_common_init(dev);
183157
}
184158

159+
#if defined(CONFIG_PM_DEVICE)
160+
static int input_kbd_matrix_pm_action_suspend(const struct device *dev)
161+
{
162+
const struct rts5912_kbd_config *config = dev->config;
163+
const struct input_kbd_matrix_common_config *common = &config->common;
164+
volatile struct kbm_regs *inst = config->base;
165+
const uint32_t kso_mask = BIT_MASK(common->col_size) & ~config->kso_ignore_mask;
166+
int ret;
167+
168+
ret = clock_control_off(config->clk_dev, (clock_control_subsys_t)&config->sccon_cfg);
169+
if (ret != 0) {
170+
LOG_ERR("clock_control_off failed: %d", ret);
171+
return ret;
172+
}
173+
inst->int_en = 0;
174+
175+
rts5912_intc_isr_clear(dev);
176+
177+
if (kso_mask & BIT(18)) {
178+
inst->ctrl &= ~KBM_CTRL_KSO18EN_Msk;
179+
}
180+
181+
if (kso_mask & BIT(19)) {
182+
inst->ctrl &= ~KBM_CTRL_KSO19EN_Msk;
183+
}
184+
185+
inst->scan_out = 0x00;
186+
inst->ctrl &= ~KBM_CTRL_KSOTYPE_Msk;
187+
188+
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_SLEEP);
189+
if (ret < 0) {
190+
LOG_ERR("pinctrl_apply_state failed: %d", ret);
191+
return ret;
192+
}
193+
194+
return 0;
195+
}
196+
197+
static int input_kbd_matrix_pm_action_resume(const struct device *dev)
198+
{
199+
const struct rts5912_kbd_config *config = dev->config;
200+
const struct input_kbd_matrix_common_config *common = &config->common;
201+
volatile struct kbm_regs *inst = config->base;
202+
const uint32_t kso_mask = BIT_MASK(common->col_size) & ~config->kso_ignore_mask;
203+
const uint32_t ksi_mask = BIT_MASK(common->row_size);
204+
int ret;
205+
206+
ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
207+
if (ret < 0) {
208+
LOG_ERR("pinctrl_apply_state failed: %d", ret);
209+
return ret;
210+
}
211+
inst->ctrl |= KBM_CTRL_KSOTYPE_Msk;
212+
213+
inst->scan_out = 0x00;
214+
215+
if (kso_mask & BIT(18)) {
216+
inst->ctrl |= KBM_CTRL_KSO18EN_Msk;
217+
}
218+
219+
if (kso_mask & BIT(19)) {
220+
inst->ctrl |= KBM_CTRL_KSO19EN_Msk;
221+
}
222+
inst->int_en |= ksi_mask;
223+
ret = clock_control_on(config->clk_dev, (clock_control_subsys_t)&config->sccon_cfg);
224+
if (ret != 0) {
225+
LOG_ERR("clock_control_on failed: %d", ret);
226+
return ret;
227+
}
228+
229+
return 0;
230+
}
231+
232+
static int input_kbd_matrix_pm_action_rts5912(const struct device *dev,
233+
enum pm_device_action action)
234+
{
235+
int ret;
236+
237+
switch (action) {
238+
case PM_DEVICE_ACTION_RESUME:
239+
ret = input_kbd_matrix_pm_action_resume(dev);
240+
if (ret != 0) {
241+
LOG_ERR("kbd rts5912 resume fail: %d", ret);
242+
return ret;
243+
}
244+
ret = input_kbd_matrix_pm_action(dev, action);
245+
if (ret != 0) {
246+
LOG_ERR("kbd pm resume fail: %d", ret);
247+
return ret;
248+
}
249+
break;
250+
case PM_DEVICE_ACTION_SUSPEND:
251+
ret = input_kbd_matrix_pm_action_suspend(dev);
252+
if (ret != 0) {
253+
LOG_ERR("kbd rts5912 suspend fail: %d", ret);
254+
return ret;
255+
}
256+
ret = input_kbd_matrix_pm_action(dev, action);
257+
if (ret != 0) {
258+
LOG_ERR("kbd pm suspend fail: %d", ret);
259+
return ret;
260+
}
261+
break;
262+
default:
263+
return -ENOTSUP;
264+
}
265+
266+
return 0;
267+
}
268+
#endif
185269
PINCTRL_DT_INST_DEFINE(0);
186270

187271
INPUT_KBD_MATRIX_DT_INST_DEFINE(0);
@@ -207,7 +291,7 @@ static const struct rts5912_kbd_config rts5912_kbd_cfg_0 = {
207291

208292
static struct rts5912_kbd_data rts5912_kbd_data_0;
209293

210-
PM_DEVICE_DT_INST_DEFINE(0, input_kbd_matrix_pm_action);
294+
PM_DEVICE_DT_INST_DEFINE(0, input_kbd_matrix_pm_action_rts5912);
211295

212296
DEVICE_DT_INST_DEFINE(0, &rts5912_kbd_init, PM_DEVICE_DT_INST_GET(0), &rts5912_kbd_data_0,
213297
&rts5912_kbd_cfg_0, POST_KERNEL, CONFIG_INPUT_INIT_PRIORITY, NULL);

dts/arm/realtek/ec/rts5912-pinctrl.dtsi

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,112 @@
449449
};
450450

451451
/* KSO PINCTRL SETTING END */
452+
/* KSO PINCTRL SLEEP SETTING START */
453+
/omit-if-no-ref/ kso0_sleep_gpio041: kso0_sleep_gpio041 {
454+
pinmux = <REALTEK_RTS5912_PINMUX(41, FUNC0)>;
455+
output-enable;
456+
output-low;
457+
};
458+
/omit-if-no-ref/ kso1_sleep_gpio042: kso1_sleep_gpio042 {
459+
pinmux = <REALTEK_RTS5912_PINMUX(42, FUNC0)>;
460+
output-enable;
461+
output-low;
462+
};
463+
/omit-if-no-ref/ kso2_sleep_gpio043: kso2_sleep_gpio043 {
464+
pinmux = <REALTEK_RTS5912_PINMUX(43, FUNC0)>;
465+
output-enable;
466+
output-low;
467+
};
468+
/omit-if-no-ref/ kso3_sleep_gpio044: kso3_sleep_gpio044 {
469+
pinmux = <REALTEK_RTS5912_PINMUX(44, FUNC0)>;
470+
output-enable;
471+
output-low;
472+
};
473+
474+
/omit-if-no-ref/ kso4_sleep_gpio045: kso4_sleep_gpio045 {
475+
pinmux = <REALTEK_RTS5912_PINMUX(45, FUNC0)>;
476+
output-enable;
477+
output-low;
478+
};
479+
/omit-if-no-ref/ kso5_sleep_gpio046: kso5_sleep_gpio046 {
480+
pinmux = <REALTEK_RTS5912_PINMUX(46, FUNC0)>;
481+
output-enable;
482+
output-low;
483+
};
484+
/omit-if-no-ref/ kso6_sleep_gpio047: kso6_sleep_gpio047 {
485+
pinmux = <REALTEK_RTS5912_PINMUX(47, FUNC0)>;
486+
output-enable;
487+
output-low;
488+
};
489+
/omit-if-no-ref/ kso7_sleep_gpio048: kso7_sleep_gpio048 {
490+
pinmux = <REALTEK_RTS5912_PINMUX(48, FUNC0)>;
491+
output-enable;
492+
output-low;
493+
};
494+
495+
/omit-if-no-ref/ kso8_sleep_gpio049: kso8_sleep_gpio049 {
496+
pinmux = <REALTEK_RTS5912_PINMUX(49, FUNC0)>;
497+
output-enable;
498+
output-low;
499+
};
500+
/omit-if-no-ref/ kso9_sleep_gpio050: kso9_sleep_gpio050 {
501+
pinmux = <REALTEK_RTS5912_PINMUX(50, FUNC0)>;
502+
output-enable;
503+
output-low;
504+
};
505+
/omit-if-no-ref/ kso10_sleep_gpio051: kso10_sleep_gpio051 {
506+
pinmux = <REALTEK_RTS5912_PINMUX(51, FUNC0)>;
507+
output-enable;
508+
output-low;
509+
};
510+
/omit-if-no-ref/ kso11_sleep_gpio055: kso11_sleep_gpio055 {
511+
pinmux = <REALTEK_RTS5912_PINMUX(55, FUNC0)>;
512+
output-enable;
513+
output-low;
514+
};
515+
516+
/omit-if-no-ref/ kso12_sleep_gpio056: kso12_sleep_gpio056 {
517+
pinmux = <REALTEK_RTS5912_PINMUX(56, FUNC0)>;
518+
output-enable;
519+
output-low;
520+
};
521+
/omit-if-no-ref/ kso13_sleep_gpio057: kso13_sleep_gpio057 {
522+
pinmux = <REALTEK_RTS5912_PINMUX(57, FUNC0)>;
523+
output-enable;
524+
output-low;
525+
};
526+
/omit-if-no-ref/ kso14_sleep_gpio058: kso14_sleep_gpio058 {
527+
pinmux = <REALTEK_RTS5912_PINMUX(58, FUNC0)>;
528+
output-enable;
529+
output-low;
530+
};
531+
/omit-if-no-ref/ kso15_sleep_gpio059: kso15_sleep_gpio059 {
532+
pinmux = <REALTEK_RTS5912_PINMUX(59, FUNC0)>;
533+
output-enable;
534+
output-low;
535+
};
536+
537+
/omit-if-no-ref/ kso16_sleep_gpio060: kso16_sleep_gpio060 {
538+
pinmux = <REALTEK_RTS5912_PINMUX(60, FUNC0)>;
539+
output-enable;
540+
output-low;
541+
};
542+
/omit-if-no-ref/ kso17_sleep_gpio061: kso17_sleep_gpio061 {
543+
pinmux = <REALTEK_RTS5912_PINMUX(61, FUNC0)>;
544+
output-enable;
545+
output-low;
546+
};
547+
/omit-if-no-ref/ kso18_sleep_gpio092: kso18_sleep_gpio092 {
548+
pinmux = <REALTEK_RTS5912_PINMUX(92, FUNC0)>;
549+
output-enable;
550+
output-low;
551+
};
552+
/omit-if-no-ref/ kso19_sleep_gpio093: kso19_sleep_gpio093 {
553+
pinmux = <REALTEK_RTS5912_PINMUX(93, FUNC0)>;
554+
output-enable;
555+
output-low;
556+
};
557+
/* KSO PINCTRL SLEEP SETTING END */
452558
/* KSI PINCTRL SETTING START */
453559
/omit-if-no-ref/ ksi0_gpio064: ksi0_gpio064 {
454560
pinmux = <REALTEK_RTS5912_PINMUX(64, FUNC1)>;

0 commit comments

Comments
 (0)