sdk-hwV1.3/lichee/brandy-2.0/u-boot-2018/cmd/cmd_pwm_led.c

237 lines
5.1 KiB
C

/*
* (C) Copyright 2019
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <sunxi_board.h>
#include <pwm.h>
#include <pwm_led.h>
#include <fdt_support.h>
#include <asm/arch/timer.h>
#define PWM_LED_PERIOD (10000)
#define MAX_VALUE (255)
static struct pwm_led_rgb led_rgb_global;
int load_pwm_led_rgb_config_from_dtb(struct pwm_led_rgb *led_rgb)
{
int node;
u32 led_r, led_g, led_b;
u32 led_r_pwm, led_g_pwm, led_b_pwm;
int workmode = get_boot_work_mode();
char *dev_name = "pwm_led";
if (workmode != WORK_MODE_BOOT)
return 0;
node = fdt_node_offset_by_prop_value(working_fdt, -1, "device_type", dev_name, strlen(dev_name) + 1);
if (node < 0) {
printf("unable to find pwm led node in device tree.\n");
return -1;
}
if (fdt_getprop_u32(working_fdt, node, "led_r_pwm", &led_r_pwm) < 0)
led_r_pwm = -1;
if (fdt_getprop_u32(working_fdt, node, "led_g_pwm", &led_g_pwm) < 0)
led_g_pwm = -1;
if (fdt_getprop_u32(working_fdt, node, "led_b_pwm", &led_b_pwm) < 0)
led_b_pwm = -1;
if (fdt_getprop_u32(working_fdt, node, "led_r", &led_r) < 0)
led_r = 0;
if (fdt_getprop_u32(working_fdt, node, "led_g", &led_g) < 0)
led_g = 0;
if (fdt_getprop_u32(working_fdt, node, "led_b", &led_b) < 0)
led_b = 0;
led_rgb->r.pwm_num = led_r_pwm;
led_rgb->r.value = led_r;
strcpy(led_rgb->r.label, "led_red");
led_rgb->g.pwm_num = led_g_pwm;
led_rgb->g.value = led_g;
strcpy(led_rgb->r.label, "led_green");
led_rgb->b.pwm_num = led_b_pwm;
led_rgb->b.value = led_b;
strcpy(led_rgb->r.label, "led_blue");
return 0;
}
int pwm_led_load(struct pwm_led_rgb *led_rgb)
{
int ret;
ret = load_pwm_led_rgb_config_from_dtb(led_rgb);
return ret;
}
int store_led_values_to_dtb(struct pwm_led led_rgb)
{
/* TODO */
return 0;
}
int pwm_led_store(struct pwm_led led_rgb)
{
int ret;
ret = store_led_values_to_dtb(led_rgb);
return ret;
}
int pwm_led_init(void)
{
int ret, workmode;
workmode = get_boot_work_mode();
if (workmode != WORK_MODE_BOOT)
return 0;
ret = pwm_led_load(&led_rgb_global);
if (ret)
return 0;
pwm_init();
pwm_request(led_rgb_global.r.pwm_num, led_rgb_global.r.label);
pwm_request(led_rgb_global.g.pwm_num, led_rgb_global.g.label);
pwm_request(led_rgb_global.b.pwm_num, led_rgb_global.b.label);
printf("init led: r:%d, g:%d b:%d\n", led_rgb_global.r.value, led_rgb_global.g.value, led_rgb_global.b.value);
pwm_led_set(led_rgb_global);
printf("pwm_led_init end\n");
return 0;
}
static int set_one_pwm_led(struct pwm_led led)
{
unsigned int duty_ns, period_ns, level;
if (led.value != 0) {
period_ns = PWM_LED_PERIOD;
level = MAX_VALUE - led.value;
if (level == 0) /* for pwm, duty_ns shoule not be zero */
level = 1;
duty_ns = (period_ns * level) / MAX_VALUE;
pwm_config(led.pwm_num, duty_ns, period_ns);
pwm_enable(led.pwm_num);
} else {
pwm_disable(led.pwm_num);
}
return 0;
}
int pwm_led_set(struct pwm_led_rgb led_rgb)
{
set_one_pwm_led(led_rgb.r);
set_one_pwm_led(led_rgb.g);
set_one_pwm_led(led_rgb.b);
/* pwm_led_store(led_rgb); */
return 0;
}
int pwm_led_test(void)
{
int i, workmode;
workmode = get_boot_work_mode();
if (workmode != WORK_MODE_BOOT)
return 0;
led_rgb_global.r.value = 0;
led_rgb_global.g.value = 0;
led_rgb_global.b.value = 0;
printf("test red\n");
for (i = 0; i <= MAX_VALUE; i++) {
led_rgb_global.r.value = i;
pwm_led_set(led_rgb_global);
__msdelay(10);
}
for (i = 0; i <= MAX_VALUE; i++) {
led_rgb_global.r.value = MAX_VALUE - i;
pwm_led_set(led_rgb_global);
__msdelay(10);
}
led_rgb_global.r.value = 0;
led_rgb_global.g.value = 0;
led_rgb_global.b.value = 0;
printf("test green\n");
for (i = 0; i <= MAX_VALUE; i++) {
led_rgb_global.g.value = i;
pwm_led_set(led_rgb_global);
__msdelay(10);
}
for (i = 0; i <= MAX_VALUE; i++) {
led_rgb_global.g.value = MAX_VALUE - i;
pwm_led_set(led_rgb_global);
__msdelay(10);
}
printf("test blue\n");
for (i = 0; i <= MAX_VALUE; i++) {
led_rgb_global.b.value = i;
pwm_led_set(led_rgb_global);
__msdelay(10);
}
for (i = 0; i <= MAX_VALUE; i++) {
led_rgb_global.b.value = MAX_VALUE - i;
pwm_led_set(led_rgb_global);
__msdelay(10);
}
return 0;
}
int do_pwm_led(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
ulong red_value, blue_value, green_value;
if (argc < 3) {
pwm_led_test();
return cmd_usage(cmdtp);
}
red_value = simple_strtoul(argv[1], NULL, 10);
green_value = simple_strtoul(argv[2], NULL, 10);
blue_value = simple_strtoul(argv[3], NULL, 10);
if (red_value > MAX_VALUE)
red_value = MAX_VALUE;
else if (red_value < 0)
red_value = 0;
if (blue_value > MAX_VALUE)
blue_value = MAX_VALUE;
else if (blue_value < 0)
blue_value = 0;
if (green_value > MAX_VALUE)
green_value = MAX_VALUE;
else if (green_value < 0)
green_value = 0;
printf("init led: r:%ld, g:%ld b:%ld\n", red_value, green_value, blue_value);
led_rgb_global.r.value = red_value;
led_rgb_global.g.value = green_value;
led_rgb_global.b.value = blue_value;
pwm_led_set(led_rgb_global);
return 0;
}
U_BOOT_CMD(
pwm_led, 5, 1, do_pwm_led,
"pwm_led - set pwm led\n",
"pwm_led red<0-255> green<0-255> blue<0-255>\n"
);