accdet.c 59 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735
  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;
  1183. ret = sscanf(buf, "%s", &call_status);
  1184. if (ret != 1) {
  1185. ACCDET_DEBUG("accdet: Invalid values\n");
  1186. return -EINVAL;
  1187. }
  1188. switch (call_status) {
  1189. case CALL_IDLE:
  1190. ACCDET_DEBUG("[Accdet]accdet call: Idle state!\n");
  1191. break;
  1192. case CALL_RINGING:
  1193. ACCDET_DEBUG("[Accdet]accdet call: ringing state!\n");
  1194. break;
  1195. case CALL_ACTIVE:
  1196. ACCDET_DEBUG("[Accdet]accdet call: active or hold state!\n");
  1197. ACCDET_DEBUG("[Accdet]accdet_ioctl : Button_Status=%d (state:%d)\n", button_status, accdet_data.state);
  1198. /*return button_status;*/
  1199. break;
  1200. default:
  1201. ACCDET_DEBUG("[Accdet]accdet call : Invalid values\n");
  1202. break;
  1203. }
  1204. return count;
  1205. }
  1206. static ssize_t show_pin_recognition_state(struct device_driver *ddri, char *buf)
  1207. {
  1208. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  1209. ACCDET_DEBUG("ACCDET show_pin_recognition_state = %d\n", cable_pin_recognition);
  1210. return sprintf(buf, "%u\n", cable_pin_recognition);
  1211. #else
  1212. return sprintf(buf, "%u\n", 0);
  1213. #endif
  1214. }
  1215. static DRIVER_ATTR(accdet_pin_recognition, 0664, show_pin_recognition_state, NULL);
  1216. static DRIVER_ATTR(accdet_call_state, 0664, NULL, accdet_store_call_state);
  1217. static int g_start_debug_thread;
  1218. static struct task_struct *thread;
  1219. static int g_dump_register;
  1220. static int dbug_thread(void *unused)
  1221. {
  1222. while (g_start_debug_thread) {
  1223. if (g_dump_register) {
  1224. dump_register();
  1225. /*dump_pmic_register();*/
  1226. }
  1227. msleep(500);
  1228. }
  1229. return 0;
  1230. }
  1231. static ssize_t store_accdet_start_debug_thread(struct device_driver *ddri, const char *buf, size_t count)
  1232. {
  1233. char start_flag;
  1234. int error;
  1235. int ret;
  1236. ret = sscanf(buf, "%s", &start_flag);
  1237. if (ret != 1) {
  1238. ACCDET_DEBUG("accdet: Invalid values\n");
  1239. return -EINVAL;
  1240. }
  1241. ACCDET_DEBUG("[Accdet] start flag =%d\n", start_flag);
  1242. g_start_debug_thread = start_flag;
  1243. if (1 == start_flag) {
  1244. thread = kthread_run(dbug_thread, 0, "ACCDET");
  1245. if (IS_ERR(thread)) {
  1246. error = PTR_ERR(thread);
  1247. ACCDET_DEBUG(" failed to create kernel thread: %d\n", error);
  1248. }
  1249. }
  1250. return count;
  1251. }
  1252. static ssize_t store_accdet_set_headset_mode(struct device_driver *ddri, const char *buf, size_t count)
  1253. {
  1254. char value;
  1255. int ret;
  1256. ret = sscanf(buf, "%s", &value);
  1257. if (ret != 1) {
  1258. ACCDET_DEBUG("accdet: Invalid values\n");
  1259. return -EINVAL;
  1260. }
  1261. ACCDET_DEBUG("[Accdet]store_accdet_set_headset_mode value =%d\n", value);
  1262. return count;
  1263. }
  1264. static ssize_t store_accdet_dump_register(struct device_driver *ddri, const char *buf, size_t count)
  1265. {
  1266. char value;
  1267. int ret;
  1268. ret = sscanf(buf, "%s", &value);
  1269. if (ret != 1) {
  1270. ACCDET_DEBUG("accdet: Invalid values\n");
  1271. return -EINVAL;
  1272. }
  1273. g_dump_register = value;
  1274. ACCDET_DEBUG("[Accdet]store_accdet_dump_register value =%d\n", value);
  1275. return count;
  1276. }
  1277. /*----------------------------------------------------------------------------*/
  1278. static DRIVER_ATTR(dump_register, S_IWUSR | S_IRUGO, NULL, store_accdet_dump_register);
  1279. static DRIVER_ATTR(set_headset_mode, S_IWUSR | S_IRUGO, NULL, store_accdet_set_headset_mode);
  1280. static DRIVER_ATTR(start_debug, S_IWUSR | S_IRUGO, NULL, store_accdet_start_debug_thread);
  1281. /*----------------------------------------------------------------------------*/
  1282. static struct driver_attribute *accdet_attr_list[] = {
  1283. &driver_attr_start_debug,
  1284. &driver_attr_set_headset_mode,
  1285. &driver_attr_dump_register,
  1286. &driver_attr_accdet_call_state,
  1287. /*#ifdef CONFIG_ACCDET_PIN_RECOGNIZATION*/
  1288. &driver_attr_accdet_pin_recognition,
  1289. /*#endif*/
  1290. #if defined(CONFIG_TS3A225E_ACCDET)
  1291. &driver_attr_TS3A225EConnectorType,
  1292. #endif
  1293. };
  1294. static int accdet_create_attr(struct device_driver *driver)
  1295. {
  1296. int idx, err = 0;
  1297. int num = (int)(sizeof(accdet_attr_list) / sizeof(accdet_attr_list[0]));
  1298. if (driver == NULL)
  1299. return -EINVAL;
  1300. for (idx = 0; idx < num; idx++) {
  1301. err = driver_create_file(driver, accdet_attr_list[idx]);
  1302. if (err) {
  1303. ACCDET_DEBUG("driver_create_file (%s) = %d\n", accdet_attr_list[idx]->attr.name, err);
  1304. break;
  1305. }
  1306. }
  1307. return err;
  1308. }
  1309. #endif
  1310. void accdet_int_handler(void)
  1311. {
  1312. int ret = 0;
  1313. ACCDET_DEBUG("[accdet_int_handler]....\n");
  1314. ret = accdet_irq_handler();
  1315. if (0 == ret)
  1316. ACCDET_DEBUG("[accdet_int_handler] don't finished\n");
  1317. }
  1318. void accdet_eint_int_handler(void)
  1319. {
  1320. int ret = 0;
  1321. ACCDET_DEBUG("[accdet_eint_int_handler]....\n");
  1322. ret = accdet_irq_handler();
  1323. if (0 == ret)
  1324. ACCDET_DEBUG("[accdet_int_handler] don't finished\n");
  1325. }
  1326. int mt_accdet_probe(struct platform_device *dev)
  1327. {
  1328. int ret = 0;
  1329. #if DEBUG_THREAD
  1330. struct platform_driver accdet_driver_hal = accdet_driver_func();
  1331. #endif
  1332. #if defined(CONFIG_TS3A225E_ACCDET)
  1333. if (ts3a225e_i2c_client == NULL) {
  1334. ACCDET_DEBUG("[Accdet]ts3a225e_i2c_client is NULL!\n");
  1335. return -EPROBE_DEFER;
  1336. }
  1337. #endif
  1338. ACCDET_INFO("[Accdet]accdet_probe begin!\n");
  1339. /*--------------------------------------------------------------------
  1340. // below register accdet as switch class
  1341. //------------------------------------------------------------------*/
  1342. accdet_data.name = "h2w";
  1343. accdet_data.index = 0;
  1344. accdet_data.state = NO_DEVICE;
  1345. ret = switch_dev_register(&accdet_data);
  1346. if (ret) {
  1347. ACCDET_ERROR("[Accdet]switch_dev_register returned:%d!\n", ret);
  1348. return 1;
  1349. }
  1350. /*----------------------------------------------------------------------
  1351. // Create normal device for auido use
  1352. //--------------------------------------------------------------------*/
  1353. ret = alloc_chrdev_region(&accdet_devno, 0, 1, ACCDET_DEVNAME);
  1354. if (ret)
  1355. ACCDET_ERROR("[Accdet]alloc_chrdev_region: Get Major number error!\n");
  1356. accdet_cdev = cdev_alloc();
  1357. accdet_cdev->owner = THIS_MODULE;
  1358. accdet_cdev->ops = accdet_get_fops();
  1359. ret = cdev_add(accdet_cdev, accdet_devno, 1);
  1360. if (ret)
  1361. ACCDET_ERROR("[Accdet]accdet error: cdev_add\n");
  1362. accdet_class = class_create(THIS_MODULE, ACCDET_DEVNAME);
  1363. /* if we want auto creat device node, we must call this*/
  1364. accdet_nor_device = device_create(accdet_class, NULL, accdet_devno, NULL, ACCDET_DEVNAME);
  1365. /*--------------------------------------------------------------------
  1366. // Create input device
  1367. //------------------------------------------------------------------*/
  1368. kpd_accdet_dev = input_allocate_device();
  1369. if (!kpd_accdet_dev) {
  1370. ACCDET_ERROR("[Accdet]kpd_accdet_dev : fail!\n");
  1371. return -ENOMEM;
  1372. }
  1373. /*INIT the timer to disable micbias.*/
  1374. init_timer(&micbias_timer);
  1375. micbias_timer.expires = jiffies + MICBIAS_DISABLE_TIMER;
  1376. micbias_timer.function = &disable_micbias;
  1377. micbias_timer.data = ((unsigned long)0);
  1378. /*define multi-key keycode*/
  1379. __set_bit(EV_KEY, kpd_accdet_dev->evbit);
  1380. __set_bit(KEY_PLAYPAUSE, kpd_accdet_dev->keybit);
  1381. __set_bit(KEY_VOLUMEDOWN, kpd_accdet_dev->keybit);
  1382. __set_bit(KEY_VOLUMEUP, kpd_accdet_dev->keybit);
  1383. __set_bit(KEY_VOICECOMMAND, kpd_accdet_dev->keybit);
  1384. kpd_accdet_dev->id.bustype = BUS_HOST;
  1385. kpd_accdet_dev->name = "ACCDET";
  1386. if (input_register_device(kpd_accdet_dev))
  1387. ACCDET_ERROR("[Accdet]kpd_accdet_dev register : fail!\n");
  1388. /*------------------------------------------------------------------
  1389. // Create workqueue
  1390. //------------------------------------------------------------------ */
  1391. accdet_workqueue = create_singlethread_workqueue("accdet");
  1392. INIT_WORK(&accdet_work, accdet_work_callback);
  1393. /*------------------------------------------------------------------
  1394. // wake lock
  1395. //------------------------------------------------------------------*/
  1396. wake_lock_init(&accdet_suspend_lock, WAKE_LOCK_SUSPEND, "accdet wakelock");
  1397. wake_lock_init(&accdet_irq_lock, WAKE_LOCK_SUSPEND, "accdet irq wakelock");
  1398. wake_lock_init(&accdet_key_lock, WAKE_LOCK_SUSPEND, "accdet key wakelock");
  1399. wake_lock_init(&accdet_timer_lock, WAKE_LOCK_SUSPEND, "accdet timer wakelock");
  1400. #if DEBUG_THREAD
  1401. ret = accdet_create_attr(&accdet_driver_hal.driver);
  1402. if (ret != 0)
  1403. ACCDET_ERROR("create attribute err = %d\n", ret);
  1404. #endif
  1405. pmic_register_interrupt_callback(12, accdet_int_handler);
  1406. pmic_register_interrupt_callback(13, accdet_eint_int_handler);
  1407. ACCDET_INFO("[Accdet]accdet_probe : ACCDET_INIT\n");
  1408. if (g_accdet_first == 1) {
  1409. eint_accdet_sync_flag = 1;
  1410. #ifdef CONFIG_ACCDET_EINT_IRQ
  1411. accdet_eint_workqueue = create_singlethread_workqueue("accdet_eint");
  1412. INIT_WORK(&accdet_eint_work, accdet_eint_work_callback);
  1413. accdet_disable_workqueue = create_singlethread_workqueue("accdet_disable");
  1414. INIT_WORK(&accdet_disable_work, disable_micbias_callback);
  1415. #endif
  1416. /*Accdet Hardware Init*/
  1417. accdet_get_dts_data();
  1418. accdet_init();
  1419. accdet_pmic_Read_Efuse_HPOffset();
  1420. /*schedule a work for the first detection*/
  1421. queue_work(accdet_workqueue, &accdet_work);
  1422. #ifdef CONFIG_ACCDET_EINT
  1423. accdet_disable_workqueue = create_singlethread_workqueue("accdet_disable");
  1424. INIT_WORK(&accdet_disable_work, disable_micbias_callback);
  1425. accdet_eint_workqueue = create_singlethread_workqueue("accdet_eint");
  1426. INIT_WORK(&accdet_eint_work, accdet_eint_work_callback);
  1427. accdet_setup_eint(dev);
  1428. #endif
  1429. g_accdet_first = 0;
  1430. }
  1431. ACCDET_INFO("[Accdet]accdet_probe done!\n");
  1432. return 0;
  1433. }
  1434. void mt_accdet_remove(void)
  1435. {
  1436. ACCDET_DEBUG("[Accdet]accdet_remove begin!\n");
  1437. /*cancel_delayed_work(&accdet_work);*/
  1438. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  1439. destroy_workqueue(accdet_eint_workqueue);
  1440. #endif
  1441. destroy_workqueue(accdet_workqueue);
  1442. switch_dev_unregister(&accdet_data);
  1443. device_del(accdet_nor_device);
  1444. class_destroy(accdet_class);
  1445. cdev_del(accdet_cdev);
  1446. unregister_chrdev_region(accdet_devno, 1);
  1447. input_unregister_device(kpd_accdet_dev);
  1448. ACCDET_DEBUG("[Accdet]accdet_remove Done!\n");
  1449. }
  1450. void mt_accdet_suspend(void) /*only one suspend mode*/
  1451. {
  1452. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  1453. ACCDET_DEBUG("[Accdet] in suspend1: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));
  1454. #else
  1455. ACCDET_DEBUG("[Accdet]accdet_suspend: ACCDET_CTRL=[0x%x], STATE=[0x%x]->[0x%x]\n",
  1456. pmic_pwrap_read(ACCDET_CTRL), pre_state_swctrl, pmic_pwrap_read(ACCDET_STATE_SWCTRL));
  1457. #endif
  1458. }
  1459. void mt_accdet_resume(void) /*wake up*/
  1460. {
  1461. #if defined CONFIG_ACCDET_EINT || defined CONFIG_ACCDET_EINT_IRQ
  1462. ACCDET_DEBUG("[Accdet] in resume1: ACCDET_IRQ_STS = 0x%x\n", pmic_pwrap_read(ACCDET_IRQ_STS));
  1463. #else
  1464. ACCDET_DEBUG("[Accdet]accdet_resume: ACCDET_CTRL=[0x%x], STATE_SWCTRL=[0x%x]\n",
  1465. pmic_pwrap_read(ACCDET_CTRL), pmic_pwrap_read(ACCDET_STATE_SWCTRL));
  1466. #endif
  1467. }
  1468. /**********************************************************************
  1469. //add for IPO-H need update headset state when resume
  1470. ***********************************************************************/
  1471. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  1472. struct timer_list accdet_disable_ipoh_timer;
  1473. static void mt_accdet_pm_disable(unsigned long a)
  1474. {
  1475. if (cable_type == NO_DEVICE && eint_accdet_sync_flag == 0) {
  1476. /*disable accdet*/
  1477. pre_state_swctrl = pmic_pwrap_read(ACCDET_STATE_SWCTRL);
  1478. pmic_pwrap_write(ACCDET_STATE_SWCTRL, 0);
  1479. #ifdef CONFIG_ACCDET_EINT
  1480. pmic_pwrap_write(ACCDET_CTRL, ACCDET_DISABLE);
  1481. /*disable clock*/
  1482. pmic_pwrap_write(TOP_CKPDN_SET, RG_ACCDET_CLK_SET);
  1483. #endif
  1484. #ifdef CONFIG_ACCDET_EINT_IRQ
  1485. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) & (~(ACCDET_ENABLE)));
  1486. #endif
  1487. ACCDET_DEBUG("[Accdet]daccdet_pm_disable: disable!\n");
  1488. } else {
  1489. ACCDET_DEBUG("[Accdet]daccdet_pm_disable: enable!\n");
  1490. }
  1491. }
  1492. #endif
  1493. void mt_accdet_pm_restore_noirq(void)
  1494. {
  1495. int current_status_restore = 0;
  1496. ACCDET_DEBUG("[Accdet]accdet_pm_restore_noirq start!\n");
  1497. /*enable ACCDET unit*/
  1498. ACCDET_DEBUG("accdet: enable_accdet\n");
  1499. /*enable clock*/
  1500. pmic_pwrap_write(TOP_CKPDN_CLR, RG_ACCDET_CLK_CLR);
  1501. #ifdef CONFIG_ACCDET_EINT_IRQ
  1502. pmic_pwrap_write(TOP_CKPDN_CLR, RG_ACCDET_EINT_IRQ_CLR);
  1503. pmic_pwrap_write(ACCDET_RSV, pmic_pwrap_read(ACCDET_RSV) | ACCDET_INPUT_MICP);
  1504. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) | ACCDET_EINT_CON_EN);
  1505. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) | ACCDET_EINT_CON_EN);
  1506. pmic_pwrap_write(ACCDET_CTRL, ACCDET_EINT_EN);
  1507. #endif
  1508. #ifdef ACCDET_NEGV_IRQ
  1509. pmic_pwrap_write(TOP_CKPDN_CLR, RG_ACCDET_NEGV_IRQ_CLR);
  1510. pmic_pwrap_write(ACCDET_EINT_NV, pmic_pwrap_read(ACCDET_EINT_NV) | ACCDET_NEGV_DT_EN);
  1511. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) | ACCDET_NEGV_EN);
  1512. #endif
  1513. enable_accdet(ACCDET_SWCTRL_EN);
  1514. pmic_pwrap_write(ACCDET_STATE_SWCTRL, (pmic_pwrap_read(ACCDET_STATE_SWCTRL) | ACCDET_SWCTRL_IDLE_EN));
  1515. eint_accdet_sync_flag = 1;
  1516. current_status_restore = ((pmic_pwrap_read(ACCDET_STATE_RG) & 0xc0) >> 6); /*AB*/
  1517. switch (current_status_restore) {
  1518. case 0: /*AB=0*/
  1519. cable_type = HEADSET_NO_MIC;
  1520. accdet_status = HOOK_SWITCH;
  1521. break;
  1522. case 1: /*AB=1*/
  1523. cable_type = HEADSET_MIC;
  1524. accdet_status = MIC_BIAS;
  1525. break;
  1526. case 3: /*AB=3*/
  1527. cable_type = NO_DEVICE;
  1528. accdet_status = PLUG_OUT;
  1529. break;
  1530. default:
  1531. ACCDET_DEBUG("[Accdet]accdet_pm_restore_noirq: accdet current status error!\n");
  1532. break;
  1533. }
  1534. switch_set_state((struct switch_dev *)&accdet_data, cable_type);
  1535. if (cable_type == NO_DEVICE) {
  1536. #ifdef CONFIG_ACCDET_PIN_RECOGNIZATION
  1537. init_timer(&accdet_disable_ipoh_timer);
  1538. accdet_disable_ipoh_timer.expires = jiffies + 3 * HZ;
  1539. accdet_disable_ipoh_timer.function = &mt_accdet_pm_disable;
  1540. accdet_disable_ipoh_timer.data = ((unsigned long)0);
  1541. add_timer(&accdet_disable_ipoh_timer);
  1542. ACCDET_DEBUG("[Accdet]enable! pm timer\n");
  1543. #else
  1544. /*disable accdet*/
  1545. pre_state_swctrl = pmic_pwrap_read(ACCDET_STATE_SWCTRL);
  1546. #ifdef CONFIG_ACCDET_EINT
  1547. pmic_pwrap_write(ACCDET_STATE_SWCTRL, 0);
  1548. pmic_pwrap_write(ACCDET_CTRL, ACCDET_DISABLE);
  1549. /*disable clock*/
  1550. pmic_pwrap_write(TOP_CKPDN_SET, RG_ACCDET_CLK_SET);
  1551. #endif
  1552. #ifdef CONFIG_ACCDET_EINT_IRQ
  1553. pmic_pwrap_write(ACCDET_STATE_SWCTRL, ACCDET_EINT_PWM_EN);
  1554. pmic_pwrap_write(ACCDET_CTRL, pmic_pwrap_read(ACCDET_CTRL) & (~(ACCDET_ENABLE)));
  1555. #endif
  1556. #endif
  1557. }
  1558. }
  1559. /*//////////////////////////////////IPO_H end/////////////////////////////////////////////*/
  1560. long mt_accdet_unlocked_ioctl(unsigned int cmd, unsigned long arg)
  1561. {
  1562. switch (cmd) {
  1563. case ACCDET_INIT:
  1564. break;
  1565. case SET_CALL_STATE:
  1566. call_status = (int)arg;
  1567. ACCDET_DEBUG("[Accdet]accdet_ioctl : CALL_STATE=%d\n", call_status);
  1568. break;
  1569. case GET_BUTTON_STATUS:
  1570. ACCDET_DEBUG("[Accdet]accdet_ioctl : Button_Status=%d (state:%d)\n", button_status, accdet_data.state);
  1571. return button_status;
  1572. default:
  1573. ACCDET_DEBUG("[Accdet]accdet_ioctl : default\n");
  1574. break;
  1575. }
  1576. return 0;
  1577. }