cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

wm8350-gpio.c (5988B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * wm8350-core.c  --  Device access for Wolfson WM8350
      4 *
      5 * Copyright 2007, 2008 Wolfson Microelectronics PLC.
      6 *
      7 * Author: Liam Girdwood
      8 */
      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	else
     28		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	else
     41		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	else
    145		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	else
    157		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	else
    169		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	else
    179		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);