Skip to content

Commit aee4613

Browse files
committed
cmd: Add vibrator command
1 parent fbad9f7 commit aee4613

3 files changed

Lines changed: 156 additions & 0 deletions

File tree

cmd/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,16 @@ config CMD_PVBLOCK
15671567
help
15681568
Xen para-virtualized block device support
15691569

1570+
config CMD_VIBRATOR
1571+
bool "vibrator"
1572+
depends on VIBRATOR
1573+
default y if VIBRATOR
1574+
help
1575+
Enable the 'vibrator' command which allows for control of vibrator
1576+
motors available on the board. The vibrator motors can be listed with
1577+
'vibrator list' and controlled with vibrator on/off/time. Any
1578+
vibrator driver can be controlled with this command.
1579+
15701580
config CMD_VIRTIO
15711581
bool "virtio"
15721582
depends on VIRTIO

cmd/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ obj-$(CONFIG_CMD_UBIFS) += ubifs.o
183183
obj-$(CONFIG_CMD_UNIVERSE) += universe.o
184184
obj-$(CONFIG_CMD_UNLZ4) += unlz4.o
185185
obj-$(CONFIG_CMD_UNZIP) += unzip.o
186+
obj-$(CONFIG_CMD_VIBRATOR) += vibrator.o
186187
obj-$(CONFIG_CMD_VIRTIO) += virtio.o
187188
obj-$(CONFIG_CMD_WDT) += wdt.o
188189
obj-$(CONFIG_CMD_LZMADEC) += lzmadec.o

cmd/vibrator.c

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* Copyright (c) 2021 Samuel Dionne-Riel <samuel@dionne-riel.com>
4+
* Copyright (c) 2017 Google, Inc
5+
* Largely derived from `cmd/led.c`
6+
* Original written by Simon Glass <sjg@chromium.org>
7+
*/
8+
9+
#include <common.h>
10+
#include <command.h>
11+
#include <dm.h>
12+
#include <vibrator.h>
13+
#include <dm/uclass-internal.h>
14+
15+
static const char *const state_label[] = {
16+
[VIBRATOR_STATE_OFF] = "off",
17+
[VIBRATOR_STATE_ON] = "on",
18+
[VIBRATOR_STATE_TOGGLE] = "toggle",
19+
};
20+
21+
enum vibrator_state_t get_vibrator_cmd(char *var)
22+
{
23+
int i;
24+
25+
for (i = 0; i < VIBRATOR_STATE_COUNT; i++) {
26+
if (!strncmp(var, state_label[i], strlen(var)))
27+
return i;
28+
}
29+
30+
return -1;
31+
}
32+
33+
static int show_vibrator_state(struct udevice *dev)
34+
{
35+
int ret;
36+
37+
ret = vibrator_get_state(dev);
38+
if (ret >= VIBRATOR_STATE_COUNT)
39+
ret = -EINVAL;
40+
if (ret >= 0)
41+
printf("%s\n", state_label[ret]);
42+
43+
return ret;
44+
}
45+
46+
static int list_vibrators(void)
47+
{
48+
struct udevice *dev;
49+
int ret;
50+
51+
for (uclass_find_first_device(UCLASS_VIBRATOR, &dev);
52+
dev;
53+
uclass_find_next_device(&dev)) {
54+
struct vibrator_uc_plat *plat = dev_get_uclass_plat(dev);
55+
56+
if (!plat->label)
57+
continue;
58+
printf("%-15s ", plat->label);
59+
if (device_active(dev)) {
60+
ret = show_vibrator_state(dev);
61+
if (ret < 0)
62+
printf("Error %d\n", ret);
63+
} else {
64+
printf("<inactive>\n");
65+
}
66+
}
67+
68+
return 0;
69+
}
70+
71+
int timed_vibration(struct udevice *dev, int duration_ms)
72+
{
73+
int ret;
74+
ret = vibrator_set_state(dev, VIBRATOR_STATE_ON);
75+
if (ret < 0) {
76+
printf("Vibrator operation failed (err=%d)\n", ret);
77+
return CMD_RET_FAILURE;
78+
}
79+
80+
udelay(duration_ms * 1000);
81+
82+
ret = vibrator_set_state(dev, VIBRATOR_STATE_OFF);
83+
if (ret < 0) {
84+
printf("Vibrator operation failed (err=%d)\n", ret);
85+
return CMD_RET_FAILURE;
86+
}
87+
}
88+
89+
int do_vibrator(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
90+
{
91+
enum vibrator_state_t cmd;
92+
const char *vibrator_label;
93+
struct udevice *dev;
94+
int ret;
95+
int duration_ms = 0;
96+
97+
/* Validate arguments */
98+
if (argc < 2)
99+
return CMD_RET_USAGE;
100+
vibrator_label = argv[1];
101+
if (strncmp(vibrator_label, "list", 4) == 0)
102+
return list_vibrators();
103+
104+
cmd = argc > 2 ? get_vibrator_cmd(argv[2]) : VIBRATOR_STATE_COUNT;
105+
ret = vibrator_get_by_label(vibrator_label, &dev);
106+
if (ret) {
107+
printf("Vibrator '%s' not found (err=%d)\n", vibrator_label, ret);
108+
return CMD_RET_FAILURE;
109+
}
110+
111+
if (strncmp(argv[2], "timed", 5) == 0) {
112+
if (argc < 4)
113+
return CMD_RET_USAGE;
114+
duration_ms = dectoul(argv[3], NULL);
115+
116+
return timed_vibration(dev, duration_ms);
117+
}
118+
119+
switch (cmd) {
120+
case VIBRATOR_STATE_OFF:
121+
case VIBRATOR_STATE_ON:
122+
case VIBRATOR_STATE_TOGGLE:
123+
ret = vibrator_set_state(dev, cmd);
124+
break;
125+
case VIBRATOR_STATE_COUNT:
126+
printf("Vibrator '%s': ", vibrator_label);
127+
ret = show_vibrator_state(dev);
128+
break;
129+
}
130+
if (ret < 0) {
131+
printf("Vibrator '%s' operation failed (err=%d)\n", vibrator_label, ret);
132+
return CMD_RET_FAILURE;
133+
}
134+
135+
return 0;
136+
}
137+
138+
U_BOOT_CMD(
139+
vibrator, 4, 1, do_vibrator,
140+
"manage VIBRATORs",
141+
"<vibrator_label> on|off\tChange VIBRATOR state\n"
142+
"vibrator <vibrator_label> timed <ms duration>\t\tVibrate for the given duration (will block)\n"
143+
"vibrator <vibrator_label>\tGet VIBRATOR state\n"
144+
"vibrator list\t\tShow a list of VIBRATORs"
145+
);

0 commit comments

Comments
 (0)