|
@@ -1,14 +1,20 @@
|
|
|
|
+#include <linux/version.h>
|
|
#include <linux/init.h>
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h> // printk()
|
|
#include <linux/kernel.h> // printk()
|
|
|
|
+#include <linux/module.h> // THIS_MODULE
|
|
#include <linux/kobject.h> // struct kobject
|
|
#include <linux/kobject.h> // struct kobject
|
|
|
|
+#include <linux/timer.h>
|
|
#include <linux/errno.h> // error codes
|
|
#include <linux/errno.h> // error codes
|
|
-#include <linux/module.h> // THIS_MODULE
|
|
|
|
#include <linux/sysfs.h>
|
|
#include <linux/sysfs.h>
|
|
#include <linux/syscalls.h>
|
|
#include <linux/syscalls.h>
|
|
|
|
+#include <linux/workqueue.h>
|
|
#include <asm/ioctls.h>
|
|
#include <asm/ioctls.h>
|
|
#include <linux/spi/spidev.h>
|
|
#include <linux/spi/spidev.h>
|
|
#include "kfile.h"
|
|
#include "kfile.h"
|
|
#include "kspi.h"
|
|
#include "kspi.h"
|
|
|
|
+#include "sfsattrib.h"
|
|
|
|
+
|
|
|
|
+#define _TIMER_INTERVAL (jiffies + 3 * HZ)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
@@ -18,54 +24,161 @@ MODULE_AUTHOR("GfA");
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#define _SPI_DEVICE "/dev/spidev1.0"
|
|
#define _SPI_DEVICE "/dev/spidev1.0"
|
|
-static struct file *g_pfSpiDev = NULL;
|
|
|
|
|
|
+
|
|
|
|
+static void work_queue_func(struct work_struct *work);
|
|
|
|
+static struct kobject *g_pKoGfa = NULL, *g_pKoTiva = NULL;
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+// timer
|
|
|
|
|
|
-static struct kobject *pKoGfa = NULL, *pKoTiva = NULL;
|
|
|
|
|
|
+static struct workqueue_struct *g_pwq = NULL;
|
|
|
|
+static DECLARE_WORK(g_wo, work_queue_func);
|
|
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
+static volatile bool g_bTimerRunning = false;
|
|
|
|
+static struct timer_list g_jiq_timer;
|
|
|
|
|
|
-static ssize_t firmware_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
|
|
|
|
|
|
+static void OnJigTimer(unsigned long ptr)
|
|
{
|
|
{
|
|
- int hw = 0, sw = 0;
|
|
|
|
- printk(KERN_ALERT "%s, TID: %d, \"%s\"\n", __FUNCTION__, current->pid, current->comm);
|
|
|
|
- CmdGetFirmwareVersion(g_pfSpiDev, &hw, &sw);
|
|
|
|
- return sprintf(buf, "HW: %08X SW: %08X\n", hw, sw);
|
|
|
|
|
|
+// printk(KERN_ALERT "%s, Ctx: \"%s\"-(%d)\n", __FUNCTION__, current->comm, current->pid);
|
|
|
|
+ queue_work(g_pwq, &g_wo);
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+// work queue
|
|
|
|
+// sysfs_notify
|
|
|
|
+// https://stackoverflow.com/questions/16367623/using-the-linux-sysfs-notify-call
|
|
|
|
+//
|
|
|
|
|
|
-static struct kobj_attribute tivaFirmwareAtt = __ATTR_RO(firmware);
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-static int drv_init(void)
|
|
|
|
|
|
+static void work_queue_func(struct work_struct *work)
|
|
{
|
|
{
|
|
- long ret;
|
|
|
|
|
|
+ TIVA_ADC tadc;
|
|
|
|
+ struct file *pfSpiDev = NULL;
|
|
uint8_t mode = SPI_MODE_3;
|
|
uint8_t mode = SPI_MODE_3;
|
|
uint8_t bits = 8;
|
|
uint8_t bits = 8;
|
|
uint32_t speed = 1000000;
|
|
uint32_t speed = 1000000;
|
|
|
|
+ unsigned long start = jiffies;
|
|
|
|
|
|
- /////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
+// printk(KERN_ALERT "%s, Ctx: \"%s\"-(%d)\n", __FUNCTION__, current->comm, current->pid);
|
|
|
|
+// CmdGetFirmwareVersion(pfSpiDev, &g_hw, &g_sw);
|
|
|
|
+// sysfs_notify(g_pKoTiva, NULL, "firmware");
|
|
|
|
|
|
- do
|
|
|
|
|
|
+ if((pfSpiDev = kf_open(_SPI_DEVICE, O_RDWR, 0)))
|
|
{
|
|
{
|
|
- if(!(g_pfSpiDev = kf_open(_SPI_DEVICE, O_RDWR, 0)))
|
|
|
|
|
|
+ if(kf_ioctl(pfSpiDev, SPI_IOC_WR_MODE, (unsigned long)&mode) < 0)
|
|
{
|
|
{
|
|
- printk(KERN_ALERT "file_open failed\n");
|
|
|
|
- break;
|
|
|
|
|
|
+ printk(KERN_ALERT "can't set spi mode\n");
|
|
|
|
+// break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(kf_ioctl(pfSpiDev, SPI_IOC_RD_MODE, (unsigned long)&mode) < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't get spi mode\n");
|
|
|
|
+// break;
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
- if(!(pKoGfa = kobject_create_and_add("gfa", /*kernel_kobj*/NULL)))
|
|
|
|
|
|
+ if(kf_ioctl(pfSpiDev, SPI_IOC_WR_BITS_PER_WORD, (unsigned long)&bits) < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't set bits per word\n");
|
|
|
|
+// break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(kf_ioctl(pfSpiDev, SPI_IOC_RD_BITS_PER_WORD, (unsigned long)&bits) < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't get bits per word\n");
|
|
|
|
+// break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ if(kf_ioctl(pfSpiDev, SPI_IOC_WR_MAX_SPEED_HZ, (unsigned long)&speed) < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't set max speed hz\n");
|
|
|
|
+// break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(kf_ioctl(pfSpiDev, SPI_IOC_RD_MAX_SPEED_HZ, (unsigned long)&speed) < 0)
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "can't get max speed hz\n");
|
|
|
|
+// break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(CmdGetADC(pfSpiDev, &tadc) == 0)
|
|
|
|
+ {
|
|
|
|
+ if(g_tadc.UVers != tadc.UVers)
|
|
|
|
+ {
|
|
|
|
+ g_tadc.UVers = tadc.UVers;
|
|
|
|
+ sysfs_notify(g_pKoTiva, NULL, "UVers");
|
|
|
|
+// printk(KERN_ALERT "Update UVers.\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(g_tadc.UBatV3 != tadc.UBatV3)
|
|
|
|
+ {
|
|
|
|
+ g_tadc.UBatV3 = tadc.UBatV3;
|
|
|
|
+ sysfs_notify(g_pKoTiva, NULL, "UBatV3");
|
|
|
|
+// printk(KERN_ALERT "Update UBatV3.\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(g_tadc.Temp != tadc.Temp)
|
|
|
|
+ {
|
|
|
|
+ g_tadc.Temp = tadc.Temp;
|
|
|
|
+ sysfs_notify(g_pKoTiva, NULL, "Temp");
|
|
|
|
+// printk(KERN_ALERT "Update Temp.\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(g_tadc.UV5Vsys != tadc.UV5Vsys)
|
|
|
|
+ {
|
|
|
|
+ g_tadc.UV5Vsys = tadc.UV5Vsys;
|
|
|
|
+ sysfs_notify(g_pKoTiva, NULL, "UV5Vsys");
|
|
|
|
+// printk(KERN_ALERT "Update UV5Vsys.\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(g_tadc.UV3V6Bat != tadc.UV3V6Bat)
|
|
|
|
+ {
|
|
|
|
+ g_tadc.UV3V6Bat = tadc.UV3V6Bat;
|
|
|
|
+ sysfs_notify(g_pKoTiva, NULL, "UV3V6Bat");
|
|
|
|
+// printk(KERN_ALERT "Update UV3V6Bat.\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(g_tadc.TempTIVA != tadc.TempTIVA)
|
|
|
|
+ {
|
|
|
|
+ g_tadc.TempTIVA = tadc.TempTIVA;
|
|
|
|
+ sysfs_notify(g_pKoTiva, NULL, "TempTIVA");
|
|
|
|
+// printk(KERN_ALERT "Update TempTIVA.\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ kf_close(pfSpiDev);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "file_open failed\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(g_bTimerRunning)
|
|
|
|
+ {
|
|
|
|
+ mod_timer(&g_jiq_timer, _TIMER_INTERVAL);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printk(KERN_ALERT "Worker pass jiffies: %lu\n", ((long)jiffies - (long)start));
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+static int drv_init(void)
|
|
|
|
+{
|
|
|
|
+ /////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ if(!(g_pKoGfa = kobject_create_and_add("gfa", NULL)))
|
|
{
|
|
{
|
|
printk(KERN_ALERT "kobject_create_and_add failed\n");
|
|
printk(KERN_ALERT "kobject_create_and_add failed\n");
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- if(!(pKoTiva = kobject_create_and_add("tiva", pKoGfa)))
|
|
|
|
|
|
+ if(!(g_pKoTiva = kobject_create_and_add("tiva", g_pKoGfa)))
|
|
{
|
|
{
|
|
printk(KERN_ALERT "kobject_create_and_add failed\n");
|
|
printk(KERN_ALERT "kobject_create_and_add failed\n");
|
|
break;
|
|
break;
|
|
@@ -73,89 +186,108 @@ static int drv_init(void)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
- if(sysfs_create_file(pKoTiva, &tivaFirmwareAtt.attr))
|
|
|
|
|
|
+ if(sysfs_create_file(g_pKoTiva, &g_tivaFirmwareAtt.attr))
|
|
{
|
|
{
|
|
printk(KERN_ALERT "sysfs_create_file failed\n");
|
|
printk(KERN_ALERT "sysfs_create_file failed\n");
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- /////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
+ if(sysfs_create_file(g_pKoTiva, &g_tivaUVersAtt.attr))
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "sysfs_create_file failed\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
|
|
- ret = kf_ioctl(g_pfSpiDev, SPI_IOC_WR_MODE, (unsigned long)&mode);
|
|
|
|
- if(ret < 0)
|
|
|
|
|
|
+ if(sysfs_create_file(g_pKoTiva, &g_tivaUBatV3Att.attr))
|
|
{
|
|
{
|
|
- printk(KERN_ALERT "can't set spi mode\n");
|
|
|
|
|
|
+ printk(KERN_ALERT "sysfs_create_file failed\n");
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- mode = 0;
|
|
|
|
- ret = kf_ioctl(g_pfSpiDev, SPI_IOC_RD_MODE, (unsigned long)&mode);
|
|
|
|
- if(ret < 0)
|
|
|
|
|
|
+ if(sysfs_create_file(g_pKoTiva, &g_tivaTempAtt.attr))
|
|
{
|
|
{
|
|
- printk(KERN_ALERT "can't get spi mode\n");
|
|
|
|
|
|
+ printk(KERN_ALERT "sysfs_create_file failed\n");
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- /////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
+ if(sysfs_create_file(g_pKoTiva, &g_tivaUV5VsysAtt.attr))
|
|
|
|
+ {
|
|
|
|
+ printk(KERN_ALERT "sysfs_create_file failed\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
|
|
- ret = kf_ioctl(g_pfSpiDev, SPI_IOC_WR_BITS_PER_WORD, (unsigned long)&bits);
|
|
|
|
- if(ret < 0)
|
|
|
|
|
|
+ if(sysfs_create_file(g_pKoTiva, &g_tivaUV3V6BatAtt.attr))
|
|
{
|
|
{
|
|
- printk(KERN_ALERT "can't set bits per word\n");
|
|
|
|
|
|
+ printk(KERN_ALERT "sysfs_create_file failed\n");
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- bits = 0;
|
|
|
|
- ret = kf_ioctl(g_pfSpiDev, SPI_IOC_RD_BITS_PER_WORD, (unsigned long)&bits);
|
|
|
|
- if(ret < 0)
|
|
|
|
|
|
+ if(sysfs_create_file(g_pKoTiva, &g_tivaTempTIVAAtt.attr))
|
|
{
|
|
{
|
|
- printk(KERN_ALERT "can't get bits per word\n");
|
|
|
|
|
|
+ printk(KERN_ALERT "sysfs_create_file failed\n");
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
- ret = kf_ioctl(g_pfSpiDev, SPI_IOC_WR_MAX_SPEED_HZ, (unsigned long)&speed);
|
|
|
|
- if(ret < 0)
|
|
|
|
|
|
+ if(!(g_pwq = create_workqueue("GfaWrk")))
|
|
{
|
|
{
|
|
- printk(KERN_ALERT "can't set max speed hz\n");
|
|
|
|
|
|
+ printk(KERN_ALERT "create_workqueue failed!\n");
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
- speed = 0;
|
|
|
|
- ret = kf_ioctl(g_pfSpiDev, SPI_IOC_RD_MAX_SPEED_HZ, (unsigned long)&speed);
|
|
|
|
- if(ret < 0)
|
|
|
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ init_timer(&g_jiq_timer);
|
|
|
|
+ g_jiq_timer.function = OnJigTimer;
|
|
|
|
+ g_jiq_timer.data = 0;
|
|
|
|
+ g_jiq_timer.expires = _TIMER_INTERVAL;
|
|
|
|
+ add_timer(&g_jiq_timer);
|
|
|
|
+ g_bTimerRunning = true;
|
|
|
|
+
|
|
|
|
+ /////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ if(!queue_work(g_pwq, &g_wo))
|
|
{
|
|
{
|
|
- printk(KERN_ALERT "can't get max speed hz\n");
|
|
|
|
|
|
+ printk(KERN_ALERT "queue_work failed\n");
|
|
break;
|
|
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, TID: %d, \"%s\"\n", __FUNCTION__, current->pid, current->comm);
|
|
|
|
|
|
+ printk(KERN_ALERT "%s, Ctx: \"%s\"-(%d)\n", __FUNCTION__, current->comm, current->pid);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
while(0);
|
|
while(0);
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ if(g_bTimerRunning)
|
|
|
|
+ {
|
|
|
|
+ g_bTimerRunning = false;
|
|
|
|
+ del_timer_sync(&g_jiq_timer);
|
|
|
|
+ }
|
|
|
|
|
|
- if(g_pfSpiDev)
|
|
|
|
- kf_close(g_pfSpiDev);
|
|
|
|
|
|
+ if(g_pwq)
|
|
|
|
+ destroy_workqueue(g_pwq);
|
|
|
|
|
|
- if(pKoTiva)
|
|
|
|
|
|
+ if(g_pKoTiva)
|
|
{
|
|
{
|
|
- sysfs_remove_file(pKoTiva, &tivaFirmwareAtt.attr);
|
|
|
|
- kobject_put(pKoTiva);
|
|
|
|
- pKoTiva = NULL;
|
|
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaFirmwareAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaUVersAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaUBatV3Att.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaTempAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaUV5VsysAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaUV3V6BatAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaTempTIVAAtt.attr);
|
|
|
|
+ kobject_put(g_pKoTiva);
|
|
|
|
+ g_pKoTiva = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
- if(pKoGfa)
|
|
|
|
|
|
+ if(g_pKoGfa)
|
|
{
|
|
{
|
|
- kobject_put(pKoGfa);
|
|
|
|
- pKoGfa = NULL;
|
|
|
|
|
|
+ kobject_put(g_pKoGfa);
|
|
|
|
+ g_pKoGfa = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
@@ -165,19 +297,28 @@ static int drv_init(void)
|
|
|
|
|
|
static void drv_exit(void)
|
|
static void drv_exit(void)
|
|
{
|
|
{
|
|
- if(g_pfSpiDev)
|
|
|
|
- kf_close(g_pfSpiDev);
|
|
|
|
|
|
+ g_bTimerRunning = false;
|
|
|
|
+ del_timer_sync(&g_jiq_timer);
|
|
|
|
+
|
|
|
|
+ if(g_pwq)
|
|
|
|
+ destroy_workqueue(g_pwq);
|
|
|
|
|
|
- if(pKoTiva)
|
|
|
|
|
|
+ if(g_pKoTiva)
|
|
{
|
|
{
|
|
- sysfs_remove_file(pKoTiva, &tivaFirmwareAtt.attr);
|
|
|
|
- kobject_put(pKoTiva);
|
|
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaFirmwareAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaUVersAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaUBatV3Att.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaTempAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaUV5VsysAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaUV3V6BatAtt.attr);
|
|
|
|
+ sysfs_remove_file(g_pKoTiva, &g_tivaTempTIVAAtt.attr);
|
|
|
|
+ kobject_put(g_pKoTiva);
|
|
}
|
|
}
|
|
|
|
|
|
- if(pKoGfa)
|
|
|
|
- kobject_put(pKoGfa);
|
|
|
|
|
|
+ if(g_pKoGfa)
|
|
|
|
+ kobject_put(g_pKoGfa);
|
|
|
|
|
|
- printk(KERN_ALERT "%s, TID: %d, \"%s\"\n", __FUNCTION__, current->pid, current->comm);
|
|
|
|
|
|
+ printk(KERN_ALERT "%s, Ctx: \"%s\"-(%d)\n", __FUNCTION__, current->comm, current->pid);
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|