From cd14fc9e8f341013b2604dcfb33bc8099ec2aba4 Mon Sep 17 00:00:00 2001 From: Roman Bazalevskiy Date: Thu, 20 Apr 2017 13:07:02 +0300 Subject: [PATCH] =?utf8?q?=D0=9A=D0=BE=D0=BB=D0=BB=D0=B5=D0=BA=D1=86=D0=B8?= =?utf8?q?=D1=8F=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D0=B5=D0=B9=20=D0=B4?= =?utf8?q?=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E=D1=87=D0=B5?= =?utf8?q?=D0=BD=D0=B8=D1=8F=20=D1=83=D1=81=D1=82=D1=80=D0=BE=D0=B9=D1=81?= =?utf8?q?=D1=82=D0=B2=20=D0=BF=D0=BE=20i2c.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- am2320/Makefile | 52 +++++ am2320/README.md | 51 +++++ am2320/src | 1 + lcdi2c | 1 + ledtrig-morse/Makefile | 50 +++++ ledtrig-morse/src/Makefile | 7 + ledtrig-morse/src/ledtrig_morse.c | 319 ++++++++++++++++++++++++++++++ 7 files changed, 481 insertions(+) create mode 100644 am2320/Makefile create mode 100644 am2320/README.md create mode 160000 am2320/src create mode 160000 lcdi2c create mode 100644 ledtrig-morse/Makefile create mode 100644 ledtrig-morse/src/Makefile create mode 100644 ledtrig-morse/src/ledtrig_morse.c diff --git a/am2320/Makefile b/am2320/Makefile new file mode 100644 index 0000000..511edbc --- /dev/null +++ b/am2320/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (C) 2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# $Id: $ + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=am2320 +PKG_VERSION:=0.1 +PKG_RELEASE:=2 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +MAKEFLAGS_KMOD:= -C "$(LINUX_DIR)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + PATH="$(TARGET_PATH)" \ + SUBDIRS="$(PKG_BUILD_DIR)" + +define KernelPackage/am2320 + SUBMENU:=Other modules + DEPENDS:= + TITLE:=Kernel driver for AM2320 temperature/humidity sensor + URL:=https://github.com/rvbglas/linux-am2320-driver + FILES:=$(PKG_BUILD_DIR)/am2320.$(LINUX_KMOD_SUFFIX) + VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(PKG_RELEASE) + AUTOLOAD:=$(call AutoLoad,80,am2320) + $(call AddDepends/hwmon,+kmod-i2c-core) +endef + +define KernelPackage/am2320/description + Kernel driver for AM2320 i2c temperature/humidity sensor +endef + + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Compile + $(MAKE) $(MAKEFLAGS_KMOD) \ + modules +endef + +$(eval $(call KernelPackage,am2320)) diff --git a/am2320/README.md b/am2320/README.md new file mode 100644 index 0000000..3e993cf --- /dev/null +++ b/am2320/README.md @@ -0,0 +1,51 @@ +# linux-am2320-driver +Linux Device Driver for AM2320 + +**Experimental** + +Tested on a Raspberry pi 3 with kernel version 4.4.14-v7+ + +Usage +------ +You need to have the proper kernel headers installed to build this driver. Use this tool to install kernel headers https://github.com/notro/rpi-source + +1. clone this repo +2. git clone linux-am2320-driver +3. cd into directory +4. type make +5. sudo insmod am2320.ko +6. type lsmod and see whether the driver is loaded properly +7. sudo bash +8. if you have a new Raspberry pi (B+, 2 or 3) + + echo am2320 0x5c > /sys/class/i2c-adapter/i2c-1/new_device + + else if this is a Rev. 1 + + echo am2320 0x5c > /sys/class/i2c-adapter/i2c-0/new_device + +Viewing measurements +====================== +cat /sys/bus/i2c/devices/1-005c/temp1_input + +cat /sys/bus/i2c/devices/1-005c/humidity1_input + +OR + +cat /sys/class/i2c-adapter/i2c-1/1-005c/temp1_input + +cat /sys/class/i2c-adapter/i2c-1/1-005c/humidity1_input + +To remove from kernel +===================== +sudo bash +echo 0x5c > /sys/class/i2c-adapter/i2c-1/delete_device + +then do, + +rmmod am2320 + +Cleaning the directory +======================= +make clean + diff --git a/am2320/src b/am2320/src new file mode 160000 index 0000000..84b1ca1 --- /dev/null +++ b/am2320/src @@ -0,0 +1 @@ +Subproject commit 84b1ca12926769ba7a1380ee5ffdf652791b6594 diff --git a/lcdi2c b/lcdi2c new file mode 160000 index 0000000..f374077 --- /dev/null +++ b/lcdi2c @@ -0,0 +1 @@ +Subproject commit f374077b17d2222a8683394b2259753ca10fde3e diff --git a/ledtrig-morse/Makefile b/ledtrig-morse/Makefile new file mode 100644 index 0000000..13b1ec2 --- /dev/null +++ b/ledtrig-morse/Makefile @@ -0,0 +1,50 @@ +# +# Copyright (C) 2007 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# $Id: $ + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=ledtrig-morse +PKG_VERSION:=0.1 +PKG_RELEASE:=2 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk + +MAKEFLAGS_KMOD:= -C "$(LINUX_DIR)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + PATH="$(TARGET_PATH)" \ + SUBDIRS="$(PKG_BUILD_DIR)" + +define KernelPackage/ledtrig-morse + SUBMENU:=LED modules + DEPENDS:= + TITLE:=Kernel driver for Morse code LED trigger + FILES:=$(PKG_BUILD_DIR)/ledtrig_morse.$(LINUX_KMOD_SUFFIX) + VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(PKG_RELEASE) + AUTOLOAD:=$(call AutoLoad,80,ledtrig_morse) +endef + +define KernelPackage/ledtrig-morse/description + Kernel driver for Morse code LED trigger +endef + + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Compile + $(MAKE) $(MAKEFLAGS_KMOD) \ + modules +endef + +$(eval $(call KernelPackage,ledtrig-morse)) diff --git a/ledtrig-morse/src/Makefile b/ledtrig-morse/src/Makefile new file mode 100644 index 0000000..d7decdc --- /dev/null +++ b/ledtrig-morse/src/Makefile @@ -0,0 +1,7 @@ +obj-m += ledtrig_morse.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean diff --git a/ledtrig-morse/src/ledtrig_morse.c b/ledtrig-morse/src/ledtrig_morse.c new file mode 100644 index 0000000..35e6fa7 --- /dev/null +++ b/ledtrig-morse/src/ledtrig_morse.c @@ -0,0 +1,319 @@ +/* + * LED Morse Trigger + * + * Copyright (C) 2007 Gabor Juhos + * + * This file was based on: drivers/led/ledtrig-timer.c + * Copyright 2005-2006 Openedhand Ltd. + * Author: Richard Purdie + * + * also based on the patch '[PATCH] 2.5.59 morse code panics' posted + * in the LKML by Tomas Szepe at Thu, 30 Jan 2003 + * Copyright (C) 2002 Andrew Rodland + * Copyright (C) 2003 Tomas Szepe + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MORSE_DELAY_BASE (HZ/2) + +#define MORSE_STATE_BLINK_START 0 +#define MORSE_STATE_BLINK_STOP 1 + +#define MORSE_DIT_LEN 1 +#define MORSE_DAH_LEN 3 +#define MORSE_SPACE_LEN 7 + +struct morse_trig_data { + unsigned long delay; + char *msg; + + unsigned char morse; + unsigned char state; + char *msgpos; + struct timer_list timer; +}; + +const unsigned char morsetable[] = { + 0122, 0, 0310, 0, 0, 0163, /* "#$%&' */ + 055, 0155, 0, 0, 0163, 0141, 0152, 0051, /* ()*+,-./ */ + 077, 076, 074, 070, 060, 040, 041, 043, 047, 057, /* 0-9 */ + 0107, 0125, 0, 0061, 0, 0114, 0, /* :;<=>?@ */ + 006, 021, 025, 011, 002, 024, 013, 020, 004, /* A-I */ + 036, 015, 022, 007, 005, 017, 026, 033, 012, /* J-R */ + 010, 003, 014, 030, 016, 031, 035, 023, /* S-Z */ + 0, 0, 0, 0, 0154 /* [\]^_ */ +}; + +static inline unsigned char tomorse(char c) { + if (c >= 'a' && c <= 'z') + c = c - 'a' + 'A'; + if (c >= '"' && c <= '_') { + return morsetable[c - '"']; + } else + return 0; +} + +static inline unsigned long dit_len(struct morse_trig_data *morse_data) +{ + return MORSE_DIT_LEN*morse_data->delay; +} + +static inline unsigned long dah_len(struct morse_trig_data *morse_data) +{ + return MORSE_DAH_LEN*morse_data->delay; +} + +static inline unsigned long space_len(struct morse_trig_data *morse_data) +{ + return MORSE_SPACE_LEN*morse_data->delay; +} + +static void morse_timer_function(unsigned long data) +{ + struct led_classdev *led_cdev = (struct led_classdev *)data; + struct morse_trig_data *morse_data = led_cdev->trigger_data; + unsigned long brightness = LED_OFF; + unsigned long delay = 0; + + if (!morse_data->msg) + goto set_led; + + switch (morse_data->state) { + case MORSE_STATE_BLINK_START: + /* Starting a new blink. We have a valid code in morse. */ + delay = (morse_data->morse & 001) ? dah_len(morse_data): + dit_len(morse_data); + brightness = LED_FULL; + morse_data->state = MORSE_STATE_BLINK_STOP; + morse_data->morse >>= 1; + break; + case MORSE_STATE_BLINK_STOP: + /* Coming off of a blink. */ + morse_data->state = MORSE_STATE_BLINK_START; + + if (morse_data->morse > 1) { + /* Not done yet, just a one-dit pause. */ + delay = dit_len(morse_data); + break; + } + + /* Get a new char, figure out how much space. */ + /* First time through */ + if (!morse_data->msgpos) + morse_data->msgpos = (char *)morse_data->msg; + + if (!*morse_data->msgpos) { + /* Repeating */ + morse_data->msgpos = (char *)morse_data->msg; + delay = space_len(morse_data); + } else { + /* Inter-letter space */ + delay = dah_len(morse_data); + } + + if (!(morse_data->morse = tomorse(*morse_data->msgpos))) { + delay = space_len(morse_data); + /* And get us back here */ + morse_data->state = MORSE_STATE_BLINK_STOP; + } + morse_data->msgpos++; + break; + } + + mod_timer(&morse_data->timer, jiffies + msecs_to_jiffies(delay)); + +set_led: + led_set_brightness(led_cdev, brightness); +} + +static ssize_t _morse_delay_show(struct led_classdev *led_cdev, char *buf) +{ + struct morse_trig_data *morse_data = led_cdev->trigger_data; + + sprintf(buf, "%lu\n", morse_data->delay); + + return strlen(buf) + 1; +} + +static ssize_t _morse_delay_store(struct led_classdev *led_cdev, + const char *buf, size_t size) +{ + struct morse_trig_data *morse_data = led_cdev->trigger_data; + char *after; + unsigned long state = simple_strtoul(buf, &after, 10); + size_t count = after - buf; + int ret = -EINVAL; + + if (*after && isspace(*after)) + count++; + + if (count == size) { + morse_data->delay = state; + mod_timer(&morse_data->timer, jiffies + 1); + ret = count; + } + + return ret; +} + +static ssize_t _morse_msg_show(struct led_classdev *led_cdev, char *buf) +{ + struct morse_trig_data *morse_data = led_cdev->trigger_data; + + if (!morse_data->msg) + sprintf(buf, "\n"); + else + sprintf(buf, "%s\n", morse_data->msg); + + return strlen(buf) + 1; +} + +static ssize_t _morse_msg_store(struct led_classdev *led_cdev, + const char *buf, size_t size) +{ + struct morse_trig_data *morse_data = led_cdev->trigger_data; + char *m; + + m = kmalloc(size, GFP_KERNEL); + if (!m) + return -ENOMEM; + + memcpy(m,buf,size); + m[size]='\0'; + + if (morse_data->msg) + kfree(morse_data->msg); + + morse_data->msg = m; + morse_data->msgpos = NULL; + morse_data->state = MORSE_STATE_BLINK_STOP; + + mod_timer(&morse_data->timer, jiffies + 1); + + return size; +} + +static ssize_t morse_delay_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + + return _morse_delay_show(led_cdev, buf); +} + +static ssize_t morse_delay_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + + return _morse_delay_store(led_cdev, buf, size); +} + +static ssize_t morse_msg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + + return _morse_msg_show(led_cdev, buf); +} + +static ssize_t morse_msg_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + + return _morse_msg_store(led_cdev, buf, size); +} + +static DEVICE_ATTR(delay, 0644, morse_delay_show, morse_delay_store); +static DEVICE_ATTR(message, 0644, morse_msg_show, morse_msg_store); + +#define led_device_create_file(leddev, attr) \ + device_create_file(leddev->dev, &dev_attr_ ## attr) +#define led_device_remove_file(leddev, attr) \ + device_remove_file(leddev->dev, &dev_attr_ ## attr) + +static void morse_trig_activate(struct led_classdev *led_cdev) +{ + struct morse_trig_data *morse_data; + int rc; + + morse_data = kzalloc(sizeof(*morse_data), GFP_KERNEL); + if (!morse_data) + return; + + morse_data->delay = MORSE_DELAY_BASE; + init_timer(&morse_data->timer); + morse_data->timer.function = morse_timer_function; + morse_data->timer.data = (unsigned long)led_cdev; + + rc = led_device_create_file(led_cdev, delay); + if (rc) goto err; + + rc = led_device_create_file(led_cdev, message); + if (rc) goto err_delay; + + led_cdev->trigger_data = morse_data; + + return; + +err_delay: + led_device_remove_file(led_cdev, delay); +err: + kfree(morse_data); +} + +static void morse_trig_deactivate(struct led_classdev *led_cdev) +{ + struct morse_trig_data *morse_data = led_cdev->trigger_data; + + if (!morse_data) + return; + + led_device_remove_file(led_cdev, message); + led_device_remove_file(led_cdev, delay); + + del_timer_sync(&morse_data->timer); + if (morse_data->msg) + kfree(morse_data->msg); + + kfree(morse_data); +} + +static struct led_trigger morse_led_trigger = { + .name = "morse", + .activate = morse_trig_activate, + .deactivate = morse_trig_deactivate, +}; + +static int __init morse_trig_init(void) +{ + return led_trigger_register(&morse_led_trigger); +} + +static void __exit morse_trig_exit(void) +{ + led_trigger_unregister(&morse_led_trigger); +} + +module_init(morse_trig_init); +module_exit(morse_trig_exit); + +MODULE_AUTHOR("Gabor Juhos "); +MODULE_DESCRIPTION("Morse LED trigger"); +MODULE_LICENSE("GPL"); + -- 2.34.1