Skip to content

Commit b4c3960

Browse files
elkablolag-linaro
authored andcommitted
leds: turris-omnia: Use command execution functions from the MCU driver
Use the MCU command execution functions from the MCU driver instead of the ad-hoc implementation in the LED driver. This allows as to drop the LED driver implementation, which is a duplicate. Signed-off-by: Marek Behún <kabel@kernel.org> Link: https://lore.kernel.org/r/20241111100355.6978-3-kabel@kernel.org Signed-off-by: Lee Jones <lee@kernel.org>
1 parent 082e8f6 commit b4c3960

File tree

2 files changed

+55
-83
lines changed

2 files changed

+55
-83
lines changed

drivers/leds/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ config LEDS_TURRIS_OMNIA
217217
depends on I2C
218218
depends on MACH_ARMADA_38X || COMPILE_TEST
219219
depends on OF
220+
depends on TURRIS_OMNIA_MCU
220221
select LEDS_TRIGGERS
221222
help
222223
This option enables basic support for the LEDs found on the front

drivers/leds/leds-turris-omnia.c

Lines changed: 54 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
/*
33
* CZ.NIC's Turris Omnia LEDs driver
44
*
5-
* 2020, 2023 by Marek Behún <kabel@kernel.org>
5+
* 2020, 2023, 2024 by Marek Behún <kabel@kernel.org>
66
*/
77

88
#include <linux/i2c.h>
99
#include <linux/led-class-multicolor.h>
1010
#include <linux/module.h>
1111
#include <linux/mutex.h>
1212
#include <linux/of.h>
13+
#include <linux/turris-omnia-mcu-interface.h>
1314

1415
#define OMNIA_BOARD_LEDS 12
1516
#define OMNIA_LED_NUM_CHANNELS 3
@@ -56,66 +57,21 @@ struct omnia_leds {
5657
struct omnia_led leds[];
5758
};
5859

59-
static int omnia_cmd_write_u8(const struct i2c_client *client, u8 cmd, u8 val)
60+
static int omnia_cmd_set_color(const struct i2c_client *client, u8 led, u8 r, u8 g, u8 b)
6061
{
61-
u8 buf[2] = { cmd, val };
62-
int ret;
63-
64-
ret = i2c_master_send(client, buf, sizeof(buf));
62+
u8 buf[5] = { CMD_LED_COLOR, led, r, g, b };
6563

66-
return ret < 0 ? ret : 0;
67-
}
68-
69-
static int omnia_cmd_read_raw(struct i2c_adapter *adapter, u8 addr, u8 cmd,
70-
void *reply, size_t len)
71-
{
72-
struct i2c_msg msgs[2];
73-
int ret;
74-
75-
msgs[0].addr = addr;
76-
msgs[0].flags = 0;
77-
msgs[0].len = 1;
78-
msgs[0].buf = &cmd;
79-
msgs[1].addr = addr;
80-
msgs[1].flags = I2C_M_RD;
81-
msgs[1].len = len;
82-
msgs[1].buf = reply;
83-
84-
ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
85-
if (likely(ret == ARRAY_SIZE(msgs)))
86-
return 0;
87-
else if (ret < 0)
88-
return ret;
89-
else
90-
return -EIO;
91-
}
92-
93-
static int omnia_cmd_read_u8(const struct i2c_client *client, u8 cmd)
94-
{
95-
u8 reply;
96-
int err;
97-
98-
err = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1);
99-
if (err)
100-
return err;
101-
102-
return reply;
64+
return omnia_cmd_write(client, buf, sizeof(buf));
10365
}
10466

10567
static int omnia_led_send_color_cmd(const struct i2c_client *client,
10668
struct omnia_led *led)
10769
{
108-
char cmd[5];
10970
int ret;
11071

111-
cmd[0] = CMD_LED_COLOR;
112-
cmd[1] = led->reg;
113-
cmd[2] = led->subled_info[0].brightness;
114-
cmd[3] = led->subled_info[1].brightness;
115-
cmd[4] = led->subled_info[2].brightness;
116-
11772
/* Send the color change command */
118-
ret = i2c_master_send(client, cmd, 5);
73+
ret = omnia_cmd_set_color(client, led->reg, led->subled_info[0].brightness,
74+
led->subled_info[1].brightness, led->subled_info[2].brightness);
11975
if (ret < 0)
12076
return ret;
12177

@@ -351,14 +307,14 @@ static ssize_t brightness_show(struct device *dev, struct device_attribute *a,
351307
char *buf)
352308
{
353309
struct i2c_client *client = to_i2c_client(dev);
354-
int ret;
355-
356-
ret = omnia_cmd_read_u8(client, CMD_LED_GET_BRIGHTNESS);
310+
u8 reply;
311+
int err;
357312

358-
if (ret < 0)
359-
return ret;
313+
err = omnia_cmd_read_u8(client, CMD_LED_GET_BRIGHTNESS, &reply);
314+
if (err < 0)
315+
return err;
360316

361-
return sysfs_emit(buf, "%d\n", ret);
317+
return sysfs_emit(buf, "%d\n", reply);
362318
}
363319

364320
static ssize_t brightness_store(struct device *dev, struct device_attribute *a,
@@ -385,17 +341,16 @@ static ssize_t gamma_correction_show(struct device *dev,
385341
{
386342
struct i2c_client *client = to_i2c_client(dev);
387343
struct omnia_leds *leds = i2c_get_clientdata(client);
388-
int ret;
344+
u8 reply = 0;
345+
int err;
389346

390347
if (leds->has_gamma_correction) {
391-
ret = omnia_cmd_read_u8(client, CMD_GET_GAMMA_CORRECTION);
392-
if (ret < 0)
393-
return ret;
394-
} else {
395-
ret = 0;
348+
err = omnia_cmd_read_u8(client, CMD_GET_GAMMA_CORRECTION, &reply);
349+
if (err < 0)
350+
return err;
396351
}
397352

398-
return sysfs_emit(buf, "%d\n", !!ret);
353+
return sysfs_emit(buf, "%d\n", !!reply);
399354
}
400355

401356
static ssize_t gamma_correction_store(struct device *dev,
@@ -426,26 +381,51 @@ static struct attribute *omnia_led_controller_attrs[] = {
426381
};
427382
ATTRIBUTE_GROUPS(omnia_led_controller);
428383

429-
static int omnia_mcu_get_features(const struct i2c_client *client)
384+
static int omnia_mcu_get_features(const struct i2c_client *mcu_client)
430385
{
431386
u16 reply;
432387
int err;
433388

434-
err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
435-
CMD_GET_STATUS_WORD, &reply, sizeof(reply));
389+
err = omnia_cmd_read_u16(mcu_client, CMD_GET_STATUS_WORD, &reply);
436390
if (err)
437391
return err;
438392

439393
/* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */
440-
if (!(le16_to_cpu(reply) & STS_FEATURES_SUPPORTED))
394+
if (!(reply & STS_FEATURES_SUPPORTED))
441395
return 0;
442396

443-
err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR,
444-
CMD_GET_FEATURES, &reply, sizeof(reply));
397+
err = omnia_cmd_read_u16(mcu_client, CMD_GET_FEATURES, &reply);
445398
if (err)
446399
return err;
447400

448-
return le16_to_cpu(reply);
401+
return reply;
402+
}
403+
404+
static int omnia_match_mcu_client(struct device *dev, void *data)
405+
{
406+
struct i2c_client *client;
407+
408+
client = i2c_verify_client(dev);
409+
if (!client)
410+
return 0;
411+
412+
return client->addr == OMNIA_MCU_I2C_ADDR;
413+
}
414+
415+
static int omnia_find_mcu_and_get_features(struct device *dev)
416+
{
417+
struct device *mcu_dev;
418+
int ret;
419+
420+
mcu_dev = device_find_child(dev->parent, NULL, omnia_match_mcu_client);
421+
if (!mcu_dev)
422+
return -ENODEV;
423+
424+
ret = omnia_mcu_get_features(i2c_verify_client(mcu_dev));
425+
426+
put_device(mcu_dev);
427+
428+
return ret;
449429
}
450430

451431
static int omnia_leds_probe(struct i2c_client *client)
@@ -472,7 +452,7 @@ static int omnia_leds_probe(struct i2c_client *client)
472452
leds->client = client;
473453
i2c_set_clientdata(client, leds);
474454

475-
ret = omnia_mcu_get_features(client);
455+
ret = omnia_find_mcu_and_get_features(dev);
476456
if (ret < 0) {
477457
dev_err(dev, "Cannot determine MCU supported features: %d\n",
478458
ret);
@@ -509,20 +489,11 @@ static int omnia_leds_probe(struct i2c_client *client)
509489

510490
static void omnia_leds_remove(struct i2c_client *client)
511491
{
512-
u8 buf[5];
513-
514492
/* put all LEDs into default (HW triggered) mode */
515-
omnia_cmd_write_u8(client, CMD_LED_MODE,
516-
CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
493+
omnia_cmd_write_u8(client, CMD_LED_MODE, CMD_LED_MODE_LED(OMNIA_BOARD_LEDS));
517494

518495
/* set all LEDs color to [255, 255, 255] */
519-
buf[0] = CMD_LED_COLOR;
520-
buf[1] = OMNIA_BOARD_LEDS;
521-
buf[2] = 255;
522-
buf[3] = 255;
523-
buf[4] = 255;
524-
525-
i2c_master_send(client, buf, 5);
496+
omnia_cmd_set_color(client, OMNIA_BOARD_LEDS, 255, 255, 255);
526497
}
527498

528499
static const struct of_device_id of_omnia_leds_match[] = {

0 commit comments

Comments
 (0)