brintos

brintos / linux-shallow public Read only

0
0
Text · 5.8 KiB · a653da6 Raw
218 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * wm8350-core.c  --  Device access for Wolfson WM83504 *5 * Copyright 2007, 2008 Wolfson Microelectronics PLC.6 *7 * Author: Liam Girdwood8 */9 10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/errno.h>13 14#include <linux/mfd/wm8350/core.h>15#include <linux/mfd/wm8350/gpio.h>16#include <linux/mfd/wm8350/pmic.h>17 18static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir)19{20	int ret;21 22	wm8350_reg_unlock(wm8350);23	if (dir == WM8350_GPIO_DIR_OUT)24		ret = wm8350_clear_bits(wm8350,25					WM8350_GPIO_CONFIGURATION_I_O,26					1 << gpio);27	else28		ret = wm8350_set_bits(wm8350,29				      WM8350_GPIO_CONFIGURATION_I_O,30				      1 << gpio);31	wm8350_reg_lock(wm8350);32	return ret;33}34 35static int wm8350_gpio_set_debounce(struct wm8350 *wm8350, int gpio, int db)36{37	if (db == WM8350_GPIO_DEBOUNCE_ON)38		return wm8350_set_bits(wm8350, WM8350_GPIO_DEBOUNCE,39				       1 << gpio);40	else41		return wm8350_clear_bits(wm8350,42					 WM8350_GPIO_DEBOUNCE, 1 << gpio);43}44 45static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func)46{47	u16 reg;48 49	wm8350_reg_unlock(wm8350);50	switch (gpio) {51	case 0:52		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)53		    & ~WM8350_GP0_FN_MASK;54		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,55				 reg | ((func & 0xf) << 0));56		break;57	case 1:58		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)59		    & ~WM8350_GP1_FN_MASK;60		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,61				 reg | ((func & 0xf) << 4));62		break;63	case 2:64		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)65		    & ~WM8350_GP2_FN_MASK;66		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,67				 reg | ((func & 0xf) << 8));68		break;69	case 3:70		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1)71		    & ~WM8350_GP3_FN_MASK;72		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1,73				 reg | ((func & 0xf) << 12));74		break;75	case 4:76		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)77		    & ~WM8350_GP4_FN_MASK;78		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,79				 reg | ((func & 0xf) << 0));80		break;81	case 5:82		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)83		    & ~WM8350_GP5_FN_MASK;84		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,85				 reg | ((func & 0xf) << 4));86		break;87	case 6:88		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)89		    & ~WM8350_GP6_FN_MASK;90		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,91				 reg | ((func & 0xf) << 8));92		break;93	case 7:94		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2)95		    & ~WM8350_GP7_FN_MASK;96		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2,97				 reg | ((func & 0xf) << 12));98		break;99	case 8:100		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)101		    & ~WM8350_GP8_FN_MASK;102		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,103				 reg | ((func & 0xf) << 0));104		break;105	case 9:106		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)107		    & ~WM8350_GP9_FN_MASK;108		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,109				 reg | ((func & 0xf) << 4));110		break;111	case 10:112		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)113		    & ~WM8350_GP10_FN_MASK;114		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,115				 reg | ((func & 0xf) << 8));116		break;117	case 11:118		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3)119		    & ~WM8350_GP11_FN_MASK;120		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3,121				 reg | ((func & 0xf) << 12));122		break;123	case 12:124		reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_4)125		    & ~WM8350_GP12_FN_MASK;126		wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_4,127				 reg | ((func & 0xf) << 0));128		break;129	default:130		wm8350_reg_lock(wm8350);131		return -EINVAL;132	}133 134	wm8350_reg_lock(wm8350);135	return 0;136}137 138static int gpio_set_pull_up(struct wm8350 *wm8350, int gpio, int up)139{140	if (up)141		return wm8350_set_bits(wm8350,142				       WM8350_GPIO_PIN_PULL_UP_CONTROL,143				       1 << gpio);144	else145		return wm8350_clear_bits(wm8350,146					 WM8350_GPIO_PIN_PULL_UP_CONTROL,147					 1 << gpio);148}149 150static int gpio_set_pull_down(struct wm8350 *wm8350, int gpio, int down)151{152	if (down)153		return wm8350_set_bits(wm8350,154				       WM8350_GPIO_PULL_DOWN_CONTROL,155				       1 << gpio);156	else157		return wm8350_clear_bits(wm8350,158					 WM8350_GPIO_PULL_DOWN_CONTROL,159					 1 << gpio);160}161 162static int gpio_set_polarity(struct wm8350 *wm8350, int gpio, int pol)163{164	if (pol == WM8350_GPIO_ACTIVE_HIGH)165		return wm8350_set_bits(wm8350,166				       WM8350_GPIO_PIN_POLARITY_TYPE,167				       1 << gpio);168	else169		return wm8350_clear_bits(wm8350,170					 WM8350_GPIO_PIN_POLARITY_TYPE,171					 1 << gpio);172}173 174static int gpio_set_invert(struct wm8350 *wm8350, int gpio, int invert)175{176	if (invert == WM8350_GPIO_INVERT_ON)177		return wm8350_set_bits(wm8350, WM8350_GPIO_INT_MODE, 1 << gpio);178	else179		return wm8350_clear_bits(wm8350,180					 WM8350_GPIO_INT_MODE, 1 << gpio);181}182 183int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func,184		       int pol, int pull, int invert, int debounce)185{186	/* make sure we never pull up and down at the same time */187	if (pull == WM8350_GPIO_PULL_NONE) {188		if (gpio_set_pull_up(wm8350, gpio, 0))189			goto err;190		if (gpio_set_pull_down(wm8350, gpio, 0))191			goto err;192	} else if (pull == WM8350_GPIO_PULL_UP) {193		if (gpio_set_pull_down(wm8350, gpio, 0))194			goto err;195		if (gpio_set_pull_up(wm8350, gpio, 1))196			goto err;197	} else if (pull == WM8350_GPIO_PULL_DOWN) {198		if (gpio_set_pull_up(wm8350, gpio, 0))199			goto err;200		if (gpio_set_pull_down(wm8350, gpio, 1))201			goto err;202	}203 204	if (gpio_set_invert(wm8350, gpio, invert))205		goto err;206	if (gpio_set_polarity(wm8350, gpio, pol))207		goto err;208	if (wm8350_gpio_set_debounce(wm8350, gpio, debounce))209		goto err;210	if (gpio_set_dir(wm8350, gpio, dir))211		goto err;212	return gpio_set_func(wm8350, gpio, func);213 214err:215	return -EIO;216}217EXPORT_SYMBOL_GPL(wm8350_gpio_config);218