accdet.c 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746
  1. #include "accdet.h"
  2. #include "ts3a225e.h"
  3. #ifdef CONFIG_ACCDET_EINT
  4. #include <linux/gpio.h>
  5. #endif
  6. #include <upmu_common.h>
  7. #include <linux/timer.h>
  8. #include <linux/of.h>
  9. #include <linux/of_irq.h>
  10. #define DEBUG_THREAD 1
  11. /*----------------------------------------------------------------------
  12. static variable defination
  13. ----------------------------------------------------------------------*/
  14. #define REGISTER_VALUE(x) (x - 1)
  15. static int button_press_debounce = 0x400;
  16. int cur_key = 0;
  17. struct head_dts_data accdet_dts_data;
  18. s8 accdet_auxadc_offset;
  19. int accdet_irq;
  20. unsigned int gpiopin, headsetdebounce;
  21. unsigned int accdet_eint_type;
  22. struct headset_mode_settings *cust_headset_settings;
  23. #define ACCDET_DEBUG(format, args...) pr_debug(format, ##args)
  24. #define ACCDET_INFO(format, args...) pr_warn(format, ##args)
  25. #define ACCDET_ERROR(format, args...) pr_err(format, ##args)
  26. static struct switch_dev accdet_data;
  27. static struct input_dev *kpd_accdet_dev;
  28. static struct cdev *accdet_cdev;
  29. static struct class *accdet_class;
  30. static struct device *accdet_nor_device;
  31. static dev_t accdet_devno;
  32. static int pre_status;
  33. static int pre_state_swctrl;
  34. static int accdet_status = PLUG_OUT;
  35. static int cable_type;
  36. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  37. /*add for new feature PIN recognition*/
  38. static int cable_pin_recognition;
  39. static int show_icon_delay;
  40. #endif
  41. #if defined(CONFIG_TS3A225E_ACCDET)
  42. #define TS3A225E_CONNECTOR_NONE 0
  43. #define TS3A225E_CONNECTOR_TRS 1
  44. #define TS3A225E_CONNECTOR_TRRS_STANDARD 2
  45. #define TS3A225E_CONNECTOR_TRRS_OMTP 3
  46. unsigned char ts3a225e_reg_value[7] = { 0 };
  47. unsigned char ts3a225e_connector_type = TS3A225E_CONNECTOR_NONE;
  48. #endif
  49. static int eint_accdet_sync_flag;
  50. static int g_accdet_first = 1;
  51. static bool IRQ_CLR_FLAG;
  52. static char call_status;
  53. static int button_status;
  54. struct wake_lock accdet_suspend_lock;
  55. struct wake_lock accdet_irq_lock;
  56. struct wake_lock accdet_key_lock;
  57. struct wake_lock accdet_timer_lock;
  58. static struct work_struct accdet_work;
  59. static struct workqueue_struct *accdet_workqueue;
  60. static DEFINE_MUTEX(accdet_eint_irq_sync_mutex);
  61. static inline void clear_accdet_interrupt(void);
  62. static inline void clear_accdet_eint_interrupt(void);
  63. static void send_key_event(int keycode, int flag);
  64. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  65. static struct work_struct accdet_eint_work;
  66. static struct workqueue_struct *accdet_eint_workqueue;
  67. static inline void accdet_init(void);
  68. #define MICBIAS_DISABLE_TIMER (6 * HZ) /*6 seconds*/
  69. struct timer_list micbias_timer;
  70. static void disable_micbias(unsigned long a);
  71. /* Used to let accdet know if the pin has been fully plugged-in */
  72. #define EINT_PIN_PLUG_IN (1)
  73. #define EINT_PIN_PLUG_OUT (0)
  74. int cur_eint_state = EINT_PIN_PLUG_OUT;
  75. static struct work_struct accdet_disable_work;
  76. static struct workqueue_struct *accdet_disable_workqueue;
  77. #else
  78. /*static int g_accdet_working_in_suspend =0;*/
  79. #endif/*end CONFIG_ACCDET_EINT*/
  80. #ifndef CONFIG_ACCDET_EINT_IRQ
  81. struct pinctrl *accdet_pinctrl1;
  82. struct pinctrl_state *pins_eint_int;
  83. #endif
  84. #ifdef DEBUG_THREAD
  85. #endif
  86. static u32 pmic_pwrap_read(u32 addr);
  87. static void pmic_pwrap_write(u32 addr, unsigned int wdata);
  88. char *accdet_status_string[5] = {
  89. "Plug_out",
  90. "Headset_plug_in",
  91. /*"Double_check",*/
  92. "Hook_switch",
  93. /*"Tvout_plug_in",*/
  94. "Stand_by"
  95. };
  96. char *accdet_report_string[4] = {
  97. "No_device",
  98. "Headset_mic",
  99. "Headset_no_mic",
  100. /*"HEADSET_illegal",*/
  101. /* "Double_check"*/
  102. };
  103. /****************************************************************/
  104. /*** export function **/
  105. /****************************************************************/
  106. void accdet_detect(void)
  107. {
  108. int ret = 0;
  109. ACCDET_DEBUG("[Accdet]accdet_detect\n");
  110. accdet_status = PLUG_OUT;
  111. ret = queue_work(accdet_workqueue, &accdet_work);
  112. if (!ret)
  113. ACCDET_DEBUG("[Accdet]accdet_detect:accdet_work return:%d!\n", ret);
  114. }
  115. EXPORT_SYMBOL(accdet_detect);
  116. void accdet_state_reset(void)
  117. {
  118. ACCDET_DEBUG("[Accdet]accdet_state_reset\n");
  119. accdet_status = PLUG_OUT;
  120. cable_type = NO_DEVICE;
  121. }
  122. EXPORT_SYMBOL(accdet_state_reset);
  123. int accdet_get_cable_type(void)
  124. {
  125. return cable_type;
  126. }
  127. void accdet_auxadc_switch(int enable)
  128. {
  129. if (enable) {
  130. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) | ACCDET_BF_ON);
  131. /*ACCDET_DEBUG("ACCDET enable switch\n");*/
  132. } else {
  133. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) & ~(ACCDET_BF_ON));
  134. /*ACCDET_DEBUG("ACCDET disable switch\n");*/
  135. }
  136. }
  137. /****************************************************************/
  138. /*******static function defination **/
  139. /****************************************************************/
  140. static u64 accdet_get_current_time(void)
  141. {
  142. return sched_clock();
  143. }
  144. static bool accdet_timeout_ns(u64 start_time_ns, u64 timeout_time_ns)
  145. {
  146. u64 cur_time = 0;
  147. u64 elapse_time = 0;
  148. /*get current tick*/
  149. cur_time = accdet_get_current_time(); /*ns*/
  150. if (cur_time < start_time_ns) {
  151. ACCDET_DEBUG("@@@@Timer overflow! start%lld cur timer%lld\n", start_time_ns, cur_time);
  152. start_time_ns = cur_time;
  153. timeout_time_ns = 400 * 1000; /*400us*/
  154. ACCDET_DEBUG("@@@@reset timer! start%lld setting%lld\n", start_time_ns, timeout_time_ns);
  155. }
  156. elapse_time = cur_time - start_time_ns;
  157. /*check if timeout*/
  158. if (timeout_time_ns <= elapse_time) {
  159. /*timeout*/
  160. ACCDET_DEBUG("@@@@ACCDET IRQ clear Timeout\n");
  161. return false;
  162. }
  163. return true;
  164. }
  165. /*pmic wrap read and write func*/
  166. static u32 pmic_pwrap_read(u32 addr)
  167. {
  168. u32 val = 0;
  169. pwrap_read(addr, &val);
  170. return val;
  171. }
  172. static void pmic_pwrap_write(unsigned int addr, unsigned int wdata)
  173. {
  174. pwrap_write(addr, wdata);
  175. }
  176. static int Accdet_PMIC_IMM_GetOneChannelValue(int deCount)
  177. {
  178. unsigned int vol_val = 0;
  179. pmic_pwrap_write(ACCDET_AUXADC_CTL_SET, ACCDET_CH_REQ_EN);
  180. mdelay(3);
  181. while ((pmic_pwrap_read(ACCDET_AUXADC_REG) & ACCDET_DATA_READY) != ACCDET_DATA_READY)
  182. ;
  183. /*wait AUXADC data ready*/
  184. vol_val = (pmic_pwrap_read(ACCDET_AUXADC_REG) & ACCDET_DATA_MASK);
  185. vol_val = (vol_val * 1800) / 4096; /*mv*/
  186. vol_val -= accdet_auxadc_offset;
  187. ACCDET_DEBUG("ACCDET accdet_auxadc_offset: %d mv, MIC_Voltage1 = %d mv!\n\r", accdet_auxadc_offset, vol_val);
  188. return vol_val;
  189. }
  190. #ifdef CONFIG_ACCDET_PIN_SWAP
  191. static void accdet_FSA8049_enable(void)
  192. {
  193. mt_set_gpio_mode(GPIO_FSA8049_PIN, GPIO_FSA8049_PIN_M_GPIO);
  194. mt_set_gpio_dir(GPIO_FSA8049_PIN, GPIO_DIR_OUT);
  195. mt_set_gpio_out(GPIO_FSA8049_PIN, GPIO_OUT_ONE);
  196. }
  197. static void accdet_FSA8049_disable(void)
  198. {
  199. mt_set_gpio_mode(GPIO_FSA8049_PIN, GPIO_FSA8049_PIN_M_GPIO);
  200. mt_set_gpio_dir(GPIO_FSA8049_PIN, GPIO_DIR_OUT);
  201. mt_set_gpio_out(GPIO_FSA8049_PIN, GPIO_OUT_ZERO);
  202. }
  203. #endif
  204. static inline void headset_plug_out(void)
  205. {
  206. accdet_status = PLUG_OUT;
  207. cable_type = NO_DEVICE;
  208. /*update the cable_type*/
  209. if (cur_key != 0) {
  210. send_key_event(cur_key, 0);
  211. ACCDET_DEBUG(" [accdet] headset_plug_out send key = %d release\n", cur_key);
  212. cur_key = 0;
  213. }
  214. switch_set_state((struct switch_dev *)&accdet_data, cable_type);
  215. ACCDET_DEBUG(" [accdet] set state in cable_type = NO_DEVICE\n");
  216. }
  217. /*Accdet only need this func*/
  218. static inline void enable_accdet(u32 state_swctrl)
  219. {
  220. /*enable ACCDET unit*/
  221. ACCDET_DEBUG("accdet: enable_accdet\n");
  222. /*enable clock*/
  223. pmic_pwrap_write(TOP_CKPDN_CLR, RG_ACCDET_CLK_CLR);
  224. pmic_pwrap_write(ACCDET_STATE_SWCTRL, pmic_pwrap_read(ACCDET_STATE_SWCTRL) | state_swctrl);
  225. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) | ACCDET_ENABLE);
  226. }
  227. static inline void disable_accdet(void)
  228. {
  229. int irq_temp = 0;
  230. /*sync with accdet_irq_handler set clear accdet irq bit to avoid set clear accdet irq bit after disable accdet
  231. disable accdet irq*/
  232. pmic_pwrap_write(INT_CON_ACCDET_CLR, RG_ACCDET_IRQ_CLR);
  233. clear_accdet_interrupt();
  234. udelay(200);
  235. mutex_lock(&accdet_eint_irq_sync_mutex);
  236. while (pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT) {
  237. ACCDET_DEBUG("[Accdet]check_cable_type: Clear interrupt on-going....\n");
  238. msleep(20);
  239. }
  240. irq_temp = pmic_pwrap_read(ACCDET_IRQ_STS);
  241. irq_temp = irq_temp & (~IRQ_CLR_BIT);
  242. pmic_pwrap_write(ACCDET_IRQ_STS, irq_temp);
  243. mutex_unlock(&accdet_eint_irq_sync_mutex);
  244. /*disable ACCDET unit*/
  245. ACCDET_DEBUG("accdet: disable_accdet\n");
  246. pre_state_swctrl = pmic_pwrap_read(ACCDET_STATE_SWCTRL);
  247. #ifdef CONFIG_ACCDET_EINT
  248. pmic_pwrap_write(ACCDET_STATE_SWCTRL, 0);
  249. pmic_pwrap_write(ACCDET_CTRL, ACCDET_DISABLE);
  250. /*disable clock and Analog control*/
  251. /*mt6331_upmu_set_rg_audmicbias1vref(0x0);*/
  252. pmic_pwrap_write(TOP_CKPDN_SET, RG_ACCDET_CLK_SET);
  253. #endif
  254. #ifdef CONFIG_ACCDET_EINT_IRQ
  255. pmic_pwrap_write(ACCDET_STATE_SWCTRL, ACCDET_EINT_PWM_EN);
  256. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) & (~(ACCDET_ENABLE)));
  257. /*mt_set_gpio_out(GPIO_CAMERA_2_CMRST_PIN, GPIO_OUT_ZERO);*/
  258. #endif
  259. }
  260. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  261. static void disable_micbias(unsigned long a)
  262. {
  263. int ret = 0;
  264. ret = queue_work(accdet_disable_workqueue, &accdet_disable_work);
  265. if (!ret)
  266. ACCDET_DEBUG("[Accdet]disable_micbias:accdet_work return:%d!\n", ret);
  267. }
  268. static void disable_micbias_callback(struct work_struct *work)
  269. {
  270. if (cable_type == HEADSET_NO_MIC) {
  271. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  272. show_icon_delay = 0;
  273. cable_pin_recognition = 0;
  274. ACCDET_DEBUG("[Accdet] cable_pin_recognition = %d\n", cable_pin_recognition);
  275. pmic_pwrap_write(ACCDET_PWM_WIDTH, cust_headset_settings->pwm_width);
  276. pmic_pwrap_write(ACCDET_PWM_THRESH, cust_headset_settings->pwm_thresh);
  277. #endif
  278. /*setting pwm idle;*/
  279. pmic_pwrap_write(ACCDET_STATE_SWCTRL, pmic_pwrap_read(ACCDET_STATE_SWCTRL) & ~ACCDET_SWCTRL_IDLE_EN);
  280. #ifdef CONFIG_ACCDET_PIN_SWAP
  281. /*accdet_FSA8049_disable(); disable GPIOxxx for PIN swap */
  282. /*ACCDET_DEBUG("[Accdet] FSA8049 disable!\n");*/
  283. #endif
  284. disable_accdet();
  285. ACCDET_DEBUG("[Accdet] more than 5s MICBIAS : Disabled\n");
  286. }
  287. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  288. else if (cable_type == HEADSET_MIC) {
  289. pmic_pwrap_write(ACCDET_PWM_WIDTH, cust_headset_settings->pwm_width);
  290. pmic_pwrap_write(ACCDET_PWM_THRESH, cust_headset_settings->pwm_thresh);
  291. ACCDET_DEBUG("[Accdet]pin recog after 5s recover micbias polling!\n");
  292. }
  293. #endif
  294. }
  295. static void accdet_eint_work_callback(struct work_struct *work)
  296. {
  297. #ifdef CONFIG_ACCDET_EINT_IRQ
  298. int irq_temp = 0;
  299. if (cur_eint_state == EINT_PIN_PLUG_IN) {
  300. ACCDET_DEBUG("[Accdet]DCC EINT func :plug-in, cur_eint_state = %d\n", cur_eint_state);
  301. mutex_lock(&accdet_eint_irq_sync_mutex);
  302. eint_accdet_sync_flag = 1;
  303. mutex_unlock(&accdet_eint_irq_sync_mutex);
  304. wake_lock_timeout(&accdet_timer_lock, 7 * HZ);
  305. #ifdef CONFIG_ACCDET_PIN_SWAP
  306. /*pmic_pwrap_write(0x0400, pmic_pwrap_read(0x0400)|(1<<14)); */
  307. msleep(800);
  308. accdet_FSA8049_enable(); /*enable GPIOxxx for PIN swap */
  309. ACCDET_DEBUG("[Accdet] FSA8049 enable!\n");
  310. msleep(250); /*PIN swap need ms*/
  311. #endif
  312. accdet_init(); /*do set pwm_idle on in accdet_init*/
  313. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  314. show_icon_delay = 1;
  315. /*micbias always on during detected PIN recognition*/
  316. pmic_pwrap_write(ACCDET_PWM_WIDTH, cust_headset_settings->pwm_width);
  317. pmic_pwrap_write(ACCDET_PWM_THRESH, cust_headset_settings->pwm_width);
  318. ACCDET_DEBUG("[Accdet]pin recog start! micbias always on!\n");
  319. #endif
  320. /*set PWM IDLE on*/
  321. pmic_pwrap_write(ACCDET_STATE_SWCTRL, (pmic_pwrap_read(ACCDET_STATE_SWCTRL) | ACCDET_SWCTRL_IDLE_EN));
  322. /*enable ACCDET unit*/
  323. enable_accdet(ACCDET_SWCTRL_EN);
  324. } else {
  325. /*EINT_PIN_PLUG_OUT*/
  326. /*Disable ACCDET*/
  327. ACCDET_DEBUG("[Accdet]DCC EINT func :plug-out, cur_eint_state = %d\n", cur_eint_state);
  328. mutex_lock(&accdet_eint_irq_sync_mutex);
  329. eint_accdet_sync_flag = 0;
  330. mutex_unlock(&accdet_eint_irq_sync_mutex);
  331. del_timer_sync(&micbias_timer);
  332. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  333. show_icon_delay = 0;
  334. cable_pin_recognition = 0;
  335. #endif
  336. #ifdef CONFIG_ACCDET_PIN_SWAP
  337. /*pmic_pwrap_write(0x0400, pmic_pwrap_read(0x0400)&~(1<<14)); */
  338. accdet_FSA8049_disable(); /*disable GPIOxxx for PIN swap */
  339. ACCDET_DEBUG("[Accdet] FSA8049 disable!\n");
  340. #endif
  341. /*accdet_auxadc_switch(0);*/
  342. disable_accdet();
  343. headset_plug_out();
  344. /*recover EINT irq clear bit */
  345. /*TODO: need think~~~*/
  346. irq_temp = pmic_pwrap_read(ACCDET_IRQ_STS);
  347. irq_temp = irq_temp & (~IRQ_EINT_CLR_BIT);
  348. pmic_pwrap_write(ACCDET_IRQ_STS, irq_temp);
  349. }
  350. #else
  351. /*KE under fastly plug in and plug out*/
  352. if (cur_eint_state == EINT_PIN_PLUG_IN) {
  353. ACCDET_DEBUG("[Accdet]ACC EINT func :plug-in, cur_eint_state = %d\n", cur_eint_state);
  354. mutex_lock(&accdet_eint_irq_sync_mutex);
  355. eint_accdet_sync_flag = 1;
  356. mutex_unlock(&accdet_eint_irq_sync_mutex);
  357. wake_lock_timeout(&accdet_timer_lock, 7 * HZ);
  358. #ifdef CONFIG_ACCDET_PIN_SWAP
  359. /*pmic_pwrap_write(0x0400, pmic_pwrap_read(0x0400)|(1<<14)); */
  360. msleep(800);
  361. accdet_FSA8049_enable(); /*enable GPIOxxx for PIN swap */
  362. ACCDET_DEBUG("[Accdet] FSA8049 enable!\n");
  363. msleep(250); /*PIN swap need ms */
  364. #endif
  365. #if defined(CONFIG_TS3A225E_ACCDET)
  366. ACCDET_DEBUG("[Accdet] TS3A225E enable!\n");
  367. msleep(300);
  368. ts3a225e_write_byte(0x04, 0x01);
  369. msleep(500);
  370. ts3a225e_read_byte(0x02, &ts3a225e_reg_value[1]);
  371. ts3a225e_read_byte(0x03, &ts3a225e_reg_value[2]);
  372. ts3a225e_read_byte(0x05, &ts3a225e_reg_value[4]);
  373. ts3a225e_read_byte(0x06, &ts3a225e_reg_value[5]);
  374. ACCDET_DEBUG("[Accdet] TS3A225E CTRL1=%x!\n", ts3a225e_reg_value[1]);
  375. ACCDET_DEBUG("[Accdet] TS3A225E CTRL2=%x!\n", ts3a225e_reg_value[2]);
  376. ACCDET_DEBUG("[Accdet] TS3A225E DAT1=%x!\n", ts3a225e_reg_value[4]);
  377. ACCDET_DEBUG("[Accdet] TS3A225E INT=%x!\n", ts3a225e_reg_value[5]);
  378. if (ts3a225e_reg_value[5] == 0x01) {
  379. ACCDET_DEBUG("[Accdet] TS3A225E A standard TSR headset detected, RING2 and SLEEVE shorted!\n");
  380. ts3a225e_connector_type = TS3A225E_CONNECTOR_TRS;
  381. ts3a225e_write_byte(0x02, 0x07);
  382. ts3a225e_write_byte(0x03, 0xf3);
  383. msleep(20);
  384. } else if (ts3a225e_reg_value[5] == 0x02) {
  385. ACCDET_DEBUG("[Accdet] TS3A225E A microphone detected on either RING2 or SLEEVE!\n");
  386. if ((ts3a225e_reg_value[4] & 0x40) == 0x00)
  387. ts3a225e_connector_type = TS3A225E_CONNECTOR_TRRS_STANDARD;
  388. else
  389. ts3a225e_connector_type = TS3A225E_CONNECTOR_TRRS_OMTP;
  390. } else {
  391. ACCDET_DEBUG("[Accdet] TS3A225E Detection sequence completed without successful!\n");
  392. }
  393. #endif
  394. accdet_init(); /* do set pwm_idle on in accdet_init*/
  395. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  396. show_icon_delay = 1;
  397. /*micbias always on during detected PIN recognition*/
  398. pmic_pwrap_write(ACCDET_PWM_WIDTH, cust_headset_settings->pwm_width);
  399. pmic_pwrap_write(ACCDET_PWM_THRESH, cust_headset_settings->pwm_width);
  400. ACCDET_DEBUG("[Accdet]pin recog start! micbias always on!\n");
  401. #endif
  402. /*set PWM IDLE on*/
  403. pmic_pwrap_write(ACCDET_STATE_SWCTRL, (pmic_pwrap_read(ACCDET_STATE_SWCTRL) | ACCDET_SWCTRL_IDLE_EN));
  404. /*enable ACCDET unit*/
  405. enable_accdet(ACCDET_SWCTRL_EN);
  406. } else {
  407. /*EINT_PIN_PLUG_OUT*/
  408. /*Disable ACCDET*/
  409. ACCDET_DEBUG("[Accdet]ACC EINT func :plug-out, cur_eint_state = %d\n", cur_eint_state);
  410. mutex_lock(&accdet_eint_irq_sync_mutex);
  411. eint_accdet_sync_flag = 0;
  412. mutex_unlock(&accdet_eint_irq_sync_mutex);
  413. del_timer_sync(&micbias_timer);
  414. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  415. show_icon_delay = 0;
  416. cable_pin_recognition = 0;
  417. #endif
  418. #ifdef CONFIG_ACCDET_PIN_SWAP
  419. /*pmic_pwrap_write(0x0400, pmic_pwrap_read(0x0400)&~(1<<14));*/
  420. accdet_FSA8049_disable(); /*disable GPIOxxx for PIN swap*/
  421. ACCDET_DEBUG("[Accdet] FSA8049 disable!\n");
  422. #endif
  423. #if defined(CONFIG_TS3A225E_ACCDET)
  424. ACCDET_DEBUG("[Accdet] TS3A225E disable!\n");
  425. ts3a225e_connector_type = TS3A225E_CONNECTOR_NONE;
  426. #endif
  427. /*accdet_auxadc_switch(0);*/
  428. disable_accdet();
  429. headset_plug_out();
  430. }
  431. enable_irq(accdet_irq);
  432. ACCDET_DEBUG("[Accdet]enable_irq !!!!!!\n");
  433. #endif
  434. }
  435. static irqreturn_t accdet_eint_func(int irq, void *data)
  436. {
  437. int ret = 0;
  438. ACCDET_DEBUG("[Accdet]Enter accdet_eint_func !!!!!!\n");
  439. if (cur_eint_state == EINT_PIN_PLUG_IN) {
  440. /*
  441. To trigger EINT when the headset was plugged in
  442. We set the polarity back as we initialed.
  443. */
  444. #ifndef CONFIG_ACCDET_EINT_IRQ
  445. if (accdet_eint_type == IRQ_TYPE_LEVEL_HIGH)
  446. irq_set_irq_type(accdet_irq, IRQ_TYPE_LEVEL_HIGH);
  447. else
  448. irq_set_irq_type(accdet_irq, IRQ_TYPE_LEVEL_LOW);
  449. #endif
  450. #ifdef CONFIG_ACCDET_EINT_IRQ
  451. pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) & (~(7 << 4)));
  452. /*debounce=256ms*/
  453. pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) | EINT_IRQ_DE_IN);
  454. pmic_pwrap_write(ACCDET_DEBOUNCE3, cust_headset_settings->debounce3);
  455. #else
  456. gpio_set_debounce(gpiopin, headsetdebounce);
  457. #endif
  458. /* update the eint status */
  459. cur_eint_state = EINT_PIN_PLUG_OUT;
  460. } else {
  461. /*
  462. To trigger EINT when the headset was plugged out
  463. We set the opposite polarity to what we initialed.
  464. */
  465. #ifndef CONFIG_ACCDET_EINT_IRQ
  466. if (accdet_eint_type == IRQ_TYPE_LEVEL_HIGH)
  467. irq_set_irq_type(accdet_irq, IRQ_TYPE_LEVEL_LOW);
  468. else
  469. irq_set_irq_type(accdet_irq, IRQ_TYPE_LEVEL_HIGH);
  470. #endif
  471. #ifdef CONFIG_ACCDET_EINT_IRQ
  472. pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) & (~(7 << 4)));
  473. /*debounce=16ms*/
  474. pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) | EINT_IRQ_DE_OUT);
  475. #else
  476. gpio_set_debounce(gpiopin, accdet_dts_data.accdet_plugout_debounce * 1000);
  477. #endif
  478. /* update the eint status */
  479. cur_eint_state = EINT_PIN_PLUG_IN;
  480. mod_timer(&micbias_timer, jiffies + MICBIAS_DISABLE_TIMER);
  481. }
  482. #ifndef CONFIG_ACCDET_EINT_IRQ
  483. disable_irq_nosync(accdet_irq);
  484. #endif
  485. ACCDET_DEBUG("[Accdet]accdet_eint_func after cur_eint_state=%d\n", cur_eint_state);
  486. ret = queue_work(accdet_eint_workqueue, &accdet_eint_work);
  487. return IRQ_HANDLED;
  488. }
  489. #ifndef CONFIG_ACCDET_EINT_IRQ
  490. static inline int accdet_setup_eint(struct platform_device *accdet_device)
  491. {
  492. int ret;
  493. u32 ints[2] = { 0, 0 };
  494. u32 ints1[2] = { 0, 0 };
  495. struct device_node *node = NULL;
  496. struct pinctrl_state *pins_default;
  497. /*configure to GPIO function, external interrupt */
  498. ACCDET_INFO("[Accdet]accdet_setup_eint\n");
  499. accdet_pinctrl1 = devm_pinctrl_get(&accdet_device->dev);
  500. if (IS_ERR(accdet_pinctrl1)) {
  501. ret = PTR_ERR(accdet_pinctrl1);
  502. dev_err(&accdet_device->dev, "fwq Cannot find accdet accdet_pinctrl1!\n");
  503. return ret;
  504. }
  505. pins_default = pinctrl_lookup_state(accdet_pinctrl1, "default");
  506. if (IS_ERR(pins_default)) {
  507. ret = PTR_ERR(pins_default);
  508. /*dev_err(&accdet_device->dev, "fwq Cannot find accdet pinctrl default!\n");*/
  509. }
  510. pins_eint_int = pinctrl_lookup_state(accdet_pinctrl1, "state_eint_as_int");
  511. if (IS_ERR(pins_eint_int)) {
  512. ret = PTR_ERR(pins_eint_int);
  513. dev_err(&accdet_device->dev, "fwq Cannot find accdet pinctrl state_eint_accdet!\n");
  514. return ret;
  515. }
  516. pinctrl_select_state(accdet_pinctrl1, pins_eint_int);
  517. /*node = of_find_matching_node(node, accdet_of_match);*/
  518. node = of_find_matching_node(node, accdet_of_match);
  519. if (node) {
  520. of_property_read_u32_array(node, "debounce", ints, ARRAY_SIZE(ints));
  521. of_property_read_u32_array(node, "interrupts", ints1, ARRAY_SIZE(ints1));
  522. gpiopin = ints[0];
  523. headsetdebounce = ints[1];
  524. accdet_eint_type = ints1[1];
  525. gpio_set_debounce(gpiopin, headsetdebounce);
  526. accdet_irq = irq_of_parse_and_map(node, 0);
  527. ret = request_irq(accdet_irq, accdet_eint_func, IRQF_TRIGGER_NONE, "accdet-eint", NULL);
  528. if (ret != 0) {
  529. ACCDET_ERROR("[Accdet]EINT IRQ LINE NOT AVAILABLE\n");
  530. } else {
  531. ACCDET_ERROR("[Accdet]accdet set EINT finished, accdet_irq=%d, headsetdebounce=%d\n",
  532. accdet_irq, headsetdebounce);
  533. }
  534. } else {
  535. ACCDET_ERROR("[Accdet]%s can't find compatible node\n", __func__);
  536. }
  537. return 0;
  538. }
  539. #endif /*CONFIG_ACCDET_EINT_IRQ*/
  540. #endif /*endif CONFIG_ACCDET_EINT*/
  541. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  542. #define KEY_SAMPLE_PERIOD (60) /*ms*/
  543. #define MULTIKEY_ADC_CHANNEL (8)
  544. static DEFINE_MUTEX(accdet_multikey_mutex);
  545. #define NO_KEY (0x0)
  546. #define UP_KEY (0x01)
  547. #define MD_KEY (0x02)
  548. #define DW_KEY (0x04)
  549. #define AS_KEY (0x08)
  550. #ifndef CONFIG_FOUR_KEY_HEADSET
  551. static int key_check(int b)
  552. {
  553. /*ACCDET_DEBUG("adc_data: %d v\n",b);*/
  554. /* 0.24V ~ */
  555. /*ACCDET_DEBUG("[accdet] come in key_check!!\n");*/
  556. if ((b < accdet_dts_data.three_key.down_key) && (b >= accdet_dts_data.three_key.up_key))
  557. return DW_KEY;
  558. else if ((b < accdet_dts_data.three_key.up_key) && (b >= accdet_dts_data.three_key.mid_key))
  559. return UP_KEY;
  560. else if (b < accdet_dts_data.three_key.mid_key)
  561. return MD_KEY;
  562. ACCDET_DEBUG("[accdet] leave key_check!!\n");
  563. return NO_KEY;
  564. }
  565. #else
  566. static int key_check(int b)
  567. {
  568. /* 0.24V ~ */
  569. /*ACCDET_DEBUG("[accdet] come in key_check!!\n");*/
  570. if ((b < accdet_dts_data.four_key.down_key_four) && (b >= accdet_dts_data.four_key.up_key_four))
  571. return DW_KEY;
  572. else if ((b < accdet_dts_data.four_key.up_key_four) && (b >= accdet_dts_data.four_key.voice_key_four))
  573. return UP_KEY;
  574. else if ((b < accdet_dts_data.four_key.voice_key_four) && (b >= accdet_dts_data.four_key.mid_key_four))
  575. return AS_KEY;
  576. else if (b < accdet_dts_data.four_key.mid_key_four)
  577. return MD_KEY;
  578. ACCDET_DEBUG("[accdet] leave key_check!!\n");
  579. return NO_KEY;
  580. }
  581. #endif
  582. static void send_key_event(int keycode, int flag)
  583. {
  584. switch (keycode) {
  585. case DW_KEY:
  586. input_report_key(kpd_accdet_dev, KEY_VOLUMEDOWN, flag);
  587. input_sync(kpd_accdet_dev);
  588. ACCDET_DEBUG("[accdet]KEY_VOLUMEDOWN %d\n", flag);
  589. break;
  590. case UP_KEY:
  591. input_report_key(kpd_accdet_dev, KEY_VOLUMEUP, flag);
  592. input_sync(kpd_accdet_dev);
  593. ACCDET_DEBUG("[accdet]KEY_VOLUMEUP %d\n", flag);
  594. break;
  595. case MD_KEY:
  596. input_report_key(kpd_accdet_dev, KEY_PLAYPAUSE, flag);
  597. input_sync(kpd_accdet_dev);
  598. ACCDET_DEBUG("[accdet]KEY_PLAYPAUSE %d\n", flag);
  599. break;
  600. case AS_KEY:
  601. input_report_key(kpd_accdet_dev, KEY_VOICECOMMAND, flag);
  602. input_sync(kpd_accdet_dev);
  603. ACCDET_DEBUG("[accdet]KEY_VOICECOMMAND %d\n", flag);
  604. break;
  605. }
  606. }
  607. static void multi_key_detection(int current_status)
  608. {
  609. int m_key = 0;
  610. int cali_voltage = 0;
  611. if (0 == current_status) {
  612. cali_voltage = Accdet_PMIC_IMM_GetOneChannelValue(1);
  613. /*ACCDET_DEBUG("[Accdet]adc cali_voltage1 = %d mv\n", cali_voltage);*/
  614. m_key = cur_key = key_check(cali_voltage);
  615. }
  616. mdelay(30);
  617. #ifdef CONFIG_ACCDET_EINT_IRQ
  618. if (((pmic_pwrap_read(ACCDET_IRQ_STS) & EINT_IRQ_STATUS_BIT) != EINT_IRQ_STATUS_BIT) || eint_accdet_sync_flag) {
  619. #else /* ifdef CONFIG_ACCDET_EINT */
  620. if (((pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT) != IRQ_STATUS_BIT) || eint_accdet_sync_flag) {
  621. #endif
  622. send_key_event(cur_key, !current_status);
  623. } else {
  624. ACCDET_DEBUG("[Accdet]plug out side effect key press, do not report key = %d\n", cur_key);
  625. cur_key = NO_KEY;
  626. }
  627. if (current_status)
  628. cur_key = NO_KEY;
  629. }
  630. #endif
  631. static void accdet_workqueue_func(void)
  632. {
  633. int ret;
  634. ret = queue_work(accdet_workqueue, &accdet_work);
  635. if (!ret)
  636. ACCDET_DEBUG("[Accdet]accdet_work return:%d!\n", ret);
  637. }
  638. int accdet_irq_handler(void)
  639. {
  640. u64 cur_time = 0;
  641. cur_time = accdet_get_current_time();
  642. #ifdef CONFIG_ACCDET_EINT_IRQ
  643. ACCDET_DEBUG("[Accdet accdet_irq_handler]clear_accdet_eint_interrupt: ACCDET_IRQ_STS = 0x%x\n",
  644. pmic_pwrap_read(ACCDET_IRQ_STS));
  645. if ((pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT)
  646. && ((pmic_pwrap_read(ACCDET_IRQ_STS) & EINT_IRQ_STATUS_BIT) != EINT_IRQ_STATUS_BIT)) {
  647. clear_accdet_interrupt();
  648. if (accdet_status == MIC_BIAS) {
  649. /*accdet_auxadc_switch(1);*/
  650. pmic_pwrap_write(ACCDET_PWM_WIDTH, REGISTER_VALUE(cust_headset_settings->pwm_width));
  651. pmic_pwrap_write(ACCDET_PWM_THRESH, REGISTER_VALUE(cust_headset_settings->pwm_width));
  652. }
  653. accdet_workqueue_func();
  654. while (((pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT)
  655. && (accdet_timeout_ns(cur_time, ACCDET_TIME_OUT))))
  656. ;
  657. } else if ((pmic_pwrap_read(ACCDET_IRQ_STS) & EINT_IRQ_STATUS_BIT) == EINT_IRQ_STATUS_BIT) {
  658. if (cur_eint_state == EINT_PIN_PLUG_IN) {
  659. if (accdet_eint_type == IRQ_TYPE_LEVEL_HIGH)
  660. pmic_pwrap_write(ACCDET_IRQ_STS, pmic_pwrap_read(ACCDET_IRQ_STS) | EINT_IRQ_POL_HIGH);
  661. else
  662. pmic_pwrap_write(ACCDET_IRQ_STS, pmic_pwrap_read(ACCDET_IRQ_STS) & ~EINT_IRQ_POL_LOW);
  663. } else {
  664. if (accdet_eint_type == IRQ_TYPE_LEVEL_HIGH)
  665. pmic_pwrap_write(ACCDET_IRQ_STS, pmic_pwrap_read(ACCDET_IRQ_STS) & ~EINT_IRQ_POL_LOW);
  666. else
  667. pmic_pwrap_write(ACCDET_IRQ_STS, pmic_pwrap_read(ACCDET_IRQ_STS) | EINT_IRQ_POL_HIGH);
  668. }
  669. clear_accdet_eint_interrupt();
  670. while (((pmic_pwrap_read(ACCDET_IRQ_STS) & EINT_IRQ_STATUS_BIT)
  671. && (accdet_timeout_ns(cur_time, ACCDET_TIME_OUT))))
  672. ;
  673. accdet_eint_func(accdet_irq, NULL);
  674. } else {
  675. ACCDET_DEBUG("ACCDET IRQ and EINT IRQ don't be triggerred!!\n");
  676. }
  677. #else
  678. if ((pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT))
  679. clear_accdet_interrupt();
  680. if (accdet_status == MIC_BIAS) {
  681. /*accdet_auxadc_switch(1);*/
  682. pmic_pwrap_write(ACCDET_PWM_WIDTH, REGISTER_VALUE(cust_headset_settings->pwm_width));
  683. pmic_pwrap_write(ACCDET_PWM_THRESH, REGISTER_VALUE(cust_headset_settings->pwm_width));
  684. }
  685. accdet_workqueue_func();
  686. while (((pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT)
  687. && (accdet_timeout_ns(cur_time, ACCDET_TIME_OUT))))
  688. ;
  689. #endif
  690. #ifdef ACCDET_NEGV_IRQ
  691. cur_time = accdet_get_current_time();
  692. if ((pmic_pwrap_read(ACCDET_IRQ_STS) & NEGV_IRQ_STATUS_BIT) == NEGV_IRQ_STATUS_BIT) {
  693. ACCDET_DEBUG("[ACCDET NEGV detect]plug in a error Headset\n\r");
  694. pmic_pwrap_write(ACCDET_IRQ_STS, (IRQ_NEGV_CLR_BIT));
  695. while (((pmic_pwrap_read(ACCDET_IRQ_STS) & NEGV_IRQ_STATUS_BIT)
  696. && (accdet_timeout_ns(cur_time, ACCDET_TIME_OUT))))
  697. ;
  698. pmic_pwrap_write(ACCDET_IRQ_STS, (pmic_pwrap_read(ACCDET_IRQ_STS) & (~IRQ_NEGV_CLR_BIT)));
  699. }
  700. #endif
  701. return 1;
  702. }
  703. /*clear ACCDET IRQ in accdet register*/
  704. static inline void clear_accdet_interrupt(void)
  705. {
  706. /*it is safe by using polling to adjust when to clear IRQ_CLR_BIT*/
  707. pmic_pwrap_write(ACCDET_IRQ_STS, ((pmic_pwrap_read(ACCDET_IRQ_STS)) & 0x8000) | (IRQ_CLR_BIT));
  708. ACCDET_DEBUG("[Accdet]clear_accdet_interrupt: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));
  709. }
  710. static inline void clear_accdet_eint_interrupt(void)
  711. {
  712. pmic_pwrap_write(ACCDET_IRQ_STS, (((pmic_pwrap_read(ACCDET_IRQ_STS)) & 0x8000) | IRQ_EINT_CLR_BIT));
  713. ACCDET_DEBUG("[Accdet]clear_accdet_eint_interrupt: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));
  714. }
  715. static inline void check_cable_type(void)
  716. {
  717. int current_status = 0;
  718. int irq_temp = 0; /*for clear IRQ_bit*/
  719. int wait_clear_irq_times = 0;
  720. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  721. int pin_adc_value = 0;
  722. #define PIN_ADC_CHANNEL 5
  723. #endif
  724. current_status = ((pmic_pwrap_read(ACCDET_STATE_RG) & 0xc0) >> 6); /*A=bit1; B=bit0*/
  725. ACCDET_DEBUG("[Accdet]accdet interrupt happen:[%s]current AB = %d\n",
  726. accdet_status_string[accdet_status], current_status);
  727. button_status = 0;
  728. pre_status = accdet_status;
  729. /*ACCDET_DEBUG("[Accdet]check_cable_type: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));*/
  730. IRQ_CLR_FLAG = false;
  731. switch (accdet_status) {
  732. case PLUG_OUT:
  733. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  734. pmic_pwrap_write(ACCDET_DEBOUNCE1, cust_headset_settings->debounce1);
  735. #endif
  736. if (current_status == 0) {
  737. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  738. /*micbias always on during detected PIN recognition*/
  739. pmic_pwrap_write(ACCDET_PWM_WIDTH, cust_headset_settings->pwm_width);
  740. pmic_pwrap_write(ACCDET_PWM_THRESH, cust_headset_settings->pwm_width);
  741. ACCDET_DEBUG("[Accdet]PIN recognition micbias always on!\n");
  742. ACCDET_DEBUG("[Accdet]before adc read, pin_adc_value = %d mv!\n", pin_adc_value);
  743. msleep(500);
  744. current_status = ((pmic_pwrap_read(ACCDET_STATE_RG) & 0xc0) >> 6); /*A=bit1; B=bit0*/
  745. if (current_status == 0 && show_icon_delay != 0) {
  746. /*accdet_auxadc_switch(1);switch on when need to use auxadc read voltage*/
  747. pin_adc_value = Accdet_PMIC_IMM_GetOneChannelValue(1);
  748. ACCDET_DEBUG("[Accdet]pin_adc_value = %d mv!\n", pin_adc_value);
  749. /*accdet_auxadc_switch(0);*/
  750. if (180 > pin_adc_value && pin_adc_value > 90) { /*90mv ilegal headset*/
  751. /*mt_set_gpio_out(GPIO_CAMERA_2_CMRST_PIN, GPIO_OUT_ONE);*/
  752. /*ACCDET_DEBUG("[Accdet]PIN recognition change GPIO_OUT!\n");*/
  753. mutex_lock(&accdet_eint_irq_sync_mutex);
  754. if (1 == eint_accdet_sync_flag) {
  755. cable_type = HEADSET_NO_MIC;
  756. accdet_status = HOOK_SWITCH;
  757. cable_pin_recognition = 1;
  758. ACCDET_DEBUG("[Accdet] cable_pin_recognition = %d\n",
  759. cable_pin_recognition);
  760. } else {
  761. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  762. }
  763. mutex_unlock(&accdet_eint_irq_sync_mutex);
  764. } else {
  765. mutex_lock(&accdet_eint_irq_sync_mutex);
  766. if (1 == eint_accdet_sync_flag) {
  767. cable_type = HEADSET_NO_MIC;
  768. accdet_status = HOOK_SWITCH;
  769. } else {
  770. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  771. }
  772. mutex_unlock(&accdet_eint_irq_sync_mutex);
  773. }
  774. }
  775. #else
  776. mutex_lock(&accdet_eint_irq_sync_mutex);
  777. if (1 == eint_accdet_sync_flag) {
  778. cable_type = HEADSET_NO_MIC;
  779. accdet_status = HOOK_SWITCH;
  780. } else {
  781. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  782. }
  783. mutex_unlock(&accdet_eint_irq_sync_mutex);
  784. #endif
  785. } else if (current_status == 1) {
  786. mutex_lock(&accdet_eint_irq_sync_mutex);
  787. if (1 == eint_accdet_sync_flag) {
  788. accdet_status = MIC_BIAS;
  789. cable_type = HEADSET_MIC;
  790. /*AB=11 debounce=30ms*/
  791. pmic_pwrap_write(ACCDET_DEBOUNCE3, cust_headset_settings->debounce3 * 30);
  792. } else {
  793. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  794. }
  795. mutex_unlock(&accdet_eint_irq_sync_mutex);
  796. pmic_pwrap_write(ACCDET_DEBOUNCE0, button_press_debounce);
  797. /*recover polling set AB 00-01*/
  798. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  799. pmic_pwrap_write(ACCDET_PWM_WIDTH, REGISTER_VALUE(cust_headset_settings->pwm_width));
  800. pmic_pwrap_write(ACCDET_PWM_THRESH, REGISTER_VALUE(cust_headset_settings->pwm_thresh));
  801. #endif
  802. } else if (current_status == 3) {
  803. ACCDET_DEBUG("[Accdet]PLUG_OUT state not change!\n");
  804. #ifdef CONFIG_ACCDET_EINT
  805. ACCDET_DEBUG("[Accdet] do not send plug out event in plug out\n");
  806. #else
  807. mutex_lock(&accdet_eint_irq_sync_mutex);
  808. if (1 == eint_accdet_sync_flag) {
  809. accdet_status = PLUG_OUT;
  810. cable_type = NO_DEVICE;
  811. } else {
  812. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  813. }
  814. mutex_unlock(&accdet_eint_irq_sync_mutex);
  815. #endif
  816. } else {
  817. ACCDET_DEBUG("[Accdet]PLUG_OUT can't change to this state!\n");
  818. }
  819. break;
  820. case MIC_BIAS:
  821. /*solution: resume hook switch debounce time*/
  822. pmic_pwrap_write(ACCDET_DEBOUNCE0, cust_headset_settings->debounce0);
  823. if (current_status == 0) {
  824. mutex_lock(&accdet_eint_irq_sync_mutex);
  825. if (1 == eint_accdet_sync_flag) {
  826. while ((pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT)
  827. && (wait_clear_irq_times < 3)) {
  828. ACCDET_DEBUG("[Accdet]check_cable_type: MIC BIAS clear IRQ on-going1....\n");
  829. wait_clear_irq_times++;
  830. msleep(20);
  831. }
  832. irq_temp = pmic_pwrap_read(ACCDET_IRQ_STS);
  833. irq_temp = irq_temp & (~IRQ_CLR_BIT);
  834. pmic_pwrap_write(ACCDET_IRQ_STS, irq_temp);
  835. IRQ_CLR_FLAG = true;
  836. accdet_status = HOOK_SWITCH;
  837. } else {
  838. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  839. }
  840. mutex_unlock(&accdet_eint_irq_sync_mutex);
  841. button_status = 1;
  842. if (button_status) {
  843. mutex_lock(&accdet_eint_irq_sync_mutex);
  844. if (1 == eint_accdet_sync_flag)
  845. multi_key_detection(current_status);
  846. else
  847. ACCDET_DEBUG("[Accdet] multi_key_detection: Headset has plugged out\n");
  848. mutex_unlock(&accdet_eint_irq_sync_mutex);
  849. /*accdet_auxadc_switch(0);*/
  850. /*recover pwm frequency and duty*/
  851. pmic_pwrap_write(ACCDET_PWM_WIDTH, REGISTER_VALUE(cust_headset_settings->pwm_width));
  852. pmic_pwrap_write(ACCDET_PWM_THRESH, REGISTER_VALUE(cust_headset_settings->pwm_thresh));
  853. }
  854. } else if (current_status == 1) {
  855. mutex_lock(&accdet_eint_irq_sync_mutex);
  856. if (1 == eint_accdet_sync_flag) {
  857. accdet_status = MIC_BIAS;
  858. cable_type = HEADSET_MIC;
  859. ACCDET_DEBUG("[Accdet]MIC_BIAS state not change!\n");
  860. } else {
  861. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  862. }
  863. mutex_unlock(&accdet_eint_irq_sync_mutex);
  864. } else if (current_status == 3) {
  865. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  866. ACCDET_DEBUG("[Accdet]do not send plug ou in micbiast\n");
  867. mutex_lock(&accdet_eint_irq_sync_mutex);
  868. if (1 == eint_accdet_sync_flag)
  869. accdet_status = PLUG_OUT;
  870. else
  871. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  872. mutex_unlock(&accdet_eint_irq_sync_mutex);
  873. #else
  874. mutex_lock(&accdet_eint_irq_sync_mutex);
  875. if (1 == eint_accdet_sync_flag) {
  876. accdet_status = PLUG_OUT;
  877. cable_type = NO_DEVICE;
  878. } else {
  879. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  880. }
  881. mutex_unlock(&accdet_eint_irq_sync_mutex);
  882. #endif
  883. } else {
  884. ACCDET_DEBUG("[Accdet]MIC_BIAS can't change to this state!\n");
  885. }
  886. break;
  887. case HOOK_SWITCH:
  888. if (current_status == 0) {
  889. mutex_lock(&accdet_eint_irq_sync_mutex);
  890. if (1 == eint_accdet_sync_flag) {
  891. /*for avoid 01->00 framework of Headset will report press key info for Audio*/
  892. /*cable_type = HEADSET_NO_MIC;*/
  893. /*accdet_status = HOOK_SWITCH;*/
  894. ACCDET_DEBUG("[Accdet]HOOK_SWITCH state not change!\n");
  895. } else {
  896. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  897. }
  898. mutex_unlock(&accdet_eint_irq_sync_mutex);
  899. } else if (current_status == 1) {
  900. mutex_lock(&accdet_eint_irq_sync_mutex);
  901. if (1 == eint_accdet_sync_flag) {
  902. multi_key_detection(current_status);
  903. accdet_status = MIC_BIAS;
  904. cable_type = HEADSET_MIC;
  905. } else {
  906. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  907. }
  908. mutex_unlock(&accdet_eint_irq_sync_mutex);
  909. /*accdet_auxadc_switch(0);*/
  910. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  911. cable_pin_recognition = 0;
  912. ACCDET_DEBUG("[Accdet] cable_pin_recognition = %d\n", cable_pin_recognition);
  913. pmic_pwrap_write(ACCDET_PWM_WIDTH, REGISTER_VALUE(cust_headset_settings->pwm_width));
  914. pmic_pwrap_write(ACCDET_PWM_THRESH, REGISTER_VALUE(cust_headset_settings->pwm_thresh));
  915. #endif
  916. /*solution: reduce hook switch debounce time to 0x400*/
  917. pmic_pwrap_write(ACCDET_DEBOUNCE0, button_press_debounce);
  918. } else if (current_status == 3) {
  919. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  920. cable_pin_recognition = 0;
  921. ACCDET_DEBUG("[Accdet] cable_pin_recognition = %d\n", cable_pin_recognition);
  922. mutex_lock(&accdet_eint_irq_sync_mutex);
  923. if (1 == eint_accdet_sync_flag)
  924. accdet_status = PLUG_OUT;
  925. else
  926. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  927. mutex_unlock(&accdet_eint_irq_sync_mutex);
  928. #endif
  929. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  930. ACCDET_DEBUG("[Accdet] do not send plug out event in hook switch\n");
  931. mutex_lock(&accdet_eint_irq_sync_mutex);
  932. if (1 == eint_accdet_sync_flag)
  933. accdet_status = PLUG_OUT;
  934. else
  935. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  936. mutex_unlock(&accdet_eint_irq_sync_mutex);
  937. #else
  938. mutex_lock(&accdet_eint_irq_sync_mutex);
  939. if (1 == eint_accdet_sync_flag) {
  940. accdet_status = PLUG_OUT;
  941. cable_type = NO_DEVICE;
  942. } else {
  943. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  944. }
  945. mutex_unlock(&accdet_eint_irq_sync_mutex);
  946. #endif
  947. } else {
  948. ACCDET_DEBUG("[Accdet]HOOK_SWITCH can't change to this state!\n");
  949. }
  950. break;
  951. case STAND_BY:
  952. if (current_status == 3) {
  953. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  954. ACCDET_DEBUG("[Accdet]accdet do not send plug out event in stand by!\n");
  955. #else
  956. mutex_lock(&accdet_eint_irq_sync_mutex);
  957. if (1 == eint_accdet_sync_flag) {
  958. accdet_status = PLUG_OUT;
  959. cable_type = NO_DEVICE;
  960. } else {
  961. ACCDET_DEBUG("[Accdet] Headset has plugged out\n");
  962. }
  963. mutex_unlock(&accdet_eint_irq_sync_mutex);
  964. #endif
  965. } else {
  966. ACCDET_DEBUG("[Accdet]STAND_BY can't change to this state!\n");
  967. }
  968. break;
  969. default:
  970. ACCDET_DEBUG("[Accdet]check_cable_type: accdet current status error!\n");
  971. break;
  972. }
  973. if (!IRQ_CLR_FLAG) {
  974. mutex_lock(&accdet_eint_irq_sync_mutex);
  975. if (1 == eint_accdet_sync_flag) {
  976. while ((pmic_pwrap_read(ACCDET_IRQ_STS) & IRQ_STATUS_BIT) && (wait_clear_irq_times < 3)) {
  977. ACCDET_DEBUG("[Accdet]check_cable_type: Clear interrupt on-going2....\n");
  978. wait_clear_irq_times++;
  979. msleep(20);
  980. }
  981. }
  982. irq_temp = pmic_pwrap_read(ACCDET_IRQ_STS);
  983. irq_temp = irq_temp & (~IRQ_CLR_BIT);
  984. pmic_pwrap_write(ACCDET_IRQ_STS, irq_temp);
  985. mutex_unlock(&accdet_eint_irq_sync_mutex);
  986. IRQ_CLR_FLAG = true;
  987. ACCDET_DEBUG("[Accdet]check_cable_type:Clear interrupt:Done[0x%x]!\n", pmic_pwrap_read(ACCDET_IRQ_STS));
  988. } else {
  989. IRQ_CLR_FLAG = false;
  990. }
  991. ACCDET_DEBUG("[Accdet]cable type:[%s], status switch:[%s]->[%s]\n",
  992. accdet_report_string[cable_type], accdet_status_string[pre_status],
  993. accdet_status_string[accdet_status]);
  994. }
  995. static void accdet_work_callback(struct work_struct *work)
  996. {
  997. wake_lock(&accdet_irq_lock);
  998. check_cable_type();
  999. #ifdef CONFIG_ACCDET_PIN_SWAP
  1000. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  1001. if (cable_pin_recognition == 1) {
  1002. cable_pin_recognition = 0;
  1003. accdet_FSA8049_disable();
  1004. cable_type = HEADSET_NO_MIC;
  1005. accdet_status = PLUG_OUT;
  1006. }
  1007. #endif
  1008. #endif
  1009. mutex_lock(&accdet_eint_irq_sync_mutex);
  1010. if (1 == eint_accdet_sync_flag)
  1011. switch_set_state((struct switch_dev *)&accdet_data, cable_type);
  1012. else
  1013. ACCDET_DEBUG("[Accdet] Headset has plugged out don't set accdet state\n");
  1014. mutex_unlock(&accdet_eint_irq_sync_mutex);
  1015. ACCDET_DEBUG(" [accdet] set state in cable_type status\n");
  1016. wake_unlock(&accdet_irq_lock);
  1017. }
  1018. void accdet_get_dts_data(void)
  1019. {
  1020. struct device_node *node = NULL;
  1021. int debounce[7];
  1022. #ifdef CONFIG_FOUR_KEY_HEADSET
  1023. int four_key[5];
  1024. #else
  1025. int three_key[4];
  1026. #endif
  1027. ACCDET_INFO("[ACCDET]Start accdet_get_dts_data");
  1028. node = of_find_matching_node(node, accdet_of_match);
  1029. if (node) {
  1030. of_property_read_u32_array(node, "headset-mode-setting", debounce, ARRAY_SIZE(debounce));
  1031. of_property_read_u32(node, "accdet-mic-vol", &accdet_dts_data.mic_mode_vol);
  1032. of_property_read_u32(node, "accdet-plugout-debounce", &accdet_dts_data.accdet_plugout_debounce);
  1033. of_property_read_u32(node, "accdet-mic-mode", &accdet_dts_data.accdet_mic_mode);
  1034. #ifdef CONFIG_FOUR_KEY_HEADSET
  1035. of_property_read_u32_array(node, "headset-four-key-threshold", four_key, ARRAY_SIZE(four_key));
  1036. memcpy(&accdet_dts_data.four_key, four_key+1, sizeof(struct four_key_threshold));
  1037. ACCDET_INFO("[Accdet]mid-Key = %d, voice = %d, up_key = %d, down_key = %d\n",
  1038. accdet_dts_data.four_key.mid_key_four, accdet_dts_data.four_key.voice_key_four,
  1039. accdet_dts_data.four_key.up_key_four, accdet_dts_data.four_key.down_key_four);
  1040. #else
  1041. of_property_read_u32_array(node, "headset-three-key-threshold", three_key, ARRAY_SIZE(three_key));
  1042. memcpy(&accdet_dts_data.three_key, three_key+1, sizeof(struct three_key_threshold));
  1043. ACCDET_INFO("[Accdet]mid-Key = %d, up_key = %d, down_key = %d\n",
  1044. accdet_dts_data.three_key.mid_key, accdet_dts_data.three_key.up_key,
  1045. accdet_dts_data.three_key.down_key);
  1046. #endif
  1047. memcpy(&accdet_dts_data.headset_debounce, debounce, sizeof(debounce));
  1048. cust_headset_settings = &accdet_dts_data.headset_debounce;
  1049. ACCDET_INFO("[Accdet]pwm_width = %x, pwm_thresh = %x\n deb0 = %x, deb1 = %x, mic_mode = %d\n",
  1050. cust_headset_settings->pwm_width, cust_headset_settings->pwm_thresh,
  1051. cust_headset_settings->debounce0, cust_headset_settings->debounce1,
  1052. accdet_dts_data.accdet_mic_mode);
  1053. } else {
  1054. ACCDET_ERROR("[Accdet]%s can't find compatible dts node\n", __func__);
  1055. }
  1056. }
  1057. void accdet_pmic_Read_Efuse_HPOffset(void)
  1058. {
  1059. s16 efusevalue;
  1060. efusevalue = (s16) pmic_Read_Efuse_HPOffset(0x10);
  1061. accdet_auxadc_offset = (efusevalue >> 8) & 0xFF;
  1062. accdet_auxadc_offset = (accdet_auxadc_offset / 2);
  1063. ACCDET_INFO(" efusevalue = 0x%x, accdet_auxadc_offset = %d\n", efusevalue, accdet_auxadc_offset);
  1064. }
  1065. static inline void accdet_init(void)
  1066. {
  1067. ACCDET_DEBUG("[Accdet]accdet hardware init\n");
  1068. /*clock*/
  1069. pmic_pwrap_write(TOP_CKPDN_CLR, RG_ACCDET_CLK_CLR);
  1070. /*ACCDET_DEBUG("[Accdet]accdet TOP_CKPDN=0x%x!\n", pmic_pwrap_read(TOP_CKPDN)); */
  1071. /*reset the accdet unit*/
  1072. /*ACCDET_DEBUG("ACCDET reset : reset start!\n\r");*/
  1073. pmic_pwrap_write(TOP_RST_ACCDET_SET, ACCDET_RESET_SET);
  1074. /*ACCDET_DEBUG("ACCDET reset function test: reset finished!!\n\r");*/
  1075. pmic_pwrap_write(TOP_RST_ACCDET_CLR, ACCDET_RESET_CLR);
  1076. /*init pwm frequency and duty*/
  1077. pmic_pwrap_write(ACCDET_PWM_WIDTH, REGISTER_VALUE(cust_headset_settings->pwm_width));
  1078. pmic_pwrap_write(ACCDET_PWM_THRESH, REGISTER_VALUE(cust_headset_settings->pwm_thresh));
  1079. pmic_pwrap_write(ACCDET_STATE_SWCTRL, 0x07);
  1080. /*rise and fall delay of PWM*/
  1081. pmic_pwrap_write(ACCDET_EN_DELAY_NUM,
  1082. (cust_headset_settings->fall_delay << 15 | cust_headset_settings->rise_delay));
  1083. /* init the debounce time*/
  1084. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  1085. pmic_pwrap_write(ACCDET_DEBOUNCE0, cust_headset_settings->debounce0);
  1086. pmic_pwrap_write(ACCDET_DEBOUNCE1, 0xFFFF); /*2.0s*/
  1087. pmic_pwrap_write(ACCDET_DEBOUNCE3, cust_headset_settings->debounce3);
  1088. pmic_pwrap_write(ACCDET_DEBOUNCE4, ACCDET_DE4);
  1089. #else
  1090. pmic_pwrap_write(ACCDET_DEBOUNCE0, cust_headset_settings->debounce0);
  1091. pmic_pwrap_write(ACCDET_DEBOUNCE1, cust_headset_settings->debounce1);
  1092. pmic_pwrap_write(ACCDET_DEBOUNCE3, cust_headset_settings->debounce3);
  1093. pmic_pwrap_write(ACCDET_DEBOUNCE4, ACCDET_DE4);
  1094. #endif
  1095. /*enable INT */
  1096. #ifdef CONFIG_ACCDET_EINT_IRQ
  1097. pmic_pwrap_write(ACCDET_IRQ_STS, pmic_pwrap_read(ACCDET_IRQ_STS) & (~IRQ_EINT_CLR_BIT));
  1098. #endif
  1099. #ifdef CONFIG_ACCDET_EINT
  1100. pmic_pwrap_write(ACCDET_IRQ_STS, pmic_pwrap_read(ACCDET_IRQ_STS) & (~IRQ_CLR_BIT));
  1101. #endif
  1102. pmic_pwrap_write(INT_CON_ACCDET_SET, RG_ACCDET_IRQ_SET);
  1103. #ifdef CONFIG_ACCDET_EINT_IRQ
  1104. pmic_pwrap_write(INT_CON_ACCDET_SET, RG_ACCDET_EINT_IRQ_SET);
  1105. #endif
  1106. #ifdef ACCDET_NEGV_IRQ
  1107. pmic_pwrap_write(INT_CON_ACCDET_SET, RG_ACCDET_NEGV_IRQ_SET);
  1108. #endif
  1109. /*********************ACCDET Analog Setting***********************************************************/
  1110. pmic_set_register_value(PMIC_RG_AUDMICBIASVREF, accdet_dts_data.mic_mode_vol);
  1111. pmic_pwrap_write(ACCDET_RSV, 0x1290); /*TODO: need confirm pull low,6328 bit[12]=1*/
  1112. #ifdef CONFIG_ACCDET_EINT_IRQ
  1113. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) | ACCDET_EINT_CON_EN);
  1114. #endif
  1115. #ifdef ACCDET_NEGV_IRQ
  1116. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) | ACCDET_NEGV_DT_EN);
  1117. #endif
  1118. if (accdet_dts_data.accdet_mic_mode == 1) /* ACC mode*/
  1119. pmic_set_register_value(PMIC_RG_AUDMICBIAS1DCSWPEN, 0);
  1120. else if (accdet_dts_data.accdet_mic_mode == 2) /* Low cost mode without internal bias*/
  1121. pmic_pwrap_write(ACCDET_RSV, pmic_pwrap_read(ACCDET_RSV) | ACCDET_INPUT_MICP);
  1122. else if (accdet_dts_data.accdet_mic_mode == 6) {/* Low cost mode with internal bias*/
  1123. pmic_pwrap_write(ACCDET_RSV, pmic_pwrap_read(ACCDET_RSV) | ACCDET_INPUT_MICP);
  1124. pmic_set_register_value(PMIC_RG_AUDMICBIAS1DCSWPEN, 1); /*switch P internal*/
  1125. }
  1126. /**************************************************************************************************/
  1127. #if defined CONFIG_ACCDET_EINT
  1128. /* disable ACCDET unit*/
  1129. pre_state_swctrl = pmic_pwrap_read(ACCDET_STATE_SWCTRL);
  1130. pmic_pwrap_write(ACCDET_CTRL, ACCDET_DISABLE);
  1131. pmic_pwrap_write(ACCDET_STATE_SWCTRL, 0x0);
  1132. pmic_pwrap_write(TOP_CKPDN_SET, RG_ACCDET_CLK_SET);
  1133. #elif defined CONFIG_ACCDET_EINT_IRQ
  1134. if (cur_eint_state == EINT_PIN_PLUG_OUT)
  1135. pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) | EINT_IRQ_DE_IN);/*debounce=256ms*/
  1136. pmic_pwrap_write(ACCDET_EINT_CTL, pmic_pwrap_read(ACCDET_EINT_CTL) | EINT_PWM_THRESH);
  1137. /* disable ACCDET unit, except CLK of ACCDET*/
  1138. pre_state_swctrl = pmic_pwrap_read(ACCDET_STATE_SWCTRL);
  1139. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) | ACCDET_DISABLE);
  1140. pmic_pwrap_write(ACCDET_STATE_SWCTRL, pmic_pwrap_read(ACCDET_STATE_SWCTRL) & (~ACCDET_SWCTRL_EN));
  1141. pmic_pwrap_write(ACCDET_STATE_SWCTRL, pmic_pwrap_read(ACCDET_STATE_SWCTRL) | ACCDET_EINT_PWM_EN);
  1142. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) | ACCDET_EINT_EN);
  1143. #else
  1144. /* enable ACCDET unit*/
  1145. pmic_pwrap_write(ACCDET_CTRL, ACCDET_ENABLE);
  1146. #endif
  1147. #ifdef ACCDET_NEGV_IRQ
  1148. pmic_pwrap_write(ACCDET_EINT_PWM_DELAY, pmic_pwrap_read(ACCDET_EINT_PWM_DELAY) & (~0x1F));
  1149. pmic_pwrap_write(ACCDET_EINT_PWM_DELAY, pmic_pwrap_read(ACCDET_EINT_PWM_DELAY) | 0x0F);
  1150. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) | ACCDET_NEGV_EN);
  1151. #endif
  1152. /**************************************AUXADC enable auto sample****************************************/
  1153. pmic_pwrap_write(ACCDET_AUXADC_AUTO_SPL, (pmic_pwrap_read(ACCDET_AUXADC_AUTO_SPL) | ACCDET_AUXADC_AUTO_SET));
  1154. }
  1155. /*-----------------------------------sysfs-----------------------------------------*/
  1156. #if DEBUG_THREAD
  1157. static int dump_register(void)
  1158. {
  1159. int i = 0;
  1160. for (i = ACCDET_RSV; i <= ACCDET_RSV_CON1; i += 2)
  1161. ACCDET_DEBUG(" ACCDET_BASE + %x=%x\n", i, pmic_pwrap_read(ACCDET_BASE + i));
  1162. ACCDET_DEBUG(" TOP_RST_ACCDET(0x%x) =%x\n", TOP_RST_ACCDET, pmic_pwrap_read(TOP_RST_ACCDET));
  1163. ACCDET_DEBUG(" INT_CON_ACCDET(0x%x) =%x\n", INT_CON_ACCDET, pmic_pwrap_read(INT_CON_ACCDET));
  1164. ACCDET_DEBUG(" TOP_CKPDN(0x%x) =%x\n", TOP_CKPDN, pmic_pwrap_read(TOP_CKPDN));
  1165. ACCDET_DEBUG(" ACCDET_ADC_REG(0x%x) =%x\n", ACCDET_ADC_REG, pmic_pwrap_read(ACCDET_ADC_REG));
  1166. #ifdef CONFIG_ACCDET_PIN_SWAP
  1167. /*ACCDET_DEBUG(" 0x00004000 =%x\n",pmic_pwrap_read(0x00004000));*/
  1168. /*VRF28 power for PIN swap feature*/
  1169. #endif
  1170. return 0;
  1171. }
  1172. #if defined(CONFIG_TS3A225E_ACCDET)
  1173. static ssize_t show_TS3A225EConnectorType(struct device_driver *ddri, char *buf)
  1174. {
  1175. ACCDET_DEBUG("[Accdet] TS3A225E ts3a225e_connector_type=%d\n", ts3a225e_connector_type);
  1176. return sprintf(buf, "%u\n", ts3a225e_connector_type);
  1177. }
  1178. static DRIVER_ATTR(TS3A225EConnectorType, 0664, show_TS3A225EConnectorType, NULL);
  1179. #endif
  1180. static ssize_t accdet_store_call_state(struct device_driver *ddri, const char *buf, size_t count)
  1181. {
  1182. int ret = 0;
  1183. int value = 0;
  1184. if (buf == NULL) {
  1185. ACCDET_INFO("[%s] Invalid input!!\n", __func__);
  1186. return 0;
  1187. }
  1188. ret = kstrtoint(buf, sizeof(int), &value);
  1189. if (ret < 0) {
  1190. ACCDET_INFO("accdet: Invalid values\n");
  1191. return 0;
  1192. }
  1193. call_status = (char)value;
  1194. switch (call_status) {
  1195. case CALL_IDLE:
  1196. ACCDET_DEBUG("[Accdet]accdet call: Idle state!\n");
  1197. break;
  1198. case CALL_RINGING:
  1199. ACCDET_DEBUG("[Accdet]accdet call: ringing state!\n");
  1200. break;
  1201. case CALL_ACTIVE:
  1202. ACCDET_DEBUG("[Accdet]accdet call: active or hold state!\n");
  1203. ACCDET_DEBUG("[Accdet]accdet_ioctl : Button_Status=%d (state:%d)\n", button_status, accdet_data.state);
  1204. /*return button_status;*/
  1205. break;
  1206. default:
  1207. ACCDET_DEBUG("[Accdet]accdet call : Invalid values\n");
  1208. break;
  1209. }
  1210. return count;
  1211. }
  1212. static ssize_t show_pin_recognition_state(struct device_driver *ddri, char *buf)
  1213. {
  1214. if (buf == NULL) {
  1215. ACCDET_INFO("[%s] Invalid input!!\n", __func__);
  1216. return 0;
  1217. }
  1218. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  1219. ACCDET_DEBUG("ACCDET show_pin_recognition_state = %d\n", cable_pin_recognition);
  1220. return snprintf(buf, (size_t)sizeof(cable_pin_recognition), "%u\n", cable_pin_recognition);
  1221. #else
  1222. return snprintf(buf, 4, "%u\n", 0);
  1223. #endif
  1224. }
  1225. static DRIVER_ATTR(accdet_pin_recognition, 0664, show_pin_recognition_state, NULL);
  1226. static DRIVER_ATTR(accdet_call_state, 0664, NULL, accdet_store_call_state);
  1227. static int g_start_debug_thread;
  1228. static struct task_struct *thread;
  1229. static int g_dump_register;
  1230. static int dbug_thread(void *unused)
  1231. {
  1232. while (g_start_debug_thread) {
  1233. if (g_dump_register) {
  1234. dump_register();
  1235. /*dump_pmic_register();*/
  1236. }
  1237. msleep(500);
  1238. }
  1239. return 0;
  1240. }
  1241. static ssize_t store_accdet_start_debug_thread(struct device_driver *ddri, const char *buf, size_t count)
  1242. {
  1243. int ret = 0;
  1244. int error = 0;
  1245. int start_flag = 0;
  1246. if (buf == NULL) {
  1247. ACCDET_INFO("[%s] Invalid input!!\n", __func__);
  1248. return 0;
  1249. }
  1250. ret = kstrtoint(buf, sizeof(int), &start_flag);
  1251. if (ret != 0) {
  1252. ACCDET_DEBUG("accdet: Invalid values\n");
  1253. return 0;
  1254. }
  1255. if (start_flag) {/* if write 0, Invalid; otherwise, valid */
  1256. g_start_debug_thread = 1;
  1257. thread = kthread_run(dbug_thread, 0, "ACCDET");
  1258. if (IS_ERR(thread)) {
  1259. error = PTR_ERR(thread);
  1260. ACCDET_DEBUG("[store_accdet_start_debug_thread] failed to create kernel thread: %d\n", error);
  1261. } else {
  1262. ACCDET_INFO("[store_accdet_start_debug_thread] start debug thread!\n");
  1263. }
  1264. } else {
  1265. g_start_debug_thread = 0;
  1266. ACCDET_INFO("[store_accdet_start_debug_thread] stop debug thread!\n");
  1267. }
  1268. return count;
  1269. }
  1270. static ssize_t store_accdet_set_headset_mode(struct device_driver *ddri, const char *buf, size_t count)
  1271. {
  1272. ACCDET_INFO("[%s] Not Support\n", __func__);
  1273. return count;
  1274. }
  1275. static ssize_t store_accdet_dump_register(struct device_driver *ddri, const char *buf, size_t count)
  1276. {
  1277. int ret = 0;
  1278. int value = 0;
  1279. if (buf == NULL) {
  1280. ACCDET_INFO("[%s] Invalid input!!\n", __func__);
  1281. return 0;
  1282. }
  1283. /* if write 0, Invalid; otherwise, valid */
  1284. ret = kstrtoint(buf, sizeof(int), &value);
  1285. if (ret != 0) {
  1286. ACCDET_DEBUG("accdet: Invalid values\n");
  1287. return 0;
  1288. }
  1289. g_dump_register = value;
  1290. ACCDET_INFO("[store_accdet_dump_register] start flag:%d\n", g_dump_register);
  1291. return count;
  1292. }
  1293. /*----------------------------------------------------------------------------*/
  1294. static DRIVER_ATTR(dump_register, S_IWUSR | S_IRUGO, NULL, store_accdet_dump_register);
  1295. static DRIVER_ATTR(set_headset_mode, S_IWUSR | S_IRUGO, NULL, store_accdet_set_headset_mode);
  1296. static DRIVER_ATTR(start_debug, S_IWUSR | S_IRUGO, NULL, store_accdet_start_debug_thread);
  1297. /*----------------------------------------------------------------------------*/
  1298. static struct driver_attribute *accdet_attr_list[] = {
  1299. &driver_attr_start_debug,
  1300. &driver_attr_set_headset_mode,
  1301. &driver_attr_dump_register,
  1302. &driver_attr_accdet_call_state,
  1303. /*#ifdef CONFIG_ACCDET_PIN_RECOGNIZATION*/
  1304. &driver_attr_accdet_pin_recognition,
  1305. /*#endif*/
  1306. #if defined(CONFIG_TS3A225E_ACCDET)
  1307. &driver_attr_TS3A225EConnectorType,
  1308. #endif
  1309. };
  1310. static int accdet_create_attr(struct device_driver *driver)
  1311. {
  1312. int idx, err = 0;
  1313. int num = (int)(sizeof(accdet_attr_list) / sizeof(accdet_attr_list[0]));
  1314. if (driver == NULL)
  1315. return -EINVAL;
  1316. for (idx = 0; idx < num; idx++) {
  1317. err = driver_create_file(driver, accdet_attr_list[idx]);
  1318. if (err) {
  1319. ACCDET_DEBUG("driver_create_file (%s) = %d\n", accdet_attr_list[idx]->attr.name, err);
  1320. break;
  1321. }
  1322. }
  1323. return err;
  1324. }
  1325. #endif
  1326. void accdet_int_handler(void)
  1327. {
  1328. int ret = 0;
  1329. ACCDET_DEBUG("[accdet_int_handler]....\n");
  1330. ret = accdet_irq_handler();
  1331. if (0 == ret)
  1332. ACCDET_DEBUG("[accdet_int_handler] don't finished\n");
  1333. }
  1334. void accdet_eint_int_handler(void)
  1335. {
  1336. int ret = 0;
  1337. ACCDET_DEBUG("[accdet_eint_int_handler]....\n");
  1338. ret = accdet_irq_handler();
  1339. if (0 == ret)
  1340. ACCDET_DEBUG("[accdet_int_handler] don't finished\n");
  1341. }
  1342. int mt_accdet_probe(struct platform_device *dev)
  1343. {
  1344. int ret = 0;
  1345. #if DEBUG_THREAD
  1346. struct platform_driver accdet_driver_hal = accdet_driver_func();
  1347. #endif
  1348. #if defined(CONFIG_TS3A225E_ACCDET)
  1349. if (ts3a225e_i2c_client == NULL) {
  1350. ACCDET_DEBUG("[Accdet]ts3a225e_i2c_client is NULL!\n");
  1351. return -EPROBE_DEFER;
  1352. }
  1353. #endif
  1354. ACCDET_INFO("[Accdet]accdet_probe begin!\n");
  1355. /*--------------------------------------------------------------------
  1356. // below register accdet as switch class
  1357. //------------------------------------------------------------------*/
  1358. accdet_data.name = "h2w";
  1359. accdet_data.index = 0;
  1360. accdet_data.state = NO_DEVICE;
  1361. ret = switch_dev_register(&accdet_data);
  1362. if (ret) {
  1363. ACCDET_ERROR("[Accdet]switch_dev_register returned:%d!\n", ret);
  1364. return 1;
  1365. }
  1366. /*----------------------------------------------------------------------
  1367. // Create normal device for auido use
  1368. //--------------------------------------------------------------------*/
  1369. ret = alloc_chrdev_region(&accdet_devno, 0, 1, ACCDET_DEVNAME);
  1370. if (ret)
  1371. ACCDET_ERROR("[Accdet]alloc_chrdev_region: Get Major number error!\n");
  1372. accdet_cdev = cdev_alloc();
  1373. accdet_cdev->owner = THIS_MODULE;
  1374. accdet_cdev->ops = accdet_get_fops();
  1375. ret = cdev_add(accdet_cdev, accdet_devno, 1);
  1376. if (ret)
  1377. ACCDET_ERROR("[Accdet]accdet error: cdev_add\n");
  1378. accdet_class = class_create(THIS_MODULE, ACCDET_DEVNAME);
  1379. /* if we want auto creat device node, we must call this*/
  1380. accdet_nor_device = device_create(accdet_class, NULL, accdet_devno, NULL, ACCDET_DEVNAME);
  1381. /*--------------------------------------------------------------------
  1382. // Create input device
  1383. //------------------------------------------------------------------*/
  1384. kpd_accdet_dev = input_allocate_device();
  1385. if (!kpd_accdet_dev) {
  1386. ACCDET_ERROR("[Accdet]kpd_accdet_dev : fail!\n");
  1387. return -ENOMEM;
  1388. }
  1389. /*INIT the timer to disable micbias.*/
  1390. init_timer(&micbias_timer);
  1391. micbias_timer.expires = jiffies + MICBIAS_DISABLE_TIMER;
  1392. micbias_timer.function = &disable_micbias;
  1393. micbias_timer.data = ((unsigned long)0);
  1394. /*define multi-key keycode*/
  1395. __set_bit(EV_KEY, kpd_accdet_dev->evbit);
  1396. __set_bit(KEY_PLAYPAUSE, kpd_accdet_dev->keybit);
  1397. __set_bit(KEY_VOLUMEDOWN, kpd_accdet_dev->keybit);
  1398. __set_bit(KEY_VOLUMEUP, kpd_accdet_dev->keybit);
  1399. __set_bit(KEY_VOICECOMMAND, kpd_accdet_dev->keybit);
  1400. kpd_accdet_dev->id.bustype = BUS_HOST;
  1401. kpd_accdet_dev->name = "ACCDET";
  1402. if (input_register_device(kpd_accdet_dev))
  1403. ACCDET_ERROR("[Accdet]kpd_accdet_dev register : fail!\n");
  1404. /*------------------------------------------------------------------
  1405. // Create workqueue
  1406. //------------------------------------------------------------------ */
  1407. accdet_workqueue = create_singlethread_workqueue("accdet");
  1408. INIT_WORK(&accdet_work, accdet_work_callback);
  1409. /*------------------------------------------------------------------
  1410. // wake lock
  1411. //------------------------------------------------------------------*/
  1412. wake_lock_init(&accdet_suspend_lock, WAKE_LOCK_SUSPEND, "accdet wakelock");
  1413. wake_lock_init(&accdet_irq_lock, WAKE_LOCK_SUSPEND, "accdet irq wakelock");
  1414. wake_lock_init(&accdet_key_lock, WAKE_LOCK_SUSPEND, "accdet key wakelock");
  1415. wake_lock_init(&accdet_timer_lock, WAKE_LOCK_SUSPEND, "accdet timer wakelock");
  1416. #if DEBUG_THREAD
  1417. ret = accdet_create_attr(&accdet_driver_hal.driver);
  1418. if (ret != 0)
  1419. ACCDET_ERROR("create attribute err = %d\n", ret);
  1420. #endif
  1421. pmic_register_interrupt_callback(12, accdet_int_handler);
  1422. pmic_register_interrupt_callback(13, accdet_eint_int_handler);
  1423. ACCDET_INFO("[Accdet]accdet_probe : ACCDET_INIT\n");
  1424. if (g_accdet_first == 1) {
  1425. eint_accdet_sync_flag = 1;
  1426. #ifdef CONFIG_ACCDET_EINT_IRQ
  1427. accdet_eint_workqueue = create_singlethread_workqueue("accdet_eint");
  1428. INIT_WORK(&accdet_eint_work, accdet_eint_work_callback);
  1429. accdet_disable_workqueue = create_singlethread_workqueue("accdet_disable");
  1430. INIT_WORK(&accdet_disable_work, disable_micbias_callback);
  1431. #endif
  1432. /*Accdet Hardware Init*/
  1433. accdet_get_dts_data();
  1434. accdet_init();
  1435. accdet_pmic_Read_Efuse_HPOffset();
  1436. /*schedule a work for the first detection*/
  1437. queue_work(accdet_workqueue, &accdet_work);
  1438. #ifdef CONFIG_ACCDET_EINT
  1439. accdet_disable_workqueue = create_singlethread_workqueue("accdet_disable");
  1440. INIT_WORK(&accdet_disable_work, disable_micbias_callback);
  1441. accdet_eint_workqueue = create_singlethread_workqueue("accdet_eint");
  1442. INIT_WORK(&accdet_eint_work, accdet_eint_work_callback);
  1443. accdet_setup_eint(dev);
  1444. #endif
  1445. g_accdet_first = 0;
  1446. }
  1447. ACCDET_INFO("[Accdet]accdet_probe done!\n");
  1448. return 0;
  1449. }
  1450. void mt_accdet_remove(void)
  1451. {
  1452. ACCDET_DEBUG("[Accdet]accdet_remove begin!\n");
  1453. /*cancel_delayed_work(&accdet_work);*/
  1454. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  1455. destroy_workqueue(accdet_eint_workqueue);
  1456. #endif
  1457. destroy_workqueue(accdet_workqueue);
  1458. switch_dev_unregister(&accdet_data);
  1459. device_del(accdet_nor_device);
  1460. class_destroy(accdet_class);
  1461. cdev_del(accdet_cdev);
  1462. unregister_chrdev_region(accdet_devno, 1);
  1463. input_unregister_device(kpd_accdet_dev);
  1464. ACCDET_DEBUG("[Accdet]accdet_remove Done!\n");
  1465. }
  1466. void mt_accdet_suspend(void) /*only one suspend mode*/
  1467. {
  1468. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  1469. ACCDET_DEBUG("[Accdet] in suspend1: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));
  1470. #else
  1471. ACCDET_DEBUG("[Accdet]accdet_suspend: ACCDET_CTRL=[0x%x], STATE=[0x%x]->[0x%x]\n",
  1472. pmic_pwrap_read(ACCDET_CTRL), pre_state_swctrl, pmic_pwrap_read(ACCDET_STATE_SWCTRL));
  1473. #endif
  1474. }
  1475. void mt_accdet_resume(void) /*wake up*/
  1476. {
  1477. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  1478. ACCDET_DEBUG("[Accdet] in resume1: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));
  1479. #else
  1480. ACCDET_DEBUG("[Accdet]accdet_resume: ACCDET_CTRL=[0x%x], STATE_SWCTRL=[0x%x]\n",
  1481. pmic_pwrap_read(ACCDET_CTRL), pmic_pwrap_read(ACCDET_STATE_SWCTRL));
  1482. #endif
  1483. }
  1484. /**********************************************************************
  1485. //add for IPO-H need update headset state when resume
  1486. ***********************************************************************/
  1487. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  1488. struct timer_list accdet_disable_ipoh_timer;
  1489. static void mt_accdet_pm_disable(unsigned long a)
  1490. {
  1491. if (cable_type == NO_DEVICE && eint_accdet_sync_flag == 0) {
  1492. /*disable accdet*/
  1493. pre_state_swctrl = pmic_pwrap_read(ACCDET_STATE_SWCTRL);
  1494. pmic_pwrap_write(ACCDET_STATE_SWCTRL, 0);
  1495. #ifdef CONFIG_ACCDET_EINT
  1496. pmic_pwrap_write(ACCDET_CTRL, ACCDET_DISABLE);
  1497. /*disable clock*/
  1498. pmic_pwrap_write(TOP_CKPDN_SET, RG_ACCDET_CLK_SET);
  1499. #endif
  1500. #ifdef CONFIG_ACCDET_EINT_IRQ
  1501. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) & (~(ACCDET_ENABLE)));
  1502. #endif
  1503. ACCDET_DEBUG("[Accdet]daccdet_pm_disable: disable!\n");
  1504. } else {
  1505. ACCDET_DEBUG("[Accdet]daccdet_pm_disable: enable!\n");
  1506. }
  1507. }
  1508. #endif
  1509. void mt_accdet_pm_restore_noirq(void)
  1510. {
  1511. int current_status_restore = 0;
  1512. ACCDET_DEBUG("[Accdet]accdet_pm_restore_noirq start!\n");
  1513. /*enable ACCDET unit*/
  1514. ACCDET_DEBUG("accdet: enable_accdet\n");
  1515. /*enable clock*/
  1516. pmic_pwrap_write(TOP_CKPDN_CLR, RG_ACCDET_CLK_CLR);
  1517. #ifdef CONFIG_ACCDET_EINT_IRQ
  1518. pmic_pwrap_write(TOP_CKPDN_CLR, RG_ACCDET_EINT_IRQ_CLR);
  1519. pmic_pwrap_write(ACCDET_RSV, pmic_pwrap_read(ACCDET_RSV) | ACCDET_INPUT_MICP);
  1520. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) | ACCDET_EINT_CON_EN);
  1521. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) | ACCDET_EINT_CON_EN);
  1522. pmic_pwrap_write(ACCDET_CTRL, ACCDET_EINT_EN);
  1523. #endif
  1524. #ifdef ACCDET_NEGV_IRQ
  1525. pmic_pwrap_write(TOP_CKPDN_CLR, RG_ACCDET_NEGV_IRQ_CLR);
  1526. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) | ACCDET_NEGV_DT_EN);
  1527. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) | ACCDET_NEGV_EN);
  1528. #endif
  1529. enable_accdet(ACCDET_SWCTRL_EN);
  1530. pmic_pwrap_write(ACCDET_STATE_SWCTRL, (pmic_pwrap_read(ACCDET_STATE_SWCTRL) | ACCDET_SWCTRL_IDLE_EN));
  1531. eint_accdet_sync_flag = 1;
  1532. current_status_restore = ((pmic_pwrap_read(ACCDET_STATE_RG) & 0xc0) >> 6); /*AB*/
  1533. switch (current_status_restore) {
  1534. case 0: /*AB=0*/
  1535. cable_type = HEADSET_NO_MIC;
  1536. accdet_status = HOOK_SWITCH;
  1537. break;
  1538. case 1: /*AB=1*/
  1539. cable_type = HEADSET_MIC;
  1540. accdet_status = MIC_BIAS;
  1541. break;
  1542. case 3: /*AB=3*/
  1543. cable_type = NO_DEVICE;
  1544. accdet_status = PLUG_OUT;
  1545. break;
  1546. default:
  1547. ACCDET_DEBUG("[Accdet]accdet_pm_restore_noirq: accdet current status error!\n");
  1548. break;
  1549. }
  1550. switch_set_state((struct switch_dev *)&accdet_data, cable_type);
  1551. if (cable_type == NO_DEVICE) {
  1552. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  1553. init_timer(&accdet_disable_ipoh_timer);
  1554. accdet_disable_ipoh_timer.expires = jiffies + 3 * HZ;
  1555. accdet_disable_ipoh_timer.function = &mt_accdet_pm_disable;
  1556. accdet_disable_ipoh_timer.data = ((unsigned long)0);
  1557. add_timer(&accdet_disable_ipoh_timer);
  1558. ACCDET_DEBUG("[Accdet]enable! pm timer\n");
  1559. #else
  1560. /*disable accdet*/
  1561. pre_state_swctrl = pmic_pwrap_read(ACCDET_STATE_SWCTRL);
  1562. #ifdef CONFIG_ACCDET_EINT
  1563. pmic_pwrap_write(ACCDET_STATE_SWCTRL, 0);
  1564. pmic_pwrap_write(ACCDET_CTRL, ACCDET_DISABLE);
  1565. /*disable clock*/
  1566. pmic_pwrap_write(TOP_CKPDN_SET, RG_ACCDET_CLK_SET);
  1567. #endif
  1568. #ifdef CONFIG_ACCDET_EINT_IRQ
  1569. pmic_pwrap_write(ACCDET_STATE_SWCTRL, ACCDET_EINT_PWM_EN);
  1570. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) & (~(ACCDET_ENABLE)));
  1571. #endif
  1572. #endif
  1573. }
  1574. }
  1575. /*//////////////////////////////////IPO_H end/////////////////////////////////////////////*/
  1576. long mt_accdet_unlocked_ioctl(unsigned int cmd, unsigned long arg)
  1577. {
  1578. switch (cmd) {
  1579. case ACCDET_INIT:
  1580. break;
  1581. case SET_CALL_STATE:
  1582. call_status = (int)arg;
  1583. ACCDET_DEBUG("[Accdet]accdet_ioctl : CALL_STATE=%d\n", call_status);
  1584. break;
  1585. case GET_BUTTON_STATUS:
  1586. ACCDET_DEBUG("[Accdet]accdet_ioctl : Button_Status=%d (state:%d)\n", button_status, accdet_data.state);
  1587. return button_status;
  1588. default:
  1589. ACCDET_DEBUG("[Accdet]accdet_ioctl : default\n");
  1590. break;
  1591. }
  1592. return 0;
  1593. }