brintos

brintos / linux-shallow public Read only

0
0
Text · 14.5 KiB · fce9211 Raw
594 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Pinctrl driver for the Wondermedia SoC's4 *5 * Copyright (c) 2013 Tony Prisk <linux@prisktech.co.nz>6 */7 8#include <linux/err.h>9#include <linux/gpio/driver.h>10#include <linux/interrupt.h>11#include <linux/io.h>12#include <linux/irq.h>13#include <linux/of.h>14#include <linux/of_irq.h>15#include <linux/pinctrl/consumer.h>16#include <linux/pinctrl/machine.h>17#include <linux/pinctrl/pinconf.h>18#include <linux/pinctrl/pinconf-generic.h>19#include <linux/pinctrl/pinctrl.h>20#include <linux/pinctrl/pinmux.h>21#include <linux/platform_device.h>22#include <linux/slab.h>23 24#include "pinctrl-wmt.h"25 26static inline void wmt_setbits(struct wmt_pinctrl_data *data, u32 reg,27				 u32 mask)28{29	u32 val;30 31	val = readl_relaxed(data->base + reg);32	val |= mask;33	writel_relaxed(val, data->base + reg);34}35 36static inline void wmt_clearbits(struct wmt_pinctrl_data *data, u32 reg,37				   u32 mask)38{39	u32 val;40 41	val = readl_relaxed(data->base + reg);42	val &= ~mask;43	writel_relaxed(val, data->base + reg);44}45 46enum wmt_func_sel {47	WMT_FSEL_GPIO_IN = 0,48	WMT_FSEL_GPIO_OUT = 1,49	WMT_FSEL_ALT = 2,50	WMT_FSEL_COUNT = 3,51};52 53static const char * const wmt_functions[WMT_FSEL_COUNT] = {54	[WMT_FSEL_GPIO_IN] = "gpio_in",55	[WMT_FSEL_GPIO_OUT] = "gpio_out",56	[WMT_FSEL_ALT] = "alt",57};58 59static int wmt_pmx_get_functions_count(struct pinctrl_dev *pctldev)60{61	return WMT_FSEL_COUNT;62}63 64static const char *wmt_pmx_get_function_name(struct pinctrl_dev *pctldev,65					     unsigned selector)66{67	return wmt_functions[selector];68}69 70static int wmt_pmx_get_function_groups(struct pinctrl_dev *pctldev,71				       unsigned selector,72				       const char * const **groups,73				       unsigned * const num_groups)74{75	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);76 77	/* every pin does every function */78	*groups = data->groups;79	*num_groups = data->ngroups;80 81	return 0;82}83 84static int wmt_set_pinmux(struct wmt_pinctrl_data *data, unsigned func,85			  unsigned pin)86{87	u32 bank = WMT_BANK_FROM_PIN(pin);88	u32 bit = WMT_BIT_FROM_PIN(pin);89	u32 reg_en = data->banks[bank].reg_en;90	u32 reg_dir = data->banks[bank].reg_dir;91 92	if (reg_dir == NO_REG) {93		dev_err(data->dev, "pin:%d no direction register defined\n",94			pin);95		return -EINVAL;96	}97 98	/*99	 * If reg_en == NO_REG, we assume it is a dedicated GPIO and cannot be100	 * disabled (as on VT8500) and that no alternate function is available.101	 */102	switch (func) {103	case WMT_FSEL_GPIO_IN:104		if (reg_en != NO_REG)105			wmt_setbits(data, reg_en, BIT(bit));106		wmt_clearbits(data, reg_dir, BIT(bit));107		break;108	case WMT_FSEL_GPIO_OUT:109		if (reg_en != NO_REG)110			wmt_setbits(data, reg_en, BIT(bit));111		wmt_setbits(data, reg_dir, BIT(bit));112		break;113	case WMT_FSEL_ALT:114		if (reg_en == NO_REG) {115			dev_err(data->dev, "pin:%d no alt function available\n",116				pin);117			return -EINVAL;118		}119		wmt_clearbits(data, reg_en, BIT(bit));120	}121 122	return 0;123}124 125static int wmt_pmx_set_mux(struct pinctrl_dev *pctldev,126			   unsigned func_selector,127			   unsigned group_selector)128{129	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);130	u32 pinnum = data->pins[group_selector].number;131 132	return wmt_set_pinmux(data, func_selector, pinnum);133}134 135static void wmt_pmx_gpio_disable_free(struct pinctrl_dev *pctldev,136				      struct pinctrl_gpio_range *range,137				      unsigned offset)138{139	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);140 141	/* disable by setting GPIO_IN */142	wmt_set_pinmux(data, WMT_FSEL_GPIO_IN, offset);143}144 145static int wmt_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,146				      struct pinctrl_gpio_range *range,147				      unsigned offset,148				      bool input)149{150	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);151 152	wmt_set_pinmux(data, (input ? WMT_FSEL_GPIO_IN : WMT_FSEL_GPIO_OUT),153		       offset);154 155	return 0;156}157 158static const struct pinmux_ops wmt_pinmux_ops = {159	.get_functions_count = wmt_pmx_get_functions_count,160	.get_function_name = wmt_pmx_get_function_name,161	.get_function_groups = wmt_pmx_get_function_groups,162	.set_mux = wmt_pmx_set_mux,163	.gpio_disable_free = wmt_pmx_gpio_disable_free,164	.gpio_set_direction = wmt_pmx_gpio_set_direction,165};166 167static int wmt_get_groups_count(struct pinctrl_dev *pctldev)168{169	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);170 171	return data->ngroups;172}173 174static const char *wmt_get_group_name(struct pinctrl_dev *pctldev,175				      unsigned selector)176{177	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);178 179	return data->groups[selector];180}181 182static int wmt_get_group_pins(struct pinctrl_dev *pctldev,183			      unsigned selector,184			      const unsigned **pins,185			      unsigned *num_pins)186{187	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);188 189	*pins = &data->pins[selector].number;190	*num_pins = 1;191 192	return 0;193}194 195static int wmt_pctl_find_group_by_pin(struct wmt_pinctrl_data *data, u32 pin)196{197	int i;198 199	for (i = 0; i < data->npins; i++) {200		if (data->pins[i].number == pin)201			return i;202	}203 204	return -EINVAL;205}206 207static int wmt_pctl_dt_node_to_map_func(struct wmt_pinctrl_data *data,208					struct device_node *np,209					u32 pin, u32 fnum,210					struct pinctrl_map **maps)211{212	int group;213	struct pinctrl_map *map = *maps;214 215	if (fnum >= ARRAY_SIZE(wmt_functions)) {216		dev_err(data->dev, "invalid wm,function %d\n", fnum);217		return -EINVAL;218	}219 220	group = wmt_pctl_find_group_by_pin(data, pin);221	if (group < 0) {222		dev_err(data->dev, "unable to match pin %d to group\n", pin);223		return group;224	}225 226	map->type = PIN_MAP_TYPE_MUX_GROUP;227	map->data.mux.group = data->groups[group];228	map->data.mux.function = wmt_functions[fnum];229	(*maps)++;230 231	return 0;232}233 234static int wmt_pctl_dt_node_to_map_pull(struct wmt_pinctrl_data *data,235					struct device_node *np,236					u32 pin, u32 pull,237					struct pinctrl_map **maps)238{239	int group;240	unsigned long *configs;241	struct pinctrl_map *map = *maps;242 243	if (pull > 2) {244		dev_err(data->dev, "invalid wm,pull %d\n", pull);245		return -EINVAL;246	}247 248	group = wmt_pctl_find_group_by_pin(data, pin);249	if (group < 0) {250		dev_err(data->dev, "unable to match pin %d to group\n", pin);251		return group;252	}253 254	configs = kzalloc(sizeof(*configs), GFP_KERNEL);255	if (!configs)256		return -ENOMEM;257 258	switch (pull) {259	case 0:260		configs[0] = PIN_CONFIG_BIAS_DISABLE;261		break;262	case 1:263		configs[0] = PIN_CONFIG_BIAS_PULL_DOWN;264		break;265	case 2:266		configs[0] = PIN_CONFIG_BIAS_PULL_UP;267		break;268	default:269		configs[0] = PIN_CONFIG_BIAS_DISABLE;270		dev_err(data->dev, "invalid pull state %d - disabling\n", pull);271	}272 273	map->type = PIN_MAP_TYPE_CONFIGS_PIN;274	map->data.configs.group_or_pin = data->groups[group];275	map->data.configs.configs = configs;276	map->data.configs.num_configs = 1;277	(*maps)++;278 279	return 0;280}281 282static void wmt_pctl_dt_free_map(struct pinctrl_dev *pctldev,283				 struct pinctrl_map *maps,284				 unsigned num_maps)285{286	int i;287 288	for (i = 0; i < num_maps; i++)289		if (maps[i].type == PIN_MAP_TYPE_CONFIGS_PIN)290			kfree(maps[i].data.configs.configs);291 292	kfree(maps);293}294 295static int wmt_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,296				   struct device_node *np,297				   struct pinctrl_map **map,298				   unsigned *num_maps)299{300	struct pinctrl_map *maps, *cur_map;301	struct property *pins, *funcs, *pulls;302	u32 pin, func, pull;303	int num_pins, num_funcs, num_pulls, maps_per_pin;304	int i, err;305	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);306 307	pins = of_find_property(np, "wm,pins", NULL);308	if (!pins) {309		dev_err(data->dev, "missing wmt,pins property\n");310		return -EINVAL;311	}312 313	funcs = of_find_property(np, "wm,function", NULL);314	pulls = of_find_property(np, "wm,pull", NULL);315 316	if (!funcs && !pulls) {317		dev_err(data->dev, "neither wm,function nor wm,pull specified\n");318		return -EINVAL;319	}320 321	/*322	 * The following lines calculate how many values are defined for each323	 * of the properties.324	 */325	num_pins = pins->length / sizeof(u32);326	num_funcs = funcs ? (funcs->length / sizeof(u32)) : 0;327	num_pulls = pulls ? (pulls->length / sizeof(u32)) : 0;328 329	if (num_funcs > 1 && num_funcs != num_pins) {330		dev_err(data->dev, "wm,function must have 1 or %d entries\n",331			num_pins);332		return -EINVAL;333	}334 335	if (num_pulls > 1 && num_pulls != num_pins) {336		dev_err(data->dev, "wm,pull must have 1 or %d entries\n",337			num_pins);338		return -EINVAL;339	}340 341	maps_per_pin = 0;342	if (num_funcs)343		maps_per_pin++;344	if (num_pulls)345		maps_per_pin++;346 347	cur_map = maps = kcalloc(num_pins * maps_per_pin, sizeof(*maps),348				 GFP_KERNEL);349	if (!maps)350		return -ENOMEM;351 352	for (i = 0; i < num_pins; i++) {353		err = of_property_read_u32_index(np, "wm,pins", i, &pin);354		if (err)355			goto fail;356 357		if (pin >= (data->nbanks * 32)) {358			dev_err(data->dev, "invalid wm,pins value\n");359			err = -EINVAL;360			goto fail;361		}362 363		if (num_funcs) {364			err = of_property_read_u32_index(np, "wm,function",365						(num_funcs > 1 ? i : 0), &func);366			if (err)367				goto fail;368 369			err = wmt_pctl_dt_node_to_map_func(data, np, pin, func,370							   &cur_map);371			if (err)372				goto fail;373		}374 375		if (num_pulls) {376			err = of_property_read_u32_index(np, "wm,pull",377						(num_pulls > 1 ? i : 0), &pull);378			if (err)379				goto fail;380 381			err = wmt_pctl_dt_node_to_map_pull(data, np, pin, pull,382							   &cur_map);383			if (err)384				goto fail;385		}386	}387	*map = maps;388	*num_maps = num_pins * maps_per_pin;389	return 0;390 391/*392 * The fail path removes any maps that have been allocated. The fail path is393 * only called from code after maps has been kzalloc'd. It is also safe to394 * pass 'num_pins * maps_per_pin' as the map count even though we probably395 * failed before all the mappings were read as all maps are allocated at once,396 * and configs are only allocated for .type = PIN_MAP_TYPE_CONFIGS_PIN - there397 * is no failpath where a config can be allocated without .type being set.398 */399fail:400	wmt_pctl_dt_free_map(pctldev, maps, num_pins * maps_per_pin);401	return err;402}403 404static const struct pinctrl_ops wmt_pctl_ops = {405	.get_groups_count = wmt_get_groups_count,406	.get_group_name	= wmt_get_group_name,407	.get_group_pins	= wmt_get_group_pins,408	.dt_node_to_map = wmt_pctl_dt_node_to_map,409	.dt_free_map = wmt_pctl_dt_free_map,410};411 412static int wmt_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin,413			   unsigned long *config)414{415	return -ENOTSUPP;416}417 418static int wmt_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin,419			   unsigned long *configs, unsigned num_configs)420{421	struct wmt_pinctrl_data *data = pinctrl_dev_get_drvdata(pctldev);422	enum pin_config_param param;423	u32 arg;424	u32 bank = WMT_BANK_FROM_PIN(pin);425	u32 bit = WMT_BIT_FROM_PIN(pin);426	u32 reg_pull_en = data->banks[bank].reg_pull_en;427	u32 reg_pull_cfg = data->banks[bank].reg_pull_cfg;428	int i;429 430	if ((reg_pull_en == NO_REG) || (reg_pull_cfg == NO_REG)) {431		dev_err(data->dev, "bias functions not supported on pin %d\n",432			pin);433		return -EINVAL;434	}435 436	for (i = 0; i < num_configs; i++) {437		param = pinconf_to_config_param(configs[i]);438		arg = pinconf_to_config_argument(configs[i]);439 440		if ((param == PIN_CONFIG_BIAS_PULL_DOWN) ||441		    (param == PIN_CONFIG_BIAS_PULL_UP)) {442			if (arg == 0)443				param = PIN_CONFIG_BIAS_DISABLE;444		}445 446		switch (param) {447		case PIN_CONFIG_BIAS_DISABLE:448			wmt_clearbits(data, reg_pull_en, BIT(bit));449			break;450		case PIN_CONFIG_BIAS_PULL_DOWN:451			wmt_clearbits(data, reg_pull_cfg, BIT(bit));452			wmt_setbits(data, reg_pull_en, BIT(bit));453			break;454		case PIN_CONFIG_BIAS_PULL_UP:455			wmt_setbits(data, reg_pull_cfg, BIT(bit));456			wmt_setbits(data, reg_pull_en, BIT(bit));457			break;458		default:459			dev_err(data->dev, "unknown pinconf param\n");460			return -EINVAL;461		}462	} /* for each config */463 464	return 0;465}466 467static const struct pinconf_ops wmt_pinconf_ops = {468	.pin_config_get = wmt_pinconf_get,469	.pin_config_set = wmt_pinconf_set,470};471 472static struct pinctrl_desc wmt_desc = {473	.owner = THIS_MODULE,474	.name = "pinctrl-wmt",475	.pctlops = &wmt_pctl_ops,476	.pmxops = &wmt_pinmux_ops,477	.confops = &wmt_pinconf_ops,478};479 480static int wmt_gpio_get_direction(struct gpio_chip *chip, unsigned offset)481{482	struct wmt_pinctrl_data *data = gpiochip_get_data(chip);483	u32 bank = WMT_BANK_FROM_PIN(offset);484	u32 bit = WMT_BIT_FROM_PIN(offset);485	u32 reg_dir = data->banks[bank].reg_dir;486	u32 val;487 488	val = readl_relaxed(data->base + reg_dir);489	if (val & BIT(bit))490		return GPIO_LINE_DIRECTION_OUT;491 492	return GPIO_LINE_DIRECTION_IN;493}494 495static int wmt_gpio_get_value(struct gpio_chip *chip, unsigned offset)496{497	struct wmt_pinctrl_data *data = gpiochip_get_data(chip);498	u32 bank = WMT_BANK_FROM_PIN(offset);499	u32 bit = WMT_BIT_FROM_PIN(offset);500	u32 reg_data_in = data->banks[bank].reg_data_in;501 502	if (reg_data_in == NO_REG) {503		dev_err(data->dev, "no data in register defined\n");504		return -EINVAL;505	}506 507	return !!(readl_relaxed(data->base + reg_data_in) & BIT(bit));508}509 510static void wmt_gpio_set_value(struct gpio_chip *chip, unsigned offset,511			       int val)512{513	struct wmt_pinctrl_data *data = gpiochip_get_data(chip);514	u32 bank = WMT_BANK_FROM_PIN(offset);515	u32 bit = WMT_BIT_FROM_PIN(offset);516	u32 reg_data_out = data->banks[bank].reg_data_out;517 518	if (reg_data_out == NO_REG) {519		dev_err(data->dev, "no data out register defined\n");520		return;521	}522 523	if (val)524		wmt_setbits(data, reg_data_out, BIT(bit));525	else526		wmt_clearbits(data, reg_data_out, BIT(bit));527}528 529static int wmt_gpio_direction_output(struct gpio_chip *chip, unsigned offset,530				     int value)531{532	wmt_gpio_set_value(chip, offset, value);533	return pinctrl_gpio_direction_output(chip, offset);534}535 536static const struct gpio_chip wmt_gpio_chip = {537	.label = "gpio-wmt",538	.owner = THIS_MODULE,539	.request = gpiochip_generic_request,540	.free = gpiochip_generic_free,541	.get_direction = wmt_gpio_get_direction,542	.direction_input = pinctrl_gpio_direction_input,543	.direction_output = wmt_gpio_direction_output,544	.get = wmt_gpio_get_value,545	.set = wmt_gpio_set_value,546	.can_sleep = false,547};548 549int wmt_pinctrl_probe(struct platform_device *pdev,550		      struct wmt_pinctrl_data *data)551{552	int err;553 554	data->base = devm_platform_ioremap_resource(pdev, 0);555	if (IS_ERR(data->base))556		return PTR_ERR(data->base);557 558	wmt_desc.pins = data->pins;559	wmt_desc.npins = data->npins;560 561	data->gpio_chip = wmt_gpio_chip;562	data->gpio_chip.parent = &pdev->dev;563	data->gpio_chip.ngpio = data->nbanks * 32;564 565	platform_set_drvdata(pdev, data);566 567	data->dev = &pdev->dev;568 569	data->pctl_dev = devm_pinctrl_register(&pdev->dev, &wmt_desc, data);570	if (IS_ERR(data->pctl_dev)) {571		dev_err(&pdev->dev, "Failed to register pinctrl\n");572		return PTR_ERR(data->pctl_dev);573	}574 575	err = gpiochip_add_data(&data->gpio_chip, data);576	if (err) {577		dev_err(&pdev->dev, "could not add GPIO chip\n");578		return err;579	}580 581	err = gpiochip_add_pin_range(&data->gpio_chip, dev_name(data->dev),582				     0, 0, data->nbanks * 32);583	if (err)584		goto fail_range;585 586	dev_info(&pdev->dev, "Pin controller initialized\n");587 588	return 0;589 590fail_range:591	gpiochip_remove(&data->gpio_chip);592	return err;593}594