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:
luckfox-eng29
2024-08-21 10:05:47 +08:00
parent e79fd21975
commit 8f34c2760d
20902 changed files with 6567362 additions and 11248383 deletions

View File

@@ -6,7 +6,6 @@
#include <linux/list.h>
#include <linux/gpio.h>
#include <linux/time.h>
#include <linux/hrtimer.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/module.h>
@@ -24,8 +23,349 @@
#include <linux/seq_file.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/clockchips.h>
#include <linux/sched_clock.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/dev_printk.h>
#include "motor_24byj48.h"
#define TIMER_LOAD_COUNT0 0x00
#define TIMER_LOAD_COUNT1 0x04
#define TIMER_CONTROL_REG3288 0x10
#define TIMER_CONTROL_REG3399 0x1c
#define TIMER_INT_STATUS 0x18
#define TIMER_DISABLE 0x0
#define TIMER_ENABLE 0x1
#define TIMER_MODE_FREE_RUNNING (0 << 1)
#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1)
#define TIMER_INT_UNMASK (1 << 2)
struct rk_timer {
void __iomem *base;
void __iomem *ctrl;
struct clk *timer_clk;
struct clk *pclk;
u32 freq;
bool skipped;
};
enum motor_status {
MOTOR_IS_STOP,
MOTOR_IS_RUNNING,
};
struct motor_reset_data {
unsigned int x_max_steps;
unsigned int y_max_steps;
unsigned int reset_x;
unsigned int reset_y;
unsigned int x_cur_steps;
unsigned int y_cur_steps;
};
enum motor_cnt {
HORIZONTAL_MOTOR,
VERTICAL_MOTOR,
HAS_MOTOR_CNT,
};
struct motor_device_attribute {
char motor_direction;
int max_steps;
int input_move_steps;
int real_move_steps;
int cur_steps;
int motor_speed;
int reset_point;
ktime_t m_kt;
unsigned int timer_count;
int motor_gpio[MAX_GPIO_NUM];
enum motor_status motor_current_status;
};
struct motor_message {
int x_cur_steps;
int y_cur_steps;
enum motor_status x_cur_status;
enum motor_status y_cur_status;
int x_cur_speed;
int y_cur_speed;
};
struct motors_input_steps {
int input_x_steps;
int input_y_steps;
};
struct motors_input_speed {
int input_x_speed;
int input_y_speed;
};
struct motors_init_data {
struct motor_reset_data motor_data;
struct motors_input_speed motor_speed;
};
struct motor_device {
struct proc_dir_entry *proc;
struct miscdevice misc_dev;
struct device *dev;
struct mutex dev_mutex;
spinlock_t slock;
int motor_open_flag;
struct rk_timer rk_timer;
struct motor_device_attribute motors[HAS_MOTOR_CNT];
};
static inline void rk_timer_disable(struct rk_timer *timer)
{
writel_relaxed(TIMER_DISABLE, timer->ctrl);
}
static inline void rk_timer_enable(struct rk_timer *timer, u32 flags)
{
writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, timer->ctrl);
}
static void rk_timer_update_counter(unsigned long cycles, struct rk_timer *timer)
{
writel_relaxed(cycles, timer->base + TIMER_LOAD_COUNT0);
writel_relaxed(0, timer->base + TIMER_LOAD_COUNT1);
}
static void rk_timer_interrupt_clear(struct rk_timer *timer)
{
writel_relaxed(1, timer->base + TIMER_INT_STATUS);
}
static inline int rk_timer_set_next_event(unsigned long cycles, struct rk_timer *timer)
{
rk_timer_disable(timer);
rk_timer_update_counter(cycles, timer);
rk_timer_enable(timer, TIMER_MODE_USER_DEFINED_COUNT | TIMER_INT_UNMASK);
return 0;
}
static __maybe_unused int rk_timer_set_periodic(unsigned long cycles, struct rk_timer *timer)
{
rk_timer_disable(timer);
rk_timer_update_counter(cycles, timer);
rk_timer_enable(timer, TIMER_MODE_FREE_RUNNING);
return 0;
}
void motor_off(struct motor_device_attribute motor)
{
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 0);
}
static int meter_turn(struct motor_device_attribute motor)
{
switch (motor.timer_count) {
case 0:
gpio_set_value(motor.motor_gpio[0], 1);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 1:
gpio_set_value(motor.motor_gpio[0], 1);
gpio_set_value(motor.motor_gpio[1], 1);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 2:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 1);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 3:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 1);
gpio_set_value(motor.motor_gpio[2], 1);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 4:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 1);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 5:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 1);
gpio_set_value(motor.motor_gpio[3], 1);
break;
case 6:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 1);
break;
case 7:
gpio_set_value(motor.motor_gpio[0], 1);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 1);
break;
}
return 0;
}
static void motor_turn_by_id(struct motor_device *mdev, int motor_id)
{
unsigned long flags;
if (mdev->motors[motor_id].motor_direction == 'R') {
mdev->motors[motor_id].timer_count++;
if (mdev->motors[motor_id].timer_count > 7)
mdev->motors[motor_id].timer_count = 0;
} else {
if (mdev->motors[motor_id].timer_count == 0)
mdev->motors[motor_id].timer_count = 8;
mdev->motors[motor_id].timer_count--;
}
meter_turn(mdev->motors[motor_id]);
mdev->motors[motor_id].real_move_steps++;
mdev->motors[motor_id].input_move_steps--;
if (mdev->motors[motor_id].input_move_steps == 0) {
mutex_lock(&mdev->dev_mutex);
spin_lock_irqsave(&mdev->slock, flags);
mdev->motors[motor_id].motor_current_status = MOTOR_IS_STOP;
if (mdev->motors[motor_id].motor_direction == 'R')
mdev->motors[motor_id].cur_steps = mdev->motors[motor_id].cur_steps +
mdev->motors[motor_id].real_move_steps;
else if (mdev->motors[motor_id].motor_direction == 'L')
mdev->motors[motor_id].cur_steps = mdev->motors[motor_id].cur_steps -
mdev->motors[motor_id].real_move_steps;
mdev->motors[motor_id].input_move_steps = 0;
mdev->motors[motor_id].real_move_steps = 0;
spin_unlock_irqrestore(&mdev->slock, flags);
mutex_unlock(&mdev->dev_mutex);
printk("the motor %d steps after stop%d\n", motor_id, mdev->motors[HORIZONTAL_MOTOR].cur_steps);
motor_off(mdev->motors[motor_id]);
}
}
#define SECOND_IN_NS 1000000000u
static inline uint32_t ns_to_rktimer_cycles(uint32_t freq, uint32_t ns)
{
return ns / (SECOND_IN_NS / freq);
}
static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
{
struct motor_device *mdev = dev_id;
int next_event = 0;
rk_timer_interrupt_clear(&mdev->rk_timer);
if (mdev->motors[HORIZONTAL_MOTOR].input_move_steps != 0) {
next_event = 1;
motor_turn_by_id(mdev, HORIZONTAL_MOTOR);
}
if (mdev->motors[VERTICAL_MOTOR].input_move_steps !=0) {
next_event = 1;
motor_turn_by_id(mdev, VERTICAL_MOTOR);
}
if (next_event) {
rk_timer_set_next_event(ns_to_rktimer_cycles(mdev->rk_timer.freq, MOTOR_MAX_SPEED), &mdev->rk_timer);
}
return IRQ_HANDLED;
}
static void rk_timer_deinit(struct motor_device *mdev)
{
struct rk_timer *timer = &mdev->rk_timer;
rk_timer_interrupt_clear(timer);
rk_timer_disable(timer);
clk_disable_unprepare(timer->timer_clk);
clk_disable_unprepare(timer->pclk);
iounmap(timer->base);
};
static struct rk_timer *rk_timer_init(struct platform_device *pdev, struct motor_device *mdev)
{
struct rk_timer *timer = &mdev->rk_timer;
struct device_node *np = pdev->dev.of_node;
int ret, irq;
timer->base = of_iomap(np, 0);
if (!timer->base) {
dev_err(mdev->dev, "Failed to get base address\n");
return NULL;
}
timer->ctrl = timer->base + TIMER_CONTROL_REG3288; //TODO: check 3399/3288
timer->pclk = of_clk_get_by_name(np, "pclk");
if (IS_ERR(timer->pclk)) {
dev_err(mdev->dev, "Failed to get pclk\n");
goto out_unmap;
}
if (clk_prepare_enable(timer->pclk)) {
dev_err(mdev->dev, "Failed to enable pclk\n");
goto out_unmap;
}
timer->timer_clk = of_clk_get_by_name(np, "timer");
if (IS_ERR(timer->timer_clk)) {
dev_err(mdev->dev, "Failed to get timer clock\n");
goto out_timer_clk;
}
if (clk_prepare_enable(timer->timer_clk)) {
dev_err(mdev->dev, "Failed to enable timer clock\n");
goto out_timer_clk;
}
timer->freq = clk_get_rate(timer->timer_clk);
dev_info(mdev->dev, "Timer clk is %d\n", timer->freq);
irq = irq_of_parse_and_map(np, 0);
if (!irq) {
dev_err(mdev->dev, "Failed to map interrupts for\n");
goto out_irq;
}
rk_timer_interrupt_clear(timer);
rk_timer_disable(timer);
ret = devm_request_irq(mdev->dev, irq, rk_timer_interrupt,
IRQF_TIMER, dev_name(mdev->dev), mdev);
if (ret) {
dev_err(mdev->dev, "Failed to initialize: %d\n", ret);
goto out_irq;
}
return timer;
out_irq:
clk_disable_unprepare(timer->timer_clk);
out_timer_clk:
clk_disable_unprepare(timer->pclk);
out_unmap:
iounmap(timer->base);
return NULL;
}
static void motor_set_default(struct motor_device *mdev)
{
int index = 0;
@@ -44,14 +384,6 @@ static void motor_set_default(struct motor_device *mdev)
}
}
void motor_off(struct motor_device_attribute motor)
{
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 0);
}
static long motor_ops_move(struct motor_device *mdev, int x, int y)
{
struct motor_device_attribute *motors = mdev->motors;
@@ -121,20 +453,7 @@ static long motor_ops_move(struct motor_device *mdev, int x, int y)
}
spin_unlock_irqrestore(&mdev->slock, flags);
mutex_unlock(&mdev->dev_mutex);
if (x1 > 0) {
mdev->motors[HORIZONTAL_MOTOR].m_kt =
ktime_set(0, mdev->motors[HORIZONTAL_MOTOR].motor_speed);
hrtimer_cancel(&mdev->horizontal_motor_timer);
hrtimer_start(&mdev->horizontal_motor_timer,
mdev->motors[HORIZONTAL_MOTOR].m_kt, HRTIMER_MODE_REL);
}
if (y1 > 0) {
mdev->motors[VERTICAL_MOTOR].m_kt =
ktime_set(0, mdev->motors[VERTICAL_MOTOR].motor_speed);
hrtimer_cancel(&mdev->vertical_motor_timer);
hrtimer_start(&mdev->vertical_motor_timer,
mdev->motors[VERTICAL_MOTOR].m_kt, HRTIMER_MODE_REL);
}
rk_timer_set_next_event(ns_to_rktimer_cycles(mdev->rk_timer.freq, MOTOR_MAX_SPEED), &mdev->rk_timer);
return 0;
}
@@ -151,12 +470,10 @@ static void motor_ops_stop(struct motor_device *mdev)
return;
if (mdev->motors[HORIZONTAL_MOTOR].motor_current_status !=
MOTOR_IS_STOP) {
hrtimer_cancel(&mdev->horizontal_motor_timer);
motor_off(mdev->motors[HORIZONTAL_MOTOR]);
}
if (mdev->motors[VERTICAL_MOTOR].motor_current_status !=
MOTOR_IS_STOP) {
hrtimer_cancel(&mdev->vertical_motor_timer);
motor_off(mdev->motors[VERTICAL_MOTOR]);
}
mutex_lock(&mdev->dev_mutex);
@@ -183,27 +500,11 @@ static int motor_speed(struct motor_device *mdev, struct motors_input_speed spee
if ((speed.input_x_speed <= MOTOR_MIN_SPEED) &&
(speed.input_x_speed >= MOTOR_MAX_SPEED)) {
mdev->motors[HORIZONTAL_MOTOR].motor_speed = speed.input_x_speed;
if (mdev->motors[HORIZONTAL_MOTOR].motor_current_status ==
MOTOR_IS_RUNNING) {
mdev->motors[HORIZONTAL_MOTOR].m_kt =
ktime_set(0, mdev->motors[HORIZONTAL_MOTOR].motor_speed);
hrtimer_cancel(&mdev->horizontal_motor_timer);
hrtimer_start(&mdev->horizontal_motor_timer,
mdev->motors[HORIZONTAL_MOTOR].m_kt, HRTIMER_MODE_REL);
}
}
if ((speed.input_y_speed <= MOTOR_MIN_SPEED) &&
(speed.input_y_speed >= MOTOR_MAX_SPEED)) {
mdev->motors[VERTICAL_MOTOR].motor_speed = speed.input_y_speed;
if (mdev->motors[VERTICAL_MOTOR].motor_current_status ==
MOTOR_IS_RUNNING) {
mdev->motors[VERTICAL_MOTOR].m_kt =
ktime_set(0, mdev->motors[VERTICAL_MOTOR].motor_speed);
hrtimer_cancel(&mdev->vertical_motor_timer);
hrtimer_start(&mdev->vertical_motor_timer,
mdev->motors[VERTICAL_MOTOR].m_kt, HRTIMER_MODE_REL);
}
}
return 0;
}
@@ -266,6 +567,19 @@ static int motor_set_message(struct motor_device *mdev, struct motors_init_data
return 0;
}
static int motor_set_calibrated_message(struct motor_device *mdev, struct motor_reset_data msg) {
struct motor_device_attribute *motors = mdev->motors;
if (msg.x_cur_steps > mdev->motors[HORIZONTAL_MOTOR].max_steps ||
msg.y_cur_steps > mdev->motors[VERTICAL_MOTOR].max_steps)
return -1;
motors[HORIZONTAL_MOTOR].cur_steps = msg.x_cur_steps;
motors[VERTICAL_MOTOR].cur_steps = msg.y_cur_steps;
return 0;
}
static long motor_ops_reset(struct motor_device *mdev, struct motor_reset_data *rdata)
{
unsigned long flags;
@@ -373,143 +687,6 @@ static int motor_release(struct inode *inode, struct file *file)
return 0;
}
static int meter_turn(struct motor_device_attribute motor)
{
switch (motor.timer_count) {
case 0:
gpio_set_value(motor.motor_gpio[0], 1);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 1:
gpio_set_value(motor.motor_gpio[0], 1);
gpio_set_value(motor.motor_gpio[1], 1);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 2:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 1);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 3:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 1);
gpio_set_value(motor.motor_gpio[2], 1);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 4:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 1);
gpio_set_value(motor.motor_gpio[3], 0);
break;
case 5:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 1);
gpio_set_value(motor.motor_gpio[3], 1);
break;
case 6:
gpio_set_value(motor.motor_gpio[0], 0);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 1);
break;
case 7:
gpio_set_value(motor.motor_gpio[0], 1);
gpio_set_value(motor.motor_gpio[1], 0);
gpio_set_value(motor.motor_gpio[2], 0);
gpio_set_value(motor.motor_gpio[3], 1);
break;
}
return 0;
}
static enum hrtimer_restart motor_horizontal_timer_poll(struct hrtimer *timer)
{
unsigned long flags;
struct motor_device *mdev = container_of(timer, struct motor_device, horizontal_motor_timer);
if (mdev->motors[HORIZONTAL_MOTOR].motor_direction == 'R') {
mdev->motors[HORIZONTAL_MOTOR].timer_count++;
if (mdev->motors[HORIZONTAL_MOTOR].timer_count > 7)
mdev->motors[HORIZONTAL_MOTOR].timer_count = 0;
} else {
if (mdev->motors[HORIZONTAL_MOTOR].timer_count == 0)
mdev->motors[HORIZONTAL_MOTOR].timer_count = 8;
mdev->motors[HORIZONTAL_MOTOR].timer_count--;
}
meter_turn(mdev->motors[HORIZONTAL_MOTOR]);
mdev->motors[HORIZONTAL_MOTOR].real_move_steps++;
mdev->motors[HORIZONTAL_MOTOR].input_move_steps--;
if (mdev->motors[HORIZONTAL_MOTOR].input_move_steps == 0) {
mutex_lock(&mdev->dev_mutex);
spin_lock_irqsave(&mdev->slock, flags);
mdev->motors[HORIZONTAL_MOTOR].motor_current_status = MOTOR_IS_STOP;
if (mdev->motors[HORIZONTAL_MOTOR].motor_direction == 'R')
mdev->motors[HORIZONTAL_MOTOR].cur_steps = mdev->motors[HORIZONTAL_MOTOR].cur_steps +
mdev->motors[HORIZONTAL_MOTOR].real_move_steps;
else if (mdev->motors[HORIZONTAL_MOTOR].motor_direction == 'L')
mdev->motors[HORIZONTAL_MOTOR].cur_steps = mdev->motors[HORIZONTAL_MOTOR].cur_steps -
mdev->motors[HORIZONTAL_MOTOR].real_move_steps;
mdev->motors[HORIZONTAL_MOTOR].input_move_steps = 0;
mdev->motors[HORIZONTAL_MOTOR].real_move_steps = 0;
spin_unlock_irqrestore(&mdev->slock, flags);
mutex_unlock(&mdev->dev_mutex);
printk("the x steps after stop%d\n", mdev->motors[HORIZONTAL_MOTOR].cur_steps);
motor_off(mdev->motors[HORIZONTAL_MOTOR]);
return HRTIMER_NORESTART;
}
hrtimer_forward(timer, timer->base->get_time(), mdev->motors[HORIZONTAL_MOTOR].m_kt);
return HRTIMER_RESTART;
}
static enum hrtimer_restart motor_vertical_timer_poll(struct hrtimer *timer)
{
unsigned long flags;
struct motor_device *mdev = container_of(timer, struct motor_device, vertical_motor_timer);
if (mdev->motors[VERTICAL_MOTOR].motor_direction == 'R') {
mdev->motors[VERTICAL_MOTOR].timer_count++;
if (mdev->motors[VERTICAL_MOTOR].timer_count > 7)
mdev->motors[VERTICAL_MOTOR].timer_count = 0;
} else {
if (mdev->motors[VERTICAL_MOTOR].timer_count == 0)
mdev->motors[VERTICAL_MOTOR].timer_count = 8;
mdev->motors[VERTICAL_MOTOR].timer_count--;
}
meter_turn(mdev->motors[VERTICAL_MOTOR]);
mdev->motors[VERTICAL_MOTOR].real_move_steps++;
mdev->motors[VERTICAL_MOTOR].input_move_steps--;
if (mdev->motors[VERTICAL_MOTOR].input_move_steps == 0) {
mutex_lock(&mdev->dev_mutex);
spin_lock_irqsave(&mdev->slock, flags);
mdev->motors[VERTICAL_MOTOR].motor_current_status = MOTOR_IS_STOP;
if (mdev->motors[VERTICAL_MOTOR].motor_direction == 'R')
mdev->motors[VERTICAL_MOTOR].cur_steps = mdev->motors[VERTICAL_MOTOR].cur_steps +
mdev->motors[VERTICAL_MOTOR].real_move_steps;
else if (mdev->motors[VERTICAL_MOTOR].motor_direction == 'L')
mdev->motors[VERTICAL_MOTOR].cur_steps = mdev->motors[VERTICAL_MOTOR].cur_steps -
mdev->motors[VERTICAL_MOTOR].real_move_steps;
mdev->motors[VERTICAL_MOTOR].input_move_steps = 0;
mdev->motors[VERTICAL_MOTOR].real_move_steps = 0;
spin_unlock_irqrestore(&mdev->slock, flags);
mutex_unlock(&mdev->dev_mutex);
printk("the y steps after stop%d\n", mdev->motors[VERTICAL_MOTOR].cur_steps);
motor_off(mdev->motors[VERTICAL_MOTOR]);
return HRTIMER_NORESTART;
}
hrtimer_forward(timer, timer->base->get_time(), mdev->motors[VERTICAL_MOTOR].m_kt);
return HRTIMER_RESTART;
}
static long motor_ioctl(struct file *file, unsigned int cmd, unsigned long value)
{
struct miscdevice *dev = file->private_data;
@@ -520,7 +697,6 @@ static long motor_ioctl(struct file *file, unsigned int cmd, unsigned long value
printk("Please Open /dev/motor Firstly\n");
return -EPERM;
}
switch (cmd) {
case MOTOR_STOP: {
motor_ops_stop(mdev);
@@ -562,7 +738,7 @@ static long motor_ioctl(struct file *file, unsigned int cmd, unsigned long value
return -EFAULT;
}
motor_ops_move(mdev, dst.input_x_steps, dst.input_y_steps);
printk("MOTOR_MOVE!!!!!!!!!!!!!!!!!!!\n");
//printk("MOTOR_MOVE!!!!!!!!!!!!!!!!!!!\n");
break;
}
case MOTOR_GET_STATUS: {
@@ -624,6 +800,22 @@ static long motor_ioctl(struct file *file, unsigned int cmd, unsigned long value
/*printk("MOTOR_SET_STATUS!!!!!!!!!!!!!!!!!!\n");*/
break;
}
case MOTOR_RESET_NOTCALI: {
struct motor_reset_data data;
if (copy_from_user(&data, (void __user *)value,
sizeof(struct motor_reset_data))) {
dev_err(mdev->dev, "[%s][%d] copy from user error\n",
__func__, __LINE__);
return -EFAULT;
}
printk("saved location x is %d, y is %d \n", data.x_cur_steps, data.y_cur_steps);
ret = motor_set_calibrated_message(mdev,data);
if (ret) {
dev_err(mdev->dev,"motor_set_calibrated_messgae fail\n");
ret = -1;
}
break;
}
default:
return -EINVAL;
}
@@ -917,12 +1109,12 @@ static void motor_release_gpio(struct motor_device *mdev)
static int motor_probe(struct platform_device *pdev)
{
int ret;
int i = 0, index = 0;
struct motor_device_attribute *motor = NULL;
struct motor_device *mdev;
struct proc_dir_entry *proc = NULL;
struct proc_dir_entry *motor_info = NULL;
int ret = 0;
printk("%s enter\n", __func__);
mdev = devm_kzalloc(&pdev->dev, sizeof(struct motor_device), GFP_KERNEL);
@@ -947,11 +1139,6 @@ static int motor_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "misc_register failed\n");
}
hrtimer_init(&mdev->horizontal_motor_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
mdev->horizontal_motor_timer.function = motor_horizontal_timer_poll;
hrtimer_init(&mdev->vertical_motor_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
mdev->vertical_motor_timer.function = motor_vertical_timer_poll;
proc = proc_mkdir("motor", NULL);
if (!proc) {
mdev->proc = NULL;
@@ -982,9 +1169,16 @@ static int motor_probe(struct platform_device *pdev)
ret = -1;
goto motor_request_gpio_fail;
}
if (rk_timer_init(pdev, mdev) == NULL) {
printk("init timer fail\n");
ret = -1;
goto motor_timer_init_fail;
}
printk("%s leave\n", __func__);
return 0;
motor_timer_init_fail:
motor_release_gpio(mdev);
motor_request_gpio_fail:
if (mdev->proc)
proc_remove(mdev->proc);
@@ -999,7 +1193,7 @@ error_devm_kzalloc:
static int motor_remove(struct platform_device *pdev)
{
struct motor_device *mdev = platform_get_drvdata(pdev);
rk_timer_deinit(mdev);
mutex_destroy(&mdev->dev_mutex);
motor_release_gpio(mdev);
if (mdev->proc)
@@ -1009,8 +1203,9 @@ static int motor_remove(struct platform_device *pdev)
return 0;
}
struct of_device_id of_match_table = {
.compatible = "motor"
struct of_device_id of_match_table[] = {
{ .compatible = "motor",},
{},
};
static struct platform_driver motor_platform_driver = {
@@ -1019,7 +1214,7 @@ static struct platform_driver motor_platform_driver = {
.driver = {
.name = "motor",
.owner = THIS_MODULE,
.of_match_table = &of_match_table,
.of_match_table = of_match_ptr(of_match_table),
}
};

View File

@@ -26,75 +26,7 @@
#define MOTOR_GOBACK _IOW('M', 5, long)
#define MOTOR_CRUISE _IOW('M', 6, long)
#define MOTOR_SET_STATUS _IOW('M', 7, long)
enum motor_status {
MOTOR_IS_STOP,
MOTOR_IS_RUNNING,
};
struct motor_reset_data {
unsigned int x_max_steps;
unsigned int y_max_steps;
unsigned int reset_x;
unsigned int reset_y;
};
enum motor_cnt {
HORIZONTAL_MOTOR,
VERTICAL_MOTOR,
HAS_MOTOR_CNT,
};
struct motor_device_attribute {
char motor_direction;
int max_steps;
int input_move_steps;
int real_move_steps;
int cur_steps;
int motor_speed;
int reset_point;
ktime_t m_kt;
unsigned int timer_count;
int motor_gpio[MAX_GPIO_NUM];
enum motor_status motor_current_status;
};
struct motor_message {
int x_cur_steps;
int y_cur_steps;
enum motor_status x_cur_status;
enum motor_status y_cur_status;
int x_cur_speed;
int y_cur_speed;
};
struct motors_input_steps {
int input_x_steps;
int input_y_steps;
};
struct motors_input_speed {
int input_x_speed;
int input_y_speed;
};
struct motors_init_data {
struct motor_reset_data motor_data;
struct motors_input_speed motor_speed;
};
struct motor_device {
struct proc_dir_entry *proc;
struct miscdevice misc_dev;
struct device *dev;
struct mutex dev_mutex;
spinlock_t slock;
int motor_open_flag;
struct hrtimer horizontal_motor_timer;
struct hrtimer vertical_motor_timer;
struct motor_device_attribute motors[HAS_MOTOR_CNT];
};
#define MOTOR_RESET_NOTCALI _IOW('M', 8, long)
#endif //__RK_MOTOR_H__