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