sfsattrib.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. #include <linux/version.h>
  2. #include <linux/init.h>
  3. #include <linux/kernel.h>
  4. #include <linux/module.h>
  5. #include <linux/kobject.h>
  6. #include <linux/errno.h>
  7. #include <linux/sysfs.h>
  8. #include <linux/syscalls.h>
  9. #include "defines.h"
  10. #include "sfsattrib.h"
  11. #include "kfirmware.h"
  12. #include "ksync.h"
  13. /////////////////////////////////////////////////////////////////////////////
  14. int g_hw = -1, g_sw = -1;
  15. TIVA_ADC g_tadc;
  16. unsigned long long g_nUpTime = 0;
  17. static void *g_pFwBuffer = NULL;
  18. static size_t g_nCbFwData = 0;
  19. static atomic_t g_flgFwLocked;
  20. static atomic_t g_flgBacklightChanged;
  21. static atomic_t g_valBacklightBrightness;
  22. static atomic_t g_valBacklightFrequency;
  23. /////////////////////////////////////////////////////////////////////////////
  24. static ssize_t version_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  25. {
  26. int hw, sw;
  27. ksync_lock();
  28. hw = g_hw;
  29. sw = g_sw;
  30. ksync_unlock();
  31. return sprintf(buf, "%d %d", hw, sw);
  32. }
  33. /////////////////////////////////////////////////////////////////////////////
  34. static ssize_t uptime_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  35. {
  36. unsigned long long nVal;
  37. ksync_lock();
  38. nVal = g_nUpTime;
  39. ksync_unlock();
  40. return sprintf(buf, "%llu", nVal);
  41. }
  42. /////////////////////////////////////////////////////////////////////////////
  43. static ssize_t UVers_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  44. {
  45. int nVal;
  46. ksync_lock();
  47. nVal = g_tadc.UVers + 40;
  48. ksync_unlock();
  49. return sprintf(buf, "%d.%02d", nVal / 100, nVal % 100);
  50. }
  51. /////////////////////////////////////////////////////////////////////////////
  52. static ssize_t UBatV3_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  53. {
  54. int nVal;
  55. ksync_lock();
  56. nVal = g_tadc.UBatV3;
  57. ksync_unlock();
  58. return sprintf(buf, "%d.%02d", nVal / 100, nVal % 100);
  59. }
  60. /////////////////////////////////////////////////////////////////////////////
  61. static ssize_t TempBoard_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  62. {
  63. int nVal;
  64. ksync_lock();
  65. nVal = g_tadc.Temp;
  66. ksync_unlock();
  67. return sprintf(buf, "%d.%d0", nVal / 10, nVal % 10);
  68. }
  69. /////////////////////////////////////////////////////////////////////////////
  70. static ssize_t UV5Vsys_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  71. {
  72. int nVal;
  73. ksync_lock();
  74. nVal = g_tadc.UV5Vsys;
  75. ksync_unlock();
  76. return sprintf(buf, "%d.%02d", nVal / 100, nVal % 100);
  77. }
  78. /////////////////////////////////////////////////////////////////////////////
  79. static ssize_t UV3V6Bat_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  80. {
  81. int nVal;
  82. ksync_lock();
  83. nVal = g_tadc.UV3V6Bat;
  84. ksync_unlock();
  85. return sprintf(buf, "%d.%02d", nVal / 100, nVal % 100);
  86. }
  87. /////////////////////////////////////////////////////////////////////////////
  88. static ssize_t TempTIVA_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  89. {
  90. long nVal;
  91. ksync_lock();
  92. nVal = 14750 - 18750 * g_tadc.TempTIVA / 4096;
  93. ksync_unlock();
  94. return sprintf(buf, "%ld.%02ld", nVal / 100, nVal % 100);
  95. }
  96. /////////////////////////////////////////////////////////////////////////////
  97. static ssize_t AdcBin_read(struct file *pf, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t len)
  98. {
  99. if(off >= sizeof(g_tadc))
  100. return 0;
  101. if((len + off) > sizeof(g_tadc))
  102. len = sizeof(g_tadc) - off;
  103. ksync_lock();
  104. memcpy(buf, ((const unsigned char*)&g_tadc) + off, len);
  105. ksync_unlock();
  106. return (ssize_t)len;
  107. }
  108. /////////////////////////////////////////////////////////////////////////////
  109. static ssize_t brightness_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
  110. {
  111. ssize_t ret = -EINVAL;
  112. if(buf && count)
  113. {
  114. char szBuf[32];
  115. long long val;
  116. if(count >= sizeof(szBuf))
  117. return -ENOMEM;
  118. memcpy(szBuf, buf, count);
  119. szBuf[count] = '\0';
  120. if(!(ret = kstrtoll(szBuf, 10, &val)))
  121. {
  122. SfAttSetBacklightBrightness(val);
  123. atomic_set(&g_flgBacklightChanged, 1);
  124. ret = count;
  125. }
  126. }
  127. return ret;
  128. }
  129. /////////////////////////////////////////////////////////////////////////////
  130. static ssize_t frequency_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
  131. {
  132. ssize_t ret = -EINVAL;
  133. if(buf && count)
  134. {
  135. char szBuf[32];
  136. long long val;
  137. if(count >= sizeof(szBuf))
  138. return -ENOMEM;
  139. memcpy(szBuf, buf, count);
  140. szBuf[count] = '\0';
  141. if(!(ret = kstrtoll(szBuf, 10, &val)))
  142. {
  143. SfAttSetBacklightFrequency(val);
  144. atomic_set(&g_flgBacklightChanged, 1);
  145. ret = count;
  146. }
  147. }
  148. return ret;
  149. }
  150. /////////////////////////////////////////////////////////////////////////////
  151. static ssize_t image_read(struct file *pf, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t len)
  152. {
  153. return -EACCES;
  154. /* if(off >= g_nCbFwData)
  155. return 0;
  156. if((off + len) > g_nCbFwData)
  157. len = g_nCbFwData - off;
  158. ksync_lock();
  159. memcpy(buf, ((char*)g_pFwBuffer) + off, len);
  160. ksync_unlock();
  161. KALERT("%s buf: %p, off: %lld, len: %zu\n", __FUNCTION__, buf, off, len);
  162. return len;*/
  163. }
  164. static ssize_t image_write(struct file *pf, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t len)
  165. {
  166. int nRet;
  167. size_t nCbUbound;
  168. static KFW_DROP_CTX dctx;
  169. if(SfAttIsFirmwareLocked())
  170. return -EBUSY;
  171. else if(len == 0)
  172. return 0;
  173. else if(off < 0)
  174. return -EFAULT;
  175. else if(off >= _FIRMWARE_BUFFER_SIZE)
  176. return -ENOMEM;
  177. else if((off + len) > _FIRMWARE_BUFFER_SIZE)
  178. len = _FIRMWARE_BUFFER_SIZE - off;
  179. if(off == 0) // first block of data
  180. {
  181. memset(&dctx, 0, sizeof(dctx));
  182. ksync_lock();
  183. g_nCbFwData = 0;
  184. memset(g_pFwBuffer, 0xFF, _FIRMWARE_BUFFER_SIZE);
  185. ksync_unlock();
  186. }
  187. nCbUbound = off + len;
  188. ksync_lock();
  189. memcpy(((char*)g_pFwBuffer) + off, buf, len);
  190. if(g_nCbFwData < nCbUbound)
  191. g_nCbFwData = nCbUbound;
  192. ksync_unlock();
  193. if((nRet = KfwOnDataDropped(g_pFwBuffer, g_nCbFwData, &dctx)) < 0)
  194. {
  195. ksync_lock();
  196. g_nCbFwData = 0;
  197. ksync_unlock();
  198. memset(&dctx, 0, sizeof(dctx));
  199. SfAttLockFirmware(false);
  200. return nRet;
  201. }
  202. else if(nRet > 0)
  203. {
  204. ksync_lock();
  205. g_nCbFwData = 0;
  206. ksync_unlock();
  207. memset(&dctx, 0, sizeof(dctx));
  208. }
  209. // KALERT("%s buf: %p, off: %lld, len: %zu\n", __FUNCTION__, buf, off, len);
  210. return len;
  211. }
  212. bool SfAttInit(void)
  213. {
  214. g_nCbFwData = 0;
  215. atomic_set(&g_flgBacklightChanged, 0);
  216. SfAttSetBacklightBrightness(_BACKLIGHT_DEF_BRIGHT_PERC);
  217. SfAttSetBacklightFrequency(_BACKLIGHT_DEF_FREQ_HZ);
  218. g_pFwBuffer = (void*)__get_free_pages(GFP_KERNEL, _FIRMWARE_PAGES_COUNT);
  219. return !!g_pFwBuffer;
  220. }
  221. void SfAttExit(void)
  222. {
  223. g_nCbFwData = 0;
  224. if(g_pFwBuffer)
  225. {
  226. free_pages((unsigned long)g_pFwBuffer, _FIRMWARE_PAGES_COUNT);
  227. g_pFwBuffer = NULL;
  228. }
  229. }
  230. /////////////////////////////////////////////////////////////////////////////
  231. bool SfAttIsFirmwareLocked(void)
  232. {
  233. return !!atomic_read(&g_flgFwLocked);
  234. }
  235. /////////////////////////////////////////////////////////////////////////////
  236. void SfAttLockFirmware(bool bLock)
  237. {
  238. atomic_set(&g_flgFwLocked, bLock ? 1 : 0);
  239. }
  240. /////////////////////////////////////////////////////////////////////////////
  241. unsigned int SfAttGetBacklightBrightness(void)
  242. {
  243. return (unsigned int)atomic_read(&g_valBacklightBrightness);
  244. }
  245. /////////////////////////////////////////////////////////////////////////////
  246. void SfAttSetBacklightBrightness(int val)
  247. {
  248. if(val < 0)
  249. val = 0;
  250. else if(val > 100)
  251. val = 100;
  252. atomic_set(&g_valBacklightBrightness, val);
  253. }
  254. /////////////////////////////////////////////////////////////////////////////
  255. unsigned int SfAttGetBacklightFrequency(void)
  256. {
  257. return (unsigned int)atomic_read(&g_valBacklightFrequency);
  258. }
  259. /////////////////////////////////////////////////////////////////////////////
  260. void SfAttSetBacklightFrequency(int val)
  261. {
  262. if(val < _BACKLIGHT_FREQ_MIN_HZ)
  263. val = _BACKLIGHT_FREQ_MIN_HZ;
  264. else if(val > _BACKLIGHT_FREQ_MAX_HZ)
  265. val = _BACKLIGHT_FREQ_MAX_HZ;
  266. atomic_set(&g_valBacklightFrequency, val);
  267. }
  268. /////////////////////////////////////////////////////////////////////////////
  269. bool SfAttBacklightChanged(void)
  270. {
  271. bool ret = !!atomic_read(&g_flgBacklightChanged);
  272. if(ret)
  273. atomic_set(&g_flgBacklightChanged, 0);
  274. return ret;
  275. }
  276. /////////////////////////////////////////////////////////////////////////////
  277. /////////////////////////////////////////////////////////////////////////////
  278. /////////////////////////////////////////////////////////////////////////////
  279. // tiva generic
  280. struct kobj_attribute g_tivaUptimeAtt = __ATTR_RO(uptime);
  281. /////////////////////////////////////////////////////////////////////////////
  282. // backlight
  283. struct kobj_attribute g_tivaBrightnessAtt = __ATTR_WO(brightness);
  284. struct kobj_attribute g_tivaFrequencyAtt = __ATTR_WO(frequency);
  285. /////////////////////////////////////////////////////////////////////////////
  286. // ADC
  287. struct kobj_attribute g_tivaUVersAtt = __ATTR_RO(UVers);
  288. struct kobj_attribute g_tivaUBatV3Att = __ATTR_RO(UBatV3);
  289. struct kobj_attribute g_tivaTempAtt = __ATTR_RO(TempBoard);
  290. struct kobj_attribute g_tivaUV5VsysAtt = __ATTR_RO(UV5Vsys);
  291. struct kobj_attribute g_tivaUV3V6BatAtt = __ATTR_RO(UV3V6Bat);
  292. struct kobj_attribute g_tivaTempTIVAAtt = __ATTR_RO(TempTIVA);
  293. struct bin_attribute g_tivaAdcBinAtt = __BIN_ATTR_RO(AdcBin, sizeof(TIVA_ADC));
  294. /////////////////////////////////////////////////////////////////////////////
  295. // tiva firmware
  296. struct kobj_attribute g_tivaVersionAtt = __ATTR_RO(version);
  297. struct bin_attribute g_tivaFwImageAtt = __BIN_ATTR_RW(image, 0);