Lines Matching +full:turris +full:- +full:omnia +full:- +full:mcu

1 // SPDX-License-Identifier: GPL-2.0
3 * CZ.NIC's Turris Omnia LEDs driver
9 #include <linux/led-class-multicolor.h>
18 /* MCU controller commands at I2C address 0x2a */
91 return -EIO; in omnia_cmd_read_raw()
99 err = omnia_cmd_read_raw(client->adapter, client->addr, cmd, &reply, 1); in omnia_cmd_read_u8()
113 cmd[1] = led->reg; in omnia_led_send_color_cmd()
114 cmd[2] = led->subled_info[0].brightness; in omnia_led_send_color_cmd()
115 cmd[3] = led->subled_info[1].brightness; in omnia_led_send_color_cmd()
116 cmd[4] = led->subled_info[2].brightness; in omnia_led_send_color_cmd()
125 led->cached_channels[i] = led->subled_info[i].brightness; in omnia_led_send_color_cmd()
134 if (led->subled_info[i].brightness != led->cached_channels[i]) in omnia_led_channels_changed()
144 struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); in omnia_led_brightness_set_blocking()
148 mutex_lock(&leds->lock); in omnia_led_brightness_set_blocking()
152 * non-zero (if it is zero and the LED is in HW blinking mode, we use in omnia_led_brightness_set_blocking()
154 * we can save ourselves some software divisions (Omnia's CPU does not in omnia_led_brightness_set_blocking()
157 if (brightness || led->hwtrig) { in omnia_led_brightness_set_blocking()
159 cdev->max_brightness); in omnia_led_brightness_set_blocking()
162 * Send color command only if brightness is non-zero and the RGB in omnia_led_brightness_set_blocking()
166 err = omnia_led_send_color_cmd(leds->client, led); in omnia_led_brightness_set_blocking()
173 if (!err && !led->hwtrig && !brightness != !led->on) { in omnia_led_brightness_set_blocking()
174 u8 state = CMD_LED_STATE_LED(led->reg); in omnia_led_brightness_set_blocking()
179 err = omnia_cmd_write_u8(leds->client, CMD_LED_STATE, state); in omnia_led_brightness_set_blocking()
181 led->on = !!brightness; in omnia_led_brightness_set_blocking()
184 mutex_unlock(&leds->lock); in omnia_led_brightness_set_blocking()
194 struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); in omnia_hwtrig_activate()
198 mutex_lock(&leds->lock); in omnia_hwtrig_activate()
200 if (!led->on) { in omnia_hwtrig_activate()
203 * configured color was not necessarily sent to the MCU. in omnia_hwtrig_activate()
206 led_mc_calc_color_components(mc_cdev, cdev->max_brightness); in omnia_hwtrig_activate()
209 err = omnia_led_send_color_cmd(leds->client, led); in omnia_hwtrig_activate()
213 /* Put the LED into MCU controlled mode */ in omnia_hwtrig_activate()
214 err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE, in omnia_hwtrig_activate()
215 CMD_LED_MODE_LED(led->reg)); in omnia_hwtrig_activate()
217 led->hwtrig = true; in omnia_hwtrig_activate()
220 mutex_unlock(&leds->lock); in omnia_hwtrig_activate()
227 struct omnia_leds *leds = dev_get_drvdata(cdev->dev->parent); in omnia_hwtrig_deactivate()
231 mutex_lock(&leds->lock); in omnia_hwtrig_deactivate()
233 led->hwtrig = false; in omnia_hwtrig_deactivate()
236 err = omnia_cmd_write_u8(leds->client, CMD_LED_MODE, in omnia_hwtrig_deactivate()
237 CMD_LED_MODE_LED(led->reg) | in omnia_hwtrig_deactivate()
240 mutex_unlock(&leds->lock); in omnia_hwtrig_deactivate()
243 dev_err(cdev->dev, "Cannot put LED to software mode: %i\n", in omnia_hwtrig_deactivate()
248 .name = "omnia-mcu",
258 struct device *dev = &client->dev; in omnia_led_register()
262 ret = of_property_read_u32(np, "reg", &led->reg); in omnia_led_register()
263 if (ret || led->reg >= OMNIA_BOARD_LEDS) { in omnia_led_register()
266 np, OMNIA_BOARD_LEDS - 1); in omnia_led_register()
278 led->subled_info[0].color_index = LED_COLOR_ID_RED; in omnia_led_register()
279 led->subled_info[1].color_index = LED_COLOR_ID_GREEN; in omnia_led_register()
280 led->subled_info[2].color_index = LED_COLOR_ID_BLUE; in omnia_led_register()
284 led->subled_info[i].intensity = 255; in omnia_led_register()
285 led->subled_info[i].brightness = 255; in omnia_led_register()
286 led->subled_info[i].channel = i; in omnia_led_register()
289 led->mc_cdev.subled_info = led->subled_info; in omnia_led_register()
290 led->mc_cdev.num_colors = OMNIA_LED_NUM_CHANNELS; in omnia_led_register()
292 init_data.fwnode = &np->fwnode; in omnia_led_register()
294 cdev = &led->mc_cdev.led_cdev; in omnia_led_register()
295 cdev->max_brightness = 255; in omnia_led_register()
296 cdev->brightness_set_blocking = omnia_led_brightness_set_blocking; in omnia_led_register()
297 cdev->trigger_type = &omnia_hw_trigger_type; in omnia_led_register()
299 * Use the omnia-mcu trigger as the default trigger. It may be rewritten in omnia_led_register()
300 * by LED class from the linux,default-trigger property. in omnia_led_register()
302 cdev->default_trigger = omnia_hw_trigger.name; in omnia_led_register()
306 CMD_LED_MODE_LED(led->reg) | in omnia_led_register()
316 CMD_LED_STATE_LED(led->reg)); in omnia_led_register()
330 ret = devm_led_classdev_multicolor_register_ext(dev, &led->mc_cdev, in omnia_led_register()
341 * On the front panel of the Turris Omnia router there is also a button which
373 return -EINVAL; in brightness_store()
376 return -EINVAL; in brightness_store()
391 if (leds->has_gamma_correction) { in gamma_correction_show()
411 if (!leds->has_gamma_correction) in gamma_correction_store()
412 return -EOPNOTSUPP; in gamma_correction_store()
415 return -EINVAL; in gamma_correction_store()
435 err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, in omnia_mcu_get_features()
440 /* Check whether MCU firmware supports the CMD_GET_FEAUTRES command */ in omnia_mcu_get_features()
444 err = omnia_cmd_read_raw(client->adapter, OMNIA_MCU_I2C_ADDR, in omnia_mcu_get_features()
454 struct device *dev = &client->dev; in omnia_leds_probe()
463 return -ENODEV; in omnia_leds_probe()
466 return -EINVAL; in omnia_leds_probe()
471 return -ENOMEM; in omnia_leds_probe()
473 leds->client = client; in omnia_leds_probe()
478 dev_err(dev, "Cannot determine MCU supported features: %d\n", in omnia_leds_probe()
483 leds->has_gamma_correction = ret & FEAT_LED_GAMMA_CORRECTION; in omnia_leds_probe()
484 if (!leds->has_gamma_correction) { in omnia_leds_probe()
486 "Your board's MCU firmware does not support the LED gamma correction feature.\n"); in omnia_leds_probe()
488 "Consider upgrading MCU firmware with the omnia-mcutool utility.\n"); in omnia_leds_probe()
491 mutex_init(&leds->lock); in omnia_leds_probe()
499 led = &leds->leds[0]; in omnia_leds_probe()
530 { .compatible = "cznic,turris-omnia-leds", },
536 { "omnia" },
546 .name = "leds-turris-omnia",
555 MODULE_DESCRIPTION("CZ.NIC's Turris Omnia LEDs");