brintos

brintos / linux-shallow public Read only

0
0
Text · 2.5 KiB · cc5f2c1 Raw
107 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * GPIO-controlled multiplexer driver4 *5 * Copyright (C) 2017 Axentia Technologies AB6 *7 * Author: Peter Rosin <peda@axentia.se>8 */9 10#include <linux/bitmap.h>11#include <linux/err.h>12#include <linux/gpio/consumer.h>13#include <linux/mod_devicetable.h>14#include <linux/module.h>15#include <linux/mux/driver.h>16#include <linux/platform_device.h>17#include <linux/property.h>18 19struct mux_gpio {20	struct gpio_descs *gpios;21};22 23static int mux_gpio_set(struct mux_control *mux, int state)24{25	struct mux_gpio *mux_gpio = mux_chip_priv(mux->chip);26	DECLARE_BITMAP(values, BITS_PER_TYPE(state));27	u32 value = state;28 29	bitmap_from_arr32(values, &value, BITS_PER_TYPE(value));30 31	gpiod_set_array_value_cansleep(mux_gpio->gpios->ndescs,32				       mux_gpio->gpios->desc,33				       mux_gpio->gpios->info, values);34 35	return 0;36}37 38static const struct mux_control_ops mux_gpio_ops = {39	.set = mux_gpio_set,40};41 42static const struct of_device_id mux_gpio_dt_ids[] = {43	{ .compatible = "gpio-mux", },44	{ /* sentinel */ }45};46MODULE_DEVICE_TABLE(of, mux_gpio_dt_ids);47 48static int mux_gpio_probe(struct platform_device *pdev)49{50	struct device *dev = &pdev->dev;51	struct mux_chip *mux_chip;52	struct mux_gpio *mux_gpio;53	int pins;54	s32 idle_state;55	int ret;56 57	pins = gpiod_count(dev, "mux");58	if (pins < 0)59		return pins;60 61	mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*mux_gpio));62	if (IS_ERR(mux_chip))63		return PTR_ERR(mux_chip);64 65	mux_gpio = mux_chip_priv(mux_chip);66	mux_chip->ops = &mux_gpio_ops;67 68	mux_gpio->gpios = devm_gpiod_get_array(dev, "mux", GPIOD_OUT_LOW);69	if (IS_ERR(mux_gpio->gpios))70		return dev_err_probe(dev, PTR_ERR(mux_gpio->gpios),71				     "failed to get gpios\n");72	WARN_ON(pins != mux_gpio->gpios->ndescs);73	mux_chip->mux->states = BIT(pins);74 75	ret = device_property_read_u32(dev, "idle-state", (u32 *)&idle_state);76	if (ret >= 0 && idle_state != MUX_IDLE_AS_IS) {77		if (idle_state < 0 || idle_state >= mux_chip->mux->states) {78			dev_err(dev, "invalid idle-state %u\n", idle_state);79			return -EINVAL;80		}81 82		mux_chip->mux->idle_state = idle_state;83	}84 85	ret = devm_mux_chip_register(dev, mux_chip);86	if (ret < 0)87		return ret;88 89	dev_info(dev, "%u-way mux-controller registered\n",90		 mux_chip->mux->states);91 92	return 0;93}94 95static struct platform_driver mux_gpio_driver = {96	.driver = {97		.name = "gpio-mux",98		.of_match_table	= mux_gpio_dt_ids,99	},100	.probe = mux_gpio_probe,101};102module_platform_driver(mux_gpio_driver);103 104MODULE_DESCRIPTION("GPIO-controlled multiplexer driver");105MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");106MODULE_LICENSE("GPL v2");107