es705-platform.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * es705-platform.c -- Audience eS705 platform dependent functions
  3. *
  4. * Copyright 2011 Audience, Inc.
  5. *
  6. * Author: Genisim Tsilker <gtsilker@audience.com>
  7. *
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #define SAMSUNG_ES705_FEATURE
  14. #include <linux/err.h>
  15. #include <linux/errno.h>
  16. #include <linux/delay.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/device.h>
  20. #include <linux/gpio.h>
  21. #include <linux/of_gpio.h>
  22. #include <linux/clk.h>
  23. #if defined(SAMSUNG_ES705_FEATURE)
  24. #include <linux/input.h>
  25. #endif
  26. #include <linux/esxxx.h>
  27. #include "es705.h"
  28. #include "es705-platform.h"
  29. void es705_gpio_reset(struct es705_priv *es705)
  30. {
  31. dev_dbg(es705->dev, "%s(): GPIO reset\n", __func__);
  32. gpio_set_value(es705->pdata->reset_gpio, 0);
  33. /* Wait 1 ms then pull Reset signal in High */
  34. usleep_range(1000, 1000);
  35. gpio_set_value(es705->pdata->reset_gpio, 1);
  36. /* Wait 10 ms then */
  37. usleep_range(10000, 10000);
  38. /* eSxxx is READY */
  39. }
  40. int es705_gpio_init(struct es705_priv *es705)
  41. {
  42. int rc = 0;
  43. #ifdef CONFIG_SND_SOC_ES704_TEMP
  44. static int gpio_initialized = 0;
  45. if (gpio_initialized)
  46. return rc;
  47. #endif
  48. if (es705->pdata->reset_gpio != -1) {
  49. rc = gpio_request(es705->pdata->reset_gpio, "es705_reset");
  50. if (rc < 0) {
  51. dev_err(es705->dev, "%s(): es705_reset request failed",
  52. __func__);
  53. goto reset_gpio_request_error;
  54. }
  55. rc = gpio_direction_output(es705->pdata->reset_gpio, 0);
  56. if (rc < 0) {
  57. dev_err(es705->dev, "%s(): es705_reset direction failed",
  58. __func__);
  59. goto reset_gpio_direction_error;
  60. }
  61. } else {
  62. dev_warn(es705->dev, "%s(): es705_reset undefined\n",
  63. __func__);
  64. }
  65. if (es705->pdata->wakeup_gpio != -1) {
  66. rc = gpio_request(es705->pdata->wakeup_gpio, "es705_wakeup");
  67. if (rc < 0) {
  68. dev_err(es705->dev, "%s(): es705_wakeup request failed",
  69. __func__);
  70. goto wakeup_gpio_request_error;
  71. }
  72. rc = gpio_direction_output(es705->pdata->wakeup_gpio, 0);
  73. if (rc < 0) {
  74. dev_err(es705->dev, "%s(): es705_wakeup direction failed",
  75. __func__);
  76. goto wakeup_gpio_direction_error;
  77. }
  78. } else {
  79. dev_warn(es705->dev, "%s(): wakeup_gpio undefined\n",
  80. __func__);
  81. }
  82. /* under H/W rev 0.5 */
  83. if (es705->pdata->uart_gpio != -1) {
  84. rc = gpio_request(es705->pdata->uart_gpio, "es705_uart");
  85. if (rc < 0) {
  86. dev_err(es705->dev, "%s(): es705_uart request failed",
  87. __func__);
  88. goto uart_gpio_request_error;
  89. }
  90. rc = gpio_direction_output(es705->pdata->uart_gpio, 0);
  91. if (rc < 0) {
  92. dev_err(es705->dev, "%s(): es705_uart direction failed",
  93. __func__);
  94. goto uart_gpio_direction_error;
  95. }
  96. } else {
  97. dev_warn(es705->dev, "%s(): es705_uart undefined\n",
  98. __func__);
  99. }
  100. if (es705->pdata->gpiob_gpio) {
  101. rc = request_threaded_irq(es705->pdata->irq_base,
  102. NULL,
  103. es705_irq_event, IRQF_TRIGGER_RISING,
  104. "es705-irq-event", es705);
  105. if (rc) {
  106. dev_err(es705->dev, "%s(): event request_irq() failed\n",
  107. __func__);
  108. goto event_irq_request_error;
  109. }
  110. rc = irq_set_irq_wake(es705->pdata->irq_base, 1);
  111. if (rc < 0) {
  112. dev_err(es705->dev, "%s(): set event irq wake failed\n",
  113. __func__);
  114. disable_irq(es705->pdata->irq_base);
  115. free_irq(es705->pdata->irq_base, es705);
  116. goto event_irq_wake_error;
  117. }
  118. }
  119. #if defined(CONFIG_MACH_K3GDUOS_CTC)
  120. gpio_tlmm_config(GPIO_CFG(es705->pdata->uart_tx_gpio, 2, GPIO_CFG_OUTPUT,GPIO_CFG_NO_PULL, GPIO_CFG_8MA), 1);
  121. gpio_tlmm_config(GPIO_CFG(es705->pdata->uart_rx_gpio, 2, GPIO_CFG_INPUT,GPIO_CFG_NO_PULL, GPIO_CFG_8MA), 1);
  122. #endif /* CONFIG_MACH_K3GDUOS_CTC */
  123. #ifdef CONFIG_SND_SOC_ES704_TEMP
  124. gpio_initialized = 1;
  125. #endif
  126. return rc;
  127. uart_gpio_direction_error:
  128. gpio_free(es705->pdata->uart_gpio);
  129. uart_gpio_request_error:
  130. wakeup_gpio_direction_error:
  131. gpio_free(es705->pdata->wakeup_gpio);
  132. wakeup_gpio_request_error:
  133. reset_gpio_direction_error:
  134. gpio_free(es705->pdata->reset_gpio);
  135. reset_gpio_request_error:
  136. event_irq_wake_error:
  137. event_irq_request_error:
  138. return rc;
  139. }
  140. #if defined(SAMSUNG_ES705_FEATURE)
  141. extern unsigned int system_rev;
  142. void es705_gpio_wakeup(struct es705_priv *es705)
  143. {
  144. dev_info(es705->dev, "%s(): generate gpio wakeup falling edge\n",
  145. __func__);
  146. if (system_rev >= 4) {
  147. gpio_tlmm_config(GPIO_CFG(0, 0, GPIO_CFG_INPUT,
  148. GPIO_CFG_NO_PULL, GPIO_CFG_16MA), 1);
  149. gpio_direction_output(es705->pdata->wakeup_gpio, 1);
  150. } else
  151. gpio_set_value(es705->pdata->wakeup_gpio, 1);
  152. usleep_range(1000,1000);
  153. if (system_rev >= 4) {
  154. gpio_direction_output(es705->pdata->wakeup_gpio, 0);
  155. gpio_direction_input(es705->pdata->wakeup_gpio);
  156. gpio_tlmm_config(GPIO_CFG(0, 2, GPIO_CFG_OUTPUT,
  157. GPIO_CFG_NO_PULL, GPIO_CFG_16MA), 1);
  158. } else
  159. gpio_set_value(es705->pdata->wakeup_gpio, 0);
  160. }
  161. void es705_uart_pin_preset(struct es705_priv *es705)
  162. {
  163. if((es705->pdata->uart_tx_gpio != -1)
  164. && (es705->pdata->uart_rx_gpio != -1)) {
  165. gpio_tlmm_config(GPIO_CFG(es705->pdata->uart_tx_gpio, 2, GPIO_CFG_OUTPUT,
  166. GPIO_CFG_NO_PULL, GPIO_CFG_16MA), 1);
  167. gpio_tlmm_config(GPIO_CFG(es705->pdata->uart_rx_gpio, 2, GPIO_CFG_OUTPUT,
  168. GPIO_CFG_NO_PULL, GPIO_CFG_16MA), 1);
  169. }
  170. }
  171. void es705_uart_pin_postset(struct es705_priv *es705)
  172. {
  173. if((es705->pdata->uart_tx_gpio != -1)
  174. && (es705->pdata->uart_rx_gpio != -1)) {
  175. gpio_tlmm_config(GPIO_CFG(es705->pdata->uart_tx_gpio, 0, GPIO_CFG_INPUT,
  176. GPIO_CFG_NO_PULL, GPIO_CFG_16MA), 1);
  177. gpio_tlmm_config(GPIO_CFG(es705->pdata->uart_rx_gpio, 0, GPIO_CFG_INPUT,
  178. GPIO_CFG_NO_PULL, GPIO_CFG_16MA), 1);
  179. }
  180. }
  181. int es705_init_input_device(struct es705_priv *es705)
  182. {
  183. int rc;
  184. es705->input = input_allocate_device();
  185. if (!es705->input) {
  186. rc = -ENOMEM;
  187. goto es705_init_input_device_exit;
  188. }
  189. es705->input->name = "es705 input";
  190. set_bit(EV_SYN, es705->input->evbit);
  191. set_bit(EV_KEY, es705->input->evbit);
  192. set_bit(KEY_VOICE_WAKEUP, es705->input->keybit);
  193. set_bit(KEY_VOICE_WAKEUP_LPSD, es705->input->keybit);
  194. rc = input_register_device(es705->input);
  195. if (rc < 0)
  196. input_free_device(es705->input);
  197. es705_init_input_device_exit:
  198. return rc;
  199. }
  200. void es705_unregister_input_device(struct es705_priv *es705)
  201. {
  202. input_unregister_device(es705->input);
  203. }
  204. #endif
  205. void es705_vs_event(struct es705_priv *es705)
  206. {
  207. #if defined(SAMSUNG_ES705_FEATURE)
  208. unsigned int vs_event_type = 0;
  209. if (es705->voice_wakeup_enable == 1) /* Voice wakeup */
  210. vs_event_type = KEY_VOICE_WAKEUP;
  211. else if (es705->voice_wakeup_enable == 2) /* Voice wakeup LPSD */
  212. vs_event_type = KEY_VOICE_WAKEUP_LPSD;
  213. else {
  214. dev_info(es705->dev, "%s(): Invalid value(%d)\n", __func__, es705->voice_wakeup_enable);
  215. return;
  216. }
  217. dev_info(es705->dev, "%s(): Raise key event(%d)\n", __func__, vs_event_type);
  218. input_report_key(es705_priv.input, vs_event_type, 1);
  219. input_sync(es705_priv.input);
  220. msleep(10);
  221. input_report_key(es705_priv.input, vs_event_type, 0);
  222. input_sync(es705_priv.input);
  223. #else
  224. struct slim_device *sbdev = es705->gen0_client;
  225. kobject_uevent(&sbdev->dev.kobj, KOBJ_CHANGE);
  226. #endif
  227. }
  228. void es705_gpio_free(struct esxxx_platform_data *pdata)
  229. {
  230. if (pdata->reset_gpio != -1)
  231. gpio_free(pdata->reset_gpio);
  232. if (pdata->gpioa_gpio != -1)
  233. gpio_free(pdata->gpioa_gpio);
  234. if (pdata->uart_gpio != -1)
  235. gpio_free(pdata->uart_gpio);
  236. if (pdata->wakeup_gpio != -1)
  237. gpio_free(pdata->wakeup_gpio);
  238. }
  239. static struct platform_device msm_es705_mclk_dev = {
  240. .name = "es705_mclk_dev_pdev",
  241. .id = -1,
  242. .dev = {
  243. .init_name = "es705_mclk_dev",
  244. },
  245. };
  246. int es705_enable_ext_clk(int enable)
  247. {
  248. struct clk *es705_codec_clk;
  249. dev_dbg(es705_priv.dev, "%s: clk_get osr_clk enable=%d\n",
  250. __func__, enable);
  251. es705_codec_clk = clk_get(&msm_es705_mclk_dev.dev, "osr_clk");
  252. if (!es705_codec_clk) {
  253. dev_err(es705_priv.dev, "%s: clk_get osr_clk FAIL\n",
  254. __func__);
  255. return -ENODEV;
  256. }
  257. if (enable)
  258. clk_prepare_enable(es705_codec_clk);
  259. else
  260. clk_disable_unprepare(es705_codec_clk);
  261. clk_put(es705_codec_clk);
  262. return 0;
  263. }
  264. void es705_clk_init(struct es705_priv *es705)
  265. {
  266. es705->pdata->esxxx_clk_cb = es705_enable_ext_clk;
  267. }
  268. struct esxxx_platform_data *es705_populate_dt_pdata(struct device *dev)
  269. {
  270. struct esxxx_platform_data *pdata;
  271. pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
  272. if (!pdata) {
  273. dev_err(dev, "%s(): platform data allocation failed\n",
  274. __func__);
  275. goto err;
  276. }
  277. pdata->reset_gpio = of_get_named_gpio(dev->of_node,
  278. "es705-reset-gpio", 0);
  279. if (pdata->reset_gpio < 0)
  280. of_property_read_u32(dev->of_node,
  281. "es705-reset-expander-gpio", &pdata->reset_gpio);
  282. if (pdata->reset_gpio < 0) {
  283. dev_err(dev, "%s(): get reset_gpio failed\n", __func__);
  284. goto alloc_err;
  285. }
  286. dev_dbg(dev, "%s(): reset gpio %d\n", __func__, pdata->reset_gpio);
  287. #if !defined(CONFIG_ARCH_MSM8226)
  288. pdata->gpioa_gpio = of_get_named_gpio(dev->of_node,
  289. "es705-gpioa-gpio", 0);
  290. if (pdata->gpioa_gpio < 0) {
  291. dev_err(dev, "%s(): get gpioa_gpio failed\n", __func__);
  292. goto alloc_err;
  293. }
  294. dev_dbg(dev, "%s(): gpioa gpio %d\n", __func__, pdata->gpioa_gpio);
  295. #endif
  296. #if !defined(CONFIG_SEC_S_PROJECT) && !defined(CONFIG_ARCH_MSM8226)
  297. pdata->gpiob_gpio = of_get_named_gpio(dev->of_node,
  298. "es705-gpiob-gpio", 0);
  299. if (pdata->gpiob_gpio < 0) {
  300. dev_err(dev, "%s(): get gpiob_gpio failed\n", __func__);
  301. goto alloc_err;
  302. }
  303. dev_dbg(dev, "%s(): gpiob gpio %d\n", __func__, pdata->gpiob_gpio);
  304. #endif
  305. pdata->uart_tx_gpio = of_get_named_gpio(dev->of_node,
  306. "es705-uart-tx", 0);
  307. if (pdata->uart_tx_gpio < 0) {
  308. dev_info(dev, "%s(): get uart_tx_gpio failed\n", __func__);
  309. pdata->uart_tx_gpio = -1;
  310. }
  311. dev_dbg(dev, "%s(): uart tx gpio %d\n", __func__, pdata->uart_tx_gpio);
  312. pdata->uart_rx_gpio = of_get_named_gpio(dev->of_node,
  313. "es705-uart-rx", 0);
  314. if (pdata->uart_rx_gpio < 0) {
  315. dev_info(dev, "%s(): get uart_rx_gpio failed\n", __func__);
  316. pdata->uart_rx_gpio = -1;
  317. }
  318. dev_dbg(dev, "%s(): uart rx gpio %d\n", __func__, pdata->uart_rx_gpio);
  319. pdata->wakeup_gpio = of_get_named_gpio(dev->of_node,
  320. "es705-wakeup-gpio", 0);
  321. if (pdata->wakeup_gpio < 0) {
  322. dev_info(dev, "%s(): get wakeup_gpio failed\n", __func__);
  323. pdata->wakeup_gpio = -1;
  324. }
  325. dev_dbg(dev, "%s(): wakeup gpio %d\n", __func__, pdata->wakeup_gpio);
  326. pdata->uart_gpio = of_get_named_gpio(dev->of_node,
  327. "es705-uart-gpio", 0);
  328. if (pdata->uart_gpio < 0) {
  329. dev_info(dev, "%s(): get uart_gpio failed\n", __func__);
  330. pdata->uart_gpio = -1;
  331. }
  332. dev_dbg(dev, "%s(): uart gpio %d\n", __func__, pdata->uart_gpio);
  333. #if !defined(CONFIG_SEC_S_PROJECT) && !defined(CONFIG_ARCH_MSM8226)
  334. pdata->irq_base = gpio_to_irq(pdata->gpiob_gpio);
  335. #endif
  336. return pdata;
  337. alloc_err:
  338. devm_kfree(dev, pdata);
  339. err:
  340. return NULL;
  341. }