pinctrl-wcd.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /*
  2. * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/gpio.h>
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/pinctrl/pinconf-generic.h>
  17. #include <linux/pinctrl/pinconf.h>
  18. #include <linux/pinctrl/pinmux.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/regmap.h>
  21. #include <linux/slab.h>
  22. #include <linux/types.h>
  23. #include <linux/mfd/wcd934x/registers.h>
  24. #include "../core.h"
  25. #include "../pinctrl-utils.h"
  26. #define WCD_REG_DIR_CTL WCD934X_CHIP_TIER_CTRL_GPIO_CTL_OE
  27. #define WCD_REG_VAL_CTL WCD934X_CHIP_TIER_CTRL_GPIO_CTL_DATA
  28. #define WCD_GPIO_PULL_UP 1
  29. #define WCD_GPIO_PULL_DOWN 2
  30. #define WCD_GPIO_BIAS_DISABLE 3
  31. #define WCD_GPIO_STRING_LEN 20
  32. /**
  33. * struct wcd_gpio_pad - keep current GPIO settings
  34. * @offset: offset of gpio.
  35. * @is_valid: Set to false, when GPIO in high Z state.
  36. * @value: value of a pin
  37. * @output_enabled: Set to true if GPIO is output and false if it is input
  38. * @pullup: Constant current which flow through GPIO output buffer.
  39. * @strength: Drive strength of a pin
  40. */
  41. struct wcd_gpio_pad {
  42. u16 offset;
  43. bool is_valid;
  44. bool value;
  45. bool output_enabled;
  46. unsigned int pullup;
  47. unsigned int strength;
  48. };
  49. struct wcd_gpio_priv {
  50. struct device *dev;
  51. struct regmap *map;
  52. struct pinctrl_dev *ctrl;
  53. struct gpio_chip chip;
  54. };
  55. static int wcd_gpio_read(struct wcd_gpio_priv *priv_data,
  56. struct wcd_gpio_pad *pad, unsigned int addr)
  57. {
  58. unsigned int val;
  59. int ret;
  60. ret = regmap_read(priv_data->map, addr, &val);
  61. if (ret < 0)
  62. dev_err(priv_data->dev, "%s: read 0x%x failed\n",
  63. __func__, addr);
  64. else
  65. ret = (val >> pad->offset);
  66. return ret;
  67. }
  68. static int wcd_gpio_write(struct wcd_gpio_priv *priv_data,
  69. struct wcd_gpio_pad *pad, unsigned int addr,
  70. unsigned int val)
  71. {
  72. int ret;
  73. ret = regmap_update_bits(priv_data->map, addr, (1 << pad->offset),
  74. val << pad->offset);
  75. if (ret < 0)
  76. dev_err(priv_data->dev, "write 0x%x failed\n", addr);
  77. return ret;
  78. }
  79. static int wcd_get_groups_count(struct pinctrl_dev *pctldev)
  80. {
  81. return pctldev->desc->npins;
  82. }
  83. static const char *wcd_get_group_name(struct pinctrl_dev *pctldev,
  84. unsigned int pin)
  85. {
  86. return pctldev->desc->pins[pin].name;
  87. }
  88. static int wcd_get_group_pins(struct pinctrl_dev *pctldev, unsigned int pin,
  89. const unsigned int **pins, unsigned int *num_pins)
  90. {
  91. *pins = &pctldev->desc->pins[pin].number;
  92. *num_pins = 1;
  93. return 0;
  94. }
  95. static const struct pinctrl_ops wcd_pinctrl_ops = {
  96. .get_groups_count = wcd_get_groups_count,
  97. .get_group_name = wcd_get_group_name,
  98. .get_group_pins = wcd_get_group_pins,
  99. .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
  100. .dt_free_map = pinctrl_utils_free_map,
  101. };
  102. static int wcd_config_get(struct pinctrl_dev *pctldev,
  103. unsigned int pin, unsigned long *config)
  104. {
  105. unsigned int param = pinconf_to_config_param(*config);
  106. struct wcd_gpio_pad *pad;
  107. unsigned int arg;
  108. pad = pctldev->desc->pins[pin].drv_data;
  109. switch (param) {
  110. case PIN_CONFIG_BIAS_PULL_DOWN:
  111. arg = pad->pullup == WCD_GPIO_PULL_DOWN;
  112. break;
  113. case PIN_CONFIG_BIAS_DISABLE:
  114. arg = pad->pullup = WCD_GPIO_BIAS_DISABLE;
  115. break;
  116. case PIN_CONFIG_BIAS_PULL_UP:
  117. arg = pad->pullup == WCD_GPIO_PULL_UP;
  118. break;
  119. case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
  120. arg = !pad->is_valid;
  121. break;
  122. case PIN_CONFIG_INPUT_ENABLE:
  123. arg = pad->output_enabled;
  124. break;
  125. case PIN_CONFIG_OUTPUT:
  126. arg = pad->value;
  127. break;
  128. default:
  129. return -EINVAL;
  130. }
  131. *config = pinconf_to_config_packed(param, arg);
  132. return 0;
  133. }
  134. static int wcd_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
  135. unsigned long *configs, unsigned int nconfs)
  136. {
  137. struct wcd_gpio_priv *priv_data = pinctrl_dev_get_drvdata(pctldev);
  138. struct wcd_gpio_pad *pad;
  139. unsigned int param, arg;
  140. int i, ret;
  141. pad = pctldev->desc->pins[pin].drv_data;
  142. for (i = 0; i < nconfs; i++) {
  143. param = pinconf_to_config_param(configs[i]);
  144. arg = pinconf_to_config_argument(configs[i]);
  145. dev_dbg(priv_data->dev, "%s: param: %d arg: %d",
  146. __func__, param, arg);
  147. switch (param) {
  148. case PIN_CONFIG_BIAS_DISABLE:
  149. pad->pullup = WCD_GPIO_BIAS_DISABLE;
  150. break;
  151. case PIN_CONFIG_BIAS_PULL_UP:
  152. pad->pullup = WCD_GPIO_PULL_UP;
  153. break;
  154. case PIN_CONFIG_BIAS_PULL_DOWN:
  155. pad->pullup = WCD_GPIO_PULL_DOWN;
  156. break;
  157. case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
  158. pad->is_valid = false;
  159. break;
  160. case PIN_CONFIG_INPUT_ENABLE:
  161. pad->output_enabled = false;
  162. break;
  163. case PIN_CONFIG_OUTPUT:
  164. pad->output_enabled = true;
  165. pad->value = arg;
  166. break;
  167. case PIN_CONFIG_DRIVE_STRENGTH:
  168. pad->strength = arg;
  169. break;
  170. default:
  171. ret = -EINVAL;
  172. goto done;
  173. }
  174. }
  175. if (pad->output_enabled) {
  176. ret = wcd_gpio_write(priv_data, pad, WCD_REG_DIR_CTL,
  177. pad->output_enabled);
  178. if (ret < 0)
  179. goto done;
  180. ret = wcd_gpio_write(priv_data, pad, WCD_REG_VAL_CTL,
  181. pad->value);
  182. } else
  183. ret = wcd_gpio_write(priv_data, pad, WCD_REG_DIR_CTL,
  184. pad->output_enabled);
  185. done:
  186. return ret;
  187. }
  188. static const struct pinconf_ops wcd_pinconf_ops = {
  189. .is_generic = true,
  190. .pin_config_group_get = wcd_config_get,
  191. .pin_config_group_set = wcd_config_set,
  192. };
  193. static int wcd_gpio_direction_input(struct gpio_chip *chip, unsigned int pin)
  194. {
  195. struct wcd_gpio_priv *priv_data = gpiochip_get_data(chip);
  196. unsigned long config;
  197. config = pinconf_to_config_packed(PIN_CONFIG_INPUT_ENABLE, 1);
  198. return wcd_config_set(priv_data->ctrl, pin, &config, 1);
  199. }
  200. static int wcd_gpio_direction_output(struct gpio_chip *chip,
  201. unsigned int pin, int val)
  202. {
  203. struct wcd_gpio_priv *priv_data = gpiochip_get_data(chip);
  204. unsigned long config;
  205. config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, val);
  206. return wcd_config_set(priv_data->ctrl, pin, &config, 1);
  207. }
  208. static int wcd_gpio_get(struct gpio_chip *chip, unsigned int pin)
  209. {
  210. struct wcd_gpio_priv *priv_data = gpiochip_get_data(chip);
  211. struct wcd_gpio_pad *pad;
  212. int value;
  213. pad = priv_data->ctrl->desc->pins[pin].drv_data;
  214. if (!pad->is_valid)
  215. return -EINVAL;
  216. value = wcd_gpio_read(priv_data, pad, WCD_REG_VAL_CTL);
  217. return value;
  218. }
  219. static void wcd_gpio_set(struct gpio_chip *chip, unsigned int pin, int value)
  220. {
  221. struct wcd_gpio_priv *priv_data = gpiochip_get_data(chip);
  222. unsigned long config;
  223. config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT, value);
  224. wcd_config_set(priv_data->ctrl, pin, &config, 1);
  225. }
  226. static const struct gpio_chip wcd_gpio_chip = {
  227. .direction_input = wcd_gpio_direction_input,
  228. .direction_output = wcd_gpio_direction_output,
  229. .get = wcd_gpio_get,
  230. .set = wcd_gpio_set,
  231. };
  232. static int wcd_pinctrl_probe(struct platform_device *pdev)
  233. {
  234. struct device *dev = &pdev->dev;
  235. struct pinctrl_pin_desc *pindesc;
  236. struct pinctrl_desc *pctrldesc;
  237. struct wcd_gpio_pad *pad, *pads;
  238. struct wcd_gpio_priv *priv_data;
  239. int ret, i, j;
  240. u32 npins;
  241. char **name;
  242. ret = of_property_read_u32(dev->of_node, "qcom,num-gpios", &npins);
  243. if (ret) {
  244. dev_err(dev, "%s: Looking up %s property in node %s failed\n",
  245. __func__, "qcom,num-gpios", dev->of_node->full_name);
  246. ret = -EINVAL;
  247. goto err_priv_alloc;
  248. }
  249. if (!npins) {
  250. dev_err(dev, "%s: no.of pins are 0\n", __func__);
  251. ret = -EINVAL;
  252. goto err_priv_alloc;
  253. }
  254. priv_data = devm_kzalloc(dev, sizeof(*priv_data), GFP_KERNEL);
  255. if (!priv_data) {
  256. ret = -ENOMEM;
  257. goto err_priv_alloc;
  258. }
  259. priv_data->dev = dev;
  260. priv_data->map = dev_get_regmap(dev->parent, NULL);
  261. if (!priv_data->map) {
  262. dev_err(dev, "%s: failed to get regmap\n", __func__);
  263. ret = -EINVAL;
  264. goto err_regmap;
  265. }
  266. pindesc = devm_kcalloc(dev, npins, sizeof(*pindesc), GFP_KERNEL);
  267. if (!pindesc) {
  268. ret = -ENOMEM;
  269. goto err_pinsec_alloc;
  270. }
  271. pads = devm_kcalloc(dev, npins, sizeof(*pads), GFP_KERNEL);
  272. if (!pads) {
  273. ret = -ENOMEM;
  274. goto err_pads_alloc;
  275. }
  276. pctrldesc = devm_kzalloc(dev, sizeof(*pctrldesc), GFP_KERNEL);
  277. if (!pctrldesc) {
  278. ret = -ENOMEM;
  279. goto err_pinctrl_alloc;
  280. }
  281. pctrldesc->pctlops = &wcd_pinctrl_ops;
  282. pctrldesc->confops = &wcd_pinconf_ops;
  283. pctrldesc->owner = THIS_MODULE;
  284. pctrldesc->name = dev_name(dev);
  285. pctrldesc->pins = pindesc;
  286. pctrldesc->npins = npins;
  287. name = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL);
  288. if (!name) {
  289. ret = -ENOMEM;
  290. goto err_name_alloc;
  291. }
  292. for (i = 0; i < npins; i++, pindesc++) {
  293. name[i] = devm_kzalloc(dev, sizeof(char) * WCD_GPIO_STRING_LEN,
  294. GFP_KERNEL);
  295. if (!name[i]) {
  296. ret = -ENOMEM;
  297. goto err_pin;
  298. }
  299. pad = &pads[i];
  300. pindesc->drv_data = pad;
  301. pindesc->number = i;
  302. snprintf(name[i], (WCD_GPIO_STRING_LEN - 1), "gpio%d", (i+1));
  303. pindesc->name = name[i];
  304. pad->offset = i;
  305. pad->is_valid = true;
  306. }
  307. priv_data->chip = wcd_gpio_chip;
  308. priv_data->chip.parent = dev;
  309. priv_data->chip.base = -1;
  310. priv_data->chip.ngpio = npins;
  311. priv_data->chip.label = dev_name(dev);
  312. priv_data->chip.of_gpio_n_cells = 2;
  313. priv_data->chip.can_sleep = false;
  314. priv_data->ctrl = devm_pinctrl_register(dev, pctrldesc, priv_data);
  315. if (IS_ERR(priv_data->ctrl)) {
  316. dev_err(dev, "%s: failed to register to pinctrl\n", __func__);
  317. ret = PTR_ERR(priv_data->ctrl);
  318. goto err_pin;
  319. }
  320. ret = gpiochip_add_data(&priv_data->chip, priv_data);
  321. if (ret) {
  322. dev_err(dev, "%s: can't add gpio chip\n", __func__);
  323. goto err_pin;
  324. }
  325. ret = gpiochip_add_pin_range(&priv_data->chip, dev_name(dev), 0, 0,
  326. npins);
  327. if (ret) {
  328. dev_err(dev, "%s: failed to add pin range\n", __func__);
  329. goto err_range;
  330. }
  331. platform_set_drvdata(pdev, priv_data);
  332. return 0;
  333. err_range:
  334. gpiochip_remove(&priv_data->chip);
  335. err_pin:
  336. for (j = 0; j < i; j++)
  337. devm_kfree(dev, name[j]);
  338. devm_kfree(dev, name);
  339. err_name_alloc:
  340. devm_kfree(dev, pctrldesc);
  341. err_pinctrl_alloc:
  342. devm_kfree(dev, pads);
  343. err_pads_alloc:
  344. devm_kfree(dev, pindesc);
  345. err_pinsec_alloc:
  346. err_regmap:
  347. devm_kfree(dev, priv_data);
  348. err_priv_alloc:
  349. return ret;
  350. }
  351. static int wcd_pinctrl_remove(struct platform_device *pdev)
  352. {
  353. struct wcd_gpio_priv *priv_data = platform_get_drvdata(pdev);
  354. gpiochip_remove(&priv_data->chip);
  355. return 0;
  356. }
  357. static const struct of_device_id wcd_pinctrl_of_match[] = {
  358. { .compatible = "qcom,wcd-pinctrl" },
  359. { },
  360. };
  361. MODULE_DEVICE_TABLE(of, wcd_pinctrl_of_match);
  362. static struct platform_driver wcd_pinctrl_driver = {
  363. .driver = {
  364. .name = "qcom-wcd-pinctrl",
  365. .of_match_table = wcd_pinctrl_of_match,
  366. },
  367. .probe = wcd_pinctrl_probe,
  368. .remove = wcd_pinctrl_remove,
  369. };
  370. module_platform_driver(wcd_pinctrl_driver);
  371. MODULE_DESCRIPTION("Qualcomm Technologies, Inc WCD GPIO pin control driver");
  372. MODULE_LICENSE("GPL v2");