From 6e53c59739e3668ef380c1f3e1fb142e1a7e45eb Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 11:45:17 +0900 Subject: [PATCH 01/26] renamed rtmouse.c to rtmouse_main.c --- src/drivers/Makefile.header_from_apt | 5 +++-- src/drivers/Makefile.header_from_source | 3 ++- src/drivers/{rtmouse.c => rtmouse_main.c} | 0 3 files changed, 5 insertions(+), 3 deletions(-) rename src/drivers/{rtmouse.c => rtmouse_main.c} (100%) diff --git a/src/drivers/Makefile.header_from_apt b/src/drivers/Makefile.header_from_apt index c43215a..6b9563f 100644 --- a/src/drivers/Makefile.header_from_apt +++ b/src/drivers/Makefile.header_from_apt @@ -1,17 +1,18 @@ MODULE:= rtmouse obj-m:= $(MODULE).o +$(MODULE)-y:= $(MODULE)_main.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux-headers-$(shell uname -r) VERBOSE:=0 -rtmouse.ko: rtmouse.c rtmouse.h +$(MODULE).ko: $(MODULE)_main.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) clean -install: rtmouse.ko +install: $(MODULE).ko cp ../../50-rtmouse.rules /etc/udev/rules.d/ uninstall: diff --git a/src/drivers/Makefile.header_from_source b/src/drivers/Makefile.header_from_source index 8d43e03..89ae3b7 100644 --- a/src/drivers/Makefile.header_from_source +++ b/src/drivers/Makefile.header_from_source @@ -1,11 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o +$(MODULE)-y:= $(MODULE)_main.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux VERBOSE:=0 -rtmouse.ko: rtmouse.c rtmouse.h +$(MODULE).ko: $(MODULE)_main.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/rtmouse.c b/src/drivers/rtmouse_main.c similarity index 100% rename from src/drivers/rtmouse.c rename to src/drivers/rtmouse_main.c From a4b6b0e8d8d8373a7c252d1081449c4559d2077d Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 11:48:31 +0900 Subject: [PATCH 02/26] =?UTF-8?q?lint=E3=81=AE=E5=AF=BE=E8=B1=A1=E3=83=95?= =?UTF-8?q?=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .test/lint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.test/lint.sh b/.test/lint.sh index c445865..c85fe17 100755 --- a/.test/lint.sh +++ b/.test/lint.sh @@ -6,7 +6,7 @@ SRC_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); cd ../; pwd) lint_driver () { pushd $SRC_DIR/src/drivers - python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse.c + python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_main.c python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse.h popd } From 4f0ef43c5a4008baf3d0dd7313d6082d50d8e479 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 13:53:35 +0900 Subject: [PATCH 03/26] =?UTF-8?q?C=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E5=88=86=E5=89=B2=E3=81=AE=E6=BA=96=E5=82=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/Makefile.header_from_apt | 4 ++-- src/drivers/Makefile.header_from_source | 4 ++-- src/drivers/rtmouse.h | 27 +++---------------------- src/drivers/rtmouse_dev.c | 5 +++++ src/drivers/rtmouse_main.c | 27 +++++++++++++++++++++++++ 5 files changed, 39 insertions(+), 28 deletions(-) create mode 100644 src/drivers/rtmouse_dev.c diff --git a/src/drivers/Makefile.header_from_apt b/src/drivers/Makefile.header_from_apt index 6b9563f..bc74e19 100644 --- a/src/drivers/Makefile.header_from_apt +++ b/src/drivers/Makefile.header_from_apt @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux-headers-$(shell uname -r) VERBOSE:=0 -$(MODULE).ko: $(MODULE)_main.c $(MODULE).h +$(MODULE).ko: $(MODULE)_dev.c $(MODULE)_main.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/Makefile.header_from_source b/src/drivers/Makefile.header_from_source index 89ae3b7..0d8510c 100644 --- a/src/drivers/Makefile.header_from_source +++ b/src/drivers/Makefile.header_from_source @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux VERBOSE:=0 -$(MODULE).ko: $(MODULE)_main.c $(MODULE).h +$(MODULE).ko: $(MODULE)_dev.c $(MODULE)_main.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index 573e762..ac78318 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -66,30 +66,9 @@ #define ID_DEV_CNT 8 #define ID_DEV_SIZE 9 -/* --- Device Numbers --- */ -const unsigned int NUM_DEV[ID_DEV_SIZE] = { - [ID_DEV_LED] = 4, [ID_DEV_SWITCH] = 3, [ID_DEV_SENSOR] = 1, - [ID_DEV_BUZZER] = 1, [ID_DEV_MOTORRAWR] = 1, [ID_DEV_MOTORRAWL] = 1, - [ID_DEV_MOTOREN] = 1, [ID_DEV_MOTOR] = 1, [ID_DEV_CNT] = 2}; - -/* --- Device Names --- */ -const char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", - [ID_DEV_SWITCH] = "rtswitch", - [ID_DEV_SENSOR] = "rtlightsensor", - [ID_DEV_BUZZER] = "rtbuzzer", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l", - [ID_DEV_MOTOREN] = "rtmotoren", - [ID_DEV_MOTOR] = "rtmotor"}; - -const char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", - [ID_DEV_SWITCH] = "rtswitch%u", - [ID_DEV_SENSOR] = "rtlightsensor%u", - [ID_DEV_BUZZER] = "rtbuzzer%u", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", - [ID_DEV_MOTOREN] = "rtmotoren%u", - [ID_DEV_MOTOR] = "rtmotor%u"}; +extern unsigned int NUM_DEV[ID_DEV_SIZE]; +extern char *NAME_DEV[ID_DEV_SIZE]; +extern char *NAME_DEV_U[ID_DEV_SIZE]; #define NUM_DEV_TOTAL \ (NUM_DEV[ID_DEV_LED] + NUM_DEV[ID_DEV_SWITCH] + \ diff --git a/src/drivers/rtmouse_dev.c b/src/drivers/rtmouse_dev.c new file mode 100644 index 0000000..7dc24b8 --- /dev/null +++ b/src/drivers/rtmouse_dev.c @@ -0,0 +1,5 @@ +#include "rtmouse.h" + +void tmp_func(void) { + return; +} diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 5b2d447..c17092f 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -29,12 +29,39 @@ MODULE_LICENSE("GPL"); MODULE_VERSION("3.3.2"); MODULE_DESCRIPTION("Raspberry Pi Mouse device driver"); +/* --- Device Numbers --- */ +unsigned int NUM_DEV[ID_DEV_SIZE] = { + [ID_DEV_LED] = 4, [ID_DEV_SWITCH] = 3, [ID_DEV_SENSOR] = 1, + [ID_DEV_BUZZER] = 1, [ID_DEV_MOTORRAWR] = 1, [ID_DEV_MOTORRAWL] = 1, + [ID_DEV_MOTOREN] = 1, [ID_DEV_MOTOR] = 1, [ID_DEV_CNT] = 2}; + +/* --- Device Names --- */ +char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", + [ID_DEV_SWITCH] = "rtswitch", + [ID_DEV_SENSOR] = "rtlightsensor", + [ID_DEV_BUZZER] = "rtbuzzer", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l", + [ID_DEV_MOTOREN] = "rtmotoren", + [ID_DEV_MOTOR] = "rtmotor"}; + +char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", + [ID_DEV_SWITCH] = "rtswitch%u", + [ID_DEV_SENSOR] = "rtlightsensor%u", + [ID_DEV_BUZZER] = "rtbuzzer%u", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", + [ID_DEV_MOTOREN] = "rtmotoren%u", + [ID_DEV_MOTOR] = "rtmotor%u"}; + +// used in by register_dev() and cleanup_each_dev() static int _major_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = DEV_MAJOR, [ID_DEV_SWITCH] = DEV_MAJOR, [ID_DEV_SENSOR] = DEV_MAJOR, [ID_DEV_BUZZER] = DEV_MAJOR, [ID_DEV_MOTORRAWR] = DEV_MAJOR, [ID_DEV_MOTORRAWL] = DEV_MAJOR, [ID_DEV_MOTOREN] = DEV_MAJOR, [ID_DEV_MOTOR] = DEV_MAJOR}; +// used in register_dev() and cleanup_each_dev() static int _minor_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = DEV_MINOR, [ID_DEV_SWITCH] = DEV_MINOR, [ID_DEV_SENSOR] = DEV_MINOR, [ID_DEV_BUZZER] = DEV_MINOR, From 93ad739e6abbfca757a6ddfa9c4817b192ee36f8 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 14:23:49 +0900 Subject: [PATCH 04/26] =?UTF-8?q?=E5=A4=96=E9=83=A8=E5=A4=89=E6=95=B0?= =?UTF-8?q?=E3=82=92=E3=83=98=E3=83=83=E3=83=80=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=A7=E5=AE=A3=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse.h | 35 ++++++++++++++++++++++++++----- src/drivers/rtmouse_main.c | 42 +++++++++++++++++++------------------- 2 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index ac78318..084b108 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -66,10 +66,6 @@ #define ID_DEV_CNT 8 #define ID_DEV_SIZE 9 -extern unsigned int NUM_DEV[ID_DEV_SIZE]; -extern char *NAME_DEV[ID_DEV_SIZE]; -extern char *NAME_DEV_U[ID_DEV_SIZE]; - #define NUM_DEV_TOTAL \ (NUM_DEV[ID_DEV_LED] + NUM_DEV[ID_DEV_SWITCH] + \ NUM_DEV[ID_DEV_SENSOR] + NUM_DEV[ID_DEV_BUZZER] + \ @@ -230,7 +226,36 @@ extern char *NAME_DEV_U[ID_DEV_SIZE]; #define SIGNED_COUNT_SIZE 32767 #define MAX_PULSE_COUNT 65535 -/* -- Buffer -- */ +/* --- Buffer --- */ #define MAX_BUFLEN 64 +/* --- extern --- */ +extern unsigned int NUM_DEV[ID_DEV_SIZE]; +extern char *NAME_DEV[ID_DEV_SIZE]; +extern char *NAME_DEV_U[ID_DEV_SIZE]; +extern int _major_dev[ID_DEV_SIZE]; +extern int _minor_dev[ID_DEV_SIZE]; +extern struct cdev *cdev_array; +extern struct class *class_dev[ID_DEV_SIZE]; +extern volatile void __iomem *pwm_base; +extern volatile void __iomem *clk_base; +extern volatile uint32_t *gpio_base; +extern volatile int cdev_index; +extern struct mutex lock; +extern struct spi_device_id mcp3204_id[]; +extern struct spi_board_info mcp3204_info; +extern struct spi_driver mcp3204_driver; +extern struct i2c_client *i2c_client_r; +extern struct i2c_client *i2c_client_l; +extern unsigned int motor_l_freq_is_positive; +extern unsigned int motor_r_freq_is_positive; +extern struct i2c_device_id i2c_counter_id[]; +extern struct i2c_driver i2c_counter_driver; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) +extern struct device *mcp320x_dev; +#endif + +void tmp_func(void); + #endif // RTMOUSE_H diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index c17092f..197ec8e 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -55,34 +55,32 @@ char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", [ID_DEV_MOTOR] = "rtmotor%u"}; // used in by register_dev() and cleanup_each_dev() -static int _major_dev[ID_DEV_SIZE] = { +int _major_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = DEV_MAJOR, [ID_DEV_SWITCH] = DEV_MAJOR, [ID_DEV_SENSOR] = DEV_MAJOR, [ID_DEV_BUZZER] = DEV_MAJOR, [ID_DEV_MOTORRAWR] = DEV_MAJOR, [ID_DEV_MOTORRAWL] = DEV_MAJOR, [ID_DEV_MOTOREN] = DEV_MAJOR, [ID_DEV_MOTOR] = DEV_MAJOR}; // used in register_dev() and cleanup_each_dev() -static int _minor_dev[ID_DEV_SIZE] = { +int _minor_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = DEV_MINOR, [ID_DEV_SWITCH] = DEV_MINOR, [ID_DEV_SENSOR] = DEV_MINOR, [ID_DEV_BUZZER] = DEV_MINOR, [ID_DEV_MOTORRAWR] = DEV_MINOR, [ID_DEV_MOTORRAWL] = DEV_MINOR, [ID_DEV_MOTOREN] = DEV_MINOR, [ID_DEV_MOTOR] = DEV_MINOR}; /* --- General Options --- */ -static struct cdev *cdev_array = NULL; -static struct class *class_dev[ID_DEV_SIZE] = { +struct cdev *cdev_array = NULL; +struct class *class_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = NULL, [ID_DEV_SWITCH] = NULL, [ID_DEV_SENSOR] = NULL, [ID_DEV_BUZZER] = NULL, [ID_DEV_MOTORRAWR] = NULL, [ID_DEV_MOTORRAWL] = NULL, [ID_DEV_MOTOREN] = NULL, [ID_DEV_MOTOR] = NULL}; -static volatile void __iomem *pwm_base; -static volatile void __iomem *clk_base; -static volatile uint32_t *gpio_base; - -static volatile int cdev_index = 0; - -static struct mutex lock; +volatile void __iomem *pwm_base; +volatile void __iomem *clk_base; +volatile uint32_t *gpio_base; +volatile int cdev_index = 0; +struct mutex lock; /* --- Function Declarations --- */ static void set_motor_r_freq(int freq); @@ -123,13 +121,13 @@ struct mcp3204_drvdata { /* --- Static variables --- */ /* SPI device ID */ -static struct spi_device_id mcp3204_id[] = { +struct spi_device_id mcp3204_id[] = { {"mcp3204", 0}, {}, }; /* SPI Info */ -static struct spi_board_info mcp3204_info = { +struct spi_board_info mcp3204_info = { .modalias = "mcp3204", .max_speed_hz = 100000, .bus_num = 0, @@ -138,11 +136,11 @@ static struct spi_board_info mcp3204_info = { }; #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) -static struct device *mcp320x_dev; +struct device *mcp320x_dev; #endif /* SPI Dirver Info */ -static struct spi_driver mcp3204_driver = { +struct spi_driver mcp3204_driver = { .driver = { .name = DEVNAME_SENSOR, @@ -165,20 +163,20 @@ struct rtcnt_device_info { int raw_pulse_count; }; -static struct i2c_client *i2c_client_r = NULL; -static struct i2c_client *i2c_client_l = NULL; -static unsigned int motor_l_freq_is_positive = 1; -static unsigned int motor_r_freq_is_positive = 1; +struct i2c_client *i2c_client_r = NULL; +struct i2c_client *i2c_client_l = NULL; +unsigned int motor_l_freq_is_positive = 1; +unsigned int motor_r_freq_is_positive = 1; /* I2C Device ID */ -static struct i2c_device_id i2c_counter_id[] = { +struct i2c_device_id i2c_counter_id[] = { {DEVNAME_CNTL, 0}, {DEVNAME_CNTR, 1}, {}, }; /* I2C Dirver Info */ -static struct i2c_driver i2c_counter_driver = { +struct i2c_driver i2c_counter_driver = { .driver = { .name = "rtcounter", @@ -1673,6 +1671,8 @@ int dev_init_module(void) int registered_devices = 0; size_t size; + tmp_func(); + /* log loding message */ printk(KERN_INFO "%s: loading driver...\n", DRIVER_NAME); From bd7640b4099c22dbb81c40a6b6601345397b7d65 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 15:07:19 +0900 Subject: [PATCH 05/26] =?UTF-8?q?=E3=83=87=E3=83=90=E3=82=A4=E3=82=B9?= =?UTF-8?q?=E9=96=A2=E9=80=A3=E3=81=AE=E9=96=A2=E6=95=B0=E3=82=92rtmouse?= =?UTF-8?q?=5Fdev.c=E3=81=B8=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse.h | 40 +- src/drivers/rtmouse_dev.c | 845 +++++++++++++++++++++++++++++++++++- src/drivers/rtmouse_main.c | 855 +------------------------------------ 3 files changed, 883 insertions(+), 857 deletions(-) diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index 084b108..a729f4c 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -229,6 +229,29 @@ /* --- Buffer --- */ #define MAX_BUFLEN 64 +/* --- Variable Type definitions --- */ +/* SPI */ +struct mcp3204_drvdata { + struct spi_device *spi; + struct mutex lock; + unsigned char tx[MCP320X_PACKET_SIZE] ____cacheline_aligned; + unsigned char rx[MCP320X_PACKET_SIZE] ____cacheline_aligned; + struct spi_transfer xfer ____cacheline_aligned; + struct spi_message msg ____cacheline_aligned; +}; + +/* I2C */ +struct rtcnt_device_info { + struct cdev cdev; + unsigned int device_major; + unsigned int device_minor; + struct class *device_class; + struct i2c_client *client; + struct mutex lock; + int signed_pulse_count; + int raw_pulse_count; +}; + /* --- extern --- */ extern unsigned int NUM_DEV[ID_DEV_SIZE]; extern char *NAME_DEV[ID_DEV_SIZE]; @@ -251,11 +274,26 @@ extern unsigned int motor_l_freq_is_positive; extern unsigned int motor_r_freq_is_positive; extern struct i2c_device_id i2c_counter_id[]; extern struct i2c_driver i2c_counter_driver; +extern struct file_operations dev_fops[ID_DEV_SIZE]; #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) extern struct device *mcp320x_dev; #endif -void tmp_func(void); +/* --- function --- */ +int dev_open(struct inode *inode, struct file *filep); +int dev_release(struct inode *inode, struct file *filep); +int i2c_dev_open(struct inode *inode, struct file *filep); +int i2c_dev_release(struct inode *inode, struct file *filep); +ssize_t led_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); +ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); +ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); +ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); +ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); +ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); +int rpi_gpio_function_set(int pin, uint32_t func); +void rpi_gpio_set32(uint32_t mask, uint32_t val); +void rpi_gpio_clear32(uint32_t mask, uint32_t val); +int buzzer_init(void); #endif // RTMOUSE_H diff --git a/src/drivers/rtmouse_dev.c b/src/drivers/rtmouse_dev.c index 7dc24b8..b7b57ab 100644 --- a/src/drivers/rtmouse_dev.c +++ b/src/drivers/rtmouse_dev.c @@ -1,5 +1,846 @@ +/* + * + * rtmouse_dev.c + * Raspberry Pi Mouse device driver + * + * Version: 3.3.2 + * + * Copyright (C) 2015-2024 RT Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + #include "rtmouse.h" -void tmp_func(void) { - return; +/* + * update_signed_count - update signed pulse count of dev_info + * called by rtcnt_read() + */ +void update_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) +{ + int diff_count = rtcnt_count - dev_info->raw_pulse_count; + + // カウントがMAX_PULSE_COUNTから0に変わる場合の処理 + // ただし、それ以外でもdiffが負の値になることがある + // そのため、diffが十分に大きな負の値の場合に処理する + // if(diff_count < 0) では正常に動作しない + if (diff_count < -SIGNED_COUNT_SIZE) { + diff_count += MAX_PULSE_COUNT; + } + + if (dev_info->client->addr == DEV_ADDR_CNTL) { + if (motor_l_freq_is_positive) { + dev_info->signed_pulse_count += diff_count; + } else { + dev_info->signed_pulse_count -= diff_count; + } + } else { + if (motor_r_freq_is_positive) { + dev_info->signed_pulse_count += diff_count; + } else { + dev_info->signed_pulse_count -= diff_count; + } + } + + if (dev_info->signed_pulse_count > SIGNED_COUNT_SIZE || + dev_info->signed_pulse_count < -SIGNED_COUNT_SIZE) { + dev_info->signed_pulse_count = 0; + } +} + +/* + * i2c_counter_set - set value to I2C pulse counter + * called by cntr_write() and cntl_write() + */ +static int i2c_counter_set(struct rtcnt_device_info *dev_info, int setval) +{ + int ret = 0; + int lsb = 0, msb = 0; + struct i2c_client *client = dev_info->client; + + // printk(KERN_INFO "set 0x%x = 0x%x\n", client->addr, setval); + msb = (setval >> 8) & 0xFF; + lsb = setval & 0xFF; + mutex_lock(&dev_info->lock); + // printk(KERN_INFO "set 0x%x msb = 0x%x\n", client->addr, msb); + ret = i2c_smbus_write_byte_data(client, 0x10, msb); + if (ret < 0) { + printk(KERN_ERR + "%s: Failed writing to i2c counter device, addr=0x%x\n", + __func__, client->addr); + return -ENODEV; + } + // printk(KERN_INFO "set 0x%x lsb = 0x%x\n", client->addr, lsb); + ret = i2c_smbus_write_byte_data(client, 0x11, lsb); + if (ret < 0) { + printk(KERN_ERR + "%s: Failed writing to i2c counter device, addr=0x%x\n", + __func__, client->addr); + return -ENODEV; + } + mutex_unlock(&dev_info->lock); + return ret; +} + +/* + * i2c_counter_read - get value from I2C pulse counter + * called by rtcnt_read() + */ +static int i2c_counter_read(struct rtcnt_device_info *dev_info, int *ret) +{ + int lsb = 0, msb = 0; + // printk(KERN_INFO "read 0x%x\n", client->addr); + struct i2c_client *client = dev_info->client; + mutex_lock(&dev_info->lock); + + lsb = i2c_smbus_read_byte_data(client, CNT_ADDR_LSB); + if (lsb < 0) { + printk( + KERN_ERR + "%s: Failed reading from i2c counter device, addr=0x%x\n", + __func__, client->addr); + return -ENODEV; + } + msb = i2c_smbus_read_byte_data(client, CNT_ADDR_MSB); + if (msb < 0) { + printk( + KERN_ERR + "%s: Failed reading from i2c counter device, addr=0x%x\n", + __func__, client->addr); + return -ENODEV; + } + mutex_unlock(&dev_info->lock); + + *ret = ((msb << 8) & 0xFF00) + (lsb & 0xFF); + + // printk(KERN_INFO "0x%x == 0x%x\n", client->addr, *ret); + return 0; +} + +/* + * reset_signed_count - reset signed pulse count of dev_info + * called by rtcnt_write() + */ +void reset_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) +{ + int raw_count; + + if (rtcnt_count > SIGNED_COUNT_SIZE) { + rtcnt_count = SIGNED_COUNT_SIZE; + } else if (rtcnt_count < -SIGNED_COUNT_SIZE) { + rtcnt_count = -SIGNED_COUNT_SIZE; + } + dev_info->signed_pulse_count = rtcnt_count; + i2c_counter_read(dev_info, &raw_count); + dev_info->raw_pulse_count = raw_count; +} + +/* + * rtcnt_read - Read value from right/left pulse counter + * Read function of /dev/rtcounter_* + */ +static ssize_t rtcnt_read(struct file *filep, char __user *buf, size_t count, + loff_t *f_pos) +{ + struct rtcnt_device_info *dev_info = filep->private_data; + + unsigned char rw_buf[64]; + int buflen; + + int rtcnt_count = 0; + if (*f_pos > 0) + return 0; /* close device */ + i2c_counter_read(dev_info, &rtcnt_count); + + if (dev_info->device_minor == 1) { + update_signed_count(dev_info, rtcnt_count); + dev_info->raw_pulse_count = rtcnt_count; + rtcnt_count = dev_info->signed_pulse_count; + } else { + dev_info->raw_pulse_count = rtcnt_count; + } + + /* set sensor data to rw_buf(static buffer) */ + sprintf(rw_buf, "%d\n", rtcnt_count); + buflen = strlen(rw_buf); + count = buflen; + + /* copy data to user area */ + if (copy_to_user((void *)buf, &rw_buf, count)) { + printk(KERN_INFO "err read buffer from %s\n", rw_buf); + printk(KERN_INFO "err sample_char_read size(%zu)\n", count); + printk(KERN_INFO "sample_char_read size err(%d)\n", -EFAULT); + return -EFAULT; + } + *f_pos += count; + return count; +} + +/* + * cnt_write - Set value to right/left pulse counter + * Write function of /dev/rtcounter + */ +static ssize_t rtcnt_write(struct file *filep, const char __user *buf, + size_t count, loff_t *pos) +{ + struct rtcnt_device_info *dev_info = filep->private_data; + + int rtcnt_count = 0; + int ret; + + ret = kstrtoint_from_user(buf, count, 10, &rtcnt_count); + if (ret) { + printk(KERN_ERR "%s: error parsing string to int in %s()\n", + DRIVER_NAME, __func__); + return ret; + } + + i2c_counter_set(dev_info, rtcnt_count); + + if (dev_info->device_minor == 1) { + reset_signed_count(dev_info, rtcnt_count); + } + + printk(KERN_INFO "%s: set pulse counter value %d\n", DRIVER_NAME, + rtcnt_count); + return count; +} + +/* + * Read Push Switches + * return 0 : device close + */ +static ssize_t sw_read(struct file *filep, char __user *buf, size_t count, + loff_t *f_pos) +{ + int buflen = 0; + unsigned char rw_buf[MAX_BUFLEN]; + unsigned int ret = 0; + int len; + int index; + unsigned int pin = SW1_PIN; + uint32_t mask; + int minor = *((int *)filep->private_data); +#if RASPBERRYPI == 4 + int pullreg = GPPUPPDN1 + (pin >> 4); // SW1, 2, 3 is between GPIO16-31 + int pullshift = (pin & 0xf) << 1; + unsigned int pullbits; + unsigned int pull; +#endif + + switch (minor) { + case 0: + pin = SW1_PIN; + break; + case 1: + pin = SW2_PIN; + break; + case 2: + pin = SW3_PIN; + break; + default: + return 0; + break; + } + + if (*f_pos > 0) + return 0; /* End of file */ + +#if RASPBERRYPI == 4 + pull = GPIO_PULLUP; + pullbits = *(gpio_base + pullreg); + pullbits &= ~(3 << pullshift); + pullbits |= (pull << pullshift); + *(gpio_base + pullreg) = pullbits; +#else + // プルモード (2bit)を書き込む NONE/DOWN/UP + gpio_base[37] = GPIO_PULLUP & 0x3; // GPPUD + // ピンにクロックを供給(前後にウェイト) + msleep(1); + gpio_base[38] = 0x1 << pin; // GPPUDCLK0 + msleep(1); + // プルモード・クロック状態をクリアして終了 + gpio_base[37] = 0; + gpio_base[38] = 0; +#endif + + index = RPI_GPFSEL0_INDEX + pin / 10; + mask = ~(0x7 << ((pin % 10) * 3)); + + ret = ((gpio_base[13] & (0x01 << pin)) != 0); + sprintf(rw_buf, "%d\n", ret); + + buflen = strlen(rw_buf); + count = buflen; + len = buflen; + + if (copy_to_user((void *)buf, &rw_buf, count)) { + printk(KERN_INFO "err read buffer from ret %d\n", ret); + printk(KERN_INFO "err read buffer from %s\n", rw_buf); + printk(KERN_INFO "err sample_char_read size(%zu)\n", count); + printk(KERN_INFO "sample_char_read size err(%d)\n", -EFAULT); + return 0; + } + *f_pos += count; + + return count; +} + +/* + * mcp3204_get_value - get sensor data from MCP3204 + * called by 'sensor_read' + */ +static unsigned int mcp3204_get_value(int channel) +{ + struct device *dev; + struct mcp3204_drvdata *data; + struct spi_device *spi; + char str[128]; + + unsigned int r = 0; + unsigned char c = channel & 0x03; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) + + if (mcp320x_dev == NULL) + return 0; + dev = mcp320x_dev; + +#else + struct spi_master *master; + master = spi_busnum_to_master(mcp3204_info.bus_num); + snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), + mcp3204_info.chip_select); + dev = bus_find_device_by_name(&spi_bus_type, NULL, str); +#endif + + spi = to_spi_device(dev); + data = (struct mcp3204_drvdata *)spi_get_drvdata(spi); + mutex_lock(&data->lock); + data->tx[0] = 1 << 2; // start bit + data->tx[0] |= 1 << 1; // Single + data->tx[1] = c << 6; // channel + data->tx[2] = 0; + + if (spi_sync(data->spi, &data->msg)) { + printk(KERN_INFO "%s: spi_sync_transfer returned non zero\n", + __func__); + } + + mutex_unlock(&data->lock); + + r = (data->rx[1] & 0xf) << 8; + r |= data->rx[2]; + + // printk(KERN_INFO "%s: get result on ch[%d] : %04d\n", __func__, + // channel, r); + + return r; +} + +/* + * Read Sensor information + * return 0 : device close + */ +static ssize_t sensor_read(struct file *filep, char __user *buf, size_t count, + loff_t *f_pos) +{ + int buflen = 0; + unsigned char rw_buf[MAX_BUFLEN]; + unsigned int ret = 0; + int len; + + // printk(KERN_INFO "new\n"); + + int usecs = 30; + int rf = 0, lf = 0, r = 0, l = 0; + int orf = 0, olf = 0, or = 0, ol = 0; + + if (*f_pos > 0) + return 0; /* End of file */ + + /* get values through MCP3204 */ + /* Right side */ + or = mcp3204_get_value(R_AD_CH); + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << R_LED_BASE); + udelay(usecs); + r = mcp3204_get_value(R_AD_CH); + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << R_LED_BASE); + udelay(usecs); + /* Left side */ + ol = mcp3204_get_value(L_AD_CH); + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << L_LED_BASE); + udelay(usecs); + l = mcp3204_get_value(L_AD_CH); + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << L_LED_BASE); + udelay(usecs); + /* Right front side */ + orf = mcp3204_get_value(RF_AD_CH); + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << RF_LED_BASE); + udelay(usecs); + rf = mcp3204_get_value(RF_AD_CH); + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << RF_LED_BASE); + udelay(usecs); + /* Left front side */ + olf = mcp3204_get_value(LF_AD_CH); + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LF_LED_BASE); + udelay(usecs); + lf = mcp3204_get_value(LF_AD_CH); + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LF_LED_BASE); + udelay(usecs); + + /* set sensor data to rw_buf(static buffer) */ + snprintf(rw_buf, sizeof(rw_buf), "%d %d %d %d\n", rf - orf, r - or, + l - ol, lf - olf); + buflen = strlen(rw_buf); + count = buflen; + len = buflen; + + /* copy data to user area */ + if (copy_to_user((void *)buf, &rw_buf, count)) { + printk(KERN_INFO "err read buffer from ret %d\n", ret); + printk(KERN_INFO "err read buffer from %s\n", rw_buf); + printk(KERN_INFO "err sample_char_read size(%zu)\n", count); + printk(KERN_INFO "sample_char_read size err(%d)\n", -EFAULT); + return 0; + } + + *f_pos += count; + + return count; +} + +/* pwm set function */ +static void rpi_pwm_write32(uint32_t offset, uint32_t val) +{ + iowrite32(val, pwm_base + offset); } + +/* + * Initialize buzzer + * return 0 : device close + */ +int buzzer_init(void) +{ + + rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); // io is pwm out + rpi_pwm_write32(RPI_PWM_CTRL, 0x00000000); + udelay(1000); + rpi_pwm_write32(RPI_PWM_CTRL, 0x00008181); // PWM1,2 enable + + // printk(KERN_DEBUG "%s: rpi_pwm_ctrl:%08X\n", DRIVER_NAME, + // ioread32(pwm_base + RPI_PWM_CTRL)); + + return 0; +} + +/* --- GPIO Operation --- */ +/* getPWMCount function for GPIO Operation */ +static int getPWMCount(int freq) +{ + if (freq < 1) + return PWM_BASECLK; + if (freq > 10000) + return PWM_BASECLK / 10000; + + return PWM_BASECLK / freq; +} + +/* left motor function */ +static void set_motor_l_freq(int freq) +{ + int dat; + + rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); + + // Reset uncontrollable frequency to zero. + if (abs(freq) < MOTOR_UNCONTROLLABLE_FREQ) { + freq = 0; + } + + if (freq == 0) { + rpi_gpio_function_set(MOTCLK_L_BASE, RPI_GPF_OUTPUT); + return; + } else { + rpi_gpio_function_set(MOTCLK_L_BASE, RPI_GPF_ALT0); + } + + if (freq > 0) { + motor_l_freq_is_positive = 1; + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTDIR_L_BASE); + } else { + motor_l_freq_is_positive = 0; + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTDIR_L_BASE); + freq = -freq; + } + + dat = getPWMCount(freq); + + rpi_pwm_write32(RPI_PWM_RNG1, dat); + rpi_pwm_write32(RPI_PWM_DAT1, dat >> 1); + + return; +} + +/* right motor function */ +static void set_motor_r_freq(int freq) +{ + int dat; + + rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); + + // Reset uncontrollable frequency to zero. + if (abs(freq) < MOTOR_UNCONTROLLABLE_FREQ) { + freq = 0; + } + + if (freq == 0) { + rpi_gpio_function_set(MOTCLK_R_BASE, RPI_GPF_OUTPUT); + return; + } else { + rpi_gpio_function_set(MOTCLK_R_BASE, RPI_GPF_ALT0); + } + + if (freq > 0) { + motor_r_freq_is_positive = 1; + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTDIR_R_BASE); + } else { + motor_r_freq_is_positive = 0; + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTDIR_R_BASE); + freq = -freq; + } + + dat = getPWMCount(freq); + + rpi_pwm_write32(RPI_PWM_RNG2, dat); + rpi_pwm_write32(RPI_PWM_DAT2, dat >> 1); + + return; +} + +/* Parse motor command */ +static int parseMotorCmd(const char __user *buf, size_t count, int *ret) +{ + int r_motor_val, l_motor_val, time_val; + char *newbuf = kmalloc(sizeof(char) * count, GFP_KERNEL); + + if (copy_from_user(newbuf, buf, sizeof(char) * count)) { + kfree(newbuf); + return -EFAULT; + } + + sscanf(newbuf, "%d%d%d\n", &l_motor_val, &r_motor_val, &time_val); + + kfree(newbuf); + + mutex_lock(&lock); + + set_motor_l_freq(l_motor_val); + set_motor_r_freq(r_motor_val); + + msleep_interruptible(time_val); + + set_motor_l_freq(0); + set_motor_r_freq(0); + + mutex_unlock(&lock); + + return count; +} + +/* + * Turn On LEDs + * return 0 : device close + */ +static int led_put(int ledno) +{ + switch (ledno) { + case 0: + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED0_BASE); + break; + case 1: + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED1_BASE); + break; + case 2: + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED2_BASE); + break; + case 3: + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED3_BASE); + break; + } + return 0; +} + +/*set mask and value */ +void rpi_gpio_set32(uint32_t mask, uint32_t val) +{ + gpio_base[RPI_GPSET0_INDEX] = val & mask; +} + +/* clear mask and value */ +void rpi_gpio_clear32(uint32_t mask, uint32_t val) +{ + gpio_base[RPI_GPCLR0_INDEX] = val & mask; +} + +/* set function */ +int rpi_gpio_function_set(int pin, uint32_t func) +{ + int index = RPI_GPFSEL0_INDEX + pin / 10; + uint32_t mask = ~(0x7 << ((pin % 10) * 3)); + + gpio_base[index] = + (gpio_base[index] & mask) | ((func & 0x7) << ((pin % 10) * 3)); + + return 1; +} + +/* + * Turn Off LEDs + * return 0 : device close + */ +static int led_del(int ledno) +{ + switch (ledno) { + case 0: + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED0_BASE); + break; + case 1: + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED1_BASE); + break; + case 2: + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED2_BASE); + break; + case 3: + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED3_BASE); + break; + } + + return 0; +} + +/* --- Device File Operation --- */ +/* Open Device */ +int dev_open(struct inode *inode, struct file *filep) +{ + int *minor = (int *)kmalloc(sizeof(int), GFP_KERNEL); + int major = MAJOR(inode->i_rdev); + *minor = MINOR(inode->i_rdev); + + filep->private_data = (void *)minor; + + const char *dev_name = filep->f_path.dentry->d_name.name; + printk(KERN_INFO "Device opened: %s, Major: %d\n", dev_name, major); + + return 0; +} + +/* Close device */ +int dev_release(struct inode *inode, struct file *filep) +{ + kfree(filep->private_data); + return 0; +} + +int i2c_dev_open(struct inode *inode, struct file *filep) +{ + struct rtcnt_device_info *dev_info; + dev_info = container_of(inode->i_cdev, struct rtcnt_device_info, cdev); + if (dev_info == NULL || dev_info->client == NULL) { + printk(KERN_ERR "%s: i2c dev_open failed.\n", DRIVER_NAME); + } + dev_info->device_minor = MINOR(inode->i_rdev); + filep->private_data = dev_info; + return 0; +} + +int i2c_dev_release(struct inode *inode, struct file *filep) +{ + return 0; +} + +/* + * led_write - Trun ON/OFF LEDs + * Write function of /dev/rtled + */ +ssize_t led_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +{ + char cval; + int ret; + int minor = *((int *)filep->private_data); + + if (count > 0) { + if (copy_from_user(&cval, buf, sizeof(char))) { + return -EFAULT; + } + switch (cval) { + case '1': + ret = led_put(minor); + break; + case '0': + ret = led_del(minor); + break; + } + return sizeof(char); + } + return 0; +} + +/* + * buzzer_write - Write buzzer frequency + * Write function of /dev/rtbuzzer + */ +ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +{ + int ret; + int freq, dat; + + ret = kstrtoint_from_user(buf, count, 10, &freq); + if (ret) { + printk(KERN_ERR "%s: error parsing string to int in %s()\n", + DRIVER_NAME, __func__); + return ret; + } + + if (freq != 0) { + if (freq < 1) { + freq = 1; + } + + if (freq > 20000) { + freq = 20000; + } + + rpi_gpio_function_set(BUZZER_BASE, + RPI_GPF_ALT5); // io is pwm out + dat = PWM_BASECLK / freq; + rpi_pwm_write32(RPI_PWM_RNG2, dat); + rpi_pwm_write32(RPI_PWM_DAT2, dat >> 1); + } else { + rpi_gpio_function_set(BUZZER_BASE, + RPI_GPF_OUTPUT); // io is pwm out + } + + return count; +} + +/* + * rawmotor_l_write - Output frequency to the left motor + * Write function of /dev/rtmotor_raw_l + */ +ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +{ + int freq, ret; + + ret = kstrtoint_from_user(buf, count, 10, &freq); + if (ret) { + printk(KERN_ERR "%s: error parsing string to int in %s()\n", + DRIVER_NAME, __func__); + return ret; + } + set_motor_l_freq(freq); + + return count; +} + +/* + * rawmotor_r_write - Output frequency to the right motor + * Write function of /dev/rtmotor_raw_r + */ +ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +{ + int freq, ret; + + ret = kstrtoint_from_user(buf, count, 10, &freq); + if (ret) { + printk(KERN_ERR "%s: error parsing string to int in %s()\n", + DRIVER_NAME, __func__); + return ret; + } + + set_motor_r_freq(freq); + + return count; +} + +/* + * motoren_write - Turn ON/OFF SteppingMotor Power + * Write function of /dev/rtmotoren + */ +ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +{ + char cval; + + if (count > 0) { + if (copy_from_user(&cval, buf, sizeof(char))) { + return -EFAULT; + } + + switch (cval) { + case '1': + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTEN_BASE); + break; + case '0': + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTEN_BASE); + break; + } + return sizeof(char); + } + return 0; +} + +/* + * motor_write - Output frequency to right and left both motors + * Write function of /dev/rtmotor + */ +ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +{ + int tmp; + int bufcnt; + bufcnt = parseMotorCmd(buf, count, &tmp); + + return bufcnt; +} + +/* --- Device File Operations --- */ +struct file_operations dev_fops[ID_DEV_SIZE] = { + [ID_DEV_LED].open = dev_open, + [ID_DEV_LED].release = dev_release, + [ID_DEV_LED].write = led_write, + [ID_DEV_SWITCH].open = dev_open, + [ID_DEV_SWITCH].read = sw_read, + [ID_DEV_SWITCH].release = dev_release, + [ID_DEV_SENSOR].open = dev_open, + [ID_DEV_SENSOR].read = sensor_read, + [ID_DEV_SENSOR].release = dev_release, + [ID_DEV_BUZZER].open = dev_open, + [ID_DEV_BUZZER].release = dev_release, + [ID_DEV_BUZZER].write = buzzer_write, + [ID_DEV_MOTORRAWR].open = dev_open, + [ID_DEV_MOTORRAWR].release = dev_release, + [ID_DEV_MOTORRAWR].write = rawmotor_r_write, + [ID_DEV_MOTORRAWL].open = dev_open, + [ID_DEV_MOTORRAWL].release = dev_release, + [ID_DEV_MOTORRAWL].write = rawmotor_l_write, + [ID_DEV_MOTOREN].open = dev_open, + [ID_DEV_MOTOREN].release = dev_release, + [ID_DEV_MOTOREN].write = motoren_write, + [ID_DEV_MOTOR].open = dev_open, + [ID_DEV_MOTOR].release = dev_release, + [ID_DEV_MOTOR].write = motor_write, + [ID_DEV_CNT].open = i2c_dev_open, + [ID_DEV_CNT].release = i2c_dev_release, + [ID_DEV_CNT].read = rtcnt_read, + [ID_DEV_CNT].write = rtcnt_write}; diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 197ec8e..4ef5364 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -1,6 +1,6 @@ /* * - * rtmouse.c + * rtmouse_main.c * Raspberry Pi Mouse device driver * * Version: 3.3.2 @@ -108,17 +108,6 @@ static int rtcnt_i2c_remove(struct i2c_client *client); static void rtcnt_i2c_remove(struct i2c_client *client); #endif -/* --- Variable Type definitions --- */ -/* SPI */ -struct mcp3204_drvdata { - struct spi_device *spi; - struct mutex lock; - unsigned char tx[MCP320X_PACKET_SIZE] ____cacheline_aligned; - unsigned char rx[MCP320X_PACKET_SIZE] ____cacheline_aligned; - struct spi_transfer xfer ____cacheline_aligned; - struct spi_message msg ____cacheline_aligned; -}; - /* --- Static variables --- */ /* SPI device ID */ struct spi_device_id mcp3204_id[] = { @@ -151,18 +140,6 @@ struct spi_driver mcp3204_driver = { .remove = mcp3204_remove, }; -/* I2C */ -struct rtcnt_device_info { - struct cdev cdev; - unsigned int device_major; - unsigned int device_minor; - struct class *device_class; - struct i2c_client *client; - struct mutex lock; - int signed_pulse_count; - int raw_pulse_count; -}; - struct i2c_client *i2c_client_r = NULL; struct i2c_client *i2c_client_l = NULL; unsigned int motor_l_freq_is_positive = 1; @@ -191,338 +168,6 @@ struct i2c_driver i2c_counter_driver = { MODULE_DEVICE_TABLE(spi, mcp3204_id); MODULE_DEVICE_TABLE(i2c, i2c_counter_id); -/* --- GPIO Operation --- */ -/* getPWMCount function for GPIO Operation */ -static int getPWMCount(int freq) -{ - if (freq < 1) - return PWM_BASECLK; - if (freq > 10000) - return PWM_BASECLK / 10000; - - return PWM_BASECLK / freq; -} - -/* set function */ -static int rpi_gpio_function_set(int pin, uint32_t func) -{ - int index = RPI_GPFSEL0_INDEX + pin / 10; - uint32_t mask = ~(0x7 << ((pin % 10) * 3)); - - gpio_base[index] = - (gpio_base[index] & mask) | ((func & 0x7) << ((pin % 10) * 3)); - - return 1; -} - -/*set mask and value */ -static void rpi_gpio_set32(uint32_t mask, uint32_t val) -{ - gpio_base[RPI_GPSET0_INDEX] = val & mask; -} - -/* clear mask and value */ -static void rpi_gpio_clear32(uint32_t mask, uint32_t val) -{ - gpio_base[RPI_GPCLR0_INDEX] = val & mask; -} - -/* pwm set function */ -static void rpi_pwm_write32(uint32_t offset, uint32_t val) -{ - iowrite32(val, pwm_base + offset); -} - -/* left motor function */ -static void set_motor_l_freq(int freq) -{ - int dat; - - rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); - - // Reset uncontrollable frequency to zero. - if (abs(freq) < MOTOR_UNCONTROLLABLE_FREQ) { - freq = 0; - } - - if (freq == 0) { - rpi_gpio_function_set(MOTCLK_L_BASE, RPI_GPF_OUTPUT); - return; - } else { - rpi_gpio_function_set(MOTCLK_L_BASE, RPI_GPF_ALT0); - } - - if (freq > 0) { - motor_l_freq_is_positive = 1; - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTDIR_L_BASE); - } else { - motor_l_freq_is_positive = 0; - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTDIR_L_BASE); - freq = -freq; - } - - dat = getPWMCount(freq); - - rpi_pwm_write32(RPI_PWM_RNG1, dat); - rpi_pwm_write32(RPI_PWM_DAT1, dat >> 1); - - return; -} - -/* right motor function */ -static void set_motor_r_freq(int freq) -{ - int dat; - - rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); - - // Reset uncontrollable frequency to zero. - if (abs(freq) < MOTOR_UNCONTROLLABLE_FREQ) { - freq = 0; - } - - if (freq == 0) { - rpi_gpio_function_set(MOTCLK_R_BASE, RPI_GPF_OUTPUT); - return; - } else { - rpi_gpio_function_set(MOTCLK_R_BASE, RPI_GPF_ALT0); - } - - if (freq > 0) { - motor_r_freq_is_positive = 1; - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTDIR_R_BASE); - } else { - motor_r_freq_is_positive = 0; - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTDIR_R_BASE); - freq = -freq; - } - - dat = getPWMCount(freq); - - rpi_pwm_write32(RPI_PWM_RNG2, dat); - rpi_pwm_write32(RPI_PWM_DAT2, dat >> 1); - - return; -} - -/* --- Function for device file operations --- */ -/* - * Read Push Switches - * return 0 : device close - */ -static ssize_t sw_read(struct file *filep, char __user *buf, size_t count, - loff_t *f_pos) -{ - int buflen = 0; - unsigned char rw_buf[MAX_BUFLEN]; - unsigned int ret = 0; - int len; - int index; - unsigned int pin = SW1_PIN; - uint32_t mask; - int minor = *((int *)filep->private_data); -#if RASPBERRYPI == 4 - int pullreg = GPPUPPDN1 + (pin >> 4); // SW1, 2, 3 is between GPIO16-31 - int pullshift = (pin & 0xf) << 1; - unsigned int pullbits; - unsigned int pull; -#endif - - switch (minor) { - case 0: - pin = SW1_PIN; - break; - case 1: - pin = SW2_PIN; - break; - case 2: - pin = SW3_PIN; - break; - default: - return 0; - break; - } - - if (*f_pos > 0) - return 0; /* End of file */ - -#if RASPBERRYPI == 4 - pull = GPIO_PULLUP; - pullbits = *(gpio_base + pullreg); - pullbits &= ~(3 << pullshift); - pullbits |= (pull << pullshift); - *(gpio_base + pullreg) = pullbits; -#else - // プルモード (2bit)を書き込む NONE/DOWN/UP - gpio_base[37] = GPIO_PULLUP & 0x3; // GPPUD - // ピンにクロックを供給(前後にウェイト) - msleep(1); - gpio_base[38] = 0x1 << pin; // GPPUDCLK0 - msleep(1); - // プルモード・クロック状態をクリアして終了 - gpio_base[37] = 0; - gpio_base[38] = 0; -#endif - - index = RPI_GPFSEL0_INDEX + pin / 10; - mask = ~(0x7 << ((pin % 10) * 3)); - - ret = ((gpio_base[13] & (0x01 << pin)) != 0); - sprintf(rw_buf, "%d\n", ret); - - buflen = strlen(rw_buf); - count = buflen; - len = buflen; - - if (copy_to_user((void *)buf, &rw_buf, count)) { - printk(KERN_INFO "err read buffer from ret %d\n", ret); - printk(KERN_INFO "err read buffer from %s\n", rw_buf); - printk(KERN_INFO "err sample_char_read size(%zu)\n", count); - printk(KERN_INFO "sample_char_read size err(%d)\n", -EFAULT); - return 0; - } - *f_pos += count; - - return count; -} - -/* - * Read Sensor information - * return 0 : device close - */ -static ssize_t sensor_read(struct file *filep, char __user *buf, size_t count, - loff_t *f_pos) -{ - int buflen = 0; - unsigned char rw_buf[MAX_BUFLEN]; - unsigned int ret = 0; - int len; - - // printk(KERN_INFO "new\n"); - - int usecs = 30; - int rf = 0, lf = 0, r = 0, l = 0; - int orf = 0, olf = 0, or = 0, ol = 0; - - if (*f_pos > 0) - return 0; /* End of file */ - - /* get values through MCP3204 */ - /* Right side */ - or = mcp3204_get_value(R_AD_CH); - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << R_LED_BASE); - udelay(usecs); - r = mcp3204_get_value(R_AD_CH); - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << R_LED_BASE); - udelay(usecs); - /* Left side */ - ol = mcp3204_get_value(L_AD_CH); - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << L_LED_BASE); - udelay(usecs); - l = mcp3204_get_value(L_AD_CH); - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << L_LED_BASE); - udelay(usecs); - /* Right front side */ - orf = mcp3204_get_value(RF_AD_CH); - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << RF_LED_BASE); - udelay(usecs); - rf = mcp3204_get_value(RF_AD_CH); - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << RF_LED_BASE); - udelay(usecs); - /* Left front side */ - olf = mcp3204_get_value(LF_AD_CH); - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LF_LED_BASE); - udelay(usecs); - lf = mcp3204_get_value(LF_AD_CH); - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LF_LED_BASE); - udelay(usecs); - - /* set sensor data to rw_buf(static buffer) */ - snprintf(rw_buf, sizeof(rw_buf), "%d %d %d %d\n", rf - orf, r - or, - l - ol, lf - olf); - buflen = strlen(rw_buf); - count = buflen; - len = buflen; - - /* copy data to user area */ - if (copy_to_user((void *)buf, &rw_buf, count)) { - printk(KERN_INFO "err read buffer from ret %d\n", ret); - printk(KERN_INFO "err read buffer from %s\n", rw_buf); - printk(KERN_INFO "err sample_char_read size(%zu)\n", count); - printk(KERN_INFO "sample_char_read size err(%d)\n", -EFAULT); - return 0; - } - - *f_pos += count; - - return count; -} - -/* - * Turn On LEDs - * return 0 : device close - */ -static int led_put(int ledno) -{ - switch (ledno) { - case 0: - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED0_BASE); - break; - case 1: - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED1_BASE); - break; - case 2: - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED2_BASE); - break; - case 3: - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED3_BASE); - break; - } - return 0; -} - -/* - * Turn Off LEDs - * return 0 : device close - */ -static int led_del(int ledno) -{ - switch (ledno) { - case 0: - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED0_BASE); - break; - case 1: - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED1_BASE); - break; - case 2: - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED2_BASE); - break; - case 3: - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED3_BASE); - break; - } - - return 0; -} - -/* - * Initialize buzzer - * return 0 : device close - */ -static int buzzer_init(void) -{ - - rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); // io is pwm out - rpi_pwm_write32(RPI_PWM_CTRL, 0x00000000); - udelay(1000); - rpi_pwm_write32(RPI_PWM_CTRL, 0x00008181); // PWM1,2 enable - - // printk(KERN_DEBUG "%s: rpi_pwm_ctrl:%08X\n", DRIVER_NAME, - // ioread32(pwm_base + RPI_PWM_CTRL)); - - return 0; -} - /* --- GPIO mapping for Device Open/Close --- */ /* * Get gpio addresses and set them to global variables. @@ -591,450 +236,6 @@ static int gpio_unmap(void) return 0; } -/* --- Device File Operation --- */ -/* Open Device */ -static int dev_open(struct inode *inode, struct file *filep) -{ - int *minor = (int *)kmalloc(sizeof(int), GFP_KERNEL); - int major = MAJOR(inode->i_rdev); - *minor = MINOR(inode->i_rdev); - - filep->private_data = (void *)minor; - - const char *dev_name = filep->f_path.dentry->d_name.name; - printk(KERN_INFO "Device opened: %s, Major: %d\n", dev_name, major); - - return 0; -} - -/* Close device */ -static int dev_release(struct inode *inode, struct file *filep) -{ - kfree(filep->private_data); - return 0; -} - -static int i2c_dev_open(struct inode *inode, struct file *filep) -{ - struct rtcnt_device_info *dev_info; - dev_info = container_of(inode->i_cdev, struct rtcnt_device_info, cdev); - if (dev_info == NULL || dev_info->client == NULL) { - printk(KERN_ERR "%s: i2c dev_open failed.\n", DRIVER_NAME); - } - dev_info->device_minor = MINOR(inode->i_rdev); - filep->private_data = dev_info; - return 0; -} - -static int i2c_dev_release(struct inode *inode, struct file *filep) -{ - return 0; -} - -/* Parse motor command */ -static int parseMotorCmd(const char __user *buf, size_t count, int *ret) -{ - int r_motor_val, l_motor_val, time_val; - char *newbuf = kmalloc(sizeof(char) * count, GFP_KERNEL); - - if (copy_from_user(newbuf, buf, sizeof(char) * count)) { - kfree(newbuf); - return -EFAULT; - } - - sscanf(newbuf, "%d%d%d\n", &l_motor_val, &r_motor_val, &time_val); - - kfree(newbuf); - - mutex_lock(&lock); - - set_motor_l_freq(l_motor_val); - set_motor_r_freq(r_motor_val); - - msleep_interruptible(time_val); - - set_motor_l_freq(0); - set_motor_r_freq(0); - - mutex_unlock(&lock); - - return count; -} - -/* - * led_write - Trun ON/OFF LEDs - * Write function of /dev/rtled - */ -static ssize_t led_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos) -{ - char cval; - int ret; - int minor = *((int *)filep->private_data); - - if (count > 0) { - if (copy_from_user(&cval, buf, sizeof(char))) { - return -EFAULT; - } - switch (cval) { - case '1': - ret = led_put(minor); - break; - case '0': - ret = led_del(minor); - break; - } - return sizeof(char); - } - return 0; -} - -/* - * buzzer_write - Write buzzer frequency - * Write function of /dev/rtbuzzer - */ -static ssize_t buzzer_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos) -{ - int ret; - int freq, dat; - - ret = kstrtoint_from_user(buf, count, 10, &freq); - if (ret) { - printk(KERN_ERR "%s: error parsing string to int in %s()\n", - DRIVER_NAME, __func__); - return ret; - } - - if (freq != 0) { - if (freq < 1) { - freq = 1; - } - - if (freq > 20000) { - freq = 20000; - } - - rpi_gpio_function_set(BUZZER_BASE, - RPI_GPF_ALT5); // io is pwm out - dat = PWM_BASECLK / freq; - rpi_pwm_write32(RPI_PWM_RNG2, dat); - rpi_pwm_write32(RPI_PWM_DAT2, dat >> 1); - } else { - rpi_gpio_function_set(BUZZER_BASE, - RPI_GPF_OUTPUT); // io is pwm out - } - - return count; -} - -/* - * rawmotor_l_write - Output frequency to the left motor - * Write function of /dev/rtmotor_raw_l - */ -static ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos) -{ - int freq, ret; - - ret = kstrtoint_from_user(buf, count, 10, &freq); - if (ret) { - printk(KERN_ERR "%s: error parsing string to int in %s()\n", - DRIVER_NAME, __func__); - return ret; - } - set_motor_l_freq(freq); - - return count; -} - -/* - * rawmotor_r_write - Output frequency to the right motor - * Write function of /dev/rtmotor_raw_r - */ -static ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos) -{ - int freq, ret; - - ret = kstrtoint_from_user(buf, count, 10, &freq); - if (ret) { - printk(KERN_ERR "%s: error parsing string to int in %s()\n", - DRIVER_NAME, __func__); - return ret; - } - - set_motor_r_freq(freq); - - return count; -} - -/* - * motoren_write - Turn ON/OFF SteppingMotor Power - * Write function of /dev/rtmotoren - */ -static ssize_t motoren_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos) -{ - char cval; - - if (count > 0) { - if (copy_from_user(&cval, buf, sizeof(char))) { - return -EFAULT; - } - - switch (cval) { - case '1': - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTEN_BASE); - break; - case '0': - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTEN_BASE); - break; - } - return sizeof(char); - } - return 0; -} - -/* - * motor_write - Output frequency to right and left both motors - * Write function of /dev/rtmotor - */ -static ssize_t motor_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos) -{ - int tmp; - int bufcnt; - bufcnt = parseMotorCmd(buf, count, &tmp); - - return bufcnt; -} - -/* - * i2c_counter_set - set value to I2C pulse counter - * called by cntr_write() and cntl_write() - */ -static int i2c_counter_set(struct rtcnt_device_info *dev_info, int setval) -{ - int ret = 0; - int lsb = 0, msb = 0; - struct i2c_client *client = dev_info->client; - - // printk(KERN_INFO "set 0x%x = 0x%x\n", client->addr, setval); - msb = (setval >> 8) & 0xFF; - lsb = setval & 0xFF; - mutex_lock(&dev_info->lock); - // printk(KERN_INFO "set 0x%x msb = 0x%x\n", client->addr, msb); - ret = i2c_smbus_write_byte_data(client, 0x10, msb); - if (ret < 0) { - printk(KERN_ERR - "%s: Failed writing to i2c counter device, addr=0x%x\n", - __func__, client->addr); - return -ENODEV; - } - // printk(KERN_INFO "set 0x%x lsb = 0x%x\n", client->addr, lsb); - ret = i2c_smbus_write_byte_data(client, 0x11, lsb); - if (ret < 0) { - printk(KERN_ERR - "%s: Failed writing to i2c counter device, addr=0x%x\n", - __func__, client->addr); - return -ENODEV; - } - mutex_unlock(&dev_info->lock); - return ret; -} - -/* - * i2c_counter_read - get value from I2C pulse counter - * called by rtcnt_read() - */ -static int i2c_counter_read(struct rtcnt_device_info *dev_info, int *ret) -{ - int lsb = 0, msb = 0; - // printk(KERN_INFO "read 0x%x\n", client->addr); - struct i2c_client *client = dev_info->client; - mutex_lock(&dev_info->lock); - - lsb = i2c_smbus_read_byte_data(client, CNT_ADDR_LSB); - if (lsb < 0) { - printk( - KERN_ERR - "%s: Failed reading from i2c counter device, addr=0x%x\n", - __func__, client->addr); - return -ENODEV; - } - msb = i2c_smbus_read_byte_data(client, CNT_ADDR_MSB); - if (msb < 0) { - printk( - KERN_ERR - "%s: Failed reading from i2c counter device, addr=0x%x\n", - __func__, client->addr); - return -ENODEV; - } - mutex_unlock(&dev_info->lock); - - *ret = ((msb << 8) & 0xFF00) + (lsb & 0xFF); - - // printk(KERN_INFO "0x%x == 0x%x\n", client->addr, *ret); - return 0; -} - -/* - * update_signed_count - update signed pulse count of dev_info - * called by rtcnt_read() - */ -void update_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) -{ - int diff_count = rtcnt_count - dev_info->raw_pulse_count; - - // カウントがMAX_PULSE_COUNTから0に変わる場合の処理 - // ただし、それ以外でもdiffが負の値になることがある - // そのため、diffが十分に大きな負の値の場合に処理する - // if(diff_count < 0) では正常に動作しない - if (diff_count < -SIGNED_COUNT_SIZE) { - diff_count += MAX_PULSE_COUNT; - } - - if (dev_info->client->addr == DEV_ADDR_CNTL) { - if (motor_l_freq_is_positive) { - dev_info->signed_pulse_count += diff_count; - } else { - dev_info->signed_pulse_count -= diff_count; - } - } else { - if (motor_r_freq_is_positive) { - dev_info->signed_pulse_count += diff_count; - } else { - dev_info->signed_pulse_count -= diff_count; - } - } - - if (dev_info->signed_pulse_count > SIGNED_COUNT_SIZE || - dev_info->signed_pulse_count < -SIGNED_COUNT_SIZE) { - dev_info->signed_pulse_count = 0; - } -} - -/* - * reset_signed_count - reset signed pulse count of dev_info - * called by rtcnt_write() - */ -void reset_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) -{ - int raw_count; - - if (rtcnt_count > SIGNED_COUNT_SIZE) { - rtcnt_count = SIGNED_COUNT_SIZE; - } else if (rtcnt_count < -SIGNED_COUNT_SIZE) { - rtcnt_count = -SIGNED_COUNT_SIZE; - } - dev_info->signed_pulse_count = rtcnt_count; - i2c_counter_read(dev_info, &raw_count); - dev_info->raw_pulse_count = raw_count; -} - -/* - * rtcnt_read - Read value from right/left pulse counter - * Read function of /dev/rtcounter_* - */ -static ssize_t rtcnt_read(struct file *filep, char __user *buf, size_t count, - loff_t *f_pos) -{ - struct rtcnt_device_info *dev_info = filep->private_data; - - unsigned char rw_buf[64]; - int buflen; - - int rtcnt_count = 0; - if (*f_pos > 0) - return 0; /* close device */ - i2c_counter_read(dev_info, &rtcnt_count); - - if (dev_info->device_minor == 1) { - update_signed_count(dev_info, rtcnt_count); - dev_info->raw_pulse_count = rtcnt_count; - rtcnt_count = dev_info->signed_pulse_count; - } else { - dev_info->raw_pulse_count = rtcnt_count; - } - - /* set sensor data to rw_buf(static buffer) */ - sprintf(rw_buf, "%d\n", rtcnt_count); - buflen = strlen(rw_buf); - count = buflen; - - /* copy data to user area */ - if (copy_to_user((void *)buf, &rw_buf, count)) { - printk(KERN_INFO "err read buffer from %s\n", rw_buf); - printk(KERN_INFO "err sample_char_read size(%zu)\n", count); - printk(KERN_INFO "sample_char_read size err(%d)\n", -EFAULT); - return -EFAULT; - } - *f_pos += count; - return count; -} - -/* - * cnt_write - Set value to right/left pulse counter - * Write function of /dev/rtcounter - */ -static ssize_t rtcnt_write(struct file *filep, const char __user *buf, - size_t count, loff_t *pos) -{ - struct rtcnt_device_info *dev_info = filep->private_data; - - int rtcnt_count = 0; - int ret; - - ret = kstrtoint_from_user(buf, count, 10, &rtcnt_count); - if (ret) { - printk(KERN_ERR "%s: error parsing string to int in %s()\n", - DRIVER_NAME, __func__); - return ret; - } - - i2c_counter_set(dev_info, rtcnt_count); - - if (dev_info->device_minor == 1) { - reset_signed_count(dev_info, rtcnt_count); - } - - printk(KERN_INFO "%s: set pulse counter value %d\n", DRIVER_NAME, - rtcnt_count); - return count; -} - -/* --- Device File Operations --- */ -static struct file_operations dev_fops[ID_DEV_SIZE] = { - [ID_DEV_LED].open = dev_open, - [ID_DEV_LED].release = dev_release, - [ID_DEV_LED].write = led_write, - [ID_DEV_SWITCH].open = dev_open, - [ID_DEV_SWITCH].read = sw_read, - [ID_DEV_SWITCH].release = dev_release, - [ID_DEV_SENSOR].open = dev_open, - [ID_DEV_SENSOR].read = sensor_read, - [ID_DEV_SENSOR].release = dev_release, - [ID_DEV_BUZZER].open = dev_open, - [ID_DEV_BUZZER].release = dev_release, - [ID_DEV_BUZZER].write = buzzer_write, - [ID_DEV_MOTORRAWR].open = dev_open, - [ID_DEV_MOTORRAWR].release = dev_release, - [ID_DEV_MOTORRAWR].write = rawmotor_r_write, - [ID_DEV_MOTORRAWL].open = dev_open, - [ID_DEV_MOTORRAWL].release = dev_release, - [ID_DEV_MOTORRAWL].write = rawmotor_l_write, - [ID_DEV_MOTOREN].open = dev_open, - [ID_DEV_MOTOREN].release = dev_release, - [ID_DEV_MOTOREN].write = motoren_write, - [ID_DEV_MOTOR].open = dev_open, - [ID_DEV_MOTOR].release = dev_release, - [ID_DEV_MOTOR].write = motor_write, - [ID_DEV_CNT].open = i2c_dev_open, - [ID_DEV_CNT].release = i2c_dev_release, - [ID_DEV_CNT].read = rtcnt_read, - [ID_DEV_CNT].write = rtcnt_write}; - /* --- Device Driver Registration and Device File Creation --- */ static int register_dev(int id_dev) { @@ -1173,58 +374,6 @@ static int mcp3204_probe(struct spi_device *spi) return 0; } -/* - * mcp3204_get_value - get sensor data from MCP3204 - * called by 'sensor_read' - */ -static unsigned int mcp3204_get_value(int channel) -{ - struct device *dev; - struct mcp3204_drvdata *data; - struct spi_device *spi; - char str[128]; - - unsigned int r = 0; - unsigned char c = channel & 0x03; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) - - if (mcp320x_dev == NULL) - return 0; - dev = mcp320x_dev; - -#else - struct spi_master *master; - master = spi_busnum_to_master(mcp3204_info.bus_num); - snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), - mcp3204_info.chip_select); - dev = bus_find_device_by_name(&spi_bus_type, NULL, str); -#endif - - spi = to_spi_device(dev); - data = (struct mcp3204_drvdata *)spi_get_drvdata(spi); - mutex_lock(&data->lock); - data->tx[0] = 1 << 2; // start bit - data->tx[0] |= 1 << 1; // Single - data->tx[1] = c << 6; // channel - data->tx[2] = 0; - - if (spi_sync(data->spi, &data->msg)) { - printk(KERN_INFO "%s: spi_sync_transfer returned non zero\n", - __func__); - } - - mutex_unlock(&data->lock); - - r = (data->rx[1] & 0xf) << 8; - r |= data->rx[2]; - - // printk(KERN_INFO "%s: get result on ch[%d] : %04d\n", __func__, - // channel, r); - - return r; -} - /* * spi_remove_device - remove SPI device * called by mcp3204_init and mcp3204_exit @@ -1671,8 +820,6 @@ int dev_init_module(void) int registered_devices = 0; size_t size; - tmp_func(); - /* log loding message */ printk(KERN_INFO "%s: loading driver...\n", DRIVER_NAME); From f2e86ce9faaed50da006d8e536fff896a5648974 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 15:30:45 +0900 Subject: [PATCH 06/26] =?UTF-8?q?lint=E5=AF=BE=E8=B1=A1=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3&=E3=82=A4=E3=83=B3=E3=83=87=E3=83=B3=E3=83=88?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .test/lint.sh | 1 + src/drivers/rtmouse_main.c | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.test/lint.sh b/.test/lint.sh index c85fe17..7cf6001 100755 --- a/.test/lint.sh +++ b/.test/lint.sh @@ -7,6 +7,7 @@ SRC_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); cd ../; pwd) lint_driver () { pushd $SRC_DIR/src/drivers python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_main.c + python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_dev.c python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse.h popd } diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 4ef5364..538d23d 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -37,22 +37,22 @@ unsigned int NUM_DEV[ID_DEV_SIZE] = { /* --- Device Names --- */ char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", - [ID_DEV_SWITCH] = "rtswitch", - [ID_DEV_SENSOR] = "rtlightsensor", - [ID_DEV_BUZZER] = "rtbuzzer", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l", - [ID_DEV_MOTOREN] = "rtmotoren", - [ID_DEV_MOTOR] = "rtmotor"}; + [ID_DEV_SWITCH] = "rtswitch", + [ID_DEV_SENSOR] = "rtlightsensor", + [ID_DEV_BUZZER] = "rtbuzzer", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l", + [ID_DEV_MOTOREN] = "rtmotoren", + [ID_DEV_MOTOR] = "rtmotor"}; char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", - [ID_DEV_SWITCH] = "rtswitch%u", - [ID_DEV_SENSOR] = "rtlightsensor%u", - [ID_DEV_BUZZER] = "rtbuzzer%u", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", - [ID_DEV_MOTOREN] = "rtmotoren%u", - [ID_DEV_MOTOR] = "rtmotor%u"}; + [ID_DEV_SWITCH] = "rtswitch%u", + [ID_DEV_SENSOR] = "rtlightsensor%u", + [ID_DEV_BUZZER] = "rtbuzzer%u", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", + [ID_DEV_MOTOREN] = "rtmotoren%u", + [ID_DEV_MOTOR] = "rtmotor%u"}; // used in by register_dev() and cleanup_each_dev() int _major_dev[ID_DEV_SIZE] = { From f260f46be394e90c5246bf26281b67825ac722d3 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 15:34:49 +0900 Subject: [PATCH 07/26] =?UTF-8?q?lint=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=97?= =?UTF-8?q?=E3=81=A6=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse_dev.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/drivers/rtmouse_dev.c b/src/drivers/rtmouse_dev.c index b7b57ab..ad1c364 100644 --- a/src/drivers/rtmouse_dev.c +++ b/src/drivers/rtmouse_dev.c @@ -666,16 +666,14 @@ int i2c_dev_open(struct inode *inode, struct file *filep) return 0; } -int i2c_dev_release(struct inode *inode, struct file *filep) -{ - return 0; -} +int i2c_dev_release(struct inode *inode, struct file *filep) { return 0; } /* * led_write - Trun ON/OFF LEDs * Write function of /dev/rtled */ -ssize_t led_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +ssize_t led_write(struct file *filep, const char __user *buf, size_t count, + loff_t *f_pos) { char cval; int ret; @@ -702,7 +700,8 @@ ssize_t led_write(struct file *filep, const char __user *buf, size_t count, loff * buzzer_write - Write buzzer frequency * Write function of /dev/rtbuzzer */ -ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, + loff_t *f_pos) { int ret; int freq, dat; @@ -740,7 +739,8 @@ ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, l * rawmotor_l_write - Output frequency to the left motor * Write function of /dev/rtmotor_raw_l */ -ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, + size_t count, loff_t *f_pos) { int freq, ret; @@ -759,7 +759,8 @@ ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, size_t coun * rawmotor_r_write - Output frequency to the right motor * Write function of /dev/rtmotor_raw_r */ -ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, + size_t count, loff_t *f_pos) { int freq, ret; @@ -779,7 +780,8 @@ ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, size_t coun * motoren_write - Turn ON/OFF SteppingMotor Power * Write function of /dev/rtmotoren */ -ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, + loff_t *f_pos) { char cval; @@ -805,7 +807,8 @@ ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, * motor_write - Output frequency to right and left both motors * Write function of /dev/rtmotor */ -ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) +ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, + loff_t *f_pos) { int tmp; int bufcnt; From 152d0577ff6d849b0dda78beebaeb427906076fe Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 15:43:57 +0900 Subject: [PATCH 08/26] =?UTF-8?q?lint=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=97?= =?UTF-8?q?=E3=81=A6=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index a729f4c..cba0f53 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -285,12 +285,18 @@ int dev_open(struct inode *inode, struct file *filep); int dev_release(struct inode *inode, struct file *filep); int i2c_dev_open(struct inode *inode, struct file *filep); int i2c_dev_release(struct inode *inode, struct file *filep); -ssize_t led_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); -ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); -ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); -ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); -ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); -ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos); +ssize_t led_write(struct file *filep, const char __user *buf, size_t count, + loff_t *f_pos); +ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, + loff_t *f_pos); +ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, + size_t count, loff_t *f_pos); +ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, + size_t count, loff_t *f_pos); +ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, + loff_t *f_pos); +ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, + loff_t *f_pos); int rpi_gpio_function_set(int pin, uint32_t func); void rpi_gpio_set32(uint32_t mask, uint32_t val); void rpi_gpio_clear32(uint32_t mask, uint32_t val); From 560bd677b5fbb834c9cf886577f2bcb9c8f68d0a Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 15:53:46 +0900 Subject: [PATCH 09/26] =?UTF-8?q?rtmouse=5Fdev.c=E3=82=92rtmouse=5Fdev=5Ff?= =?UTF-8?q?ops.c=E3=81=B8=E5=90=8D=E7=A7=B0=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .test/lint.sh | 2 +- src/drivers/Makefile.header_from_apt | 4 ++-- src/drivers/Makefile.header_from_source | 4 ++-- src/drivers/{rtmouse_dev.c => rtmouse_dev_fops.c} | 0 4 files changed, 5 insertions(+), 5 deletions(-) rename src/drivers/{rtmouse_dev.c => rtmouse_dev_fops.c} (100%) diff --git a/.test/lint.sh b/.test/lint.sh index 7cf6001..12c6180 100755 --- a/.test/lint.sh +++ b/.test/lint.sh @@ -7,7 +7,7 @@ SRC_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); cd ../; pwd) lint_driver () { pushd $SRC_DIR/src/drivers python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_main.c - python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_dev.c + python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_dev_fops.c python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse.h popd } diff --git a/src/drivers/Makefile.header_from_apt b/src/drivers/Makefile.header_from_apt index bc74e19..5c67a61 100644 --- a/src/drivers/Makefile.header_from_apt +++ b/src/drivers/Makefile.header_from_apt @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux-headers-$(shell uname -r) VERBOSE:=0 -$(MODULE).ko: $(MODULE)_dev.c $(MODULE)_main.c $(MODULE).h +$(MODULE).ko: $(MODULE)_dev_fops.c $(MODULE)_main.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/Makefile.header_from_source b/src/drivers/Makefile.header_from_source index 0d8510c..b910cdc 100644 --- a/src/drivers/Makefile.header_from_source +++ b/src/drivers/Makefile.header_from_source @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux VERBOSE:=0 -$(MODULE).ko: $(MODULE)_dev.c $(MODULE)_main.c $(MODULE).h +$(MODULE).ko: $(MODULE)_dev_fops.c $(MODULE)_main.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/rtmouse_dev.c b/src/drivers/rtmouse_dev_fops.c similarity index 100% rename from src/drivers/rtmouse_dev.c rename to src/drivers/rtmouse_dev_fops.c From d530af8f23b3a6a2fa398088f01f547416eac40f Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 16:43:18 +0900 Subject: [PATCH 10/26] =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=82=BB=E3=83=B3?= =?UTF-8?q?=E3=82=B9=E3=81=A8=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=82=92=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse_dev_fops.c | 8 +++----- src/drivers/rtmouse_main.c | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/drivers/rtmouse_dev_fops.c b/src/drivers/rtmouse_dev_fops.c index ad1c364..baaac84 100644 --- a/src/drivers/rtmouse_dev_fops.c +++ b/src/drivers/rtmouse_dev_fops.c @@ -1,11 +1,9 @@ /* * - * rtmouse_dev.c - * Raspberry Pi Mouse device driver + * rtmouse_dev_fops.c + * Define device file operations * - * Version: 3.3.2 - * - * Copyright (C) 2015-2024 RT Corporation + * Copyright (C) 2024 RT Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 538d23d..50a284b 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -1,9 +1,9 @@ /* * * rtmouse_main.c - * Raspberry Pi Mouse device driver + * Raspberry Pi Mouse device driver main * - * Version: 3.3.2 + * Version: 3.3.3 * * Copyright (C) 2015-2024 RT Corporation * @@ -26,7 +26,7 @@ MODULE_AUTHOR("RT Corporation"); MODULE_LICENSE("GPL"); -MODULE_VERSION("3.3.2"); +MODULE_VERSION("3.3.3"); MODULE_DESCRIPTION("Raspberry Pi Mouse device driver"); /* --- Device Numbers --- */ From 71aa6615798aaa4e7957f71293910d00e0e646e8 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 17:37:53 +0900 Subject: [PATCH 11/26] =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=81=AE=E4=B8=A6?= =?UTF-8?q?=E3=81=B3=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse.h | 1 + src/drivers/rtmouse_dev_fops.c | 607 +++++++++++++++++---------------- src/drivers/rtmouse_main.c | 21 +- 3 files changed, 325 insertions(+), 304 deletions(-) diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index cba0f53..c71747b 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -300,6 +300,7 @@ ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, int rpi_gpio_function_set(int pin, uint32_t func); void rpi_gpio_set32(uint32_t mask, uint32_t val); void rpi_gpio_clear32(uint32_t mask, uint32_t val); +void rpi_pwm_write32(uint32_t offset, uint32_t val); int buzzer_init(void); #endif // RTMOUSE_H diff --git a/src/drivers/rtmouse_dev_fops.c b/src/drivers/rtmouse_dev_fops.c index baaac84..95ab41e 100644 --- a/src/drivers/rtmouse_dev_fops.c +++ b/src/drivers/rtmouse_dev_fops.c @@ -22,45 +22,9 @@ #include "rtmouse.h" -/* - * update_signed_count - update signed pulse count of dev_info - * called by rtcnt_read() - */ -void update_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) -{ - int diff_count = rtcnt_count - dev_info->raw_pulse_count; - - // カウントがMAX_PULSE_COUNTから0に変わる場合の処理 - // ただし、それ以外でもdiffが負の値になることがある - // そのため、diffが十分に大きな負の値の場合に処理する - // if(diff_count < 0) では正常に動作しない - if (diff_count < -SIGNED_COUNT_SIZE) { - diff_count += MAX_PULSE_COUNT; - } - - if (dev_info->client->addr == DEV_ADDR_CNTL) { - if (motor_l_freq_is_positive) { - dev_info->signed_pulse_count += diff_count; - } else { - dev_info->signed_pulse_count -= diff_count; - } - } else { - if (motor_r_freq_is_positive) { - dev_info->signed_pulse_count += diff_count; - } else { - dev_info->signed_pulse_count -= diff_count; - } - } - - if (dev_info->signed_pulse_count > SIGNED_COUNT_SIZE || - dev_info->signed_pulse_count < -SIGNED_COUNT_SIZE) { - dev_info->signed_pulse_count = 0; - } -} - /* * i2c_counter_set - set value to I2C pulse counter - * called by cntr_write() and cntl_write() + * called by rtcnt_write() */ static int i2c_counter_set(struct rtcnt_device_info *dev_info, int setval) { @@ -127,6 +91,42 @@ static int i2c_counter_read(struct rtcnt_device_info *dev_info, int *ret) return 0; } +/* + * update_signed_count - update signed pulse count of dev_info + * called by rtcnt_read() + */ +void update_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) +{ + int diff_count = rtcnt_count - dev_info->raw_pulse_count; + + // カウントがMAX_PULSE_COUNTから0に変わる場合の処理 + // ただし、それ以外でもdiffが負の値になることがある + // そのため、diffが十分に大きな負の値の場合に処理する + // if(diff_count < 0) では正常に動作しない + if (diff_count < -SIGNED_COUNT_SIZE) { + diff_count += MAX_PULSE_COUNT; + } + + if (dev_info->client->addr == DEV_ADDR_CNTL) { + if (motor_l_freq_is_positive) { + dev_info->signed_pulse_count += diff_count; + } else { + dev_info->signed_pulse_count -= diff_count; + } + } else { + if (motor_r_freq_is_positive) { + dev_info->signed_pulse_count += diff_count; + } else { + dev_info->signed_pulse_count -= diff_count; + } + } + + if (dev_info->signed_pulse_count > SIGNED_COUNT_SIZE || + dev_info->signed_pulse_count < -SIGNED_COUNT_SIZE) { + dev_info->signed_pulse_count = 0; + } +} + /* * reset_signed_count - reset signed pulse count of dev_info * called by rtcnt_write() @@ -140,9 +140,275 @@ void reset_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) } else if (rtcnt_count < -SIGNED_COUNT_SIZE) { rtcnt_count = -SIGNED_COUNT_SIZE; } - dev_info->signed_pulse_count = rtcnt_count; - i2c_counter_read(dev_info, &raw_count); - dev_info->raw_pulse_count = raw_count; + dev_info->signed_pulse_count = rtcnt_count; + i2c_counter_read(dev_info, &raw_count); + dev_info->raw_pulse_count = raw_count; +} + +/* + * mcp3204_get_value - get sensor data from MCP3204 + * called by sensor_read() + */ +static unsigned int mcp3204_get_value(int channel) +{ + struct device *dev; + struct mcp3204_drvdata *data; + struct spi_device *spi; + char str[128]; + + unsigned int r = 0; + unsigned char c = channel & 0x03; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) + + if (mcp320x_dev == NULL) + return 0; + dev = mcp320x_dev; + +#else + struct spi_master *master; + master = spi_busnum_to_master(mcp3204_info.bus_num); + snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), + mcp3204_info.chip_select); + dev = bus_find_device_by_name(&spi_bus_type, NULL, str); +#endif + + spi = to_spi_device(dev); + data = (struct mcp3204_drvdata *)spi_get_drvdata(spi); + mutex_lock(&data->lock); + data->tx[0] = 1 << 2; // start bit + data->tx[0] |= 1 << 1; // Single + data->tx[1] = c << 6; // channel + data->tx[2] = 0; + + if (spi_sync(data->spi, &data->msg)) { + printk(KERN_INFO "%s: spi_sync_transfer returned non zero\n", + __func__); + } + + mutex_unlock(&data->lock); + + r = (data->rx[1] & 0xf) << 8; + r |= data->rx[2]; + + // printk(KERN_INFO "%s: get result on ch[%d] : %04d\n", __func__, + // channel, r); + + return r; +} + +/* + * pwm set function + * called by buzzer_init() and set_motor_l_freq(), set_motor_r_freq(), buzzer_write() + */ +void rpi_pwm_write32(uint32_t offset, uint32_t val) +{ + iowrite32(val, pwm_base + offset); +} + +/* + * set mask and value + * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_put() and motoren_write() + */ +void rpi_gpio_set32(uint32_t mask, uint32_t val) +{ + gpio_base[RPI_GPSET0_INDEX] = val & mask; +} + +/* + * clear mask and value + * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_del() and motoren_write() + */ +void rpi_gpio_clear32(uint32_t mask, uint32_t val) +{ + gpio_base[RPI_GPCLR0_INDEX] = val & mask; +} + +/* + * set function + * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() and buzzer_write() + */ +int rpi_gpio_function_set(int pin, uint32_t func) +{ + int index = RPI_GPFSEL0_INDEX + pin / 10; + uint32_t mask = ~(0x7 << ((pin % 10) * 3)); + + gpio_base[index] = + (gpio_base[index] & mask) | ((func & 0x7) << ((pin % 10) * 3)); + + return 1; +} + +/* --- GPIO Operation --- */ +/* getPWMCount function for GPIO Operation */ +static int getPWMCount(int freq) +{ + if (freq < 1) + return PWM_BASECLK; + if (freq > 10000) + return PWM_BASECLK / 10000; + + return PWM_BASECLK / freq; +} + +/* + * left motor function + * called by parseMotorCmd() and rawmotor_l_write() + */ +static void set_motor_l_freq(int freq) +{ + int dat; + + rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); + + // Reset uncontrollable frequency to zero. + if (abs(freq) < MOTOR_UNCONTROLLABLE_FREQ) { + freq = 0; + } + + if (freq == 0) { + rpi_gpio_function_set(MOTCLK_L_BASE, RPI_GPF_OUTPUT); + return; + } else { + rpi_gpio_function_set(MOTCLK_L_BASE, RPI_GPF_ALT0); + } + + if (freq > 0) { + motor_l_freq_is_positive = 1; + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTDIR_L_BASE); + } else { + motor_l_freq_is_positive = 0; + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTDIR_L_BASE); + freq = -freq; + } + + dat = getPWMCount(freq); + + rpi_pwm_write32(RPI_PWM_RNG1, dat); + rpi_pwm_write32(RPI_PWM_DAT1, dat >> 1); + + return; +} + +/* + * right motor function + * called by parseMotorCmd() and rawmotor_r_write() + */ +static void set_motor_r_freq(int freq) +{ + int dat; + + rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); + + // Reset uncontrollable frequency to zero. + if (abs(freq) < MOTOR_UNCONTROLLABLE_FREQ) { + freq = 0; + } + + if (freq == 0) { + rpi_gpio_function_set(MOTCLK_R_BASE, RPI_GPF_OUTPUT); + return; + } else { + rpi_gpio_function_set(MOTCLK_R_BASE, RPI_GPF_ALT0); + } + + if (freq > 0) { + motor_r_freq_is_positive = 1; + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTDIR_R_BASE); + } else { + motor_r_freq_is_positive = 0; + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTDIR_R_BASE); + freq = -freq; + } + + dat = getPWMCount(freq); + + rpi_pwm_write32(RPI_PWM_RNG2, dat); + rpi_pwm_write32(RPI_PWM_DAT2, dat >> 1); + + return; +} + +/* + * Parse motor command + * called by motor_write() + */ +static int parseMotorCmd(const char __user *buf, size_t count, int *ret) +{ + int r_motor_val, l_motor_val, time_val; + char *newbuf = kmalloc(sizeof(char) * count, GFP_KERNEL); + + if (copy_from_user(newbuf, buf, sizeof(char) * count)) { + kfree(newbuf); + return -EFAULT; + } + + sscanf(newbuf, "%d%d%d\n", &l_motor_val, &r_motor_val, &time_val); + + kfree(newbuf); + + mutex_lock(&lock); + + set_motor_l_freq(l_motor_val); + set_motor_r_freq(r_motor_val); + + msleep_interruptible(time_val); + + set_motor_l_freq(0); + set_motor_r_freq(0); + + mutex_unlock(&lock); + + return count; +} + +/* + * Turn On LEDs + * return 0 : device close + * called by led_write() + */ +static int led_put(int ledno) +{ + switch (ledno) { + case 0: + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED0_BASE); + break; + case 1: + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED1_BASE); + break; + case 2: + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED2_BASE); + break; + case 3: + rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED3_BASE); + break; + } + return 0; +} + +/* + * Turn Off LEDs + * return 0 : device close + * called by led_write() + */ +static int led_del(int ledno) +{ + switch (ledno) { + case 0: + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED0_BASE); + break; + case 1: + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED1_BASE); + break; + case 2: + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED2_BASE); + break; + case 3: + rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED3_BASE); + break; + } + + return 0; } /* @@ -296,58 +562,6 @@ static ssize_t sw_read(struct file *filep, char __user *buf, size_t count, return count; } -/* - * mcp3204_get_value - get sensor data from MCP3204 - * called by 'sensor_read' - */ -static unsigned int mcp3204_get_value(int channel) -{ - struct device *dev; - struct mcp3204_drvdata *data; - struct spi_device *spi; - char str[128]; - - unsigned int r = 0; - unsigned char c = channel & 0x03; - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) - - if (mcp320x_dev == NULL) - return 0; - dev = mcp320x_dev; - -#else - struct spi_master *master; - master = spi_busnum_to_master(mcp3204_info.bus_num); - snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), - mcp3204_info.chip_select); - dev = bus_find_device_by_name(&spi_bus_type, NULL, str); -#endif - - spi = to_spi_device(dev); - data = (struct mcp3204_drvdata *)spi_get_drvdata(spi); - mutex_lock(&data->lock); - data->tx[0] = 1 << 2; // start bit - data->tx[0] |= 1 << 1; // Single - data->tx[1] = c << 6; // channel - data->tx[2] = 0; - - if (spi_sync(data->spi, &data->msg)) { - printk(KERN_INFO "%s: spi_sync_transfer returned non zero\n", - __func__); - } - - mutex_unlock(&data->lock); - - r = (data->rx[1] & 0xf) << 8; - r |= data->rx[2]; - - // printk(KERN_INFO "%s: get result on ch[%d] : %04d\n", __func__, - // channel, r); - - return r; -} - /* * Read Sensor information * return 0 : device close @@ -420,215 +634,6 @@ static ssize_t sensor_read(struct file *filep, char __user *buf, size_t count, return count; } -/* pwm set function */ -static void rpi_pwm_write32(uint32_t offset, uint32_t val) -{ - iowrite32(val, pwm_base + offset); -} - -/* - * Initialize buzzer - * return 0 : device close - */ -int buzzer_init(void) -{ - - rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); // io is pwm out - rpi_pwm_write32(RPI_PWM_CTRL, 0x00000000); - udelay(1000); - rpi_pwm_write32(RPI_PWM_CTRL, 0x00008181); // PWM1,2 enable - - // printk(KERN_DEBUG "%s: rpi_pwm_ctrl:%08X\n", DRIVER_NAME, - // ioread32(pwm_base + RPI_PWM_CTRL)); - - return 0; -} - -/* --- GPIO Operation --- */ -/* getPWMCount function for GPIO Operation */ -static int getPWMCount(int freq) -{ - if (freq < 1) - return PWM_BASECLK; - if (freq > 10000) - return PWM_BASECLK / 10000; - - return PWM_BASECLK / freq; -} - -/* left motor function */ -static void set_motor_l_freq(int freq) -{ - int dat; - - rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); - - // Reset uncontrollable frequency to zero. - if (abs(freq) < MOTOR_UNCONTROLLABLE_FREQ) { - freq = 0; - } - - if (freq == 0) { - rpi_gpio_function_set(MOTCLK_L_BASE, RPI_GPF_OUTPUT); - return; - } else { - rpi_gpio_function_set(MOTCLK_L_BASE, RPI_GPF_ALT0); - } - - if (freq > 0) { - motor_l_freq_is_positive = 1; - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTDIR_L_BASE); - } else { - motor_l_freq_is_positive = 0; - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTDIR_L_BASE); - freq = -freq; - } - - dat = getPWMCount(freq); - - rpi_pwm_write32(RPI_PWM_RNG1, dat); - rpi_pwm_write32(RPI_PWM_DAT1, dat >> 1); - - return; -} - -/* right motor function */ -static void set_motor_r_freq(int freq) -{ - int dat; - - rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); - - // Reset uncontrollable frequency to zero. - if (abs(freq) < MOTOR_UNCONTROLLABLE_FREQ) { - freq = 0; - } - - if (freq == 0) { - rpi_gpio_function_set(MOTCLK_R_BASE, RPI_GPF_OUTPUT); - return; - } else { - rpi_gpio_function_set(MOTCLK_R_BASE, RPI_GPF_ALT0); - } - - if (freq > 0) { - motor_r_freq_is_positive = 1; - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << MOTDIR_R_BASE); - } else { - motor_r_freq_is_positive = 0; - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << MOTDIR_R_BASE); - freq = -freq; - } - - dat = getPWMCount(freq); - - rpi_pwm_write32(RPI_PWM_RNG2, dat); - rpi_pwm_write32(RPI_PWM_DAT2, dat >> 1); - - return; -} - -/* Parse motor command */ -static int parseMotorCmd(const char __user *buf, size_t count, int *ret) -{ - int r_motor_val, l_motor_val, time_val; - char *newbuf = kmalloc(sizeof(char) * count, GFP_KERNEL); - - if (copy_from_user(newbuf, buf, sizeof(char) * count)) { - kfree(newbuf); - return -EFAULT; - } - - sscanf(newbuf, "%d%d%d\n", &l_motor_val, &r_motor_val, &time_val); - - kfree(newbuf); - - mutex_lock(&lock); - - set_motor_l_freq(l_motor_val); - set_motor_r_freq(r_motor_val); - - msleep_interruptible(time_val); - - set_motor_l_freq(0); - set_motor_r_freq(0); - - mutex_unlock(&lock); - - return count; -} - -/* - * Turn On LEDs - * return 0 : device close - */ -static int led_put(int ledno) -{ - switch (ledno) { - case 0: - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED0_BASE); - break; - case 1: - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED1_BASE); - break; - case 2: - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED2_BASE); - break; - case 3: - rpi_gpio_set32(RPI_GPIO_P2MASK, 1 << LED3_BASE); - break; - } - return 0; -} - -/*set mask and value */ -void rpi_gpio_set32(uint32_t mask, uint32_t val) -{ - gpio_base[RPI_GPSET0_INDEX] = val & mask; -} - -/* clear mask and value */ -void rpi_gpio_clear32(uint32_t mask, uint32_t val) -{ - gpio_base[RPI_GPCLR0_INDEX] = val & mask; -} - -/* set function */ -int rpi_gpio_function_set(int pin, uint32_t func) -{ - int index = RPI_GPFSEL0_INDEX + pin / 10; - uint32_t mask = ~(0x7 << ((pin % 10) * 3)); - - gpio_base[index] = - (gpio_base[index] & mask) | ((func & 0x7) << ((pin % 10) * 3)); - - return 1; -} - -/* - * Turn Off LEDs - * return 0 : device close - */ -static int led_del(int ledno) -{ - switch (ledno) { - case 0: - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED0_BASE); - break; - case 1: - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED1_BASE); - break; - case 2: - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED2_BASE); - break; - case 3: - rpi_gpio_clear32(RPI_GPIO_P2MASK, 1 << LED3_BASE); - break; - } - - return 0; -} - /* --- Device File Operation --- */ /* Open Device */ int dev_open(struct inode *inode, struct file *filep) diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 50a284b..e2a6150 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -83,9 +83,6 @@ volatile int cdev_index = 0; struct mutex lock; /* --- Function Declarations --- */ -static void set_motor_r_freq(int freq); -static void set_motor_l_freq(int freq); - #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) static int mcp3204_remove(struct spi_device *spi); #else @@ -168,6 +165,24 @@ struct i2c_driver i2c_counter_driver = { MODULE_DEVICE_TABLE(spi, mcp3204_id); MODULE_DEVICE_TABLE(i2c, i2c_counter_id); +/* + * Initialize buzzer + * return 0 : device close + */ +int buzzer_init(void) +{ + + rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); // io is pwm out + rpi_pwm_write32(RPI_PWM_CTRL, 0x00000000); + udelay(1000); + rpi_pwm_write32(RPI_PWM_CTRL, 0x00008181); // PWM1,2 enable + + // printk(KERN_DEBUG "%s: rpi_pwm_ctrl:%08X\n", DRIVER_NAME, + // ioread32(pwm_base + RPI_PWM_CTRL)); + + return 0; +} + /* --- GPIO mapping for Device Open/Close --- */ /* * Get gpio addresses and set them to global variables. From b2d7b7d6feeb480fed77192a5b6b17f608869ec8 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 18:04:02 +0900 Subject: [PATCH 12/26] =?UTF-8?q?=E5=A4=96=E9=83=A8=E5=A4=89=E6=95=B0?= =?UTF-8?q?=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse.h | 22 +++---------------- src/drivers/rtmouse_dev_fops.c | 9 +++++--- src/drivers/rtmouse_main.c | 39 ++++++++++++++++------------------ 3 files changed, 27 insertions(+), 43 deletions(-) diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index c71747b..eca97c9 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -252,35 +252,18 @@ struct rtcnt_device_info { int raw_pulse_count; }; -/* --- extern --- */ -extern unsigned int NUM_DEV[ID_DEV_SIZE]; -extern char *NAME_DEV[ID_DEV_SIZE]; -extern char *NAME_DEV_U[ID_DEV_SIZE]; -extern int _major_dev[ID_DEV_SIZE]; -extern int _minor_dev[ID_DEV_SIZE]; -extern struct cdev *cdev_array; -extern struct class *class_dev[ID_DEV_SIZE]; +/* --- rtmouse_dev_fops.c extern --- */ extern volatile void __iomem *pwm_base; -extern volatile void __iomem *clk_base; extern volatile uint32_t *gpio_base; -extern volatile int cdev_index; extern struct mutex lock; -extern struct spi_device_id mcp3204_id[]; extern struct spi_board_info mcp3204_info; -extern struct spi_driver mcp3204_driver; -extern struct i2c_client *i2c_client_r; -extern struct i2c_client *i2c_client_l; -extern unsigned int motor_l_freq_is_positive; -extern unsigned int motor_r_freq_is_positive; -extern struct i2c_device_id i2c_counter_id[]; -extern struct i2c_driver i2c_counter_driver; extern struct file_operations dev_fops[ID_DEV_SIZE]; #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) extern struct device *mcp320x_dev; #endif -/* --- function --- */ +/* --- rtmouse_dev_fops.c function --- */ int dev_open(struct inode *inode, struct file *filep); int dev_release(struct inode *inode, struct file *filep); int i2c_dev_open(struct inode *inode, struct file *filep); @@ -302,5 +285,6 @@ void rpi_gpio_set32(uint32_t mask, uint32_t val); void rpi_gpio_clear32(uint32_t mask, uint32_t val); void rpi_pwm_write32(uint32_t offset, uint32_t val); int buzzer_init(void); +unsigned int mcp3204_get_value(int channel); #endif // RTMOUSE_H diff --git a/src/drivers/rtmouse_dev_fops.c b/src/drivers/rtmouse_dev_fops.c index 95ab41e..18bd759 100644 --- a/src/drivers/rtmouse_dev_fops.c +++ b/src/drivers/rtmouse_dev_fops.c @@ -22,6 +22,9 @@ #include "rtmouse.h" +static unsigned int motor_l_freq_is_positive = 1; +static unsigned int motor_r_freq_is_positive = 1; + /* * i2c_counter_set - set value to I2C pulse counter * called by rtcnt_write() @@ -95,7 +98,7 @@ static int i2c_counter_read(struct rtcnt_device_info *dev_info, int *ret) * update_signed_count - update signed pulse count of dev_info * called by rtcnt_read() */ -void update_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) +static void update_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) { int diff_count = rtcnt_count - dev_info->raw_pulse_count; @@ -131,7 +134,7 @@ void update_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) * reset_signed_count - reset signed pulse count of dev_info * called by rtcnt_write() */ -void reset_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) +static void reset_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) { int raw_count; @@ -149,7 +152,7 @@ void reset_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) * mcp3204_get_value - get sensor data from MCP3204 * called by sensor_read() */ -static unsigned int mcp3204_get_value(int channel) +unsigned int mcp3204_get_value(int channel) { struct device *dev; struct mcp3204_drvdata *data; diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index e2a6150..1be5e1b 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -30,13 +30,13 @@ MODULE_VERSION("3.3.3"); MODULE_DESCRIPTION("Raspberry Pi Mouse device driver"); /* --- Device Numbers --- */ -unsigned int NUM_DEV[ID_DEV_SIZE] = { +static const unsigned int NUM_DEV[ID_DEV_SIZE] = { [ID_DEV_LED] = 4, [ID_DEV_SWITCH] = 3, [ID_DEV_SENSOR] = 1, [ID_DEV_BUZZER] = 1, [ID_DEV_MOTORRAWR] = 1, [ID_DEV_MOTORRAWL] = 1, [ID_DEV_MOTOREN] = 1, [ID_DEV_MOTOR] = 1, [ID_DEV_CNT] = 2}; /* --- Device Names --- */ -char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", +static const char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", [ID_DEV_SWITCH] = "rtswitch", [ID_DEV_SENSOR] = "rtlightsensor", [ID_DEV_BUZZER] = "rtbuzzer", @@ -45,7 +45,7 @@ char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", [ID_DEV_MOTOREN] = "rtmotoren", [ID_DEV_MOTOR] = "rtmotor"}; -char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", +static const char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", [ID_DEV_SWITCH] = "rtswitch%u", [ID_DEV_SENSOR] = "rtlightsensor%u", [ID_DEV_BUZZER] = "rtbuzzer%u", @@ -55,31 +55,31 @@ char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", [ID_DEV_MOTOR] = "rtmotor%u"}; // used in by register_dev() and cleanup_each_dev() -int _major_dev[ID_DEV_SIZE] = { +static int _major_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = DEV_MAJOR, [ID_DEV_SWITCH] = DEV_MAJOR, [ID_DEV_SENSOR] = DEV_MAJOR, [ID_DEV_BUZZER] = DEV_MAJOR, [ID_DEV_MOTORRAWR] = DEV_MAJOR, [ID_DEV_MOTORRAWL] = DEV_MAJOR, [ID_DEV_MOTOREN] = DEV_MAJOR, [ID_DEV_MOTOR] = DEV_MAJOR}; // used in register_dev() and cleanup_each_dev() -int _minor_dev[ID_DEV_SIZE] = { +static int _minor_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = DEV_MINOR, [ID_DEV_SWITCH] = DEV_MINOR, [ID_DEV_SENSOR] = DEV_MINOR, [ID_DEV_BUZZER] = DEV_MINOR, [ID_DEV_MOTORRAWR] = DEV_MINOR, [ID_DEV_MOTORRAWL] = DEV_MINOR, [ID_DEV_MOTOREN] = DEV_MINOR, [ID_DEV_MOTOR] = DEV_MINOR}; /* --- General Options --- */ -struct cdev *cdev_array = NULL; -struct class *class_dev[ID_DEV_SIZE] = { +static struct cdev *cdev_array = NULL; +static struct class *class_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = NULL, [ID_DEV_SWITCH] = NULL, [ID_DEV_SENSOR] = NULL, [ID_DEV_BUZZER] = NULL, [ID_DEV_MOTORRAWR] = NULL, [ID_DEV_MOTORRAWL] = NULL, [ID_DEV_MOTOREN] = NULL, [ID_DEV_MOTOR] = NULL}; volatile void __iomem *pwm_base; -volatile void __iomem *clk_base; +static volatile void __iomem *clk_base; volatile uint32_t *gpio_base; -volatile int cdev_index = 0; +static volatile int cdev_index = 0; struct mutex lock; /* --- Function Declarations --- */ @@ -90,7 +90,6 @@ static void mcp3204_remove(struct spi_device *spi); #endif static int mcp3204_probe(struct spi_device *spi); -static unsigned int mcp3204_get_value(int channel); #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0) static int rtcnt_i2c_probe(struct i2c_client *client, @@ -107,7 +106,7 @@ static void rtcnt_i2c_remove(struct i2c_client *client); /* --- Static variables --- */ /* SPI device ID */ -struct spi_device_id mcp3204_id[] = { +static struct spi_device_id mcp3204_id[] = { {"mcp3204", 0}, {}, }; @@ -126,7 +125,7 @@ struct device *mcp320x_dev; #endif /* SPI Dirver Info */ -struct spi_driver mcp3204_driver = { +static struct spi_driver mcp3204_driver = { .driver = { .name = DEVNAME_SENSOR, @@ -137,20 +136,18 @@ struct spi_driver mcp3204_driver = { .remove = mcp3204_remove, }; -struct i2c_client *i2c_client_r = NULL; -struct i2c_client *i2c_client_l = NULL; -unsigned int motor_l_freq_is_positive = 1; -unsigned int motor_r_freq_is_positive = 1; +static struct i2c_client *i2c_client_r = NULL; +static struct i2c_client *i2c_client_l = NULL; /* I2C Device ID */ -struct i2c_device_id i2c_counter_id[] = { +static struct i2c_device_id i2c_counter_id[] = { {DEVNAME_CNTL, 0}, {DEVNAME_CNTR, 1}, {}, }; /* I2C Dirver Info */ -struct i2c_driver i2c_counter_driver = { +static struct i2c_driver i2c_counter_driver = { .driver = { .name = "rtcounter", @@ -829,7 +826,7 @@ static void rtcnt_i2c_remove(struct i2c_client *client) * dev_init_module - register driver module * called by module_init(dev_init_module) */ -int dev_init_module(void) +static int dev_init_module(void) { int retval, i; int registered_devices = 0; @@ -939,7 +936,7 @@ int dev_init_module(void) * dev_cleanup_module - cleanup driver module * called by module_exit(dev_cleanup_module) */ -void cleanup_each_dev(int id_dev) +static void cleanup_each_dev(int id_dev) { int i; dev_t devno; @@ -953,7 +950,7 @@ void cleanup_each_dev(int id_dev) unregister_chrdev_region(devno_top, NUM_DEV[id_dev]); } -void dev_cleanup_module(void) +static void dev_cleanup_module(void) { int i; From c680610180b76f095a45f3935d60be9610c86796 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 18:07:00 +0900 Subject: [PATCH 13/26] =?UTF-8?q?lint=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=97?= =?UTF-8?q?=E3=81=A6=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse_main.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 1be5e1b..835b722 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -36,23 +36,25 @@ static const unsigned int NUM_DEV[ID_DEV_SIZE] = { [ID_DEV_MOTOREN] = 1, [ID_DEV_MOTOR] = 1, [ID_DEV_CNT] = 2}; /* --- Device Names --- */ -static const char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", - [ID_DEV_SWITCH] = "rtswitch", - [ID_DEV_SENSOR] = "rtlightsensor", - [ID_DEV_BUZZER] = "rtbuzzer", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l", - [ID_DEV_MOTOREN] = "rtmotoren", - [ID_DEV_MOTOR] = "rtmotor"}; - -static const char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", - [ID_DEV_SWITCH] = "rtswitch%u", - [ID_DEV_SENSOR] = "rtlightsensor%u", - [ID_DEV_BUZZER] = "rtbuzzer%u", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", - [ID_DEV_MOTOREN] = "rtmotoren%u", - [ID_DEV_MOTOR] = "rtmotor%u"}; +static const char *NAME_DEV[ID_DEV_SIZE] = { + [ID_DEV_LED] = "rtled", + [ID_DEV_SWITCH] = "rtswitch", + [ID_DEV_SENSOR] = "rtlightsensor", + [ID_DEV_BUZZER] = "rtbuzzer", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l", + [ID_DEV_MOTOREN] = "rtmotoren", + [ID_DEV_MOTOR] = "rtmotor"}; + +static const char *NAME_DEV_U[ID_DEV_SIZE] = { + [ID_DEV_LED] = "rtled%u", + [ID_DEV_SWITCH] = "rtswitch%u", + [ID_DEV_SENSOR] = "rtlightsensor%u", + [ID_DEV_BUZZER] = "rtbuzzer%u", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", + [ID_DEV_MOTOREN] = "rtmotoren%u", + [ID_DEV_MOTOR] = "rtmotor%u"}; // used in by register_dev() and cleanup_each_dev() static int _major_dev[ID_DEV_SIZE] = { From 29482389999dfbdbfca5ef1a4d6f7b166a1d3b8e Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 18:15:57 +0900 Subject: [PATCH 14/26] =?UTF-8?q?=E5=A4=96=E9=83=A8=E3=81=8B=E3=82=89?= =?UTF-8?q?=E3=82=82=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B=E9=96=A2=E6=95=B0?= =?UTF-8?q?=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse.h | 23 ++--------------------- src/drivers/rtmouse_dev_fops.c | 22 +++++++++++----------- src/drivers/rtmouse_main.c | 2 +- 3 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index eca97c9..92c7e4f 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -252,39 +252,20 @@ struct rtcnt_device_info { int raw_pulse_count; }; -/* --- rtmouse_dev_fops.c extern --- */ +/* --- used in rtmouse_dev_fops.c --- */ extern volatile void __iomem *pwm_base; extern volatile uint32_t *gpio_base; extern struct mutex lock; extern struct spi_board_info mcp3204_info; extern struct file_operations dev_fops[ID_DEV_SIZE]; - #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) extern struct device *mcp320x_dev; #endif -/* --- rtmouse_dev_fops.c function --- */ -int dev_open(struct inode *inode, struct file *filep); -int dev_release(struct inode *inode, struct file *filep); -int i2c_dev_open(struct inode *inode, struct file *filep); -int i2c_dev_release(struct inode *inode, struct file *filep); -ssize_t led_write(struct file *filep, const char __user *buf, size_t count, - loff_t *f_pos); -ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, - loff_t *f_pos); -ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos); -ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos); -ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, - loff_t *f_pos); -ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, - loff_t *f_pos); +/* --- used in rtmouse_dev_fops.c --- */ int rpi_gpio_function_set(int pin, uint32_t func); void rpi_gpio_set32(uint32_t mask, uint32_t val); void rpi_gpio_clear32(uint32_t mask, uint32_t val); void rpi_pwm_write32(uint32_t offset, uint32_t val); -int buzzer_init(void); -unsigned int mcp3204_get_value(int channel); #endif // RTMOUSE_H diff --git a/src/drivers/rtmouse_dev_fops.c b/src/drivers/rtmouse_dev_fops.c index 18bd759..f709a18 100644 --- a/src/drivers/rtmouse_dev_fops.c +++ b/src/drivers/rtmouse_dev_fops.c @@ -152,7 +152,7 @@ static void reset_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_cou * mcp3204_get_value - get sensor data from MCP3204 * called by sensor_read() */ -unsigned int mcp3204_get_value(int channel) +static unsigned int mcp3204_get_value(int channel) { struct device *dev; struct mcp3204_drvdata *data; @@ -639,7 +639,7 @@ static ssize_t sensor_read(struct file *filep, char __user *buf, size_t count, /* --- Device File Operation --- */ /* Open Device */ -int dev_open(struct inode *inode, struct file *filep) +static int dev_open(struct inode *inode, struct file *filep) { int *minor = (int *)kmalloc(sizeof(int), GFP_KERNEL); int major = MAJOR(inode->i_rdev); @@ -654,13 +654,13 @@ int dev_open(struct inode *inode, struct file *filep) } /* Close device */ -int dev_release(struct inode *inode, struct file *filep) +static int dev_release(struct inode *inode, struct file *filep) { kfree(filep->private_data); return 0; } -int i2c_dev_open(struct inode *inode, struct file *filep) +static int i2c_dev_open(struct inode *inode, struct file *filep) { struct rtcnt_device_info *dev_info; dev_info = container_of(inode->i_cdev, struct rtcnt_device_info, cdev); @@ -672,13 +672,13 @@ int i2c_dev_open(struct inode *inode, struct file *filep) return 0; } -int i2c_dev_release(struct inode *inode, struct file *filep) { return 0; } +static int i2c_dev_release(struct inode *inode, struct file *filep) { return 0; } /* * led_write - Trun ON/OFF LEDs * Write function of /dev/rtled */ -ssize_t led_write(struct file *filep, const char __user *buf, size_t count, +static ssize_t led_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) { char cval; @@ -706,7 +706,7 @@ ssize_t led_write(struct file *filep, const char __user *buf, size_t count, * buzzer_write - Write buzzer frequency * Write function of /dev/rtbuzzer */ -ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, +static ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) { int ret; @@ -745,7 +745,7 @@ ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, * rawmotor_l_write - Output frequency to the left motor * Write function of /dev/rtmotor_raw_l */ -ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, +static ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) { int freq, ret; @@ -765,7 +765,7 @@ ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, * rawmotor_r_write - Output frequency to the right motor * Write function of /dev/rtmotor_raw_r */ -ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, +static ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) { int freq, ret; @@ -786,7 +786,7 @@ ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, * motoren_write - Turn ON/OFF SteppingMotor Power * Write function of /dev/rtmotoren */ -ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, +static ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) { char cval; @@ -813,7 +813,7 @@ ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, * motor_write - Output frequency to right and left both motors * Write function of /dev/rtmotor */ -ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, +static ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, loff_t *f_pos) { int tmp; diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 835b722..c4738a0 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -168,7 +168,7 @@ MODULE_DEVICE_TABLE(i2c, i2c_counter_id); * Initialize buzzer * return 0 : device close */ -int buzzer_init(void) +static int buzzer_init(void) { rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); // io is pwm out From 92ec244bfb0b9fe3d2f439fe534a6db0e519ac8d Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Tue, 5 Nov 2024 18:26:55 +0900 Subject: [PATCH 15/26] =?UTF-8?q?lint=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=97?= =?UTF-8?q?=E3=81=A6=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse_dev_fops.c | 43 ++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/drivers/rtmouse_dev_fops.c b/src/drivers/rtmouse_dev_fops.c index f709a18..d7cab02 100644 --- a/src/drivers/rtmouse_dev_fops.c +++ b/src/drivers/rtmouse_dev_fops.c @@ -98,7 +98,8 @@ static int i2c_counter_read(struct rtcnt_device_info *dev_info, int *ret) * update_signed_count - update signed pulse count of dev_info * called by rtcnt_read() */ -static void update_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) +static void update_signed_count(struct rtcnt_device_info *dev_info, + int rtcnt_count) { int diff_count = rtcnt_count - dev_info->raw_pulse_count; @@ -134,7 +135,8 @@ static void update_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_co * reset_signed_count - reset signed pulse count of dev_info * called by rtcnt_write() */ -static void reset_signed_count(struct rtcnt_device_info *dev_info, int rtcnt_count) +static void reset_signed_count(struct rtcnt_device_info *dev_info, + int rtcnt_count) { int raw_count; @@ -202,7 +204,8 @@ static unsigned int mcp3204_get_value(int channel) /* * pwm set function - * called by buzzer_init() and set_motor_l_freq(), set_motor_r_freq(), buzzer_write() + * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() + * and buzzer_write() */ void rpi_pwm_write32(uint32_t offset, uint32_t val) { @@ -211,7 +214,8 @@ void rpi_pwm_write32(uint32_t offset, uint32_t val) /* * set mask and value - * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_put() and motoren_write() + * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_put() + * and motoren_write() */ void rpi_gpio_set32(uint32_t mask, uint32_t val) { @@ -220,7 +224,8 @@ void rpi_gpio_set32(uint32_t mask, uint32_t val) /* * clear mask and value - * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_del() and motoren_write() + * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_del() + * and motoren_write() */ void rpi_gpio_clear32(uint32_t mask, uint32_t val) { @@ -229,7 +234,8 @@ void rpi_gpio_clear32(uint32_t mask, uint32_t val) /* * set function - * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() and buzzer_write() + * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() and + * buzzer_write() */ int rpi_gpio_function_set(int pin, uint32_t func) { @@ -672,14 +678,17 @@ static int i2c_dev_open(struct inode *inode, struct file *filep) return 0; } -static int i2c_dev_release(struct inode *inode, struct file *filep) { return 0; } +static int i2c_dev_release(struct inode *inode, struct file *filep) +{ + return 0; +} /* * led_write - Trun ON/OFF LEDs * Write function of /dev/rtled */ -static ssize_t led_write(struct file *filep, const char __user *buf, size_t count, - loff_t *f_pos) +static ssize_t led_write(struct file *filep, const char __user *buf, + size_t count, loff_t *f_pos) { char cval; int ret; @@ -706,8 +715,8 @@ static ssize_t led_write(struct file *filep, const char __user *buf, size_t coun * buzzer_write - Write buzzer frequency * Write function of /dev/rtbuzzer */ -static ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t count, - loff_t *f_pos) +static ssize_t buzzer_write(struct file *filep, const char __user *buf, + size_t count, loff_t *f_pos) { int ret; int freq, dat; @@ -746,7 +755,7 @@ static ssize_t buzzer_write(struct file *filep, const char __user *buf, size_t c * Write function of /dev/rtmotor_raw_l */ static ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos) + size_t count, loff_t *f_pos) { int freq, ret; @@ -766,7 +775,7 @@ static ssize_t rawmotor_l_write(struct file *filep, const char __user *buf, * Write function of /dev/rtmotor_raw_r */ static ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, - size_t count, loff_t *f_pos) + size_t count, loff_t *f_pos) { int freq, ret; @@ -786,8 +795,8 @@ static ssize_t rawmotor_r_write(struct file *filep, const char __user *buf, * motoren_write - Turn ON/OFF SteppingMotor Power * Write function of /dev/rtmotoren */ -static ssize_t motoren_write(struct file *filep, const char __user *buf, size_t count, - loff_t *f_pos) +static ssize_t motoren_write(struct file *filep, const char __user *buf, + size_t count, loff_t *f_pos) { char cval; @@ -813,8 +822,8 @@ static ssize_t motoren_write(struct file *filep, const char __user *buf, size_t * motor_write - Output frequency to right and left both motors * Write function of /dev/rtmotor */ -static ssize_t motor_write(struct file *filep, const char __user *buf, size_t count, - loff_t *f_pos) +static ssize_t motor_write(struct file *filep, const char __user *buf, + size_t count, loff_t *f_pos) { int tmp; int bufcnt; From cead9f2e579a411a10510330472b098bc974065c Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 10:41:15 +0900 Subject: [PATCH 16/26] =?UTF-8?q?rtmouse=5Fmain.c=E3=81=A7=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=99=E3=82=8B=E9=96=A2=E6=95=B0=E3=81=AFrtmouse?= =?UTF-8?q?=5Fmain.c=E3=81=AB=E6=AE=8B=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse_dev_fops.c | 46 ---------------------------------- src/drivers/rtmouse_main.c | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/src/drivers/rtmouse_dev_fops.c b/src/drivers/rtmouse_dev_fops.c index d7cab02..b3358b9 100644 --- a/src/drivers/rtmouse_dev_fops.c +++ b/src/drivers/rtmouse_dev_fops.c @@ -202,52 +202,6 @@ static unsigned int mcp3204_get_value(int channel) return r; } -/* - * pwm set function - * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() - * and buzzer_write() - */ -void rpi_pwm_write32(uint32_t offset, uint32_t val) -{ - iowrite32(val, pwm_base + offset); -} - -/* - * set mask and value - * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_put() - * and motoren_write() - */ -void rpi_gpio_set32(uint32_t mask, uint32_t val) -{ - gpio_base[RPI_GPSET0_INDEX] = val & mask; -} - -/* - * clear mask and value - * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_del() - * and motoren_write() - */ -void rpi_gpio_clear32(uint32_t mask, uint32_t val) -{ - gpio_base[RPI_GPCLR0_INDEX] = val & mask; -} - -/* - * set function - * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() and - * buzzer_write() - */ -int rpi_gpio_function_set(int pin, uint32_t func) -{ - int index = RPI_GPFSEL0_INDEX + pin / 10; - uint32_t mask = ~(0x7 << ((pin % 10) * 3)); - - gpio_base[index] = - (gpio_base[index] & mask) | ((func & 0x7) << ((pin % 10) * 3)); - - return 1; -} - /* --- GPIO Operation --- */ /* getPWMCount function for GPIO Operation */ static int getPWMCount(int freq) diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index c4738a0..4d8b837 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -164,6 +164,52 @@ static struct i2c_driver i2c_counter_driver = { MODULE_DEVICE_TABLE(spi, mcp3204_id); MODULE_DEVICE_TABLE(i2c, i2c_counter_id); +/* + * set function + * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() and + * buzzer_write() + */ +int rpi_gpio_function_set(int pin, uint32_t func) +{ + int index = RPI_GPFSEL0_INDEX + pin / 10; + uint32_t mask = ~(0x7 << ((pin % 10) * 3)); + + gpio_base[index] = + (gpio_base[index] & mask) | ((func & 0x7) << ((pin % 10) * 3)); + + return 1; +} + +/* + * set mask and value + * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_put() + * and motoren_write() + */ +void rpi_gpio_set32(uint32_t mask, uint32_t val) +{ + gpio_base[RPI_GPSET0_INDEX] = val & mask; +} + +/* + * clear mask and value + * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_del() + * and motoren_write() + */ +void rpi_gpio_clear32(uint32_t mask, uint32_t val) +{ + gpio_base[RPI_GPCLR0_INDEX] = val & mask; +} + +/* + * pwm set function + * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() + * and buzzer_write() + */ +void rpi_pwm_write32(uint32_t offset, uint32_t val) +{ + iowrite32(val, pwm_base + offset); +} + /* * Initialize buzzer * return 0 : device close From 5b87a720fbf08e9e5f8b03f1c69d6c828db71630 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 11:53:09 +0900 Subject: [PATCH 17/26] =?UTF-8?q?rtmouse=5Fspi.c=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=81=97=E3=81=A6SPI=E9=96=A2=E9=80=A3=E3=81=AE?= =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=82=92=E7=A7=BB=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/Makefile.header_from_apt | 4 +- src/drivers/Makefile.header_from_source | 4 +- src/drivers/rtmouse.h | 5 +- src/drivers/rtmouse_main.c | 209 +--------------------- src/drivers/rtmouse_spi.c | 223 ++++++++++++++++++++++++ 5 files changed, 236 insertions(+), 209 deletions(-) create mode 100644 src/drivers/rtmouse_spi.c diff --git a/src/drivers/Makefile.header_from_apt b/src/drivers/Makefile.header_from_apt index 5c67a61..9669df7 100644 --- a/src/drivers/Makefile.header_from_apt +++ b/src/drivers/Makefile.header_from_apt @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o $(MODULE)_spi.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux-headers-$(shell uname -r) VERBOSE:=0 -$(MODULE).ko: $(MODULE)_dev_fops.c $(MODULE)_main.c $(MODULE).h +$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev_fops.c $(MODULE)_spi.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/Makefile.header_from_source b/src/drivers/Makefile.header_from_source index b910cdc..c9d2c0c 100644 --- a/src/drivers/Makefile.header_from_source +++ b/src/drivers/Makefile.header_from_source @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o $(MODULE)_spi.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux VERBOSE:=0 -$(MODULE).ko: $(MODULE)_dev_fops.c $(MODULE)_main.c $(MODULE).h +$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev_fops.c $(MODULE)_spi.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index 92c7e4f..a08be6b 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -262,10 +262,13 @@ extern struct file_operations dev_fops[ID_DEV_SIZE]; extern struct device *mcp320x_dev; #endif -/* --- used in rtmouse_dev_fops.c --- */ int rpi_gpio_function_set(int pin, uint32_t func); void rpi_gpio_set32(uint32_t mask, uint32_t val); void rpi_gpio_clear32(uint32_t mask, uint32_t val); void rpi_pwm_write32(uint32_t offset, uint32_t val); +/* --- used in rtmouse_spi.c --- */ +int mcp3204_init(void); +void mcp3204_exit(void); + #endif // RTMOUSE_H diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 4d8b837..8b85565 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -78,21 +78,15 @@ static struct class *class_dev[ID_DEV_SIZE] = { [ID_DEV_MOTORRAWR] = NULL, [ID_DEV_MOTORRAWL] = NULL, [ID_DEV_MOTOREN] = NULL, [ID_DEV_MOTOR] = NULL}; -volatile void __iomem *pwm_base; static volatile void __iomem *clk_base; -volatile uint32_t *gpio_base; static volatile int cdev_index = 0; + +// used in rtmouse_dev_fops.c +volatile void __iomem *pwm_base; +volatile uint32_t *gpio_base; struct mutex lock; /* --- Function Declarations --- */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) -static int mcp3204_remove(struct spi_device *spi); -#else -static void mcp3204_remove(struct spi_device *spi); -#endif - -static int mcp3204_probe(struct spi_device *spi); - #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0) static int rtcnt_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id); @@ -107,37 +101,11 @@ static void rtcnt_i2c_remove(struct i2c_client *client); #endif /* --- Static variables --- */ -/* SPI device ID */ -static struct spi_device_id mcp3204_id[] = { - {"mcp3204", 0}, - {}, -}; - -/* SPI Info */ -struct spi_board_info mcp3204_info = { - .modalias = "mcp3204", - .max_speed_hz = 100000, - .bus_num = 0, - .chip_select = 0, - .mode = SPI_MODE_3, -}; - +// used in rtmouse_dev_fops.c #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) struct device *mcp320x_dev; #endif -/* SPI Dirver Info */ -static struct spi_driver mcp3204_driver = { - .driver = - { - .name = DEVNAME_SENSOR, - .owner = THIS_MODULE, - }, - .id_table = mcp3204_id, - .probe = mcp3204_probe, - .remove = mcp3204_remove, -}; - static struct i2c_client *i2c_client_r = NULL; static struct i2c_client *i2c_client_l = NULL; @@ -161,7 +129,6 @@ static struct i2c_driver i2c_counter_driver = { }; /* -- Device Addition -- */ -MODULE_DEVICE_TABLE(spi, mcp3204_id); MODULE_DEVICE_TABLE(i2c, i2c_counter_id); /* @@ -365,172 +332,6 @@ static int register_dev(int id_dev) return 0; } -/* mcp3204_remove - remove function lined with spi_dirver */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) -static int mcp3204_remove(struct spi_device *spi) -{ - struct mcp3204_drvdata *data; - /* get drvdata */ - data = (struct mcp3204_drvdata *)spi_get_drvdata(spi); - /* free kernel memory */ - kfree(data); - printk(KERN_INFO "%s: mcp3204 removed\n", DRIVER_NAME); - return 0; -} -#else -static void mcp3204_remove(struct spi_device *spi) -{ - struct mcp3204_drvdata *data; - /* get drvdata */ - data = (struct mcp3204_drvdata *)spi_get_drvdata(spi); - /* free kernel memory */ - kfree(data); - printk(KERN_INFO "%s: mcp3204 removed\n", DRIVER_NAME); -} -#endif - -/* mcp3204_probe - probe function lined with spi_dirver */ -static int mcp3204_probe(struct spi_device *spi) -{ - struct mcp3204_drvdata *data; - - spi->max_speed_hz = mcp3204_info.max_speed_hz; - spi->mode = mcp3204_info.mode; - spi->bits_per_word = 8; - - if (spi_setup(spi)) { - printk(KERN_ERR "%s:spi_setup failed!\n", __func__); - return -ENODEV; - } - - /* alloc kernel memory */ - data = kzalloc(sizeof(struct mcp3204_drvdata), GFP_KERNEL); - if (data == NULL) { - printk(KERN_ERR "%s:kzalloc() failed!\n", __func__); - return -ENODEV; - } - - data->spi = spi; - - mutex_init(&data->lock); - - // memset(data->tx, 0, MCP320X_PACKET_SIZE); - // memset(data->rx, 0, MCP320X_PACKET_SIZE); - - data->xfer.tx_buf = data->tx; - data->xfer.rx_buf = data->rx; - data->xfer.bits_per_word = 8; - data->xfer.len = MCP320X_PACKET_SIZE; - data->xfer.cs_change = 0; - data->xfer.speed_hz = 100000; - - spi_message_init_with_transfers(&data->msg, &data->xfer, 1); - - /* set drvdata */ - spi_set_drvdata(spi, data); - - printk(KERN_INFO "%s: mcp3204 probed", DRIVER_NAME); - - return 0; -} - -/* - * spi_remove_device - remove SPI device - * called by mcp3204_init and mcp3204_exit - */ -static void spi_remove_device(struct spi_master *master, unsigned int cs) -{ - struct device *dev; - char str[128]; - - snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), cs); - - dev = bus_find_device_by_name(&spi_bus_type, NULL, str); - // ここを参考にspi_deviceを取得するプログラムを作成する - if (dev) { - device_del(dev); - } -} - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) -/* spiをサーチする関数 */ -static int __callback_find_mcp3204(struct device *dev, void *data) -{ - printk(KERN_INFO " device_name: %s\n", dev->driver->name); - if (mcp320x_dev == NULL && strcmp(dev->driver->name, "mcp320x") == 0) { - mcp320x_dev = dev; - mcp3204_probe(to_spi_device(dev)); - } - return 0; -} -#endif - -/* - * mcp3204_init - initialize MCP3204 - * called by 'dev_init_module' - */ -static int mcp3204_init(void) -{ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) - bus_for_each_dev(&spi_bus_type, NULL, NULL, __callback_find_mcp3204); -#else - struct spi_master *master; - struct spi_device *spi_device; - - spi_register_driver(&mcp3204_driver); - - mcp3204_info.bus_num = SPI_BUS_NUM; - mcp3204_info.chip_select = SPI_CHIP_SELECT; - - master = spi_busnum_to_master(mcp3204_info.bus_num); - - if (!master) { - printk(KERN_ERR "%s: spi_busnum_to_master returned NULL\n", - __func__); - spi_unregister_driver(&mcp3204_driver); - return -ENODEV; - } - - spi_remove_device(master, mcp3204_info.chip_select); - - spi_device = spi_new_device(master, &mcp3204_info); - if (!spi_device) { - printk(KERN_ERR "%s: spi_new_device returned NULL\n", __func__); - spi_unregister_driver(&mcp3204_driver); - return -ENODEV; - } -#endif - - return 0; -} - -/* - * mcp3204_exit - cleanup MCP3204 - * called by dev_cleanup_module() - */ -static void mcp3204_exit(void) -{ - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) - printk(KERN_INFO " mcp3204_exit\n"); - if (mcp320x_dev) { - mcp3204_remove(to_spi_device(mcp320x_dev)); - } -#else - struct spi_master *master; - master = spi_busnum_to_master(mcp3204_info.bus_num); - - if (master) { - spi_remove_device(master, mcp3204_info.chip_select); - } else { - printk(KERN_ERR "mcp3204 remove error\n"); - } - - spi_unregister_driver(&mcp3204_driver); -#endif -} - static int rtcntr_i2c_create_cdev(struct rtcnt_device_info *dev_info) { int minor; diff --git a/src/drivers/rtmouse_spi.c b/src/drivers/rtmouse_spi.c new file mode 100644 index 0000000..3e3f319 --- /dev/null +++ b/src/drivers/rtmouse_spi.c @@ -0,0 +1,223 @@ +#include "rtmouse.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) +static int mcp3204_remove(struct spi_device *spi); +#else +static void mcp3204_remove(struct spi_device *spi); +#endif +static int mcp3204_probe(struct spi_device *spi); + +/* + * SPI device ID + * used in mcp3204_driver + */ +static struct spi_device_id mcp3204_id[] = { + {"mcp3204", 0}, + {}, +}; + +/* + * SPI Info + * used in mcp3204_probe(), mcp3204_init(), mcp3204_exit() + * and mcp3204_get_value() + */ +struct spi_board_info mcp3204_info = { + .modalias = "mcp3204", + .max_speed_hz = 100000, + .bus_num = 0, + .chip_select = 0, + .mode = SPI_MODE_3, +}; + +/* + * SPI Dirver Info + * used in mcp3204_init() and mcp3204_exit() + */ +static struct spi_driver mcp3204_driver = { + .driver = + { + .name = DEVNAME_SENSOR, + .owner = THIS_MODULE, + }, + .id_table = mcp3204_id, + .probe = mcp3204_probe, + .remove = mcp3204_remove, +}; + +/* -- Device Addition -- */ +MODULE_DEVICE_TABLE(spi, mcp3204_id); + +/* + * mcp3204_remove - remove function lined with spi_dirver + * used in mcp3204_driver and mcp3204_exit() + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) +static int mcp3204_remove(struct spi_device *spi) +{ + struct mcp3204_drvdata *data; + /* get drvdata */ + data = (struct mcp3204_drvdata *)spi_get_drvdata(spi); + /* free kernel memory */ + kfree(data); + printk(KERN_INFO "%s: mcp3204 removed\n", DRIVER_NAME); + return 0; +} +#else +static void mcp3204_remove(struct spi_device *spi) +{ + struct mcp3204_drvdata *data; + /* get drvdata */ + data = (struct mcp3204_drvdata *)spi_get_drvdata(spi); + /* free kernel memory */ + kfree(data); + printk(KERN_INFO "%s: mcp3204 removed\n", DRIVER_NAME); +} +#endif + +/* + * mcp3204_probe - probe function lined with spi_dirver + * used in mcp3204_driver and __callback_find_mcp3204() + */ +static int mcp3204_probe(struct spi_device *spi) +{ + struct mcp3204_drvdata *data; + + spi->max_speed_hz = mcp3204_info.max_speed_hz; + spi->mode = mcp3204_info.mode; + spi->bits_per_word = 8; + + if (spi_setup(spi)) { + printk(KERN_ERR "%s:spi_setup failed!\n", __func__); + return -ENODEV; + } + + /* alloc kernel memory */ + data = kzalloc(sizeof(struct mcp3204_drvdata), GFP_KERNEL); + if (data == NULL) { + printk(KERN_ERR "%s:kzalloc() failed!\n", __func__); + return -ENODEV; + } + + data->spi = spi; + + mutex_init(&data->lock); + + // memset(data->tx, 0, MCP320X_PACKET_SIZE); + // memset(data->rx, 0, MCP320X_PACKET_SIZE); + + data->xfer.tx_buf = data->tx; + data->xfer.rx_buf = data->rx; + data->xfer.bits_per_word = 8; + data->xfer.len = MCP320X_PACKET_SIZE; + data->xfer.cs_change = 0; + data->xfer.speed_hz = 100000; + + spi_message_init_with_transfers(&data->msg, &data->xfer, 1); + + /* set drvdata */ + spi_set_drvdata(spi, data); + + printk(KERN_INFO "%s: mcp3204 probed", DRIVER_NAME); + + return 0; +} + +/* + * spi_remove_device - remove SPI device + * called by mcp3204_init() and mcp3204_exit() + */ +static void spi_remove_device(struct spi_master *master, unsigned int cs) +{ + struct device *dev; + char str[128]; + + snprintf(str, sizeof(str), "%s.%u", dev_name(&master->dev), cs); + + dev = bus_find_device_by_name(&spi_bus_type, NULL, str); + // ここを参考にspi_deviceを取得するプログラムを作成する + if (dev) { + device_del(dev); + } +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) +/* + * spiをサーチする関数 + * used in mcp3204_init() + */ +static int __callback_find_mcp3204(struct device *dev, void *data) +{ + printk(KERN_INFO " device_name: %s\n", dev->driver->name); + if (mcp320x_dev == NULL && strcmp(dev->driver->name, "mcp320x") == 0) { + mcp320x_dev = dev; + mcp3204_probe(to_spi_device(dev)); + } + return 0; +} +#endif + +/* + * mcp3204_init - initialize MCP3204 + * called by dev_init_module() + */ +int mcp3204_init(void) +{ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) + bus_for_each_dev(&spi_bus_type, NULL, NULL, __callback_find_mcp3204); +#else + struct spi_master *master; + struct spi_device *spi_device; + + spi_register_driver(&mcp3204_driver); + + mcp3204_info.bus_num = SPI_BUS_NUM; + mcp3204_info.chip_select = SPI_CHIP_SELECT; + + master = spi_busnum_to_master(mcp3204_info.bus_num); + + if (!master) { + printk(KERN_ERR "%s: spi_busnum_to_master returned NULL\n", + __func__); + spi_unregister_driver(&mcp3204_driver); + return -ENODEV; + } + + spi_remove_device(master, mcp3204_info.chip_select); + + spi_device = spi_new_device(master, &mcp3204_info); + if (!spi_device) { + printk(KERN_ERR "%s: spi_new_device returned NULL\n", __func__); + spi_unregister_driver(&mcp3204_driver); + return -ENODEV; + } +#endif + + return 0; +} + +/* + * mcp3204_exit - cleanup MCP3204 + * called by dev_cleanup_module() + */ +void mcp3204_exit(void) +{ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) + printk(KERN_INFO " mcp3204_exit\n"); + if (mcp320x_dev) { + mcp3204_remove(to_spi_device(mcp320x_dev)); + } +#else + struct spi_master *master; + master = spi_busnum_to_master(mcp3204_info.bus_num); + + if (master) { + spi_remove_device(master, mcp3204_info.chip_select); + } else { + printk(KERN_ERR "mcp3204 remove error\n"); + } + + spi_unregister_driver(&mcp3204_driver); +#endif +} From c1f774a20ce0367119336ab4aaf8716961fb344e Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 11:59:29 +0900 Subject: [PATCH 18/26] =?UTF-8?q?rtmouse=5Fspi.c=E3=81=AB=E3=82=B3?= =?UTF-8?q?=E3=83=A1=E3=83=B3=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse_spi.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/drivers/rtmouse_spi.c b/src/drivers/rtmouse_spi.c index 3e3f319..8d6a134 100644 --- a/src/drivers/rtmouse_spi.c +++ b/src/drivers/rtmouse_spi.c @@ -1,3 +1,25 @@ +/* + * + * rtmouse_spi.c + * SPI Driver + * + * Copyright (C) 2024 RT Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + #include "rtmouse.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0) From f6cd192b9e2cefc15ae806715cba66c66819529c Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 16:23:50 +0900 Subject: [PATCH 19/26] =?UTF-8?q?rtmouse=5Fi2c.c=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=81=97=E3=81=A6I2C=E9=96=A2=E9=80=A3=E3=81=AE?= =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=82=92=E7=A7=BB=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/Makefile.header_from_apt | 4 +- src/drivers/Makefile.header_from_source | 4 +- src/drivers/rtmouse.h | 7 + src/drivers/rtmouse_dev_fops.c | 6 +- src/drivers/rtmouse_i2c.c | 412 ++++++++++++++++++++++++ src/drivers/rtmouse_main.c | 394 +--------------------- 6 files changed, 439 insertions(+), 388 deletions(-) create mode 100644 src/drivers/rtmouse_i2c.c diff --git a/src/drivers/Makefile.header_from_apt b/src/drivers/Makefile.header_from_apt index 9669df7..bb31919 100644 --- a/src/drivers/Makefile.header_from_apt +++ b/src/drivers/Makefile.header_from_apt @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o $(MODULE)_spi.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o $(MODULE)_spi.o $(MODULE)_i2c.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux-headers-$(shell uname -r) VERBOSE:=0 -$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev_fops.c $(MODULE)_spi.c $(MODULE).h +$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev_fops.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/Makefile.header_from_source b/src/drivers/Makefile.header_from_source index c9d2c0c..8244f9a 100644 --- a/src/drivers/Makefile.header_from_source +++ b/src/drivers/Makefile.header_from_source @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o $(MODULE)_spi.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o $(MODULE)_spi.o $(MODULE)_i2c.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux VERBOSE:=0 -$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev_fops.c $(MODULE)_spi.c $(MODULE).h +$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev_fops.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index a08be6b..356e527 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -271,4 +271,11 @@ void rpi_pwm_write32(uint32_t offset, uint32_t val); int mcp3204_init(void); void mcp3204_exit(void); +/* --- used in rtmouse_i2c.c --- */ +extern const unsigned int NUM_DEV[ID_DEV_SIZE]; +extern struct cdev *cdev_array; +extern volatile int cdev_index; +int i2c_counter_init(void); +void i2c_counter_exit(void); + #endif // RTMOUSE_H diff --git a/src/drivers/rtmouse_dev_fops.c b/src/drivers/rtmouse_dev_fops.c index b3358b9..cf3e874 100644 --- a/src/drivers/rtmouse_dev_fops.c +++ b/src/drivers/rtmouse_dev_fops.c @@ -786,7 +786,11 @@ static ssize_t motor_write(struct file *filep, const char __user *buf, return bufcnt; } -/* --- Device File Operations --- */ +/* + * Device File Operations + * used in register_dev(), rtcntr_i2c_create_cdev() + * and rtcntl_i2c_create_cdev() + */ struct file_operations dev_fops[ID_DEV_SIZE] = { [ID_DEV_LED].open = dev_open, [ID_DEV_LED].release = dev_release, diff --git a/src/drivers/rtmouse_i2c.c b/src/drivers/rtmouse_i2c.c new file mode 100644 index 0000000..25c181f --- /dev/null +++ b/src/drivers/rtmouse_i2c.c @@ -0,0 +1,412 @@ +/* + * + * rtmouse_i2c.c + * I2C Driver + * + * Copyright (C) 2024 RT Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "rtmouse.h" + +/* --- Function Declarations --- */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0) +static int rtcnt_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id); +#else +static int rtcnt_i2c_probe(struct i2c_client *client); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int rtcnt_i2c_remove(struct i2c_client *client); +#else +static void rtcnt_i2c_remove(struct i2c_client *client); +#endif + +// used in i2c_counter_init() and i2c_counter_exit() +static struct i2c_client *i2c_client_r = NULL; +static struct i2c_client *i2c_client_l = NULL; + +/* + * I2C Device ID + * used in i2c_counter_driver + */ +static struct i2c_device_id i2c_counter_id[] = { + {DEVNAME_CNTL, 0}, + {DEVNAME_CNTR, 1}, + {}, +}; + +/* + * I2C Dirver Info + * used in i2c_counter_init() and i2c_counter_exit() + */ +static struct i2c_driver i2c_counter_driver = { + .driver = + { + .name = "rtcounter", + .owner = THIS_MODULE, + }, + .id_table = i2c_counter_id, + .probe = rtcnt_i2c_probe, + .remove = rtcnt_i2c_remove, +}; + +/* -- Device Addition -- */ +MODULE_DEVICE_TABLE(i2c, i2c_counter_id); + +static int rtcntr_i2c_create_cdev(struct rtcnt_device_info *dev_info) +{ + int minor; + int alloc_ret = 0; + int cdev_err = 0; + dev_t dev; + + /* 空いているメジャー番号を確保する */ + alloc_ret = alloc_chrdev_region(&dev, DEV_MINOR, NUM_DEV[ID_DEV_CNT], + DEVNAME_CNTR); + if (alloc_ret != 0) { + printk(KERN_ERR "alloc_chrdev_region = %d\n", alloc_ret); + return -1; + } + + /* 取得したdev( = メジャー番号 + マイナー番号) + * からメジャー番号を取得して保持しておく */ + dev_info->device_major = MAJOR(dev); + dev = MKDEV(dev_info->device_major, DEV_MINOR); + + /* cdev構造体の初期化とシステムコールハンドラテーブルの登録 */ + cdev_init(&dev_info->cdev, &dev_fops[ID_DEV_CNT]); + dev_info->cdev.owner = THIS_MODULE; + + /* このデバイスドライバ(cdev)をカーネルに登録する */ + cdev_err = cdev_add(&dev_info->cdev, dev, NUM_DEV[ID_DEV_CNT]); + if (cdev_err != 0) { + printk(KERN_ERR "cdev_add = %d\n", alloc_ret); + unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); + return -1; + } + + /* このデバイスのクラス登録をする(/sys/class/mydevice/ を作る) */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) + dev_info->device_class = class_create(THIS_MODULE, DEVNAME_CNTR); +#else + dev_info->device_class = class_create(DEVNAME_CNTR); +#endif + + if (IS_ERR(dev_info->device_class)) { + printk(KERN_ERR "class_create\n"); + cdev_del(&dev_info->cdev); + unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); + return -1; + } + + for (minor = DEV_MINOR; minor < DEV_MINOR + NUM_DEV[ID_DEV_CNT]; + minor++) { + + struct device *dev_ret; + dev_ret = device_create(dev_info->device_class, NULL, + MKDEV(dev_info->device_major, minor), + NULL, "rtcounter_r%d", minor); + + /* デバイスファイル作成の可否を判定 */ + if (IS_ERR(dev_ret)) { + /* デバイスファイルの作成に失敗した */ + printk(KERN_ERR "device_create failed minor = %d\n", + minor); + /* リソースリークを避けるために登録された状態cdevを削除する + */ + cdev_del(&(cdev_array[cdev_index])); + return PTR_ERR(dev_ret); + } + } + + return 0; +} + +// called by rtcnt_i2c_probe() +static int rtcntl_i2c_create_cdev(struct rtcnt_device_info *dev_info) +{ + int minor; + int alloc_ret = 0; + int cdev_err = 0; + dev_t dev; + + /* 空いているメジャー番号を確保する */ + alloc_ret = alloc_chrdev_region(&dev, DEV_MINOR, NUM_DEV[ID_DEV_CNT], + DEVNAME_CNTL); + if (alloc_ret != 0) { + printk(KERN_ERR "alloc_chrdev_region = %d\n", alloc_ret); + return -1; + } + + /* 取得したdev( = メジャー番号 + マイナー番号) + * からメジャー番号を取得して保持しておく */ + dev_info->device_major = MAJOR(dev); + dev = MKDEV(dev_info->device_major, DEV_MINOR); + + /* cdev構造体の初期化とシステムコールハンドラテーブルの登録 */ + cdev_init(&dev_info->cdev, &dev_fops[ID_DEV_CNT]); + dev_info->cdev.owner = THIS_MODULE; + + /* このデバイスドライバ(cdev)をカーネルに登録する */ + cdev_err = cdev_add(&dev_info->cdev, dev, NUM_DEV[ID_DEV_CNT]); + if (cdev_err != 0) { + printk(KERN_ERR "cdev_add = %d\n", alloc_ret); + unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); + return -1; + } + +/* このデバイスのクラス登録をする(/sys/class/mydevice/ を作る) */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) + dev_info->device_class = class_create(THIS_MODULE, DEVNAME_CNTL); +#else + dev_info->device_class = class_create(DEVNAME_CNTL); +#endif + + if (IS_ERR(dev_info->device_class)) { + printk(KERN_ERR "class_create\n"); + cdev_del(&dev_info->cdev); + unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); + return -1; + } + + /* /sys/class/mydevice/mydevice* を作る */ + for (minor = DEV_MINOR; minor < DEV_MINOR + NUM_DEV[ID_DEV_CNT]; + minor++) { + + struct device *dev_ret; + dev_ret = device_create(dev_info->device_class, NULL, + MKDEV(dev_info->device_major, minor), + NULL, "rtcounter_l%d", minor); + + /* デバイスファイル作成の可否を判定 */ + if (IS_ERR(dev_ret)) { + /* デバイスファイルの作成に失敗した */ + printk(KERN_ERR "device_create failed minor = %d\n", + minor); + /* リソースリークを避けるために登録された状態cdevを削除する + */ + cdev_del(&(cdev_array[cdev_index])); + return PTR_ERR(dev_ret); + } + } + + return 0; +} + +// called by rtcnt_i2c_remove() +static void rtcnt_i2c_delete_cdev(struct rtcnt_device_info *dev_info) +{ + dev_t dev = MKDEV(dev_info->device_major, DEV_MINOR); + int minor; + /* /sys/class/mydevice/mydevice* を削除する */ + for (minor = DEV_MINOR; minor < DEV_MINOR + NUM_DEV[ID_DEV_CNT]; + minor++) { + device_destroy(dev_info->device_class, + MKDEV(dev_info->device_major, minor)); + } + /* このデバイスのクラス登録を取り除く(/sys/class/mydevice/を削除する) */ + class_destroy(dev_info->device_class); + /* このデバイスドライバ(cdev)をカーネルから取り除く */ + cdev_del(&dev_info->cdev); + /* このデバイスドライバで使用していたメジャー番号の登録を取り除く */ + unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); +} + +// called by i2c_counter_driver() +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0) +static int rtcnt_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct rtcnt_device_info *dev_info; + int msb = 0, lsb = 0; + // printk(KERN_DEBUG "%s: probing i2c device", __func__); + + /* check i2c device */ + // printk(KERN_DEBUG "%s: checking i2c device", __func__); + msb = i2c_smbus_read_byte_data(client, CNT_ADDR_MSB); + lsb = i2c_smbus_read_byte_data(client, CNT_ADDR_LSB); + if ((msb < 0) || (lsb < 0)) { + printk(KERN_INFO + "%s: rtcounter not found, or wrong i2c device probed", + DRIVER_NAME); + // printk(KERN_DEBUG "%s: addr 0x%x, msb %d, lsb %d", __func__, + // client->addr, msb, lsb); + return -ENODEV; + } + printk(KERN_INFO "%s: new i2c device probed, id.name=%s, " + "id.driver_data=%d, addr=0x%x\n", + DRIVER_NAME, id->name, (int)(id->driver_data), client->addr); + + dev_info = (struct rtcnt_device_info *)devm_kzalloc( + &client->dev, sizeof(struct rtcnt_device_info), GFP_KERNEL); + dev_info->client = client; + i2c_set_clientdata(client, dev_info); + mutex_init(&dev_info->lock); + + /* create character device */ + if ((int)(id->driver_data) == 0) { + if (rtcntl_i2c_create_cdev(dev_info)) + return -ENOMEM; + } else if ((int)(id->driver_data) == 1) { + if (rtcntr_i2c_create_cdev(dev_info)) + return -ENOMEM; + } + + return 0; +} +#else +static int rtcnt_i2c_probe(struct i2c_client *client) +{ + const struct i2c_device_id *id = i2c_client_get_device_id(client); + struct rtcnt_device_info *dev_info; + int msb = 0, lsb = 0; + // printk(KERN_DEBUG "%s: probing i2c device", __func__); + + /* check i2c device */ + // printk(KERN_DEBUG "%s: checking i2c device", __func__); + msb = i2c_smbus_read_byte_data(client, CNT_ADDR_MSB); + lsb = i2c_smbus_read_byte_data(client, CNT_ADDR_LSB); + if ((msb < 0) || (lsb < 0)) { + printk(KERN_INFO + "%s: rtcounter not found, or wrong i2c device probed", + DRIVER_NAME); + // printk(KERN_DEBUG "%s: addr 0x%x, msb %d, lsb %d", __func__, + // client->addr, msb, lsb); + return -ENODEV; + } + printk(KERN_INFO "%s: new i2c device probed, id.name=%s, " + "id.driver_data=%d, addr=0x%x\n", + DRIVER_NAME, id->name, (int)(id->driver_data), client->addr); + + dev_info = (struct rtcnt_device_info *)devm_kzalloc( + &client->dev, sizeof(struct rtcnt_device_info), GFP_KERNEL); + dev_info->client = client; + i2c_set_clientdata(client, dev_info); + mutex_init(&dev_info->lock); + + /* create character device */ + if ((int)(id->driver_data) == 0) { + if (rtcntl_i2c_create_cdev(dev_info)) + return -ENOMEM; + } else if ((int)(id->driver_data) == 1) { + if (rtcntr_i2c_create_cdev(dev_info)) + return -ENOMEM; + } + + return 0; +} +#endif + +/* + * i2c_counter_remove - I2C pulse counter + * called when I2C pulse counter removed + * called by i2c_counter_driver() + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) +static int rtcnt_i2c_remove(struct i2c_client *client) +{ + struct rtcnt_device_info *dev_info; + // printk(KERN_DEBUG "%s: removing i2c device 0x%x\n", __func__, + // client->addr); + dev_info = i2c_get_clientdata(client); + rtcnt_i2c_delete_cdev(dev_info); + printk(KERN_INFO "%s: i2c device 0x%x removed\n", DRIVER_NAME, + client->addr); + return 0; +} +#else +static void rtcnt_i2c_remove(struct i2c_client *client) +{ + struct rtcnt_device_info *dev_info; + // printk(KERN_DEBUG "%s: removing i2c device 0x%x\n", __func__, + // client->addr); + dev_info = i2c_get_clientdata(client); + rtcnt_i2c_delete_cdev(dev_info); + printk(KERN_INFO "%s: i2c device 0x%x removed\n", DRIVER_NAME, + client->addr); +} +#endif + +/* + * i2c_counter_init - initialize I2C counter + * called by dev_init_module() + */ +int i2c_counter_init(void) +{ + int retval = 0; + struct i2c_adapter *i2c_adap_l; + struct i2c_adapter *i2c_adap_r; + struct i2c_board_info i2c_board_info_l = { + I2C_BOARD_INFO(DEVNAME_CNTL, DEV_ADDR_CNTL)}; + struct i2c_board_info i2c_board_info_r = { + I2C_BOARD_INFO(DEVNAME_CNTR, DEV_ADDR_CNTR)}; + + // printk(KERN_DEBUG "%s: initializing i2c device", __func__); + retval = i2c_add_driver(&i2c_counter_driver); + if (retval != 0) { + printk(KERN_INFO "%s: failed adding i2c device", DRIVER_NAME); + return retval; + } + + /* + * 動的にデバイス実体を作成 + * (https://www.kernel.org/doc/Documentation/i2c/instantiating-devices) + */ +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 0, 0) + // printk(KERN_DEBUG "%s: adding i2c device", __func__); + i2c_adap_l = i2c_get_adapter(1); + i2c_client_l = i2c_new_device(i2c_adap_l, &i2c_board_info_l); + i2c_put_adapter(i2c_adap_l); + // printk(KERN_DEBUG "%s: added i2c device rtcntl", __func__); + + // printk(KERN_DEBUG "%s: adding i2c device", __func__); + i2c_adap_r = i2c_get_adapter(1); + i2c_client_r = i2c_new_device(i2c_adap_r, &i2c_board_info_r); + i2c_put_adapter(i2c_adap_r); + // printk(KERN_DEBUG "%s: added i2c device rtcntr", __func__); +#else + // printk(KERN_DEBUG "%s: adding i2c device", __func__); + i2c_adap_l = i2c_get_adapter(1); + i2c_client_l = i2c_new_client_device(i2c_adap_l, &i2c_board_info_l); + i2c_put_adapter(i2c_adap_l); + // printk(KERN_DEBUG "%s: added i2c device rtcntl", __func__); + + // printk(KERN_DEBUG "%s: adding i2c device", __func__); + i2c_adap_r = i2c_get_adapter(1); + i2c_client_r = i2c_new_client_device(i2c_adap_r, &i2c_board_info_r); + i2c_put_adapter(i2c_adap_r); + // printk(KERN_DEBUG "%s: added i2c device rtcntr", __func__); +#endif + + return retval; +} + +/* + * i2c_counter_exit - cleanup I2C device + * called by dev_cleanup_module() + */ +void i2c_counter_exit(void) +{ + /* delete I2C driver */ + i2c_del_driver(&i2c_counter_driver); + /* free memory */ + if (i2c_client_r) + i2c_unregister_device(i2c_client_r); + if (i2c_client_l) + i2c_unregister_device(i2c_client_l); +} diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 8b85565..08201c5 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -1,7 +1,7 @@ /* * * rtmouse_main.c - * Raspberry Pi Mouse device driver main + * Raspberry Pi Mouse device driver * * Version: 3.3.3 * @@ -29,8 +29,11 @@ MODULE_LICENSE("GPL"); MODULE_VERSION("3.3.3"); MODULE_DESCRIPTION("Raspberry Pi Mouse device driver"); -/* --- Device Numbers --- */ -static const unsigned int NUM_DEV[ID_DEV_SIZE] = { +/* + * --- Device Numbers --- + * used in rtmouse_i2c.c + */ +const unsigned int NUM_DEV[ID_DEV_SIZE] = { [ID_DEV_LED] = 4, [ID_DEV_SWITCH] = 3, [ID_DEV_SENSOR] = 1, [ID_DEV_BUZZER] = 1, [ID_DEV_MOTORRAWR] = 1, [ID_DEV_MOTORRAWL] = 1, [ID_DEV_MOTOREN] = 1, [ID_DEV_MOTOR] = 1, [ID_DEV_CNT] = 2}; @@ -46,6 +49,7 @@ static const char *NAME_DEV[ID_DEV_SIZE] = { [ID_DEV_MOTOREN] = "rtmotoren", [ID_DEV_MOTOR] = "rtmotor"}; +/* --- Device Names(+%u) --- */ static const char *NAME_DEV_U[ID_DEV_SIZE] = { [ID_DEV_LED] = "rtled%u", [ID_DEV_SWITCH] = "rtswitch%u", @@ -71,7 +75,6 @@ static int _minor_dev[ID_DEV_SIZE] = { [ID_DEV_MOTOREN] = DEV_MINOR, [ID_DEV_MOTOR] = DEV_MINOR}; /* --- General Options --- */ -static struct cdev *cdev_array = NULL; static struct class *class_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = NULL, [ID_DEV_SWITCH] = NULL, [ID_DEV_SENSOR] = NULL, [ID_DEV_BUZZER] = NULL, @@ -79,58 +82,22 @@ static struct class *class_dev[ID_DEV_SIZE] = { [ID_DEV_MOTOREN] = NULL, [ID_DEV_MOTOR] = NULL}; static volatile void __iomem *clk_base; -static volatile int cdev_index = 0; + +// used in rtmouse_i2c.c +struct cdev *cdev_array = NULL; +volatile int cdev_index = 0; // used in rtmouse_dev_fops.c volatile void __iomem *pwm_base; volatile uint32_t *gpio_base; struct mutex lock; -/* --- Function Declarations --- */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0) -static int rtcnt_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id); -#else -static int rtcnt_i2c_probe(struct i2c_client *client); -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) -static int rtcnt_i2c_remove(struct i2c_client *client); -#else -static void rtcnt_i2c_remove(struct i2c_client *client); -#endif - /* --- Static variables --- */ // used in rtmouse_dev_fops.c #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) struct device *mcp320x_dev; #endif -static struct i2c_client *i2c_client_r = NULL; -static struct i2c_client *i2c_client_l = NULL; - -/* I2C Device ID */ -static struct i2c_device_id i2c_counter_id[] = { - {DEVNAME_CNTL, 0}, - {DEVNAME_CNTR, 1}, - {}, -}; - -/* I2C Dirver Info */ -static struct i2c_driver i2c_counter_driver = { - .driver = - { - .name = "rtcounter", - .owner = THIS_MODULE, - }, - .id_table = i2c_counter_id, - .probe = rtcnt_i2c_probe, - .remove = rtcnt_i2c_remove, -}; - -/* -- Device Addition -- */ -MODULE_DEVICE_TABLE(i2c, i2c_counter_id); - /* * set function * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() and @@ -332,345 +299,6 @@ static int register_dev(int id_dev) return 0; } -static int rtcntr_i2c_create_cdev(struct rtcnt_device_info *dev_info) -{ - int minor; - int alloc_ret = 0; - int cdev_err = 0; - dev_t dev; - - /* 空いているメジャー番号を確保する */ - alloc_ret = alloc_chrdev_region(&dev, DEV_MINOR, NUM_DEV[ID_DEV_CNT], - DEVNAME_CNTR); - if (alloc_ret != 0) { - printk(KERN_ERR "alloc_chrdev_region = %d\n", alloc_ret); - return -1; - } - - /* 取得したdev( = メジャー番号 + マイナー番号) - * からメジャー番号を取得して保持しておく */ - dev_info->device_major = MAJOR(dev); - dev = MKDEV(dev_info->device_major, DEV_MINOR); - - /* cdev構造体の初期化とシステムコールハンドラテーブルの登録 */ - cdev_init(&dev_info->cdev, &dev_fops[ID_DEV_CNT]); - dev_info->cdev.owner = THIS_MODULE; - - /* このデバイスドライバ(cdev)をカーネルに登録する */ - cdev_err = cdev_add(&dev_info->cdev, dev, NUM_DEV[ID_DEV_CNT]); - if (cdev_err != 0) { - printk(KERN_ERR "cdev_add = %d\n", alloc_ret); - unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); - return -1; - } - - /* このデバイスのクラス登録をする(/sys/class/mydevice/ を作る) */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) - dev_info->device_class = class_create(THIS_MODULE, DEVNAME_CNTR); -#else - dev_info->device_class = class_create(DEVNAME_CNTR); -#endif - - if (IS_ERR(dev_info->device_class)) { - printk(KERN_ERR "class_create\n"); - cdev_del(&dev_info->cdev); - unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); - return -1; - } - - for (minor = DEV_MINOR; minor < DEV_MINOR + NUM_DEV[ID_DEV_CNT]; - minor++) { - - struct device *dev_ret; - dev_ret = device_create(dev_info->device_class, NULL, - MKDEV(dev_info->device_major, minor), - NULL, "rtcounter_r%d", minor); - - /* デバイスファイル作成の可否を判定 */ - if (IS_ERR(dev_ret)) { - /* デバイスファイルの作成に失敗した */ - printk(KERN_ERR "device_create failed minor = %d\n", - minor); - /* リソースリークを避けるために登録された状態cdevを削除する - */ - cdev_del(&(cdev_array[cdev_index])); - return PTR_ERR(dev_ret); - } - } - - return 0; -} - -static int rtcntl_i2c_create_cdev(struct rtcnt_device_info *dev_info) -{ - int minor; - int alloc_ret = 0; - int cdev_err = 0; - dev_t dev; - - /* 空いているメジャー番号を確保する */ - alloc_ret = alloc_chrdev_region(&dev, DEV_MINOR, NUM_DEV[ID_DEV_CNT], - DEVNAME_CNTL); - if (alloc_ret != 0) { - printk(KERN_ERR "alloc_chrdev_region = %d\n", alloc_ret); - return -1; - } - - /* 取得したdev( = メジャー番号 + マイナー番号) - * からメジャー番号を取得して保持しておく */ - dev_info->device_major = MAJOR(dev); - dev = MKDEV(dev_info->device_major, DEV_MINOR); - - /* cdev構造体の初期化とシステムコールハンドラテーブルの登録 */ - cdev_init(&dev_info->cdev, &dev_fops[ID_DEV_CNT]); - dev_info->cdev.owner = THIS_MODULE; - - /* このデバイスドライバ(cdev)をカーネルに登録する */ - cdev_err = cdev_add(&dev_info->cdev, dev, NUM_DEV[ID_DEV_CNT]); - if (cdev_err != 0) { - printk(KERN_ERR "cdev_add = %d\n", alloc_ret); - unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); - return -1; - } - -/* このデバイスのクラス登録をする(/sys/class/mydevice/ を作る) */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) - dev_info->device_class = class_create(THIS_MODULE, DEVNAME_CNTL); -#else - dev_info->device_class = class_create(DEVNAME_CNTL); -#endif - - if (IS_ERR(dev_info->device_class)) { - printk(KERN_ERR "class_create\n"); - cdev_del(&dev_info->cdev); - unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); - return -1; - } - - /* /sys/class/mydevice/mydevice* を作る */ - for (minor = DEV_MINOR; minor < DEV_MINOR + NUM_DEV[ID_DEV_CNT]; - minor++) { - - struct device *dev_ret; - dev_ret = device_create(dev_info->device_class, NULL, - MKDEV(dev_info->device_major, minor), - NULL, "rtcounter_l%d", minor); - - /* デバイスファイル作成の可否を判定 */ - if (IS_ERR(dev_ret)) { - /* デバイスファイルの作成に失敗した */ - printk(KERN_ERR "device_create failed minor = %d\n", - minor); - /* リソースリークを避けるために登録された状態cdevを削除する - */ - cdev_del(&(cdev_array[cdev_index])); - return PTR_ERR(dev_ret); - } - } - - return 0; -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0) -static int rtcnt_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct rtcnt_device_info *dev_info; - int msb = 0, lsb = 0; - // printk(KERN_DEBUG "%s: probing i2c device", __func__); - - /* check i2c device */ - // printk(KERN_DEBUG "%s: checking i2c device", __func__); - msb = i2c_smbus_read_byte_data(client, CNT_ADDR_MSB); - lsb = i2c_smbus_read_byte_data(client, CNT_ADDR_LSB); - if ((msb < 0) || (lsb < 0)) { - printk(KERN_INFO - "%s: rtcounter not found, or wrong i2c device probed", - DRIVER_NAME); - // printk(KERN_DEBUG "%s: addr 0x%x, msb %d, lsb %d", __func__, - // client->addr, msb, lsb); - return -ENODEV; - } - printk(KERN_INFO "%s: new i2c device probed, id.name=%s, " - "id.driver_data=%d, addr=0x%x\n", - DRIVER_NAME, id->name, (int)(id->driver_data), client->addr); - - dev_info = (struct rtcnt_device_info *)devm_kzalloc( - &client->dev, sizeof(struct rtcnt_device_info), GFP_KERNEL); - dev_info->client = client; - i2c_set_clientdata(client, dev_info); - mutex_init(&dev_info->lock); - - /* create character device */ - if ((int)(id->driver_data) == 0) { - if (rtcntl_i2c_create_cdev(dev_info)) - return -ENOMEM; - } else if ((int)(id->driver_data) == 1) { - if (rtcntr_i2c_create_cdev(dev_info)) - return -ENOMEM; - } - - return 0; -} -#else -static int rtcnt_i2c_probe(struct i2c_client *client) -{ - const struct i2c_device_id *id = i2c_client_get_device_id(client); - struct rtcnt_device_info *dev_info; - int msb = 0, lsb = 0; - // printk(KERN_DEBUG "%s: probing i2c device", __func__); - - /* check i2c device */ - // printk(KERN_DEBUG "%s: checking i2c device", __func__); - msb = i2c_smbus_read_byte_data(client, CNT_ADDR_MSB); - lsb = i2c_smbus_read_byte_data(client, CNT_ADDR_LSB); - if ((msb < 0) || (lsb < 0)) { - printk(KERN_INFO - "%s: rtcounter not found, or wrong i2c device probed", - DRIVER_NAME); - // printk(KERN_DEBUG "%s: addr 0x%x, msb %d, lsb %d", __func__, - // client->addr, msb, lsb); - return -ENODEV; - } - printk(KERN_INFO "%s: new i2c device probed, id.name=%s, " - "id.driver_data=%d, addr=0x%x\n", - DRIVER_NAME, id->name, (int)(id->driver_data), client->addr); - - dev_info = (struct rtcnt_device_info *)devm_kzalloc( - &client->dev, sizeof(struct rtcnt_device_info), GFP_KERNEL); - dev_info->client = client; - i2c_set_clientdata(client, dev_info); - mutex_init(&dev_info->lock); - - /* create character device */ - if ((int)(id->driver_data) == 0) { - if (rtcntl_i2c_create_cdev(dev_info)) - return -ENOMEM; - } else if ((int)(id->driver_data) == 1) { - if (rtcntr_i2c_create_cdev(dev_info)) - return -ENOMEM; - } - - return 0; -} -#endif - -/* - * i2c_counter_init - initialize I2C counter - * called by dev_init_module() - */ -static int i2c_counter_init(void) -{ - int retval = 0; - struct i2c_adapter *i2c_adap_l; - struct i2c_adapter *i2c_adap_r; - struct i2c_board_info i2c_board_info_l = { - I2C_BOARD_INFO(DEVNAME_CNTL, DEV_ADDR_CNTL)}; - struct i2c_board_info i2c_board_info_r = { - I2C_BOARD_INFO(DEVNAME_CNTR, DEV_ADDR_CNTR)}; - - // printk(KERN_DEBUG "%s: initializing i2c device", __func__); - retval = i2c_add_driver(&i2c_counter_driver); - if (retval != 0) { - printk(KERN_INFO "%s: failed adding i2c device", DRIVER_NAME); - return retval; - } - - /* - * 動的にデバイス実体を作成 - * (https://www.kernel.org/doc/Documentation/i2c/instantiating-devices) - */ -#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 0, 0) - // printk(KERN_DEBUG "%s: adding i2c device", __func__); - i2c_adap_l = i2c_get_adapter(1); - i2c_client_l = i2c_new_device(i2c_adap_l, &i2c_board_info_l); - i2c_put_adapter(i2c_adap_l); - // printk(KERN_DEBUG "%s: added i2c device rtcntl", __func__); - - // printk(KERN_DEBUG "%s: adding i2c device", __func__); - i2c_adap_r = i2c_get_adapter(1); - i2c_client_r = i2c_new_device(i2c_adap_r, &i2c_board_info_r); - i2c_put_adapter(i2c_adap_r); - // printk(KERN_DEBUG "%s: added i2c device rtcntr", __func__); -#else - // printk(KERN_DEBUG "%s: adding i2c device", __func__); - i2c_adap_l = i2c_get_adapter(1); - i2c_client_l = i2c_new_client_device(i2c_adap_l, &i2c_board_info_l); - i2c_put_adapter(i2c_adap_l); - // printk(KERN_DEBUG "%s: added i2c device rtcntl", __func__); - - // printk(KERN_DEBUG "%s: adding i2c device", __func__); - i2c_adap_r = i2c_get_adapter(1); - i2c_client_r = i2c_new_client_device(i2c_adap_r, &i2c_board_info_r); - i2c_put_adapter(i2c_adap_r); - // printk(KERN_DEBUG "%s: added i2c device rtcntr", __func__); -#endif - - return retval; -} - -/* - * i2c_counter_exit - cleanup I2C device - * called by dev_cleanup_module() - */ -static void i2c_counter_exit(void) -{ - /* delete I2C driver */ - i2c_del_driver(&i2c_counter_driver); - /* free memory */ - if (i2c_client_r) - i2c_unregister_device(i2c_client_r); - if (i2c_client_l) - i2c_unregister_device(i2c_client_l); -} - -static void rtcnt_i2c_delete_cdev(struct rtcnt_device_info *dev_info) -{ - dev_t dev = MKDEV(dev_info->device_major, DEV_MINOR); - int minor; - /* /sys/class/mydevice/mydevice* を削除する */ - for (minor = DEV_MINOR; minor < DEV_MINOR + NUM_DEV[ID_DEV_CNT]; - minor++) { - device_destroy(dev_info->device_class, - MKDEV(dev_info->device_major, minor)); - } - /* このデバイスのクラス登録を取り除く(/sys/class/mydevice/を削除する) */ - class_destroy(dev_info->device_class); - /* このデバイスドライバ(cdev)をカーネルから取り除く */ - cdev_del(&dev_info->cdev); - /* このデバイスドライバで使用していたメジャー番号の登録を取り除く */ - unregister_chrdev_region(dev, NUM_DEV[ID_DEV_CNT]); -} - -/* - * i2c_counter_remove - I2C pulse counter - * called when I2C pulse counter removed - */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0) -static int rtcnt_i2c_remove(struct i2c_client *client) -{ - struct rtcnt_device_info *dev_info; - // printk(KERN_DEBUG "%s: removing i2c device 0x%x\n", __func__, - // client->addr); - dev_info = i2c_get_clientdata(client); - rtcnt_i2c_delete_cdev(dev_info); - printk(KERN_INFO "%s: i2c device 0x%x removed\n", DRIVER_NAME, - client->addr); - return 0; -} -#else -static void rtcnt_i2c_remove(struct i2c_client *client) -{ - struct rtcnt_device_info *dev_info; - // printk(KERN_DEBUG "%s: removing i2c device 0x%x\n", __func__, - // client->addr); - dev_info = i2c_get_clientdata(client); - rtcnt_i2c_delete_cdev(dev_info); - printk(KERN_INFO "%s: i2c device 0x%x removed\n", DRIVER_NAME, - client->addr); -} -#endif - /* * dev_init_module - register driver module * called by module_init(dev_init_module) From b175fbc3ddb59ea3ad9401753e777ddd35e24c62 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 16:47:10 +0900 Subject: [PATCH 20/26] =?UTF-8?q?register=5Fdev()=E3=82=92rtmouse=5Fdev=5F?= =?UTF-8?q?fops.c=E3=81=B8=E7=A7=BB=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse.h | 18 +++-- src/drivers/rtmouse_dev_fops.c | 87 +++++++++++++++++++++++++ src/drivers/rtmouse_main.c | 116 ++++++--------------------------- 3 files changed, 119 insertions(+), 102 deletions(-) diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index 356e527..29e6e1d 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -253,6 +253,11 @@ struct rtcnt_device_info { }; /* --- used in rtmouse_dev_fops.c --- */ +extern const char *NAME_DEV[ID_DEV_SIZE]; +extern const char *NAME_DEV_U[ID_DEV_SIZE]; +extern int _major_dev[ID_DEV_SIZE]; +extern int _minor_dev[ID_DEV_SIZE]; +extern struct class *class_dev[ID_DEV_SIZE]; extern volatile void __iomem *pwm_base; extern volatile uint32_t *gpio_base; extern struct mutex lock; @@ -261,11 +266,8 @@ extern struct file_operations dev_fops[ID_DEV_SIZE]; #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) extern struct device *mcp320x_dev; #endif - -int rpi_gpio_function_set(int pin, uint32_t func); -void rpi_gpio_set32(uint32_t mask, uint32_t val); -void rpi_gpio_clear32(uint32_t mask, uint32_t val); -void rpi_pwm_write32(uint32_t offset, uint32_t val); +int buzzer_init(void); +int register_dev(int id_dev); /* --- used in rtmouse_spi.c --- */ int mcp3204_init(void); @@ -278,4 +280,10 @@ extern volatile int cdev_index; int i2c_counter_init(void); void i2c_counter_exit(void); +/* --- used in rtmouse_gpio.c --- */ +int rpi_gpio_function_set(int pin, uint32_t func); +void rpi_gpio_set32(uint32_t mask, uint32_t val); +void rpi_gpio_clear32(uint32_t mask, uint32_t val); +void rpi_pwm_write32(uint32_t offset, uint32_t val); + #endif // RTMOUSE_H diff --git a/src/drivers/rtmouse_dev_fops.c b/src/drivers/rtmouse_dev_fops.c index cf3e874..cbb5bdd 100644 --- a/src/drivers/rtmouse_dev_fops.c +++ b/src/drivers/rtmouse_dev_fops.c @@ -704,6 +704,24 @@ static ssize_t buzzer_write(struct file *filep, const char __user *buf, return count; } +/* + * Initialize buzzer + * return 0 : device close + */ +int buzzer_init(void) +{ + + rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); // io is pwm out + rpi_pwm_write32(RPI_PWM_CTRL, 0x00000000); + udelay(1000); + rpi_pwm_write32(RPI_PWM_CTRL, 0x00008181); // PWM1,2 enable + + // printk(KERN_DEBUG "%s: rpi_pwm_ctrl:%08X\n", DRIVER_NAME, + // ioread32(pwm_base + RPI_PWM_CTRL)); + + return 0; +} + /* * rawmotor_l_write - Output frequency to the left motor * Write function of /dev/rtmotor_raw_l @@ -820,3 +838,72 @@ struct file_operations dev_fops[ID_DEV_SIZE] = { [ID_DEV_CNT].release = i2c_dev_release, [ID_DEV_CNT].read = rtcnt_read, [ID_DEV_CNT].write = rtcnt_write}; + +/* --- Device Driver Registration and Device File Creation --- */ +int register_dev(int id_dev) +{ + int retval; + dev_t dev; + dev_t devno; + int i; + + /* 空いているメジャー番号を使ってメジャー& + マイナー番号をカーネルに登録する */ + retval = + alloc_chrdev_region(&dev, /* 結果を格納するdev_t構造体 */ + DEV_MINOR, /* ベースマイナー番号 */ + NUM_DEV[id_dev], /* デバイスの数 */ + NAME_DEV[id_dev] /* デバイスドライバの名前 */ + ); + + if (retval < 0) { + printk(KERN_ERR "alloc_chrdev_region failed.\n"); + return retval; + } + _major_dev[id_dev] = MAJOR(dev); + + /* デバイスクラスを作成する */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) + class_dev[id_dev] = class_create(THIS_MODULE, NAME_DEV[id_dev]); +#else + class_dev[id_dev] = class_create(NAME_DEV[id_dev]); +#endif + + if (IS_ERR(class_dev[id_dev])) { + return PTR_ERR(class_dev[id_dev]); + } + + for (i = 0; i < NUM_DEV[id_dev]; i++) { + /* デバイスの数だけキャラクタデバイスを登録する */ + devno = MKDEV(_major_dev[id_dev], _minor_dev[id_dev] + i); + + /* キャラクタデバイスとしてこのモジュールをカーネルに登録する */ + cdev_init(&(cdev_array[cdev_index]), &dev_fops[id_dev]); + cdev_array[cdev_index].owner = THIS_MODULE; + if (cdev_add(&(cdev_array[cdev_index]), devno, 1) < 0) { + /* 登録に失敗した */ + printk(KERN_ERR "cdev_add failed minor = %d\n", + _minor_dev[id_dev] + i); + } else { + /* デバイスノードの作成 */ + struct device *dev_ret; + dev_ret = device_create(class_dev[id_dev], NULL, devno, + NULL, NAME_DEV_U[id_dev], + _minor_dev[id_dev] + i); + + /* デバイスファイル作成の可否を判定 */ + if (IS_ERR(dev_ret)) { + /* デバイスファイルの作成に失敗した */ + printk(KERN_ERR + "device_create failed minor = %d\n", + _minor_dev[id_dev] + i); + /* リソースリークを避けるために登録された状態cdevを削除する + */ + cdev_del(&(cdev_array[cdev_index])); + return PTR_ERR(dev_ret); + } + } + cdev_index++; + } + return 0; +} diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 08201c5..6392ad5 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -38,8 +38,11 @@ const unsigned int NUM_DEV[ID_DEV_SIZE] = { [ID_DEV_BUZZER] = 1, [ID_DEV_MOTORRAWR] = 1, [ID_DEV_MOTORRAWL] = 1, [ID_DEV_MOTOREN] = 1, [ID_DEV_MOTOR] = 1, [ID_DEV_CNT] = 2}; -/* --- Device Names --- */ -static const char *NAME_DEV[ID_DEV_SIZE] = { +/* + * --- Device Names --- + * used in rtmouse_dev.c + */ +const char *NAME_DEV[ID_DEV_SIZE] = { [ID_DEV_LED] = "rtled", [ID_DEV_SWITCH] = "rtswitch", [ID_DEV_SENSOR] = "rtlightsensor", @@ -49,8 +52,11 @@ static const char *NAME_DEV[ID_DEV_SIZE] = { [ID_DEV_MOTOREN] = "rtmotoren", [ID_DEV_MOTOR] = "rtmotor"}; -/* --- Device Names(+%u) --- */ -static const char *NAME_DEV_U[ID_DEV_SIZE] = { +/* + * --- Device Names(+%u) --- + * used in rtmouse_dev.c + */ +const char *NAME_DEV_U[ID_DEV_SIZE] = { [ID_DEV_LED] = "rtled%u", [ID_DEV_SWITCH] = "rtswitch%u", [ID_DEV_SENSOR] = "rtlightsensor%u", @@ -60,22 +66,25 @@ static const char *NAME_DEV_U[ID_DEV_SIZE] = { [ID_DEV_MOTOREN] = "rtmotoren%u", [ID_DEV_MOTOR] = "rtmotor%u"}; -// used in by register_dev() and cleanup_each_dev() -static int _major_dev[ID_DEV_SIZE] = { +// used in by rtmouse_dev.c and cleanup_each_dev() +int _major_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = DEV_MAJOR, [ID_DEV_SWITCH] = DEV_MAJOR, [ID_DEV_SENSOR] = DEV_MAJOR, [ID_DEV_BUZZER] = DEV_MAJOR, [ID_DEV_MOTORRAWR] = DEV_MAJOR, [ID_DEV_MOTORRAWL] = DEV_MAJOR, [ID_DEV_MOTOREN] = DEV_MAJOR, [ID_DEV_MOTOR] = DEV_MAJOR}; -// used in register_dev() and cleanup_each_dev() -static int _minor_dev[ID_DEV_SIZE] = { +// used in rtmouse_dev.c and cleanup_each_dev() +int _minor_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = DEV_MINOR, [ID_DEV_SWITCH] = DEV_MINOR, [ID_DEV_SENSOR] = DEV_MINOR, [ID_DEV_BUZZER] = DEV_MINOR, [ID_DEV_MOTORRAWR] = DEV_MINOR, [ID_DEV_MOTORRAWL] = DEV_MINOR, [ID_DEV_MOTOREN] = DEV_MINOR, [ID_DEV_MOTOR] = DEV_MINOR}; -/* --- General Options --- */ -static struct class *class_dev[ID_DEV_SIZE] = { +/* + * --- General Options --- + * used in rtmouse_dev.c + */ +struct class *class_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = NULL, [ID_DEV_SWITCH] = NULL, [ID_DEV_SENSOR] = NULL, [ID_DEV_BUZZER] = NULL, [ID_DEV_MOTORRAWR] = NULL, [ID_DEV_MOTORRAWL] = NULL, @@ -144,24 +153,6 @@ void rpi_pwm_write32(uint32_t offset, uint32_t val) iowrite32(val, pwm_base + offset); } -/* - * Initialize buzzer - * return 0 : device close - */ -static int buzzer_init(void) -{ - - rpi_gpio_function_set(BUZZER_BASE, RPI_GPF_OUTPUT); // io is pwm out - rpi_pwm_write32(RPI_PWM_CTRL, 0x00000000); - udelay(1000); - rpi_pwm_write32(RPI_PWM_CTRL, 0x00008181); // PWM1,2 enable - - // printk(KERN_DEBUG "%s: rpi_pwm_ctrl:%08X\n", DRIVER_NAME, - // ioread32(pwm_base + RPI_PWM_CTRL)); - - return 0; -} - /* --- GPIO mapping for Device Open/Close --- */ /* * Get gpio addresses and set them to global variables. @@ -230,75 +221,6 @@ static int gpio_unmap(void) return 0; } -/* --- Device Driver Registration and Device File Creation --- */ -static int register_dev(int id_dev) -{ - int retval; - dev_t dev; - dev_t devno; - int i; - - /* 空いているメジャー番号を使ってメジャー& - マイナー番号をカーネルに登録する */ - retval = - alloc_chrdev_region(&dev, /* 結果を格納するdev_t構造体 */ - DEV_MINOR, /* ベースマイナー番号 */ - NUM_DEV[id_dev], /* デバイスの数 */ - NAME_DEV[id_dev] /* デバイスドライバの名前 */ - ); - - if (retval < 0) { - printk(KERN_ERR "alloc_chrdev_region failed.\n"); - return retval; - } - _major_dev[id_dev] = MAJOR(dev); - - /* デバイスクラスを作成する */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) - class_dev[id_dev] = class_create(THIS_MODULE, NAME_DEV[id_dev]); -#else - class_dev[id_dev] = class_create(NAME_DEV[id_dev]); -#endif - - if (IS_ERR(class_dev[id_dev])) { - return PTR_ERR(class_dev[id_dev]); - } - - for (i = 0; i < NUM_DEV[id_dev]; i++) { - /* デバイスの数だけキャラクタデバイスを登録する */ - devno = MKDEV(_major_dev[id_dev], _minor_dev[id_dev] + i); - - /* キャラクタデバイスとしてこのモジュールをカーネルに登録する */ - cdev_init(&(cdev_array[cdev_index]), &dev_fops[id_dev]); - cdev_array[cdev_index].owner = THIS_MODULE; - if (cdev_add(&(cdev_array[cdev_index]), devno, 1) < 0) { - /* 登録に失敗した */ - printk(KERN_ERR "cdev_add failed minor = %d\n", - _minor_dev[id_dev] + i); - } else { - /* デバイスノードの作成 */ - struct device *dev_ret; - dev_ret = device_create(class_dev[id_dev], NULL, devno, - NULL, NAME_DEV_U[id_dev], - _minor_dev[id_dev] + i); - - /* デバイスファイル作成の可否を判定 */ - if (IS_ERR(dev_ret)) { - /* デバイスファイルの作成に失敗した */ - printk(KERN_ERR - "device_create failed minor = %d\n", - _minor_dev[id_dev] + i); - /* リソースリークを避けるために登録された状態cdevを削除する - */ - cdev_del(&(cdev_array[cdev_index])); - return PTR_ERR(dev_ret); - } - } - cdev_index++; - } - return 0; -} - /* * dev_init_module - register driver module * called by module_init(dev_init_module) From 77bb4770fa223a9eeba7fbd8c03f5a66d638a30c Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 16:49:19 +0900 Subject: [PATCH 21/26] =?UTF-8?q?rtmouse=5Fdev=5Ffops.c=E3=82=92rtmouse=5F?= =?UTF-8?q?dev.c=E3=81=B8=E5=90=8D=E7=A7=B0=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/Makefile.header_from_apt | 4 ++-- src/drivers/Makefile.header_from_source | 4 ++-- src/drivers/{rtmouse_dev_fops.c => rtmouse_dev.c} | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/drivers/{rtmouse_dev_fops.c => rtmouse_dev.c} (99%) diff --git a/src/drivers/Makefile.header_from_apt b/src/drivers/Makefile.header_from_apt index bb31919..436f571 100644 --- a/src/drivers/Makefile.header_from_apt +++ b/src/drivers/Makefile.header_from_apt @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o $(MODULE)_spi.o $(MODULE)_i2c.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o $(MODULE)_spi.o $(MODULE)_i2c.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux-headers-$(shell uname -r) VERBOSE:=0 -$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev_fops.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE).h +$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/Makefile.header_from_source b/src/drivers/Makefile.header_from_source index 8244f9a..f5d3398 100644 --- a/src/drivers/Makefile.header_from_source +++ b/src/drivers/Makefile.header_from_source @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev_fops.o $(MODULE)_spi.o $(MODULE)_i2c.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o $(MODULE)_spi.o $(MODULE)_i2c.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux VERBOSE:=0 -$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev_fops.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE).h +$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/rtmouse_dev_fops.c b/src/drivers/rtmouse_dev.c similarity index 99% rename from src/drivers/rtmouse_dev_fops.c rename to src/drivers/rtmouse_dev.c index cbb5bdd..8436b32 100644 --- a/src/drivers/rtmouse_dev_fops.c +++ b/src/drivers/rtmouse_dev.c @@ -1,7 +1,7 @@ /* * - * rtmouse_dev_fops.c - * Define device file operations + * rtmouse_dev.c + * Define device file operations and register device * * Copyright (C) 2024 RT Corporation * From a556d624fc052f5a7f056ac7f6697611ee1c6a2b Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 16:51:40 +0900 Subject: [PATCH 22/26] =?UTF-8?q?lint=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=97?= =?UTF-8?q?=E3=81=A6=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse_main.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 6392ad5..4f2bf16 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -42,29 +42,27 @@ const unsigned int NUM_DEV[ID_DEV_SIZE] = { * --- Device Names --- * used in rtmouse_dev.c */ -const char *NAME_DEV[ID_DEV_SIZE] = { - [ID_DEV_LED] = "rtled", - [ID_DEV_SWITCH] = "rtswitch", - [ID_DEV_SENSOR] = "rtlightsensor", - [ID_DEV_BUZZER] = "rtbuzzer", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l", - [ID_DEV_MOTOREN] = "rtmotoren", - [ID_DEV_MOTOR] = "rtmotor"}; +const char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", + [ID_DEV_SWITCH] = "rtswitch", + [ID_DEV_SENSOR] = "rtlightsensor", + [ID_DEV_BUZZER] = "rtbuzzer", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l", + [ID_DEV_MOTOREN] = "rtmotoren", + [ID_DEV_MOTOR] = "rtmotor"}; /* * --- Device Names(+%u) --- * used in rtmouse_dev.c */ -const char *NAME_DEV_U[ID_DEV_SIZE] = { - [ID_DEV_LED] = "rtled%u", - [ID_DEV_SWITCH] = "rtswitch%u", - [ID_DEV_SENSOR] = "rtlightsensor%u", - [ID_DEV_BUZZER] = "rtbuzzer%u", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", - [ID_DEV_MOTOREN] = "rtmotoren%u", - [ID_DEV_MOTOR] = "rtmotor%u"}; +const char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", + [ID_DEV_SWITCH] = "rtswitch%u", + [ID_DEV_SENSOR] = "rtlightsensor%u", + [ID_DEV_BUZZER] = "rtbuzzer%u", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", + [ID_DEV_MOTOREN] = "rtmotoren%u", + [ID_DEV_MOTOR] = "rtmotor%u"}; // used in by rtmouse_dev.c and cleanup_each_dev() int _major_dev[ID_DEV_SIZE] = { From 0cc93d9eb7da572895a7a18c3b903a080f3c9a77 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 16:56:19 +0900 Subject: [PATCH 23/26] =?UTF-8?q?lint=E5=AF=BE=E8=B1=A1=E3=81=AE=E3=83=95?= =?UTF-8?q?=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .test/lint.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.test/lint.sh b/.test/lint.sh index 12c6180..ff7a1c6 100755 --- a/.test/lint.sh +++ b/.test/lint.sh @@ -7,7 +7,9 @@ SRC_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); cd ../; pwd) lint_driver () { pushd $SRC_DIR/src/drivers python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_main.c - python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_dev_fops.c + python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_dev.c + python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_spi.c + python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_i2c.c python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse.h popd } From 6e95fbf1217ef2872a537ea5aa8e9ad3abf7959c Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 17:24:40 +0900 Subject: [PATCH 24/26] =?UTF-8?q?rtmouse=5Fgpio.c=E3=82=92=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=81=97=E3=81=A6GPIO=E9=96=A2=E9=80=A3=E3=81=AE?= =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=82=92=E7=A7=BB=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/Makefile.header_from_apt | 4 +- src/drivers/Makefile.header_from_source | 4 +- src/drivers/rtmouse.h | 2 + src/drivers/rtmouse_gpio.c | 139 ++++++++++++++++++++++++ src/drivers/rtmouse_i2c.c | 2 +- src/drivers/rtmouse_main.c | 120 +------------------- src/drivers/rtmouse_spi.c | 2 +- 7 files changed, 149 insertions(+), 124 deletions(-) create mode 100644 src/drivers/rtmouse_gpio.c diff --git a/src/drivers/Makefile.header_from_apt b/src/drivers/Makefile.header_from_apt index 436f571..e471aa1 100644 --- a/src/drivers/Makefile.header_from_apt +++ b/src/drivers/Makefile.header_from_apt @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o $(MODULE)_spi.o $(MODULE)_i2c.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o $(MODULE)_spi.o $(MODULE)_i2c.o $(MODULE)_gpio.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux-headers-$(shell uname -r) VERBOSE:=0 -$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE).h +$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE)_gpio.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/Makefile.header_from_source b/src/drivers/Makefile.header_from_source index f5d3398..75798f1 100644 --- a/src/drivers/Makefile.header_from_source +++ b/src/drivers/Makefile.header_from_source @@ -1,12 +1,12 @@ MODULE:= rtmouse obj-m:= $(MODULE).o -$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o $(MODULE)_spi.o $(MODULE)_i2c.o +$(MODULE)-y:= $(MODULE)_main.o $(MODULE)_dev.o $(MODULE)_spi.o $(MODULE)_i2c.o $(MODULE)_gpio.o clean-files:= *.o *.ko *.mod.[co] *~ LINUX_SRC_DIR:=/usr/src/linux VERBOSE:=0 -$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE).h +$(MODULE).ko: $(MODULE)_main.c $(MODULE)_dev.c $(MODULE)_spi.c $(MODULE)_i2c.c $(MODULE)_gpio.c $(MODULE).h make -C $(LINUX_SRC_DIR) M=$(shell pwd) V=$(VERBOSE) modules clean: diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index 29e6e1d..954adce 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -285,5 +285,7 @@ int rpi_gpio_function_set(int pin, uint32_t func); void rpi_gpio_set32(uint32_t mask, uint32_t val); void rpi_gpio_clear32(uint32_t mask, uint32_t val); void rpi_pwm_write32(uint32_t offset, uint32_t val); +int gpio_map(void); +int gpio_unmap(void); #endif // RTMOUSE_H diff --git a/src/drivers/rtmouse_gpio.c b/src/drivers/rtmouse_gpio.c new file mode 100644 index 0000000..a6446e1 --- /dev/null +++ b/src/drivers/rtmouse_gpio.c @@ -0,0 +1,139 @@ +/* + * + * rtmouse_gpio.c + * GPIO driver + * + * Copyright (C) 2024 RT Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "rtmouse.h" + +static volatile void __iomem *clk_base; + +/* + * set function + * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() and + * buzzer_write() + */ +int rpi_gpio_function_set(int pin, uint32_t func) +{ + int index = RPI_GPFSEL0_INDEX + pin / 10; + uint32_t mask = ~(0x7 << ((pin % 10) * 3)); + + gpio_base[index] = + (gpio_base[index] & mask) | ((func & 0x7) << ((pin % 10) * 3)); + + return 1; +} + +/* + * set mask and value + * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_put() + * and motoren_write() + */ +void rpi_gpio_set32(uint32_t mask, uint32_t val) +{ + gpio_base[RPI_GPSET0_INDEX] = val & mask; +} + +/* + * clear mask and value + * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_del() + * and motoren_write() + */ +void rpi_gpio_clear32(uint32_t mask, uint32_t val) +{ + gpio_base[RPI_GPCLR0_INDEX] = val & mask; +} + +/* + * pwm set function + * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() + * and buzzer_write() + */ +void rpi_pwm_write32(uint32_t offset, uint32_t val) +{ + iowrite32(val, pwm_base + offset); +} + +/* --- GPIO mapping for Device Open/Close --- */ +/* + * Get gpio addresses and set them to global variables. + * - gpio_base + * - pwm_base + * - clk_base + * - clk_status + */ +int gpio_map(void) +{ + static int clk_status = 1; + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 0, 0) + if (gpio_base == NULL) { + gpio_base = ioremap_nocache(RPI_GPIO_BASE, RPI_GPIO_SIZE); + } + + if (pwm_base == NULL) { + pwm_base = ioremap_nocache(RPI_PWM_BASE, RPI_PWM_SIZE); + } + + if (clk_base == NULL) { + clk_base = ioremap_nocache(RPI_CLK_BASE, RPI_CLK_SIZE); + } +#else + if (gpio_base == NULL) { + gpio_base = ioremap(RPI_GPIO_BASE, RPI_GPIO_SIZE); + } + + if (pwm_base == NULL) { + pwm_base = ioremap(RPI_PWM_BASE, RPI_PWM_SIZE); + } + + if (clk_base == NULL) { + clk_base = ioremap(RPI_CLK_BASE, RPI_CLK_SIZE); + } +#endif + + /* kill */ + if (clk_status == 1) { + iowrite32(0x5a000000 | (1 << 5), clk_base + CLK_PWM_INDEX); + udelay(1000); + + /* clk set */ + iowrite32(0x5a000000 | (2 << 12), clk_base + CLK_PWMDIV_INDEX); + iowrite32(0x5a000011, clk_base + CLK_PWM_INDEX); + + udelay(1000); /* wait for 1msec */ + + clk_status = 0; + } + + return 0; +} + +/* Unmap GPIO addresses */ +int gpio_unmap(void) +{ + iounmap(gpio_base); + iounmap(pwm_base); + iounmap(clk_base); + + gpio_base = NULL; + pwm_base = NULL; + clk_base = NULL; + return 0; +} diff --git a/src/drivers/rtmouse_i2c.c b/src/drivers/rtmouse_i2c.c index 25c181f..a63acee 100644 --- a/src/drivers/rtmouse_i2c.c +++ b/src/drivers/rtmouse_i2c.c @@ -1,7 +1,7 @@ /* * * rtmouse_i2c.c - * I2C Driver + * I2C driver * * Copyright (C) 2024 RT Corporation * diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index 4f2bf16..fb9e1ef 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -88,137 +88,21 @@ struct class *class_dev[ID_DEV_SIZE] = { [ID_DEV_MOTORRAWR] = NULL, [ID_DEV_MOTORRAWL] = NULL, [ID_DEV_MOTOREN] = NULL, [ID_DEV_MOTOR] = NULL}; -static volatile void __iomem *clk_base; - // used in rtmouse_i2c.c struct cdev *cdev_array = NULL; volatile int cdev_index = 0; -// used in rtmouse_dev_fops.c +// used in rtmouse_dev.c volatile void __iomem *pwm_base; volatile uint32_t *gpio_base; struct mutex lock; /* --- Static variables --- */ -// used in rtmouse_dev_fops.c +// used in rtmouse_dev.c and rtmouse_spi.c #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 16, 0) struct device *mcp320x_dev; #endif -/* - * set function - * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() and - * buzzer_write() - */ -int rpi_gpio_function_set(int pin, uint32_t func) -{ - int index = RPI_GPFSEL0_INDEX + pin / 10; - uint32_t mask = ~(0x7 << ((pin % 10) * 3)); - - gpio_base[index] = - (gpio_base[index] & mask) | ((func & 0x7) << ((pin % 10) * 3)); - - return 1; -} - -/* - * set mask and value - * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_put() - * and motoren_write() - */ -void rpi_gpio_set32(uint32_t mask, uint32_t val) -{ - gpio_base[RPI_GPSET0_INDEX] = val & mask; -} - -/* - * clear mask and value - * called by sensor_read(), set_motor_l_freq(), set_motor_r_freq(), led_del() - * and motoren_write() - */ -void rpi_gpio_clear32(uint32_t mask, uint32_t val) -{ - gpio_base[RPI_GPCLR0_INDEX] = val & mask; -} - -/* - * pwm set function - * called by buzzer_init(), set_motor_l_freq(), set_motor_r_freq() - * and buzzer_write() - */ -void rpi_pwm_write32(uint32_t offset, uint32_t val) -{ - iowrite32(val, pwm_base + offset); -} - -/* --- GPIO mapping for Device Open/Close --- */ -/* - * Get gpio addresses and set them to global variables. - * - gpio_base - * - pwm_base - * - clk_base - * - clk_status - */ -static int gpio_map(void) -{ - static int clk_status = 1; - -#if LINUX_VERSION_CODE <= KERNEL_VERSION(5, 0, 0) - if (gpio_base == NULL) { - gpio_base = ioremap_nocache(RPI_GPIO_BASE, RPI_GPIO_SIZE); - } - - if (pwm_base == NULL) { - pwm_base = ioremap_nocache(RPI_PWM_BASE, RPI_PWM_SIZE); - } - - if (clk_base == NULL) { - clk_base = ioremap_nocache(RPI_CLK_BASE, RPI_CLK_SIZE); - } -#else - if (gpio_base == NULL) { - gpio_base = ioremap(RPI_GPIO_BASE, RPI_GPIO_SIZE); - } - - if (pwm_base == NULL) { - pwm_base = ioremap(RPI_PWM_BASE, RPI_PWM_SIZE); - } - - if (clk_base == NULL) { - clk_base = ioremap(RPI_CLK_BASE, RPI_CLK_SIZE); - } -#endif - - /* kill */ - if (clk_status == 1) { - iowrite32(0x5a000000 | (1 << 5), clk_base + CLK_PWM_INDEX); - udelay(1000); - - /* clk set */ - iowrite32(0x5a000000 | (2 << 12), clk_base + CLK_PWMDIV_INDEX); - iowrite32(0x5a000011, clk_base + CLK_PWM_INDEX); - - udelay(1000); /* wait for 1msec */ - - clk_status = 0; - } - - return 0; -} - -/* Unmap GPIO addresses */ -static int gpio_unmap(void) -{ - iounmap(gpio_base); - iounmap(pwm_base); - iounmap(clk_base); - - gpio_base = NULL; - pwm_base = NULL; - clk_base = NULL; - return 0; -} - /* * dev_init_module - register driver module * called by module_init(dev_init_module) diff --git a/src/drivers/rtmouse_spi.c b/src/drivers/rtmouse_spi.c index 8d6a134..e5f8db2 100644 --- a/src/drivers/rtmouse_spi.c +++ b/src/drivers/rtmouse_spi.c @@ -1,7 +1,7 @@ /* * * rtmouse_spi.c - * SPI Driver + * SPI driver * * Copyright (C) 2024 RT Corporation * From 2b5007062be44e14fdd44ca00dcbd2d24c517841 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 18:09:56 +0900 Subject: [PATCH 25/26] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=81=AA=E3=81=A9=E5=BE=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .test/lint.sh | 1 + src/drivers/rtmouse.h | 5 ++--- src/drivers/rtmouse_dev.c | 13 +++++++++++++ src/drivers/rtmouse_main.c | 28 ++++++++++------------------ 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/.test/lint.sh b/.test/lint.sh index ff7a1c6..71f334b 100755 --- a/.test/lint.sh +++ b/.test/lint.sh @@ -10,6 +10,7 @@ lint_driver () { python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_dev.c python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_spi.c python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_i2c.c + python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse_gpio.c python3 $SRC_DIR/.test/bin/run-clang-format.py rtmouse.h popd } diff --git a/src/drivers/rtmouse.h b/src/drivers/rtmouse.h index 954adce..a11c390 100644 --- a/src/drivers/rtmouse.h +++ b/src/drivers/rtmouse.h @@ -52,7 +52,7 @@ // Raspberry Pi 2 B : 2 // Raspberry Pi 3 B/A+/B+ : 2 // Raspberry Pi 4 B : 4 -#define RASPBERRYPI 4 +#define RASPBERRYPI 2 /* --- Device ID --- */ #define ID_DEV_LED 0 @@ -252,9 +252,8 @@ struct rtcnt_device_info { int raw_pulse_count; }; -/* --- used in rtmouse_dev_fops.c --- */ +/* --- used in rtmouse_dev.c --- */ extern const char *NAME_DEV[ID_DEV_SIZE]; -extern const char *NAME_DEV_U[ID_DEV_SIZE]; extern int _major_dev[ID_DEV_SIZE]; extern int _minor_dev[ID_DEV_SIZE]; extern struct class *class_dev[ID_DEV_SIZE]; diff --git a/src/drivers/rtmouse_dev.c b/src/drivers/rtmouse_dev.c index 8436b32..11fdde4 100644 --- a/src/drivers/rtmouse_dev.c +++ b/src/drivers/rtmouse_dev.c @@ -25,6 +25,19 @@ static unsigned int motor_l_freq_is_positive = 1; static unsigned int motor_r_freq_is_positive = 1; +/* + * --- Device Names(+%u) --- + * used in register_dev() + */ +static const char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", + [ID_DEV_SWITCH] = "rtswitch%u", + [ID_DEV_SENSOR] = "rtlightsensor%u", + [ID_DEV_BUZZER] = "rtbuzzer%u", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", + [ID_DEV_MOTOREN] = "rtmotoren%u", + [ID_DEV_MOTOR] = "rtmotor%u"}; + /* * i2c_counter_set - set value to I2C pulse counter * called by rtcnt_write() diff --git a/src/drivers/rtmouse_main.c b/src/drivers/rtmouse_main.c index fb9e1ef..df071f5 100644 --- a/src/drivers/rtmouse_main.c +++ b/src/drivers/rtmouse_main.c @@ -31,7 +31,8 @@ MODULE_DESCRIPTION("Raspberry Pi Mouse device driver"); /* * --- Device Numbers --- - * used in rtmouse_i2c.c + * used in rtmouse_i2c.c, dev_init_module() + * and cleanup_each_dev() */ const unsigned int NUM_DEV[ID_DEV_SIZE] = { [ID_DEV_LED] = 4, [ID_DEV_SWITCH] = 3, [ID_DEV_SENSOR] = 1, @@ -40,7 +41,7 @@ const unsigned int NUM_DEV[ID_DEV_SIZE] = { /* * --- Device Names --- - * used in rtmouse_dev.c + * used in rtmouse_dev.c and dev_init_module() */ const char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", [ID_DEV_SWITCH] = "rtswitch", @@ -51,19 +52,6 @@ const char *NAME_DEV[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled", [ID_DEV_MOTOREN] = "rtmotoren", [ID_DEV_MOTOR] = "rtmotor"}; -/* - * --- Device Names(+%u) --- - * used in rtmouse_dev.c - */ -const char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", - [ID_DEV_SWITCH] = "rtswitch%u", - [ID_DEV_SENSOR] = "rtlightsensor%u", - [ID_DEV_BUZZER] = "rtbuzzer%u", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", - [ID_DEV_MOTOREN] = "rtmotoren%u", - [ID_DEV_MOTOR] = "rtmotor%u"}; - // used in by rtmouse_dev.c and cleanup_each_dev() int _major_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = DEV_MAJOR, [ID_DEV_SWITCH] = DEV_MAJOR, @@ -80,7 +68,7 @@ int _minor_dev[ID_DEV_SIZE] = { /* * --- General Options --- - * used in rtmouse_dev.c + * used in rtmouse_dev.c and dev_cleanup_module() */ struct class *class_dev[ID_DEV_SIZE] = { [ID_DEV_LED] = NULL, [ID_DEV_SWITCH] = NULL, @@ -88,13 +76,17 @@ struct class *class_dev[ID_DEV_SIZE] = { [ID_DEV_MOTORRAWR] = NULL, [ID_DEV_MOTORRAWL] = NULL, [ID_DEV_MOTOREN] = NULL, [ID_DEV_MOTOR] = NULL}; -// used in rtmouse_i2c.c +// used in rtmouse_i2c.c and dev_cleanup_module() struct cdev *cdev_array = NULL; + +// used in rtmouse_i2c.c volatile int cdev_index = 0; -// used in rtmouse_dev.c +// used in rtmouse_dev.c and rtmouse_gpio.c volatile void __iomem *pwm_base; volatile uint32_t *gpio_base; + +// used in rtmouse_dev.c, rtmouse_i2c.c and rtmouse_spi.c struct mutex lock; /* --- Static variables --- */ From b3c3c793b37b3ab2d01b1f9117d1e1e7e30d0951 Mon Sep 17 00:00:00 2001 From: YusukeKato Date: Thu, 7 Nov 2024 18:13:20 +0900 Subject: [PATCH 26/26] =?UTF-8?q?lint=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=97?= =?UTF-8?q?=E3=81=A6=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/drivers/rtmouse_dev.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/drivers/rtmouse_dev.c b/src/drivers/rtmouse_dev.c index 11fdde4..d124d64 100644 --- a/src/drivers/rtmouse_dev.c +++ b/src/drivers/rtmouse_dev.c @@ -29,14 +29,15 @@ static unsigned int motor_r_freq_is_positive = 1; * --- Device Names(+%u) --- * used in register_dev() */ -static const char *NAME_DEV_U[ID_DEV_SIZE] = {[ID_DEV_LED] = "rtled%u", - [ID_DEV_SWITCH] = "rtswitch%u", - [ID_DEV_SENSOR] = "rtlightsensor%u", - [ID_DEV_BUZZER] = "rtbuzzer%u", - [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", - [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", - [ID_DEV_MOTOREN] = "rtmotoren%u", - [ID_DEV_MOTOR] = "rtmotor%u"}; +static const char *NAME_DEV_U[ID_DEV_SIZE] = { + [ID_DEV_LED] = "rtled%u", + [ID_DEV_SWITCH] = "rtswitch%u", + [ID_DEV_SENSOR] = "rtlightsensor%u", + [ID_DEV_BUZZER] = "rtbuzzer%u", + [ID_DEV_MOTORRAWR] = "rtmotor_raw_r%u", + [ID_DEV_MOTORRAWL] = "rtmotor_raw_l%u", + [ID_DEV_MOTOREN] = "rtmotoren%u", + [ID_DEV_MOTOR] = "rtmotor%u"}; /* * i2c_counter_set - set value to I2C pulse counter pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy