1 /* 2 * GPIO-controlled multiplexer driver 3 * 4 * Copyright (C) 2017 Axentia Technologies AB 5 * 6 * Author: Peter Rosin <peda@axentia.se> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13 #include <linux/err.h> 14 #include <linux/gpio/consumer.h> 15 #include <linux/module.h> 16 #include <linux/mux/driver.h> 17 #include <linux/of_platform.h> 18 #include <linux/platform_device.h> 19 #include <linux/property.h> 20 21 struct mux_gpio { 22 struct gpio_descs *gpios; 23 int *val; 24 }; 25 26 static int mux_gpio_set(struct mux_control *mux, int state) 27 { 28 struct mux_gpio *mux_gpio = mux_chip_priv(mux->chip); 29 int i; 30 31 for (i = 0; i < mux_gpio->gpios->ndescs; i++) 32 mux_gpio->val[i] = (state >> i) & 1; 33 34 gpiod_set_array_value_cansleep(mux_gpio->gpios->ndescs, 35 mux_gpio->gpios->desc, 36 mux_gpio->val); 37 38 return 0; 39 } 40 41 static const struct mux_control_ops mux_gpio_ops = { 42 .set = mux_gpio_set, 43 }; 44 45 static const struct of_device_id mux_gpio_dt_ids[] = { 46 { .compatible = "gpio-mux", }, 47 { /* sentinel */ } 48 }; 49 MODULE_DEVICE_TABLE(of, mux_gpio_dt_ids); 50 51 static int mux_gpio_probe(struct platform_device *pdev) 52 { 53 struct device *dev = &pdev->dev; 54 struct mux_chip *mux_chip; 55 struct mux_gpio *mux_gpio; 56 int pins; 57 s32 idle_state; 58 int ret; 59 60 pins = gpiod_count(dev, "mux"); 61 if (pins < 0) 62 return pins; 63 64 mux_chip = devm_mux_chip_alloc(dev, 1, sizeof(*mux_gpio) + 65 pins * sizeof(*mux_gpio->val)); 66 if (IS_ERR(mux_chip)) 67 return PTR_ERR(mux_chip); 68 69 mux_gpio = mux_chip_priv(mux_chip); 70 mux_gpio->val = (int *)(mux_gpio + 1); 71 mux_chip->ops = &mux_gpio_ops; 72 73 mux_gpio->gpios = devm_gpiod_get_array(dev, "mux", GPIOD_OUT_LOW); 74 if (IS_ERR(mux_gpio->gpios)) { 75 ret = PTR_ERR(mux_gpio->gpios); 76 if (ret != -EPROBE_DEFER) 77 dev_err(dev, "failed to get gpios\n"); 78 return ret; 79 } 80 WARN_ON(pins != mux_gpio->gpios->ndescs); 81 mux_chip->mux->states = 1 << pins; 82 83 ret = device_property_read_u32(dev, "idle-state", (u32 *)&idle_state); 84 if (ret >= 0 && idle_state != MUX_IDLE_AS_IS) { 85 if (idle_state < 0 || idle_state >= mux_chip->mux->states) { 86 dev_err(dev, "invalid idle-state %u\n", idle_state); 87 return -EINVAL; 88 } 89 90 mux_chip->mux->idle_state = idle_state; 91 } 92 93 ret = devm_mux_chip_register(dev, mux_chip); 94 if (ret < 0) 95 return ret; 96 97 dev_info(dev, "%u-way mux-controller registered\n", 98 mux_chip->mux->states); 99 100 return 0; 101 } 102 103 static struct platform_driver mux_gpio_driver = { 104 .driver = { 105 .name = "gpio-mux", 106 .of_match_table = of_match_ptr(mux_gpio_dt_ids), 107 }, 108 .probe = mux_gpio_probe, 109 }; 110 module_platform_driver(mux_gpio_driver); 111 112 MODULE_DESCRIPTION("GPIO-controlled multiplexer driver"); 113 MODULE_AUTHOR("Peter Rosin <peda@axentia.se>"); 114 MODULE_LICENSE("GPL v2"); 115