mirror of
https://github.com/LuckfoxTECH/luckfox-pico.git
synced 2026-01-19 09:52:31 +01:00
project:build.sh: Added fastboot support; custom modifications to U-Boot and kernel implemented using patches.
project:cfg:BoardConfig_IPC: Added fastboot BoardConfig file and firmware post-scripts, distinguishing between the BoardConfigs for Luckfox Pico Pro and Luckfox Pico Max. project:app: Added fastboot_client and rk_smart_door for quick boot applications; updated rkipc app to adapt to the latest media library. media:samples: Added more usage examples. media:rockit: Fixed bugs; removed support for retrieving data frames from VPSS. media:isp: Updated rkaiq library and related tools to support connection to RKISP_Tuner. sysdrv:Makefile: Added support for compiling drv_ko on Luckfox Pico Ultra W using Ubuntu; added support for custom root filesystem. sysdrv:tools:board: Updated Buildroot optional mirror sources, updated some software versions, and stored device tree files and configuration files that undergo multiple modifications for U-Boot and kernel separately. sysdrv:source:mcu: Used RISC-V MCU SDK with RT-Thread system, mainly for initializing camera AE during quick boot. sysdrv:source:uboot: Added support for fastboot; added high baud rate DDR bin for serial firmware upgrades. sysdrv:source:kernel: Upgraded to version 5.10.160; increased NPU frequency for RV1106G3; added support for fastboot. Signed-off-by: luckfox-eng29 <eng29@luckfox.com>
This commit is contained in:
@@ -11,13 +11,10 @@
|
||||
static int adc_key_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct dm_key_uclass_platdata *uc_key;
|
||||
u32 chn[2], mV;
|
||||
int vref, ret;
|
||||
#ifdef CONFIG_SARADC_ROCKCHIP_V2
|
||||
int range = 4096; /* 12-bit adc */
|
||||
#else
|
||||
int range = 1024; /* 10-bit adc */
|
||||
#endif
|
||||
int t, down_threshold = -1, up_threshold;
|
||||
int ret, num = 0, volt_margin = 150000; /* will be div 2 */
|
||||
u32 voltage, chn[2];
|
||||
ofnode node;
|
||||
|
||||
uc_key = dev_get_uclass_platdata(dev);
|
||||
if (!uc_key)
|
||||
@@ -33,29 +30,50 @@ static int adc_key_ofdata_to_platdata(struct udevice *dev)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
vref = dev_read_u32_default(dev_get_parent(dev),
|
||||
up_threshold = dev_read_u32_default(dev_get_parent(dev),
|
||||
"keyup-threshold-microvolt", -ENODATA);
|
||||
if (vref < 0) {
|
||||
printf("%s: read 'keyup-threshold-microvolt' failed, ret=%d\n",
|
||||
uc_key->name, vref);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (up_threshold < 0)
|
||||
return -ENODATA;
|
||||
|
||||
uc_key->code = dev_read_u32_default(dev, "linux,code", -ENODATA);
|
||||
if (uc_key->code < 0) {
|
||||
printf("%s: read 'linux,code' failed\n", uc_key->name);
|
||||
return -EINVAL;
|
||||
if (uc_key->code < 0)
|
||||
return -ENODATA;
|
||||
|
||||
voltage = dev_read_u32_default(dev, "press-threshold-microvolt", -ENODATA);
|
||||
if (voltage < 0)
|
||||
return -ENODATA;
|
||||
|
||||
dev_for_each_subnode(node, dev->parent) {
|
||||
ret = ofnode_read_s32(node, "press-threshold-microvolt", &t);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (t > voltage && t < up_threshold)
|
||||
up_threshold = t;
|
||||
else if (t < voltage && t > down_threshold)
|
||||
down_threshold = t;
|
||||
num++;
|
||||
}
|
||||
|
||||
mV = dev_read_u32_default(dev, "press-threshold-microvolt", -ENODATA);
|
||||
if (mV < 0) {
|
||||
printf("%s: read 'press-threshold-microvolt' failed\n",
|
||||
uc_key->name);
|
||||
return -EINVAL;
|
||||
/* although one node only, it doesn't mean only one key on hardware */
|
||||
if (num == 1) {
|
||||
down_threshold = voltage - volt_margin;
|
||||
up_threshold = voltage + volt_margin;
|
||||
}
|
||||
|
||||
uc_key->in_volt = 1;
|
||||
uc_key->channel = chn[1];
|
||||
uc_key->adcval = mV / (vref / range);
|
||||
uc_key->center = voltage;
|
||||
/*
|
||||
* Define the voltage range such that the button is only pressed
|
||||
* when the voltage is closest to its own press-threshold-microvolt
|
||||
*/
|
||||
if (down_threshold < 0)
|
||||
uc_key->min = 0;
|
||||
else
|
||||
uc_key->min = down_threshold + (voltage - down_threshold) / 2;
|
||||
|
||||
uc_key->max = voltage + (up_threshold - voltage) / 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <adc.h>
|
||||
#include <div64.h>
|
||||
#include <dm.h>
|
||||
#include <irq-generic.h>
|
||||
#include <key.h>
|
||||
@@ -37,11 +38,42 @@ uint64_t key_timer(uint64_t base)
|
||||
return (cntpct > base) ? (cntpct - base) : 0;
|
||||
}
|
||||
|
||||
static int key_adc_event(struct dm_key_uclass_platdata *uc_key, int adcval)
|
||||
#ifdef CONFIG_ADC
|
||||
static int adc_raw_to_mV(struct udevice *dev, unsigned int raw, int *mV)
|
||||
{
|
||||
return (adcval <= uc_key->max && adcval >= uc_key->min) ?
|
||||
unsigned int data_mask;
|
||||
int ret, vref = 1800000;
|
||||
u64 raw64 = raw;
|
||||
|
||||
ret = adc_data_mask(dev, &data_mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
raw64 *= vref;
|
||||
do_div(raw64, data_mask);
|
||||
*mV = raw64;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int key_adc_event(struct udevice *dev,
|
||||
struct dm_key_uclass_platdata *uc_key, int adcval)
|
||||
{
|
||||
int val = adcval;
|
||||
|
||||
if (uc_key->in_volt) {
|
||||
if (adc_raw_to_mV(dev, adcval, &val))
|
||||
return KEY_PRESS_NONE;
|
||||
}
|
||||
|
||||
debug("[%s] <%d, %d, %d>: adcval=%d -> mV=%d\n",
|
||||
uc_key->name, uc_key->min, uc_key->center, uc_key->max,
|
||||
adcval, val);
|
||||
|
||||
return (val <= uc_key->max && val >= uc_key->min) ?
|
||||
KEY_PRESS_DOWN : KEY_PRESS_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int key_gpio_event(struct dm_key_uclass_platdata *uc_key)
|
||||
{
|
||||
@@ -108,16 +140,36 @@ int key_is_pressed(int event)
|
||||
|
||||
static int key_core_read(struct dm_key_uclass_platdata *uc_key)
|
||||
{
|
||||
unsigned int adcval;
|
||||
|
||||
if (uc_key->type == ADC_KEY) {
|
||||
if (adc_channel_single_shot("saradc",
|
||||
uc_key->channel, &adcval)) {
|
||||
KEY_ERR("%s failed to read saradc\n", uc_key->name);
|
||||
#ifdef CONFIG_ADC
|
||||
struct udevice *dev;
|
||||
unsigned int adcval;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device_by_name(UCLASS_ADC, "saradc", &dev);
|
||||
if (ret)
|
||||
ret = uclass_get_device_by_name(UCLASS_ADC, "adc", &dev);
|
||||
if (ret) {
|
||||
KEY_ERR("%s: No saradc\n", uc_key->name);
|
||||
return KEY_NOT_EXIST;
|
||||
}
|
||||
|
||||
return key_adc_event(uc_key, adcval);
|
||||
ret = adc_start_channel(dev, uc_key->channel);
|
||||
if (ret) {
|
||||
KEY_ERR("%s: Failed to start saradc\n", uc_key->name);
|
||||
return KEY_NOT_EXIST;
|
||||
}
|
||||
|
||||
ret = adc_channel_data(dev, uc_key->channel, &adcval);
|
||||
if (ret) {
|
||||
KEY_ERR("%s: Failed to read saradc, %d\n", uc_key->name, ret);
|
||||
return KEY_NOT_EXIST;
|
||||
}
|
||||
|
||||
return key_adc_event(dev, uc_key, adcval);
|
||||
#else
|
||||
return KEY_NOT_EXIST;
|
||||
#endif
|
||||
}
|
||||
|
||||
return (uc_key->code == KEY_POWER) ?
|
||||
@@ -273,11 +325,7 @@ static int key_post_probe(struct udevice *dev)
|
||||
{
|
||||
struct dm_key_uclass_platdata *uc_key;
|
||||
int ret;
|
||||
#ifdef CONFIG_SARADC_ROCKCHIP_V2
|
||||
int margin = 120;
|
||||
#else
|
||||
int margin = 30;
|
||||
#endif
|
||||
|
||||
uc_key = dev_get_uclass_platdata(dev);
|
||||
if (!uc_key)
|
||||
return -ENXIO;
|
||||
@@ -286,11 +334,7 @@ static int key_post_probe(struct udevice *dev)
|
||||
uc_key->pre_reloc = dev_read_bool(dev, "u-boot,dm-pre-reloc") ||
|
||||
dev_read_bool(dev, "u-boot,dm-spl");
|
||||
|
||||
if (uc_key->type == ADC_KEY) {
|
||||
uc_key->max = uc_key->adcval + margin;
|
||||
uc_key->min = uc_key->adcval > margin ?
|
||||
uc_key->adcval - margin : 0;
|
||||
} else {
|
||||
if (uc_key->type != ADC_KEY) {
|
||||
if (uc_key->code == KEY_POWER) {
|
||||
#if CONFIG_IS_ENABLED(IRQ)
|
||||
int irq;
|
||||
@@ -337,8 +381,9 @@ static int key_post_probe(struct udevice *dev)
|
||||
dev->parent->name);
|
||||
|
||||
if (uc_key->type == ADC_KEY) {
|
||||
printf(" adcval: %d (%d, %d)\n", uc_key->adcval,
|
||||
uc_key->min, uc_key->max);
|
||||
printf(" %s: %d (%d, %d)\n",
|
||||
uc_key->in_volt ? "volt" : " adc",
|
||||
uc_key->center, uc_key->min, uc_key->max);
|
||||
printf(" channel: %d\n\n", uc_key->channel);
|
||||
} else {
|
||||
const char *gpio_name =
|
||||
|
||||
@@ -27,9 +27,13 @@ static int rk_key_ofdata_to_platdata(struct udevice *dev)
|
||||
|
||||
if (dev_read_bool(dev, "rockchip,adc_value")) {
|
||||
uc_key->type = ADC_KEY;
|
||||
uc_key->in_volt = 0;
|
||||
uc_key->channel = chn[1];
|
||||
uc_key->adcval =
|
||||
dev_read_u32_default(dev, "rockchip,adc_value", 0);
|
||||
uc_key->center = dev_read_u32_default(dev, "rockchip,adc_value", 0);
|
||||
uc_key->min = uc_key->center - 30;
|
||||
if (uc_key->min < 0)
|
||||
uc_key->min = 0;
|
||||
uc_key->max = uc_key->center + 30;
|
||||
} else {
|
||||
uc_key->type = GPIO_KEY;
|
||||
if (dev_read_u32_array(dev, "gpios",
|
||||
|
||||
@@ -6,28 +6,48 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <adc.h>
|
||||
#include <div64.h>
|
||||
#include <fdtdec.h>
|
||||
#include <dm/uclass.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static int adc_raw_to_mV(struct udevice *dev, unsigned int raw, int *mV)
|
||||
{
|
||||
unsigned int data_mask;
|
||||
int ret, vref = 1800000;
|
||||
u64 raw64 = raw;
|
||||
|
||||
ret = adc_data_mask(dev, &data_mask);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
raw64 *= vref;
|
||||
do_div(raw64, data_mask);
|
||||
*mV = raw64;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int key_read(int code)
|
||||
{
|
||||
const void *fdt_blob = gd->fdt_blob;
|
||||
struct udevice *dev;
|
||||
int adc_node, offset;
|
||||
int cd, channel, adc;
|
||||
int ret, vref, mv;
|
||||
int t, down_threshold = -1, up_threshold;
|
||||
int ret, num = 0, volt_margin = 150000; /* will be div 2 */
|
||||
int mV, cd, voltage = -1;
|
||||
int min, max;
|
||||
int margin;
|
||||
int range;
|
||||
uint val;
|
||||
u32 chn[2];
|
||||
#ifdef CONFIG_SARADC_ROCKCHIP_V2
|
||||
range = 4096; /* 12-bit adc */
|
||||
margin = 120;
|
||||
#else
|
||||
range = 1024; /* 10-bit adc */
|
||||
margin = 30;
|
||||
#endif
|
||||
u32 chn[2], adc;
|
||||
|
||||
ret = uclass_get_device_by_name(UCLASS_ADC, "saradc", &dev);
|
||||
if (ret)
|
||||
ret = uclass_get_device_by_name(UCLASS_ADC, "adc", &dev);
|
||||
if (ret) {
|
||||
debug("No saradc device, ret=%d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
adc_node = fdt_node_offset_by_compatible(fdt_blob, 0, "adc-keys");
|
||||
if (adc_node < 0) {
|
||||
debug("No 'adc-keys' node, ret=%d\n", adc_node);
|
||||
@@ -41,40 +61,89 @@ int key_read(int code)
|
||||
return 0;
|
||||
}
|
||||
|
||||
vref = fdtdec_get_int(fdt_blob, adc_node,
|
||||
"keyup-threshold-microvolt", -1);
|
||||
if (vref < 0) {
|
||||
up_threshold = fdtdec_get_int(fdt_blob, adc_node,
|
||||
"keyup-threshold-microvolt", -ENODATA);
|
||||
if (up_threshold < 0) {
|
||||
debug("Can't read 'keyup-threshold-microvolt'\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
channel = chn[1];
|
||||
/* find the expected key-code */
|
||||
for (offset = fdt_first_subnode(fdt_blob, adc_node);
|
||||
offset >= 0;
|
||||
offset = fdt_next_subnode(fdt_blob, offset)) {
|
||||
cd = fdtdec_get_int(fdt_blob, offset, "linux,code", -ENODATA);
|
||||
if (cd < 0) {
|
||||
debug("Can't read 'linux,code', ret=%d\n", cd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cd == code) {
|
||||
voltage = fdtdec_get_int(fdt_blob, offset,
|
||||
"press-threshold-microvolt", -ENODATA);
|
||||
if (voltage < 0) {
|
||||
debug("Can't read 'press-threshold-microvolt'\n");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (voltage < 0)
|
||||
return 0;
|
||||
|
||||
for (offset = fdt_first_subnode(fdt_blob, adc_node);
|
||||
offset >= 0;
|
||||
offset = fdt_next_subnode(fdt_blob, offset)) {
|
||||
cd = fdtdec_get_int(fdt_blob, offset, "linux,code", -1);
|
||||
if (cd == code) {
|
||||
mv = fdtdec_get_int(fdt_blob, offset,
|
||||
"press-threshold-microvolt", -1);
|
||||
if (mv < 0) {
|
||||
debug("Can't read 'press-threshold-microvolt'\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
adc = mv / (vref / range);
|
||||
max = adc + margin;
|
||||
min = adc > margin ? adc - margin : 0;
|
||||
ret = adc_channel_single_shot("saradc", channel, &val);
|
||||
if (ret) {
|
||||
debug("Failed to read adc%d, ret=%d\n",
|
||||
channel, ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (val >= min && val <= max);
|
||||
t = fdtdec_get_int(fdt_blob, offset,
|
||||
"press-threshold-microvolt", -ENODATA);
|
||||
if (t < 0) {
|
||||
debug("Can't read 'press-threshold-microvolt'\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (t > voltage && t < up_threshold)
|
||||
up_threshold = t;
|
||||
else if (t < voltage && t > down_threshold)
|
||||
down_threshold = t;
|
||||
num++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* although one node only, it doesn't mean only one key on hardware */
|
||||
if (num == 1) {
|
||||
down_threshold = voltage - volt_margin;
|
||||
up_threshold = voltage + volt_margin;
|
||||
}
|
||||
|
||||
/*
|
||||
* Define the voltage range such that the button is only pressed
|
||||
* when the voltage is closest to its own press-threshold-microvolt
|
||||
*/
|
||||
if (down_threshold < 0)
|
||||
min = 0;
|
||||
else
|
||||
min = down_threshold + (voltage - down_threshold) / 2;
|
||||
|
||||
max = voltage + (up_threshold - voltage) / 2;
|
||||
|
||||
/* now, read key status */
|
||||
ret = adc_channel_single_shot("saradc", chn[1], &adc);
|
||||
if (ret)
|
||||
ret = adc_channel_single_shot("adc", chn[1], &adc);
|
||||
if (ret) {
|
||||
debug("Failed to read adc%d, ret=%d\n", chn[1], ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = adc_raw_to_mV(dev, adc, &mV);
|
||||
if (ret) {
|
||||
debug("Failed to convert adc to mV, ret=%d\n", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("key[%d] <%d, %d, %d>: adc=%d -> mV=%d\n",
|
||||
code, min, voltage, max, adc, mV);
|
||||
|
||||
return (mV <= max && mV >= min);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user