Linux Audio

Check our new training course

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