#include #include #include #include #include #include #include #include #include "defines.h" #include "sfsattrib.h" #include "kfirmware.h" #include "ksync.h" ///////////////////////////////////////////////////////////////////////////// int g_hw = -1, g_sw = -1; TIVA_ADC g_tadc; unsigned long long g_nUpTime = 0; static void *g_pFwBuffer = NULL; static size_t g_nCbFwData = 0; static atomic_t g_flgFwLocked; static atomic_t g_flgBacklightChanged; static atomic_t g_valBacklightBrightness; static atomic_t g_valBacklightFrequency; ///////////////////////////////////////////////////////////////////////////// static ssize_t version_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int hw, sw; ksync_lock(); hw = g_hw; sw = g_sw; ksync_unlock(); return sprintf(buf, "%d %d", hw, sw); } ///////////////////////////////////////////////////////////////////////////// static ssize_t uptime_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { unsigned long long nVal; ksync_lock(); nVal = g_nUpTime; ksync_unlock(); return sprintf(buf, "%llu", nVal); } ///////////////////////////////////////////////////////////////////////////// static ssize_t UVers_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int nVal; ksync_lock(); nVal = g_tadc.UVers + 40; ksync_unlock(); return sprintf(buf, "%d.%02d", nVal / 100, nVal % 100); } ///////////////////////////////////////////////////////////////////////////// static ssize_t UBatV3_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int nVal; ksync_lock(); nVal = g_tadc.UBatV3; ksync_unlock(); return sprintf(buf, "%d.%02d", nVal / 100, nVal % 100); } ///////////////////////////////////////////////////////////////////////////// static ssize_t TempBoard_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int nVal; ksync_lock(); nVal = g_tadc.Temp; ksync_unlock(); return sprintf(buf, "%d.%d0", nVal / 10, nVal % 10); } ///////////////////////////////////////////////////////////////////////////// static ssize_t UV5Vsys_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int nVal; ksync_lock(); nVal = g_tadc.UV5Vsys; ksync_unlock(); return sprintf(buf, "%d.%02d", nVal / 100, nVal % 100); } ///////////////////////////////////////////////////////////////////////////// static ssize_t UV3V6Bat_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int nVal; ksync_lock(); nVal = g_tadc.UV3V6Bat; ksync_unlock(); return sprintf(buf, "%d.%02d", nVal / 100, nVal % 100); } ///////////////////////////////////////////////////////////////////////////// static ssize_t TempTIVA_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { long nVal; ksync_lock(); nVal = 14750 - 18750 * g_tadc.TempTIVA / 4096; ksync_unlock(); return sprintf(buf, "%ld.%02ld", nVal / 100, nVal % 100); } ///////////////////////////////////////////////////////////////////////////// static ssize_t AdcBin_read(struct file *pf, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t len) { if(off >= sizeof(g_tadc)) return 0; if((len + off) > sizeof(g_tadc)) len = sizeof(g_tadc) - off; ksync_lock(); memcpy(buf, ((const unsigned char*)&g_tadc) + off, len); ksync_unlock(); return (ssize_t)len; } ///////////////////////////////////////////////////////////////////////////// static ssize_t brightness_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { ssize_t ret = -EINVAL; if(buf && count) { char szBuf[32]; long long val; if(count >= sizeof(szBuf)) return -ENOMEM; memcpy(szBuf, buf, count); szBuf[count] = '\0'; if(!(ret = kstrtoll(szBuf, 10, &val))) { SfAttSetBacklightBrightness(val); atomic_set(&g_flgBacklightChanged, 1); ret = count; } } return ret; } ///////////////////////////////////////////////////////////////////////////// static ssize_t frequency_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { ssize_t ret = -EINVAL; if(buf && count) { char szBuf[32]; long long val; if(count >= sizeof(szBuf)) return -ENOMEM; memcpy(szBuf, buf, count); szBuf[count] = '\0'; if(!(ret = kstrtoll(szBuf, 10, &val))) { SfAttSetBacklightFrequency(val); atomic_set(&g_flgBacklightChanged, 1); ret = count; } } return ret; } ///////////////////////////////////////////////////////////////////////////// static ssize_t image_read(struct file *pf, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t len) { return -EACCES; /* if(off >= g_nCbFwData) return 0; if((off + len) > g_nCbFwData) len = g_nCbFwData - off; ksync_lock(); memcpy(buf, ((char*)g_pFwBuffer) + off, len); ksync_unlock(); KALERT("%s buf: %p, off: %lld, len: %zu\n", __FUNCTION__, buf, off, len); return len;*/ } static ssize_t image_write(struct file *pf, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t len) { int nRet; size_t nCbUbound; static KFW_DROP_CTX dctx; if(SfAttIsFirmwareLocked()) return -EBUSY; else if(len == 0) return 0; else if(off < 0) return -EFAULT; else if(off >= _FIRMWARE_BUFFER_SIZE) return -ENOMEM; else if((off + len) > _FIRMWARE_BUFFER_SIZE) len = _FIRMWARE_BUFFER_SIZE - off; if(off == 0) // first block of data { memset(&dctx, 0, sizeof(dctx)); ksync_lock(); g_nCbFwData = 0; memset(g_pFwBuffer, 0xFF, _FIRMWARE_BUFFER_SIZE); ksync_unlock(); } nCbUbound = off + len; ksync_lock(); memcpy(((char*)g_pFwBuffer) + off, buf, len); if(g_nCbFwData < nCbUbound) g_nCbFwData = nCbUbound; ksync_unlock(); if((nRet = KfwOnDataDropped(g_pFwBuffer, g_nCbFwData, &dctx)) < 0) { ksync_lock(); g_nCbFwData = 0; ksync_unlock(); memset(&dctx, 0, sizeof(dctx)); SfAttLockFirmware(false); return nRet; } else if(nRet > 0) { ksync_lock(); g_nCbFwData = 0; ksync_unlock(); memset(&dctx, 0, sizeof(dctx)); } // KALERT("%s buf: %p, off: %lld, len: %zu\n", __FUNCTION__, buf, off, len); return len; } bool SfAttInit(void) { g_nCbFwData = 0; atomic_set(&g_flgBacklightChanged, 0); SfAttSetBacklightBrightness(_BACKLIGHT_DEF_BRIGHT_PERC); SfAttSetBacklightFrequency(_BACKLIGHT_DEF_FREQ_HZ); g_pFwBuffer = (void*)__get_free_pages(GFP_KERNEL, _FIRMWARE_PAGES_COUNT); return !!g_pFwBuffer; } void SfAttExit(void) { g_nCbFwData = 0; if(g_pFwBuffer) { free_pages((unsigned long)g_pFwBuffer, _FIRMWARE_PAGES_COUNT); g_pFwBuffer = NULL; } } ///////////////////////////////////////////////////////////////////////////// bool SfAttIsFirmwareLocked(void) { return !!atomic_read(&g_flgFwLocked); } ///////////////////////////////////////////////////////////////////////////// void SfAttLockFirmware(bool bLock) { atomic_set(&g_flgFwLocked, bLock ? 1 : 0); } ///////////////////////////////////////////////////////////////////////////// unsigned int SfAttGetBacklightBrightness(void) { return (unsigned int)atomic_read(&g_valBacklightBrightness); } ///////////////////////////////////////////////////////////////////////////// void SfAttSetBacklightBrightness(int val) { if(val < 0) val = 0; else if(val > 100) val = 100; atomic_set(&g_valBacklightBrightness, val); } ///////////////////////////////////////////////////////////////////////////// unsigned int SfAttGetBacklightFrequency(void) { return (unsigned int)atomic_read(&g_valBacklightFrequency); } ///////////////////////////////////////////////////////////////////////////// void SfAttSetBacklightFrequency(int val) { if(val < _BACKLIGHT_FREQ_MIN_HZ) val = _BACKLIGHT_FREQ_MIN_HZ; else if(val > _BACKLIGHT_FREQ_MAX_HZ) val = _BACKLIGHT_FREQ_MAX_HZ; atomic_set(&g_valBacklightFrequency, val); } ///////////////////////////////////////////////////////////////////////////// bool SfAttBacklightChanged(void) { bool ret = !!atomic_read(&g_flgBacklightChanged); if(ret) atomic_set(&g_flgBacklightChanged, 0); return ret; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // tiva generic struct kobj_attribute g_tivaUptimeAtt = __ATTR_RO(uptime); ///////////////////////////////////////////////////////////////////////////// // backlight struct kobj_attribute g_tivaBrightnessAtt = __ATTR_WO(brightness); struct kobj_attribute g_tivaFrequencyAtt = __ATTR_WO(frequency); ///////////////////////////////////////////////////////////////////////////// // ADC struct kobj_attribute g_tivaUVersAtt = __ATTR_RO(UVers); struct kobj_attribute g_tivaUBatV3Att = __ATTR_RO(UBatV3); struct kobj_attribute g_tivaTempAtt = __ATTR_RO(TempBoard); struct kobj_attribute g_tivaUV5VsysAtt = __ATTR_RO(UV5Vsys); struct kobj_attribute g_tivaUV3V6BatAtt = __ATTR_RO(UV3V6Bat); struct kobj_attribute g_tivaTempTIVAAtt = __ATTR_RO(TempTIVA); struct bin_attribute g_tivaAdcBinAtt = __BIN_ATTR_RO(AdcBin, sizeof(TIVA_ADC)); ///////////////////////////////////////////////////////////////////////////// // tiva firmware struct kobj_attribute g_tivaVersionAtt = __ATTR_RO(version); struct bin_attribute g_tivaFwImageAtt = __BIN_ATTR_RW(image, 0);