Advertisement
Guest User

Untitled

a guest
Sep 20th, 2015
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.75 KB | None | 0 0
  1. /*
  2. * Copyright © 2015, Avinaba Dalal "corphish" <d97.avinaba@gmail.com>
  3. * Copyright © 2015, Santhosh Subramanian "sandy" <sansans90@gmail.com>
  4. *
  5. * Charger Control driver for qpnp-smbcharger
  6. *
  7. * This software is licensed under the terms of the GNU General Public
  8. * License version 2, as published by the Free Software Foundation, and
  9. * may be copied, distributed, and modified under those terms.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. */
  17.  
  18. #include <linux/module.h>
  19. #include <linux/kobject.h>
  20. #include <linux/sysfs.h>
  21. #include <linux/kernel.h>
  22.  
  23. #include "sandy_charger_control.h"
  24.  
  25. #define DRIVER_MAJOR_VERSION 1
  26. #define DRIVER_MINOR_VERSION 0
  27.  
  28. #define MAX_CUSTOM_CURRENT 1500
  29. #define MIN_CUSTOM_CURRENT 100 //TBD
  30.  
  31. #define DEFAULT_SWITCH 0 //Master Switch disabled by default
  32. #define DEFAULT_CURRENT 500
  33.  
  34. //Tuneables
  35. int master_switch = DEFAULT_SWITCH; //disabled by default
  36. int custom_current = DEFAULT_CURRENT;
  37.  
  38. int check_switch_validity (int input_switch) {
  39.  
  40. /* Checks whether value of switch is proper or not.
  41. Return 0 if proper else return 1.*/
  42.  
  43. if (input_switch == 0 || input_switch == 1)
  44. return 0;
  45. else
  46. return 1;
  47. }
  48.  
  49. int check_current_limits (int input_current) {
  50.  
  51. /*
  52. Checks whether user input current is within safe limits or not.
  53. Return 0 if within safe limit, else return 1
  54. */
  55.  
  56. if (input_current >= MIN_CUSTOM_CURRENT && input_current <= MAX_CUSTOM_CURRENT)
  57. return 0;
  58. else
  59. return 1;
  60. }
  61.  
  62. //sys fs stuff
  63. static ssize_t master_switch_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  64. {
  65. return sprintf(buf, "%d", master_switch);
  66. }
  67.  
  68. static ssize_t master_switch_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
  69. {
  70. int val, rc;
  71. sscanf(buf, "%d", &val);
  72. rc = check_switch_validity(val);
  73. if(rc) {
  74. master_switch = DEFAULT_SWITCH;
  75. pr_info ("sandy_charger_control: Invalid switch selection. Using default value %d\n", master_switch);
  76. } else {
  77. master_switch = val;
  78. pr_info ("sandy_charger_control: Switch - %d\n", master_switch);
  79. }
  80.  
  81. return count;
  82. }
  83.  
  84. static ssize_t custom_current_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  85. {
  86. return sprintf(buf, "%d", custom_current);
  87. }
  88.  
  89. static ssize_t custom_current_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
  90. {
  91. int new_current, rc;
  92. sscanf(buf, "%d", &new_current);
  93. rc = check_current_limits(new_current);
  94. if (rc) {
  95. custom_current = DEFAULT_CURRENT;
  96. pr_info ("sandy_charger_control: Unsafe current input, switching to defalt value of %d\n", custom_current);
  97. } else {
  98. custom_current = new_current;
  99. }
  100. return count;
  101. }
  102.  
  103. static ssize_t charger_version_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
  104. {
  105. return sprintf(buf, "Charger Control %u.%u", DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION);
  106. }
  107.  
  108. static struct kobj_attribute master_switch_attribute =
  109. __ATTR(enabled,
  110. 0666,
  111. master_switch_show,
  112. master_switch_store);
  113.  
  114. static struct kobj_attribute charger_ctrl_ver_attribute =
  115. __ATTR(version,
  116. 0444,
  117. charger_version_show, NULL);
  118.  
  119. static struct kobj_attribute custom_current_attribute =
  120. __ATTR(custom_current,
  121. 0666,
  122. custom_current_show,
  123. custom_current_store);
  124.  
  125. static struct attribute *charger_control_attrs[] =
  126. {
  127. &custom_current_attribute.attr,
  128. &master_switch_attribute.attr,
  129. &charger_ctrl_ver_attribute.attr,
  130. NULL,
  131. };
  132.  
  133. static struct attribute_group charger_control_attr_group =
  134. {
  135. .attrs = charger_control_attrs,
  136. };
  137.  
  138. static struct kobject *charger_control_kobj;
  139.  
  140. static int charger_control_probe(void)
  141. {
  142. int sysfs_result;
  143. printk(KERN_DEBUG "[%s]\n",__func__);
  144.  
  145. charger_control_kobj = kobject_create_and_add("sandy_charger_control", kernel_kobj);
  146.  
  147. if (!charger_control_kobj) {
  148. pr_err("%s Interface create failed!\n",
  149. __FUNCTION__);
  150. return -ENOMEM;
  151. }
  152.  
  153. sysfs_result = sysfs_create_group(charger_control_kobj,
  154. &charger_control_attr_group);
  155.  
  156. if (sysfs_result) {
  157. pr_info("%s sysfs create failed!\n", __FUNCTION__);
  158. kobject_put(charger_control_kobj);
  159. }
  160. return sysfs_result;
  161. }
  162.  
  163. static void charger_control_remove(void)
  164. {
  165. if (charger_control_kobj != NULL)
  166. kobject_put(charger_control_kobj);
  167. }
  168.  
  169. module_init(charger_control_probe);
  170. module_exit(charger_control_remove);
  171. MODULE_LICENSE("GPL and additional rights");
  172. MODULE_AUTHOR("Avinaba Dalal <d97.avinaba@gmail.com>");
  173. MODULE_AUTHOR("sandy <sansans90@gmail.com>");
  174. MODULE_DESCRIPTION("Qpnp-SMB Charger control driver");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement