Skip to content

Commit 6dec659

Browse files
feckertlag-linaro
authored andcommitted
leds: ledtrig-tty: Add additional line state evaluation
The serial tty interface also supports additional input signals, that can also be evaluated within this trigger. This change is adding the following additional input sources, which could be controlled via the '/sys/class/<leds>/' sysfs interface. Explanation: DCE = Data Communication Equipment (Modem) DTE = Data Terminal Equipment (Computer) - cts: DCE is ready to accept data from the DTE (CTS = Clear To Send). If the line state is detected, the LED is switched on. If set to 0 (default), the LED will not evaluate CTS. If set to 1, the LED will evaluate CTS. - dsr: DCE is ready to receive and send data (DSR = Data Set Ready). If the line state is detected, the LED is switched on. If set to 0 (default), the LED will not evaluate DSR. If set to 1, the LED will evaluate DSR. - dcd: DTE is receiving a carrier from the DCE (DCD = Data Carrier Detect). If the line state is detected, the LED is switched on. If set to 0 (default), the LED will not evaluate DCD. If set to 1, the LED will evaluate DCD. - rng: DCE has detected an incoming ring signal on the telephone line (RNG = Ring Indicator). If the line state is detected, the LED is switched on. If set to 0 (default), the LED will not evaluate RNG. If set to 1, the LED will evaluate RNG. Also add an invert flag on LED blink, so that the LED blinks in the correct order. * If one off the new enabled input signals are evaluatet as 'enabled', and data are transmitted, then the LED should first blink 'off' and then 'on' (invert). * If all the new enabled input signals are evaluatet as 'disabled', and data are transmitted, then the LED should first blink 'on' and then 'off'. Signed-off-by: Florian Eckert <fe@dev.tdt.de> Reviewed-by: Maarten Brock <m.brock@vanmierlo.com> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Link: https://lore.kernel.org/r/20231127110311.3583957-5-fe@dev.tdt.de Signed-off-by: Lee Jones <lee@kernel.org>
1 parent 5b755ca commit 6dec659

File tree

2 files changed

+117
-1
lines changed

2 files changed

+117
-1
lines changed

Documentation/ABI/testing/sysfs-class-led-trigger-tty

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,43 @@ Description:
2020
Signal transmission (tx) of data on the named tty device.
2121
If set to 0, the LED will not blink on transmission.
2222
If set to 1 (default), the LED will blink on transmission.
23+
24+
What: /sys/class/leds/<led>/cts
25+
Date: February 2024
26+
KernelVersion: 6.8
27+
Description:
28+
CTS = Clear To Send
29+
DCE is ready to accept data from the DTE.
30+
If the line state is detected, the LED is switched on.
31+
If set to 0 (default), the LED will not evaluate CTS.
32+
If set to 1, the LED will evaluate CTS.
33+
34+
What: /sys/class/leds/<led>/dsr
35+
Date: February 2024
36+
KernelVersion: 6.8
37+
Description:
38+
DSR = Data Set Ready
39+
DCE is ready to receive and send data.
40+
If the line state is detected, the LED is switched on.
41+
If set to 0 (default), the LED will not evaluate DSR.
42+
If set to 1, the LED will evaluate DSR.
43+
44+
What: /sys/class/leds/<led>/dcd
45+
Date: February 2024
46+
KernelVersion: 6.8
47+
Description:
48+
DCD = Data Carrier Detect
49+
DTE is receiving a carrier from the DCE.
50+
If the line state is detected, the LED is switched on.
51+
If set to 0 (default), the LED will not evaluate CAR (DCD).
52+
If set to 1, the LED will evaluate CAR (DCD).
53+
54+
What: /sys/class/leds/<led>/rng
55+
Date: February 2024
56+
KernelVersion: 6.8
57+
Description:
58+
RNG = Ring Indicator
59+
DCE has detected an incoming ring signal on the telephone
60+
line. If the line state is detected, the LED is switched on.
61+
If set to 0 (default), the LED will not evaluate RNG.
62+
If set to 1, the LED will evaluate RNG.

drivers/leds/trigger/ledtrig-tty.c

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,26 @@ struct ledtrig_tty_data {
1919
int rx, tx;
2020
bool mode_rx;
2121
bool mode_tx;
22+
bool mode_cts;
23+
bool mode_dsr;
24+
bool mode_dcd;
25+
bool mode_rng;
2226
};
2327

2428
/* Indicates which state the LED should now display */
2529
enum led_trigger_tty_state {
2630
TTY_LED_BLINK,
31+
TTY_LED_ENABLE,
2732
TTY_LED_DISABLE,
2833
};
2934

3035
enum led_trigger_tty_modes {
3136
TRIGGER_TTY_RX = 0,
3237
TRIGGER_TTY_TX,
38+
TRIGGER_TTY_CTS,
39+
TRIGGER_TTY_DSR,
40+
TRIGGER_TTY_DCD,
41+
TRIGGER_TTY_RNG,
3342
};
3443

3544
static int ledtrig_tty_wait_for_completion(struct device *dev)
@@ -111,6 +120,18 @@ static ssize_t ledtrig_tty_attr_show(struct device *dev, char *buf,
111120
case TRIGGER_TTY_TX:
112121
state = trigger_data->mode_tx;
113122
break;
123+
case TRIGGER_TTY_CTS:
124+
state = trigger_data->mode_cts;
125+
break;
126+
case TRIGGER_TTY_DSR:
127+
state = trigger_data->mode_dsr;
128+
break;
129+
case TRIGGER_TTY_DCD:
130+
state = trigger_data->mode_dcd;
131+
break;
132+
case TRIGGER_TTY_RNG:
133+
state = trigger_data->mode_rng;
134+
break;
114135
}
115136

116137
return sysfs_emit(buf, "%u\n", state);
@@ -134,6 +155,18 @@ static ssize_t ledtrig_tty_attr_store(struct device *dev, const char *buf,
134155
case TRIGGER_TTY_TX:
135156
trigger_data->mode_tx = state;
136157
break;
158+
case TRIGGER_TTY_CTS:
159+
trigger_data->mode_cts = state;
160+
break;
161+
case TRIGGER_TTY_DSR:
162+
trigger_data->mode_dsr = state;
163+
break;
164+
case TRIGGER_TTY_DCD:
165+
trigger_data->mode_dcd = state;
166+
break;
167+
case TRIGGER_TTY_RNG:
168+
trigger_data->mode_rng = state;
169+
break;
137170
}
138171

139172
return size;
@@ -154,13 +187,19 @@ static ssize_t ledtrig_tty_attr_store(struct device *dev, const char *buf,
154187

155188
DEFINE_TTY_TRIGGER(rx, TRIGGER_TTY_RX);
156189
DEFINE_TTY_TRIGGER(tx, TRIGGER_TTY_TX);
190+
DEFINE_TTY_TRIGGER(cts, TRIGGER_TTY_CTS);
191+
DEFINE_TTY_TRIGGER(dsr, TRIGGER_TTY_DSR);
192+
DEFINE_TTY_TRIGGER(dcd, TRIGGER_TTY_DCD);
193+
DEFINE_TTY_TRIGGER(rng, TRIGGER_TTY_RNG);
157194

158195
static void ledtrig_tty_work(struct work_struct *work)
159196
{
160197
struct ledtrig_tty_data *trigger_data =
161198
container_of(work, struct ledtrig_tty_data, dwork.work);
162199
enum led_trigger_tty_state state = TTY_LED_DISABLE;
163200
unsigned long interval = LEDTRIG_TTY_INTERVAL;
201+
bool invert = false;
202+
int status;
164203
int ret;
165204

166205
if (!trigger_data->ttyname)
@@ -188,6 +227,33 @@ static void ledtrig_tty_work(struct work_struct *work)
188227
trigger_data->tty = tty;
189228
}
190229

230+
status = tty_get_tiocm(trigger_data->tty);
231+
if (status > 0) {
232+
if (trigger_data->mode_cts) {
233+
if (status & TIOCM_CTS)
234+
state = TTY_LED_ENABLE;
235+
}
236+
237+
if (trigger_data->mode_dsr) {
238+
if (status & TIOCM_DSR)
239+
state = TTY_LED_ENABLE;
240+
}
241+
242+
if (trigger_data->mode_dcd) {
243+
if (status & TIOCM_CAR)
244+
state = TTY_LED_ENABLE;
245+
}
246+
247+
if (trigger_data->mode_rng) {
248+
if (status & TIOCM_RNG)
249+
state = TTY_LED_ENABLE;
250+
}
251+
}
252+
253+
/*
254+
* The evaluation of rx/tx must be done after the evaluation
255+
* of TIOCM_*, because rx/tx has priority.
256+
*/
191257
if (trigger_data->mode_rx || trigger_data->mode_tx) {
192258
struct serial_icounter_struct icount;
193259

@@ -197,11 +263,13 @@ static void ledtrig_tty_work(struct work_struct *work)
197263

198264
if (trigger_data->mode_tx && (icount.tx != trigger_data->tx)) {
199265
trigger_data->tx = icount.tx;
266+
invert = state == TTY_LED_ENABLE;
200267
state = TTY_LED_BLINK;
201268
}
202269

203270
if (trigger_data->mode_rx && (icount.rx != trigger_data->rx)) {
204271
trigger_data->rx = icount.rx;
272+
invert = state == TTY_LED_ENABLE;
205273
state = TTY_LED_BLINK;
206274
}
207275
}
@@ -210,7 +278,11 @@ static void ledtrig_tty_work(struct work_struct *work)
210278
switch (state) {
211279
case TTY_LED_BLINK:
212280
led_blink_set_oneshot(trigger_data->led_cdev, &interval,
213-
&interval, 0);
281+
&interval, invert);
282+
break;
283+
case TTY_LED_ENABLE:
284+
led_set_brightness(trigger_data->led_cdev,
285+
trigger_data->led_cdev->blink_brightness);
214286
break;
215287
case TTY_LED_DISABLE:
216288
fallthrough;
@@ -228,6 +300,10 @@ static struct attribute *ledtrig_tty_attrs[] = {
228300
&dev_attr_ttyname.attr,
229301
&dev_attr_rx.attr,
230302
&dev_attr_tx.attr,
303+
&dev_attr_cts.attr,
304+
&dev_attr_dsr.attr,
305+
&dev_attr_dcd.attr,
306+
&dev_attr_rng.attr,
231307
NULL
232308
};
233309
ATTRIBUTE_GROUPS(ledtrig_tty);

0 commit comments

Comments
 (0)