|
@@ -0,0 +1,187 @@
|
|
|
|
+#include <linux/init.h>
|
|
|
|
+#include <linux/kernel.h> // printk()
|
|
|
|
+#include <linux/kobject.h> // struct kobject
|
|
|
|
+#include <linux/errno.h> // error codes
|
|
|
|
+#include <linux/module.h> // THIS_MODULE
|
|
|
|
+#include <linux/sysfs.h>
|
|
|
|
+#include <linux/syscalls.h>
|
|
|
|
+#include <asm/ioctls.h>
|
|
|
|
+#include <linux/spi/spidev.h>
|
|
|
|
+#include "kfile.h"
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+MODULE_LICENSE("Dual BSD/GPL");
|
|
|
|
+MODULE_AUTHOR("GfA");
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+#define _SPI_DEVICE "/dev/spidev1.0"
|
|
|
|
+static struct file *g_fdSpiDev = NULL;
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+static int temp = 0;
|
|
|
|
+static struct kobject *pKoGfa = NULL, *pKoTiva = NULL;
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+static ssize_t tivaTempShow(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
|
|
|
|
+{
|
|
|
|
+ printk(KERN_ALERT "tivaTemp - Read!!!\n");
|
|
|
|
+ return sprintf(buf, "%d", ++temp);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static ssize_t tivaTempStore(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
|
|
|
|
+{
|
|
|
|
+ printk(KERN_ALERT "tivaTemp - Write!!!\n");
|
|
|
|
+ sscanf(buf, "%d", &temp);
|
|
|
|
+ return count;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+static struct kobj_attribute tivaTempAtt = __ATTR(temp, 0660, tivaTempShow, tivaTempStore);
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+static int drv_init(void)
|
|
|
|
+{
|
|
|
|
+ long ret;
|
|
|
|
+ uint8_t mode = SPI_MODE_3;
|
|
|
|
+ uint8_t bits = 8;
|
|
|
|
+ uint32_t speed = 1000000;
|
|
|
|
+
|
|
|
|
+ /////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ if(!(pKoGfa = kobject_create_and_add("gfa", /*kernel_kobj*/NULL)))
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "kobject_create_and_add failed\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(!(pKoTiva = kobject_create_and_add("tiva", pKoGfa)))
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "kobject_create_and_add failed\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ if(sysfs_create_file(pKoTiva, &tivaTempAtt.attr))
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "sysfs_create_file failed\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ if(!(g_fdSpiDev = kf_open(_SPI_DEVICE, O_RDWR, 0)))
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "file_open failed\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ ret = kf_ioctl(g_fdSpiDev, SPI_IOC_WR_MODE, (unsigned long)&mode);
|
|
|
|
+ if(ret < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't set spi mode\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ mode = 0;
|
|
|
|
+ ret = kf_ioctl(g_fdSpiDev, SPI_IOC_RD_MODE, (unsigned long)&mode);
|
|
|
|
+ if(ret < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't get spi mode\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = kf_ioctl(g_fdSpiDev, SPI_IOC_WR_BITS_PER_WORD, (unsigned long)&bits);
|
|
|
|
+ if(ret < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't set bits per word\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bits = 0;
|
|
|
|
+ ret = kf_ioctl(g_fdSpiDev, SPI_IOC_RD_BITS_PER_WORD, (unsigned long)&bits);
|
|
|
|
+ if(ret < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't get bits per word\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ret = kf_ioctl(g_fdSpiDev, SPI_IOC_WR_MAX_SPEED_HZ, (unsigned long)&speed);
|
|
|
|
+ if(ret < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't set max speed hz\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ speed = 0;
|
|
|
|
+ ret = kf_ioctl(g_fdSpiDev, SPI_IOC_RD_MAX_SPEED_HZ, (unsigned long)&speed);
|
|
|
|
+ if(ret < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't get max speed hz\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ printk(KERN_ALERT "mode: %hhu\n", mode);
|
|
|
|
+ printk(KERN_ALERT "bits: %hhu\n", bits);
|
|
|
|
+ printk(KERN_ALERT "speed: %u\n", speed);
|
|
|
|
+ printk(KERN_ALERT "%s\n", __FUNCTION__);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ while(0);
|
|
|
|
+
|
|
|
|
+ /////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ if(g_fdSpiDev)
|
|
|
|
+ kf_close(g_fdSpiDev);
|
|
|
|
+
|
|
|
|
+ if(pKoTiva)
|
|
|
|
+ {
|
|
|
|
+ sysfs_remove_file(pKoTiva, &tivaTempAtt.attr);
|
|
|
|
+ kobject_put(pKoTiva);
|
|
|
|
+ pKoTiva = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(pKoGfa)
|
|
|
|
+ {
|
|
|
|
+ kobject_put(pKoGfa);
|
|
|
|
+ pKoGfa = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+static void drv_exit(void)
|
|
|
|
+{
|
|
|
|
+ if(g_fdSpiDev)
|
|
|
|
+ kf_close(g_fdSpiDev);
|
|
|
|
+
|
|
|
|
+ if(pKoTiva)
|
|
|
|
+ {
|
|
|
|
+ sysfs_remove_file(pKoTiva, &tivaTempAtt.attr);
|
|
|
|
+ kobject_put(pKoTiva);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(pKoGfa)
|
|
|
|
+ kobject_put(pKoGfa);
|
|
|
|
+
|
|
|
|
+ printk(KERN_ALERT "%s\n", __FUNCTION__);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+module_init(drv_init);
|
|
|
|
+module_exit(drv_exit);
|