bq24296.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. #include <linux/types.h>
  2. #include <linux/init.h> /* For init/exit macros */
  3. #include <linux/module.h> /* For MODULE_ marcros */
  4. #include <linux/platform_device.h>
  5. #include <linux/i2c.h>
  6. #include <linux/slab.h>
  7. #ifdef CONFIG_OF
  8. #include <linux/of.h>
  9. #include <linux/of_irq.h>
  10. #include <linux/of_address.h>
  11. #endif
  12. #include <mt-plat/charging.h>
  13. #include "bq24296.h"
  14. /**********************************************************
  15. *
  16. * [I2C Slave Setting]
  17. *
  18. *********************************************************/
  19. #define bq24296_SLAVE_ADDR_WRITE 0xD6
  20. #define bq24296_SLAVE_ADDR_READ 0xD7
  21. static struct i2c_client *new_client;
  22. static const struct i2c_device_id bq24296_i2c_id[] = { {"bq24296", 0}, {} };
  23. kal_bool chargin_hw_init_done = KAL_FALSE;
  24. static int bq24296_driver_probe(struct i2c_client *client, const struct i2c_device_id *id);
  25. #ifdef CONFIG_OF
  26. static const struct of_device_id bq24296_of_match[] = {
  27. {.compatible = "bq24296",},
  28. {},
  29. };
  30. MODULE_DEVICE_TABLE(of, bq24296_of_match);
  31. #endif
  32. static struct i2c_driver bq24296_driver = {
  33. .driver = {
  34. .name = "bq24296",
  35. #ifdef CONFIG_OF
  36. .of_match_table = bq24296_of_match,
  37. #endif
  38. },
  39. .probe = bq24296_driver_probe,
  40. .id_table = bq24296_i2c_id,
  41. };
  42. /**********************************************************
  43. *
  44. * [Global Variable]
  45. *
  46. *********************************************************/
  47. unsigned char bq24296_reg[bq24296_REG_NUM] = { 0 };
  48. static DEFINE_MUTEX(bq24296_i2c_access);
  49. int g_bq24296_hw_exist = 0;
  50. /**********************************************************
  51. *
  52. * [I2C Function For Read/Write bq24296]
  53. *
  54. *********************************************************/
  55. int bq24296_read_byte(unsigned char cmd, unsigned char *returnData)
  56. {
  57. char cmd_buf[1] = { 0x00 };
  58. char readData = 0;
  59. int ret = 0;
  60. mutex_lock(&bq24296_i2c_access);
  61. /* new_client->addr = ((new_client->addr) & I2C_MASK_FLAG) | I2C_WR_FLAG; */
  62. new_client->ext_flag =
  63. ((new_client->ext_flag) & I2C_MASK_FLAG) | I2C_WR_FLAG | I2C_DIRECTION_FLAG;
  64. cmd_buf[0] = cmd;
  65. ret = i2c_master_send(new_client, &cmd_buf[0], (1 << 8 | 1));
  66. if (ret < 0) {
  67. /* new_client->addr = new_client->addr & I2C_MASK_FLAG; */
  68. new_client->ext_flag = 0;
  69. mutex_unlock(&bq24296_i2c_access);
  70. return 0;
  71. }
  72. readData = cmd_buf[0];
  73. *returnData = readData;
  74. /* new_client->addr = new_client->addr & I2C_MASK_FLAG; */
  75. new_client->ext_flag = 0;
  76. mutex_unlock(&bq24296_i2c_access);
  77. return 1;
  78. }
  79. int bq24296_write_byte(unsigned char cmd, unsigned char writeData)
  80. {
  81. char write_data[2] = { 0 };
  82. int ret = 0;
  83. mutex_lock(&bq24296_i2c_access);
  84. write_data[0] = cmd;
  85. write_data[1] = writeData;
  86. new_client->ext_flag = ((new_client->ext_flag) & I2C_MASK_FLAG) | I2C_DIRECTION_FLAG;
  87. ret = i2c_master_send(new_client, write_data, 2);
  88. if (ret < 0) {
  89. new_client->ext_flag = 0;
  90. mutex_unlock(&bq24296_i2c_access);
  91. return 0;
  92. }
  93. new_client->ext_flag = 0;
  94. mutex_unlock(&bq24296_i2c_access);
  95. return 1;
  96. }
  97. /**********************************************************
  98. *
  99. * [Read / Write Function]
  100. *
  101. *********************************************************/
  102. unsigned int bq24296_read_interface(unsigned char RegNum, unsigned char *val, unsigned char MASK,
  103. unsigned char SHIFT)
  104. {
  105. unsigned char bq24296_reg = 0;
  106. int ret = 0;
  107. battery_log(BAT_LOG_FULL, "--------------------------------------------------\n");
  108. ret = bq24296_read_byte(RegNum, &bq24296_reg);
  109. battery_log(BAT_LOG_FULL, "[bq24296_read_interface] Reg[%x]=0x%x\n", RegNum, bq24296_reg);
  110. bq24296_reg &= (MASK << SHIFT);
  111. *val = (bq24296_reg >> SHIFT);
  112. battery_log(BAT_LOG_FULL, "[bq24296_read_interface] val=0x%x\n", *val);
  113. return ret;
  114. }
  115. unsigned int bq24296_config_interface(unsigned char RegNum, unsigned char val, unsigned char MASK,
  116. unsigned char SHIFT)
  117. {
  118. unsigned char bq24296_reg = 0;
  119. int ret = 0;
  120. battery_log(BAT_LOG_FULL, "--------------------------------------------------\n");
  121. ret = bq24296_read_byte(RegNum, &bq24296_reg);
  122. battery_log(BAT_LOG_FULL, "[bq24296_config_interface] Reg[%x]=0x%x\n", RegNum, bq24296_reg);
  123. bq24296_reg &= ~(MASK << SHIFT);
  124. bq24296_reg |= (val << SHIFT);
  125. ret = bq24296_write_byte(RegNum, bq24296_reg);
  126. battery_log(BAT_LOG_FULL, "[bq24296_config_interface] write Reg[%x]=0x%x\n", RegNum, bq24296_reg);
  127. /* Check */
  128. /* bq24296_read_byte(RegNum, &bq24296_reg); */
  129. /* battery_log(BAT_LOG_FULL, "[bq24296_config_interface] Check Reg[%x]=0x%x\n", RegNum, bq24296_reg); */
  130. return ret;
  131. }
  132. /* write one register directly */
  133. unsigned int bq24296_reg_config_interface(unsigned char RegNum, unsigned char val)
  134. {
  135. unsigned int ret = 0;
  136. ret = bq24296_write_byte(RegNum, val);
  137. return ret;
  138. }
  139. /**********************************************************
  140. *
  141. * [Internal Function]
  142. *
  143. *********************************************************/
  144. /* CON0---------------------------------------------------- */
  145. void bq24296_set_en_hiz(unsigned int val)
  146. {
  147. unsigned int ret = 0;
  148. ret = bq24296_config_interface((unsigned char) (bq24296_CON0),
  149. (unsigned char) (val),
  150. (unsigned char) (CON0_EN_HIZ_MASK),
  151. (unsigned char) (CON0_EN_HIZ_SHIFT)
  152. );
  153. }
  154. void bq24296_set_vindpm(unsigned int val)
  155. {
  156. unsigned int ret = 0;
  157. ret = bq24296_config_interface((unsigned char) (bq24296_CON0),
  158. (unsigned char) (val),
  159. (unsigned char) (CON0_VINDPM_MASK),
  160. (unsigned char) (CON0_VINDPM_SHIFT)
  161. );
  162. }
  163. void bq24296_set_iinlim(unsigned int val)
  164. {
  165. unsigned int ret = 0;
  166. ret = bq24296_config_interface((unsigned char) (bq24296_CON0),
  167. (unsigned char) (val),
  168. (unsigned char) (CON0_IINLIM_MASK),
  169. (unsigned char) (CON0_IINLIM_SHIFT)
  170. );
  171. }
  172. /* CON1---------------------------------------------------- */
  173. void bq24296_set_reg_rst(unsigned int val)
  174. {
  175. unsigned int ret = 0;
  176. ret = bq24296_config_interface((unsigned char) (bq24296_CON1),
  177. (unsigned char) (val),
  178. (unsigned char) (CON1_REG_RST_MASK),
  179. (unsigned char) (CON1_REG_RST_SHIFT)
  180. );
  181. }
  182. void bq24296_set_wdt_rst(unsigned int val)
  183. {
  184. unsigned int ret = 0;
  185. ret = bq24296_config_interface((unsigned char) (bq24296_CON1),
  186. (unsigned char) (val),
  187. (unsigned char) (CON1_WDT_RST_MASK),
  188. (unsigned char) (CON1_WDT_RST_SHIFT)
  189. );
  190. }
  191. void bq24296_set_otg_config(unsigned int val)
  192. {
  193. unsigned int ret = 0;
  194. ret = bq24296_config_interface((unsigned char) (bq24296_CON1),
  195. (unsigned char) (val),
  196. (unsigned char) (CON1_OTG_CONFIG_MASK),
  197. (unsigned char) (CON1_OTG_CONFIG_SHIFT)
  198. );
  199. }
  200. void bq24296_set_chg_config(unsigned int val)
  201. {
  202. unsigned int ret = 0;
  203. ret = bq24296_config_interface((unsigned char) (bq24296_CON1),
  204. (unsigned char) (val),
  205. (unsigned char) (CON1_CHG_CONFIG_MASK),
  206. (unsigned char) (CON1_CHG_CONFIG_SHIFT)
  207. );
  208. }
  209. void bq24296_set_sys_min(unsigned int val)
  210. {
  211. unsigned int ret = 0;
  212. ret = bq24296_config_interface((unsigned char) (bq24296_CON1),
  213. (unsigned char) (val),
  214. (unsigned char) (CON1_SYS_MIN_MASK),
  215. (unsigned char) (CON1_SYS_MIN_SHIFT)
  216. );
  217. }
  218. void bq24296_set_boost_lim(unsigned int val)
  219. {
  220. unsigned int ret = 0;
  221. ret = bq24296_config_interface((unsigned char) (bq24296_CON1),
  222. (unsigned char) (val),
  223. (unsigned char) (CON1_BOOST_LIM_MASK),
  224. (unsigned char) (CON1_BOOST_LIM_SHIFT)
  225. );
  226. }
  227. /* CON2---------------------------------------------------- */
  228. void bq24296_set_ichg(unsigned int val)
  229. {
  230. unsigned int ret = 0;
  231. ret = bq24296_config_interface((unsigned char) (bq24296_CON2),
  232. (unsigned char) (val),
  233. (unsigned char) (CON2_ICHG_MASK), (unsigned char) (CON2_ICHG_SHIFT)
  234. );
  235. }
  236. void bq24296_set_bcold(unsigned int val)
  237. {
  238. unsigned int ret = 0;
  239. ret = bq24296_config_interface((unsigned char) (bq24296_CON2),
  240. (unsigned char) (val),
  241. (unsigned char) (CON2_BCOLD_MASK), (unsigned char) (CON2_BCOLD_SHIFT)
  242. );
  243. }
  244. void bq24296_set_force_20pct(unsigned int val)
  245. {
  246. unsigned int ret = 0;
  247. ret = bq24296_config_interface((unsigned char) (bq24296_CON2),
  248. (unsigned char) (val),
  249. (unsigned char) (CON2_FORCE_20PCT_MASK),
  250. (unsigned char) (CON2_FORCE_20PCT_SHIFT)
  251. );
  252. }
  253. /* CON3---------------------------------------------------- */
  254. void bq24296_set_iprechg(unsigned int val)
  255. {
  256. unsigned int ret = 0;
  257. ret = bq24296_config_interface((unsigned char) (bq24296_CON3),
  258. (unsigned char) (val),
  259. (unsigned char) (CON3_IPRECHG_MASK),
  260. (unsigned char) (CON3_IPRECHG_SHIFT)
  261. );
  262. }
  263. void bq24296_set_iterm(unsigned int val)
  264. {
  265. unsigned int ret = 0;
  266. ret = bq24296_config_interface((unsigned char) (bq24296_CON3),
  267. (unsigned char) (val),
  268. (unsigned char) (CON3_ITERM_MASK), (unsigned char) (CON3_ITERM_SHIFT)
  269. );
  270. }
  271. /* CON4---------------------------------------------------- */
  272. void bq24296_set_vreg(unsigned int val)
  273. {
  274. unsigned int ret = 0;
  275. ret = bq24296_config_interface((unsigned char) (bq24296_CON4),
  276. (unsigned char) (val),
  277. (unsigned char) (CON4_VREG_MASK), (unsigned char) (CON4_VREG_SHIFT)
  278. );
  279. }
  280. void bq24296_set_batlowv(unsigned int val)
  281. {
  282. unsigned int ret = 0;
  283. ret = bq24296_config_interface((unsigned char) (bq24296_CON4),
  284. (unsigned char) (val),
  285. (unsigned char) (CON4_BATLOWV_MASK),
  286. (unsigned char) (CON4_BATLOWV_SHIFT)
  287. );
  288. }
  289. void bq24296_set_vrechg(unsigned int val)
  290. {
  291. unsigned int ret = 0;
  292. ret = bq24296_config_interface((unsigned char) (bq24296_CON4),
  293. (unsigned char) (val),
  294. (unsigned char) (CON4_VRECHG_MASK),
  295. (unsigned char) (CON4_VRECHG_SHIFT)
  296. );
  297. }
  298. /* CON5---------------------------------------------------- */
  299. void bq24296_set_en_term(unsigned int val)
  300. {
  301. unsigned int ret = 0;
  302. ret = bq24296_config_interface((unsigned char) (bq24296_CON5),
  303. (unsigned char) (val),
  304. (unsigned char) (CON5_EN_TERM_MASK),
  305. (unsigned char) (CON5_EN_TERM_SHIFT)
  306. );
  307. }
  308. void bq24296_set_watchdog(unsigned int val)
  309. {
  310. unsigned int ret = 0;
  311. ret = bq24296_config_interface((unsigned char) (bq24296_CON5),
  312. (unsigned char) (val),
  313. (unsigned char) (CON5_WATCHDOG_MASK),
  314. (unsigned char) (CON5_WATCHDOG_SHIFT)
  315. );
  316. }
  317. void bq24296_set_en_timer(unsigned int val)
  318. {
  319. unsigned int ret = 0;
  320. ret = bq24296_config_interface((unsigned char) (bq24296_CON5),
  321. (unsigned char) (val),
  322. (unsigned char) (CON5_EN_TIMER_MASK),
  323. (unsigned char) (CON5_EN_TIMER_SHIFT)
  324. );
  325. }
  326. void bq24296_set_chg_timer(unsigned int val)
  327. {
  328. unsigned int ret = 0;
  329. ret = bq24296_config_interface((unsigned char) (bq24296_CON5),
  330. (unsigned char) (val),
  331. (unsigned char) (CON5_CHG_TIMER_MASK),
  332. (unsigned char) (CON5_CHG_TIMER_SHIFT)
  333. );
  334. }
  335. /* CON6---------------------------------------------------- */
  336. void bq24296_set_treg(unsigned int val)
  337. {
  338. unsigned int ret = 0;
  339. ret = bq24296_config_interface((unsigned char) (bq24296_CON6),
  340. (unsigned char) (val),
  341. (unsigned char) (CON6_TREG_MASK), (unsigned char) (CON6_TREG_SHIFT)
  342. );
  343. }
  344. void bq24296_set_boostv(unsigned int val)
  345. {
  346. unsigned int ret = 0;
  347. ret = bq24296_config_interface((unsigned char) (bq24296_CON6),
  348. (unsigned char) (val),
  349. (unsigned char) (CON6_BOOSTV_MASK),
  350. (unsigned char) (CON6_BOOSTV_SHIFT)
  351. );
  352. }
  353. void bq24296_set_bhot(unsigned int val)
  354. {
  355. unsigned int ret = 0;
  356. ret = bq24296_config_interface((unsigned char) (bq24296_CON6),
  357. (unsigned char) (val),
  358. (unsigned char) (CON6_BHOT_MASK), (unsigned char) (CON6_BHOT_SHIFT)
  359. );
  360. }
  361. /* CON7---------------------------------------------------- */
  362. void bq24296_set_tmr2x_en(unsigned int val)
  363. {
  364. unsigned int ret = 0;
  365. ret = bq24296_config_interface((unsigned char) (bq24296_CON7),
  366. (unsigned char) (val),
  367. (unsigned char) (CON7_TMR2X_EN_MASK),
  368. (unsigned char) (CON7_TMR2X_EN_SHIFT)
  369. );
  370. }
  371. void bq24296_set_batfet_disable(unsigned int val)
  372. {
  373. unsigned int ret = 0;
  374. ret = bq24296_config_interface((unsigned char) (bq24296_CON7),
  375. (unsigned char) (val),
  376. (unsigned char) (CON7_BATFET_Disable_MASK),
  377. (unsigned char) (CON7_BATFET_Disable_SHIFT)
  378. );
  379. }
  380. void bq24296_set_int_mask(unsigned int val)
  381. {
  382. unsigned int ret = 0;
  383. ret = bq24296_config_interface((unsigned char) (bq24296_CON7),
  384. (unsigned char) (val),
  385. (unsigned char) (CON7_INT_MASK_MASK),
  386. (unsigned char) (CON7_INT_MASK_SHIFT)
  387. );
  388. }
  389. /* CON8---------------------------------------------------- */
  390. unsigned int bq24296_get_system_status(void)
  391. {
  392. unsigned int ret = 0;
  393. unsigned char val = 0;
  394. ret = bq24296_read_interface((unsigned char) (bq24296_CON8),
  395. (&val), (unsigned char) (0xFF), (unsigned char) (0x0)
  396. );
  397. return val;
  398. }
  399. unsigned int bq24296_get_vbus_stat(void)
  400. {
  401. unsigned int ret = 0;
  402. unsigned char val = 0;
  403. ret = bq24296_read_interface((unsigned char) (bq24296_CON8),
  404. (&val),
  405. (unsigned char) (CON8_VBUS_STAT_MASK),
  406. (unsigned char) (CON8_VBUS_STAT_SHIFT)
  407. );
  408. return val;
  409. }
  410. unsigned int bq24296_get_chrg_stat(void)
  411. {
  412. unsigned int ret = 0;
  413. unsigned char val = 0;
  414. ret = bq24296_read_interface((unsigned char) (bq24296_CON8),
  415. (&val),
  416. (unsigned char) (CON8_CHRG_STAT_MASK),
  417. (unsigned char) (CON8_CHRG_STAT_SHIFT)
  418. );
  419. return val;
  420. }
  421. unsigned int bq24296_get_vsys_stat(void)
  422. {
  423. unsigned int ret = 0;
  424. unsigned char val = 0;
  425. ret = bq24296_read_interface((unsigned char) (bq24296_CON8),
  426. (&val),
  427. (unsigned char) (CON8_VSYS_STAT_MASK),
  428. (unsigned char) (CON8_VSYS_STAT_SHIFT)
  429. );
  430. return val;
  431. }
  432. /**********************************************************
  433. *
  434. * [Internal Function]
  435. *
  436. *********************************************************/
  437. void bq24296_hw_component_detect(void)
  438. {
  439. unsigned int ret = 0;
  440. unsigned char val = 0;
  441. ret = bq24296_read_interface(0x0A, &val, 0xFF, 0x0);
  442. if (val == 0)
  443. g_bq24296_hw_exist = 0;
  444. else
  445. g_bq24296_hw_exist = 1;
  446. battery_log(BAT_LOG_CRTI, "[bq24296_hw_component_detect] exist=%d, Reg[0x03]=0x%x\n", g_bq24296_hw_exist, val);
  447. }
  448. int is_bq24296_exist(void)
  449. {
  450. battery_log(BAT_LOG_CRTI, "[is_bq24296_exist] g_bq24296_hw_exist=%d\n", g_bq24296_hw_exist);
  451. return g_bq24296_hw_exist;
  452. }
  453. void bq24296_dump_register(void)
  454. {
  455. int i = 0;
  456. battery_log(BAT_LOG_FULL, "[bq24296] ");
  457. for (i = 0; i < bq24296_REG_NUM; i++) {
  458. bq24296_read_byte(i, &bq24296_reg[i]);
  459. battery_log(BAT_LOG_FULL, "[0x%x]=0x%x ", i, bq24296_reg[i]);
  460. }
  461. battery_log(BAT_LOG_FULL, "\n");
  462. }
  463. static int bq24296_driver_probe(struct i2c_client *client, const struct i2c_device_id *id)
  464. {
  465. int err = 0;
  466. battery_log(BAT_LOG_CRTI, "[bq24296_driver_probe]\n");
  467. new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
  468. if (!new_client) {
  469. err = -ENOMEM;
  470. goto exit;
  471. }
  472. memset(new_client, 0, sizeof(struct i2c_client));
  473. new_client = client;
  474. /* --------------------- */
  475. bq24296_hw_component_detect();
  476. bq24296_dump_register();
  477. chargin_hw_init_done = KAL_TRUE;
  478. return 0;
  479. exit:
  480. return err;
  481. }
  482. /**********************************************************
  483. *
  484. * [platform_driver API]
  485. *
  486. *********************************************************/
  487. unsigned char g_reg_value_bq24296 = 0;
  488. static ssize_t show_bq24296_access(struct device *dev, struct device_attribute *attr, char *buf)
  489. {
  490. battery_log(BAT_LOG_CRTI, "[show_bq24296_access] 0x%x\n", g_reg_value_bq24296);
  491. return sprintf(buf, "%u\n", g_reg_value_bq24296);
  492. }
  493. static ssize_t store_bq24296_access(struct device *dev, struct device_attribute *attr,
  494. const char *buf, size_t size)
  495. {
  496. int ret = 0;
  497. char *pvalue = NULL, *addr, *val;
  498. unsigned int reg_value = 0;
  499. unsigned int reg_address = 0;
  500. battery_log(BAT_LOG_CRTI, "[store_bq24296_access]\n");
  501. if (buf != NULL && size != 0) {
  502. battery_log(BAT_LOG_CRTI, "[store_bq24296_access] buf is %s and size is %zu\n", buf, size);
  503. /*reg_address = kstrtoul(buf, 16, &pvalue);*/
  504. pvalue = (char *)buf;
  505. if (size > 3) {
  506. addr = strsep(&pvalue, " ");
  507. ret = kstrtou32(addr, 16, (unsigned int *)&reg_address);
  508. } else
  509. ret = kstrtou32(pvalue, 16, (unsigned int *)&reg_address);
  510. if (size > 3) {
  511. val = strsep(&pvalue, " ");
  512. ret = kstrtou32(val, 16, (unsigned int *)&reg_value);
  513. battery_log(BAT_LOG_CRTI,
  514. "[store_bq24296_access] write bq24296 reg 0x%x with value 0x%x !\n",
  515. reg_address, reg_value);
  516. ret = bq24296_config_interface(reg_address, reg_value, 0xFF, 0x0);
  517. } else {
  518. ret = bq24296_read_interface(reg_address, &g_reg_value_bq24296, 0xFF, 0x0);
  519. battery_log(BAT_LOG_CRTI,
  520. "[store_bq24296_access] read bq24296 reg 0x%x with value 0x%x !\n",
  521. reg_address, g_reg_value_bq24296);
  522. battery_log(BAT_LOG_CRTI,
  523. "[store_bq24296_access] Please use \"cat bq24296_access\" to get value\r\n");
  524. }
  525. }
  526. return size;
  527. }
  528. static DEVICE_ATTR(bq24296_access, 0664, show_bq24296_access, store_bq24296_access); /* 664 */
  529. static int bq24296_user_space_probe(struct platform_device *dev)
  530. {
  531. int ret_device_file = 0;
  532. battery_log(BAT_LOG_CRTI, "******** bq24296_user_space_probe!! ********\n");
  533. ret_device_file = device_create_file(&(dev->dev), &dev_attr_bq24296_access);
  534. return 0;
  535. }
  536. struct platform_device bq24296_user_space_device = {
  537. .name = "bq24296-user",
  538. .id = -1,
  539. };
  540. static struct platform_driver bq24296_user_space_driver = {
  541. .probe = bq24296_user_space_probe,
  542. .driver = {
  543. .name = "bq24296-user",
  544. },
  545. };
  546. static int __init bq24296_subsys_init(void)
  547. {
  548. int ret = 0;
  549. if (i2c_add_driver(&bq24296_driver) != 0)
  550. battery_log(BAT_LOG_CRTI, "[bq24261_init] failed to register bq24261 i2c driver.\n");
  551. else
  552. battery_log(BAT_LOG_CRTI, "[bq24261_init] Success to register bq24261 i2c driver.\n");
  553. /* bq24296 user space access interface */
  554. ret = platform_device_register(&bq24296_user_space_device);
  555. if (ret) {
  556. battery_log(BAT_LOG_CRTI, "****[bq24296_init] Unable to device register(%d)\n", ret);
  557. return ret;
  558. }
  559. ret = platform_driver_register(&bq24296_user_space_driver);
  560. if (ret) {
  561. battery_log(BAT_LOG_CRTI, "****[bq24296_init] Unable to register driver (%d)\n", ret);
  562. return ret;
  563. }
  564. return 0;
  565. }
  566. static void __exit bq24296_exit(void)
  567. {
  568. i2c_del_driver(&bq24296_driver);
  569. }
  570. /* module_init(bq24296_init); */
  571. /* module_exit(bq24296_exit); */
  572. subsys_initcall(bq24296_subsys_init);
  573. MODULE_LICENSE("GPL");
  574. MODULE_DESCRIPTION("I2C bq24296 Driver");
  575. MODULE_AUTHOR("YT Lee<yt.lee@mediatek.com>");